From 24a752a70840f3e4b027ba7c020af71f2bcfd94a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 12 Nov 2014 12:56:03 -0500 Subject: [PATCH] channels/cliprdr: remove dependency on deprecated eventing system, svc_plugin.c --- channels/cliprdr/client/cliprdr_format.c | 255 ---------------- channels/cliprdr/client/cliprdr_format.h | 5 - channels/cliprdr/client/cliprdr_main.c | 488 +++++++++++++++++-------------- channels/cliprdr/client/cliprdr_main.h | 17 +- 4 files changed, 280 insertions(+), 485 deletions(-) diff --git a/channels/cliprdr/client/cliprdr_format.c b/channels/cliprdr/client/cliprdr_format.c index c50e705..239a8ad 100644 --- a/channels/cliprdr/client/cliprdr_format.c +++ b/channels/cliprdr/client/cliprdr_format.c @@ -22,10 +22,6 @@ #include "config.h" #endif -#include -#include -#include - #include #include @@ -36,93 +32,6 @@ #include "cliprdr_main.h" #include "cliprdr_format.h" -#define CFSTR_HTML "H\0T\0M\0L\0 \0F\0o\0r\0m\0a\0t\0\0" -#define CFSTR_PNG "P\0N\0G\0\0" -#define CFSTR_JPEG "J\0F\0I\0F\0\0" -#define CFSTR_GIF "G\0I\0F\0\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, short_name_length = 32, x; - - 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) - { - x = (name_length > short_name_length) ? - name_length : short_name_length; - - Stream_EnsureRemainingCapacity(body, 4 + short_name_length); - Stream_Write_UINT32(body, cb_event->formats[i]); - Stream_Write(body, name, x); - - while (x++ < short_name_length) - Stream_Write(body, "\0", 1); - } - else - { - 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); -} - -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); -} - void cliprdr_process_short_format_names(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags) { int i; @@ -281,101 +190,6 @@ void cliprdr_process_format_list(cliprdrPlugin* cliprdr, wStream* s, UINT32 data 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 CF_TEXT: - case CF_DIB: - case CF_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; - - WLog_Print(cliprdr->log, WLOG_DEBUG, "ServerFormatList: numFormats: %d", - cb_event->num_formats); - - cliprdr_send_format_list_response(cliprdr); - svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event); - } } void cliprdr_process_format_list_response(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags) @@ -384,8 +198,6 @@ void cliprdr_process_format_list_response(cliprdrPlugin* cliprdr, wStream* s, UI WLog_Print(cliprdr->log, WLOG_DEBUG, "ServerFormatListResponse"); - /* http://msdn.microsoft.com/en-us/library/hh872154.aspx */ - if (context->custom) { CLIPRDR_FORMAT_LIST_RESPONSE formatListResponse; @@ -397,17 +209,6 @@ void cliprdr_process_format_list_response(cliprdrPlugin* cliprdr, wStream* s, UI 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); - } - } } void cliprdr_process_format_data_request(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags) @@ -429,46 +230,6 @@ void cliprdr_process_format_data_request(cliprdrPlugin* cliprdr, wStream* s, UIN 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); - } -} - -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); -} - -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); } void cliprdr_process_format_data_response(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags) @@ -497,20 +258,4 @@ void cliprdr_process_format_data_response(cliprdrPlugin* cliprdr, wStream* s, UI 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); - } } diff --git a/channels/cliprdr/client/cliprdr_format.h b/channels/cliprdr/client/cliprdr_format.h index 5454e02..8503830 100644 --- a/channels/cliprdr/client/cliprdr_format.h +++ b/channels/cliprdr/client/cliprdr_format.h @@ -21,14 +21,9 @@ #ifndef __CLIPRDR_FORMAT_H #define __CLIPRDR_FORMAT_H -void cliprdr_process_format_list_event(cliprdrPlugin* cliprdr, RDP_CB_FORMAT_LIST_EVENT* cb_event); void cliprdr_process_format_list(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags); void cliprdr_process_format_list_response(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags); - void cliprdr_process_format_data_request(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags); -void cliprdr_process_format_data_response_event(cliprdrPlugin* cliprdr, RDP_CB_DATA_RESPONSE_EVENT* cb_event); - -void cliprdr_process_format_data_request_event(cliprdrPlugin* cliprdr, RDP_CB_DATA_REQUEST_EVENT* cb_event); void cliprdr_process_format_data_response(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags); #endif /* __CLIPRDR_FORMAT_H */ diff --git a/channels/cliprdr/client/cliprdr_main.c b/channels/cliprdr/client/cliprdr_main.c index 3d6b18d..a481e9a 100644 --- a/channels/cliprdr/client/cliprdr_main.c +++ b/channels/cliprdr/client/cliprdr_main.c @@ -22,10 +22,6 @@ #include "config.h" #endif -#include -#include -#include - #include #include @@ -55,19 +51,22 @@ static const char* const CB_MSG_TYPE_STRINGS[] = CliprdrClientContext* cliprdr_get_client_interface(cliprdrPlugin* cliprdr) { CliprdrClientContext* pInterface; - rdpSvcPlugin* plugin = (rdpSvcPlugin*) cliprdr; - pInterface = (CliprdrClientContext*) plugin->channel_entry_points.pInterface; + pInterface = (CliprdrClientContext*) cliprdr->channelEntryPoints.pInterface; return pInterface; } wStream* cliprdr_packet_new(UINT16 msgType, UINT16 msgFlags, UINT32 dataLen) { wStream* s; + s = Stream_New(NULL, dataLen + 8); + Stream_Write_UINT16(s, msgType); Stream_Write_UINT16(s, msgFlags); + /* Write actual length after the entire packet has been constructed. */ Stream_Seek(s, 4); + return s; } @@ -75,21 +74,36 @@ void cliprdr_packet_send(cliprdrPlugin* cliprdr, wStream* s) { int pos; UINT32 dataLen; + UINT32 status = 0; + pos = Stream_GetPosition(s); + dataLen = pos - 8; + Stream_SetPosition(s, 4); Stream_Write_UINT32(s, dataLen); Stream_SetPosition(s, pos); + #ifdef WITH_DEBUG_CLIPRDR WLog_DBG(TAG, "Cliprdr Sending (%d bytes)", dataLen + 8); winpr_HexDump(TAG, WLOG_DEBUG, Stream_Buffer(s), dataLen + 8); #endif - svc_plugin_send((rdpSvcPlugin*) cliprdr, s); -} -static void cliprdr_process_connect(rdpSvcPlugin* plugin) -{ - DEBUG_CLIPRDR("connecting"); + if (!cliprdr) + { + status = CHANNEL_RC_BAD_INIT_HANDLE; + } + else + { + status = cliprdr->channelEntryPoints.pVirtualChannelWrite(cliprdr->OpenHandle, + Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); + } + + if (status != CHANNEL_RC_OK) + { + Stream_Free(s, TRUE); + WLog_ERR(TAG, "cliprdr_packet_send: VirtualChannelWrite failed %d", status); + } } void cliprdr_print_general_capability_flags(UINT32 flags) @@ -152,13 +166,6 @@ static int cliprdr_process_general_capability(cliprdrPlugin* cliprdr, wStream* s 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); - } return 1; } @@ -193,27 +200,6 @@ static int cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, wStream* s, UINT16 return 1; } -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); -} - static int cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr, wStream* s, UINT16 length, UINT16 flags) { CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr); @@ -230,16 +216,6 @@ static int cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr, wStream* s, UIN 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); - } return 1; } @@ -272,23 +248,6 @@ static int cliprdr_process_filecontents_request(cliprdrPlugin* cliprdr, wStream* if (context->ServerFileContentsRequest) context->ServerFileContentsRequest(context, &request); } - else - { - RDP_CB_FILECONTENTS_REQUEST_EVENT* cb_event; - - cb_event = (RDP_CB_FILECONTENTS_REQUEST_EVENT*) freerdp_event_new(CliprdrChannel_Class, - CliprdrChannel_FilecontentsRequest, NULL, NULL); - - Stream_Read_UINT32(s, cb_event->streamId); - Stream_Read_UINT32(s, cb_event->lindex); - Stream_Read_UINT32(s, cb_event->dwFlags); - Stream_Read_UINT32(s, cb_event->nPositionLow); - Stream_Read_UINT32(s, cb_event->nPositionHigh); - Stream_Read_UINT32(s, cb_event->cbRequested); - //Stream_Read_UINT32(s, cb_event->clipDataId); - - svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event); - } return 1; } @@ -318,24 +277,6 @@ static int cliprdr_process_filecontents_response(cliprdrPlugin* cliprdr, wStream if (context->ServerFileContentsResponse) context->ServerFileContentsResponse(context, &response); } - else - { - RDP_CB_FILECONTENTS_RESPONSE_EVENT* cb_event; - - cb_event = (RDP_CB_FILECONTENTS_RESPONSE_EVENT*) freerdp_event_new(CliprdrChannel_Class, - CliprdrChannel_FilecontentsResponse, NULL, NULL); - - Stream_Read_UINT32(s, cb_event->streamId); - - if (length > 0) - { - cb_event->size = length - 4; - cb_event->data = (BYTE*) malloc(cb_event->size); - CopyMemory(cb_event->data, Stream_Pointer(s), cb_event->size); - } - - svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event); - } return 1; } @@ -362,17 +303,6 @@ static int cliprdr_process_lock_clipdata(cliprdrPlugin* cliprdr, wStream* s, UIN if (context->ServerLockClipboardData) context->ServerLockClipboardData(context, &lockClipboardData); } - else - { - RDP_CB_LOCK_CLIPDATA_EVENT* cb_event; - - cb_event = (RDP_CB_LOCK_CLIPDATA_EVENT*) freerdp_event_new(CliprdrChannel_Class, - CliprdrChannel_LockClipdata, NULL, NULL); - - Stream_Read_UINT32(s, cb_event->clipDataId); - - svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event); - } return 1; } @@ -399,27 +329,16 @@ static int cliprdr_process_unlock_clipdata(cliprdrPlugin* cliprdr, wStream* s, U if (context->ServerUnlockClipboardData) context->ServerUnlockClipboardData(context, &unlockClipboardData); } - else - { - RDP_CB_UNLOCK_CLIPDATA_EVENT* cb_event; - - cb_event = (RDP_CB_UNLOCK_CLIPDATA_EVENT*) freerdp_event_new(CliprdrChannel_Class, - CliprdrChannel_UnLockClipdata, NULL, NULL); - - Stream_Read_UINT32(s, cb_event->clipDataId); - - svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event); - } return 1; } -static void cliprdr_process_receive(rdpSvcPlugin* plugin, wStream* s) +static void cliprdr_order_recv(cliprdrPlugin* cliprdr, 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); @@ -435,140 +354,47 @@ static void cliprdr_process_receive(rdpSvcPlugin* plugin, wStream* s) 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; - } -} - -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); -} - -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); -} - -static void cliprdr_process_lock_clipdata_event(cliprdrPlugin* plugin, RDP_CB_LOCK_CLIPDATA_EVENT* event) -{ - wStream* s; - DEBUG_CLIPRDR("Sending Lock Request"); - s = cliprdr_packet_new(CB_LOCK_CLIPDATA, 0, 4); - Stream_Write_UINT32(s, event->clipDataId); - cliprdr_packet_send(plugin, s); -} - -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); -} - -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); -} -static void cliprdr_process_event(rdpSvcPlugin* plugin, wMessage* event) -{ - switch (GetMessageType(event->id)) - { - case CliprdrChannel_FormatList: - cliprdr_process_format_list_event((cliprdrPlugin*) plugin, (RDP_CB_FORMAT_LIST_EVENT*) event); - break; - case CliprdrChannel_DataRequest: - cliprdr_process_format_data_request_event((cliprdrPlugin*) plugin, (RDP_CB_DATA_REQUEST_EVENT*) event); - break; - case CliprdrChannel_DataResponse: - cliprdr_process_format_data_response_event((cliprdrPlugin*) plugin, (RDP_CB_DATA_RESPONSE_EVENT*) event); - break; - case CliprdrChannel_FilecontentsRequest: - cliprdr_process_filecontents_request_event((cliprdrPlugin*) plugin, (RDP_CB_FILECONTENTS_REQUEST_EVENT*) event); - break; - case CliprdrChannel_FilecontentsResponse: - cliprdr_process_filecontents_response_event((cliprdrPlugin*) plugin, (RDP_CB_FILECONTENTS_RESPONSE_EVENT*) event); - break; - case CliprdrChannel_LockClipdata: - cliprdr_process_lock_clipdata_event((cliprdrPlugin*) plugin, (RDP_CB_LOCK_CLIPDATA_EVENT*) event); - break; - case CliprdrChannel_UnLockClipdata: - cliprdr_process_unlock_clipdata_event((cliprdrPlugin*) plugin, (RDP_CB_UNLOCK_CLIPDATA_EVENT*) event); - break; - case CliprdrChannel_TemporaryDirectory: - cliprdr_process_tempdir_event((cliprdrPlugin*) plugin, (RDP_CB_TEMPDIR_EVENT*) event); - break; default: - WLog_ERR(TAG, "unknown event type %d", GetMessageType(event->id)); + WLog_ERR(TAG, "unknown msgType %d", msgType); break; } - - freerdp_event_free(event); -} - -static void cliprdr_process_terminate(rdpSvcPlugin* plugin) -{ - svc_plugin_terminate(plugin); - free(plugin); } /** @@ -816,6 +642,216 @@ int cliprdr_client_file_contents_response(CliprdrClientContext* context, CLIPRDR return 1; } +/****************************************************************************************/ + +static wListDictionary* g_InitHandles; +static wListDictionary* g_OpenHandles; + +void cliprdr_add_init_handle_data(void* pInitHandle, void* pUserData) +{ + if (!g_InitHandles) + g_InitHandles = ListDictionary_New(TRUE); + + ListDictionary_Add(g_InitHandles, pInitHandle, pUserData); +} + +void* cliprdr_get_init_handle_data(void* pInitHandle) +{ + void* pUserData = NULL; + pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle); + return pUserData; +} + +void cliprdr_remove_init_handle_data(void* pInitHandle) +{ + ListDictionary_Remove(g_InitHandles, pInitHandle); +} + +void cliprdr_add_open_handle_data(DWORD openHandle, void* pUserData) +{ + void* pOpenHandle = (void*) (size_t) openHandle; + + if (!g_OpenHandles) + g_OpenHandles = ListDictionary_New(TRUE); + + ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData); +} + +void* cliprdr_get_open_handle_data(DWORD openHandle) +{ + void* pUserData = NULL; + void* pOpenHandle = (void*) (size_t) openHandle; + pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle); + return pUserData; +} + +void cliprdr_remove_open_handle_data(DWORD openHandle) +{ + void* pOpenHandle = (void*) (size_t) openHandle; + ListDictionary_Remove(g_OpenHandles, pOpenHandle); +} + +static void cliprdr_virtual_channel_event_data_received(cliprdrPlugin* cliprdr, + void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) +{ + wStream* data_in; + + if ((dataFlags & CHANNEL_FLAG_SUSPEND) || (dataFlags & CHANNEL_FLAG_RESUME)) + { + return; + } + + if (dataFlags & CHANNEL_FLAG_FIRST) + { + if (cliprdr->data_in) + Stream_Free(cliprdr->data_in, TRUE); + + cliprdr->data_in = Stream_New(NULL, totalLength); + } + + data_in = cliprdr->data_in; + Stream_EnsureRemainingCapacity(data_in, (int) dataLength); + Stream_Write(data_in, pData, dataLength); + + if (dataFlags & CHANNEL_FLAG_LAST) + { + if (Stream_Capacity(data_in) != Stream_GetPosition(data_in)) + { + WLog_ERR(TAG, "cliprdr_plugin_process_received: read error"); + } + + cliprdr->data_in = NULL; + Stream_SealLength(data_in); + Stream_SetPosition(data_in, 0); + + MessageQueue_Post(cliprdr->MsgPipe->In, NULL, 0, (void*) data_in, NULL); + } +} + +static VOID VCAPITYPE cliprdr_virtual_channel_open_event(DWORD openHandle, UINT event, + LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) +{ + cliprdrPlugin* cliprdr; + + cliprdr = (cliprdrPlugin*) cliprdr_get_open_handle_data(openHandle); + + if (!cliprdr) + { + WLog_ERR(TAG, "cliprdr_virtual_channel_open_event: error no match"); + return; + } + + switch (event) + { + case CHANNEL_EVENT_DATA_RECEIVED: + cliprdr_virtual_channel_event_data_received(cliprdr, pData, dataLength, totalLength, dataFlags); + break; + + case CHANNEL_EVENT_WRITE_COMPLETE: + Stream_Free((wStream*) pData, TRUE); + break; + + case CHANNEL_EVENT_USER: + break; + } +} + +static void* cliprdr_virtual_channel_client_thread(void* arg) +{ + wStream* data; + wMessage message; + cliprdrPlugin* cliprdr = (cliprdrPlugin*) arg; + + while (1) + { + if (!MessageQueue_Wait(cliprdr->MsgPipe->In)) + break; + + if (MessageQueue_Peek(cliprdr->MsgPipe->In, &message, TRUE)) + { + if (message.id == WMQ_QUIT) + break; + + if (message.id == 0) + { + data = (wStream*) message.wParam; + cliprdr_order_recv(cliprdr, data); + } + } + } + + ExitThread(0); + return NULL; +} + +static void cliprdr_virtual_channel_event_connected(cliprdrPlugin* cliprdr, LPVOID pData, UINT32 dataLength) +{ + UINT32 status; + + status = cliprdr->channelEntryPoints.pVirtualChannelOpen(cliprdr->InitHandle, + &cliprdr->OpenHandle, cliprdr->channelDef.name, cliprdr_virtual_channel_open_event); + + cliprdr_add_open_handle_data(cliprdr->OpenHandle, cliprdr); + + if (status != CHANNEL_RC_OK) + { + WLog_ERR(TAG, "cliprdr_virtual_channel_event_connected: open failed: status: %d", status); + return; + } + + cliprdr->MsgPipe = MessagePipe_New(); + + cliprdr->thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) cliprdr_virtual_channel_client_thread, (void*) cliprdr, 0, NULL); +} + +static void cliprdr_virtual_channel_event_terminated(cliprdrPlugin* cliprdr) +{ + MessagePipe_PostQuit(cliprdr->MsgPipe, 0); + WaitForSingleObject(cliprdr->thread, INFINITE); + + MessagePipe_Free(cliprdr->MsgPipe); + CloseHandle(cliprdr->thread); + + cliprdr->channelEntryPoints.pVirtualChannelClose(cliprdr->OpenHandle); + + if (cliprdr->data_in) + { + Stream_Free(cliprdr->data_in, TRUE); + cliprdr->data_in = NULL; + } + + cliprdr_remove_open_handle_data(cliprdr->OpenHandle); + cliprdr_remove_init_handle_data(cliprdr->InitHandle); +} + +static VOID VCAPITYPE cliprdr_virtual_channel_init_event(LPVOID pInitHandle, UINT event, LPVOID pData, UINT dataLength) +{ + cliprdrPlugin* cliprdr; + + cliprdr = (cliprdrPlugin*) cliprdr_get_init_handle_data(pInitHandle); + + if (!cliprdr) + { + WLog_ERR(TAG, "cliprdr_virtual_channel_init_event: error no match"); + return; + } + + switch (event) + { + case CHANNEL_EVENT_CONNECTED: + cliprdr_virtual_channel_event_connected(cliprdr, pData, dataLength); + break; + + case CHANNEL_EVENT_DISCONNECTED: + break; + + case CHANNEL_EVENT_TERMINATED: + cliprdr_virtual_channel_event_terminated(cliprdr); + break; + } +} + /* cliprdr is always built-in */ #define VirtualChannelEntry cliprdr_VirtualChannelEntry @@ -827,20 +863,13 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) cliprdr = (cliprdrPlugin*) calloc(1, sizeof(cliprdrPlugin)); - cliprdr->plugin.channel_def.options = + cliprdr->channelDef.options = CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP | CHANNEL_OPTION_COMPRESS_RDP | CHANNEL_OPTION_SHOW_PROTOCOL; - strcpy(cliprdr->plugin.channel_def.name, "cliprdr"); - - cliprdr->log = WLog_Get("com.freerdp.channels.cliprdr.client"); - - cliprdr->plugin.connect_callback = cliprdr_process_connect; - cliprdr->plugin.receive_callback = cliprdr_process_receive; - cliprdr->plugin.event_callback = cliprdr_process_event; - cliprdr->plugin.terminate_callback = cliprdr_process_terminate; + strcpy(cliprdr->channelDef.name, "cliprdr"); pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints; @@ -848,7 +877,10 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) { context = (CliprdrClientContext*) calloc(1, sizeof(CliprdrClientContext)); + context->handle = (void*) cliprdr; + context->custom = NULL; + context->ClientCapabilities = cliprdr_client_capabilities; context->TempDirectory = cliprdr_temp_directory; context->ClientFormatList = cliprdr_client_format_list; @@ -859,9 +891,23 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) context->ClientFormatDataResponse = cliprdr_client_format_data_response; context->ClientFileContentsRequest = cliprdr_client_file_contents_request; context->ClientFileContentsResponse = cliprdr_client_file_contents_response; + *(pEntryPointsEx->ppInterface) = (void*) context; } - svc_plugin_init((rdpSvcPlugin*) cliprdr, pEntryPoints); + cliprdr->log = WLog_Get("com.freerdp.channels.cliprdr.client"); + + WLog_Print(cliprdr->log, WLOG_DEBUG, "VirtualChannelEntry"); + + CopyMemory(&(cliprdr->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); + + cliprdr->channelEntryPoints.pVirtualChannelInit(&cliprdr->InitHandle, + &cliprdr->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, cliprdr_virtual_channel_init_event); + + cliprdr->channelEntryPoints.pInterface = *(cliprdr->channelEntryPoints.ppInterface); + cliprdr->channelEntryPoints.ppInterface = &(cliprdr->channelEntryPoints.pInterface); + + cliprdr_add_init_handle_data(cliprdr->InitHandle, (void*) cliprdr); + return 1; } diff --git a/channels/cliprdr/client/cliprdr_main.h b/channels/cliprdr/client/cliprdr_main.h index 050de26..28ff62d 100644 --- a/channels/cliprdr/client/cliprdr_main.h +++ b/channels/cliprdr/client/cliprdr_main.h @@ -23,23 +23,32 @@ #include +#include +#include #include -#include #define TAG CHANNELS_TAG("cliprdr.client") struct cliprdr_plugin { - rdpSvcPlugin plugin; + CHANNEL_DEF channelDef; + CHANNEL_ENTRY_POINTS_FREERDP channelEntryPoints; wLog* log; + HANDLE thread; + wStream* data_in; + void* InitHandle; + DWORD OpenHandle; + wMessagePipe* MsgPipe; + + int num_format_names; + CLIPRDR_FORMAT_NAME* format_names; + BOOL received_caps; BOOL use_long_format_names; BOOL stream_fileclip_enabled; BOOL fileclip_no_file_paths; BOOL can_lock_clipdata; - CLIPRDR_FORMAT_NAME* format_names; - int num_format_names; }; typedef struct cliprdr_plugin cliprdrPlugin; -- 2.7.4