channels/rdpdr: reduce dependency on list utils in favor or lightweight interlocked singly-list lists

This commit is contained in:
Marc-André Moreau
2012-10-02 21:52:27 -04:00
parent 1fc525ccf7
commit 77023ec1dd
14 changed files with 132 additions and 94 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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[])