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;
ep.devman = devman;
ep.RegisterDevice = devman_register_device;
- ep.UnregisterDevice = devman_unregister_device;
ep.plugin_data = plugin_data;
entry(&ep);
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})
#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"
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)
uint32 rc;
/* try to return NTSTATUS version of error code */
+
switch (fs_errno)
{
case EPERM:
if (file->id == id)
return file;
}
+
return NULL;
}
if (Length > 0)
{
- stream_check_size(irp->output, (int)Length);
+ stream_check_size(irp->output, (int) Length);
stream_write(irp->output, buffer, Length);
}
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);
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;
{
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);
}
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);
xfree(disk);
}
-
void disk_register_disk_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char* name, char* path)
{
int i, length;
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);
#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>
stream_free(irp->input);
stream_free(irp->output);
- xfree(irp);
+
+ _aligned_free(irp);
}
static void irp_complete(IRP* irp)
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);
#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>
char* path;
uint32 id;
- LIST* irp_list;
+ PSLIST_HEADER pIrpList;
freerdp_thread* thread;
};
typedef struct _PARALLEL_DEVICE PARALLEL_DEVICE;
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;
break;
freerdp_thread_reset(parallel->thread);
+
parallel_process_irp_list(parallel);
}
{
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);
}
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);
}
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);
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)
#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>
rdpPrinter* printer;
- LIST* irp_list;
+ PSLIST_HEADER pIrpList;
freerdp_thread* thread;
};
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);
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;
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);
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);
}
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();
#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;
else
{
printers = driver->EnumPrinters(driver);
+
for (i = 0; printers[i]; i++)
{
printer = printers[i];
printer_register(pEntryPoints, printer);
}
+
xfree(printers);
}
* 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);
#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>
typedef struct _IRP IRP;
typedef struct _DEVMAN DEVMAN;
-
typedef void (*pcIRPRequest)(DEVICE* device, IRP* irp);
typedef void (*pcFreeDevice)(DEVICE* device);
struct _IRP
{
+ SLIST_ENTRY ItemEntry;
+
DEVICE* device;
DEVMAN* devman;
uint32 FileId;
DEVMAN* devman;
pcRegisterDevice RegisterDevice;
- pcRegisterDevice UnregisterDevice;
RDP_PLUGIN_DATA* plugin_data;
};
typedef struct _DEVICE_SERVICE_ENTRY_POINTS DEVICE_SERVICE_ENTRY_POINTS;
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})
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. */
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;
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);
}
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();
{
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;
#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
{
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;
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;
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);
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;
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)
cb = 3;
stream_write_uint32(stream, val);
}
+
return cb;
}
if (i < client->settings->num_channels)
{
channel = (rdpPeerChannel*) client->settings->channels[i].handle;
+
if (channel != NULL)
{
WTSProcessChannelData(channel, channelId, data, size, flags, total_size);
{
WTSVirtualChannelClose(channel);
}
+
list_free(vcm->dvc_channel_list);
+
if (vcm->drdynvc_channel != NULL)
{
WTSVirtualChannelClose(vcm->drdynvc_channel);
}
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);
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);
vcm->drdynvc_state = DRDYNVC_STATE_INITIALIZED;
channel = WTSVirtualChannelOpenEx(vcm, "drdynvc", 0);
+
if (channel)
{
vcm->drdynvc_channel = channel;
{
int i;
int len;
+ STREAM* s;
rdpPeerChannel* channel;
freerdp_peer* client = vcm->client;
- STREAM* s;
if ((flags & WTS_CHANNEL_OPTION_DYNAMIC) != 0)
{
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);
{
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);
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;
}
typedef struct _PROGRAM_ITEM
{
SLIST_ENTRY ItemEntry;
- ULONG Signature;
+ ULONG Signature;
} PROGRAM_ITEM, *PPROGRAM_ITEM;
int TestInterlockedSList(int argc, char* argv[])