diff --git a/channels/rdpdr/client/devman.c b/channels/rdpdr/client/devman.c index d1b5ef02b..a9fbe1671 100644 --- a/channels/rdpdr/client/devman.c +++ b/channels/rdpdr/client/devman.c @@ -68,13 +68,6 @@ static void devman_register_device(DEVMAN* devman, DEVICE* device) DEBUG_SVC("device %d.%s registered", device->id, device->name); } -static void devman_unregister_device(DEVMAN* devman, DEVICE* device) -{ - list_remove(devman->devices, device); - - DEBUG_SVC("device %d.%s unregistered", device->id, device->name); -} - boolean devman_load_device_service(DEVMAN* devman, RDP_PLUGIN_DATA* plugin_data) { DEVICE_SERVICE_ENTRY_POINTS ep; @@ -87,7 +80,6 @@ boolean devman_load_device_service(DEVMAN* devman, RDP_PLUGIN_DATA* plugin_data) ep.devman = devman; ep.RegisterDevice = devman_register_device; - ep.UnregisterDevice = devman_unregister_device; ep.plugin_data = plugin_data; entry(&ep); diff --git a/channels/rdpdr/client/disk/CMakeLists.txt b/channels/rdpdr/client/disk/CMakeLists.txt index e19638503..eca9ea0bd 100644 --- a/channels/rdpdr/client/disk/CMakeLists.txt +++ b/channels/rdpdr/client/disk/CMakeLists.txt @@ -40,7 +40,7 @@ set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") if(WITH_MONOLITHIC_BUILD) set(${MODULE_PREFIX}_LIBS freerdp winpr) else() - set(${MODULE_PREFIX}_LIBS freerdp-utils winpr-synch winpr-thread) + set(${MODULE_PREFIX}_LIBS freerdp-utils winpr-crt winpr-synch winpr-thread winpr-interlocked) endif() target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) diff --git a/channels/rdpdr/client/disk/disk_main.c b/channels/rdpdr/client/disk/disk_main.c index 8e2b06830..8e28df4c0 100644 --- a/channels/rdpdr/client/disk/disk_main.c +++ b/channels/rdpdr/client/disk/disk_main.c @@ -41,8 +41,10 @@ #include #include +#include #include #include +#include #include "rdpdr_constants.h" #include "rdpdr_types.h" @@ -57,14 +59,12 @@ struct _DISK_DEVICE char* path; LIST* files; - HANDLE mutex; HANDLE thread; - LIST* irp_list; HANDLE irpEvent; HANDLE stopEvent; + PSLIST_HEADER pIrpList; DEVMAN* devman; - pcRegisterDevice UnregisterDevice; }; static uint32 disk_map_posix_err(int fs_errno) @@ -72,6 +72,7 @@ static uint32 disk_map_posix_err(int fs_errno) uint32 rc; /* try to return NTSTATUS version of error code */ + switch (fs_errno) { case EPERM: @@ -113,6 +114,7 @@ static DISK_FILE* disk_get_file_by_id(DISK_DEVICE* disk, uint32 id) if (file->id == id) return file; } + return NULL; } @@ -263,7 +265,7 @@ static void disk_process_irp_read(DISK_DEVICE* disk, IRP* irp) if (Length > 0) { - stream_check_size(irp->output, (int)Length); + stream_check_size(irp->output, (int) Length); stream_write(irp->output, buffer, Length); } @@ -467,11 +469,11 @@ static void disk_process_irp_query_volume_information(DISK_DEVICE* disk, IRP* ir static void disk_process_irp_query_directory(DISK_DEVICE* disk, IRP* irp) { + char* path; DISK_FILE* file; - uint32 FsInformationClass; uint8 InitialQuery; uint32 PathLength; - char* path; + uint32 FsInformationClass; stream_read_uint32(irp->input, FsInformationClass); stream_read_uint8(irp->input, InitialQuery); @@ -582,11 +584,7 @@ static void disk_process_irp_list(DISK_DEVICE* disk) if (WaitForSingleObject(disk->stopEvent, 0) == WAIT_OBJECT_0) break; - WaitForSingleObject(disk->mutex, INFINITE); - - irp = (IRP*) list_dequeue(disk->irp_list); - - ReleaseMutex(disk->mutex); + irp = (IRP*) InterlockedPopEntrySList(disk->pIrpList); if (irp == NULL) break; @@ -617,9 +615,7 @@ static void disk_irp_request(DEVICE* device, IRP* irp) { DISK_DEVICE* disk = (DISK_DEVICE*) device; - WaitForSingleObject(disk->mutex, INFINITE); - list_enqueue(disk->irp_list, irp); - ReleaseMutex(disk->mutex); + InterlockedPushEntrySList(disk->pIrpList, &(irp->ItemEntry)); SetEvent(disk->irpEvent); } @@ -633,12 +629,11 @@ static void disk_free(DEVICE* device) SetEvent(disk->stopEvent); CloseHandle(disk->thread); CloseHandle(disk->irpEvent); - CloseHandle(disk->mutex); - while ((irp = (IRP*) list_dequeue(disk->irp_list)) != NULL) + while ((irp = (IRP*) InterlockedPopEntrySList(disk->pIrpList)) != NULL) irp->Discard(irp); - list_free(disk->irp_list); + _aligned_free(disk->pIrpList); while ((file = (DISK_FILE*) list_dequeue(disk->files)) != NULL) disk_file_free(file); @@ -647,7 +642,6 @@ static void disk_free(DEVICE* device) xfree(disk); } - void disk_register_disk_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char* name, char* path) { int i, length; @@ -685,8 +679,9 @@ void disk_register_disk_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char* na disk->path = path; disk->files = list_new(); - disk->irp_list = list_new(); - disk->mutex = CreateMutex(NULL, FALSE, NULL); + disk->pIrpList = (PSLIST_HEADER) _aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT); + InitializeSListHead(disk->pIrpList); + disk->irpEvent = CreateEvent(NULL, TRUE, FALSE, NULL); disk->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); disk->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) disk_thread_func, disk, CREATE_SUSPENDED, NULL); diff --git a/channels/rdpdr/client/irp.c b/channels/rdpdr/client/irp.c index 859e20793..961d28561 100644 --- a/channels/rdpdr/client/irp.c +++ b/channels/rdpdr/client/irp.c @@ -25,6 +25,9 @@ #include #include #include + +#include + #include #include #include @@ -40,7 +43,8 @@ static void irp_free(IRP* irp) stream_free(irp->input); stream_free(irp->output); - xfree(irp); + + _aligned_free(irp); } static void irp_complete(IRP* irp) @@ -68,13 +72,15 @@ IRP* irp_new(DEVMAN* devman, STREAM* data_in) stream_read_uint32(data_in, DeviceId); device = devman_get_device_by_id(devman, DeviceId); + if (device == NULL) { DEBUG_WARN("unknown DeviceId %d", DeviceId); return NULL; } - irp = xnew(IRP); + irp = (IRP*) _aligned_malloc(sizeof(IRP), MEMORY_ALLOCATION_ALIGNMENT); + irp->device = device; irp->devman = devman; stream_read_uint32(data_in, irp->FileId); diff --git a/channels/rdpdr/client/parallel/parallel_main.c b/channels/rdpdr/client/parallel/parallel_main.c index aa73bd5b1..d6c0cdb01 100644 --- a/channels/rdpdr/client/parallel/parallel_main.c +++ b/channels/rdpdr/client/parallel/parallel_main.c @@ -44,6 +44,11 @@ #include #endif +#include +#include +#include +#include + #include #include #include @@ -64,7 +69,7 @@ struct _PARALLEL_DEVICE char* path; uint32 id; - LIST* irp_list; + PSLIST_HEADER pIrpList; freerdp_thread* thread; }; typedef struct _PARALLEL_DEVICE PARALLEL_DEVICE; @@ -247,9 +252,7 @@ static void parallel_process_irp_list(PARALLEL_DEVICE* parallel) if (freerdp_thread_is_stopped(parallel->thread)) break; - freerdp_thread_lock(parallel->thread); - irp = (IRP*) list_dequeue(parallel->irp_list); - freerdp_thread_unlock(parallel->thread); + irp = (IRP*) InterlockedPopEntrySList(parallel->pIrpList); if (irp == NULL) break; @@ -270,6 +273,7 @@ static void* parallel_thread_func(void* arg) break; freerdp_thread_reset(parallel->thread); + parallel_process_irp_list(parallel); } @@ -282,9 +286,7 @@ static void parallel_irp_request(DEVICE* device, IRP* irp) { PARALLEL_DEVICE* parallel = (PARALLEL_DEVICE*) device; - freerdp_thread_lock(parallel->thread); - list_enqueue(parallel->irp_list, irp); - freerdp_thread_unlock(parallel->thread); + InterlockedPushEntrySList(parallel->pIrpList, &(irp->ItemEntry)); freerdp_thread_signal(parallel->thread); } @@ -299,10 +301,10 @@ static void parallel_free(DEVICE* device) freerdp_thread_stop(parallel->thread); freerdp_thread_free(parallel->thread); - while ((irp = (IRP*) list_dequeue(parallel->irp_list)) != NULL) + while ((irp = (IRP*) InterlockedPopEntrySList(parallel->pIrpList)) != NULL) irp->Discard(irp); - list_free(parallel->irp_list); + _aligned_free(parallel->pIrpList); xfree(parallel); } @@ -334,7 +336,9 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) parallel->path = path; - parallel->irp_list = list_new(); + parallel->pIrpList = (PSLIST_HEADER) _aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT); + InitializeSListHead(parallel->pIrpList); + parallel->thread = freerdp_thread_new(); pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) parallel); diff --git a/channels/rdpdr/client/printer/CMakeLists.txt b/channels/rdpdr/client/printer/CMakeLists.txt index 91dd64863..8dbfc7bac 100644 --- a/channels/rdpdr/client/printer/CMakeLists.txt +++ b/channels/rdpdr/client/printer/CMakeLists.txt @@ -44,9 +44,9 @@ add_library(printer ${PRINTER_SRCS}) set_target_properties(printer PROPERTIES PREFIX "") if(WITH_MONOLITHIC_BUILD) - target_link_libraries(printer freerdp) + target_link_libraries(printer freerdp winpr) else() - target_link_libraries(printer freerdp-utils) + target_link_libraries(printer freerdp-utils winpr-crt winpr-synch winpr-thread winpr-interlocked) endif() if(WITH_CUPS) diff --git a/channels/rdpdr/client/printer/printer_main.c b/channels/rdpdr/client/printer/printer_main.c index 2716472cf..bd4368a83 100644 --- a/channels/rdpdr/client/printer/printer_main.c +++ b/channels/rdpdr/client/printer/printer_main.c @@ -25,6 +25,11 @@ #include #include +#include +#include +#include +#include + #include #include #include @@ -51,7 +56,7 @@ struct _PRINTER_DEVICE rdpPrinter* printer; - LIST* irp_list; + PSLIST_HEADER pIrpList; freerdp_thread* thread; }; @@ -106,9 +111,9 @@ static void printer_process_irp_close(PRINTER_DEVICE* printer_dev, IRP* irp) static void printer_process_irp_write(PRINTER_DEVICE* printer_dev, IRP* irp) { - rdpPrintJob* printjob = NULL; uint32 Length; uint64 Offset; + rdpPrintJob* printjob = NULL; stream_read_uint32(irp->input, Length); stream_read_uint64(irp->input, Offset); @@ -170,9 +175,7 @@ static void printer_process_irp_list(PRINTER_DEVICE* printer_dev) if (freerdp_thread_is_stopped(printer_dev->thread)) break; - freerdp_thread_lock(printer_dev->thread); - irp = (IRP*)list_dequeue(printer_dev->irp_list); - freerdp_thread_unlock(printer_dev->thread); + irp = (IRP*) InterlockedPopEntrySList(printer_dev->pIrpList); if (irp == NULL) break; @@ -203,26 +206,25 @@ static void* printer_thread_func(void* arg) static void printer_irp_request(DEVICE* device, IRP* irp) { - PRINTER_DEVICE* printer_dev = (PRINTER_DEVICE*)device; + PRINTER_DEVICE* printer_dev = (PRINTER_DEVICE*) device; - freerdp_thread_lock(printer_dev->thread); - list_enqueue(printer_dev->irp_list, irp); - freerdp_thread_unlock(printer_dev->thread); + InterlockedPushEntrySList(printer_dev->pIrpList, &(irp->ItemEntry)); freerdp_thread_signal(printer_dev->thread); } static void printer_free(DEVICE* device) { - PRINTER_DEVICE* printer_dev = (PRINTER_DEVICE*)device; IRP* irp; + PRINTER_DEVICE* printer_dev = (PRINTER_DEVICE*) device; freerdp_thread_stop(printer_dev->thread); freerdp_thread_free(printer_dev->thread); - - while ((irp = (IRP*)list_dequeue(printer_dev->irp_list)) != NULL) + + while ((irp = (IRP*) InterlockedPopEntrySList(printer_dev->pIrpList)) != NULL) irp->Discard(irp); - list_free(printer_dev->irp_list); + + _aligned_free(printer_dev->pIrpList); if (printer_dev->printer) printer_dev->printer->Free(printer_dev->printer); @@ -290,10 +292,12 @@ void printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* pri xfree(DriverName); xfree(PrintName); - printer_dev->irp_list = list_new(); + printer_dev->pIrpList = (PSLIST_HEADER) _aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT); + InitializeSListHead(printer_dev->pIrpList); + printer_dev->thread = freerdp_thread_new(); - pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*)printer_dev); + pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) printer_dev); freerdp_thread_start(printer_dev->thread, printer_thread_func, printer_dev); } @@ -304,12 +308,12 @@ int printer_entry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) #endif { - rdpPrinterDriver* driver = NULL; - rdpPrinter** printers; - rdpPrinter* printer; int i; char* name; char* driver_name; + rdpPrinter* printer; + rdpPrinter** printers; + rdpPrinterDriver* driver = NULL; #ifdef WITH_CUPS driver = printer_cups_get_driver(); @@ -317,23 +321,26 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) #ifdef WIN32 driver = printer_win_get_driver(); #endif + if (driver == NULL) { - DEBUG_WARN("no driver."); + DEBUG_WARN("no driver"); return 1; } - name = (char*)pEntryPoints->plugin_data->data[1]; - driver_name = (char*)pEntryPoints->plugin_data->data[2]; + name = (char*) pEntryPoints->plugin_data->data[1]; + driver_name = (char*) pEntryPoints->plugin_data->data[2]; if (name && name[0]) { printer = driver->GetPrinter(driver, name); + if (printer == NULL) { DEBUG_WARN("printer %s not found.", name); return 1; } + if (driver_name && driver_name[0]) printer->driver = driver_name; @@ -342,11 +349,13 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) else { printers = driver->EnumPrinters(driver); + for (i = 0; printers[i]; i++) { printer = printers[i]; printer_register(pEntryPoints, printer); } + xfree(printers); } diff --git a/channels/rdpdr/client/rdpdr_main.c b/channels/rdpdr/client/rdpdr_main.c index bb5939b85..e38048ae4 100644 --- a/channels/rdpdr/client/rdpdr_main.c +++ b/channels/rdpdr/client/rdpdr_main.c @@ -175,8 +175,7 @@ static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, boolean * 3. other devices are sent only after user_loggedon */ if (rdpdr->versionMinor == 0x0005 || - device->type == RDPDR_DTYP_SMARTCARD || - user_loggedon) + device->type == RDPDR_DTYP_SMARTCARD || user_loggedon) { data_len = (device->data == NULL ? 0 : stream_get_length(device->data)); stream_check_size(data_out, 20 + data_len); diff --git a/channels/rdpdr/client/rdpdr_types.h b/channels/rdpdr/client/rdpdr_types.h index c5594e4d0..1c8ba5b47 100644 --- a/channels/rdpdr/client/rdpdr_types.h +++ b/channels/rdpdr/client/rdpdr_types.h @@ -21,6 +21,11 @@ #ifndef __RDPDR_TYPES_H #define __RDPDR_TYPES_H +#include +#include +#include +#include + #include #include #include @@ -29,7 +34,6 @@ typedef struct _DEVICE DEVICE; typedef struct _IRP IRP; typedef struct _DEVMAN DEVMAN; - typedef void (*pcIRPRequest)(DEVICE* device, IRP* irp); typedef void (*pcFreeDevice)(DEVICE* device); @@ -49,6 +53,8 @@ typedef void (*pcIRPResponse)(IRP* irp); struct _IRP { + SLIST_ENTRY ItemEntry; + DEVICE* device; DEVMAN* devman; uint32 FileId; @@ -78,7 +84,6 @@ struct _DEVICE_SERVICE_ENTRY_POINTS DEVMAN* devman; pcRegisterDevice RegisterDevice; - pcRegisterDevice UnregisterDevice; RDP_PLUGIN_DATA* plugin_data; }; typedef struct _DEVICE_SERVICE_ENTRY_POINTS DEVICE_SERVICE_ENTRY_POINTS; diff --git a/channels/rdpdr/client/smartcard/CMakeLists.txt b/channels/rdpdr/client/smartcard/CMakeLists.txt index c486e1ba7..7a8717a0a 100644 --- a/channels/rdpdr/client/smartcard/CMakeLists.txt +++ b/channels/rdpdr/client/smartcard/CMakeLists.txt @@ -29,9 +29,9 @@ add_library(scard ${SCARD_SRCS}) set_target_properties(scard PROPERTIES PREFIX "") if(WITH_MONOLITHIC_BUILD) - target_link_libraries(scard freerdp) + target_link_libraries(scard freerdp winpr) else() - target_link_libraries(scard freerdp-utils) + target_link_libraries(scard freerdp-utils winpr-crt winpr-synch winpr-thread winpr-interlocked) endif() target_link_libraries(scard ${PCSC_LIBRARIES}) diff --git a/channels/rdpdr/client/smartcard/scard_main.c b/channels/rdpdr/client/smartcard/scard_main.c index cac196787..b5998fbe0 100644 --- a/channels/rdpdr/client/smartcard/scard_main.c +++ b/channels/rdpdr/client/smartcard/scard_main.c @@ -45,11 +45,11 @@ static void scard_free(DEVICE* dev) freerdp_thread_stop(scard->thread); freerdp_thread_free(scard->thread); - - while ((irp = (IRP*) list_dequeue(scard->irp_list)) != NULL) + + while ((irp = (IRP*) InterlockedPopEntrySList(scard->pIrpList)) != NULL) irp->Discard(irp); - list_free(scard->irp_list); + _aligned_free(scard->pIrpList); /* Begin TS Client defect workaround. */ @@ -87,9 +87,7 @@ static void scard_process_irp_list(SCARD_DEVICE* scard) while (!freerdp_thread_is_stopped(scard->thread)) { - freerdp_thread_lock(scard->thread); - irp = (IRP*) list_dequeue(scard->irp_list); - freerdp_thread_unlock(scard->thread); + irp = (IRP*) InterlockedPopEntrySList(scard->pIrpList); if (irp == NULL) break; @@ -281,9 +279,7 @@ static void scard_irp_request(DEVICE* device, IRP* irp) return; } - freerdp_thread_lock(scard->thread); - list_enqueue(scard->irp_list, irp); - freerdp_thread_unlock(scard->thread); + InterlockedPushEntrySList(scard->pIrpList, &(irp->ItemEntry)); freerdp_thread_signal(scard->thread); } @@ -317,7 +313,9 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) scard->path = path; - scard->irp_list = list_new(); + scard->pIrpList = (PSLIST_HEADER) _aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT); + InitializeSListHead(scard->pIrpList); + scard->thread = freerdp_thread_new(); scard->CompletionIds = list_new(); diff --git a/channels/rdpdr/client/smartcard/scard_main.h b/channels/rdpdr/client/smartcard/scard_main.h index 1c0c5cbc3..c8143ef31 100644 --- a/channels/rdpdr/client/smartcard/scard_main.h +++ b/channels/rdpdr/client/smartcard/scard_main.h @@ -99,17 +99,15 @@ struct _SCARD_DEVICE { DEVICE device; - char * name; - char * path; + char* name; + char* path; - LIST* irp_list; + PSLIST_HEADER pIrpList; freerdp_thread* thread; LIST* CompletionIds; - HANDLE CompletionIdsMutex; /* Protect the LIST from - * multiple thread writers. - */ + HANDLE CompletionIdsMutex; }; typedef struct _SCARD_DEVICE SCARD_DEVICE; diff --git a/libfreerdp/channels/wtsvc.c b/libfreerdp/channels/wtsvc.c index 6ba0bcb29..b4f9b3e5d 100644 --- a/libfreerdp/channels/wtsvc.c +++ b/libfreerdp/channels/wtsvc.c @@ -32,11 +32,11 @@ #include "wtsvc.h" -#define CREATE_REQUEST_PDU 0x01 -#define DATA_FIRST_PDU 0x02 -#define DATA_PDU 0x03 -#define CLOSE_REQUEST_PDU 0x04 -#define CAPABILITY_REQUEST_PDU 0x05 +#define CREATE_REQUEST_PDU 0x01 +#define DATA_FIRST_PDU 0x02 +#define DATA_PDU 0x03 +#define CLOSE_REQUEST_PDU 0x04 +#define CAPABILITY_REQUEST_PDU 0x05 typedef struct wts_data_item { @@ -141,8 +141,10 @@ static void wts_read_drdynvc_create_response(rdpPeerChannel* channel, STREAM* s, if (length < 4) return; + stream_read_uint32(s, CreationStatus); - if ((sint32)CreationStatus < 0) + + if ((sint32) CreationStatus < 0) { DEBUG_DVC("ChannelId %d creation failed (%d)", channel->channel_id, (sint32)CreationStatus); channel->dvc_open_state = DVC_OPEN_STATE_FAILED; @@ -160,9 +162,12 @@ static void wts_read_drdynvc_data_first(rdpPeerChannel* channel, STREAM* s, int int value; value = wts_read_variable_uint(s, cbLen, &channel->dvc_total_length); + if (value == 0) return; + length -= value; + if (length > channel->dvc_total_length) return; @@ -181,7 +186,9 @@ static void wts_read_drdynvc_data(rdpPeerChannel* channel, STREAM* s, uint32 len printf("wts_read_drdynvc_data: incorrect fragment data, discarded.\n"); return; } + stream_write(channel->receive_data, stream_get_tail(s), length); + if (stream_get_length(channel->receive_data) >= (int) channel->dvc_total_length) { wts_queue_receive_data(channel, stream_get_head(channel->receive_data), channel->dvc_total_length); @@ -211,10 +218,13 @@ static void wts_read_drdynvc_pdu(rdpPeerChannel* channel) rdpPeerChannel* dvc; length = stream_get_pos(channel->receive_data); + if (length < 1) return; + stream_set_pos(channel->receive_data, 0); stream_read_uint8(channel->receive_data, value); + length--; Cmd = (value & 0xf0) >> 4; Sp = (value & 0x0c) >> 2; @@ -227,12 +237,15 @@ static void wts_read_drdynvc_pdu(rdpPeerChannel* channel) else if (channel->vcm->drdynvc_state == DRDYNVC_STATE_READY) { value = wts_read_variable_uint(channel->receive_data, cbChId, &ChannelId); + if (value == 0) return; + length -= value; DEBUG_DVC("Cmd %d ChannelId %d length %d", Cmd, ChannelId, length); dvc = wts_get_dvc_channel_by_id(channel->vcm, ChannelId); + if (dvc) { switch (Cmd) @@ -288,6 +301,7 @@ static int wts_write_variable_uint(STREAM* stream, uint32 val) cb = 3; stream_write_uint32(stream, val); } + return cb; } @@ -354,6 +368,7 @@ static int WTSReceiveChannelData(freerdp_peer* client, int channelId, uint8* dat if (i < client->settings->num_channels) { channel = (rdpPeerChannel*) client->settings->channels[i].handle; + if (channel != NULL) { WTSProcessChannelData(channel, channelId, data, size, flags, total_size); @@ -396,7 +411,9 @@ void WTSDestroyVirtualChannelManager(WTSVirtualChannelManager* vcm) { WTSVirtualChannelClose(channel); } + list_free(vcm->dvc_channel_list); + if (vcm->drdynvc_channel != NULL) { WTSVirtualChannelClose(vcm->drdynvc_channel); @@ -404,10 +421,12 @@ void WTSDestroyVirtualChannelManager(WTSVirtualChannelManager* vcm) } wait_obj_free(vcm->send_event); + while ((item = (wts_data_item*) list_dequeue(vcm->send_queue)) != NULL) { wts_data_item_free(item); } + list_free(vcm->send_queue); CloseHandle(vcm->mutex); xfree(vcm); @@ -418,6 +437,7 @@ void WTSVirtualChannelManagerGetFileDescriptor(WTSVirtualChannelManager* vcm, void** fds, int* fds_count) { wait_obj_get_fds(vcm->send_event, fds, fds_count); + if (vcm->drdynvc_channel) { wait_obj_get_fds(vcm->drdynvc_channel->receive_event, fds, fds_count); @@ -437,6 +457,7 @@ boolean WTSVirtualChannelManagerCheckFileDescriptor(WTSVirtualChannelManager* vc vcm->drdynvc_state = DRDYNVC_STATE_INITIALIZED; channel = WTSVirtualChannelOpenEx(vcm, "drdynvc", 0); + if (channel) { vcm->drdynvc_channel = channel; @@ -474,9 +495,9 @@ void* WTSVirtualChannelOpenEx( { int i; int len; + STREAM* s; rdpPeerChannel* channel; freerdp_peer* client = vcm->client; - STREAM* s; if ((flags & WTS_CHANNEL_OPTION_DYNAMIC) != 0) { @@ -694,6 +715,7 @@ boolean WTSVirtualChannelWrite( stream_seek_uint8(s); cbChId = wts_write_variable_uint(s, channel->channel_id); + if (first && (Length > (uint32) stream_get_left(s))) { cbLen = wts_write_variable_uint(s, Length); @@ -703,10 +725,13 @@ boolean WTSVirtualChannelWrite( { item->buffer[0] = (DATA_PDU << 4) | cbChId; } + first = false; written = stream_get_left(s); + if (written > Length) written = Length; + stream_write(s, Buffer, written); item->length = stream_get_length(s); stream_detach(s); @@ -755,21 +780,28 @@ boolean WTSVirtualChannelClose( stream_free(s); } } + if (channel->receive_data) stream_free(channel->receive_data); + if (channel->receive_event) wait_obj_free(channel->receive_event); + if (channel->receive_queue) { while ((item = (wts_data_item*) list_dequeue(channel->receive_queue)) != NULL) { wts_data_item_free(item); } + list_free(channel->receive_queue); } + if (channel->mutex) CloseHandle(channel->mutex); + xfree(channel); } + return true; } diff --git a/winpr/libwinpr/interlocked/test/TestInterlockedSList.c b/winpr/libwinpr/interlocked/test/TestInterlockedSList.c index b3eb357ec..86f2b4184 100644 --- a/winpr/libwinpr/interlocked/test/TestInterlockedSList.c +++ b/winpr/libwinpr/interlocked/test/TestInterlockedSList.c @@ -8,7 +8,7 @@ typedef struct _PROGRAM_ITEM { SLIST_ENTRY ItemEntry; - ULONG Signature; + ULONG Signature; } PROGRAM_ITEM, *PPROGRAM_ITEM; int TestInterlockedSList(int argc, char* argv[])