Exemple #1
0
static int cliprdr_process_filecontents_response(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags)
{
	CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);

	WLog_Print(cliprdr->log, WLOG_DEBUG, "FileContentsResponse");

	if (context->custom)
	{
		CLIPRDR_FILE_CONTENTS_RESPONSE response;

		if (Stream_GetRemainingLength(s) < 4)
			return -1;

		response.msgType = CB_FILECONTENTS_RESPONSE;
		response.msgFlags = flags;
		response.dataLen = length;

		Stream_Read_UINT32(s, response.streamId); /* streamId (4 bytes) */
		
		response.cbRequested = length - 4;
		response.requestedData = Stream_Pointer(s); /* requestedFileContentsData */

		if (context->ServerFileContentsResponse)
			context->ServerFileContentsResponse(context, &response);
	}

	return 1;
}
void cliprdr_process_format_list_response(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags)
{
	CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);

	/* http://msdn.microsoft.com/en-us/library/hh872154.aspx */

	if (context->custom)
	{
		CLIPRDR_FORMAT_LIST_RESPONSE formatListResponse;

		formatListResponse.msgType = CB_FORMAT_LIST_RESPONSE;
		formatListResponse.msgFlags = msgFlags;
		formatListResponse.dataLen = dataLen;

		if (context->ServerFormatListResponse)
			context->ServerFormatListResponse(context, &formatListResponse);
	}
	else
	{
		if ((msgFlags & CB_RESPONSE_FAIL) != 0)
		{
			/* In case of an error the clipboard will not be synchronized with the server.
			 * Post this event to restart format negotiation and data transfer. */

			wMessage* event = freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_MonitorReady, NULL, NULL);
			svc_plugin_send_event((rdpSvcPlugin*) cliprdr, event);
		}
	}
}
Exemple #3
0
static int cliprdr_process_filecontents_request(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags)
{
	CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);

	WLog_Print(cliprdr->log, WLOG_DEBUG, "FileContentsRequest");

	if (context->custom)
	{
		CLIPRDR_FILE_CONTENTS_REQUEST request;

		if (Stream_GetRemainingLength(s) < 28)
			return -1;

		request.msgType = CB_FILECONTENTS_REQUEST;
		request.msgFlags = flags;
		request.dataLen = length;

		Stream_Read_UINT32(s, request.streamId); /* streamId (4 bytes) */
		Stream_Read_UINT32(s, request.listIndex); /* listIndex (4 bytes) */
		Stream_Read_UINT32(s, request.dwFlags); /* dwFlags (4 bytes) */
		Stream_Read_UINT32(s, request.nPositionLow); /* nPositionLow (4 bytes) */
		Stream_Read_UINT32(s, request.nPositionHigh); /* nPositionHigh (4 bytes) */
		Stream_Read_UINT32(s, request.cbRequested); /* cbRequested (4 bytes) */
		Stream_Read_UINT32(s, request.clipDataId); /* clipDataId (4 bytes) */

		if (context->ServerFileContentsRequest)
			context->ServerFileContentsRequest(context, &request);
	}

	return 1;
}
Exemple #4
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT cliprdr_process_unlock_clipdata(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags)
{
	CLIPRDR_UNLOCK_CLIPBOARD_DATA unlockClipboardData;
	CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
	UINT error = CHANNEL_RC_OK;

	WLog_Print(cliprdr->log, WLOG_DEBUG, "UnlockClipData");

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

	if (Stream_GetRemainingLength(s) < 4)
	{
		WLog_ERR(TAG, "not enought remaining data");
		return ERROR_INVALID_DATA;
	}

	unlockClipboardData.msgType = CB_UNLOCK_CLIPDATA;
	unlockClipboardData.msgFlags = flags;
	unlockClipboardData.dataLen = length;

	Stream_Read_UINT32(s, unlockClipboardData.clipDataId); /* clipDataId (4 bytes) */


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

	return error;
}
void cliprdr_process_format_data_request(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags)
{
	CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);

	if (context->custom)
	{
		CLIPRDR_FORMAT_DATA_REQUEST formatDataRequest;

		formatDataRequest.msgType = CB_FORMAT_DATA_REQUEST;
		formatDataRequest.msgFlags = msgFlags;
		formatDataRequest.dataLen = dataLen;

		Stream_Read_UINT32(s, formatDataRequest.requestedFormatId); /* requestedFormatId (4 bytes) */

		if (context->ServerFormatDataRequest)
			context->ServerFormatDataRequest(context, &formatDataRequest);
	}
	else
	{
		RDP_CB_DATA_REQUEST_EVENT* cb_event;

		cb_event = (RDP_CB_DATA_REQUEST_EVENT*) freerdp_event_new(CliprdrChannel_Class,
				CliprdrChannel_DataRequest, NULL, NULL);

		Stream_Read_UINT32(s, cb_event->format);
		svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event);
	}
}
Exemple #6
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
UINT cliprdr_process_format_data_request(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags)
{
	CLIPRDR_FORMAT_DATA_REQUEST formatDataRequest;
	CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
	UINT error = CHANNEL_RC_OK;

	WLog_Print(cliprdr->log, WLOG_DEBUG, "ServerFormatDataRequest");

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

	formatDataRequest.msgType = CB_FORMAT_DATA_REQUEST;
	formatDataRequest.msgFlags = msgFlags;
	formatDataRequest.dataLen = dataLen;

	Stream_Read_UINT32(s, formatDataRequest.requestedFormatId); /* requestedFormatId (4 bytes) */


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

	return error;
}
Exemple #7
0
static int cliprdr_process_unlock_clipdata(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags)
{
	CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);

	WLog_Print(cliprdr->log, WLOG_DEBUG, "UnlockClipData");

	if (context->custom)
	{
		CLIPRDR_UNLOCK_CLIPBOARD_DATA unlockClipboardData;

		if (Stream_GetRemainingLength(s) < 4)
			return -1;

		unlockClipboardData.msgType = CB_UNLOCK_CLIPDATA;
		unlockClipboardData.msgFlags = flags;
		unlockClipboardData.dataLen = length;

		Stream_Read_UINT32(s, unlockClipboardData.clipDataId); /* clipDataId (4 bytes) */

		if (context->ServerUnlockClipboardData)
			context->ServerUnlockClipboardData(context, &unlockClipboardData);
	}

	return 1;
}
Exemple #8
0
static void cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr, wStream* s, UINT16 length, UINT16 flags)
{
	CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);

	if (context->custom)
	{
		CLIPRDR_MONITOR_READY monitorReady;
		monitorReady.msgType = CB_MONITOR_READY;
		monitorReady.msgFlags = flags;
		monitorReady.dataLen = length;

		if (context->MonitorReady)
			context->MonitorReady(context, &monitorReady);
	}
	else
	{
		RDP_CB_MONITOR_READY_EVENT* event;

		if (cliprdr->received_caps)
			cliprdr_send_clip_caps(cliprdr);

		event = (RDP_CB_MONITOR_READY_EVENT*) freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_MonitorReady, NULL, NULL);
		svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) event);
	}
}
Exemple #9
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;
}
Exemple #10
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);
	}
}
Exemple #11
0
static int cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr, wStream* s, UINT16 length, UINT16 flags)
{
	CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);

	WLog_Print(cliprdr->log, WLOG_DEBUG, "MonitorReady");

	if (context->custom)
	{
		CLIPRDR_MONITOR_READY monitorReady;
		monitorReady.msgType = CB_MONITOR_READY;
		monitorReady.msgFlags = flags;
		monitorReady.dataLen = length;

		if (context->MonitorReady)
			context->MonitorReady(context, &monitorReady);
	}

	return 1;
}
void cliprdr_process_format_data_response(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags)
{
	CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
	
	if (context->custom)
	{
		CLIPRDR_FORMAT_DATA_RESPONSE formatDataResponse;
		
		formatDataResponse.msgType = CB_FORMAT_DATA_RESPONSE;
		formatDataResponse.msgFlags = msgFlags;
		formatDataResponse.dataLen = dataLen;
		formatDataResponse.requestedFormatData = NULL;
		
		if (dataLen)
		{
			formatDataResponse.requestedFormatData = (BYTE*) malloc(dataLen);
			Stream_Read(s, formatDataResponse.requestedFormatData, dataLen);
		}
		
		if (context->ClientFormatDataResponse)
			context->ClientFormatDataResponse(context, &formatDataResponse);
		
		free(formatDataResponse.requestedFormatData);
	}
	else
	{
		RDP_CB_DATA_RESPONSE_EVENT* cb_event;

		cb_event = (RDP_CB_DATA_RESPONSE_EVENT*) freerdp_event_new(CliprdrChannel_Class,
				CliprdrChannel_DataResponse, NULL, NULL);
	
		if (dataLen > 0)
		{
			cb_event->size = dataLen;
			cb_event->data = (BYTE*) malloc(dataLen);
			CopyMemory(cb_event->data, Stream_Pointer(s), dataLen);
		}

		svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event);
	}
}
Exemple #13
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT cliprdr_process_filecontents_request(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags)
{
	CLIPRDR_FILE_CONTENTS_REQUEST request;
	CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
	UINT error = CHANNEL_RC_OK;

	WLog_Print(cliprdr->log, WLOG_DEBUG, "FileContentsRequest");

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

	if (Stream_GetRemainingLength(s) < 28)
	{
		WLog_ERR(TAG, "not enought remaining data");
		return ERROR_INVALID_DATA;
	}

	request.msgType = CB_FILECONTENTS_REQUEST;
	request.msgFlags = flags;
	request.dataLen = length;

	Stream_Read_UINT32(s, request.streamId); /* streamId (4 bytes) */
	Stream_Read_UINT32(s, request.listIndex); /* listIndex (4 bytes) */
	Stream_Read_UINT32(s, request.dwFlags); /* dwFlags (4 bytes) */
	Stream_Read_UINT32(s, request.nPositionLow); /* nPositionLow (4 bytes) */
	Stream_Read_UINT32(s, request.nPositionHigh); /* nPositionHigh (4 bytes) */
	Stream_Read_UINT32(s, request.cbRequested); /* cbRequested (4 bytes) */
	Stream_Read_UINT32(s, request.clipDataId); /* clipDataId (4 bytes) */


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

	return error;
}
Exemple #14
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr, wStream* s, UINT16 length, UINT16 flags)
{
	CLIPRDR_MONITOR_READY monitorReady;
	CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
	UINT error = CHANNEL_RC_OK;

	WLog_Print(cliprdr->log, WLOG_DEBUG, "MonitorReady");

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

	if (!cliprdr->capabilitiesReceived)
	{
		/**
		  * The clipboard capabilities pdu from server to client is optional,
		  * but a server using it must send it before sending the monitor ready pdu.
		  * When the server capabilities pdu is not used, default capabilities
		  * corresponding to a generalFlags field set to zero are assumed.
		  */

		cliprdr->useLongFormatNames = FALSE;
		cliprdr->streamFileClipEnabled = FALSE;
		cliprdr->fileClipNoFilePaths = TRUE;
		cliprdr->canLockClipData = FALSE;
	}

	monitorReady.msgType = CB_MONITOR_READY;
	monitorReady.msgFlags = flags;
	monitorReady.dataLen = length;

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

	return error;
}
Exemple #15
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
UINT cliprdr_process_format_data_response(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags)
{
	CLIPRDR_FORMAT_DATA_RESPONSE formatDataResponse;
	CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
	UINT error = CHANNEL_RC_OK;

	WLog_Print(cliprdr->log, WLOG_DEBUG, "ServerFormatDataResponse");

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

	formatDataResponse.msgType = CB_FORMAT_DATA_RESPONSE;
	formatDataResponse.msgFlags = msgFlags;
	formatDataResponse.dataLen = dataLen;
	formatDataResponse.requestedFormatData = NULL;

	if (dataLen)
	{
		formatDataResponse.requestedFormatData = (BYTE*) malloc(dataLen);
		if (!formatDataResponse.requestedFormatData)
		{
			WLog_ERR(TAG, "malloc failed!");
			return CHANNEL_RC_NO_MEMORY;
		}
		Stream_Read(s, formatDataResponse.requestedFormatData, dataLen);
	}

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

	free(formatDataResponse.requestedFormatData);
	return error;
}
Exemple #16
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
UINT cliprdr_process_format_list_response(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags)
{
	CLIPRDR_FORMAT_LIST_RESPONSE formatListResponse;
	CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
	UINT error = CHANNEL_RC_OK;

	WLog_Print(cliprdr->log, WLOG_DEBUG, "ServerFormatListResponse");

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

	formatListResponse.msgType = CB_FORMAT_LIST_RESPONSE;
	formatListResponse.msgFlags = msgFlags;
	formatListResponse.dataLen = dataLen;

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

	return error;
}
Exemple #17
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT cliprdr_process_filecontents_response(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags)
{
	CLIPRDR_FILE_CONTENTS_RESPONSE response;
	CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
	UINT error = CHANNEL_RC_OK;

	WLog_Print(cliprdr->log, WLOG_DEBUG, "FileContentsResponse");

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

	if (Stream_GetRemainingLength(s) < 4)
	{
		WLog_ERR(TAG, "not enought remaining data");
		return ERROR_INVALID_DATA;
	}

	response.msgType = CB_FILECONTENTS_RESPONSE;
	response.msgFlags = flags;
	response.dataLen = length;

	Stream_Read_UINT32(s, response.streamId); /* streamId (4 bytes) */

	response.cbRequested = length - 4;
	response.requestedData = Stream_Pointer(s); /* requestedFileContentsData */


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

	return error;
}
void cliprdr_process_format_list(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags)
{
	CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);

	if (context->custom)
	{
		UINT32 index;
		int formatNameLength;
		CLIPRDR_FORMAT* formats;
		CLIPRDR_FORMAT_LIST formatList;

		formatList.msgType = CB_FORMAT_LIST;
		formatList.msgFlags = msgFlags;
		formatList.dataLen = dataLen;

		formatList.cFormats = 0;

		while (dataLen)
		{
			Stream_Seek(s, 4); /* formatId */
			dataLen -= 4;

			formatNameLength = _wcslen((WCHAR*) Stream_Pointer(s));
			Stream_Seek(s, (formatNameLength + 1) * 2);
			dataLen -= ((formatNameLength + 1) * 2);
			formatList.cFormats++;
		}

		index = 0;
		dataLen = formatList.dataLen;
		Stream_Rewind(s, dataLen);

		formats = (CLIPRDR_FORMAT*) malloc(sizeof(CLIPRDR_FORMAT) * formatList.cFormats);
		formatList.formats = formats;

		while (dataLen)
		{
			Stream_Read_UINT32(s, formats[index].formatId); /* formatId */
			dataLen -= 4;

			formats[index].formatName = NULL;
			formatNameLength = _wcslen((WCHAR*) Stream_Pointer(s));

			if (formatNameLength)
			{
				formatNameLength = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s),
					-1, &(formats[index].formatName), 0, NULL, NULL);

				Stream_Seek(s, formatNameLength * 2);
				dataLen -= (formatNameLength * 2);
			}
			else
			{
				Stream_Seek(s, 2);
				dataLen -= 2;
			}

			index++;
		}

		if (context->ServerFormatList)
			context->ServerFormatList(context, &formatList);

		for (index = 0; index < formatList.cFormats; index++)
			free(formats[index].formatName);

		free(formats);
	}
	else
	{
		int i;
		UINT32 format;
		BOOL supported;
		CLIPRDR_FORMAT_NAME* format_name;
		RDP_CB_FORMAT_LIST_EVENT* cb_event;

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

		if (dataLen > 0)
		{
			cb_event->raw_format_data = (BYTE*) malloc(dataLen);
			memcpy(cb_event->raw_format_data, Stream_Pointer(s), dataLen);
			cb_event->raw_format_data_size = dataLen;
			cb_event->raw_format_unicode = (msgFlags & CB_ASCII_NAMES) ? FALSE : TRUE;
		}

		if (cliprdr->use_long_format_names)
			cliprdr_process_long_format_names(cliprdr, s, dataLen, msgFlags);
		else
			cliprdr_process_short_format_names(cliprdr, s, dataLen, msgFlags);

		if (cliprdr->num_format_names > 0)
			cb_event->formats = (UINT32*) malloc(sizeof(UINT32) * cliprdr->num_format_names);

		cb_event->num_formats = 0;

		for (i = 0; i < cliprdr->num_format_names; i++)
		{
			supported = TRUE;
			format_name = &cliprdr->format_names[i];
			format = format_name->id;

			switch (format)
			{
				case CB_FORMAT_TEXT:
				case CB_FORMAT_DIB:
				case CB_FORMAT_UNICODETEXT:
					break;

				default:

					if (format_name->length > 0)
					{
						DEBUG_CLIPRDR("format: %s", format_name->name);

						if (strcmp(format_name->name, "HTML Format") == 0)
						{
							format = CB_FORMAT_HTML;
							break;
						}
						if (strcmp(format_name->name, "PNG") == 0)
						{
							format = CB_FORMAT_PNG;
							break;
						}
						if (strcmp(format_name->name, "JFIF") == 0)
						{
							format = CB_FORMAT_JPEG;
							break;
						}
						if (strcmp(format_name->name, "GIF") == 0)
						{
							format = CB_FORMAT_GIF;
							break;
						}
					}
					else
					{
						supported = FALSE;
					}

					break;
			}

			if (supported)
				cb_event->formats[cb_event->num_formats++] = format;

			if (format_name->length > 0)
				free(format_name->name);
		}

		free(cliprdr->format_names);
		cliprdr->format_names = NULL;

		cliprdr->num_format_names = 0;

		svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event);
		cliprdr_send_format_list_response(cliprdr);
	}
}
Exemple #19
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
UINT cliprdr_process_format_list(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags)
{
	UINT32 index;
	UINT32 position;
	BOOL asciiNames;
	int formatNameLength;
	char* szFormatName;
	WCHAR* wszFormatName;
	CLIPRDR_FORMAT* formats = NULL;
	CLIPRDR_FORMAT_LIST formatList;
	CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
	UINT error = CHANNEL_RC_OK;

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

	asciiNames = (msgFlags & CB_ASCII_NAMES) ? TRUE : FALSE;

	formatList.msgType = CB_FORMAT_LIST;
	formatList.msgFlags = msgFlags;
	formatList.dataLen = dataLen;

	index = 0;
	formatList.numFormats = 0;
	position = Stream_GetPosition(s);

	if (!formatList.dataLen)
	{
		/* empty format list */
		formatList.formats = NULL;
		formatList.numFormats = 0;
	}
	else if (!cliprdr->useLongFormatNames)
	{
		formatList.numFormats = (dataLen / 36);

		if ((formatList.numFormats * 36) != dataLen)
		{
			WLog_ERR(TAG, "Invalid short format list length: %d", dataLen);
			return ERROR_INTERNAL_ERROR;
		}

		if (formatList.numFormats)
			formats = (CLIPRDR_FORMAT*) calloc(formatList.numFormats, sizeof(CLIPRDR_FORMAT));

		if (!formats)
		{
			WLog_ERR(TAG, "calloc failed!");
			return CHANNEL_RC_NO_MEMORY;
		}

		formatList.formats = formats;

		while (dataLen)
		{
			Stream_Read_UINT32(s, formats[index].formatId); /* formatId (4 bytes) */
			dataLen -= 4;

			formats[index].formatName = NULL;

			if (asciiNames)
			{
				szFormatName = (char*) Stream_Pointer(s);

				if (szFormatName[0])
				{
					formats[index].formatName = (char*) malloc(32 + 1);
					if (!formats[index].formatName)
					{
						WLog_ERR(TAG, "calloc failed!");
						error = CHANNEL_RC_NO_MEMORY;
						goto error_out;
					}
					CopyMemory(formats[index].formatName, szFormatName, 32);
					formats[index].formatName[32] = '\0';
				}
			}
			else
			{
				wszFormatName = (WCHAR*) Stream_Pointer(s);

				if (wszFormatName[0])
				{
					ConvertFromUnicode(CP_UTF8, 0, wszFormatName,
						16, &(formats[index].formatName), 0, NULL, NULL);
				}
			}

			Stream_Seek(s, 32);
			dataLen -= 32;
			index++;
		}
	}
	else
	{
		while (dataLen)
		{
			Stream_Seek(s, 4); /* formatId (4 bytes) */
			dataLen -= 4;

			wszFormatName = (WCHAR*) Stream_Pointer(s);

			if (!wszFormatName[0])
				formatNameLength = 0;
			else
				formatNameLength = _wcslen(wszFormatName);

			Stream_Seek(s, (formatNameLength + 1) * 2);
			dataLen -= ((formatNameLength + 1) * 2);

			formatList.numFormats++;
		}

		dataLen = formatList.dataLen;
		Stream_SetPosition(s, position);

		if (formatList.numFormats)
			formats = (CLIPRDR_FORMAT*) calloc(formatList.numFormats, sizeof(CLIPRDR_FORMAT));

		if (!formats)
		{
			WLog_ERR(TAG, "calloc failed!");
			return CHANNEL_RC_NO_MEMORY;
		}

		formatList.formats = formats;

		while (dataLen)
		{
			Stream_Read_UINT32(s, formats[index].formatId); /* formatId (4 bytes) */
			dataLen -= 4;

			formats[index].formatName = NULL;

			wszFormatName = (WCHAR*) Stream_Pointer(s);

			if (!wszFormatName[0])
				formatNameLength = 0;
			else
				formatNameLength = _wcslen(wszFormatName);

			if (formatNameLength)
			{
				ConvertFromUnicode(CP_UTF8, 0, wszFormatName,
					-1, &(formats[index].formatName), 0, NULL, NULL);
			}

			Stream_Seek(s, (formatNameLength + 1) * 2);
			dataLen -= ((formatNameLength + 1) * 2);

			index++;
		}
	}

	WLog_Print(cliprdr->log, WLOG_DEBUG, "ServerFormatList: numFormats: %d",
			formatList.numFormats);

	if (context->ServerFormatList)
	{
		if ((error = context->ServerFormatList(context, &formatList)))
			WLog_ERR(TAG, "ServerFormatList failed with error %d", error);
	}

error_out:
	if (formats)
	{
		for (index = 0; index < formatList.numFormats; index++)
		{
			free(formats[index].formatName);
		}

		free(formats);
	}
	return error;
}