Cleaned up RDPDR channel interhitance

* All channels inheriting from RDPDR_DRIVE base struct
* Add functions to create/free a new device of a type
* Fixed settings array resize code, prevent 0 sizes
This commit is contained in:
Armin Novak 2021-10-07 10:43:16 +02:00 committed by akallabeth
parent c627e2196f
commit 7d80c74e97
9 changed files with 398 additions and 464 deletions

View File

@ -31,6 +31,7 @@
#include <string.h>
#include <winpr/crt.h>
#include <winpr/assert.h>
#include <winpr/path.h>
#include <winpr/file.h>
#include <winpr/string.h>
@ -1017,7 +1018,12 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
char* bufdup;
char* devdup;
#endif
WINPR_ASSERT(pEntryPoints);
drive = (RDPDR_DRIVE*)pEntryPoints->device;
WINPR_ASSERT(drive);
#ifndef WIN32
sys_code_page = CP_UTF8;
@ -1045,7 +1051,8 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
}
}
error = drive_register_drive_path(pEntryPoints, drive->Name, drive->Path, drive->automount);
error =
drive_register_drive_path(pEntryPoints, drive->device.Name, drive->Path, drive->automount);
#else
sys_code_page = GetACP();
@ -1064,7 +1071,8 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
return CHANNEL_RC_NO_MEMORY;
}
error = drive_register_drive_path(pEntryPoints, drive->Name, drive->Path, drive->automount);
error = drive_register_drive_path(pEntryPoints, drive->device.Name, drive->Path,
drive->automount);
}
else if (strcmp(drive->Path, "*") == 0)
{
@ -1077,7 +1085,7 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
if (*dev > 'B')
{
/* Suppress disk drives A and B to avoid pesty messages */
len = sprintf_s(buf, sizeof(buf) - 4, "%s", drive->Name);
len = sprintf_s(buf, sizeof(buf) - 4, "%s", drive->device.Name);
buf[len] = '_';
buf[len + 1] = dev[0];
buf[len + 2] = 0;
@ -1104,7 +1112,8 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
}
else
{
error = drive_register_drive_path(pEntryPoints, drive->Name, drive->Path, drive->automount);
error = drive_register_drive_path(pEntryPoints, drive->device.Name, drive->Path,
drive->automount);
}
#endif

View File

@ -47,6 +47,7 @@
#endif
#include <winpr/crt.h>
#include <winpr/assert.h>
#include <winpr/synch.h>
#include <winpr/thread.h>
#include <winpr/stream.h>
@ -424,8 +425,13 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
RDPDR_PARALLEL* device;
PARALLEL_DEVICE* parallel;
UINT error;
WINPR_ASSERT(pEntryPoints);
device = (RDPDR_PARALLEL*)pEntryPoints->device;
name = device->Name;
WINPR_ASSERT(device);
name = device->device.Name;
path = device->Path;
if (!name || (name[0] == '*') || !path)

View File

@ -982,7 +982,7 @@ printer_DeviceServiceEntry
return ERROR_INVALID_PARAMETER;
device = (RDPDR_PRINTER*)pEntryPoints->device;
name = device->Name;
name = device->device.Name;
driver_name = _strdup(device->DriverName);
/* Secondary argument is one of the following:

View File

@ -127,6 +127,29 @@ static BOOL device_foreach(rdpdrPlugin* rdpdr, BOOL abortOnFail,
*/
static UINT rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL userLoggedOn);
static BOOL rdpdr_load_drive(rdpdrPlugin* rdpdr, const char* path, const char* name, BOOL automount)
{
UINT rc = ERROR_INTERNAL_ERROR;
union
{
RDPDR_DRIVE* drive;
RDPDR_DEVICE* device;
} drive;
const char* args[] = { name, path, automount ? NULL : name };
drive.device = freerdp_device_new(RDPDR_DTYP_FILESYSTEM, ARRAYSIZE(args), args);
if (!drive.device)
goto fail;
rc = devman_load_device_service(rdpdr->devman, drive.device, rdpdr->rdpcontext);
if (rc != CHANNEL_RC_OK)
goto fail;
fail:
freerdp_device_free(drive.device);
return rc;
}
/**
* Function description
*
@ -199,18 +222,12 @@ static void first_hotplug(rdpdrPlugin* rdpdr)
{
char drive_path[] = { 'c', ':', '\\', '\0' };
char drive_name[] = { 'c', '\0' };
RDPDR_DRIVE drive = { 0 };
drive_path[0] = 'A' + (char)i;
drive_name[0] = 'A' + (char)i;
if (check_path(drive_path))
{
drive.Type = RDPDR_DTYP_FILESYSTEM;
drive.Path = drive_path;
drive.Name = drive_name;
drive.automount = TRUE;
devman_load_device_service(rdpdr->devman, (const RDPDR_DEVICE*)&drive,
rdpdr->rdpcontext);
rdpdr_load_drive(rdpdr, drive_name, drive_path, TRUE);
}
}
@ -248,15 +265,7 @@ static LRESULT CALLBACK hotplug_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM
if (check_path(drive_path))
{
RDPDR_DRIVE drive = { 0 };
drive.Type = RDPDR_DTYP_FILESYSTEM;
drive.Path = drive_path;
drive.automount = TRUE;
drive.Name = drive_name;
devman_load_device_service(rdpdr->devman,
(const RDPDR_DEVICE*)&drive,
rdpdr->rdpcontext);
rdpdr_load_drive(rdpdr, drive_name, drive_path, TRUE);
rdpdr_send_device_list_announce_request(rdpdr, TRUE);
}
}
@ -531,30 +540,14 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr)
/* add new devices */
for (i = 0; i < size; i++)
{
if (dev_array[i].to_add)
const hotplug_dev* dev = &dev_array[i];
if (dev->to_add)
{
RDPDR_DRIVE drive = { 0 };
char* name;
drive.Type = RDPDR_DTYP_FILESYSTEM;
drive.Path = dev_array[i].path;
drive.automount = TRUE;
name = strrchr(drive.Path, '/') + 1;
drive.Name = name;
if (!drive.Name)
{
error = CHANNEL_RC_NO_MEMORY;
const char* path = dev->path;
const char* name = strrchr(path, '/') + 1;
error = rdpdr_load_drive(rdpdr, name, path, TRUE);
if (error)
goto cleanup;
}
if ((error = devman_load_device_service(rdpdr->devman, (RDPDR_DEVICE*)&drive,
rdpdr->rdpcontext)))
{
WLog_ERR(TAG, "devman_load_device_service failed!");
error = CHANNEL_RC_NO_MEMORY;
goto cleanup;
}
}
}
@ -929,34 +922,14 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr)
hotplug_dev* cur = &dev_array[i];
if (!device_already_plugged(rdpdr, cur))
{
RDPDR_DRIVE drive = { 0 };
char* name;
const char* path = cur->path;
const char* name = strrchr(path, '/') + 1;
drive.Type = RDPDR_DTYP_FILESYSTEM;
drive.Path = cur->path;
drive.automount = TRUE;
name = strrchr(drive.Path, '/') + 1;
drive.Name = name;
if (!drive.Name)
{
WLog_ERR(TAG, "_strdup failed!");
error = CHANNEL_RC_NO_MEMORY;
goto cleanup;
}
if ((error = devman_load_device_service(rdpdr->devman, (const RDPDR_DEVICE*)&drive,
rdpdr->rdpcontext)))
{
WLog_ERR(TAG, "devman_load_device_service failed!");
goto cleanup;
}
rdpdr_load_drive(rdpdr, name, path, TRUE);
error = ERROR_DISK_CHANGE;
}
}
cleanup:
for (i = 0; i < size; i++)
free(dev_array[i].path);

View File

@ -823,8 +823,13 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
SERIAL_DEVICE* serial;
#endif /* __linux__ */
UINT error = CHANNEL_RC_OK;
WINPR_ASSERT(pEntryPoints);
device = (RDPDR_SERIAL*)pEntryPoints->device;
name = device->Name;
WINPR_ASSERT(device);
name = device->device.Name;
path = device->Path;
driver = device->Driver;

View File

@ -145,14 +145,8 @@ static char* name_from_path(const char* path)
static BOOL freerdp_client_add_drive(rdpSettings* settings, const char* path, const char* name)
{
RDPDR_DRIVE* drive;
drive = (RDPDR_DRIVE*)calloc(1, sizeof(RDPDR_DRIVE));
if (!drive)
return FALSE;
drive->Type = RDPDR_DTYP_FILESYSTEM;
char* dname;
RDPDR_DEVICE* device = NULL;
if (name)
{
@ -169,36 +163,37 @@ static BOOL freerdp_client_add_drive(rdpSettings* settings, const char* path, co
}
if (name)
{
if (!(drive->Name = _strdup(name)))
goto fail;
}
dname = _strdup(name);
else /* We need a name to send to the server. */
{
if (!(drive->Name = name_from_path(path)))
goto fail;
}
dname = name_from_path(path);
if (!path || !freerdp_sanitize_drive_name(drive->Name, "\\/", "__"))
if (freerdp_sanitize_drive_name(dname, "\\/", "__"))
{
const char* args[] = { dname, path };
device = freerdp_device_new(RDPDR_DTYP_FILESYSTEM, ARRAYSIZE(args), args);
}
free(dname);
if (!device)
return FALSE;
if (!path)
goto fail;
else
{
BOOL isSpecial = FALSE;
BOOL isPath = freerdp_path_valid(path, &isSpecial);
if ((!isPath && !isSpecial) || !(drive->Path = _strdup(path)))
if (!isPath && !isSpecial)
goto fail;
}
if (!freerdp_device_collection_add(settings, (RDPDR_DEVICE*)drive))
if (!freerdp_device_collection_add(settings, device))
goto fail;
return TRUE;
fail:
free(drive->Path);
free(drive->Name);
free(drive);
freerdp_device_free(device);
return FALSE;
}
@ -552,6 +547,10 @@ static int freerdp_client_command_line_pre_filter(void* context, int index, int
BOOL freerdp_client_add_device_channel(rdpSettings* settings, size_t count, const char** params)
{
WINPR_ASSERT(settings);
WINPR_ASSERT(params);
WINPR_ASSERT(count > 0);
if (strcmp(params[0], "drive") == 0)
{
BOOL rc;
@ -568,7 +567,7 @@ BOOL freerdp_client_add_device_channel(rdpSettings* settings, size_t count, cons
}
else if (strcmp(params[0], "printer") == 0)
{
RDPDR_PRINTER* printer;
RDPDR_DEVICE* printer;
if (count < 1)
return FALSE;
@ -576,71 +575,36 @@ BOOL freerdp_client_add_device_channel(rdpSettings* settings, size_t count, cons
settings->RedirectPrinters = TRUE;
settings->DeviceRedirection = TRUE;
if (count > 1)
printer = freerdp_device_new(RDPDR_DTYP_PRINT, count - 1, &params[1]);
if (!printer)
return FALSE;
if (!freerdp_device_collection_add(settings, printer))
{
printer = (RDPDR_PRINTER*)calloc(1, sizeof(RDPDR_PRINTER));
if (!printer)
return FALSE;
printer->Type = RDPDR_DTYP_PRINT;
if (!(printer->Name = _strdup(params[1])))
{
free(printer);
return FALSE;
}
if (count > 2)
{
if (!(printer->DriverName = _strdup(params[2])))
{
free(printer->Name);
free(printer);
return FALSE;
}
}
if (!freerdp_device_collection_add(settings, (RDPDR_DEVICE*)printer))
{
free(printer->DriverName);
free(printer->Name);
free(printer);
return FALSE;
}
freerdp_device_free(printer);
return FALSE;
}
return TRUE;
}
else if (strcmp(params[0], "smartcard") == 0)
{
RDPDR_SMARTCARD* smartcard;
RDPDR_DEVICE* smartcard;
if (count < 1)
return FALSE;
settings->RedirectSmartCards = TRUE;
settings->DeviceRedirection = TRUE;
smartcard = (RDPDR_SMARTCARD*)calloc(1, sizeof(RDPDR_SMARTCARD));
smartcard = freerdp_device_new(RDPDR_DTYP_SMARTCARD, count - 1, &params[1]);
if (!smartcard)
return FALSE;
smartcard->Type = RDPDR_DTYP_SMARTCARD;
if (count > 1 && strlen(params[1]))
if (!freerdp_device_collection_add(settings, smartcard))
{
if (!(smartcard->Name = _strdup(params[1])))
{
free(smartcard);
return FALSE;
}
}
if (!freerdp_device_collection_add(settings, (RDPDR_DEVICE*)smartcard))
{
free(smartcard->Name);
free(smartcard);
freerdp_device_free(smartcard);
return FALSE;
}
@ -648,69 +612,22 @@ BOOL freerdp_client_add_device_channel(rdpSettings* settings, size_t count, cons
}
else if (strcmp(params[0], "serial") == 0)
{
RDPDR_SERIAL* serial;
RDPDR_DEVICE* serial;
if (count < 1)
return FALSE;
settings->RedirectSerialPorts = TRUE;
settings->DeviceRedirection = TRUE;
serial = (RDPDR_SERIAL*)calloc(1, sizeof(RDPDR_SERIAL));
serial = freerdp_device_new(RDPDR_DTYP_SERIAL, count - 1, &params[1]);
if (!serial)
return FALSE;
serial->Type = RDPDR_DTYP_SERIAL;
if (count > 1)
if (!freerdp_device_collection_add(settings, serial))
{
if (!(serial->Name = _strdup(params[1])))
{
free(serial);
return FALSE;
}
}
if (count > 2)
{
if (!(serial->Path = _strdup(params[2])))
{
free(serial->Name);
free(serial);
return FALSE;
}
}
if (count > 3)
{
if (!(serial->Driver = _strdup(params[3])))
{
free(serial->Path);
free(serial->Name);
free(serial);
return FALSE;
}
}
if (count > 4)
{
if (!(serial->Permissive = _strdup(params[4])))
{
free(serial->Driver);
free(serial->Path);
free(serial->Name);
free(serial);
return FALSE;
}
}
if (!freerdp_device_collection_add(settings, (RDPDR_DEVICE*)serial))
{
free(serial->Permissive);
free(serial->Driver);
free(serial->Path);
free(serial->Name);
free(serial);
freerdp_device_free(serial);
return FALSE;
}
@ -718,44 +635,22 @@ BOOL freerdp_client_add_device_channel(rdpSettings* settings, size_t count, cons
}
else if (strcmp(params[0], "parallel") == 0)
{
RDPDR_PARALLEL* parallel;
RDPDR_DEVICE* parallel;
if (count < 1)
return FALSE;
settings->RedirectParallelPorts = TRUE;
settings->DeviceRedirection = TRUE;
parallel = (RDPDR_PARALLEL*)calloc(1, sizeof(RDPDR_PARALLEL));
parallel = freerdp_device_new(RDPDR_DTYP_PARALLEL, count - 1, &params[1]);
if (!parallel)
return FALSE;
parallel->Type = RDPDR_DTYP_PARALLEL;
if (count > 1)
if (!freerdp_device_collection_add(settings, parallel))
{
if (!(parallel->Name = _strdup(params[1])))
{
free(parallel);
return FALSE;
}
}
if (count > 2)
{
if (!(parallel->Path = _strdup(params[2])))
{
free(parallel->Name);
free(parallel);
return FALSE;
}
}
if (!freerdp_device_collection_add(settings, (RDPDR_DEVICE*)parallel))
{
free(parallel->Path);
free(parallel->Name);
free(parallel);
freerdp_device_free(parallel);
return FALSE;
}
@ -977,7 +872,11 @@ static int freerdp_client_command_line_post_filter(void* context, COMMAND_LINE_A
{
settings->PasswordIsSmartcardPin = enable;
}
CommandLineSwitchEnd(arg) return status ? 1 : -1;
CommandLineSwitchEnd(arg)
return status
? 1
: -1;
}
BOOL freerdp_parse_username(const char* username, char** user, char** domain)
@ -3715,37 +3614,35 @@ BOOL freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings)
if (settings->RedirectSmartCards)
{
RDPDR_SMARTCARD* smartcard;
if (!freerdp_device_collection_find_type(settings, RDPDR_DTYP_SMARTCARD))
{
smartcard = (RDPDR_SMARTCARD*)calloc(1, sizeof(RDPDR_SMARTCARD));
RDPDR_DEVICE* smartcard = freerdp_device_new(RDPDR_DTYP_SMARTCARD, 0, NULL);
if (!smartcard)
return FALSE;
smartcard->Type = RDPDR_DTYP_SMARTCARD;
if (!freerdp_device_collection_add(settings, (RDPDR_DEVICE*)smartcard))
if (!freerdp_device_collection_add(settings, smartcard))
{
freerdp_device_free(smartcard);
return FALSE;
}
}
}
if (settings->RedirectPrinters)
{
RDPDR_PRINTER* printer;
if (!freerdp_device_collection_find_type(settings, RDPDR_DTYP_PRINT))
{
printer = (RDPDR_PRINTER*)calloc(1, sizeof(RDPDR_PRINTER));
RDPDR_DEVICE* printer = freerdp_device_new(RDPDR_DTYP_PRINT, 0, NULL);
if (!printer)
return FALSE;
printer->Type = RDPDR_DTYP_PRINT;
if (!freerdp_device_collection_add(settings, (RDPDR_DEVICE*)printer))
if (!freerdp_device_collection_add(settings, printer))
{
freerdp_device_free(printer);
return FALSE;
}
}
}

View File

@ -452,9 +452,7 @@ typedef struct _RDPDR_DEVICE RDPDR_DEVICE;
struct _RDPDR_DRIVE
{
UINT32 Id;
UINT32 Type;
char* Name;
RDPDR_DEVICE device;
char* Path;
BOOL automount;
};
@ -462,26 +460,20 @@ typedef struct _RDPDR_DRIVE RDPDR_DRIVE;
struct _RDPDR_PRINTER
{
UINT32 Id;
UINT32 Type;
char* Name;
RDPDR_DEVICE device;
char* DriverName;
};
typedef struct _RDPDR_PRINTER RDPDR_PRINTER;
struct _RDPDR_SMARTCARD
{
UINT32 Id;
UINT32 Type;
char* Name;
RDPDR_DEVICE device;
};
typedef struct _RDPDR_SMARTCARD RDPDR_SMARTCARD;
struct _RDPDR_SERIAL
{
UINT32 Id;
UINT32 Type;
char* Name;
RDPDR_DEVICE device;
char* Path;
char* Driver;
char* Permissive;
@ -490,9 +482,7 @@ typedef struct _RDPDR_SERIAL RDPDR_SERIAL;
struct _RDPDR_PARALLEL
{
UINT32 Id;
UINT32 Type;
char* Name;
RDPDR_DEVICE device;
char* Path;
};
typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
@ -1653,7 +1643,11 @@ extern "C"
const char* name);
FREERDP_API RDPDR_DEVICE* freerdp_device_collection_find_type(rdpSettings* settings,
UINT32 type);
FREERDP_API RDPDR_DEVICE* freerdp_device_clone(RDPDR_DEVICE* device);
FREERDP_API RDPDR_DEVICE* freerdp_device_new(UINT32 Type, size_t count, const char* args[]);
FREERDP_API RDPDR_DEVICE* freerdp_device_clone(const RDPDR_DEVICE* device);
FREERDP_API void freerdp_device_free(RDPDR_DEVICE* device);
FREERDP_API void freerdp_device_collection_free(rdpSettings* settings);
FREERDP_API BOOL freerdp_static_channel_collection_add(rdpSettings* settings,

View File

@ -208,15 +208,19 @@ int freerdp_addin_replace_argument_value(ADDIN_ARGV* args, const char* previous,
BOOL freerdp_device_collection_add(rdpSettings* settings, RDPDR_DEVICE* device)
{
if (!settings->DeviceArray)
return FALSE;
UINT32 count;
WINPR_ASSERT(settings);
WINPR_ASSERT(device);
if (freerdp_settings_get_uint32(settings, FreeRDP_DeviceArraySize) <
(settings->DeviceCount + 1))
count = settings->DeviceCount + 1;
if (freerdp_settings_get_uint32(settings, FreeRDP_DeviceArraySize) < count)
{
UINT32 new_size;
RDPDR_DEVICE** new_array;
new_size = freerdp_settings_get_uint32(settings, FreeRDP_DeviceArraySize) * 2;
if (new_size == 0)
new_size = count * 2;
new_array =
(RDPDR_DEVICE**)realloc(settings->DeviceArray, new_size * sizeof(RDPDR_DEVICE*));
@ -267,215 +271,267 @@ RDPDR_DEVICE* freerdp_device_collection_find_type(rdpSettings* settings, UINT32
return NULL;
}
RDPDR_DEVICE* freerdp_device_clone(RDPDR_DEVICE* device)
RDPDR_DEVICE* freerdp_device_new(UINT32 Type, size_t count, const char* args[])
{
if (device->Type == RDPDR_DTYP_FILESYSTEM)
size_t size;
union
{
RDPDR_DRIVE* drive = (RDPDR_DRIVE*)device;
RDPDR_DRIVE* _drive = (RDPDR_DRIVE*)calloc(1, sizeof(RDPDR_DRIVE));
RDPDR_DEVICE* base;
RDPDR_DRIVE* drive;
RDPDR_SERIAL* serial;
RDPDR_PRINTER* printer;
RDPDR_PARALLEL* parallel;
RDPDR_SMARTCARD* smartcard;
} device;
if (!_drive)
return NULL;
device.base = NULL;
WINPR_ASSERT(args || (count == 0));
_drive->Id = drive->Id;
_drive->Type = drive->Type;
_drive->Name = _strdup(drive->Name);
if (!_drive->Name)
goto out_fs_name_error;
_drive->Path = _strdup(drive->Path);
if (!_drive->Path)
goto out_fs_path_error;
return (RDPDR_DEVICE*)_drive;
out_fs_path_error:
free(_drive->Name);
out_fs_name_error:
free(_drive);
return NULL;
switch (Type)
{
case RDPDR_DTYP_PRINT:
size = sizeof(RDPDR_PRINTER);
break;
case RDPDR_DTYP_SERIAL:
size = sizeof(RDPDR_SERIAL);
break;
case RDPDR_DTYP_PARALLEL:
size = sizeof(RDPDR_PARALLEL);
break;
case RDPDR_DTYP_SMARTCARD:
size = sizeof(RDPDR_SMARTCARD);
break;
case RDPDR_DTYP_FILESYSTEM:
size = sizeof(RDPDR_DRIVE);
break;
default:
goto fail;
}
if (device->Type == RDPDR_DTYP_PRINT)
device.base = calloc(1, size);
if (!device.base)
goto fail;
device.base->Id = 0;
device.base->Type = Type;
if (count > 0)
{
RDPDR_PRINTER* printer = (RDPDR_PRINTER*)device;
RDPDR_PRINTER* _printer = (RDPDR_PRINTER*)calloc(1, sizeof(RDPDR_PRINTER));
device.base->Name = _strdup(args[1]);
if (!device.base->Name)
goto fail;
if (!_printer)
return NULL;
_printer->Id = printer->Id;
_printer->Type = printer->Type;
if (printer->Name)
switch (Type)
{
_printer->Name = _strdup(printer->Name);
case RDPDR_DTYP_PRINT:
if (count > 1)
{
device.printer->DriverName = _strdup(args[1]);
if (!device.printer->DriverName)
goto fail;
}
break;
case RDPDR_DTYP_SERIAL:
if (count > 1)
{
device.serial->Path = _strdup(args[1]);
if (!device.serial->Path)
goto fail;
}
if (!_printer->Name)
goto out_print_name_error;
if (count > 2)
{
device.serial->Driver = _strdup(args[2]);
if (!device.serial->Driver)
goto fail;
}
if (count > 3)
{
device.serial->Permissive = _strdup(args[1]);
if (!device.serial->Permissive)
goto fail;
}
size = sizeof(RDPDR_SERIAL);
break;
case RDPDR_DTYP_PARALLEL:
if (count > 1)
{
device.parallel->Path = _strdup(args[1]);
if (!device.serial->Path)
goto fail;
}
break;
case RDPDR_DTYP_SMARTCARD:
break;
case RDPDR_DTYP_FILESYSTEM:
if (count > 1)
{
device.drive->Path = _strdup(args[1]);
if (!device.drive->Path)
goto fail;
}
if (count > 2)
device.drive->automount = (args[2] == NULL) ? FALSE : TRUE;
break;
default:
goto fail;
}
}
return device.base;
if (printer->DriverName)
{
_printer->DriverName = _strdup(printer->DriverName);
fail:
freerdp_device_free(device.base);
return NULL;
}
if (!_printer->DriverName)
goto out_print_path_error;
}
void freerdp_device_free(RDPDR_DEVICE* device)
{
union
{
RDPDR_DEVICE* dev;
RDPDR_DRIVE* drive;
RDPDR_SERIAL* serial;
RDPDR_PRINTER* printer;
RDPDR_PARALLEL* parallel;
RDPDR_SMARTCARD* smartcard;
} cnv;
return (RDPDR_DEVICE*)_printer;
out_print_path_error:
free(_printer->Name);
out_print_name_error:
free(_printer);
cnv.dev = device;
if (!cnv.dev)
return;
switch (device->Type)
{
case RDPDR_DTYP_PRINT:
free(cnv.printer->DriverName);
break;
case RDPDR_DTYP_SERIAL:
free(cnv.serial->Path);
free(cnv.serial->Driver);
free(cnv.serial->Permissive);
break;
case RDPDR_DTYP_PARALLEL:
free(cnv.parallel->Path);
break;
case RDPDR_DTYP_SMARTCARD:
break;
case RDPDR_DTYP_FILESYSTEM:
free(cnv.drive->Path);
break;
default:
break;
}
free(cnv.dev->Name);
free(cnv.dev);
}
RDPDR_DEVICE* freerdp_device_clone(const RDPDR_DEVICE* device)
{
union
{
const RDPDR_DEVICE* dev;
const RDPDR_DRIVE* drive;
const RDPDR_SERIAL* serial;
const RDPDR_PRINTER* printer;
const RDPDR_PARALLEL* parallel;
const RDPDR_SMARTCARD* smartcard;
} src;
union
{
RDPDR_DEVICE* dev;
RDPDR_DRIVE* drive;
RDPDR_SERIAL* serial;
RDPDR_PRINTER* printer;
RDPDR_PARALLEL* parallel;
RDPDR_SMARTCARD* smartcard;
} copy;
WINPR_ASSERT(device);
src.dev = device;
copy.dev = freerdp_device_new(device->Id, device->Type, device->Name);
if (!copy.dev)
return NULL;
switch (device->Type)
{
case RDPDR_DTYP_FILESYSTEM:
{
if (src.drive->Path)
copy.drive->Path = _strdup(src.drive->Path);
if (!copy.drive->Path)
goto fail;
}
break;
case RDPDR_DTYP_PRINT:
{
if (copy.printer->DriverName)
{
copy.printer->DriverName = _strdup(src.printer->DriverName);
if (!copy.printer->DriverName)
goto fail;
}
}
break;
case RDPDR_DTYP_SMARTCARD:
break;
case RDPDR_DTYP_SERIAL:
{
if (copy.serial->Path)
{
copy.serial->Path = _strdup(src.serial->Path);
if (!copy.serial->Path)
goto fail;
}
if (copy.serial->Driver)
{
copy.serial->Driver = _strdup(src.serial->Driver);
if (!copy.serial->Driver)
goto fail;
}
}
break;
case RDPDR_DTYP_PARALLEL:
{
if (src.parallel->Path)
copy.parallel->Path = _strdup(src.parallel->Path);
if (!copy.parallel->Path)
goto fail;
}
break;
default:
WLog_ERR(TAG, "unknown device type %" PRIu32 "", device->Type);
break;
}
if (device->Type == RDPDR_DTYP_SMARTCARD)
{
RDPDR_SMARTCARD* smartcard = (RDPDR_SMARTCARD*)device;
RDPDR_SMARTCARD* _smartcard = (RDPDR_SMARTCARD*)calloc(1, sizeof(RDPDR_SMARTCARD));
return copy.dev;
if (!_smartcard)
return NULL;
_smartcard->Id = smartcard->Id;
_smartcard->Type = smartcard->Type;
if (smartcard->Name)
{
_smartcard->Name = _strdup(smartcard->Name);
if (!_smartcard->Name)
goto out_smartc_name_error;
}
return (RDPDR_DEVICE*)_smartcard;
out_smartc_name_error:
free(_smartcard);
return NULL;
}
if (device->Type == RDPDR_DTYP_SERIAL)
{
RDPDR_SERIAL* serial = (RDPDR_SERIAL*)device;
RDPDR_SERIAL* _serial = (RDPDR_SERIAL*)calloc(1, sizeof(RDPDR_SERIAL));
if (!_serial)
return NULL;
_serial->Id = serial->Id;
_serial->Type = serial->Type;
if (serial->Name)
{
_serial->Name = _strdup(serial->Name);
if (!_serial->Name)
goto out_serial_name_error;
}
if (serial->Path)
{
_serial->Path = _strdup(serial->Path);
if (!_serial->Path)
goto out_serial_path_error;
}
if (serial->Driver)
{
_serial->Driver = _strdup(serial->Driver);
if (!_serial->Driver)
goto out_serial_driver_error;
}
return (RDPDR_DEVICE*)_serial;
out_serial_driver_error:
free(_serial->Path);
out_serial_path_error:
free(_serial->Name);
out_serial_name_error:
free(_serial);
return NULL;
}
if (device->Type == RDPDR_DTYP_PARALLEL)
{
RDPDR_PARALLEL* parallel = (RDPDR_PARALLEL*)device;
RDPDR_PARALLEL* _parallel = (RDPDR_PARALLEL*)calloc(1, sizeof(RDPDR_PARALLEL));
if (!_parallel)
return NULL;
_parallel->Id = parallel->Id;
_parallel->Type = parallel->Type;
if (parallel->Name)
{
_parallel->Name = _strdup(parallel->Name);
if (!_parallel->Name)
goto out_parallel_name_error;
}
if (parallel->Path)
{
_parallel->Path = _strdup(parallel->Path);
if (!_parallel->Path)
goto out_parallel_path_error;
}
return (RDPDR_DEVICE*)_parallel;
out_parallel_path_error:
free(_parallel->Name);
out_parallel_name_error:
free(_parallel);
return NULL;
}
WLog_ERR(TAG, "unknown device type %" PRIu32 "", device->Type);
fail:
freerdp_device_free(copy.dev);
return NULL;
}
void freerdp_device_collection_free(rdpSettings* settings)
{
UINT32 index;
RDPDR_DEVICE* device;
WINPR_ASSERT(settings);
for (index = 0; index < settings->DeviceCount; index++)
{
device = (RDPDR_DEVICE*)settings->DeviceArray[index];
if (!device)
continue;
free(device->Name);
if (settings->DeviceArray[index]->Type == RDPDR_DTYP_FILESYSTEM)
{
free(((RDPDR_DRIVE*)device)->Path);
}
else if (settings->DeviceArray[index]->Type == RDPDR_DTYP_PRINT)
{
}
else if (settings->DeviceArray[index]->Type == RDPDR_DTYP_SMARTCARD)
{
}
else if (settings->DeviceArray[index]->Type == RDPDR_DTYP_SERIAL)
{
free(((RDPDR_SERIAL*)device)->Path);
free(((RDPDR_SERIAL*)device)->Driver);
}
else if (settings->DeviceArray[index]->Type == RDPDR_DTYP_PARALLEL)
{
free(((RDPDR_PARALLEL*)device)->Path);
}
free(device);
RDPDR_DEVICE* device = (RDPDR_DEVICE*)settings->DeviceArray[index];
freerdp_device_free(device);
}
free(settings->DeviceArray);
@ -511,15 +567,19 @@ BOOL freerdp_static_channel_collection_del(rdpSettings* settings, const char* na
BOOL freerdp_static_channel_collection_add(rdpSettings* settings, ADDIN_ARGV* channel)
{
UINT32 count;
if (!settings->StaticChannelArray)
return FALSE;
if (freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelArraySize) <
(freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelCount) + 1))
WINPR_ASSERT(settings);
WINPR_ASSERT(channel);
count = freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelCount) + 1;
if (freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelArraySize) < count)
{
UINT32 new_size;
ADDIN_ARGV** new_array;
new_size = freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelArraySize) * 2;
if (new_size == 0)
new_size = count * 2;
new_array =
(ADDIN_ARGV**)realloc(settings->StaticChannelArray, new_size * sizeof(ADDIN_ARGV*));
@ -541,6 +601,9 @@ ADDIN_ARGV* freerdp_static_channel_collection_find(rdpSettings* settings, const
UINT32 index;
ADDIN_ARGV* channel;
WINPR_ASSERT(settings);
WINPR_ASSERT(name);
for (index = 0; index < freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelCount);
index++)
{
@ -557,6 +620,9 @@ void freerdp_static_channel_collection_free(rdpSettings* settings)
{
UINT32 i;
if (!settings)
return;
for (i = 0; i < freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelCount); i++)
{
freerdp_addin_argv_free(settings->StaticChannelArray[i]);
@ -597,15 +663,18 @@ BOOL freerdp_dynamic_channel_collection_del(rdpSettings* settings, const char* n
BOOL freerdp_dynamic_channel_collection_add(rdpSettings* settings, ADDIN_ARGV* channel)
{
UINT32 count;
if (!settings->DynamicChannelArray)
return FALSE;
if (freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelArraySize) <
(freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelCount) + 1))
WINPR_ASSERT(settings);
WINPR_ASSERT(channel);
count = freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelCount) + 1;
if (freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelArraySize) < count)
{
ADDIN_ARGV** new_array;
const size_t size =
freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelArraySize) * 2;
size_t size = freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelArraySize) * 2;
if (size == 0)
size = count * 2;
new_array = realloc(settings->DynamicChannelArray, sizeof(ADDIN_ARGV*) * size);
if (!new_array)
@ -626,6 +695,9 @@ ADDIN_ARGV* freerdp_dynamic_channel_collection_find(const rdpSettings* settings,
UINT32 index;
ADDIN_ARGV* channel;
WINPR_ASSERT(settings);
WINPR_ASSERT(name);
for (index = 0; index < freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelCount);
index++)
{

View File

@ -584,28 +584,6 @@ rdpSettings* freerdp_settings_new(DWORD flags)
if (!settings->ClientTimeZone)
goto out_fail;
freerdp_settings_set_uint32(settings, FreeRDP_DeviceArraySize, 16);
settings->DeviceArray = (RDPDR_DEVICE**)calloc(
freerdp_settings_get_uint32(settings, FreeRDP_DeviceArraySize), sizeof(RDPDR_DEVICE*));
if (!settings->DeviceArray)
goto out_fail;
freerdp_settings_set_uint32(settings, FreeRDP_StaticChannelArraySize, 16);
settings->StaticChannelArray = (ADDIN_ARGV**)calloc(
freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelArraySize), sizeof(ADDIN_ARGV*));
if (!settings->StaticChannelArray)
goto out_fail;
freerdp_settings_set_uint32(settings, FreeRDP_DynamicChannelArraySize, 16);
settings->DynamicChannelArray =
(ADDIN_ARGV**)calloc(freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelArraySize),
sizeof(ADDIN_ARGV*));
if (!settings->DynamicChannelArray)
goto out_fail;
if (!freerdp_settings_set_bool(settings, FreeRDP_TcpKeepAlive, TRUE) ||
!freerdp_settings_set_uint32(settings, FreeRDP_TcpKeepAliveRetries, 3) ||
!freerdp_settings_set_uint32(settings, FreeRDP_TcpKeepAliveDelay, 5) ||