From abf7c29910232e0f7a8f27416c9b8b1f2307af07 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Mon, 18 May 2020 14:20:11 +0200 Subject: [PATCH] Extend lifetime of streampool in drdynvc The stream pool can not be released until all streams have been returned. This might happen as late as channel termination, so change the lifetime scope accordingly. --- channels/drdynvc/client/drdynvc_main.c | 72 ++++++++++++++++---------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/channels/drdynvc/client/drdynvc_main.c b/channels/drdynvc/client/drdynvc_main.c index 2a17358bd..d3f8fa2dd 100644 --- a/channels/drdynvc/client/drdynvc_main.c +++ b/channels/drdynvc/client/drdynvc_main.c @@ -1407,6 +1407,40 @@ static void drdynvc_queue_object_free(void* obj) Stream_Release(s); } +static UINT drdynvc_virtual_channel_event_initialized(drdynvcPlugin* drdynvc, LPVOID pData, + UINT32 dataLength) +{ + UINT error = CHANNEL_RC_OK; + WINPR_UNUSED(pData); + WINPR_UNUSED(dataLength); + + if (!drdynvc) + goto error; + + drdynvc->queue = MessageQueue_New(NULL); + + if (!drdynvc->queue) + { + error = CHANNEL_RC_NO_MEMORY; + WLog_Print(drdynvc->log, WLOG_ERROR, "MessageQueue_New failed!"); + goto error; + } + + drdynvc->queue->object.fnObjectFree = drdynvc_queue_object_free; + drdynvc->channel_mgr = dvcman_new(drdynvc); + + if (!drdynvc->channel_mgr) + { + error = CHANNEL_RC_NO_MEMORY; + WLog_Print(drdynvc->log, WLOG_ERROR, "dvcman_new failed!"); + goto error; + } + + return CHANNEL_RC_OK; +error: + return ERROR_INTERNAL_ERROR; +} + /** * Function description * @@ -1438,25 +1472,6 @@ static UINT drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc, LPVO return status; } - drdynvc->queue = MessageQueue_New(NULL); - - if (!drdynvc->queue) - { - error = CHANNEL_RC_NO_MEMORY; - WLog_Print(drdynvc->log, WLOG_ERROR, "MessageQueue_New failed!"); - goto error; - } - - drdynvc->queue->object.fnObjectFree = drdynvc_queue_object_free; - drdynvc->channel_mgr = dvcman_new(drdynvc); - - if (!drdynvc->channel_mgr) - { - error = CHANNEL_RC_NO_MEMORY; - WLog_Print(drdynvc->log, WLOG_ERROR, "dvcman_new failed!"); - goto error; - } - settings = (rdpSettings*)drdynvc->channelEntryPoints.pExtendedData; for (index = 0; index < settings->DynamicChannelCount; index++) @@ -1519,10 +1534,9 @@ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc) return status; } - MessageQueue_Free(drdynvc->queue); CloseHandle(drdynvc->thread); - drdynvc->queue = NULL; drdynvc->thread = NULL; + status = drdynvc->channelEntryPoints.pVirtualChannelCloseEx(drdynvc->InitHandle, drdynvc->OpenHandle); @@ -1540,12 +1554,6 @@ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc) drdynvc->data_in = NULL; } - if (drdynvc->channel_mgr) - { - dvcman_free(drdynvc, drdynvc->channel_mgr); - drdynvc->channel_mgr = NULL; - } - return status; } @@ -1559,6 +1567,13 @@ static UINT drdynvc_virtual_channel_event_terminated(drdynvcPlugin* drdynvc) if (!drdynvc) return CHANNEL_RC_BAD_CHANNEL_HANDLE; + if (drdynvc->channel_mgr) + { + dvcman_free(drdynvc, drdynvc->channel_mgr); + drdynvc->channel_mgr = NULL; + } + MessageQueue_Free(drdynvc->queue); + drdynvc->queue = NULL; drdynvc->InitHandle = 0; free(drdynvc->context); free(drdynvc); @@ -1645,6 +1660,9 @@ static VOID VCAPITYPE drdynvc_virtual_channel_init_event_ex(LPVOID lpUserParam, switch (event) { + case CHANNEL_EVENT_INITIALIZED: + error = drdynvc_virtual_channel_event_initialized(drdynvc, pData, dataLength); + break; case CHANNEL_EVENT_CONNECTED: if ((error = drdynvc_virtual_channel_event_connected(drdynvc, pData, dataLength))) WLog_Print(drdynvc->log, WLOG_ERROR,