Пример #1
0
static void *cliprdr_thread_func(void *arg)
{
	cliprdrContext *cliprdr = (cliprdrContext *)arg;
	BOOL mcode;
	MSG msg;
	int ret;
	HRESULT result;

	if ((ret = create_cliprdr_window(cliprdr)) != 0)
	{
		DEBUG_CLIPRDR("error: create clipboard window failed.");
		return NULL;
	}

	while ((mcode = GetMessage(&msg, 0, 0, 0) != 0))
	{
		if (mcode == -1)
		{
			DEBUG_CLIPRDR("error: clipboard thread GetMessage failed.");
			break;
		}
		else
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return NULL;
}
Пример #2
0
static void* cliprdr_thread_func(void* arg)
{
	int ret;
	MSG msg;
	BOOL mcode;
	wfClipboard* clipboard = (wfClipboard*) arg;

	OleInitialize(0);

	if ((ret = create_cliprdr_window(clipboard)) != 0)
	{
		DEBUG_CLIPRDR("error: create clipboard window failed.");
		return NULL;
	}

	while ((mcode = GetMessage(&msg, 0, 0, 0)) != 0)
	{
		if (mcode == -1)
		{
			DEBUG_CLIPRDR("error: clipboard thread GetMessage failed.");
			break;
		}
		else
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	OleUninitialize();

	return NULL;
}
Пример #3
0
static void cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, STREAM* s, uint16 length, uint16 flags)
{
	int i;
	uint16 lengthCapability;
	uint16 cCapabilitiesSets;
	uint16 capabilitySetType;

	stream_read_uint16(s, cCapabilitiesSets); /* cCapabilitiesSets (2 bytes) */
	stream_seek_uint16(s); /* pad1 (2 bytes) */

	DEBUG_CLIPRDR("cCapabilitiesSets %d", cCapabilitiesSets);

	for (i = 0; i < cCapabilitiesSets; i++)
	{
		stream_read_uint16(s, capabilitySetType); /* capabilitySetType (2 bytes) */
		stream_read_uint16(s, lengthCapability); /* lengthCapability (2 bytes) */

		switch (capabilitySetType)
		{
			case CB_CAPSTYPE_GENERAL:
				cliprdr_process_general_capability(cliprdr, s);
				break;

			default:
				DEBUG_WARN("unknown cliprdr capability set: %d", capabilitySetType);
				break;
		}
	}
}
Пример #4
0
static void cliprdr_process_general_capability(cliprdrPlugin* cliprdr, STREAM* s)
{
	uint32 version;
	uint32 generalFlags;

	stream_read_uint32(s, version); /* version (4 bytes) */
	stream_read_uint32(s, generalFlags); /* generalFlags (4 bytes) */

	DEBUG_CLIPRDR("Version: %d", version);

#ifdef WITH_DEBUG_CLIPRDR
	cliprdr_print_general_capability_flags(generalFlags);
#endif

	if (generalFlags & CB_USE_LONG_FORMAT_NAMES)
		cliprdr->use_long_format_names = true;

	if (generalFlags & CB_STREAM_FILECLIP_ENABLED)
		cliprdr->stream_fileclip_enabled = true;

	if (generalFlags & CB_FILECLIP_NO_FILE_PATHS)
		cliprdr->fileclip_no_file_paths = true;

	if (generalFlags & CB_CAN_LOCK_CLIPDATA)
		cliprdr->can_lock_clipdata = true;

	cliprdr->received_caps = true;
}
Пример #5
0
static void cliprdr_send_format_list_response(cliprdrPlugin* cliprdr)
{
	wStream* s;
	DEBUG_CLIPRDR("Sending Clipboard Format List Response");
	s = cliprdr_packet_new(CB_FORMAT_LIST_RESPONSE, CB_RESPONSE_OK, 0);
	cliprdr_packet_send(cliprdr, s);
}
Пример #6
0
static BOOL wf_cliprdr_get_file_contents(WCHAR* file_name, BYTE* buffer,
	int positionLow, int positionHigh, int nRequested, unsigned int* puSize)
{
	HANDLE hFile;
	DWORD nGet;

	if (!file_name || !buffer || !puSize)
	{
		WLog_ERR(TAG,  "get file contents Invalid Arguments.");
		return FALSE;
	}
	
	hFile = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL);
	
	if (hFile == INVALID_HANDLE_VALUE)
	{
		return FALSE;
	}

	SetFilePointer(hFile, positionLow, (PLONG) &positionHigh, FILE_BEGIN);

	if (!ReadFile(hFile, buffer, nRequested, &nGet, NULL))
	{
		DWORD err = GetLastError();
		DEBUG_CLIPRDR("ReadFile failed with 0x%x.", err);
	}

	CloseHandle(hFile);

	*puSize = nGet;

	return TRUE;
}
Пример #7
0
static int create_cliprdr_window(cliprdrContext *cliprdr)
{
	WNDCLASSEX wnd_cls;

	ZeroMemory(&wnd_cls, sizeof(WNDCLASSEX));
	wnd_cls.cbSize        = sizeof(WNDCLASSEX);
	wnd_cls.style         = CS_OWNDC;
	wnd_cls.lpfnWndProc   = cliprdr_proc;
	wnd_cls.cbClsExtra    = 0;
	wnd_cls.cbWndExtra    = 0;
	wnd_cls.hIcon         = NULL;
	wnd_cls.hCursor       = NULL;
	wnd_cls.hbrBackground = NULL;
	wnd_cls.lpszMenuName  = NULL;
	wnd_cls.lpszClassName = L"ClipboardHiddenMessageProcessor";
	wnd_cls.hInstance     = GetModuleHandle(NULL);
	wnd_cls.hIconSm       = NULL;
	RegisterClassEx(&wnd_cls);

	cliprdr->hwndClipboard = CreateWindowEx(WS_EX_LEFT,
		L"ClipboardHiddenMessageProcessor",
		L"rdpclip",
		0, 0, 0, 0, 0, HWND_MESSAGE, NULL, GetModuleHandle(NULL), cliprdr);

	if (cliprdr->hwndClipboard == NULL)
	{
		DEBUG_CLIPRDR("error: CreateWindowEx failed with %x.", GetLastError());
		return -1;
	}

	return 0;
}
Пример #8
0
static void cliprdr_process_general_capability(cliprdrPlugin* cliprdr, wStream* s)
{
	UINT32 version;
	UINT32 generalFlags;
	RDP_CB_CLIP_CAPS *caps_event;

	Stream_Read_UINT32(s, version); /* version (4 bytes) */
	Stream_Read_UINT32(s, generalFlags); /* generalFlags (4 bytes) */

	DEBUG_CLIPRDR("Version: %d", version);

#ifdef WITH_DEBUG_CLIPRDR
	cliprdr_print_general_capability_flags(generalFlags);
#endif

	caps_event = (RDP_CB_CLIP_CAPS *)freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_ClipCaps, NULL, NULL);
	caps_event->capabilities = generalFlags;

	if (generalFlags & CB_USE_LONG_FORMAT_NAMES)
		cliprdr->use_long_format_names = TRUE;

	if (generalFlags & CB_STREAM_FILECLIP_ENABLED)
		cliprdr->stream_fileclip_enabled = TRUE;

	if (generalFlags & CB_FILECLIP_NO_FILE_PATHS)
		cliprdr->fileclip_no_file_paths = TRUE;

	if (generalFlags & CB_CAN_LOCK_CLIPDATA)
		cliprdr->can_lock_clipdata = TRUE;

	cliprdr->received_caps = TRUE;

	svc_plugin_send_event((rdpSvcPlugin *)cliprdr, (wMessage *)caps_event);

}
Пример #9
0
static void cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, wStream* s, UINT16 length, UINT16 flags)
{
	int i;
	UINT16 lengthCapability;
	UINT16 cCapabilitiesSets;
	UINT16 capabilitySetType;
	Stream_Read_UINT16(s, cCapabilitiesSets); /* cCapabilitiesSets (2 bytes) */
	Stream_Seek_UINT16(s); /* pad1 (2 bytes) */
	DEBUG_CLIPRDR("cCapabilitiesSets %d", cCapabilitiesSets);

	for (i = 0; i < cCapabilitiesSets; i++)
	{
		Stream_Read_UINT16(s, capabilitySetType); /* capabilitySetType (2 bytes) */
		Stream_Read_UINT16(s, lengthCapability); /* lengthCapability (2 bytes) */

		switch (capabilitySetType)
		{
			case CB_CAPSTYPE_GENERAL:
				cliprdr_process_general_capability(cliprdr, s);
				break;
			default:
				WLog_ERR(TAG, "unknown cliprdr capability set: %d", capabilitySetType);
				break;
		}
	}
}
Пример #10
0
static void cliprdr_process_unlock_clipdata_event(cliprdrPlugin* plugin, RDP_CB_UNLOCK_CLIPDATA_EVENT* event)
{
	wStream* s;
	DEBUG_CLIPRDR("Sending UnLock Request");
	s = cliprdr_packet_new(CB_UNLOCK_CLIPDATA, 0, 4);
	Stream_Write_UINT32(s, event->clipDataId);
	cliprdr_packet_send(plugin, s);
}
Пример #11
0
static void cliprdr_process_tempdir_event(cliprdrPlugin* plugin, RDP_CB_TEMPDIR_EVENT* event)
{
	wStream* s;
	DEBUG_CLIPRDR("Sending Temporary Directory.");
	s = cliprdr_packet_new(CB_TEMP_DIRECTORY, 0, 520);
	Stream_Write(s, event->dirname, 520);
	cliprdr_packet_send(plugin, s);
}
Пример #12
0
void cliprdr_process_format_list_event(cliprdrPlugin* cliprdr, RDP_CB_FORMAT_LIST_EVENT* cb_event)
{
	int i;
	wStream* s;

	DEBUG_CLIPRDR("Sending Clipboard Format List");

	if (cb_event->raw_format_data)
	{
		s = cliprdr_packet_new(CB_FORMAT_LIST, 0, cb_event->raw_format_data_size);
		Stream_Write(s, cb_event->raw_format_data, cb_event->raw_format_data_size);
	}
	else
	{
		wStream* body = Stream_New(NULL, 64);
		
		for (i = 0; i < cb_event->num_formats; i++)
		{
			const char* name;
			int name_length;

			switch (cb_event->formats[i])
			{
				case CB_FORMAT_HTML:
					name = CFSTR_HTML; name_length = sizeof(CFSTR_HTML);
					break;
				case CB_FORMAT_PNG:
					name = CFSTR_PNG; name_length = sizeof(CFSTR_PNG);
					break;
				case CB_FORMAT_JPEG:
					name = CFSTR_JPEG; name_length = sizeof(CFSTR_JPEG);
					break;
				case CB_FORMAT_GIF:
					name = CFSTR_GIF; name_length = sizeof(CFSTR_GIF);
					break;
				default:
					name = "\0\0";
					name_length = 2;
					break;
			}
			
			if (!cliprdr->use_long_format_names)
				name_length = 32;
			
			Stream_EnsureRemainingCapacity(body, 4 + name_length);

			Stream_Write_UINT32(body, cb_event->formats[i]);
			Stream_Write(body, name, name_length);
		}
				
		Stream_SealLength(body);
		s = cliprdr_packet_new(CB_FORMAT_LIST, 0, Stream_Length(body));
		Stream_Write(s, Stream_Buffer(body), Stream_Length(body));
		Stream_Free(body, TRUE);
	}

	cliprdr_packet_send(cliprdr, s);
}
Пример #13
0
void cliprdr_process_format_list_event(cliprdrPlugin* cliprdr, RDP_CB_FORMAT_LIST_EVENT* cb_event)
{
	int i;
	wStream* s;

	DEBUG_CLIPRDR("Sending Clipboard Format List");

	if (cb_event->raw_format_data)
	{
		s = cliprdr_packet_new(CB_FORMAT_LIST, 0, cb_event->raw_format_data_size);
		stream_write(s, cb_event->raw_format_data, cb_event->raw_format_data_size);
	}
	else
	{
		wStream* body = stream_new(0);
		
		for (i = 0; i < cb_event->num_formats; i++)
		{
			const char* name;
			int name_length;

			switch (cb_event->formats[i])
			{
				case CB_FORMAT_HTML:
					name = CFSTR_HTML; name_length = sizeof(CFSTR_HTML);
					break;
				case CB_FORMAT_PNG:
					name = CFSTR_PNG; name_length = sizeof(CFSTR_PNG);
					break;
				case CB_FORMAT_JPEG:
					name = CFSTR_JPEG; name_length = sizeof(CFSTR_JPEG);
					break;
				case CB_FORMAT_GIF:
					name = CFSTR_GIF; name_length = sizeof(CFSTR_GIF);
					break;
				default:
					name = "\0\0";
					name_length = 2;
					break;
			}
			
			if (!cliprdr->use_long_format_names)
				name_length = 32;
			
			stream_extend(body, stream_get_size(body) + 4 + name_length);

			stream_write_UINT32(body, cb_event->formats[i]);
			stream_write(body, name, name_length);
		}
				
		s = cliprdr_packet_new(CB_FORMAT_LIST, 0, stream_get_size(body));
		stream_write(s, stream_get_head(body), stream_get_size(body));
		stream_free(body);
	}

	cliprdr_packet_send(cliprdr, s);
}
Пример #14
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT cliprdr_process_general_capability(cliprdrPlugin* cliprdr, wStream* s)
{
	UINT32 version;
	UINT32 generalFlags;
	CLIPRDR_CAPABILITIES capabilities;
	CLIPRDR_GENERAL_CAPABILITY_SET generalCapabilitySet;
	CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
	UINT error = CHANNEL_RC_OK;

	if (!context)
	{
		WLog_ERR(TAG, "cliprdr_get_client_interface failed!");
		return ERROR_INTERNAL_ERROR;
	}

	Stream_Read_UINT32(s, version); /* version (4 bytes) */
	Stream_Read_UINT32(s, generalFlags); /* generalFlags (4 bytes) */

	DEBUG_CLIPRDR("Version: %d", version);
#ifdef WITH_DEBUG_CLIPRDR
	cliprdr_print_general_capability_flags(generalFlags);
#endif

	if (cliprdr->useLongFormatNames)
		cliprdr->useLongFormatNames = (generalFlags & CB_USE_LONG_FORMAT_NAMES) ? TRUE : FALSE;

	if (cliprdr->streamFileClipEnabled)
		cliprdr->streamFileClipEnabled = (generalFlags & CB_STREAM_FILECLIP_ENABLED) ? TRUE : FALSE;

	if (cliprdr->fileClipNoFilePaths)
		cliprdr->fileClipNoFilePaths = (generalFlags & CB_FILECLIP_NO_FILE_PATHS) ? TRUE : FALSE;

	if (cliprdr->canLockClipData)
		cliprdr->canLockClipData = (generalFlags & CB_CAN_LOCK_CLIPDATA) ? TRUE : FALSE;

	cliprdr->capabilitiesReceived = TRUE;

	if (!context->custom)
	{
		WLog_ERR(TAG, "context->custom not set!");
		return ERROR_INTERNAL_ERROR;
	}

	capabilities.cCapabilitiesSets = 1;
	capabilities.capabilitySets = (CLIPRDR_CAPABILITY_SET*) &(generalCapabilitySet);
	generalCapabilitySet.capabilitySetType = CB_CAPSTYPE_GENERAL;
	generalCapabilitySet.capabilitySetLength = 12;
	generalCapabilitySet.version = version;
	generalCapabilitySet.generalFlags = generalFlags;


	IFCALLRET(context->ServerCapabilities, error, context, &capabilities);
	if (error)
		WLog_ERR(TAG, "ServerCapabilities failed with error %lu!", error);

	return error;
}
Пример #15
0
void cliprdr_process_format_data_request_event(cliprdrPlugin* cliprdr, RDP_CB_DATA_REQUEST_EVENT* cb_event)
{
	wStream* s;

	DEBUG_CLIPRDR("Sending Format Data Request");

	s = cliprdr_packet_new(CB_FORMAT_DATA_REQUEST, 0, 4);
	Stream_Write_UINT32(s, cb_event->format);
	cliprdr_packet_send(cliprdr, s);
}
Пример #16
0
static void cliprdr_process_receive(rdpSvcPlugin* plugin, wStream* s)
{
	UINT16 msgType;
	UINT16 msgFlags;
	UINT32 dataLen;
	cliprdrPlugin* cliprdr = (cliprdrPlugin*) plugin;
	Stream_Read_UINT16(s, msgType);
	Stream_Read_UINT16(s, msgFlags);
	Stream_Read_UINT32(s, dataLen);
	DEBUG_CLIPRDR("msgType: %s (%d), msgFlags: %d dataLen: %d",
				  CB_MSG_TYPE_STRINGS[msgType], msgType, msgFlags, dataLen);
#ifdef WITH_DEBUG_CLIPRDR
	winpr_HexDump(TAG, WLOG_DEBUG, Stream_Buffer(s), dataLen + 8);
#endif

	switch (msgType)
	{
		case CB_CLIP_CAPS:
			cliprdr_process_clip_caps(cliprdr, s, dataLen, msgFlags);
			break;
		case CB_MONITOR_READY:
			cliprdr_process_monitor_ready(cliprdr, s, dataLen, msgFlags);
			break;
		case CB_FORMAT_LIST:
			cliprdr_process_format_list(cliprdr, s, dataLen, msgFlags);
			break;
		case CB_FORMAT_LIST_RESPONSE:
			cliprdr_process_format_list_response(cliprdr, s, dataLen, msgFlags);
			break;
		case CB_FORMAT_DATA_REQUEST:
			cliprdr_process_format_data_request(cliprdr, s, dataLen, msgFlags);
			break;
		case CB_FORMAT_DATA_RESPONSE:
			cliprdr_process_format_data_response(cliprdr, s, dataLen, msgFlags);
			break;
		case CB_FILECONTENTS_REQUEST:
			cliprdr_process_filecontents_request(cliprdr, s, dataLen, msgFlags);
			break;
		case CB_FILECONTENTS_RESPONSE:
			cliprdr_process_filecontents_response(cliprdr, s, dataLen, msgFlags);
			break;
		case CB_LOCK_CLIPDATA:
			cliprdr_process_lock_clipdata(cliprdr, s, dataLen, msgFlags);
			break;
		case CB_UNLOCK_CLIPDATA:
			cliprdr_process_unlock_clipdata(cliprdr, s, dataLen, msgFlags);
			break;
		default:
			WLog_ERR(TAG, "unknown msgType %d", msgType);
			break;
	}
}
Пример #17
0
static void cliprdr_process_receive(rdpSvcPlugin* plugin, wStream* s)
{
	UINT16 msgType;
	UINT16 msgFlags;
	UINT32 dataLen;
	cliprdrPlugin* cliprdr = (cliprdrPlugin*) plugin;

	Stream_Read_UINT16(s, msgType);
	Stream_Read_UINT16(s, msgFlags);
	Stream_Read_UINT32(s, dataLen);

	DEBUG_CLIPRDR("msgType: %s (%d), msgFlags: %d dataLen: %d",
		CB_MSG_TYPE_STRINGS[msgType], msgType, msgFlags, dataLen);

#ifdef WITH_DEBUG_CLIPRDR
	winpr_HexDump(Stream_Buffer(s), dataLen + 8);
#endif

	switch (msgType)
	{
		case CB_CLIP_CAPS:
			cliprdr_process_clip_caps(cliprdr, s, dataLen, msgFlags);
			break;

		case CB_MONITOR_READY:
			cliprdr_process_monitor_ready(cliprdr, s, dataLen, msgFlags);
			break;

		case CB_FORMAT_LIST:
			cliprdr_process_format_list(cliprdr, s, dataLen, msgFlags);
			break;

		case CB_FORMAT_LIST_RESPONSE:
			cliprdr_process_format_list_response(cliprdr, s, dataLen, msgFlags);
			break;

		case CB_FORMAT_DATA_REQUEST:
			cliprdr_process_format_data_request(cliprdr, s, dataLen, msgFlags);
			break;

		case CB_FORMAT_DATA_RESPONSE:
			cliprdr_process_format_data_response(cliprdr, s, dataLen, msgFlags);
			break;

		default:
			DEBUG_WARN("unknown msgType %d", msgType);
			break;
	}

	Stream_Free(s, TRUE);
}
Пример #18
0
static void wf_cliprdr_traverse_directory(cliprdrContext *cliprdr, wchar_t *Dir, int pathLen)
{
	WIN32_FIND_DATA FindFileData;
	HANDLE hFind;
	wchar_t DirSpec[MAX_PATH];

	StringCchCopy(DirSpec,MAX_PATH,Dir);
	StringCchCat(DirSpec,MAX_PATH,TEXT("\\*"));

	hFind = FindFirstFile(DirSpec,&FindFileData);

	if(hFind == INVALID_HANDLE_VALUE)
	{
		DEBUG_CLIPRDR("FindFirstFile failed with 0x%x.", GetLastError());
		return;
	}

	while(FindNextFile(hFind, &FindFileData))
	{
		if((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0
			&& wcscmp(FindFileData.cFileName,L".") == 0
			|| wcscmp(FindFileData.cFileName,L"..") == 0)
		{
			continue;
		}


		if((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) !=0 )
		{
			wchar_t DirAdd[MAX_PATH];

			StringCchCopy(DirAdd,MAX_PATH,Dir);
			StringCchCat(DirAdd,MAX_PATH,TEXT("\\"));
			StringCchCat(DirAdd,MAX_PATH,FindFileData.cFileName);
			wf_cliprdr_add_to_file_arrays(cliprdr, DirAdd, pathLen);
			wf_cliprdr_traverse_directory(cliprdr, DirAdd, pathLen);
		}
		else
		{
			WCHAR fileName[MAX_PATH];

			StringCchCopy(fileName,MAX_PATH,Dir);
			StringCchCat(fileName,MAX_PATH,TEXT("\\"));
			StringCchCat(fileName,MAX_PATH,FindFileData.cFileName);

			wf_cliprdr_add_to_file_arrays(cliprdr, fileName, pathLen);
		}
	}

	FindClose(hFind);
}
Пример #19
0
static void cliprdr_process_filecontents_request_event(cliprdrPlugin* plugin, RDP_CB_FILECONTENTS_REQUEST_EVENT* event)
{
	wStream* s;
	DEBUG_CLIPRDR("Sending File Contents Request.");
	s = cliprdr_packet_new(CB_FILECONTENTS_REQUEST, 0, 24);
	Stream_Write_UINT32(s, event->streamId);
	Stream_Write_UINT32(s, event->lindex);
	Stream_Write_UINT32(s, event->dwFlags);
	Stream_Write_UINT32(s, event->nPositionLow);
	Stream_Write_UINT32(s, event->nPositionHigh);
	Stream_Write_UINT32(s, event->cbRequested);
	//Stream_Write_UINT32(s, event->clipDataId);
	cliprdr_packet_send(plugin, s);
}
Пример #20
0
static void cliprdr_process_general_capability(cliprdrPlugin* cliprdr, wStream* s)
{
	UINT32 version;
	UINT32 generalFlags;
	CliprdrClientContext* context;
	context = cliprdr_get_client_interface(cliprdr);
	Stream_Read_UINT32(s, version); /* version (4 bytes) */
	Stream_Read_UINT32(s, generalFlags); /* generalFlags (4 bytes) */
	DEBUG_CLIPRDR("Version: %d", version);
#ifdef WITH_DEBUG_CLIPRDR
	cliprdr_print_general_capability_flags(generalFlags);
#endif

	if (generalFlags & CB_USE_LONG_FORMAT_NAMES)
		cliprdr->use_long_format_names = TRUE;

	if (generalFlags & CB_STREAM_FILECLIP_ENABLED)
		cliprdr->stream_fileclip_enabled = TRUE;

	if (generalFlags & CB_FILECLIP_NO_FILE_PATHS)
		cliprdr->fileclip_no_file_paths = TRUE;

	if (generalFlags & CB_CAN_LOCK_CLIPDATA)
		cliprdr->can_lock_clipdata = TRUE;

	cliprdr->received_caps = TRUE;

	if (context->custom)
	{
		CLIPRDR_CAPABILITIES capabilities;
		CLIPRDR_GENERAL_CAPABILITY_SET generalCapabilitySet;
		capabilities.cCapabilitiesSets = 1;
		capabilities.capabilitySets = (CLIPRDR_CAPABILITY_SET*) &(generalCapabilitySet);
		generalCapabilitySet.capabilitySetType = CB_CAPSTYPE_GENERAL;
		generalCapabilitySet.capabilitySetLength = 12;
		generalCapabilitySet.version = version;
		generalCapabilitySet.generalFlags = generalFlags;

		if (context->ServerCapabilities)
			context->ServerCapabilities(context, &capabilities);
	}
	else
	{
		RDP_CB_CLIP_CAPS* caps_event;
		caps_event = (RDP_CB_CLIP_CAPS*) freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_ClipCaps, NULL, NULL);
		caps_event->capabilities = generalFlags;
		svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) caps_event);
	}
}
Пример #21
0
static void cliprdr_process_receive(rdpSvcPlugin* plugin, STREAM* s)
{
	uint16 msgType;
	uint16 msgFlags;
	uint32 dataLen;
	cliprdrPlugin* cliprdr = (cliprdrPlugin*) plugin;

	stream_read_uint16(s, msgType);
	stream_read_uint16(s, msgFlags);
	stream_read_uint32(s, dataLen);

	DEBUG_CLIPRDR("msgType: %s (%d), msgFlags: %d dataLen: %d",
		CB_MSG_TYPE_STRINGS[msgType], msgType, msgFlags, dataLen);

	switch (msgType)
	{
		case CB_CLIP_CAPS:
			cliprdr_process_clip_caps(cliprdr, s, dataLen, msgFlags);
			break;

		case CB_MONITOR_READY:
			cliprdr_process_monitor_ready(cliprdr, s, dataLen, msgFlags);
			break;

		case CB_FORMAT_LIST:
			cliprdr_process_format_list(cliprdr, s, dataLen, msgFlags);
			break;

		case CB_FORMAT_LIST_RESPONSE:
			cliprdr_process_format_list_response(cliprdr, s, dataLen, msgFlags);
			break;

		case CB_FORMAT_DATA_REQUEST:
			cliprdr_process_format_data_request(cliprdr, s, dataLen, msgFlags);
			break;

		case CB_FORMAT_DATA_RESPONSE:
			cliprdr_process_format_data_response(cliprdr, s, dataLen, msgFlags);
			break;

		default:
			DEBUG_WARN("unknown msgType %d", msgType);
			break;
	}

	stream_free(s);
}
Пример #22
0
void cliprdr_process_format_data_response_event(cliprdrPlugin* cliprdr, RDP_CB_DATA_RESPONSE_EVENT* cb_event)
{
	wStream* s;

	DEBUG_CLIPRDR("Sending Format Data Response");

	if (cb_event->size > 0)
	{
		s = cliprdr_packet_new(CB_FORMAT_DATA_RESPONSE, CB_RESPONSE_OK, cb_event->size);
		Stream_Write(s, cb_event->data, cb_event->size);
	}
	else
	{
		s = cliprdr_packet_new(CB_FORMAT_DATA_RESPONSE, CB_RESPONSE_FAIL, 0);
	}

	cliprdr_packet_send(cliprdr, s);
}
Пример #23
0
static void cliprdr_process_filecontents_response_event(cliprdrPlugin* plugin, RDP_CB_FILECONTENTS_RESPONSE_EVENT* event)
{
	wStream* s;
	DEBUG_CLIPRDR("Sending file contents response with size = %d", event->size);

	if (event->size > 0)
	{
		s = cliprdr_packet_new(CB_FILECONTENTS_RESPONSE, CB_RESPONSE_OK, event->size + 4);
		Stream_Write_UINT32(s, event->streamId);
		Stream_Write(s, event->data, event->size);
	}
	else
	{
		s = cliprdr_packet_new(CB_FILECONTENTS_RESPONSE, CB_RESPONSE_FAIL, 0);
	}

	cliprdr_packet_send(plugin, s);
}
Пример #24
0
static void cliprdr_send_clip_caps(cliprdrPlugin* cliprdr)
{
	STREAM* s;
	uint32 flags;

	s = cliprdr_packet_new(CB_CLIP_CAPS, 0, 4 + CB_CAPSTYPE_GENERAL_LEN);

	DEBUG_CLIPRDR("Sending Capabilities");

	flags = CB_USE_LONG_FORMAT_NAMES;

	stream_write_uint16(s, 1); /* cCapabilitiesSets */
	stream_write_uint16(s, 0); /* pad1 */
	stream_write_uint16(s, CB_CAPSTYPE_GENERAL); /* capabilitySetType */
	stream_write_uint16(s, CB_CAPSTYPE_GENERAL_LEN); /* lengthCapability */
	stream_write_uint32(s, CB_CAPS_VERSION_2); /* version */
	stream_write_uint32(s, flags); /* generalFlags */

	cliprdr_packet_send(cliprdr, s);
}
Пример #25
0
static void cliprdr_send_clip_caps(cliprdrPlugin* cliprdr)
{
	wStream* s;
	UINT32 flags;
	s = cliprdr_packet_new(CB_CLIP_CAPS, 0, 4 + CB_CAPSTYPE_GENERAL_LEN);
	DEBUG_CLIPRDR("Sending Capabilities");
	flags = CB_USE_LONG_FORMAT_NAMES
#ifdef _WIN32
			| CB_STREAM_FILECLIP_ENABLED
			| CB_FILECLIP_NO_FILE_PATHS
#endif
			;
	Stream_Write_UINT16(s, 1); /* cCapabilitiesSets */
	Stream_Write_UINT16(s, 0); /* pad1 */
	Stream_Write_UINT16(s, CB_CAPSTYPE_GENERAL); /* capabilitySetType */
	Stream_Write_UINT16(s, CB_CAPSTYPE_GENERAL_LEN); /* lengthCapability */
	Stream_Write_UINT32(s, CB_CAPS_VERSION_2); /* version */
	Stream_Write_UINT32(s, flags); /* generalFlags */
	cliprdr_packet_send(cliprdr, s);
}
Пример #26
0
void cliprdr_process_format_list_event(cliprdrPlugin* cliprdr, RDP_CB_FORMAT_LIST_EVENT* cb_event)
{
	int i;
	STREAM* s;

	DEBUG_CLIPRDR("Sending Clipboard Format List");

	if (cb_event->raw_format_data)
	{
		s = cliprdr_packet_new(CB_FORMAT_LIST, 0, cb_event->raw_format_data_size);
		stream_write(s, cb_event->raw_format_data, cb_event->raw_format_data_size);
	}
	else
	{
		s = cliprdr_packet_new(CB_FORMAT_LIST, 0, 36 * cb_event->num_formats);

		for (i = 0; i < cb_event->num_formats; i++)
		{
			stream_write_uint32(s, cb_event->formats[i]);
			switch (cb_event->formats[i])
			{
				case CB_FORMAT_HTML:
					memcpy(stream_get_tail(s), CFSTR_HTML, sizeof(CFSTR_HTML));
					break;
				case CB_FORMAT_PNG:
					memcpy(stream_get_tail(s), CFSTR_PNG, sizeof(CFSTR_PNG));
					break;
				case CB_FORMAT_JPEG:
					memcpy(stream_get_tail(s), CFSTR_JPEG, sizeof(CFSTR_JPEG));
					break;
				case CB_FORMAT_GIF:
					memcpy(stream_get_tail(s), CFSTR_GIF, sizeof(CFSTR_GIF));
					break;
			}
			stream_seek(s, 32);
		}
	}

	cliprdr_packet_send(cliprdr, s);
}
Пример #27
0
static void wf_cliprdr_process_cb_format_list_event(wfContext *wfc, RDP_CB_FORMAT_LIST_EVENT *event)
{
	cliprdrContext *cliprdr = (cliprdrContext *)wfc->cliprdr_context;
	UINT32 left_size = event->raw_format_data_size;
	int i = 0;
	BYTE *p;
	BYTE* end_mark;
	BOOL format_forbidden = FALSE;

	/* ignore the formats member in event struct, only parsing raw_format_data */

	p = event->raw_format_data;
	end_mark = p + event->raw_format_data_size;

	clear_format_map(cliprdr);

	if ((cliprdr->capabilities & CAPS_USE_LONG_FORMAT_NAMES) != 0)
	{
		while (left_size >= 6)
		{
			formatMapping *map;
			BYTE* tmp;
			int name_len;

			map = &cliprdr->format_mappings[i++];

			Read_UINT32(p, map->remote_format_id);
			map->name = NULL;

			/* get name_len */
			for (tmp = p, name_len = 0; tmp + 1 < end_mark; tmp += 2, name_len += 2)
			{
				if (*((unsigned short*) tmp) == 0)
					break;
			}

			if (name_len > 0)
			{
				map->name = malloc(name_len + 2);
				memcpy(map->name, p, name_len + 2);

				map->local_format_id = RegisterClipboardFormatW((LPCWSTR)map->name);
			}
			else
			{
				map->local_format_id = map->remote_format_id;
			}

			left_size -= name_len + 4 + 2;
			p += name_len + 2;          /* p's already +4 when Read_UINT32() is called. */

			cliprdr->map_size++;

			map_ensure_capacity(cliprdr);
		}
	}
	else
	{
		int k;

		for (k = 0; k < event->raw_format_data_size / 36; k++)
		{
			formatMapping *map;
			int name_len;

			map = &cliprdr->format_mappings[i++];

			Read_UINT32(p, map->remote_format_id);
			map->name = NULL;

			if (event->raw_format_unicode)
			{
				/* get name_len, in bytes, if the file name is truncated, no terminated null will be included. */
				for (name_len = 0; name_len < 32; name_len += 2)
				{
					if (*((unsigned short*) (p + name_len)) == 0)
						break;
				}

				if (name_len > 0)
				{
					map->name = calloc(1, name_len + 2);
					memcpy(map->name, p, name_len);
					map->local_format_id = RegisterClipboardFormatW((LPCWSTR)map->name);
				}
				else
				{
					map->local_format_id = map->remote_format_id;
				}
			}
			else
			{
				/* get name_len, in bytes, if the file name is truncated, no terminated null will be included. */
				for (name_len = 0; name_len < 32; name_len += 1)
				{
					if (*((unsigned char*) (p + name_len)) == 0)
						break;
				}

				if (name_len > 0)
				{
					map->name = calloc(1, name_len + 1);
					memcpy(map->name, p, name_len);
					map->local_format_id = RegisterClipboardFormatA((LPCSTR)map->name);
				}
				else
				{
					map->local_format_id = map->remote_format_id;
				}
			}

			p += 32;          /* p's already +4 when Read_UINT32() is called. */
			cliprdr->map_size++;
			map_ensure_capacity(cliprdr);
		}
	}

	if (!OpenClipboard(cliprdr->hwndClipboard))
	{
		DEBUG_CLIPRDR("OpenClipboard failed with 0x%x", GetLastError());
		return;
	}

	if (!EmptyClipboard())
	{
		DEBUG_CLIPRDR("EmptyClipboard failed with 0x%x", GetLastError());
		CloseClipboard();
		return;
	}

	for (i = 0; i < cliprdr->map_size; i++)
	{
		SetClipboardData(cliprdr->format_mappings[i].local_format_id, NULL);
	}

	CloseClipboard();
}
Пример #28
0
static void wf_cliprdr_process_cb_data_request_event(wfContext *wfc, RDP_CB_DATA_REQUEST_EVENT *event)
{
	cliprdrContext *cliprdr = (cliprdrContext *)wfc->cliprdr_context;
	RDP_CB_DATA_RESPONSE_EVENT *responce_event;
	HANDLE hClipdata;
	int size = 0;
	char *buff = NULL;
	char *globlemem = NULL;
	UINT32 local_format;

	local_format = event->format;

	if (local_format == 0x9)			/* FORMAT_ID_PALETTE */
	{
		/* TODO: implement this */
		DEBUG_CLIPRDR("FORMAT_ID_PALETTE is not supported yet.");
	}
	else if (local_format == 0x3)		/* FORMAT_ID_MATEFILE */
	{
		/* TODO: implement this */
		DEBUG_CLIPRDR("FORMAT_ID_MATEFILE is not supported yet.");
	}
	else if (local_format == RegisterClipboardFormatW(L"FileGroupDescriptorW"))
	{
		/* TODO: implement this */
		DEBUG_CLIPRDR("FileGroupDescriptorW is not supported yet.");
	}
	else
	{
		if (!OpenClipboard(cliprdr->hwndClipboard))
		{
			DEBUG_CLIPRDR("OpenClipboard failed with 0x%x", GetLastError());
			return;
		}

		hClipdata = GetClipboardData(event->format);
		if (!hClipdata)
		{
			DEBUG_CLIPRDR("GetClipboardData failed.");
			CloseClipboard();
			return;
		}

		globlemem = (char *)GlobalLock(hClipdata);
		size = GlobalSize(hClipdata);

		buff = (char *)malloc(size);
		memcpy(buff, globlemem, size);

		GlobalUnlock(hClipdata);

		CloseClipboard();
	}

	responce_event = (RDP_CB_DATA_RESPONSE_EVENT *)freerdp_event_new(CliprdrChannel_Class,
			CliprdrChannel_DataResponse, NULL, NULL);

	responce_event->data = (BYTE *)buff;
	responce_event->size = size;

	freerdp_channels_send_event(cliprdr->channels, (wMessage *) responce_event);

	/* Note: don't free buff here. */
}
Пример #29
0
static LRESULT CALLBACK cliprdr_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
	static cliprdrContext *cliprdr = NULL;

	switch (Msg)
	{
		case WM_CREATE:
			cliprdr = (cliprdrContext *)((CREATESTRUCT *)lParam)->lpCreateParams;
			cliprdr->hwndNextViewer = SetClipboardViewer(hWnd);

			if (cliprdr->hwndNextViewer == NULL && GetLastError() != 0)
			{
				DEBUG_CLIPRDR("error: SetClipboardViewer failed with 0x%0x.", GetLastError());
			}
			cliprdr->hwndClipboard = hWnd;
			break;

		case WM_CLOSE:
			ChangeClipboardChain(hWnd, cliprdr->hwndNextViewer);
			break;

		case WM_CHANGECBCHAIN:
			if (cliprdr->hwndNextViewer == (HWND)wParam)
			{
				cliprdr->hwndNextViewer = (HWND)lParam;
			}
			else if (cliprdr->hwndNextViewer != NULL)
			{
				SendMessage(cliprdr->hwndNextViewer, Msg, wParam, lParam);
			}
			break;

		case WM_DRAWCLIPBOARD:
			if (cliprdr->channel_initialized)
			{
				if (GetClipboardOwner() != cliprdr->hwndClipboard)
				{
						if (!cliprdr->hmem)
						{
							cliprdr->hmem = GlobalFree(cliprdr->hmem);
						}
						cliprdr_send_format_list(cliprdr);
				}
			}
			if (cliprdr->hwndNextViewer != NULL && cliprdr->hwndNextViewer != hWnd)
				SendMessage(cliprdr->hwndNextViewer, Msg, wParam, lParam);
			break;

		case WM_RENDERALLFORMATS:
			/* discard all contexts in clipboard */
			if (!OpenClipboard(cliprdr->hwndClipboard))
			{
				DEBUG_CLIPRDR("OpenClipboard failed with 0x%x", GetLastError());
				break;
			}
			EmptyClipboard();
			CloseClipboard();
			break;

		case WM_RENDERFORMAT:
			if (cliprdr_send_data_request(cliprdr, (UINT32)wParam) != 0)
			{
				DEBUG_CLIPRDR("error: cliprdr_send_data_request failed.");
				break;
			}

			if (SetClipboardData(wParam, cliprdr->hmem) == NULL)
			{
				DEBUG_CLIPRDR("SetClipboardData failed with 0x%x", GetLastError());
				cliprdr->hmem = GlobalFree(cliprdr->hmem);
			}
			/* Note: GlobalFree() is not needed when success */
			break;

		case WM_CLIPBOARDUPDATE:
		case WM_DESTROYCLIPBOARD:
		case WM_ASKCBFORMATNAME:
		case WM_HSCROLLCLIPBOARD:
		case WM_PAINTCLIPBOARD:
		case WM_SIZECLIPBOARD:
		case WM_VSCROLLCLIPBOARD:
		default:
			return DefWindowProc(hWnd, Msg, wParam, lParam);
	}

	return 0;
}
Пример #30
0
static void cliprdr_send_format_list(cliprdrContext *cliprdr)
{
	RDP_CB_FORMAT_LIST_EVENT *cliprdr_event;
	BYTE *format_data;
	int format = 0;
	int data_size;
	int format_count;
	int len = 0;
	int namelen;

	if (!OpenClipboard(cliprdr->hwndClipboard))
	{
		DEBUG_CLIPRDR("OpenClipboard failed with 0x%x", GetLastError());
		return;
	}

	format_count = CountClipboardFormats();
	data_size = format_count * (4 + MAX_PATH * 2);

	format_data = (BYTE *)calloc(1, data_size);
	assert(format_data != NULL);

	while (format = EnumClipboardFormats(format))
	{
		Write_UINT32(format_data + len, format);
		len += 4;
		if ((cliprdr->capabilities & CAPS_USE_LONG_FORMAT_NAMES) != 0)
		{
			if (format >= CF_MAX)
			{
				namelen = GetClipboardFormatNameW(format, (LPWSTR)(format_data + len), MAX_PATH);
				len += namelen * sizeof(WCHAR);
			}
			len += 2;							/* end of Unicode string */
		}
		else
		{
			if (format >= CF_MAX)
			{
				static wchar_t wName[MAX_PATH] = {0};
				int wLen;

				ZeroMemory(wName, MAX_PATH*2);
				wLen = GetClipboardFormatNameW(format, wName, MAX_PATH);
				if (wLen < 16)
				{
					memcpy(format_data + len, wName, wLen * sizeof(WCHAR));
				}
				else
				{
					memcpy(format_data + len, wName, 32);	/* truncate the long name to 32 bytes */
				}
			}
			len += 32;
		}
	}

	CloseClipboard();

	cliprdr_event = (RDP_CB_FORMAT_LIST_EVENT *) freerdp_event_new(CliprdrChannel_Class,
			CliprdrChannel_FormatList, NULL, NULL);

	cliprdr_event->raw_format_data = (BYTE *)calloc(1, len);
	assert(cliprdr_event->raw_format_data != NULL);

	CopyMemory(cliprdr_event->raw_format_data, format_data, len);
	cliprdr_event->raw_format_data_size = len;

	free(format_data);

	freerdp_channels_send_event(cliprdr->channels, (wMessage *) cliprdr_event);
}