channels/rdpdr: don't use deprecated LIST util, use ListDictionary for faster lookups

This commit is contained in:
Marc-André Moreau 2013-10-17 16:30:36 -04:00
parent b1e9cfa445
commit 490f18a7aa
5 changed files with 98 additions and 33 deletions

View File

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

View File

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

View File

@ -28,6 +28,7 @@
#include <winpr/thread.h>
#include <winpr/stream.h>
#include <winpr/interlocked.h>
#include <winpr/collections.h>
#include <freerdp/freerdp.h>
#include <freerdp/utils/list.h>
@ -338,7 +339,7 @@ struct _DEVMAN
{
void* plugin;
UINT32 id_sequence;
LIST* devices;
wListDictionary* devices;
};
typedef void (*pcRegisterDevice)(DEVMAN* devman, DEVICE* device);

View File

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

View File

@ -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.
*/