Unified DriveStoreRedirect parsing.
This commit is contained in:
parent
d8bf05367b
commit
fdf1715213
@ -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);
|
||||
|
@ -48,6 +48,83 @@
|
||||
#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_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)
|
||||
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,53 +412,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 char DynamicDrives[] = "DynamicDrives";
|
||||
const BOOL isPath = PathFileExistsA(params[2]);
|
||||
const BOOL isSpecial = (strncmp(params[2], "*", 2) == 0) ||
|
||||
(strncmp(params[2], DynamicDrives, sizeof(DynamicDrives)) == 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)
|
||||
{
|
||||
@ -3175,6 +3216,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)
|
||||
|
@ -51,7 +51,6 @@
|
||||
/*#define DEBUG_CLIENT_FILE 1*/
|
||||
|
||||
static const BYTE BOM_UTF16_LE[2] = { 0xFF, 0xFE };
|
||||
static const char DynamicDrives[] = "DynamicDrives";
|
||||
|
||||
#define INVALID_INTEGER_VALUE 0xFFFFFFFF
|
||||
|
||||
@ -786,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))
|
||||
{
|
||||
@ -1047,79 +1047,6 @@ size_t freerdp_client_write_rdp_file_buffer(const rdpFile* file, char* buffer, s
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
static BOOL freerdp_path_valid(const char* path, BOOL* special)
|
||||
{
|
||||
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_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;
|
||||
}
|
||||
|
||||
if (!path)
|
||||
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;
|
||||
}
|
||||
|
||||
BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* settings)
|
||||
{
|
||||
if (~((size_t)file->Domain))
|
||||
@ -1623,71 +1550,8 @@ 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 (!empty)
|
||||
{
|
||||
char* value;
|
||||
char* tok;
|
||||
char* context = NULL;
|
||||
|
||||
value = _strdup(file->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;
|
||||
}
|
||||
if (!freerdp_settings_set_string(settings, FreeRDP_DrivesToRedirect, file->DrivesToRedirect))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (~file->KeyboardHook)
|
||||
|
Loading…
Reference in New Issue
Block a user