ADDIN_ARGV cleanup, added camera setting to RDP parser (#6947)

* Added camerastoredirect to RDP parser

* Refactored ADDIN_ARGV handling

* Added ADDIN_ARGV unit tests
This commit is contained in:
akallabeth 2021-04-12 10:38:40 +02:00 committed by GitHub
parent 6d2b44843e
commit ef6e4c0570
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 663 additions and 285 deletions

View File

@ -746,9 +746,13 @@ BOOL freerdp_client_add_device_channel(rdpSettings* settings, size_t count, char
return FALSE;
}
BOOL freerdp_client_del_static_channel(rdpSettings* settings, const char* name)
{
return freerdp_static_channel_collection_del(settings, name);
}
BOOL freerdp_client_add_static_channel(rdpSettings* settings, size_t count, char** params)
{
int index;
ADDIN_ARGV* args;
if (!settings || !params || !params[0] || (count > INT_MAX))
@ -757,49 +761,27 @@ BOOL freerdp_client_add_static_channel(rdpSettings* settings, size_t count, char
if (freerdp_static_channel_collection_find(settings, params[0]))
return TRUE;
args = (ADDIN_ARGV*)calloc(1, sizeof(ADDIN_ARGV));
args = freerdp_addin_argv_new(count, (const char**)params);
if (!args)
return FALSE;
args->argc = (int)count;
args->argv = (char**)calloc((size_t)args->argc, sizeof(char*));
if (!args->argv)
goto error_argv;
for (index = 0; index < args->argc; index++)
{
args->argv[index] = _strdup(params[index]);
if (!args->argv[index])
{
for (--index; index >= 0; --index)
free(args->argv[index]);
goto error_argv_strdup;
}
}
if (!freerdp_static_channel_collection_add(settings, args))
goto error_argv_index;
goto fail;
return TRUE;
error_argv_index:
for (index = 0; index < args->argc; index++)
free(args->argv[index]);
error_argv_strdup:
free(args->argv);
error_argv:
free(args);
fail:
freerdp_addin_argv_free(args);
return FALSE;
}
BOOL freerdp_client_del_dynamic_channel(rdpSettings* settings, const char* name)
{
return freerdp_dynamic_channel_collection_del(settings, name);
}
BOOL freerdp_client_add_dynamic_channel(rdpSettings* settings, size_t count, char** params)
{
int index;
ADDIN_ARGV* args;
if (!settings || !params || !params[0] || (count > INT_MAX))
@ -808,43 +790,18 @@ BOOL freerdp_client_add_dynamic_channel(rdpSettings* settings, size_t count, cha
if (freerdp_dynamic_channel_collection_find(settings, params[0]))
return TRUE;
args = (ADDIN_ARGV*)malloc(sizeof(ADDIN_ARGV));
args = freerdp_addin_argv_new(count, (const char**)params);
if (!args)
return FALSE;
args->argc = (int)count;
args->argv = (char**)calloc((size_t)args->argc, sizeof(char*));
if (!args->argv)
goto error_argv;
for (index = 0; index < args->argc; index++)
{
args->argv[index] = _strdup(params[index]);
if (!args->argv[index])
{
for (--index; index >= 0; --index)
free(args->argv[index]);
goto error_argv_strdup;
}
}
if (!freerdp_dynamic_channel_collection_add(settings, args))
goto error_argv_index;
goto fail;
return TRUE;
error_argv_index:
for (index = 0; index < args->argc; index++)
free(args->argv[index]);
error_argv_strdup:
free(args->argv);
error_argv:
free(args);
fail:
freerdp_addin_argv_free(args);
return FALSE;
}
@ -3503,7 +3460,6 @@ static BOOL freerdp_client_load_static_channel_addin(rdpChannels* channels, rdpS
BOOL freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings)
{
UINT32 index;
ADDIN_ARGV* args;
if (settings->AudioPlayback)
{
@ -3750,7 +3706,7 @@ BOOL freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings)
for (index = 0; index < settings->StaticChannelCount; index++)
{
args = settings->StaticChannelArray[index];
ADDIN_ARGV* args = settings->StaticChannelArray[index];
if (!freerdp_client_load_static_channel_addin(channels, settings, args->argv[0], args))
return FALSE;

View File

@ -291,7 +291,6 @@ static int freerdp_client_old_command_line_pre_filter(void* context, int index,
char *a, *p;
int i, j, t;
int old_index;
ADDIN_ARGV* args;
old_index = index;
index++;
t = index;
@ -299,20 +298,7 @@ static int freerdp_client_old_command_line_pre_filter(void* context, int index,
if (index == argc)
return -1;
args = (ADDIN_ARGV*)malloc(sizeof(ADDIN_ARGV));
if (!args)
return -1;
args->argv = (char**)calloc(argc, sizeof(char*));
if (!args->argv)
{
free(args);
return -1;
}
args->argc = 1;
if ((index < argc - 1) && strcmp("--data", argv[index + 1]) == 0)
{
@ -321,13 +307,15 @@ static int freerdp_client_old_command_line_pre_filter(void* context, int index,
while ((index < argc) && (strcmp("--", argv[index]) != 0))
{
args_handled++;
args->argc = 1;
ADDIN_ARGV* args = freerdp_addin_argv_new(0, NULL);
if (!(args->argv[0] = _strdup(argv[t])))
if (!args)
return -1;
args_handled++;
if (!freerdp_addin_argv_add_argument(args, argv[t]))
{
free(args->argv);
free(args);
freerdp_addin_argv_free(args);
return -1;
}
@ -355,34 +343,22 @@ static int freerdp_client_old_command_line_pre_filter(void* context, int index,
{
length = (int)(p - a);
if (!(args->argv[j + 1] = (char*)malloc(length + 1)))
if (!freerdp_addin_argv_add_argument_ex(args, a, length))
{
for (; j >= 0; --j)
free(args->argv[j]);
free(args->argv);
free(args);
freerdp_addin_argv_free(args);
return -1;
}
CopyMemory(args->argv[j + 1], a, length);
args->argv[j + 1][length] = '\0';
p++;
}
else
{
if (!(args->argv[j + 1] = _strdup(a)))
if (!freerdp_addin_argv_add_argument(args, a))
{
for (; j >= 0; --j)
free(args->argv[j]);
free(args->argv);
free(args);
freerdp_addin_argv_free(args);
return -1;
}
}
args->argc++;
}
if (settings)
@ -390,10 +366,7 @@ static int freerdp_client_old_command_line_pre_filter(void* context, int index,
freerdp_client_old_process_plugin(settings, args);
}
for (j = 0; j < args->argc; j++)
free(args->argv[j]);
memset(args->argv, 0, argc * sizeof(char*));
freerdp_addin_argv_free(args);
index++;
i++;
}
@ -402,20 +375,22 @@ static int freerdp_client_old_command_line_pre_filter(void* context, int index,
{
if (settings)
{
if (!(args->argv[0] = _strdup(argv[t])))
ADDIN_ARGV* args = freerdp_addin_argv_new(0, NULL);
if (!args)
return -1;
if (!freerdp_addin_argv_add_argument(args, argv[t]))
{
free(args->argv);
free(args);
freerdp_addin_argv_free(args);
return -1;
}
args_handled = freerdp_client_old_process_plugin(settings, args);
free(args->argv[0]);
freerdp_addin_argv_free(args);
}
}
free(args->argv);
free(args);
return (index - old_index) + args_handled;
}

View File

@ -136,6 +136,7 @@ struct rdp_file
DWORD RedirectPrinters; /* redirectprinters */
DWORD RedirectComPorts; /* redirectcomports */
DWORD RedirectSmartCards; /* redirectsmartcards */
LPSTR RedirectCameras; /* camerastoredirect */
DWORD RedirectClipboard; /* redirectclipboard */
DWORD RedirectPosDevices; /* redirectposdevices */
DWORD RedirectDirectX; /* redirectdirectx */
@ -195,9 +196,7 @@ struct rdp_file
size_t lineSize;
rdpFileLine* lines;
size_t argc;
char** argv;
size_t argSize;
ADDIN_ARGV* args;
void* context;
DWORD flags;
@ -431,6 +430,8 @@ static int freerdp_client_rdp_file_set_string(rdpFile* file, const char* name, c
tmp = &file->AlternateFullAddress;
else if (_stricmp(name, "usbdevicestoredirect") == 0)
tmp = &file->UsbDevicesToRedirect;
else if (_stricmp(name, "camerastoredirect") == 0)
tmp = &file->RedirectCameras;
else if (_stricmp(name, "loadbalanceinfo") == 0)
tmp = &file->LoadBalanceInfo;
else if (_stricmp(name, "remoteapplicationname") == 0)
@ -498,27 +499,7 @@ static int freerdp_client_rdp_file_set_string(rdpFile* file, const char* name, c
static BOOL freerdp_client_add_option(rdpFile* file, const char* option)
{
while ((file->argc + 1) > file->argSize)
{
size_t new_size;
char** new_argv;
new_size = file->argSize * 2;
new_argv = (char**)realloc(file->argv, new_size * sizeof(char*));
if (!new_argv)
return FALSE;
file->argv = new_argv;
file->argSize = new_size;
}
file->argv[file->argc] = _strdup(option);
if (!file->argv[file->argc])
return FALSE;
(file->argc)++;
return TRUE;
return freerdp_addin_argv_add_argument(file->args, option);
}
static SSIZE_T freerdp_client_parse_rdp_file_add_line(rdpFile* file, const char* line,
@ -625,6 +606,8 @@ static BOOL trim_strings(rdpFile* file)
return FALSE;
if (!trim(&file->UsbDevicesToRedirect))
return FALSE;
if (!trim(&file->RedirectCameras))
return FALSE;
if (!trim(&file->LoadBalanceInfo))
return FALSE;
if (!trim(&file->GatewayHostname))
@ -858,6 +841,15 @@ BOOL freerdp_client_parse_rdp_file_ex(rdpFile* file, const char* name, rdp_file_
} \
} while (0)
static char* freerdp_client_channel_args_to_string(const rdpSettings* settings, const char* channel)
{
ADDIN_ARGV* args = freerdp_dynamic_channel_collection_find(settings, channel);
if (!args || (args->argc < 2))
return NULL;
return CommandLineToCommaSeparatedValues(args->argc - 1, args->argv + 1);
}
BOOL freerdp_client_populate_rdp_file_from_settings(rdpFile* file, const rdpSettings* settings)
{
FILE_POPULATE_STRING(file->Domain, settings->Domain);
@ -948,6 +940,7 @@ BOOL freerdp_client_populate_rdp_file_from_settings(rdpFile* file, const rdpSett
file->NetworkAutoDetect = settings->NetworkAutoDetect ? 0 : 1;
file->AutoReconnectionEnabled = settings->AutoReconnectionEnabled;
file->RedirectSmartCards = settings->RedirectSmartCards;
file->RedirectCameras = freerdp_client_channel_args_to_string(settings, "rdpecam");
file->RedirectClipboard = settings->RedirectClipboard;
file->RedirectPrinters = settings->RedirectPrinters;
file->RedirectDrives = settings->RedirectDrives;
@ -1171,6 +1164,7 @@ size_t freerdp_client_write_rdp_file_buffer(const rdpFile* file, char* buffer, s
WRITE_SETTING_STR("full address:s:%s", file->FullAddress);
WRITE_SETTING_STR("alternate full address:s:%s", file->AlternateFullAddress);
WRITE_SETTING_STR("usbdevicestoredirect:s:%s", file->UsbDevicesToRedirect);
WRITE_SETTING_STR("camerastoredirect:s:%s", file->RedirectCameras);
WRITE_SETTING_STR("loadbalanceinfo:s:%s", file->LoadBalanceInfo);
WRITE_SETTING_STR("remoteapplicationname:s:%s", file->RemoteApplicationName);
WRITE_SETTING_STR("remoteapplicationicon:s:%s", file->RemoteApplicationIcon);
@ -1800,6 +1794,17 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
return FALSE;
}
if (~((size_t)file->RedirectCameras))
{
BOOL status;
char** p;
size_t count;
p = CommandLineParseCommaSeparatedValuesEx("rdpecam", file->RedirectCameras, &count);
status = freerdp_client_add_dynamic_channel(settings, count, p);
free(p);
/* Ignore return */ WINPR_UNUSED(status);
}
if (~file->KeyboardHook)
{
if (!freerdp_settings_set_uint32(settings, FreeRDP_KeyboardHook, file->KeyboardHook))
@ -1814,13 +1819,13 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
return FALSE;
}
if (file->argc > 1)
if (file->args->argc > 1)
{
char* ConnectionFile = settings->ConnectionFile;
settings->ConnectionFile = NULL;
if (freerdp_client_settings_parse_command_line(settings, (int)file->argc, file->argv,
FALSE) < 0)
if (freerdp_client_settings_parse_command_line(settings, (int)file->args->argc,
file->args->argv, FALSE) < 0)
return FALSE;
settings->ConnectionFile = ConnectionFile;
@ -2020,21 +2025,14 @@ rdpFile* freerdp_client_rdp_file_new_ex(DWORD flags)
file->flags = flags;
FillMemory(file, sizeof(rdpFile), 0xFF);
file->argv = NULL;
file->lines = NULL;
file->lineCount = 0;
file->lineSize = 32;
file->GatewayProfileUsageMethod = 1;
file->lines = (rdpFileLine*)calloc(file->lineSize, sizeof(rdpFileLine));
if (!file->lines)
goto fail;
file->argc = 0;
file->argSize = 32;
file->argv = (char**)calloc(file->argSize, sizeof(char*));
if (!file->argv)
file->args = freerdp_addin_argv_new(0, NULL);
if (!file->lines || !file->args)
goto fail;
if (!freerdp_client_add_option(file, "freerdp"))
@ -2061,13 +2059,7 @@ void freerdp_client_rdp_file_free(rdpFile* file)
}
free(file->lines);
if (file->argv)
{
size_t i;
for (i = 0; i < file->argc; i++)
free(file->argv[i]);
}
free(file->argv);
freerdp_addin_argv_free(file->args);
freerdp_client_file_string_check_free(file->Username);
freerdp_client_file_string_check_free(file->Domain);
@ -2075,6 +2067,7 @@ void freerdp_client_rdp_file_free(rdpFile* file)
freerdp_client_file_string_check_free(file->FullAddress);
freerdp_client_file_string_check_free(file->AlternateFullAddress);
freerdp_client_file_string_check_free(file->UsbDevicesToRedirect);
freerdp_client_file_string_check_free(file->RedirectCameras);
freerdp_client_file_string_check_free(file->LoadBalanceInfo);
freerdp_client_file_string_check_free(file->RemoteApplicationName);
freerdp_client_file_string_check_free(file->RemoteApplicationIcon);

View File

@ -54,8 +54,10 @@ extern "C"
char** params);
FREERDP_API BOOL freerdp_client_add_static_channel(rdpSettings* settings, size_t count,
char** params);
FREERDP_API BOOL freerdp_client_del_static_channel(rdpSettings* settings, const char* name);
FREERDP_API BOOL freerdp_client_add_dynamic_channel(rdpSettings* settings, size_t count,
char** params);
FREERDP_API BOOL freerdp_client_del_dynamic_channel(rdpSettings* settings, const char* name);
#ifdef __cplusplus
}

View File

@ -1608,12 +1608,22 @@ extern "C"
FREERDP_API void freerdp_settings_dump(wLog* log, DWORD level, const rdpSettings* settings);
FREERDP_API int freerdp_addin_set_argument(ADDIN_ARGV* args, char* argument);
FREERDP_API int freerdp_addin_replace_argument(ADDIN_ARGV* args, char* previous,
char* argument);
FREERDP_API int freerdp_addin_set_argument_value(ADDIN_ARGV* args, char* option, char* value);
FREERDP_API int freerdp_addin_replace_argument_value(ADDIN_ARGV* args, char* previous,
char* option, char* value);
FREERDP_API ADDIN_ARGV* freerdp_addin_argv_new(size_t argc, const char* argv[]);
FREERDP_API ADDIN_ARGV* freerdp_addin_argv_clone(const ADDIN_ARGV* args);
FREERDP_API void freerdp_addin_argv_free(ADDIN_ARGV* args);
FREERDP_API BOOL freerdp_addin_argv_add_argument(ADDIN_ARGV* args, const char* argument);
FREERDP_API BOOL freerdp_addin_argv_add_argument_ex(ADDIN_ARGV* args, const char* argument,
size_t len);
FREERDP_API BOOL freerdp_addin_argv_del_argument(ADDIN_ARGV* args, const char* argument);
FREERDP_API int freerdp_addin_set_argument(ADDIN_ARGV* args, const char* argument);
FREERDP_API int freerdp_addin_replace_argument(ADDIN_ARGV* args, const char* previous,
const char* argument);
FREERDP_API int freerdp_addin_set_argument_value(ADDIN_ARGV* args, const char* option,
const char* value);
FREERDP_API int freerdp_addin_replace_argument_value(ADDIN_ARGV* args, const char* previous,
const char* option, const char* value);
FREERDP_API BOOL freerdp_device_collection_add(rdpSettings* settings, RDPDR_DEVICE* device);
FREERDP_API RDPDR_DEVICE* freerdp_device_collection_find(rdpSettings* settings,
@ -1625,16 +1635,21 @@ extern "C"
FREERDP_API BOOL freerdp_static_channel_collection_add(rdpSettings* settings,
ADDIN_ARGV* channel);
FREERDP_API BOOL freerdp_static_channel_collection_del(rdpSettings* settings, const char* name);
FREERDP_API ADDIN_ARGV* freerdp_static_channel_collection_find(rdpSettings* settings,
const char* name);
FREERDP_API ADDIN_ARGV* freerdp_static_channel_clone(ADDIN_ARGV* channel);
FREERDP_API WINPR_DEPRECATED(ADDIN_ARGV* freerdp_static_channel_clone(ADDIN_ARGV* channel));
FREERDP_API void freerdp_static_channel_collection_free(rdpSettings* settings);
FREERDP_API BOOL freerdp_dynamic_channel_collection_add(rdpSettings* settings,
ADDIN_ARGV* channel);
FREERDP_API BOOL freerdp_dynamic_channel_collection_del(rdpSettings* settings,
const char* name);
FREERDP_API ADDIN_ARGV* freerdp_dynamic_channel_collection_find(rdpSettings* settings,
const char* name);
FREERDP_API ADDIN_ARGV* freerdp_dynamic_channel_clone(ADDIN_ARGV* channel);
FREERDP_API WINPR_DEPRECATED(ADDIN_ARGV* freerdp_dynamic_channel_clone(ADDIN_ARGV* channel));
FREERDP_API void freerdp_dynamic_channel_collection_free(rdpSettings* settings);
FREERDP_API void freerdp_target_net_addresses_free(rdpSettings* settings);

View File

@ -37,10 +37,63 @@
#define TAG FREERDP_TAG("common")
int freerdp_addin_set_argument(ADDIN_ARGV* args, char* argument)
BOOL freerdp_addin_argv_add_argument_ex(ADDIN_ARGV* args, const char* argument, size_t len)
{
char* str;
char** new_argv;
if (!args || !argument)
return FALSE;
if (len == 0)
len = strlen(argument);
new_argv = (char**)realloc(args->argv, sizeof(char*) * (args->argc + 1));
if (!new_argv)
return FALSE;
args->argv = new_argv;
str = calloc(len + 1, sizeof(char));
if (!str)
return FALSE;
memcpy(str, argument, len);
args->argv[args->argc++] = str;
return TRUE;
}
BOOL freerdp_addin_argv_add_argument(ADDIN_ARGV* args, const char* argument)
{
return freerdp_addin_argv_add_argument_ex(args, argument, 0);
}
BOOL freerdp_addin_argv_del_argument(ADDIN_ARGV* args, const char* argument)
{
int x;
if (!args || !argument)
return FALSE;
for (x = 0; x < args->argc; x++)
{
char* arg = args->argv[x];
if (strcmp(argument, arg) == 0)
{
free(arg);
memmove_s(&args->argv[x], (args->argc - x) * sizeof(char*), &args->argv[x + 1],
(args->argc - x - 1) * sizeof(char*));
args->argv[args->argc - 1] = NULL;
args->argc--;
return TRUE;
}
}
return FALSE;
}
int freerdp_addin_set_argument(ADDIN_ARGV* args, const char* argument)
{
int i;
char** new_argv;
if (!args || !argument)
return -2;
for (i = 0; i < args->argc; i++)
{
@ -50,24 +103,17 @@ int freerdp_addin_set_argument(ADDIN_ARGV* args, char* argument)
}
}
new_argv = (char**)realloc(args->argv, sizeof(char*) * (args->argc + 1));
if (!new_argv)
if (!freerdp_addin_argv_add_argument(args, argument))
return -1;
args->argv = new_argv;
args->argc++;
if (!(args->argv[args->argc - 1] = _strdup(argument)))
return -1;
return 0;
}
int freerdp_addin_replace_argument(ADDIN_ARGV* args, char* previous, char* argument)
int freerdp_addin_replace_argument(ADDIN_ARGV* args, const char* previous, const char* argument)
{
int i;
char** new_argv;
if (!args || !previous || !argument)
return -2;
for (i = 0; i < args->argc; i++)
{
@ -82,29 +128,22 @@ int freerdp_addin_replace_argument(ADDIN_ARGV* args, char* previous, char* argum
}
}
new_argv = (char**)realloc(args->argv, sizeof(char*) * (args->argc + 1));
if (!new_argv)
if (!freerdp_addin_argv_add_argument(args, argument))
return -1;
args->argv = new_argv;
args->argc++;
if (!(args->argv[args->argc - 1] = _strdup(argument)))
return -1;
return 0;
}
int freerdp_addin_set_argument_value(ADDIN_ARGV* args, char* option, char* value)
int freerdp_addin_set_argument_value(ADDIN_ARGV* args, const char* option, const char* value)
{
BOOL rc;
int i;
char* p;
char* str;
size_t length;
char** new_argv;
if (!args || !option || !value)
return -2;
length = strlen(option) + strlen(value) + 1;
str = (char*)malloc(length + 1);
str = (char*)calloc(length + 1, sizeof(char));
if (!str)
return -1;
@ -126,29 +165,24 @@ int freerdp_addin_set_argument_value(ADDIN_ARGV* args, char* option, char* value
}
}
new_argv = (char**)realloc(args->argv, sizeof(char*) * (args->argc + 1));
if (!new_argv)
{
free(str);
rc = freerdp_addin_argv_add_argument(args, str);
free(str);
if (!rc)
return -1;
}
args->argv = new_argv;
args->argc++;
args->argv[args->argc - 1] = str;
return 0;
}
int freerdp_addin_replace_argument_value(ADDIN_ARGV* args, char* previous, char* option,
char* value)
int freerdp_addin_replace_argument_value(ADDIN_ARGV* args, const char* previous, const char* option,
const char* value)
{
int i;
BOOL rc;
char* str;
size_t length;
char** new_argv;
if (!args || !previous || !option || !value)
return -2;
length = strlen(option) + strlen(value) + 1;
str = (char*)malloc(length + 1);
str = (char*)calloc(length + 1, sizeof(char));
if (!str)
return -1;
@ -165,17 +199,10 @@ int freerdp_addin_replace_argument_value(ADDIN_ARGV* args, char* previous, char*
}
}
new_argv = (char**)realloc(args->argv, sizeof(char*) * (args->argc + 1));
if (!new_argv)
{
free(str);
rc = freerdp_addin_argv_add_argument(args, str);
free(str);
if (!rc)
return -1;
}
args->argv = new_argv;
args->argc++;
args->argv[args->argc - 1] = str;
return 0;
}
@ -457,6 +484,30 @@ void freerdp_device_collection_free(rdpSettings* settings)
settings->DeviceCount = 0;
}
BOOL freerdp_static_channel_collection_del(rdpSettings* settings, const char* name)
{
UINT32 x;
const UINT32 count = freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelCount);
if (!settings || !settings->StaticChannelArray)
return FALSE;
for (x = 0; x < count; x++)
{
ADDIN_ARGV* cur = settings->StaticChannelArray[x];
if (cur && (cur->argc > 0))
{
if (strcmp(name, cur->argv[0]) == 0)
{
memmove_s(&settings->StaticChannelArray[x], (count - x) * sizeof(ADDIN_ARGV*),
&settings->StaticChannelArray[x + 1],
(count - x - 1) * sizeof(ADDIN_ARGV*));
return freerdp_settings_set_uint32(settings, FreeRDP_StaticChannelCount, count - 1);
}
}
}
return FALSE;
}
BOOL freerdp_static_channel_collection_add(rdpSettings* settings, ADDIN_ARGV* channel)
{
UINT32 count;
@ -502,55 +553,13 @@ ADDIN_ARGV* freerdp_static_channel_collection_find(rdpSettings* settings, const
return NULL;
}
ADDIN_ARGV* freerdp_static_channel_clone(ADDIN_ARGV* channel)
{
int index;
ADDIN_ARGV* _channel = NULL;
_channel = (ADDIN_ARGV*)malloc(sizeof(ADDIN_ARGV));
if (!_channel)
return NULL;
_channel->argc = channel->argc;
_channel->argv = (char**)calloc(channel->argc, sizeof(char*));
if (!_channel->argv)
goto out_free;
for (index = 0; index < _channel->argc; index++)
{
_channel->argv[index] = _strdup(channel->argv[index]);
if (!_channel->argv[index])
goto out_release_args;
}
return _channel;
out_release_args:
for (index = 0; _channel->argv[index]; index++)
free(_channel->argv[index]);
out_free:
free(_channel);
return NULL;
}
void freerdp_static_channel_collection_free(rdpSettings* settings)
{
int j;
UINT32 i;
for (i = 0; i < freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelCount); i++)
{
if (!settings->StaticChannelArray[i])
continue;
for (j = 0; j < settings->StaticChannelArray[i]->argc; j++)
free(settings->StaticChannelArray[i]->argv[j]);
free(settings->StaticChannelArray[i]->argv);
free(settings->StaticChannelArray[i]);
freerdp_addin_argv_free(settings->StaticChannelArray[i]);
}
free(settings->StaticChannelArray);
@ -559,6 +568,32 @@ void freerdp_static_channel_collection_free(rdpSettings* settings)
freerdp_settings_set_uint32(settings, FreeRDP_StaticChannelCount, 0);
}
BOOL freerdp_dynamic_channel_collection_del(rdpSettings* settings, const char* name)
{
UINT32 x;
const UINT32 count = freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelCount);
if (!settings || !settings->DynamicChannelArray)
return FALSE;
for (x = 0; x < count; x++)
{
ADDIN_ARGV* cur = settings->DynamicChannelArray[x];
if (cur && (cur->argc > 0))
{
if (strcmp(name, cur->argv[0]))
{
memmove_s(&settings->DynamicChannelArray[x], (count - x) * sizeof(ADDIN_ARGV*),
&settings->DynamicChannelArray[x + 1],
(count - x - 1) * sizeof(ADDIN_ARGV*));
return freerdp_settings_set_uint32(settings, FreeRDP_DynamicChannelCount,
count - 1);
}
}
}
return FALSE;
}
BOOL freerdp_dynamic_channel_collection_add(rdpSettings* settings, ADDIN_ARGV* channel)
{
UINT32 count;
@ -603,55 +638,66 @@ ADDIN_ARGV* freerdp_dynamic_channel_collection_find(rdpSettings* settings, const
return NULL;
}
ADDIN_ARGV* freerdp_dynamic_channel_clone(ADDIN_ARGV* channel)
void freerdp_addin_argv_free(ADDIN_ARGV* args)
{
int index;
ADDIN_ARGV* _channel = NULL;
_channel = (ADDIN_ARGV*)malloc(sizeof(ADDIN_ARGV));
if (!args)
return;
if (!_channel)
return NULL;
_channel->argc = channel->argc;
_channel->argv = (char**)calloc(sizeof(char*), channel->argc);
if (!_channel->argv)
goto out_free;
for (index = 0; index < _channel->argc; index++)
if (args->argv)
{
_channel->argv[index] = _strdup(channel->argv[index]);
if (!_channel->argv[index])
goto out_release_args;
for (index = 0; index < args->argc; index++)
free(args->argv[index]);
free(args->argv);
}
return _channel;
out_release_args:
free(args);
}
for (index = 0; _channel->argv[index]; index++)
free(_channel->argv[index]);
ADDIN_ARGV* freerdp_addin_argv_new(size_t argc, const char* argv[])
{
ADDIN_ARGV* args = calloc(1, sizeof(ADDIN_ARGV));
if (!args)
return NULL;
if (argc == 0)
return args;
out_free:
free(_channel);
args->argc = argc;
args->argv = calloc(argc, sizeof(char*));
if (!args->argv)
goto fail;
if (argv)
{
size_t x;
for (x = 0; x < argc; x++)
{
args->argv[x] = _strdup(argv[x]);
if (!args->argv[x])
goto fail;
}
}
return args;
fail:
freerdp_addin_argv_free(args);
return NULL;
}
ADDIN_ARGV* freerdp_addin_argv_clone(const ADDIN_ARGV* args)
{
if (!args)
return NULL;
return freerdp_addin_argv_new(args->argc, (const char**)args->argv);
}
void freerdp_dynamic_channel_collection_free(rdpSettings* settings)
{
int j;
UINT32 i;
for (i = 0; i < freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelCount); i++)
{
if (!settings->DynamicChannelArray[i])
continue;
for (j = 0; j < settings->DynamicChannelArray[i]->argc; j++)
free(settings->DynamicChannelArray[i]->argv[j]);
free(settings->DynamicChannelArray[i]->argv);
free(settings->DynamicChannelArray[i]);
freerdp_addin_argv_free(settings->DynamicChannelArray[i]);
}
free(settings->DynamicChannelArray);
@ -1210,3 +1256,13 @@ UINT32 freerdp_settings_get_codecs_flags(const rdpSettings* settings)
/*TODO: check other codecs flags */
return flags;
}
ADDIN_ARGV* freerdp_static_channel_clone(ADDIN_ARGV* channel)
{
return freerdp_addin_argv_clone(channel);
}
ADDIN_ARGV* freerdp_dynamic_channel_clone(ADDIN_ARGV* channel)
{
return freerdp_addin_argv_clone(channel);
}

View File

@ -5,6 +5,7 @@ set(MODULE_PREFIX "TEST_COMMON")
set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
set(${MODULE_PREFIX}_TESTS
TestAddinArgv.c
TestCommonAssistance.c)
create_test_sourcelist(${MODULE_PREFIX}_SRCS

View File

@ -0,0 +1,348 @@
#include <winpr/crt.h>
#include <winpr/crypto.h>
#include <freerdp/settings.h>
static BOOL test_alloc(void)
{
BOOL rc = FALSE;
int rng, x;
const char* param[] = { "foo:", "bar", "bla", "rdp", NULL };
ADDIN_ARGV* arg1 = NULL;
ADDIN_ARGV* arg2 = NULL;
ADDIN_ARGV* arg3 = NULL;
ADDIN_ARGV* arg4 = NULL;
/* Test empty allocation */
arg1 = freerdp_addin_argv_new(0, NULL);
if (!arg1 || (arg1->argc != 0) || (arg1->argv))
goto fail;
/* Test allocation without initializing arguments of random size > 0 */
winpr_RAND((BYTE*)&rng, sizeof(rng));
rng = abs(rng % 8192) + 1;
arg2 = freerdp_addin_argv_new(rng, NULL);
if (!arg2 || (arg2->argc != rng) || (!arg2->argv))
goto fail;
for (x = 0; x < arg2->argc; x++)
{
if (arg2->argv[x])
goto fail;
}
/* Test allocation with initializing arguments of size > 0 */
arg3 = freerdp_addin_argv_new(ARRAYSIZE(param) - 1, param);
if (!arg3 || (arg3->argc != ARRAYSIZE(param) - 1) || (!arg3->argv))
goto fail;
for (x = 0; x < arg3->argc; x++)
{
if (strcmp(arg3->argv[x], param[x]) != 0)
goto fail;
}
/* Input lists with NULL elements are not allowed */
arg4 = freerdp_addin_argv_new(ARRAYSIZE(param), param);
if (arg4)
goto fail;
rc = TRUE;
fail:
freerdp_addin_argv_free(arg1);
freerdp_addin_argv_free(arg2);
freerdp_addin_argv_free(arg3);
freerdp_addin_argv_free(arg4);
printf("%s: %d\n", __FUNCTION__, rc);
return rc;
}
static BOOL test_clone(void)
{
int x;
BOOL rc = FALSE;
const char* param[] = { "foo:", "bar", "bla", "rdp" };
ADDIN_ARGV* arg = NULL;
ADDIN_ARGV* clone = NULL;
ADDIN_ARGV* clone2 = NULL;
arg = freerdp_addin_argv_new(ARRAYSIZE(param), param);
if (!arg || (arg->argc != ARRAYSIZE(param)))
goto fail;
clone = freerdp_addin_argv_clone(arg);
if (!clone || (clone->argc != arg->argc))
goto fail;
for (x = 0; x < arg->argc; x++)
{
if (strcmp(param[x], arg->argv[x]) != 0)
goto fail;
if (strcmp(param[x], clone->argv[x]) != 0)
goto fail;
}
clone2 = freerdp_addin_argv_clone(NULL);
if (clone2)
goto fail;
rc = TRUE;
fail:
freerdp_addin_argv_free(arg);
freerdp_addin_argv_free(clone);
freerdp_addin_argv_free(clone2);
printf("%s: %d\n", __FUNCTION__, rc);
return rc;
}
static BOOL test_add_remove(void)
{
size_t x, y;
const char* args[] = { "foo", "bar", "bla", "gaga" };
BOOL rc = FALSE;
ADDIN_ARGV* arg = NULL;
arg = freerdp_addin_argv_new(0, NULL);
if (!arg || (arg->argc != 0) || arg->argv)
goto fail;
for (y = 0; y < ARRAYSIZE(args); y++)
{
const char* param = args[y];
if (!freerdp_addin_argv_add_argument(arg, param))
goto fail;
if (arg->argc != (int)y + 1)
goto fail;
if (!arg->argv)
goto fail;
if (strcmp(arg->argv[y], param) != 0)
goto fail;
}
/* Try to remove non existing element, must not return TRUE */
if (freerdp_addin_argv_del_argument(arg, "foobar"))
goto fail;
/* Invalid parameters, must return FALSE */
if (freerdp_addin_argv_del_argument(NULL, "foobar"))
goto fail;
/* Invalid parameters, must return FALSE */
if (freerdp_addin_argv_del_argument(arg, NULL))
goto fail;
/* Remove elements one by one to test argument index move */
for (y = 0; y < ARRAYSIZE(args); y++)
{
const char* param = args[y];
if (!freerdp_addin_argv_del_argument(arg, param))
goto fail;
for (x = y + 1; x < ARRAYSIZE(args); x++)
{
if (strcmp(arg->argv[x - y - 1], args[x]) != 0)
goto fail;
}
}
rc = TRUE;
fail:
freerdp_addin_argv_free(arg);
printf("%s: %d\n", __FUNCTION__, rc);
return rc;
}
static BOOL test_set_argument(void)
{
int ret;
const char* newarg = "foobar";
const char* args[] = { "foo", "bar", "bla", "gaga" };
BOOL rc = FALSE;
ADDIN_ARGV* arg = NULL;
arg = freerdp_addin_argv_new(ARRAYSIZE(args), args);
if (!arg || (arg->argc != ARRAYSIZE(args)) || !arg->argv)
goto fail;
/* Check invalid parameters */
ret = freerdp_addin_set_argument(NULL, "foo");
if (ret >= 0)
goto fail;
ret = freerdp_addin_set_argument(arg, NULL);
if (ret >= 0)
goto fail;
/* Try existing parameter */
ret = freerdp_addin_set_argument(arg, "foo");
if ((ret != 1) || (arg->argc != ARRAYSIZE(args)))
goto fail;
/* Try new parameter */
ret = freerdp_addin_set_argument(arg, newarg);
if ((ret != 0) || (arg->argc != ARRAYSIZE(args) + 1) ||
(strcmp(newarg, arg->argv[ARRAYSIZE(args)]) != 0))
goto fail;
rc = TRUE;
fail:
freerdp_addin_argv_free(arg);
printf("%s: %d\n", __FUNCTION__, rc);
return rc;
}
static BOOL test_replace_argument(void)
{
int ret;
const char* newarg = "foobar";
const char* args[] = { "foo", "bar", "bla", "gaga" };
BOOL rc = FALSE;
ADDIN_ARGV* arg = NULL;
arg = freerdp_addin_argv_new(ARRAYSIZE(args), args);
if (!arg || (arg->argc != ARRAYSIZE(args)) || !arg->argv)
goto fail;
/* Check invalid parameters */
ret = freerdp_addin_replace_argument(NULL, "foo", newarg);
if (ret >= 0)
goto fail;
ret = freerdp_addin_replace_argument(arg, NULL, newarg);
if (ret >= 0)
goto fail;
ret = freerdp_addin_replace_argument(arg, "foo", NULL);
if (ret >= 0)
goto fail;
/* Try existing parameter */
ret = freerdp_addin_replace_argument(arg, "foo", newarg);
if ((ret != 1) || (arg->argc != ARRAYSIZE(args)) || (strcmp(arg->argv[0], newarg) != 0))
goto fail;
/* Try new parameter */
ret = freerdp_addin_replace_argument(arg, "lalala", newarg);
if ((ret != 0) || (arg->argc != ARRAYSIZE(args) + 1) ||
(strcmp(newarg, arg->argv[ARRAYSIZE(args)]) != 0))
goto fail;
rc = TRUE;
fail:
freerdp_addin_argv_free(arg);
printf("%s: %d\n", __FUNCTION__, rc);
return rc;
}
static BOOL test_set_argument_value(void)
{
int ret;
const char* newarg1 = "foobar";
const char* newarg2 = "lalala";
const char* fullnewarg1 = "foo:foobar";
const char* fullnewarg2 = "foo:lalala";
const char* fullnewvalue = "lalala:foobar";
const char* args[] = { "foo", "foo:", "bar", "bla", "gaga" };
BOOL rc = FALSE;
ADDIN_ARGV* arg = NULL;
arg = freerdp_addin_argv_new(ARRAYSIZE(args), args);
if (!arg || (arg->argc != ARRAYSIZE(args)) || !arg->argv)
goto fail;
/* Check invalid parameters */
ret = freerdp_addin_set_argument_value(NULL, "foo", newarg1);
if (ret >= 0)
goto fail;
ret = freerdp_addin_set_argument_value(arg, NULL, newarg1);
if (ret >= 0)
goto fail;
ret = freerdp_addin_set_argument_value(arg, "foo", NULL);
if (ret >= 0)
goto fail;
/* Try existing parameter */
ret = freerdp_addin_set_argument_value(arg, "foo", newarg1);
if ((ret != 1) || (arg->argc != ARRAYSIZE(args)) || (strcmp(arg->argv[1], fullnewarg1) != 0))
goto fail;
ret = freerdp_addin_set_argument_value(arg, "foo", newarg2);
if ((ret != 1) || (arg->argc != ARRAYSIZE(args)) || (strcmp(arg->argv[1], fullnewarg2) != 0))
goto fail;
/* Try new parameter */
ret = freerdp_addin_set_argument_value(arg, newarg2, newarg1);
if ((ret != 0) || (arg->argc != ARRAYSIZE(args) + 1) ||
(strcmp(fullnewvalue, arg->argv[ARRAYSIZE(args)]) != 0))
goto fail;
rc = TRUE;
fail:
freerdp_addin_argv_free(arg);
printf("%s: %d\n", __FUNCTION__, rc);
return rc;
}
static BOOL test_replace_argument_value(void)
{
int ret;
const char* newarg1 = "foobar";
const char* newarg2 = "lalala";
const char* fullnewarg1 = "foo:foobar";
const char* fullnewarg2 = "foo:lalala";
const char* fullnewvalue = "lalala:foobar";
const char* args[] = { "foo", "foo:", "bar", "bla", "gaga" };
BOOL rc = FALSE;
ADDIN_ARGV* arg = NULL;
arg = freerdp_addin_argv_new(ARRAYSIZE(args), args);
if (!arg || (arg->argc != ARRAYSIZE(args)) || !arg->argv)
goto fail;
/* Check invalid parameters */
ret = freerdp_addin_replace_argument_value(NULL, "bar", "foo", newarg1);
if (ret >= 0)
goto fail;
ret = freerdp_addin_replace_argument_value(arg, NULL, "foo", newarg1);
if (ret >= 0)
goto fail;
ret = freerdp_addin_replace_argument_value(arg, "foo", NULL, newarg1);
if (ret >= 0)
goto fail;
ret = freerdp_addin_replace_argument_value(arg, "bar", "foo", NULL);
if (ret >= 0)
goto fail;
/* Try existing parameter */
ret = freerdp_addin_replace_argument_value(arg, "bla", "foo", newarg1);
if ((ret != 1) || (arg->argc != ARRAYSIZE(args)) || (strcmp(arg->argv[3], fullnewarg1) != 0))
goto fail;
ret = freerdp_addin_replace_argument_value(arg, "foo", "foo", newarg2);
if ((ret != 1) || (arg->argc != ARRAYSIZE(args)) || (strcmp(arg->argv[0], fullnewarg2) != 0))
goto fail;
/* Try new parameter */
ret = freerdp_addin_replace_argument_value(arg, "hahaha", newarg2, newarg1);
if ((ret != 0) || (arg->argc != ARRAYSIZE(args) + 1) ||
(strcmp(fullnewvalue, arg->argv[ARRAYSIZE(args)]) != 0))
goto fail;
rc = TRUE;
fail:
freerdp_addin_argv_free(arg);
printf("%s: %d\n", __FUNCTION__, rc);
return rc;
}
int TestAddinArgv(int argc, char* argv[])
{
WINPR_UNUSED(argc);
WINPR_UNUSED(argv);
if (!test_alloc())
return -1;
if (!test_clone())
return -1;
if (!test_add_remove())
return -1;
if (!test_set_argument())
return -1;
if (!test_replace_argument())
return -1;
if (!test_set_argument_value())
return -1;
if (!test_replace_argument_value())
return -1;
return 0;
}

View File

@ -165,6 +165,8 @@ extern "C"
WINPR_API char** CommandLineParseCommaSeparatedValuesEx(const char* name, const char* list,
size_t* count);
WINPR_API char* CommandLineToCommaSeparatedValues(int argc, char* argv[]);
#ifdef __cplusplus
}
#endif

View File

@ -558,3 +558,33 @@ char** CommandLineParseCommaSeparatedValues(const char* list, size_t* count)
{
return CommandLineParseCommaSeparatedValuesEx(NULL, list, count);
}
char* CommandLineToCommaSeparatedValues(int argc, char* argv[])
{
int x;
char* str = NULL;
size_t offset = 0;
size_t size = argc + 1;
if ((argc <= 0) || !argv)
return NULL;
for (x = 0; x < argc; x++)
size += strlen(argv[x]);
str = calloc(size, sizeof(char));
if (!str)
return NULL;
for (x = 0; x < argc; x++)
{
int rc = _snprintf(&str[offset], size - offset, "%s,", argv[x]);
if (rc <= 0)
{
free(str);
return NULL;
}
offset += (size_t)rc;
}
if (offset > 0)
str[offset - 1] = '\0';
return str;
}