1 /**
2  * FreeRDP: A Remote Desktop Protocol Implementation
3  * Settings Management
4  *
5  * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6  * Copyright 2016 Armin Novak <armin.novak@gmail.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <errno.h>
29 
30 #include <winpr/crt.h>
31 
32 #include <freerdp/settings.h>
33 #include <freerdp/freerdp.h>
34 #include <freerdp/log.h>
35 
36 #define TAG FREERDP_TAG("common")
37 
freerdp_addin_set_argument(ADDIN_ARGV * args,char * argument)38 int freerdp_addin_set_argument(ADDIN_ARGV* args, char* argument)
39 {
40 	int i;
41 	char** new_argv;
42 
43 	for (i = 0; i < args->argc; i++)
44 	{
45 		if (strcmp(args->argv[i], argument) == 0)
46 		{
47 			return 1;
48 		}
49 	}
50 
51 	new_argv = (char**)realloc(args->argv, sizeof(char*) * (args->argc + 1));
52 
53 	if (!new_argv)
54 		return -1;
55 
56 	args->argv = new_argv;
57 	args->argc++;
58 
59 	if (!(args->argv[args->argc - 1] = _strdup(argument)))
60 		return -1;
61 
62 	return 0;
63 }
64 
freerdp_addin_replace_argument(ADDIN_ARGV * args,char * previous,char * argument)65 int freerdp_addin_replace_argument(ADDIN_ARGV* args, char* previous, char* argument)
66 {
67 	int i;
68 	char** new_argv;
69 
70 	for (i = 0; i < args->argc; i++)
71 	{
72 		if (strcmp(args->argv[i], previous) == 0)
73 		{
74 			free(args->argv[i]);
75 
76 			if (!(args->argv[i] = _strdup(argument)))
77 				return -1;
78 
79 			return 1;
80 		}
81 	}
82 
83 	new_argv = (char**)realloc(args->argv, sizeof(char*) * (args->argc + 1));
84 
85 	if (!new_argv)
86 		return -1;
87 
88 	args->argv = new_argv;
89 	args->argc++;
90 
91 	if (!(args->argv[args->argc - 1] = _strdup(argument)))
92 		return -1;
93 
94 	return 0;
95 }
96 
freerdp_addin_set_argument_value(ADDIN_ARGV * args,char * option,char * value)97 int freerdp_addin_set_argument_value(ADDIN_ARGV* args, char* option, char* value)
98 {
99 	int i;
100 	char* p;
101 	char* str;
102 	size_t length;
103 	char** new_argv;
104 	length = strlen(option) + strlen(value) + 1;
105 	str = (char*)malloc(length + 1);
106 
107 	if (!str)
108 		return -1;
109 
110 	sprintf_s(str, length + 1, "%s:%s", option, value);
111 
112 	for (i = 0; i < args->argc; i++)
113 	{
114 		p = strchr(args->argv[i], ':');
115 
116 		if (p)
117 		{
118 			if (strncmp(args->argv[i], option, p - args->argv[i]) == 0)
119 			{
120 				free(args->argv[i]);
121 				args->argv[i] = str;
122 				return 1;
123 			}
124 		}
125 	}
126 
127 	new_argv = (char**)realloc(args->argv, sizeof(char*) * (args->argc + 1));
128 
129 	if (!new_argv)
130 	{
131 		free(str);
132 		return -1;
133 	}
134 
135 	args->argv = new_argv;
136 	args->argc++;
137 	args->argv[args->argc - 1] = str;
138 	return 0;
139 }
140 
freerdp_addin_replace_argument_value(ADDIN_ARGV * args,char * previous,char * option,char * value)141 int freerdp_addin_replace_argument_value(ADDIN_ARGV* args, char* previous, char* option,
142                                          char* value)
143 {
144 	int i;
145 	char* str;
146 	size_t length;
147 	char** new_argv;
148 	length = strlen(option) + strlen(value) + 1;
149 	str = (char*)malloc(length + 1);
150 
151 	if (!str)
152 		return -1;
153 
154 	sprintf_s(str, length + 1, "%s:%s", option, value);
155 
156 	for (i = 0; i < args->argc; i++)
157 	{
158 		if (strcmp(args->argv[i], previous) == 0)
159 		{
160 			free(args->argv[i]);
161 			args->argv[i] = str;
162 			return 1;
163 		}
164 	}
165 
166 	new_argv = (char**)realloc(args->argv, sizeof(char*) * (args->argc + 1));
167 
168 	if (!new_argv)
169 	{
170 		free(str);
171 		return -1;
172 	}
173 
174 	args->argv = new_argv;
175 	args->argc++;
176 	args->argv[args->argc - 1] = str;
177 	return 0;
178 }
179 
freerdp_device_collection_add(rdpSettings * settings,RDPDR_DEVICE * device)180 BOOL freerdp_device_collection_add(rdpSettings* settings, RDPDR_DEVICE* device)
181 {
182 	if (!settings->DeviceArray)
183 		return FALSE;
184 
185 	if (settings->DeviceArraySize < (settings->DeviceCount + 1))
186 	{
187 		UINT32 new_size;
188 		RDPDR_DEVICE** new_array;
189 		new_size = settings->DeviceArraySize * 2;
190 		new_array =
191 		    (RDPDR_DEVICE**)realloc(settings->DeviceArray, new_size * sizeof(RDPDR_DEVICE*));
192 
193 		if (!new_array)
194 			return FALSE;
195 
196 		settings->DeviceArray = new_array;
197 		settings->DeviceArraySize = new_size;
198 	}
199 
200 	settings->DeviceArray[settings->DeviceCount++] = device;
201 	return TRUE;
202 }
203 
freerdp_device_collection_find(rdpSettings * settings,const char * name)204 RDPDR_DEVICE* freerdp_device_collection_find(rdpSettings* settings, const char* name)
205 {
206 	UINT32 index;
207 	RDPDR_DEVICE* device;
208 
209 	for (index = 0; index < settings->DeviceCount; index++)
210 	{
211 		device = (RDPDR_DEVICE*)settings->DeviceArray[index];
212 
213 		if (!device->Name)
214 			continue;
215 
216 		if (strcmp(device->Name, name) == 0)
217 			return device;
218 	}
219 
220 	return NULL;
221 }
222 
freerdp_device_collection_find_type(rdpSettings * settings,UINT32 type)223 RDPDR_DEVICE* freerdp_device_collection_find_type(rdpSettings* settings, UINT32 type)
224 {
225 	UINT32 index;
226 	RDPDR_DEVICE* device;
227 
228 	for (index = 0; index < settings->DeviceCount; index++)
229 	{
230 		device = (RDPDR_DEVICE*)settings->DeviceArray[index];
231 
232 		if (device->Type == type)
233 			return device;
234 	}
235 
236 	return NULL;
237 }
238 
freerdp_device_clone(RDPDR_DEVICE * device)239 RDPDR_DEVICE* freerdp_device_clone(RDPDR_DEVICE* device)
240 {
241 	if (device->Type == RDPDR_DTYP_FILESYSTEM)
242 	{
243 		RDPDR_DRIVE* drive = (RDPDR_DRIVE*)device;
244 		RDPDR_DRIVE* _drive = (RDPDR_DRIVE*)calloc(1, sizeof(RDPDR_DRIVE));
245 
246 		if (!_drive)
247 			return NULL;
248 
249 		_drive->Id = drive->Id;
250 		_drive->Type = drive->Type;
251 		_drive->Name = _strdup(drive->Name);
252 
253 		if (!_drive->Name)
254 			goto out_fs_name_error;
255 
256 		_drive->Path = _strdup(drive->Path);
257 
258 		if (!_drive->Path)
259 			goto out_fs_path_error;
260 
261 		return (RDPDR_DEVICE*)_drive;
262 	out_fs_path_error:
263 		free(_drive->Name);
264 	out_fs_name_error:
265 		free(_drive);
266 		return NULL;
267 	}
268 
269 	if (device->Type == RDPDR_DTYP_PRINT)
270 	{
271 		RDPDR_PRINTER* printer = (RDPDR_PRINTER*)device;
272 		RDPDR_PRINTER* _printer = (RDPDR_PRINTER*)calloc(1, sizeof(RDPDR_PRINTER));
273 
274 		if (!_printer)
275 			return NULL;
276 
277 		_printer->Id = printer->Id;
278 		_printer->Type = printer->Type;
279 
280 		if (printer->Name)
281 		{
282 			_printer->Name = _strdup(printer->Name);
283 
284 			if (!_printer->Name)
285 				goto out_print_name_error;
286 		}
287 
288 		if (printer->DriverName)
289 		{
290 			_printer->DriverName = _strdup(printer->DriverName);
291 
292 			if (!_printer->DriverName)
293 				goto out_print_path_error;
294 		}
295 
296 		return (RDPDR_DEVICE*)_printer;
297 	out_print_path_error:
298 		free(_printer->Name);
299 	out_print_name_error:
300 		free(_printer);
301 		return NULL;
302 	}
303 
304 	if (device->Type == RDPDR_DTYP_SMARTCARD)
305 	{
306 		RDPDR_SMARTCARD* smartcard = (RDPDR_SMARTCARD*)device;
307 		RDPDR_SMARTCARD* _smartcard = (RDPDR_SMARTCARD*)calloc(1, sizeof(RDPDR_SMARTCARD));
308 
309 		if (!_smartcard)
310 			return NULL;
311 
312 		_smartcard->Id = smartcard->Id;
313 		_smartcard->Type = smartcard->Type;
314 
315 		if (smartcard->Name)
316 		{
317 			_smartcard->Name = _strdup(smartcard->Name);
318 
319 			if (!_smartcard->Name)
320 				goto out_smartc_name_error;
321 		}
322 
323 		return (RDPDR_DEVICE*)_smartcard;
324 	out_smartc_name_error:
325 		free(_smartcard);
326 		return NULL;
327 	}
328 
329 	if (device->Type == RDPDR_DTYP_SERIAL)
330 	{
331 		RDPDR_SERIAL* serial = (RDPDR_SERIAL*)device;
332 		RDPDR_SERIAL* _serial = (RDPDR_SERIAL*)calloc(1, sizeof(RDPDR_SERIAL));
333 
334 		if (!_serial)
335 			return NULL;
336 
337 		_serial->Id = serial->Id;
338 		_serial->Type = serial->Type;
339 
340 		if (serial->Name)
341 		{
342 			_serial->Name = _strdup(serial->Name);
343 
344 			if (!_serial->Name)
345 				goto out_serial_name_error;
346 		}
347 
348 		if (serial->Path)
349 		{
350 			_serial->Path = _strdup(serial->Path);
351 
352 			if (!_serial->Path)
353 				goto out_serial_path_error;
354 		}
355 
356 		if (serial->Driver)
357 		{
358 			_serial->Driver = _strdup(serial->Driver);
359 
360 			if (!_serial->Driver)
361 				goto out_serial_driver_error;
362 		}
363 
364 		return (RDPDR_DEVICE*)_serial;
365 	out_serial_driver_error:
366 		free(_serial->Path);
367 	out_serial_path_error:
368 		free(_serial->Name);
369 	out_serial_name_error:
370 		free(_serial);
371 		return NULL;
372 	}
373 
374 	if (device->Type == RDPDR_DTYP_PARALLEL)
375 	{
376 		RDPDR_PARALLEL* parallel = (RDPDR_PARALLEL*)device;
377 		RDPDR_PARALLEL* _parallel = (RDPDR_PARALLEL*)calloc(1, sizeof(RDPDR_PARALLEL));
378 
379 		if (!_parallel)
380 			return NULL;
381 
382 		_parallel->Id = parallel->Id;
383 		_parallel->Type = parallel->Type;
384 
385 		if (parallel->Name)
386 		{
387 			_parallel->Name = _strdup(parallel->Name);
388 
389 			if (!_parallel->Name)
390 				goto out_parallel_name_error;
391 		}
392 
393 		if (parallel->Path)
394 		{
395 			_parallel->Path = _strdup(parallel->Path);
396 
397 			if (!_parallel->Path)
398 				goto out_parallel_path_error;
399 		}
400 
401 		return (RDPDR_DEVICE*)_parallel;
402 	out_parallel_path_error:
403 		free(_parallel->Name);
404 	out_parallel_name_error:
405 		free(_parallel);
406 		return NULL;
407 	}
408 
409 	WLog_ERR(TAG, "unknown device type %" PRIu32 "", device->Type);
410 	return NULL;
411 }
412 
freerdp_device_collection_free(rdpSettings * settings)413 void freerdp_device_collection_free(rdpSettings* settings)
414 {
415 	UINT32 index;
416 	RDPDR_DEVICE* device;
417 
418 	for (index = 0; index < settings->DeviceCount; index++)
419 	{
420 		device = (RDPDR_DEVICE*)settings->DeviceArray[index];
421 
422 		if (!device)
423 			continue;
424 
425 		free(device->Name);
426 
427 		if (settings->DeviceArray[index]->Type == RDPDR_DTYP_FILESYSTEM)
428 		{
429 			free(((RDPDR_DRIVE*)device)->Path);
430 		}
431 		else if (settings->DeviceArray[index]->Type == RDPDR_DTYP_PRINT)
432 		{
433 		}
434 		else if (settings->DeviceArray[index]->Type == RDPDR_DTYP_SMARTCARD)
435 		{
436 		}
437 		else if (settings->DeviceArray[index]->Type == RDPDR_DTYP_SERIAL)
438 		{
439 			free(((RDPDR_SERIAL*)device)->Path);
440 			free(((RDPDR_SERIAL*)device)->Driver);
441 		}
442 		else if (settings->DeviceArray[index]->Type == RDPDR_DTYP_PARALLEL)
443 		{
444 			free(((RDPDR_PARALLEL*)device)->Path);
445 		}
446 
447 		free(device);
448 	}
449 
450 	free(settings->DeviceArray);
451 	settings->DeviceArraySize = 0;
452 	settings->DeviceArray = NULL;
453 	settings->DeviceCount = 0;
454 }
455 
freerdp_static_channel_collection_add(rdpSettings * settings,ADDIN_ARGV * channel)456 BOOL freerdp_static_channel_collection_add(rdpSettings* settings, ADDIN_ARGV* channel)
457 {
458 	if (!settings->StaticChannelArray)
459 		return FALSE;
460 
461 	if (settings->StaticChannelArraySize < (settings->StaticChannelCount + 1))
462 	{
463 		UINT32 new_size;
464 		ADDIN_ARGV** new_array;
465 		new_size = settings->StaticChannelArraySize * 2;
466 		new_array =
467 		    (ADDIN_ARGV**)realloc(settings->StaticChannelArray, new_size * sizeof(ADDIN_ARGV*));
468 
469 		if (!new_array)
470 			return FALSE;
471 
472 		settings->StaticChannelArray = new_array;
473 		settings->StaticChannelArraySize = new_size;
474 	}
475 
476 	settings->StaticChannelArray[settings->StaticChannelCount++] = channel;
477 	return TRUE;
478 }
479 
freerdp_static_channel_collection_find(rdpSettings * settings,const char * name)480 ADDIN_ARGV* freerdp_static_channel_collection_find(rdpSettings* settings, const char* name)
481 {
482 	UINT32 index;
483 	ADDIN_ARGV* channel;
484 
485 	for (index = 0; index < settings->StaticChannelCount; index++)
486 	{
487 		channel = settings->StaticChannelArray[index];
488 
489 		if (strcmp(channel->argv[0], name) == 0)
490 			return channel;
491 	}
492 
493 	return NULL;
494 }
495 
freerdp_static_channel_clone(ADDIN_ARGV * channel)496 ADDIN_ARGV* freerdp_static_channel_clone(ADDIN_ARGV* channel)
497 {
498 	int index;
499 	ADDIN_ARGV* _channel = NULL;
500 	_channel = (ADDIN_ARGV*)malloc(sizeof(ADDIN_ARGV));
501 
502 	if (!_channel)
503 		return NULL;
504 
505 	_channel->argc = channel->argc;
506 	_channel->argv = (char**)calloc(channel->argc, sizeof(char*));
507 
508 	if (!_channel->argv)
509 		goto out_free;
510 
511 	for (index = 0; index < _channel->argc; index++)
512 	{
513 		_channel->argv[index] = _strdup(channel->argv[index]);
514 
515 		if (!_channel->argv[index])
516 			goto out_release_args;
517 	}
518 
519 	return _channel;
520 out_release_args:
521 
522 	for (index = 0; _channel->argv[index]; index++)
523 		free(_channel->argv[index]);
524 
525 out_free:
526 	free(_channel);
527 	return NULL;
528 }
529 
freerdp_static_channel_collection_free(rdpSettings * settings)530 void freerdp_static_channel_collection_free(rdpSettings* settings)
531 {
532 	int j;
533 	UINT32 i;
534 
535 	for (i = 0; i < settings->StaticChannelCount; i++)
536 	{
537 		if (!settings->StaticChannelArray[i])
538 			continue;
539 
540 		for (j = 0; j < settings->StaticChannelArray[i]->argc; j++)
541 			free(settings->StaticChannelArray[i]->argv[j]);
542 
543 		free(settings->StaticChannelArray[i]->argv);
544 		free(settings->StaticChannelArray[i]);
545 	}
546 
547 	free(settings->StaticChannelArray);
548 	settings->StaticChannelArraySize = 0;
549 	settings->StaticChannelArray = NULL;
550 	settings->StaticChannelCount = 0;
551 }
552 
freerdp_dynamic_channel_collection_add(rdpSettings * settings,ADDIN_ARGV * channel)553 BOOL freerdp_dynamic_channel_collection_add(rdpSettings* settings, ADDIN_ARGV* channel)
554 {
555 	if (!settings->DynamicChannelArray)
556 		return FALSE;
557 
558 	if (settings->DynamicChannelArraySize < (settings->DynamicChannelCount + 1))
559 	{
560 		ADDIN_ARGV** new_array;
561 		new_array = realloc(settings->DynamicChannelArray,
562 		                    settings->DynamicChannelArraySize * sizeof(ADDIN_ARGV*) * 2);
563 
564 		if (!new_array)
565 			return FALSE;
566 
567 		settings->DynamicChannelArraySize *= 2;
568 		settings->DynamicChannelArray = new_array;
569 	}
570 
571 	settings->DynamicChannelArray[settings->DynamicChannelCount++] = channel;
572 	return TRUE;
573 }
574 
freerdp_dynamic_channel_collection_find(rdpSettings * settings,const char * name)575 ADDIN_ARGV* freerdp_dynamic_channel_collection_find(rdpSettings* settings, const char* name)
576 {
577 	UINT32 index;
578 	ADDIN_ARGV* channel;
579 
580 	for (index = 0; index < settings->DynamicChannelCount; index++)
581 	{
582 		channel = settings->DynamicChannelArray[index];
583 
584 		if (strcmp(channel->argv[0], name) == 0)
585 			return channel;
586 	}
587 
588 	return NULL;
589 }
590 
freerdp_dynamic_channel_clone(ADDIN_ARGV * channel)591 ADDIN_ARGV* freerdp_dynamic_channel_clone(ADDIN_ARGV* channel)
592 {
593 	int index;
594 	ADDIN_ARGV* _channel = NULL;
595 	_channel = (ADDIN_ARGV*)malloc(sizeof(ADDIN_ARGV));
596 
597 	if (!_channel)
598 		return NULL;
599 
600 	_channel->argc = channel->argc;
601 	_channel->argv = (char**)calloc(sizeof(char*), channel->argc);
602 
603 	if (!_channel->argv)
604 		goto out_free;
605 
606 	for (index = 0; index < _channel->argc; index++)
607 	{
608 		_channel->argv[index] = _strdup(channel->argv[index]);
609 
610 		if (!_channel->argv[index])
611 			goto out_release_args;
612 	}
613 
614 	return _channel;
615 out_release_args:
616 
617 	for (index = 0; _channel->argv[index]; index++)
618 		free(_channel->argv[index]);
619 
620 out_free:
621 	free(_channel);
622 	return NULL;
623 }
624 
freerdp_dynamic_channel_collection_free(rdpSettings * settings)625 void freerdp_dynamic_channel_collection_free(rdpSettings* settings)
626 {
627 	int j;
628 	UINT32 i;
629 
630 	for (i = 0; i < settings->DynamicChannelCount; i++)
631 	{
632 		if (!settings->DynamicChannelArray[i])
633 			continue;
634 
635 		for (j = 0; j < settings->DynamicChannelArray[i]->argc; j++)
636 			free(settings->DynamicChannelArray[i]->argv[j]);
637 
638 		free(settings->DynamicChannelArray[i]->argv);
639 		free(settings->DynamicChannelArray[i]);
640 	}
641 
642 	free(settings->DynamicChannelArray);
643 	settings->DynamicChannelArraySize = 0;
644 	settings->DynamicChannelArray = NULL;
645 	settings->DynamicChannelCount = 0;
646 }
647 
freerdp_target_net_addresses_free(rdpSettings * settings)648 void freerdp_target_net_addresses_free(rdpSettings* settings)
649 {
650 	UINT32 index;
651 
652 	for (index = 0; index < settings->TargetNetAddressCount; index++)
653 		free(settings->TargetNetAddresses[index]);
654 
655 	free(settings->TargetNetAddresses);
656 	free(settings->TargetNetPorts);
657 	settings->TargetNetAddressCount = 0;
658 	settings->TargetNetAddresses = NULL;
659 	settings->TargetNetPorts = NULL;
660 }
661 
freerdp_performance_flags_make(rdpSettings * settings)662 void freerdp_performance_flags_make(rdpSettings* settings)
663 {
664 	settings->PerformanceFlags = PERF_FLAG_NONE;
665 
666 	if (settings->AllowFontSmoothing)
667 		settings->PerformanceFlags |= PERF_ENABLE_FONT_SMOOTHING;
668 
669 	if (settings->AllowDesktopComposition)
670 		settings->PerformanceFlags |= PERF_ENABLE_DESKTOP_COMPOSITION;
671 
672 	if (settings->DisableWallpaper)
673 		settings->PerformanceFlags |= PERF_DISABLE_WALLPAPER;
674 
675 	if (settings->DisableFullWindowDrag)
676 		settings->PerformanceFlags |= PERF_DISABLE_FULLWINDOWDRAG;
677 
678 	if (settings->DisableMenuAnims)
679 		settings->PerformanceFlags |= PERF_DISABLE_MENUANIMATIONS;
680 
681 	if (settings->DisableThemes)
682 		settings->PerformanceFlags |= PERF_DISABLE_THEMING;
683 }
684 
freerdp_performance_flags_split(rdpSettings * settings)685 void freerdp_performance_flags_split(rdpSettings* settings)
686 {
687 	settings->AllowFontSmoothing =
688 	    (settings->PerformanceFlags & PERF_ENABLE_FONT_SMOOTHING) ? TRUE : FALSE;
689 	settings->AllowDesktopComposition =
690 	    (settings->PerformanceFlags & PERF_ENABLE_DESKTOP_COMPOSITION) ? TRUE : FALSE;
691 	settings->DisableWallpaper =
692 	    (settings->PerformanceFlags & PERF_DISABLE_WALLPAPER) ? TRUE : FALSE;
693 	settings->DisableFullWindowDrag =
694 	    (settings->PerformanceFlags & PERF_DISABLE_FULLWINDOWDRAG) ? TRUE : FALSE;
695 	settings->DisableMenuAnims =
696 	    (settings->PerformanceFlags & PERF_DISABLE_MENUANIMATIONS) ? TRUE : FALSE;
697 	settings->DisableThemes = (settings->PerformanceFlags & PERF_DISABLE_THEMING) ? TRUE : FALSE;
698 }
699 
freerdp_set_gateway_usage_method(rdpSettings * settings,UINT32 GatewayUsageMethod)700 BOOL freerdp_set_gateway_usage_method(rdpSettings* settings, UINT32 GatewayUsageMethod)
701 {
702 	if (!freerdp_settings_set_uint32(settings, FreeRDP_GatewayUsageMethod, GatewayUsageMethod))
703 		return FALSE;
704 
705 	if (GatewayUsageMethod == TSC_PROXY_MODE_NONE_DIRECT)
706 	{
707 		if (!freerdp_settings_set_bool(settings, FreeRDP_GatewayEnabled, FALSE) ||
708 		    !freerdp_settings_set_bool(settings, FreeRDP_GatewayBypassLocal, FALSE))
709 			return FALSE;
710 	}
711 	else if (GatewayUsageMethod == TSC_PROXY_MODE_DIRECT)
712 	{
713 		if (!freerdp_settings_set_bool(settings, FreeRDP_GatewayEnabled, TRUE) ||
714 		    !freerdp_settings_set_bool(settings, FreeRDP_GatewayBypassLocal, FALSE))
715 			return FALSE;
716 	}
717 	else if (GatewayUsageMethod == TSC_PROXY_MODE_DETECT)
718 	{
719 		if (!freerdp_settings_set_bool(settings, FreeRDP_GatewayEnabled, TRUE) ||
720 		    !freerdp_settings_set_bool(settings, FreeRDP_GatewayBypassLocal, TRUE))
721 			return FALSE;
722 	}
723 	else if (GatewayUsageMethod == TSC_PROXY_MODE_DEFAULT)
724 	{
725 		/**
726 		 * This corresponds to "Automatically detect RD Gateway server settings",
727 		 * which means the client attempts to use gateway group policy settings
728 		 * http://technet.microsoft.com/en-us/library/cc770601.aspx
729 		 */
730 		if (!freerdp_settings_set_bool(settings, FreeRDP_GatewayEnabled, FALSE) ||
731 		    !freerdp_settings_set_bool(settings, FreeRDP_GatewayBypassLocal, FALSE))
732 			return FALSE;
733 	}
734 	else if (GatewayUsageMethod == TSC_PROXY_MODE_NONE_DETECT)
735 	{
736 		if (!freerdp_settings_set_bool(settings, FreeRDP_GatewayEnabled, FALSE) ||
737 		    !freerdp_settings_set_bool(settings, FreeRDP_GatewayBypassLocal, FALSE))
738 			return FALSE;
739 	}
740 
741 	return TRUE;
742 }
743 
freerdp_update_gateway_usage_method(rdpSettings * settings,UINT32 GatewayEnabled,UINT32 GatewayBypassLocal)744 void freerdp_update_gateway_usage_method(rdpSettings* settings, UINT32 GatewayEnabled,
745                                          UINT32 GatewayBypassLocal)
746 {
747 	UINT32 GatewayUsageMethod = 0;
748 
749 	if (!GatewayEnabled && !GatewayBypassLocal)
750 		GatewayUsageMethod = TSC_PROXY_MODE_NONE_DIRECT;
751 	else if (GatewayEnabled && !GatewayBypassLocal)
752 		GatewayUsageMethod = TSC_PROXY_MODE_DIRECT;
753 	else if (GatewayEnabled && GatewayBypassLocal)
754 		GatewayUsageMethod = TSC_PROXY_MODE_DETECT;
755 
756 	freerdp_set_gateway_usage_method(settings, GatewayUsageMethod);
757 }
758 
freerdp_get_param_bool(const rdpSettings * settings,int id)759 BOOL freerdp_get_param_bool(const rdpSettings* settings, int id)
760 {
761 	return freerdp_settings_get_bool(settings, (size_t)id);
762 }
763 
freerdp_set_param_bool(rdpSettings * settings,int id,BOOL param)764 int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param)
765 {
766 	return freerdp_settings_set_bool(settings, (size_t)id, param) ? 0 : -1;
767 }
768 
freerdp_get_param_int(const rdpSettings * settings,int id)769 int freerdp_get_param_int(const rdpSettings* settings, int id)
770 {
771 	return freerdp_settings_get_int32(settings, (size_t)id);
772 }
773 
freerdp_set_param_int(rdpSettings * settings,int id,int param)774 int freerdp_set_param_int(rdpSettings* settings, int id, int param)
775 {
776 	return freerdp_settings_set_int32(settings, (size_t)id, param) ? 0 : -1;
777 }
778 
freerdp_get_param_uint32(const rdpSettings * settings,int id)779 UINT32 freerdp_get_param_uint32(const rdpSettings* settings, int id)
780 {
781 	return freerdp_settings_get_uint32(settings, (size_t)id);
782 }
783 
freerdp_set_param_uint32(rdpSettings * settings,int id,UINT32 param)784 int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param)
785 {
786 	return freerdp_settings_set_uint32(settings, (size_t)id, param) ? 0 : -1;
787 }
788 
freerdp_get_param_uint64(const rdpSettings * settings,int id)789 UINT64 freerdp_get_param_uint64(const rdpSettings* settings, int id)
790 {
791 	return freerdp_settings_get_uint64(settings, (size_t)id);
792 }
793 
freerdp_set_param_uint64(rdpSettings * settings,int id,UINT64 param)794 int freerdp_set_param_uint64(rdpSettings* settings, int id, UINT64 param)
795 {
796 	return freerdp_settings_set_uint64(settings, (size_t)id, param) ? 0 : -1;
797 }
798 
freerdp_get_param_string(const rdpSettings * settings,int id)799 char* freerdp_get_param_string(const rdpSettings* settings, int id)
800 {
801 	return (char*)freerdp_settings_get_string(settings, (size_t)id);
802 }
803 
freerdp_set_param_string(rdpSettings * settings,int id,const char * param)804 int freerdp_set_param_string(rdpSettings* settings, int id, const char* param)
805 {
806 	return freerdp_settings_set_string(settings, (size_t)id, param) ? 0 : -1;
807 }
808 
value_to_uint(const char * value,ULONGLONG * result,ULONGLONG min,ULONGLONG max)809 static BOOL value_to_uint(const char* value, ULONGLONG* result, ULONGLONG min, ULONGLONG max)
810 {
811 	unsigned long long rc;
812 
813 	if (!value || !result)
814 		return FALSE;
815 
816 	errno = 0;
817 	rc = _strtoui64(value, NULL, 0);
818 
819 	if (errno != 0)
820 		return FALSE;
821 
822 	if ((rc < min) || (rc > max))
823 		return FALSE;
824 
825 	*result = rc;
826 	return TRUE;
827 }
828 
value_to_int(const char * value,LONGLONG * result,LONGLONG min,LONGLONG max)829 static BOOL value_to_int(const char* value, LONGLONG* result, LONGLONG min, LONGLONG max)
830 {
831 	long long rc;
832 
833 	if (!value || !result)
834 		return FALSE;
835 
836 	errno = 0;
837 	rc = _strtoi64(value, NULL, 0);
838 
839 	if (errno != 0)
840 		return FALSE;
841 
842 	if ((rc < min) || (rc > max))
843 		return FALSE;
844 
845 	*result = rc;
846 	return TRUE;
847 }
848 
parsing_fail(const char * key,const char * type,const char * value)849 static BOOL parsing_fail(const char* key, const char* type, const char* value)
850 {
851 	WLog_ERR(TAG, "Failed to parse key [%s] of type [%s]: value [%s]", key, type, value);
852 	return FALSE;
853 }
854 
freerdp_settings_set_value_for_name(rdpSettings * settings,const char * name,const char * value)855 BOOL freerdp_settings_set_value_for_name(rdpSettings* settings, const char* name, const char* value)
856 {
857 	ULONGLONG uval;
858 	LONGLONG ival;
859 	SSIZE_T index, type;
860 	if (!settings || !name)
861 		return FALSE;
862 
863 	index = freerdp_settings_get_key_for_name(name);
864 	if (index < 0)
865 	{
866 		WLog_ERR(TAG, "Invalid settings key [%s]", name);
867 		return FALSE;
868 	}
869 
870 	type = freerdp_settings_get_type_for_key((size_t)index);
871 	switch (type)
872 	{
873 
874 		case RDP_SETTINGS_TYPE_BOOL:
875 		{
876 			BOOL val = _strnicmp(value, "TRUE", 5) == 0;
877 			if (!val && _strnicmp(value, "FALSE", 5) != 0)
878 				return parsing_fail(name, "BOOL", value);
879 			return freerdp_settings_set_bool(settings, index, val);
880 		}
881 		case RDP_SETTINGS_TYPE_UINT16:
882 			if (!value_to_uint(value, &uval, 0, UINT16_MAX))
883 				return parsing_fail(name, "UINT16", value);
884 			if (!freerdp_settings_set_uint16(settings, index, uval))
885 				return parsing_fail(name, "UINT16", value);
886 			return TRUE;
887 
888 		case RDP_SETTINGS_TYPE_INT16:
889 			if (!value_to_int(value, &ival, INT16_MIN, INT16_MAX))
890 				return parsing_fail(name, "INT16", value);
891 			if (!freerdp_settings_set_int16(settings, index, ival))
892 				return parsing_fail(name, "INT16", value);
893 			return TRUE;
894 		case RDP_SETTINGS_TYPE_UINT32:
895 			if (!value_to_uint(value, &uval, 0, UINT32_MAX))
896 				return parsing_fail(name, "UINT32", value);
897 			if (!freerdp_settings_set_uint32(settings, index, uval))
898 				return parsing_fail(name, "UINT32", value);
899 			return TRUE;
900 		case RDP_SETTINGS_TYPE_INT32:
901 			if (!value_to_int(value, &ival, INT32_MIN, INT32_MAX))
902 				return parsing_fail(name, "INT32", value);
903 			if (!freerdp_settings_set_int32(settings, index, ival))
904 				return parsing_fail(name, "INT32", value);
905 			return TRUE;
906 		case RDP_SETTINGS_TYPE_UINT64:
907 			if (!value_to_uint(value, &uval, 0, UINT64_MAX))
908 				return parsing_fail(name, "UINT64", value);
909 			if (!freerdp_settings_set_uint64(settings, index, uval))
910 				return parsing_fail(name, "UINT64", value);
911 			return TRUE;
912 		case RDP_SETTINGS_TYPE_INT64:
913 			if (!value_to_int(value, &ival, INT64_MIN, INT64_MAX))
914 				return parsing_fail(name, "INT64", value);
915 			if (!freerdp_settings_set_int64(settings, index, ival))
916 				return parsing_fail(name, "INT64", value);
917 			return TRUE;
918 
919 		case RDP_SETTINGS_TYPE_STRING:
920 			return freerdp_settings_set_string(settings, index, value);
921 		case RDP_SETTINGS_TYPE_POINTER:
922 			return parsing_fail(name, "POINTER", value);
923 		default:
924 			return FALSE;
925 	}
926 	return FALSE;
927 }
928