mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
channels/rdpdr: reduce dependency on list utils in favor or lightweight interlocked singly-list lists
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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})
|
||||
|
||||
@@ -41,8 +41,10 @@
|
||||
#include <freerdp/utils/list.h>
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/thread.h>
|
||||
#include <winpr/interlocked.h>
|
||||
|
||||
#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);
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
|
||||
#include <freerdp/utils/memory.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
@@ -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);
|
||||
|
||||
@@ -44,6 +44,11 @@
|
||||
#include <linux/parport.h>
|
||||
#endif
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/thread.h>
|
||||
#include <winpr/interlocked.h>
|
||||
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/constants.h>
|
||||
#include <freerdp/utils/list.h>
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -25,6 +25,11 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/thread.h>
|
||||
#include <winpr/interlocked.h>
|
||||
|
||||
#include <freerdp/utils/stream.h>
|
||||
#include <freerdp/utils/unicode.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -21,6 +21,11 @@
|
||||
#ifndef __RDPDR_TYPES_H
|
||||
#define __RDPDR_TYPES_H
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/thread.h>
|
||||
#include <winpr/interlocked.h>
|
||||
|
||||
#include <freerdp/utils/stream.h>
|
||||
#include <freerdp/utils/list.h>
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
@@ -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;
|
||||
|
||||
@@ -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})
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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[])
|
||||
|
||||
Reference in New Issue
Block a user