diff --git a/channels/drive/client/drive_main.c b/channels/drive/client/drive_main.c index f744b564c..ce0a57e3d 100644 --- a/channels/drive/client/drive_main.c +++ b/channels/drive/client/drive_main.c @@ -701,14 +701,16 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) { char* name; char* path; + RDPDR_DRIVE* drive; #ifdef WIN32 char* dev; int len; char devlist[512], buf[512]; #endif - name = (char*) pEntryPoints->plugin_data->data[1]; - path = (char*) pEntryPoints->plugin_data->data[2]; + drive = (RDPDR_DRIVE*) pEntryPoints->device; + name = drive->Name; + path = drive->Path; #ifndef WIN32 drive_register_drive_path(pEntryPoints, name, path); diff --git a/channels/parallel/client/parallel_main.c b/channels/parallel/client/parallel_main.c index 14f70229e..685566571 100644 --- a/channels/parallel/client/parallel_main.c +++ b/channels/parallel/client/parallel_main.c @@ -316,10 +316,12 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) char* name; char* path; int i, length; + RDPDR_PARALLEL* device; PARALLEL_DEVICE* parallel; - name = (char*) pEntryPoints->plugin_data->data[1]; - path = (char*) pEntryPoints->plugin_data->data[2]; + device = (RDPDR_PARALLEL*) pEntryPoints->device; + name = device->Name; + path = device->Path; if (name[0] && path[0]) { diff --git a/channels/printer/client/printer_main.c b/channels/printer/client/printer_main.c index de37d15bb..4ce760484 100644 --- a/channels/printer/client/printer_main.c +++ b/channels/printer/client/printer_main.c @@ -311,6 +311,7 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) char* driver_name; rdpPrinter* printer; rdpPrinter** printers; + RDPDR_PRINTER* device; rdpPrinterDriver* driver = NULL; #ifdef WITH_CUPS @@ -326,8 +327,9 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) return 1; } - name = (char*) pEntryPoints->plugin_data->data[1]; - driver_name = (char*) pEntryPoints->plugin_data->data[2]; + device = (RDPDR_PRINTER*) pEntryPoints->device; + name = device->Name; + driver_name = device->DriverName; if (name && name[0]) { diff --git a/channels/rdpdr/client/devman.c b/channels/rdpdr/client/devman.c index 0a9c4cc5a..0f5ab9680 100644 --- a/channels/rdpdr/client/devman.c +++ b/channels/rdpdr/client/devman.c @@ -26,8 +26,9 @@ #include #include +#include + #include -#include #include #include #include @@ -35,13 +36,16 @@ #include #include "rdpdr_main.h" + #include "devman.h" DEVMAN* devman_new(rdpSvcPlugin* plugin) { DEVMAN* devman; - devman = xnew(DEVMAN); + devman = (DEVMAN*) malloc(sizeof(DEVMAN)); + ZeroMemory(devman, sizeof(DEVMAN)); + devman->plugin = plugin; devman->id_sequence = 1; devman->devices = list_new(); @@ -69,23 +73,42 @@ static void devman_register_device(DEVMAN* devman, DEVICE* device) DEBUG_SVC("device %d.%s registered", device->id, device->name); } -BOOL devman_load_device_service(DEVMAN* devman, RDP_PLUGIN_DATA* plugin_data) +static char DRIVE_SERVICE_NAME[] = "drive"; +static char PRINTER_SERVICE_NAME[] = "printer"; +static char SMARTCARD_SERVICE_NAME[] = "smartcard"; +static char SERIAL_SERVICE_NAME[] = "serial"; +static char PARALLEL_SERVICE_NAME[] = "parallel"; + +BOOL devman_load_device_service(DEVMAN* devman, RDPDR_DEVICE* device) { - char* name; + char* ServiceName = NULL; DEVICE_SERVICE_ENTRY_POINTS ep; PDEVICE_SERVICE_ENTRY entry = NULL; - name = (char*) plugin_data->data[0]; - entry = (PDEVICE_SERVICE_ENTRY) freerdp_channels_client_find_static_entry("DeviceServiceEntry", name); + if (device->Type == RDPDR_DTYP_FILESYSTEM) + ServiceName = DRIVE_SERVICE_NAME; + else if (device->Type == RDPDR_DTYP_PRINT) + ServiceName = PRINTER_SERVICE_NAME; + else if (device->Type == RDPDR_DTYP_SMARTCARD) + ServiceName = SMARTCARD_SERVICE_NAME; + else if (device->Type == RDPDR_DTYP_SERIAL) + ServiceName = SERIAL_SERVICE_NAME; + else if (device->Type == RDPDR_DTYP_PARALLEL) + ServiceName = PARALLEL_SERVICE_NAME; + + if (!ServiceName) + return FALSE; + + entry = (PDEVICE_SERVICE_ENTRY) freerdp_channels_client_find_static_entry("DeviceServiceEntry", ServiceName); if (!entry) { - printf("loading device service %s (plugin)\n", name); - entry = freerdp_load_plugin(name, "DeviceServiceEntry"); + printf("loading device service %s (dynamic)\n", ServiceName); + entry = freerdp_load_plugin(ServiceName, "DeviceServiceEntry"); } else { - printf("loading device service %s (static)\n", name); + printf("loading device service %s (static)\n", ServiceName); } if (entry == NULL) @@ -93,7 +116,7 @@ BOOL devman_load_device_service(DEVMAN* devman, RDP_PLUGIN_DATA* plugin_data) ep.devman = devman; ep.RegisterDevice = devman_register_device; - ep.plugin_data = plugin_data; + ep.device = device; entry(&ep); diff --git a/channels/rdpdr/client/devman.h b/channels/rdpdr/client/devman.h index 290e897a5..7c525b9f0 100644 --- a/channels/rdpdr/client/devman.h +++ b/channels/rdpdr/client/devman.h @@ -21,9 +21,10 @@ #ifndef FREERDP_CHANNEL_RDPDR_CLIENT_DEVMAN_H #define FREERDP_CHANNEL_RDPDR_CLIENT_DEVMAN_H -DEVMAN* devman_new(rdpSvcPlugin* plugin); -void devman_free(DEVMAN* devman); -BOOL devman_load_device_service(DEVMAN* devman, RDP_PLUGIN_DATA* plugin_data); +BOOL devman_load_device_service(DEVMAN* devman, RDPDR_DEVICE* device); DEVICE* devman_get_device_by_id(DEVMAN* devman, UINT32 id); +DEVMAN* devman_new(rdpSvcPlugin* plugin); +void devman_free(DEVMAN* devman); + #endif /* FREERDP_CHANNEL_RDPDR_CLIENT_DEVMAN_H */ diff --git a/channels/rdpdr/client/rdpdr_main.c b/channels/rdpdr/client/rdpdr_main.c index 2ceabb0a5..dc8697b2b 100644 --- a/channels/rdpdr/client/rdpdr_main.c +++ b/channels/rdpdr/client/rdpdr_main.c @@ -49,25 +49,20 @@ static void rdpdr_process_connect(rdpSvcPlugin* plugin) { + int index; + RDPDR_DEVICE* device; + rdpSettings* settings; rdpdrPlugin* rdpdr = (rdpdrPlugin*) plugin; - RDP_PLUGIN_DATA* data; rdpdr->devman = devman_new(plugin); - data = (RDP_PLUGIN_DATA*) plugin->channel_entry_points.pExtendedData; + settings = (rdpSettings*) plugin->channel_entry_points.pExtendedData; - while (data && data->size > 0) + strncpy(rdpdr->computerName, settings->ComputerName, sizeof(rdpdr->computerName) - 1); + + for (index = 0; index < settings->DeviceCount; index++) { - if (strcmp((char*) data->data[0], "clientname") == 0) - { - strncpy(rdpdr->computerName, (char*) data->data[1], sizeof(rdpdr->computerName) - 1); - DEBUG_SVC("computerName %s", rdpdr->computerName); - } - else - { - devman_load_device_service(rdpdr->devman, data); - } - - data = (RDP_PLUGIN_DATA*) (((BYTE*) data) + data->size); + device = settings->DeviceArray[index]; + devman_load_device_service(rdpdr->devman, device); } } diff --git a/channels/serial/client/serial_main.c b/channels/serial/client/serial_main.c index cebe1a146..3977eb05c 100644 --- a/channels/serial/client/serial_main.c +++ b/channels/serial/client/serial_main.c @@ -397,49 +397,6 @@ static void serial_free(DEVICE* device) free(serial); } -#ifdef STATIC_CHANNELS -#define DeviceServiceEntry serial_DeviceServiceEntry -#endif - -int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) -{ - int i, len; - char* name; - char* path; - SERIAL_DEVICE* serial; - - name = (char*) pEntryPoints->plugin_data->data[1]; - path = (char*) pEntryPoints->plugin_data->data[2]; - - if (name[0] && path[0]) - { - serial = xnew(SERIAL_DEVICE); - - serial->device.type = RDPDR_DTYP_SERIAL; - serial->device.name = name; - serial->device.IRPRequest = serial_irp_request; - serial->device.Free = serial_free; - - len = strlen(name); - serial->device.data = stream_new(len + 1); - - for (i = 0; i <= len; i++) - stream_write_BYTE(serial->device.data, name[i] < 0 ? '_' : name[i]); - - serial->path = path; - serial->irp_list = list_new(); - serial->pending_irps = list_new(); - serial->thread = freerdp_thread_new(); - serial->in_event = wait_obj_new(); - - pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*)serial); - - freerdp_thread_start(serial->thread, serial_thread_func, serial); - } - - return 0; -} - static void serial_abort_single_io(SERIAL_DEVICE* serial, UINT32 file_id, UINT32 abort_io, UINT32 io_status) { IRP* irp = NULL; @@ -732,3 +689,48 @@ static BOOL serial_check_fds(SERIAL_DEVICE* serial) return 1; } + +#ifdef STATIC_CHANNELS +#define DeviceServiceEntry serial_DeviceServiceEntry +#endif + +int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) +{ + int i, len; + char* name; + char* path; + RDPDR_SERIAL* device; + SERIAL_DEVICE* serial; + + device = (RDPDR_SERIAL*) pEntryPoints->device; + name = device->Name; + path = device->Path; + + if (name[0] && path[0]) + { + serial = xnew(SERIAL_DEVICE); + + serial->device.type = RDPDR_DTYP_SERIAL; + serial->device.name = name; + serial->device.IRPRequest = serial_irp_request; + serial->device.Free = serial_free; + + len = strlen(name); + serial->device.data = stream_new(len + 1); + + for (i = 0; i <= len; i++) + stream_write_BYTE(serial->device.data, name[i] < 0 ? '_' : name[i]); + + serial->path = path; + serial->irp_list = list_new(); + serial->pending_irps = list_new(); + serial->thread = freerdp_thread_new(); + serial->in_event = wait_obj_new(); + + pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*)serial); + + freerdp_thread_start(serial->thread, serial_thread_func, serial); + } + + return 0; +} diff --git a/channels/smartcard/client/scard_main.c b/channels/smartcard/client/scard_main.c index ab66d0c21..b5389f4c6 100644 --- a/channels/smartcard/client/scard_main.c +++ b/channels/smartcard/client/scard_main.c @@ -291,10 +291,12 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) char* name; char* path; int i, length; + RDPDR_SMARTCARD* device; SCARD_DEVICE* scard; - name = (char*) pEntryPoints->plugin_data->data[1]; - path = (char*) pEntryPoints->plugin_data->data[2]; + device = (RDPDR_SMARTCARD*) pEntryPoints->device; + name = device->Name; + path = device->Path; if (name) { diff --git a/client/X11/xfreerdp.c b/client/X11/xfreerdp.c index b1c759a09..5a65fd52b 100644 --- a/client/X11/xfreerdp.c +++ b/client/X11/xfreerdp.c @@ -517,6 +517,8 @@ BOOL xf_pre_connect(freerdp* instance) if (status < 0) exit(XF_EXIT_PARSE_ARGUMENTS); + + freerdp_client_load_addins(instance->context->channels, instance->settings); } else { diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 0e89ebab3..669885137 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -24,6 +24,8 @@ #include #include +#include + #include COMMAND_LINE_ARGUMENT_A args[] = @@ -182,19 +184,170 @@ int freerdp_client_command_line_pre_filter(void* context, int index, LPCSTR arg) return 1; } +int freerdp_client_load_device_addin(rdpSettings* settings, int count, char** params) +{ + if (strcmp(params[0], "drive") == 0) + { + RDPDR_DRIVE* drive; + + if (count < 3) + return -1; + + drive = (RDPDR_DRIVE*) malloc(sizeof(RDPDR_DRIVE)); + ZeroMemory(drive, sizeof(RDPDR_DRIVE)); + + drive->Type = RDPDR_DTYP_FILESYSTEM; + drive->Name = _strdup(params[1]); + drive->Path = _strdup(params[2]); + + freerdp_device_collection_add(settings, (RDPDR_DEVICE*) drive); + + return 1; + } + else if (strcmp(params[0], "printer") == 0) + { + RDPDR_PRINTER* printer; + + if (count < 2) + return -1; + + printer = (RDPDR_PRINTER*) malloc(sizeof(RDPDR_PRINTER)); + ZeroMemory(printer, sizeof(RDPDR_PRINTER)); + + printer->Type = RDPDR_DTYP_PRINT; + printer->Name = _strdup(params[1]); + + if (params[2]) + printer->DriverName = _strdup(params[2]); + + freerdp_device_collection_add(settings, (RDPDR_DEVICE*) printer); + + return 1; + } + else if (strcmp(params[0], "smartcard") == 0) + { + RDPDR_SMARTCARD* smartcard; + + if (count < 3) + return -1; + + smartcard = (RDPDR_SMARTCARD*) malloc(sizeof(RDPDR_SMARTCARD)); + ZeroMemory(smartcard, sizeof(RDPDR_SMARTCARD)); + + smartcard->Type = RDPDR_DTYP_SMARTCARD; + smartcard->Name = _strdup(params[1]); + smartcard->Path = _strdup(params[2]); + + freerdp_device_collection_add(settings, (RDPDR_DEVICE*) smartcard); + + return 1; + } + else if (strcmp(params[0], "serial") == 0) + { + RDPDR_SERIAL* serial; + + if (count < 3) + return -1; + + serial = (RDPDR_SERIAL*) malloc(sizeof(RDPDR_SERIAL)); + ZeroMemory(serial, sizeof(RDPDR_SERIAL)); + + serial->Type = RDPDR_DTYP_SERIAL; + serial->Name = _strdup(params[1]); + serial->Path = _strdup(params[2]); + + freerdp_device_collection_add(settings, (RDPDR_DEVICE*) serial); + + return 1; + } + else if (strcmp(params[0], "parallel") == 0) + { + RDPDR_PARALLEL* parallel; + + if (count < 3) + return -1; + + parallel = (RDPDR_PARALLEL*) malloc(sizeof(RDPDR_PARALLEL)); + ZeroMemory(parallel, sizeof(RDPDR_PARALLEL)); + + parallel->Type = RDPDR_DTYP_PARALLEL; + parallel->Name = _strdup(params[1]); + parallel->Path = _strdup(params[2]); + + freerdp_device_collection_add(settings, (RDPDR_DEVICE*) parallel); + + return 1; + } + + return 0; +} + int freerdp_client_command_line_post_filter(void* context, COMMAND_LINE_ARGUMENT_A* arg) { + rdpSettings* settings; + CommandLineSwitchStart(arg) CommandLineSwitchCase(arg, "a") { + int nArgs; + char* str; + char* p[4]; int index; int nCommas; nCommas = 0; + settings = (rdpSettings*) context; for (index = 0; arg->Value[index]; index++) nCommas += (arg->Value[index] == ',') ? 1 : 0; + + if (nCommas >= 1) + { + nArgs = nCommas + 1; + str = _strdup(arg->Value); + + p[0] = str; + p[1] = p[2] = p[3] = NULL; + + if (nCommas >= 1) + { + p[1] = strchr(p[0], ','); + *p[1] = '\0'; + p[1]++; + } + + if (nCommas >= 2) + { + p[2] = strchr(p[1], ','); + *p[2] = '\0'; + p[2]++; + } + else + { + p[2] = str + strlen(str); + } + + if (nCommas >= 3) + { + p[3] = strchr(p[2], ','); + *p[3] = '\0'; + p[3]++; + } + else + { + p[3] = str + strlen(str); + } + + printf("addin: %s %s %s\n", p[0], p[1], p[2]); + + if (freerdp_client_load_device_addin(settings, nArgs, p) > 0) + { + settings->DeviceRedirection = TRUE; + } + + free(str); + } } CommandLineSwitchEnd(arg) @@ -552,3 +705,21 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin return 1; } + +int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings) +{ + void* entry = NULL; + + if (settings->DeviceRedirection) + { + entry = freerdp_channels_client_find_entry("VirtualChannelEntry", "rdpdr"); + + if (entry) + { + if (freerdp_channels_client_load(channels, settings, entry, settings) == 0) + printf("loading channel %s\n", "rdpdr"); + } + } + + return 1; +} diff --git a/cunit/test_gcc.c b/cunit/test_gcc.c index 7dde4e5cf..5d6e40a66 100644 --- a/cunit/test_gcc.c +++ b/cunit/test_gcc.c @@ -127,7 +127,7 @@ void test_gcc_write_client_core_data(void) rdpSettings* settings; s = stream_new(512); - settings = settings_new(NULL); + settings = freerdp_settings_new(NULL); settings->width = 1280; settings->height = 1024; @@ -154,7 +154,7 @@ void test_gcc_write_client_security_data(void) rdpSettings* settings; s = stream_new(12); - settings = settings_new(NULL); + settings = freerdp_settings_new(NULL); settings->DisableEncryption = 1; /* turn on encryption */ settings->EncryptionMethods = @@ -177,7 +177,7 @@ void test_gcc_write_client_cluster_data(void) rdpSettings* settings; s = stream_new(12); - settings = settings_new(NULL); + settings = freerdp_settings_new(NULL); gcc_write_client_cluster_data(s, settings); @@ -195,7 +195,7 @@ void test_gcc_write_client_network_data(void) rdpSettings* settings; s = stream_new(44); - settings = settings_new(NULL); + settings = freerdp_settings_new(NULL); settings->ChannelCount = 3; memset(settings->ChannelDefArray, 0, sizeof(rdpChannel) * settings->ChannelCount); diff --git a/include/freerdp/channels/rdpdr.h b/include/freerdp/channels/rdpdr.h index 983033b9c..6a4c6412a 100644 --- a/include/freerdp/channels/rdpdr.h +++ b/include/freerdp/channels/rdpdr.h @@ -78,16 +78,6 @@ enum RDPDR_CAP_VERSION SMARTCARD_CAPABILITY_VERSION_01 = 0x00000001 }; -/* DEVICE_ANNOUNCE.DeviceType */ -enum RDPDR_DTYP -{ - RDPDR_DTYP_SERIAL = 0x00000001, - RDPDR_DTYP_PARALLEL = 0x00000002, - RDPDR_DTYP_PRINT = 0x00000004, - RDPDR_DTYP_FILESYSTEM = 0x00000008, - RDPDR_DTYP_SMARTCARD = 0x00000020 -}; - /* DR_DEVICE_IOREQUEST.MajorFunction */ enum IRP_MJ { @@ -516,7 +506,7 @@ struct _DEVICE_SERVICE_ENTRY_POINTS DEVMAN* devman; pcRegisterDevice RegisterDevice; - RDP_PLUGIN_DATA* plugin_data; + RDPDR_DEVICE* device; }; typedef struct _DEVICE_SERVICE_ENTRY_POINTS DEVICE_SERVICE_ENTRY_POINTS; typedef DEVICE_SERVICE_ENTRY_POINTS* PDEVICE_SERVICE_ENTRY_POINTS; @@ -524,4 +514,3 @@ typedef DEVICE_SERVICE_ENTRY_POINTS* PDEVICE_SERVICE_ENTRY_POINTS; typedef int (*PDEVICE_SERVICE_ENTRY)(PDEVICE_SERVICE_ENTRY_POINTS); #endif /* FREERDP_CHANNEL_RDPDR_H */ - diff --git a/include/freerdp/client/cmdline.h b/include/freerdp/client/cmdline.h index fc355d5dc..96515bff6 100644 --- a/include/freerdp/client/cmdline.h +++ b/include/freerdp/client/cmdline.h @@ -24,6 +24,7 @@ #include FREERDP_API int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettings* settings); +FREERDP_API int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings); #endif /* FREERDP_CLIENT_CMDLINE */ diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index e12b66fa0..be5c72f89 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -21,6 +21,7 @@ #ifndef FREERDP_SETTINGS_H #define FREERDP_SETTINGS_H +#include #include /* Performance Flags */ @@ -360,6 +361,67 @@ struct rdp_monitor }; typedef struct rdp_monitor rdpMonitor; +/* Device Redirection */ + +#define RDPDR_DTYP_SERIAL 0x00000001 +#define RDPDR_DTYP_PARALLEL 0x00000002 +#define RDPDR_DTYP_PRINT 0x00000004 +#define RDPDR_DTYP_FILESYSTEM 0x00000008 +#define RDPDR_DTYP_SMARTCARD 0x00000020 + +struct _RDPDR_DEVICE +{ + UINT32 Id; + UINT32 Type; + char* Name; +}; +typedef struct _RDPDR_DEVICE RDPDR_DEVICE; + +struct _RDPDR_DRIVE +{ + UINT32 Id; + UINT32 Type; + char* Name; + char* Path; +}; +typedef struct _RDPDR_DRIVE RDPDR_DRIVE; + +struct _RDPDR_PRINTER +{ + UINT32 Id; + UINT32 Type; + char* Name; + char* DriverName; +}; +typedef struct _RDPDR_PRINTER RDPDR_PRINTER; + +struct _RDPDR_SMARTCARD +{ + UINT32 Id; + UINT32 Type; + char* Name; + char* Path; +}; +typedef struct _RDPDR_SMARTCARD RDPDR_SMARTCARD; + +struct _RDPDR_SERIAL +{ + UINT32 Id; + UINT32 Type; + char* Name; + char* Path; +}; +typedef struct _RDPDR_SERIAL RDPDR_SERIAL; + +struct _RDPDR_PARALLEL +{ + UINT32 Id; + UINT32 Type; + char* Name; + char* Path; +}; +typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL; + /* Settings */ #ifdef __GNUC__ @@ -840,9 +902,13 @@ struct rdp_settings /* Device Redirection */ ALIGN64 BOOL DeviceRedirection; /* */ + ALIGN64 UINT32 DeviceCount; /* */ + ALIGN64 UINT32 DeviceArraySize; /* */ + ALIGN64 RDPDR_DEVICE** DeviceArray; /* */ /* Drive Redirection */ ALIGN64 BOOL RedirectDrives; /* */ + ALIGN64 char* DrivesToRedirect; /* */ /* Smartcard Redirection */ ALIGN64 BOOL RedirectSmartCards; /* */ @@ -866,7 +932,9 @@ struct rdp_settings }; typedef struct rdp_settings rdpSettings; -rdpSettings* settings_new(void* instance); -void settings_free(rdpSettings* settings); +FREERDP_API void freerdp_device_collection_add(rdpSettings* settings, RDPDR_DEVICE* device); + +FREERDP_API rdpSettings* freerdp_settings_new(void* instance); +FREERDP_API void freerdp_settings_free(rdpSettings* settings); #endif /* FREERDP_SETTINGS_H */ diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index fc7ba4a4a..40f8fbced 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -919,7 +919,7 @@ rdpRdp* rdp_new(freerdp* instance) if (rdp != NULL) { rdp->instance = instance; - rdp->settings = settings_new((void*) instance); + rdp->settings = freerdp_settings_new((void*) instance); if (instance != NULL) instance->settings = rdp->settings; @@ -954,7 +954,7 @@ void rdp_free(rdpRdp* rdp) crypto_des3_free(rdp->fips_encrypt); crypto_des3_free(rdp->fips_decrypt); crypto_hmac_free(rdp->fips_hmac); - settings_free(rdp->settings); + freerdp_settings_free(rdp->settings); extension_free(rdp->extension); transport_free(rdp->transport); license_free(rdp->license); diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index fc18583dc..ead42d787 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -199,7 +199,7 @@ void settings_get_computer_name(rdpSettings* settings) GetComputerNameExA(ComputerNameNetBIOS, settings->ComputerName, &nSize); } -rdpSettings* settings_new(void* instance) +rdpSettings* freerdp_settings_new(void* instance) { rdpSettings* settings; @@ -394,6 +394,10 @@ rdpSettings* settings_new(void* instance) settings->ClientTimeZone = (TIME_ZONE_INFO*) malloc(sizeof(TIME_ZONE_INFO)); ZeroMemory(settings->ClientTimeZone, sizeof(TIME_ZONE_INFO)); + settings->DeviceArraySize = 16; + settings->DeviceArray = (RDPDR_DEVICE**) malloc(sizeof(RDPDR_DEVICE*) * settings->DeviceArraySize); + ZeroMemory(settings->DeviceArray, sizeof(RDPDR_DEVICE*) * settings->DeviceArraySize); + freerdp_detect_paths(settings); settings_load_hkey_local_machine(settings); @@ -402,7 +406,7 @@ rdpSettings* settings_new(void* instance) return settings; } -void settings_free(rdpSettings* settings) +void freerdp_settings_free(rdpSettings* settings) { if (settings != NULL) { @@ -412,6 +416,7 @@ void settings_free(rdpSettings* settings) free(settings->Domain); free(settings->AlternateShell); free(settings->ShellWorkingDirectory); + free(settings->ComputerName); free(settings->ChannelDefArray); free(settings->MonitorDefArray); free(settings->ClientAddress); @@ -435,10 +440,22 @@ void settings_free(rdpSettings* settings) key_free(settings->RdpServerRsaKey); free(settings->ConfigPath); free(settings->CurrentPath); + free(settings->DeviceArray); free(settings); } } +void freerdp_device_collection_add(rdpSettings* settings, RDPDR_DEVICE* device) +{ + if (settings->DeviceArraySize < (settings->DeviceCount + 1)) + { + settings->DeviceArraySize *= 2; + settings->DeviceArray = (RDPDR_DEVICE**) realloc(settings->DeviceArray, settings->DeviceArraySize); + } + + settings->DeviceArray[settings->DeviceCount++] = device; +} + #ifdef _WIN32 #pragma warning(pop) #endif diff --git a/libfreerdp/utils/args.c b/libfreerdp/utils/args.c index de979c987..8746d465c 100644 --- a/libfreerdp/utils/args.c +++ b/libfreerdp/utils/args.c @@ -708,18 +708,23 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv, { index++; t = index; + if (index == argc) { printf("missing plugin name\n"); return FREERDP_ARGS_PARSE_FAILURE; } + plugin_data = NULL; + if (strstr(argv[t], "rdpsnd")) settings->AudioPlayback = TRUE; + if (index < argc - 1 && strcmp("--data", argv[index + 1]) == 0) { index += 2; i = 0; + while (index < argc && strcmp("--", argv[index]) != 0) { if (plugin_data == NULL) @@ -756,6 +761,99 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv, index++; i++; } + + if (strstr(argv[t], "rdpdr")) + { + RDP_PLUGIN_DATA* data = plugin_data; + + printf("Device Redirection!\n"); + + while (data && data->size > 0) + { + printf("Device Type: %s\n", data->data[0]); + + if (strcmp(data->data[0], "drive") == 0) + { + RDPDR_DRIVE* drive; + + drive = (RDPDR_DRIVE*) malloc(sizeof(RDPDR_DRIVE)); + ZeroMemory(drive, sizeof(RDPDR_DRIVE)); + + drive->Type = RDPDR_DTYP_FILESYSTEM; + drive->Name = _strdup(data->data[1]); + drive->Path = _strdup(data->data[2]); + + freerdp_device_collection_add(settings, (RDPDR_DEVICE*) drive); + } + else if (strcmp(data->data[0], "printer") == 0) + { + RDPDR_PRINTER* printer; + + printer = (RDPDR_PRINTER*) malloc(sizeof(RDPDR_PRINTER)); + ZeroMemory(printer, sizeof(RDPDR_PRINTER)); + + printer->Type = RDPDR_DTYP_PRINT; + printer->Name = _strdup(data->data[1]); + + if (data->data[2]) + printer->DriverName = _strdup(data->data[2]); + + freerdp_device_collection_add(settings, (RDPDR_DEVICE*) printer); + } + else if (strcmp(data->data[0], "smartcard") == 0) + { + RDPDR_SMARTCARD* smartcard; + + smartcard = (RDPDR_SMARTCARD*) malloc(sizeof(RDPDR_SMARTCARD)); + ZeroMemory(smartcard, sizeof(RDPDR_SMARTCARD)); + + smartcard->Type = RDPDR_DTYP_SMARTCARD; + smartcard->Name = _strdup(data->data[1]); + smartcard->Path = _strdup(data->data[2]); + + freerdp_device_collection_add(settings, (RDPDR_DEVICE*) smartcard); + } + else if (strcmp(data->data[0], "serial") == 0) + { + RDPDR_SERIAL* serial; + + serial = (RDPDR_SERIAL*) malloc(sizeof(RDPDR_SERIAL)); + ZeroMemory(serial, sizeof(RDPDR_SERIAL)); + + serial->Type = RDPDR_DTYP_SERIAL; + serial->Name = _strdup(data->data[1]); + serial->Path = _strdup(data->data[2]); + + freerdp_device_collection_add(settings, (RDPDR_DEVICE*) serial); + } + else if (strcmp(data->data[0], "parallel") == 0) + { + RDPDR_PARALLEL* parallel; + + parallel = (RDPDR_PARALLEL*) malloc(sizeof(RDPDR_PARALLEL)); + ZeroMemory(parallel, sizeof(RDPDR_PARALLEL)); + + parallel->Type = RDPDR_DTYP_PARALLEL; + parallel->Name = _strdup(data->data[1]); + parallel->Path = _strdup(data->data[2]); + + freerdp_device_collection_add(settings, (RDPDR_DEVICE*) parallel); + } + else + { + printf("WARNING: unknown device type: %s\n", data->data[0]); + + if (strcmp(data->data[0], "disk") == 0) + printf("Maybe you meant \"drive\" instead of \"disk\"?\n"); + else if (strcmp(data->data[0], "scard") == 0) + printf("Maybe you meant \"smartcard\" instead of \"scard\"?\n"); + } + + data = (RDP_PLUGIN_DATA*) (((BYTE*) data) + data->size); + } + + plugin_data = (RDP_PLUGIN_DATA*) settings; + } } if (plugin_callback != NULL)