diff --git a/channels/rdpdr/client/devman.c b/channels/rdpdr/client/devman.c index 75998dfe5..b40cd6172 100644 --- a/channels/rdpdr/client/devman.c +++ b/channels/rdpdr/client/devman.c @@ -94,7 +94,7 @@ void devman_unregister_device(DEVMAN* devman, void* key) if (!devman || !key) return; - device = (DEVICE*)ListDictionary_Remove(devman->devices, key); + device = (DEVICE*)ListDictionary_Take(devman->devices, key); if (device) devman_device_free(device); diff --git a/channels/rdpdr/server/rdpdr_main.c b/channels/rdpdr/server/rdpdr_main.c index 77c2c0d69..bc50361d2 100644 --- a/channels/rdpdr/server/rdpdr_main.c +++ b/channels/rdpdr/server/rdpdr_main.c @@ -189,7 +189,7 @@ static RDPDR_IRP* rdpdr_server_dequeue_irp(RdpdrServerContext* context, UINT32 c RDPDR_IRP* irp; WINPR_ASSERT(context); WINPR_ASSERT(context->priv); - irp = (RDPDR_IRP*)ListDictionary_Remove(context->priv->IrpList, (void*)(size_t)completionId); + irp = (RDPDR_IRP*)ListDictionary_Take(context->priv->IrpList, (void*)(size_t)completionId); return irp; } diff --git a/winpr/include/winpr/collections.h b/winpr/include/winpr/collections.h index 7520c8f2b..486002bc7 100644 --- a/winpr/include/winpr/collections.h +++ b/winpr/include/winpr/collections.h @@ -191,8 +191,11 @@ extern "C" WINPR_API BOOL ListDictionary_Add(wListDictionary* listDictionary, const void* key, void* value); - WINPR_API void* ListDictionary_Remove(wListDictionary* listDictionary, const void* key); - WINPR_API void* ListDictionary_Remove_Head(wListDictionary* listDictionary); + WINPR_API void* ListDictionary_Take(wListDictionary* listDictionary, const void* key); + WINPR_API void ListDictionary_Remove(wListDictionary* listDictionary, const void* key); + + WINPR_API void* ListDictionary_Take_Head(wListDictionary* listDictionary); + WINPR_API void ListDictionary_Remove_Head(wListDictionary* listDictionary); WINPR_API void ListDictionary_Clear(wListDictionary* listDictionary); WINPR_API BOOL ListDictionary_Contains(wListDictionary* listDictionary, const void* key); diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.c b/winpr/libwinpr/smartcard/smartcard_pcsc.c index 138c1d7cd..911aa6b0a 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.c +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.c @@ -680,7 +680,7 @@ static void* PCSC_RemoveMemoryBlock(SCARDCONTEXT hContext, void* pvMem) if (!g_MemoryBlocks) return NULL; - return ListDictionary_Remove(g_MemoryBlocks, pvMem); + return ListDictionary_Take(g_MemoryBlocks, pvMem); } /** diff --git a/winpr/libwinpr/utils/collections/ListDictionary.c b/winpr/libwinpr/utils/collections/ListDictionary.c index 89828b98d..4f72549bf 100644 --- a/winpr/libwinpr/utils/collections/ListDictionary.c +++ b/winpr/libwinpr/utils/collections/ListDictionary.c @@ -190,8 +190,6 @@ size_t ListDictionary_GetKeys(wListDictionary* listDictionary, ULONG_PTR** ppKey BOOL ListDictionary_Add(wListDictionary* listDictionary, const void* key, void* value) { - wListDictionaryItem* item; - wListDictionaryItem* lastItem; BOOL ret = FALSE; WINPR_ASSERT(listDictionary); @@ -199,7 +197,7 @@ BOOL ListDictionary_Add(wListDictionary* listDictionary, const void* key, void* if (listDictionary->synchronized) EnterCriticalSection(&listDictionary->lock); - item = (wListDictionaryItem*)malloc(sizeof(wListDictionaryItem)); + wListDictionaryItem* item = (wListDictionaryItem*)calloc(1, sizeof(wListDictionaryItem)); if (!item) goto out_error; @@ -222,7 +220,7 @@ BOOL ListDictionary_Add(wListDictionary* listDictionary, const void* key, void* } else { - lastItem = listDictionary->head; + wListDictionaryItem* lastItem = listDictionary->head; while (lastItem->next) lastItem = lastItem->next; @@ -239,6 +237,34 @@ out_error: return ret; } +static void item_free(wListDictionary* listDictionary, wListDictionaryItem* item) +{ + WINPR_ASSERT(listDictionary); + + if (item) + { + if (listDictionary->objectKey.fnObjectFree) + listDictionary->objectKey.fnObjectFree(item->key); + if (listDictionary->objectValue.fnObjectFree) + listDictionary->objectValue.fnObjectFree(item->value); + } + free(item); +} + +static void item_set(wListDictionary* listDictionary, wListDictionaryItem* item, const void* value) +{ + WINPR_ASSERT(listDictionary); + WINPR_ASSERT(item); + + if (listDictionary->objectValue.fnObjectFree) + listDictionary->objectValue.fnObjectFree(item->value); + + if (listDictionary->objectValue.fnObjectNew) + item->value = listDictionary->objectValue.fnObjectNew(value); + else + item->value = value; +} + /** * Removes all entries from the ListDictionary. */ @@ -261,13 +287,7 @@ void ListDictionary_Clear(wListDictionary* listDictionary) { nextItem = item->next; - if (listDictionary->objectKey.fnObjectFree) - listDictionary->objectKey.fnObjectFree(item->key); - - if (listDictionary->objectValue.fnObjectFree) - listDictionary->objectValue.fnObjectFree(item->value); - - free(item); + item_free(listDictionary, item); item = nextItem; } @@ -313,7 +333,8 @@ BOOL ListDictionary_Contains(wListDictionary* listDictionary, const void* key) * Removes the entry with the specified key from the ListDictionary. */ -void* ListDictionary_Remove(wListDictionary* listDictionary, const void* key) +static void* ListDictionary_RemoveOrTake(wListDictionary* listDictionary, const void* key, + BOOL take) { void* value = NULL; wListDictionaryItem* item; @@ -338,8 +359,12 @@ void* ListDictionary_Remove(wListDictionary* listDictionary, const void* key) else prevItem->next = item->next; - value = item->value; - free(item); + if (take) + { + value = item->value; + item->value = NULL; + } + item_free(listDictionary, item); break; } @@ -353,11 +378,21 @@ void* ListDictionary_Remove(wListDictionary* listDictionary, const void* key) return value; } +void ListDictionary_Remove(wListDictionary* listDictionary, const void* key) +{ + ListDictionary_RemoveOrTake(listDictionary, key, FALSE); +} + +void* ListDictionary_Take(wListDictionary* listDictionary, const void* key) +{ + return ListDictionary_RemoveOrTake(listDictionary, key, TRUE); +} + /** * Removes the first (head) entry from the list */ -void* ListDictionary_Remove_Head(wListDictionary* listDictionary) +static void* ListDictionary_Remove_Or_Take_Head(wListDictionary* listDictionary, BOOL take) { wListDictionaryItem* item; void* value = NULL; @@ -371,8 +406,12 @@ void* ListDictionary_Remove_Head(wListDictionary* listDictionary) { item = listDictionary->head; listDictionary->head = listDictionary->head->next; - value = item->value; - free(item); + if (take) + { + value = item->value; + item->value = NULL; + } + item_free(listDictionary, item); } if (listDictionary->synchronized) @@ -381,6 +420,16 @@ void* ListDictionary_Remove_Head(wListDictionary* listDictionary) return value; } +void ListDictionary_Remove_Head(wListDictionary* listDictionary) +{ + ListDictionary_Remove_Or_Take_Head(listDictionary, FALSE); +} + +void* ListDictionary_Take_Head(wListDictionary* listDictionary) +{ + return ListDictionary_Remove_Or_Take_Head(listDictionary, TRUE); +} + /** * Get an item value using key */ @@ -449,12 +498,7 @@ BOOL ListDictionary_SetItemValue(wListDictionary* listDictionary, const void* ke } if (item) - { - if (listDictionary->objectValue.fnObjectFree) - listDictionary->objectValue.fnObjectFree(item->value); - - item->value = value; - } + item_set(listDictionary, item, value); status = (item) ? TRUE : FALSE; } diff --git a/winpr/libwinpr/utils/test/TestListDictionary.c b/winpr/libwinpr/utils/test/TestListDictionary.c index fd9e842f2..8615cb18c 100644 --- a/winpr/libwinpr/utils/test/TestListDictionary.c +++ b/winpr/libwinpr/utils/test/TestListDictionary.c @@ -121,19 +121,19 @@ int TestListDictionary(int argc, char* argv[]) return -1; } - if (!ListDictionary_Remove(list, key2)) + if (!ListDictionary_Take(list, key2)) { printf("ListDictionary_Remove: Expected : TRUE, Actual: FALSE\n"); return -1; } - if (ListDictionary_Remove(list, key2)) + if (ListDictionary_Take(list, key2)) { printf("ListDictionary_Remove: Expected : FALSE, Actual: TRUE\n"); return -1; } - value = ListDictionary_Remove_Head(list); + value = ListDictionary_Take_Head(list); count = ListDictionary_Count(list); if (strncmp(value, val1, 4) || count != 1) { @@ -142,7 +142,7 @@ int TestListDictionary(int argc, char* argv[]) return -1; } - value = ListDictionary_Remove_Head(list); + value = ListDictionary_Take_Head(list); count = ListDictionary_Count(list); if (strncmp(value, val3, 4) || count != 0) { @@ -151,7 +151,7 @@ int TestListDictionary(int argc, char* argv[]) return -1; } - value = ListDictionary_Remove_Head(list); + value = ListDictionary_Take_Head(list); if (value) { printf("ListDictionary_Remove_Head: Expected : (null), Actual: %s\n", value);