From 490f18a7aa35ac6282d6594fadd917f7851176bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 17 Oct 2013 16:30:36 -0400 Subject: [PATCH] channels/rdpdr: don't use deprecated LIST util, use ListDictionary for faster lookups --- channels/rdpdr/client/devman.c | 53 +++++++++--------- channels/rdpdr/client/rdpdr_main.c | 18 ++++--- include/freerdp/channels/rdpdr.h | 3 +- winpr/include/winpr/collections.h | 3 ++ .../utils/collections/ListDictionary.c | 54 +++++++++++++++++++ 5 files changed, 98 insertions(+), 33 deletions(-) diff --git a/channels/rdpdr/client/devman.c b/channels/rdpdr/client/devman.c index 33db5ec24..7ff21273f 100644 --- a/channels/rdpdr/client/devman.c +++ b/channels/rdpdr/client/devman.c @@ -38,6 +38,11 @@ #include "devman.h" +static void devman_device_free(DEVICE* device) +{ + IFCALL(device->Free, device); +} + DEVMAN* devman_new(rdpdrPlugin* rdpdr) { DEVMAN* devman; @@ -47,27 +52,39 @@ DEVMAN* devman_new(rdpdrPlugin* rdpdr) devman->plugin = (void*) rdpdr; devman->id_sequence = 1; - devman->devices = list_new(); + + devman->devices = ListDictionary_New(TRUE); + + ListDictionary_Object(devman->devices)->fnObjectFree = + (OBJECT_FREE_FN) devman_device_free; return devman; } void devman_free(DEVMAN* devman) { - DEVICE* device; - - while ((device = (DEVICE*) list_dequeue(devman->devices)) != NULL) - IFCALL(device->Free, device); - - list_free(devman->devices); - + ListDictionary_Free(devman->devices); free(devman); } static void devman_register_device(DEVMAN* devman, DEVICE* device) { + void* key = NULL; + device->id = devman->id_sequence++; - list_add(devman->devices, device); + key = (void*) (size_t) device->id; + + ListDictionary_Add(devman->devices, key, device); +} + +DEVICE* devman_get_device_by_id(DEVMAN* devman, UINT32 id) +{ + DEVICE* device = NULL; + void* key = (void*) (size_t) id; + + device = (DEVICE*) ListDictionary_GetItemValue(devman->devices, key); + + return device; } static char DRIVE_SERVICE_NAME[] = "drive"; @@ -99,7 +116,7 @@ BOOL devman_load_device_service(DEVMAN* devman, RDPDR_DEVICE* device) fprintf(stderr, "Loading device service %s (static)\n", ServiceName); entry = (PDEVICE_SERVICE_ENTRY) freerdp_load_channel_addin_entry(ServiceName, NULL, "DeviceServiceEntry", 0); - if (entry == NULL) + if (!entry) return FALSE; ep.devman = devman; @@ -110,19 +127,3 @@ BOOL devman_load_device_service(DEVMAN* devman, RDPDR_DEVICE* device) return TRUE; } - -DEVICE* devman_get_device_by_id(DEVMAN* devman, UINT32 id) -{ - LIST_ITEM* item; - DEVICE* device; - - for (item = devman->devices->head; item; item = item->next) - { - device = (DEVICE*) item->data; - - if (device->id == id) - return device; - } - - return NULL; -} diff --git a/channels/rdpdr/client/rdpdr_main.c b/channels/rdpdr/client/rdpdr_main.c index 3496bea2f..96e3d6d08 100644 --- a/channels/rdpdr/client/rdpdr_main.c +++ b/channels/rdpdr/client/rdpdr_main.c @@ -134,17 +134,19 @@ static void rdpdr_process_server_clientid_confirm(rdpdrPlugin* rdpdr, wStream* s } } -static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL user_loggedon) +static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL userLoggedOn) { int i; - int pos; BYTE c; + int pos; + int index; wStream* s; UINT32 count; int data_len; int count_pos; DEVICE* device; - LIST_ITEM* item; + int keyCount; + ULONG_PTR* pKeys; s = Stream_New(NULL, 256); @@ -153,11 +155,15 @@ static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use count_pos = Stream_GetPosition(s); count = 0; + Stream_Seek_UINT32(s); /* deviceCount */ - for (item = rdpdr->devman->devices->head; item; item = item->next) + pKeys = NULL; + keyCount = ListDictionary_GetKeys(rdpdr->devman->devices, &pKeys); + + for (index = 0; index < keyCount; index++) { - device = (DEVICE*) item->data; + device = (DEVICE*) ListDictionary_GetItemValue(rdpdr->devman->devices, (void*) pKeys[index]); /** * 1. versionMinor 0x0005 doesn't send PAKID_CORE_USER_LOGGEDON @@ -167,7 +173,7 @@ static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use */ if ((rdpdr->versionMinor == 0x0005) || - (device->type == RDPDR_DTYP_SMARTCARD) || user_loggedon) + (device->type == RDPDR_DTYP_SMARTCARD) || userLoggedOn) { data_len = (device->data == NULL ? 0 : Stream_GetPosition(device->data)); Stream_EnsureRemainingCapacity(s, 20 + data_len); diff --git a/include/freerdp/channels/rdpdr.h b/include/freerdp/channels/rdpdr.h index 41e189d60..7b80db1a4 100644 --- a/include/freerdp/channels/rdpdr.h +++ b/include/freerdp/channels/rdpdr.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -338,7 +339,7 @@ struct _DEVMAN { void* plugin; UINT32 id_sequence; - LIST* devices; + wListDictionary* devices; }; typedef void (*pcRegisterDevice)(DEVMAN* devman, DEVICE* device); diff --git a/winpr/include/winpr/collections.h b/winpr/include/winpr/collections.h index c37067e46..91d74e130 100644 --- a/winpr/include/winpr/collections.h +++ b/winpr/include/winpr/collections.h @@ -195,6 +195,8 @@ struct _wListDictionary }; typedef struct _wListDictionary wListDictionary; +#define ListDictionary_Object(_dictionary) (&_dictionary->object) + WINPR_API int ListDictionary_Count(wListDictionary* listDictionary); WINPR_API void ListDictionary_Add(wListDictionary* listDictionary, void* key, void* value); @@ -203,6 +205,7 @@ WINPR_API void* ListDictionary_Remove_Head(wListDictionary* listDictionary); WINPR_API void ListDictionary_Clear(wListDictionary* listDictionary); WINPR_API BOOL ListDictionary_Contains(wListDictionary* listDictionary, void* key); +WINPR_API int ListDictionary_GetKeys(wListDictionary* listDictionary, ULONG_PTR** ppKeys); WINPR_API void* ListDictionary_GetItemValue(wListDictionary* listDictionary, void* key); WINPR_API BOOL ListDictionary_SetItemValue(wListDictionary* listDictionary, void* key, void* value); diff --git a/winpr/libwinpr/utils/collections/ListDictionary.c b/winpr/libwinpr/utils/collections/ListDictionary.c index ab4309457..94f06231e 100644 --- a/winpr/libwinpr/utils/collections/ListDictionary.c +++ b/winpr/libwinpr/utils/collections/ListDictionary.c @@ -95,6 +95,60 @@ BOOL ListDictionary_IsSynchronized(wListDictionary* listDictionary) * Methods */ +/** + * Gets the list of keys as an array + */ + +int ListDictionary_GetKeys(wListDictionary* listDictionary, ULONG_PTR** ppKeys) +{ + int index; + int count; + ULONG_PTR* pKeys; + wListDictionaryItem* item; + + if (!ppKeys) + return -1; + + if (listDictionary->synchronized) + EnterCriticalSection(&listDictionary->lock); + + count = 0; + + if (listDictionary->head) + { + item = listDictionary->head; + + while (item) + { + count++; + item = item->next; + } + } + + pKeys = (ULONG_PTR*) malloc(sizeof(ULONG_PTR*) * count); + ZeroMemory(pKeys, sizeof(ULONG_PTR*) * count); + + index = 0; + + if (listDictionary->head) + { + item = listDictionary->head; + + while (item) + { + pKeys[index++] = (ULONG_PTR) item->key; + item = item->next; + } + } + + *ppKeys = pKeys; + + if (listDictionary->synchronized) + LeaveCriticalSection(&listDictionary->lock); + + return count; +} + /** * Adds an entry with the specified key and value into the ListDictionary. */