Fixed #4809: Properly process CHANNEL_EVENT_WRITE_COMPLETE

This commit is contained in:
Armin Novak
2019-10-28 14:57:39 +01:00
parent 09d14a2462
commit 1b78b59926
9 changed files with 105 additions and 57 deletions

View File

@@ -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:

View File

@@ -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:

View File

@@ -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:

View File

@@ -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:

View File

@@ -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;
}
}

View File

@@ -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:

View File

@@ -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:

View File

@@ -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:

View File

@@ -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;
}