diff --git a/channels/drdynvc/client/dvcman.c b/channels/drdynvc/client/dvcman.c index a831bf6eb..bd3718a60 100644 --- a/channels/drdynvc/client/dvcman.c +++ b/channels/drdynvc/client/dvcman.c @@ -475,7 +475,7 @@ int dvcman_receive_channel_data_first(IWTSVirtualChannelManager* pChannelMgr, UI int dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId, wStream* data) { - int error = 0; + int status = 0; DVCMAN_CHANNEL* channel; UINT32 dataSize = Stream_GetRemainingLength(data); @@ -504,16 +504,16 @@ int dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, UINT32 C { Stream_SealLength(channel->dvc_data); Stream_SetPosition(channel->dvc_data, 0); - error = channel->channel_callback->OnDataReceived(channel->channel_callback, channel->dvc_data); + status = channel->channel_callback->OnDataReceived(channel->channel_callback, channel->dvc_data); Stream_Release(channel->dvc_data); channel->dvc_data = NULL; } } else { - error = channel->channel_callback->OnDataReceived(channel->channel_callback, data); + status = channel->channel_callback->OnDataReceived(channel->channel_callback, data); } - return error; + return status; } diff --git a/channels/rdpgfx/client/rdpgfx_main.c b/channels/rdpgfx/client/rdpgfx_main.c index 0bb29bb8c..032b51b81 100644 --- a/channels/rdpgfx/client/rdpgfx_main.c +++ b/channels/rdpgfx/client/rdpgfx_main.c @@ -210,6 +210,8 @@ int rdpgfx_recv_reset_graphics_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s context->ResetGraphics(context, &pdu); } + free(pdu.monitorDefArray); + return 1; } @@ -595,6 +597,8 @@ int rdpgfx_recv_cache_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* context->CacheToSurface(context, &pdu); } + free(pdu.destPts); + return 1; } @@ -850,7 +854,11 @@ static int rdpgfx_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManag static int rdpgfx_plugin_terminated(IWTSPlugin* pPlugin) { + int count; + int index; + ULONG_PTR* pKeys = NULL; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) pPlugin; + RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface; WLog_Print(gfx->log, WLOG_DEBUG, "Terminated"); @@ -859,8 +867,41 @@ static int rdpgfx_plugin_terminated(IWTSPlugin* pPlugin) zgfx_context_free(gfx->zgfx); + count = HashTable_GetKeys(gfx->SurfaceTable, &pKeys); + + for (index = 0; index < count; index++) + { + RDPGFX_DELETE_SURFACE_PDU pdu; + + pdu.surfaceId = ((UINT16) pKeys[index]) - 1; + + if (context && context->DeleteSurface) + { + context->DeleteSurface(context, &pdu); + } + } + + free(pKeys); + HashTable_Free(gfx->SurfaceTable); + for (index = 0; index < gfx->MaxCacheSlot; index++) + { + if (gfx->CacheSlots[index]) + { + RDPGFX_EVICT_CACHE_ENTRY_PDU pdu; + + pdu.cacheSlot = (UINT16) index; + + if (context && context->EvictCacheEntry) + { + context->EvictCacheEntry(context, &pdu); + } + + gfx->CacheSlots[index] = NULL; + } + } + free(gfx); return 0; diff --git a/client/X11/xf_channels.c b/client/X11/xf_channels.c index b00130c24..9bb36152e 100644 --- a/client/X11/xf_channels.c +++ b/client/X11/xf_channels.c @@ -38,11 +38,20 @@ void xf_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEven } else if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0) { - xf_register_graphics_pipeline(xfc, (RdpgfxClientContext*) e->pInterface); + xf_graphics_pipeline_init(xfc, (RdpgfxClientContext*) e->pInterface); } } void xf_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnectedEventArgs* e) { + xfContext* xfc = (xfContext*) context; + if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0) + { + xfc->rdpei = NULL; + } + else if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0) + { + xf_graphics_pipeline_uninit(xfc, (RdpgfxClientContext*) e->pInterface); + } } diff --git a/client/X11/xf_gfx.c b/client/X11/xf_gfx.c index 35288c515..fec5036b8 100644 --- a/client/X11/xf_gfx.c +++ b/client/X11/xf_gfx.c @@ -610,7 +610,7 @@ int xf_EvictCacheEntry(RdpgfxClientContext* context, RDPGFX_EVICT_CACHE_ENTRY_PD { xfGfxCacheEntry* cacheEntry; - printf("xf_EvictCacheEntry\n"); + //printf("xf_EvictCacheEntry\n"); cacheEntry = (xfGfxCacheEntry*) context->GetCacheSlotData(context, evictCacheEntry->cacheSlot); @@ -639,7 +639,7 @@ int xf_MapSurfaceToWindow(RdpgfxClientContext* context, RDPGFX_MAP_SURFACE_TO_WI return 1; } -void xf_register_graphics_pipeline(xfContext* xfc, RdpgfxClientContext* gfx) +void xf_graphics_pipeline_init(xfContext* xfc, RdpgfxClientContext* gfx) { xfc->gfx = gfx; gfx->custom = (void*) xfc; @@ -662,3 +662,11 @@ void xf_register_graphics_pipeline(xfContext* xfc, RdpgfxClientContext* gfx) region16_init(&(xfc->invalidRegion)); } + +void xf_graphics_pipeline_uninit(xfContext* xfc, RdpgfxClientContext* gfx) +{ + region16_uninit(&(xfc->invalidRegion)); + + gfx->custom = NULL; + xfc->gfx = NULL; +} diff --git a/client/X11/xf_gfx.h b/client/X11/xf_gfx.h index 3a95d33e0..ba937ee92 100644 --- a/client/X11/xf_gfx.h +++ b/client/X11/xf_gfx.h @@ -48,6 +48,7 @@ typedef struct xf_gfx_cache_entry xfGfxCacheEntry; int xf_OutputExpose(xfContext* xfc, int x, int y, int width, int height); -void xf_register_graphics_pipeline(xfContext* xfc, RdpgfxClientContext* gfx); +void xf_graphics_pipeline_init(xfContext* xfc, RdpgfxClientContext* gfx); +void xf_graphics_pipeline_uninit(xfContext* xfc, RdpgfxClientContext* gfx); #endif /* __XF_GRAPHICS_PIPELINE_H */ diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index ba42368da..682c0cfca 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -822,25 +822,33 @@ BOOL xf_IsWindowBorder(xfContext *xfc, xfWindow *xfw, int x, int y) void xf_DestroyWindow(xfContext *xfc, xfWindow *window) { - if(window == NULL) + if (!window) return; - if(xfc->window == window) + + if (xfc->window == window) xfc->window = NULL; - if(window->gc) + + if (window->gc) XFreeGC(xfc->display, window->gc); - if(window->handle) + + if (window->handle) { XUnmapWindow(xfc->display, window->handle); XDestroyWindow(xfc->display, window->handle); } - free(window); - if(window->xfwin) + + if (window->xfwin) munmap(0, sizeof(*window->xfwin)); - if(window->shmid >= 0) + + if (window->shmid >= 0) close(window->shmid); + shm_unlink(get_shm_id()); + window->xfwin = -1; window->shmid = -1; + + free(window); } rdpWindow *xf_rdpWindowFromWindow(xfContext *xfc, Window wnd) diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index 8f1455b81..e04230f37 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -517,11 +517,16 @@ out_free: void freerdp_dynamic_channel_collection_free(rdpSettings* settings) { - UINT32 index; + int j; + UINT32 i; - for (index = 0; index < settings->DynamicChannelCount; index++) + for (i = 0; i < settings->DynamicChannelCount; i++) { - free(settings->DynamicChannelArray[index]); + for (j = 0; j < settings->DynamicChannelArray[i]->argc; j++) + free(settings->DynamicChannelArray[i]->argv[j]); + + free(settings->DynamicChannelArray[i]->argv); + free(settings->DynamicChannelArray[i]); } free(settings->DynamicChannelArray); diff --git a/libfreerdp/utils/svc_plugin.c b/libfreerdp/utils/svc_plugin.c index b5787438a..7a529d256 100644 --- a/libfreerdp/utils/svc_plugin.c +++ b/libfreerdp/utils/svc_plugin.c @@ -179,6 +179,7 @@ static void* svc_plugin_thread_func(void* arg) IFCALL(plugin->connect_callback, plugin); SetEvent(plugin->started); + while (1) { if (!MessageQueue_Wait(plugin->MsgPipe->In)) @@ -238,7 +239,12 @@ static void svc_plugin_process_terminated(rdpSvcPlugin* plugin) MessagePipe_Free(plugin->MsgPipe); CloseHandle(plugin->thread); - CloseHandle(plugin->started); + + if (plugin->started) + { + CloseHandle(plugin->started); + plugin->started = NULL; + } plugin->channel_entry_points.pVirtualChannelClose(plugin->OpenHandle); @@ -248,10 +254,10 @@ static void svc_plugin_process_terminated(rdpSvcPlugin* plugin) plugin->data_in = NULL; } - IFCALL(plugin->terminate_callback, plugin); - svc_plugin_remove_open_handle_data(plugin->OpenHandle); svc_plugin_remove_init_handle_data(plugin->InitHandle); + + IFCALL(plugin->terminate_callback, plugin); } static VOID VCAPITYPE svc_plugin_init_event(LPVOID pInitHandle, UINT event, LPVOID pData, UINT dataLength) @@ -297,7 +303,7 @@ void svc_plugin_init(rdpSvcPlugin* plugin, CHANNEL_ENTRY_POINTS* pEntryPoints) plugin->channel_entry_points.pInterface = *(plugin->channel_entry_points.ppInterface); plugin->channel_entry_points.ppInterface = &(plugin->channel_entry_points.pInterface); - plugin->started = CreateEvent(NULL,TRUE,FALSE,NULL); + plugin->started = CreateEvent(NULL, TRUE, FALSE, NULL); plugin->pool = StreamPool_New(TRUE, 10); svc_plugin_add_init_handle_data(plugin->InitHandle, plugin); @@ -305,8 +311,17 @@ void svc_plugin_init(rdpSvcPlugin* plugin, CHANNEL_ENTRY_POINTS* pEntryPoints) void svc_plugin_terminate(rdpSvcPlugin* plugin) { - StreamPool_Free(plugin->pool); - CloseHandle(plugin->started); + if (plugin->pool) + { + StreamPool_Free(plugin->pool); + plugin->pool = NULL; + } + + if (plugin->started) + { + CloseHandle(plugin->started); + plugin->started = NULL; + } } int svc_plugin_send(rdpSvcPlugin* plugin, wStream* data_out) diff --git a/winpr/include/winpr/collections.h b/winpr/include/winpr/collections.h index b1b945b9a..f56a556d8 100644 --- a/winpr/include/winpr/collections.h +++ b/winpr/include/winpr/collections.h @@ -326,6 +326,8 @@ WINPR_API void CountdownEvent_Free(wCountdownEvent* countdown); /* Hash Table */ +typedef void (*KEY_VALUE_FREE_FN)(void* context, void* key, void* value); + struct _wHashTable { BOOL synchronized; @@ -342,6 +344,9 @@ struct _wHashTable unsigned long (*hashFunction)(void* key); void (*keyDeallocator)(void* key); void (*valueDeallocator)(void* value); + + void* context; + KEY_VALUE_FREE_FN pfnKeyValueFree; }; typedef struct _wHashTable wHashTable; @@ -354,6 +359,8 @@ WINPR_API BOOL HashTable_ContainsKey(wHashTable* table, void* key); WINPR_API BOOL HashTable_ContainsValue(wHashTable* table, void* value); WINPR_API void* HashTable_GetItemValue(wHashTable* table, void* key); WINPR_API BOOL HashTable_SetItemValue(wHashTable* table, void* key, void* value); +WINPR_API void HashTable_SetFreeFunction(wHashTable* table, void* context, KEY_VALUE_FREE_FN pfnKeyValueFree); +WINPR_API int HashTable_GetKeys(wHashTable* table, ULONG_PTR** ppKeys); WINPR_API wHashTable* HashTable_New(BOOL synchronized); WINPR_API void HashTable_Free(wHashTable* table); diff --git a/winpr/libwinpr/utils/collections/HashTable.c b/winpr/libwinpr/utils/collections/HashTable.c index fd75143c9..fcbe4aa3d 100644 --- a/winpr/libwinpr/utils/collections/HashTable.c +++ b/winpr/libwinpr/utils/collections/HashTable.c @@ -368,6 +368,9 @@ void HashTable_Clear(wHashTable* table) { nextPair = pair->next; + if (table->pfnKeyValueFree) + table->pfnKeyValueFree(table->context, pair->key, pair->value); + if (table->keyDeallocator) table->keyDeallocator((void*) pair->key); @@ -389,6 +392,48 @@ void HashTable_Clear(wHashTable* table) LeaveCriticalSection(&table->lock); } +/** + * Gets the list of keys as an array + */ + +int HashTable_GetKeys(wHashTable* table, ULONG_PTR** ppKeys) +{ + int iKey; + int count; + int index; + ULONG_PTR* pKeys; + wKeyValuePair* pair; + wKeyValuePair* nextPair; + + if (table->synchronized) + EnterCriticalSection(&table->lock); + + iKey = 0; + count = table->numOfElements; + pKeys = (ULONG_PTR*) calloc(count, sizeof(ULONG_PTR)); + + for (index = 0; index < table->numOfBuckets; index++) + { + pair = table->bucketArray[index]; + + while (pair) + { + nextPair = pair->next; + + pKeys[iKey++] = (ULONG_PTR) pair->key; + + pair = nextPair; + } + } + + if (table->synchronized) + LeaveCriticalSection(&table->lock); + + *ppKeys = pKeys; + + return count; +} + /** * Determines whether the HashTable contains a specific key. */ @@ -465,6 +510,12 @@ BOOL HashTable_ContainsValue(wHashTable* table, void* value) return status; } +void HashTable_SetFreeFunction(wHashTable* table, void* context, KEY_VALUE_FREE_FN pfnKeyValueFree) +{ + table->context = context; + table->pfnKeyValueFree = pfnKeyValueFree; +} + /** * Construction, Destruction */ diff --git a/winpr/libwinpr/utils/collections/ListDictionary.c b/winpr/libwinpr/utils/collections/ListDictionary.c index ca65d8a08..918bee44c 100644 --- a/winpr/libwinpr/utils/collections/ListDictionary.c +++ b/winpr/libwinpr/utils/collections/ListDictionary.c @@ -144,8 +144,7 @@ int ListDictionary_GetKeys(wListDictionary* listDictionary, ULONG_PTR** ppKeys) } } - pKeys = (ULONG_PTR*) malloc(sizeof(ULONG_PTR) * count); - ZeroMemory(pKeys, sizeof(ULONG_PTR) * count); + pKeys = (ULONG_PTR*) calloc(count, sizeof(ULONG_PTR)); index = 0;