Merge pull request #5541 from akallabeth/rdp_file_full_drivestoredirect_parsing
Rdp file full drivestoredirect parsing
This commit is contained in:
commit
29f914f178
@ -884,6 +884,12 @@ static UINT drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints,
|
||||
DRIVE_DEVICE* drive;
|
||||
UINT error;
|
||||
|
||||
if (!pEntryPoints || !name || !path)
|
||||
{
|
||||
WLog_ERR(TAG, "[%s] Invalid parameters: pEntryPoints=%p, name=%p, path=%p", pEntryPoints, name, path);
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (name[0] && path[0])
|
||||
{
|
||||
size_t pathLength = strnlen(path, MAX_PATH);
|
||||
|
@ -764,14 +764,14 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr)
|
||||
char* line;
|
||||
char* word;
|
||||
unsigned int wlen;
|
||||
hotplug_dev dev_array[MAX_USB_DEVICES];
|
||||
hotplug_dev dev_array[MAX_USB_DEVICES] = { 0 };
|
||||
int i, j;
|
||||
int size = 0;
|
||||
int count;
|
||||
ULONG_PTR* keys = NULL;
|
||||
UINT32 ids[1];
|
||||
UINT error = 0;
|
||||
memset(dev_array, 0, sizeof(dev_array));
|
||||
|
||||
f = fopen("/proc/mounts", "r");
|
||||
|
||||
if (f == NULL)
|
||||
@ -1050,11 +1050,14 @@ static UINT rdpdr_process_connect(rdpdrPlugin* rdpdr)
|
||||
|
||||
if (device->Type == RDPDR_DTYP_FILESYSTEM)
|
||||
{
|
||||
const char DynamicDrives[] = "DynamicDrives";
|
||||
RDPDR_DRIVE* drive = (RDPDR_DRIVE*)device;
|
||||
|
||||
if (drive->Path && (strcmp(drive->Path, "*") == 0))
|
||||
BOOL hotplugAll = strncmp(drive->Path, "*", 2) == 0;
|
||||
BOOL hotplugLater = strncmp(drive->Path, DynamicDrives, sizeof(DynamicDrives)) == 0;
|
||||
if (drive->Path && (hotplugAll || hotplugLater))
|
||||
{
|
||||
first_hotplug(rdpdr);
|
||||
if (hotplugAll)
|
||||
first_hotplug(rdpdr);
|
||||
#ifndef _WIN32
|
||||
|
||||
if (!(rdpdr->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||
|
@ -48,6 +48,102 @@
|
||||
#include <freerdp/log.h>
|
||||
#define TAG CLIENT_TAG("common.cmdline")
|
||||
|
||||
static BOOL freerdp_path_valid(const char* path, BOOL* special)
|
||||
{
|
||||
const char DynamicDrives[] = "DynamicDrives";
|
||||
BOOL isPath = FALSE;
|
||||
BOOL isSpecial;
|
||||
if (!path)
|
||||
return FALSE;
|
||||
|
||||
isSpecial = (strncmp(path, "*", 2) == 0) ||
|
||||
(strncmp(path, DynamicDrives, sizeof(DynamicDrives)) == 0) ||
|
||||
(strncmp(path, "%", 2) == 0) ? TRUE : FALSE;
|
||||
if (!isSpecial)
|
||||
isPath = PathFileExistsA(path);
|
||||
|
||||
if (special)
|
||||
*special = isSpecial;
|
||||
|
||||
return isSpecial || isPath;
|
||||
}
|
||||
|
||||
static BOOL freerdp_sanitize_drive_name(char* name, const char* invalid, const char* replacement)
|
||||
{
|
||||
if (!name || !invalid || !replacement)
|
||||
return FALSE;
|
||||
if (strlen(invalid) != strlen(replacement))
|
||||
return FALSE;
|
||||
|
||||
while(*invalid != '\0')
|
||||
{
|
||||
const char what = *invalid++;
|
||||
const char with = *replacement++;
|
||||
|
||||
char* cur = name;
|
||||
while((cur = strchr(cur, what)) != NULL)
|
||||
*cur = with;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (name)
|
||||
{
|
||||
/* Path was entered as secondary argument, swap */
|
||||
if (PathFileExistsA(name))
|
||||
{
|
||||
const char* tmp = path;
|
||||
path = name;
|
||||
name = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
if (name)
|
||||
{
|
||||
if (!(drive->Name = _strdup(name)))
|
||||
goto fail;
|
||||
}
|
||||
else /* We need a name to send to the server. */
|
||||
if (!(drive->Name = _strdup(path)))
|
||||
goto fail;
|
||||
|
||||
if (!path || !freerdp_sanitize_drive_name(drive->Name, "\\/", "__"))
|
||||
goto fail;
|
||||
else
|
||||
{
|
||||
BOOL isSpecial = FALSE;
|
||||
BOOL isPath = freerdp_path_valid(path, &isSpecial);
|
||||
|
||||
if (isSpecial && name)
|
||||
goto fail;
|
||||
|
||||
if ((!isPath && !isSpecial) || !(drive->Path = _strdup(path)))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!freerdp_device_collection_add(settings, (RDPDR_DEVICE*) drive))
|
||||
goto fail;
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
free(drive->Path);
|
||||
free(drive->Name);
|
||||
free(drive);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL copy_value(const char* value, char** dst)
|
||||
{
|
||||
if (!dst || !value)
|
||||
@ -335,51 +431,17 @@ BOOL freerdp_client_add_device_channel(rdpSettings* settings, int count,
|
||||
{
|
||||
if (strcmp(params[0], "drive") == 0)
|
||||
{
|
||||
RDPDR_DRIVE* drive;
|
||||
|
||||
if (count < 3)
|
||||
BOOL rc;
|
||||
if (count < 2)
|
||||
return FALSE;
|
||||
|
||||
settings->DeviceRedirection = TRUE;
|
||||
drive = (RDPDR_DRIVE*) calloc(1, sizeof(RDPDR_DRIVE));
|
||||
if (count < 3)
|
||||
rc = freerdp_client_add_drive(settings, params[1], NULL);
|
||||
else
|
||||
rc = freerdp_client_add_drive(settings, params[2], params[1]);
|
||||
|
||||
if (!drive)
|
||||
return FALSE;
|
||||
|
||||
drive->Type = RDPDR_DTYP_FILESYSTEM;
|
||||
|
||||
if (count > 1)
|
||||
{
|
||||
if (!(drive->Name = _strdup(params[1])))
|
||||
{
|
||||
free(drive);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 2)
|
||||
{
|
||||
const BOOL isPath = PathFileExistsA(params[2]);
|
||||
const BOOL isSpecial = (strncmp(params[2], "*", 2) == 0) ||
|
||||
(strncmp(params[2], "%", 2) == 0) ? TRUE : FALSE;
|
||||
|
||||
if ((!isPath && !isSpecial) || !(drive->Path = _strdup(params[2])))
|
||||
{
|
||||
free(drive->Name);
|
||||
free(drive);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!freerdp_device_collection_add(settings, (RDPDR_DEVICE*) drive))
|
||||
{
|
||||
free(drive->Path);
|
||||
free(drive->Name);
|
||||
free(drive);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return rc;
|
||||
}
|
||||
else if (strcmp(params[0], "printer") == 0)
|
||||
{
|
||||
@ -3173,6 +3235,72 @@ BOOL freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings)
|
||||
TRUE; /* these RDP8 features require rdpdr to be registered */
|
||||
}
|
||||
|
||||
if (settings->DrivesToRedirect && (strlen(settings->DrivesToRedirect) != 0))
|
||||
{
|
||||
/*
|
||||
* Drives to redirect:
|
||||
*
|
||||
* Very similar to DevicesToRedirect, but can contain a
|
||||
* comma-separated list of drive letters to redirect.
|
||||
*/
|
||||
char* value;
|
||||
char* tok;
|
||||
char* context = NULL;
|
||||
|
||||
value = _strdup(settings->DrivesToRedirect);
|
||||
if (!value)
|
||||
return FALSE;
|
||||
|
||||
tok = strtok_s(value, ";", &context);
|
||||
if (!tok)
|
||||
{
|
||||
free(value);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
while(tok)
|
||||
{
|
||||
/* Syntax: Comma seperated list of the following entries:
|
||||
* '*' ... Redirect all drives, including hotplug
|
||||
* 'DynamicDrives' ... hotplug
|
||||
* <label>(<path>) ... One or more paths to redirect.
|
||||
* <path>(<label>) ... One or more paths to redirect.
|
||||
* <path> ... One or more paths to redirect.
|
||||
*/
|
||||
/* TODO: Need to properly escape labels and paths */
|
||||
BOOL success;
|
||||
const char* name = NULL;
|
||||
const char* drive = tok;
|
||||
char* start = strtok(tok, "(");
|
||||
char* end = strtok(NULL, ")");
|
||||
if (end)
|
||||
name = end;
|
||||
|
||||
if (freerdp_path_valid(name, NULL) && freerdp_path_valid(drive, NULL))
|
||||
{
|
||||
success = freerdp_client_add_drive(settings, name, NULL);
|
||||
if (success)
|
||||
success = freerdp_client_add_drive(settings, drive, NULL);
|
||||
}
|
||||
else
|
||||
success = freerdp_client_add_drive(settings, drive, name);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
free(value);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
tok = strtok_s(NULL, ";", &context);
|
||||
}
|
||||
free(value);
|
||||
|
||||
if (!freerdp_settings_set_bool(settings, FreeRDP_DeviceRedirection, TRUE))
|
||||
return FALSE;
|
||||
|
||||
settings->DeviceRedirection = TRUE;
|
||||
}
|
||||
|
||||
if (settings->RedirectDrives || settings->RedirectHomeDrive
|
||||
|| settings->RedirectSerialPorts
|
||||
|| settings->RedirectSmartCards || settings->RedirectPrinters)
|
||||
|
@ -44,12 +44,13 @@
|
||||
|
||||
#include <winpr/wtypes.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <freerdp/log.h>
|
||||
#define TAG CLIENT_TAG("common")
|
||||
|
||||
/*#define DEBUG_CLIENT_FILE 1*/
|
||||
|
||||
static BYTE BOM_UTF16_LE[2] = { 0xFF, 0xFE };
|
||||
static const BYTE BOM_UTF16_LE[2] = { 0xFF, 0xFE };
|
||||
|
||||
#define INVALID_INTEGER_VALUE 0xFFFFFFFF
|
||||
|
||||
@ -784,6 +785,7 @@ BOOL freerdp_client_populate_rdp_file_from_settings(rdpFile* file, const rdpSett
|
||||
SETTING_MODIFIED_SET_STRING(file->AlternateShell, settings, AlternateShell);
|
||||
SETTING_MODIFIED_SET_STRING(file->ShellWorkingDirectory, settings, ShellWorkingDirectory);
|
||||
SETTING_MODIFIED_SET(file->ConnectionType, settings, ConnectionType);
|
||||
SETTING_MODIFIED_SET_STRING(file->DrivesToRedirect, settings, DrivesToRedirect);
|
||||
|
||||
if (SETTING_MODIFIED(settings, AudioPlayback) || SETTING_MODIFIED(settings, RemoteConsoleAudio))
|
||||
{
|
||||
@ -1548,15 +1550,7 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
|
||||
|
||||
if (~((size_t)file->DrivesToRedirect))
|
||||
{
|
||||
/*
|
||||
* Drives to redirect:
|
||||
*
|
||||
* Very similar to DevicesToRedirect, but can contain a
|
||||
* comma-separated list of drive letters to redirect.
|
||||
*/
|
||||
const BOOL empty = !file->DrivesToRedirect || (strlen(file->DrivesToRedirect) == 0);
|
||||
|
||||
if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectDrives, !empty))
|
||||
if (!freerdp_settings_set_string(settings, FreeRDP_DrivesToRedirect, file->DrivesToRedirect))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -1597,6 +1591,7 @@ static rdpFileLine* freerdp_client_rdp_file_find_line_index(rdpFile* file, SSIZE
|
||||
line = &(file->lines[index]);
|
||||
return line;
|
||||
}
|
||||
|
||||
static rdpFileLine* freerdp_client_rdp_file_find_line_by_name(rdpFile* file, const char* name)
|
||||
{
|
||||
size_t index;
|
||||
|
Loading…
Reference in New Issue
Block a user