diff --git a/channels/cliprdr/client/cliprdr_main.c b/channels/cliprdr/client/cliprdr_main.c index 8238c2d32..1d7da6edb 100644 --- a/channels/cliprdr/client/cliprdr_main.c +++ b/channels/cliprdr/client/cliprdr_main.c @@ -867,12 +867,16 @@ static VOID VCAPITYPE cliprdr_virtual_channel_open_event_ex(LPVOID lpUserParam, { case CHANNEL_EVENT_DATA_RECEIVED: if ((error = cliprdr_virtual_channel_event_data_received(cliprdr, pData, dataLength, - totalLength, dataFlags))) - WLog_ERR(TAG, "failed with error %"PRIu32"", error); + totalLength, dataFlags))) + WLog_ERR(TAG, "failed with error %" PRIu32 "", error); break; case CHANNEL_EVENT_WRITE_COMPLETE: + { + wStream* s = (wStream*)lpUserParam; + Stream_Free(s, TRUE); + } break; case CHANNEL_EVENT_USER: diff --git a/channels/drdynvc/client/drdynvc_main.c b/channels/drdynvc/client/drdynvc_main.c index 31e0e0351..276c4adda 100644 --- a/channels/drdynvc/client/drdynvc_main.c +++ b/channels/drdynvc/client/drdynvc_main.c @@ -1272,6 +1272,10 @@ static void VCAPITYPE drdynvc_virtual_channel_open_event_ex(LPVOID lpUserParam, break; case CHANNEL_EVENT_WRITE_COMPLETE: + { + wStream* s = (wStream*)lpUserParam; + Stream_Free(s, TRUE); + } break; case CHANNEL_EVENT_USER: diff --git a/channels/encomsp/client/encomsp_main.c b/channels/encomsp/client/encomsp_main.c index 5e2d8d7cb..a7045694d 100644 --- a/channels/encomsp/client/encomsp_main.c +++ b/channels/encomsp/client/encomsp_main.c @@ -1003,6 +1003,10 @@ static VOID VCAPITYPE encomsp_virtual_channel_open_event_ex(LPVOID lpUserParam, break; case CHANNEL_EVENT_WRITE_COMPLETE: + { + wStream* s = (wStream*)lpUserParam; + Stream_Free(s, TRUE); + } break; case CHANNEL_EVENT_USER: diff --git a/channels/rail/client/rail_main.c b/channels/rail/client/rail_main.c index 12491c07a..95c601c6d 100644 --- a/channels/rail/client/rail_main.c +++ b/channels/rail/client/rail_main.c @@ -706,6 +706,10 @@ static VOID VCAPITYPE rail_virtual_channel_open_event_ex(LPVOID lpUserParam, DWO break; case CHANNEL_EVENT_WRITE_COMPLETE: + { + wStream* s = (wStream*)lpUserParam; + Stream_Free(s, TRUE); + } break; case CHANNEL_EVENT_USER: diff --git a/channels/rdp2tcp/client/rdp2tcp_main.c b/channels/rdp2tcp/client/rdp2tcp_main.c index b36a380fe..ac4ebdc14 100644 --- a/channels/rdp2tcp/client/rdp2tcp_main.c +++ b/channels/rdp2tcp/client/rdp2tcp_main.c @@ -160,7 +160,7 @@ static DWORD WINAPI copyThread(void* data) } if (plugin->channelEntryPoints.pVirtualChannelWriteEx(plugin->initHandle, plugin->openHandle, - buffer, dwRead, NULL) != CHANNEL_RC_OK) + buffer, dwRead, buffer) != CHANNEL_RC_OK) { free(buffer); fprintf(stderr, "rdp2tcp copyThread failed %i\n", (int)dwRead); @@ -234,6 +234,7 @@ static void VCAPITYPE VirtualChannelOpenEventEx(LPVOID lpUserParam, DWORD openHa case CHANNEL_EVENT_WRITE_COMPLETE: SetEvent(plugin->writeComplete); + free(lpUserParam); break; } } diff --git a/channels/rdpdr/client/rdpdr_main.c b/channels/rdpdr/client/rdpdr_main.c index d018e99de..4eff7ff99 100644 --- a/channels/rdpdr/client/rdpdr_main.c +++ b/channels/rdpdr/client/rdpdr_main.c @@ -1588,6 +1588,10 @@ static VOID VCAPITYPE rdpdr_virtual_channel_open_event_ex(LPVOID lpUserParam, DW break; case CHANNEL_EVENT_WRITE_COMPLETE: + { + wStream* s = (wStream*)lpUserParam; + Stream_Free(s, TRUE); + } break; case CHANNEL_EVENT_USER: diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index 862c96746..41002401e 100644 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -991,6 +991,10 @@ static VOID VCAPITYPE rdpsnd_virtual_channel_open_event_ex(LPVOID lpUserParam, D break; case CHANNEL_EVENT_WRITE_COMPLETE: + { + wStream* s = (wStream*)lpUserParam; + Stream_Free(s, TRUE); + } break; case CHANNEL_EVENT_USER: diff --git a/channels/remdesk/client/remdesk_main.c b/channels/remdesk/client/remdesk_main.c index 1fe668673..8601a1a39 100644 --- a/channels/remdesk/client/remdesk_main.c +++ b/channels/remdesk/client/remdesk_main.c @@ -786,6 +786,10 @@ static VOID VCAPITYPE remdesk_virtual_channel_open_event_ex(LPVOID lpUserParam, break; case CHANNEL_EVENT_WRITE_COMPLETE: + { + wStream* s = (wStream*)lpUserParam; + Stream_Free(s, TRUE); + } break; case CHANNEL_EVENT_USER: diff --git a/libfreerdp/core/client.c b/libfreerdp/core/client.c index 27bf95f2e..f140f38d4 100644 --- a/libfreerdp/core/client.c +++ b/libfreerdp/core/client.c @@ -38,6 +38,8 @@ static volatile LONG g_OpenHandleSeq = 1; /* use global counter to ensure uniqueness across channel manager instances */ static WINPR_TLS rdpChannelHandles g_ChannelHandles = { NULL, NULL }; +static BOOL freerdp_channels_process_message_free(wMessage* message); + static CHANNEL_OPEN_DATA* freerdp_channels_find_channel_open_data_by_name( rdpChannels* channels, const char* name) { @@ -84,21 +86,8 @@ static void channel_queue_message_free(wMessage* msg) return; ev = (CHANNEL_OPEN_EVENT*)msg->wParam; - - if (ev) - { - /* Added by FreeRDP_VirtualChannelWriteEx */ - if (ev->UserData) - { - wStream* s = (wStream*)ev->UserData; - Stream_Free(s, TRUE); - } - /* Either has no data or added by FreeRDP_VirtualChannelWrite */ - else - free(ev->Data); - - free(ev); - } + freerdp_channels_process_message_free(msg); + free(ev); } static void channel_queue_free(void* obj) @@ -453,6 +442,72 @@ int freerdp_channels_data(freerdp* instance, UINT16 channelId, BYTE* data, return 0; } +BOOL freerdp_channels_process_message_free(wMessage* message) +{ + if (message->id == WMQ_QUIT) + { + return FALSE; + } + + if (message->id == 0) + { + CHANNEL_OPEN_DATA* pChannelOpenData; + CHANNEL_OPEN_EVENT* item = (CHANNEL_OPEN_EVENT*)message->wParam; + + if (!item) + return FALSE; + + pChannelOpenData = item->pChannelOpenData; + + if (pChannelOpenData->pChannelOpenEventProc) + { + pChannelOpenData->pChannelOpenEventProc(pChannelOpenData->OpenHandle, + CHANNEL_EVENT_WRITE_COMPLETE, item->UserData, + item->DataLength, item->DataLength, 0); + } + else if (pChannelOpenData->pChannelOpenEventProcEx) + { + pChannelOpenData->pChannelOpenEventProcEx(pChannelOpenData->lpUserParam, + pChannelOpenData->OpenHandle, + CHANNEL_EVENT_WRITE_COMPLETE, item->UserData, + item->DataLength, item->DataLength, 0); + } + } + + return TRUE; +} + +static BOOL freerdp_channels_process_message(freerdp* instance, wMessage* message) +{ + if (message->id == WMQ_QUIT) + { + return FALSE; + } + + if (message->id == 0) + { + rdpMcsChannel* channel; + CHANNEL_OPEN_DATA* pChannelOpenData; + CHANNEL_OPEN_EVENT* item = (CHANNEL_OPEN_EVENT*)message->wParam; + + if (!item) + return FALSE; + + pChannelOpenData = item->pChannelOpenData; + channel = + freerdp_channels_find_channel_by_name(instance->context->rdp, pChannelOpenData->name); + + if (channel) + instance->SendChannelData(instance, channel->ChannelId, item->Data, item->DataLength); + } + + if (!freerdp_channels_process_message_free(message)) + return FALSE; + + IFCALL(message->Free, message); + return TRUE; +} + /** * called only from main thread */ @@ -461,46 +516,10 @@ static int freerdp_channels_process_sync(rdpChannels* channels, { int status = TRUE; wMessage message; - rdpMcsChannel* channel; - CHANNEL_OPEN_EVENT* item; - CHANNEL_OPEN_DATA* pChannelOpenData; while (MessageQueue_Peek(channels->queue, &message, TRUE)) { - if (message.id == WMQ_QUIT) - { - status = FALSE; - break; - } - - if (message.id == 0) - { - item = (CHANNEL_OPEN_EVENT*) message.wParam; - - if (!item) - break; - - pChannelOpenData = item->pChannelOpenData; - channel = freerdp_channels_find_channel_by_name(instance->context->rdp, pChannelOpenData->name); - - if (channel) - instance->SendChannelData(instance, channel->ChannelId, item->Data, item->DataLength); - - if (pChannelOpenData->pChannelOpenEventProc) - { - pChannelOpenData->pChannelOpenEventProc( - pChannelOpenData->OpenHandle, CHANNEL_EVENT_WRITE_COMPLETE, item->UserData, item->DataLength, - item->DataLength, 0); - } - else if (pChannelOpenData->pChannelOpenEventProcEx) - { - pChannelOpenData->pChannelOpenEventProcEx(pChannelOpenData->lpUserParam, - pChannelOpenData->OpenHandle, CHANNEL_EVENT_WRITE_COMPLETE, item->UserData, item->DataLength, - item->DataLength, 0); - } - } - - IFCALL(message.Free, &message); + freerdp_channels_process_message(instance, &message); } return status; @@ -1004,7 +1023,7 @@ static UINT VCAPITYPE FreeRDP_VirtualChannelWriteEx(LPVOID pInitHandle, DWORD op if (!MessageQueue_Dispatch(channels->queue, &message)) { - channel_queue_message_free(&message); + free(pChannelOpenEvent); return CHANNEL_RC_NO_MEMORY; } @@ -1057,7 +1076,7 @@ static UINT VCAPITYPE FreeRDP_VirtualChannelWrite(DWORD openHandle, if (!MessageQueue_Dispatch(channels->queue, &message)) { - channel_queue_message_free(&message); + free(pChannelOpenEvent); return CHANNEL_RC_NO_MEMORY; }