FreeRDP
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Modules Pages
common/settings.c
1
23#include <freerdp/config.h>
24
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <errno.h>
29
30#include <winpr/crt.h>
31#include <winpr/assert.h>
32#include <winpr/cast.h>
33
34#include "../core/settings.h"
35#include "../core/capabilities.h"
36
37#include <freerdp/crypto/certificate.h>
38#include <freerdp/settings.h>
39#include <freerdp/freerdp.h>
40#include <freerdp/log.h>
41
42#define TAG FREERDP_TAG("common")
43
44BOOL freerdp_addin_argv_add_argument_ex(ADDIN_ARGV* args, const char* argument, size_t len)
45{
46 char* str = NULL;
47 char** new_argv = NULL;
48
49 if (!args || !argument)
50 return FALSE;
51
52 if (len == 0)
53 len = strlen(argument);
54
55 new_argv = (char**)realloc(
56 (void*)args->argv, sizeof(char*) * (WINPR_ASSERTING_INT_CAST(uint32_t, args->argc) + 1));
57
58 if (!new_argv)
59 return FALSE;
60
61 args->argv = new_argv;
62
63 str = calloc(len + 1, sizeof(char));
64 if (!str)
65 return FALSE;
66 memcpy(str, argument, len);
67 args->argv[args->argc++] = str;
68 return TRUE;
69}
70
71BOOL freerdp_addin_argv_add_argument(ADDIN_ARGV* args, const char* argument)
72{
73 return freerdp_addin_argv_add_argument_ex(args, argument, 0);
74}
75
76BOOL freerdp_addin_argv_del_argument(ADDIN_ARGV* args, const char* argument)
77{
78 if (!args || !argument)
79 return FALSE;
80 for (int x = 0; x < args->argc; x++)
81 {
82 char* arg = args->argv[x];
83 if (strcmp(argument, arg) == 0)
84 {
85 free(arg);
86 memmove_s((void*)&args->argv[x],
87 (WINPR_ASSERTING_INT_CAST(uint32_t, args->argc - x)) * sizeof(char*),
88 (void*)&args->argv[x + 1],
89 (WINPR_ASSERTING_INT_CAST(uint32_t, args->argc - x - 1)) * sizeof(char*));
90 args->argv[args->argc - 1] = NULL;
91 args->argc--;
92 return TRUE;
93 }
94 }
95 return FALSE;
96}
97
98int freerdp_addin_set_argument(ADDIN_ARGV* args, const char* argument)
99{
100 if (!args || !argument)
101 return -2;
102
103 for (int i = 0; i < args->argc; i++)
104 {
105 if (strcmp(args->argv[i], argument) == 0)
106 {
107 return 1;
108 }
109 }
110
111 if (!freerdp_addin_argv_add_argument(args, argument))
112 return -1;
113 return 0;
114}
115
116int freerdp_addin_replace_argument(ADDIN_ARGV* args, const char* previous, const char* argument)
117{
118 if (!args || !previous || !argument)
119 return -2;
120
121 for (int i = 0; i < args->argc; i++)
122 {
123 if (strcmp(args->argv[i], previous) == 0)
124 {
125 free(args->argv[i]);
126
127 if (!(args->argv[i] = _strdup(argument)))
128 return -1;
129
130 return 1;
131 }
132 }
133
134 if (!freerdp_addin_argv_add_argument(args, argument))
135 return -1;
136 return 0;
137}
138
139int freerdp_addin_set_argument_value(ADDIN_ARGV* args, const char* option, const char* value)
140{
141 BOOL rc = 0;
142 char* p = NULL;
143 char* str = NULL;
144 size_t length = 0;
145 if (!args || !option || !value)
146 return -2;
147 length = strlen(option) + strlen(value) + 1;
148 str = (char*)calloc(length + 1, sizeof(char));
149
150 if (!str)
151 return -1;
152
153 (void)sprintf_s(str, length + 1, "%s:%s", option, value);
154
155 for (int i = 0; i < args->argc; i++)
156 {
157 p = strchr(args->argv[i], ':');
158
159 if (p)
160 {
161 if (strncmp(args->argv[i], option,
162 WINPR_ASSERTING_INT_CAST(size_t, p - args->argv[i])) == 0)
163 {
164 free(args->argv[i]);
165 args->argv[i] = str;
166 return 1;
167 }
168 }
169 }
170
171 rc = freerdp_addin_argv_add_argument(args, str);
172 free(str);
173 if (!rc)
174 return -1;
175 return 0;
176}
177
178int freerdp_addin_replace_argument_value(ADDIN_ARGV* args, const char* previous, const char* option,
179 const char* value)
180{
181 BOOL rc = 0;
182 char* str = NULL;
183 size_t length = 0;
184 if (!args || !previous || !option || !value)
185 return -2;
186 length = strlen(option) + strlen(value) + 1;
187 str = (char*)calloc(length + 1, sizeof(char));
188
189 if (!str)
190 return -1;
191
192 (void)sprintf_s(str, length + 1, "%s:%s", option, value);
193
194 for (int i = 0; i < args->argc; i++)
195 {
196 if (strcmp(args->argv[i], previous) == 0)
197 {
198 free(args->argv[i]);
199 args->argv[i] = str;
200 return 1;
201 }
202 }
203
204 rc = freerdp_addin_argv_add_argument(args, str);
205 free(str);
206 if (!rc)
207 return -1;
208 return 0;
209}
210
211BOOL freerdp_device_collection_add(rdpSettings* settings, RDPDR_DEVICE* device)
212{
213 UINT32 count = 0;
214 UINT32 old = 0;
215 WINPR_ASSERT(settings);
216 WINPR_ASSERT(device);
217
218 count = freerdp_settings_get_uint32(settings, FreeRDP_DeviceCount) + 1;
219 old = freerdp_settings_get_uint32(settings, FreeRDP_DeviceArraySize);
220 if (old < count)
221 {
222 UINT32 new_size = old * 2;
223 RDPDR_DEVICE** new_array = NULL;
224
225 if (new_size == 0)
226 new_size = count * 2;
227
228 new_array =
229 (RDPDR_DEVICE**)realloc((void*)settings->DeviceArray, new_size * sizeof(RDPDR_DEVICE*));
230
231 if (!new_array)
232 return FALSE;
233
234 settings->DeviceArray = new_array;
235 memset((void*)&settings->DeviceArray[old], 0, (new_size - old) * sizeof(RDPDR_DEVICE*));
236
237 if (!freerdp_settings_set_uint32(settings, FreeRDP_DeviceArraySize, new_size))
238 return FALSE;
239 }
240
241 settings->DeviceArray[settings->DeviceCount++] = device;
242 return TRUE;
243}
244
245BOOL freerdp_device_collection_del(rdpSettings* settings, const RDPDR_DEVICE* device)
246{
247 WINPR_ASSERT(settings);
248
249 if (!device)
250 return FALSE;
251
252 const UINT32 count = settings->DeviceCount;
253 for (size_t x = 0; x < count; x++)
254 {
255 const RDPDR_DEVICE* cur = settings->DeviceArray[x];
256 if (cur == device)
257 {
258 for (size_t y = x + 1; y < count; y++)
259 {
260 RDPDR_DEVICE* next = settings->DeviceArray[y];
261 settings->DeviceArray[y - 1] = next;
262 }
263 settings->DeviceArray[count - 1] = NULL;
264 settings->DeviceCount--;
265 return TRUE;
266 }
267 }
268
269 return FALSE;
270}
271
272RDPDR_DEVICE* freerdp_device_collection_find(rdpSettings* settings, const char* name)
273{
274 RDPDR_DEVICE* device = NULL;
275
276 WINPR_ASSERT(settings);
277 WINPR_ASSERT(name);
278 for (UINT32 index = 0; index < settings->DeviceCount; index++)
279 {
280 device = settings->DeviceArray[index];
281
282 if (!device->Name)
283 continue;
284
285 if (strcmp(device->Name, name) == 0)
286 return device;
287 }
288
289 return NULL;
290}
291
292RDPDR_DEVICE* freerdp_device_collection_find_type(rdpSettings* settings, UINT32 type)
293{
294 RDPDR_DEVICE* device = NULL;
295 WINPR_ASSERT(settings);
296
297 for (UINT32 index = 0; index < settings->DeviceCount; index++)
298 {
299 device = settings->DeviceArray[index];
300
301 if (device->Type == type)
302 return device;
303 }
304
305 return NULL;
306}
307
308RDPDR_DEVICE* freerdp_device_new(UINT32 Type, size_t count, const char* const args[])
309{
310 size_t size = 0;
311 union
312 {
313 RDPDR_DEVICE* base;
314 RDPDR_DRIVE* drive;
315 RDPDR_SERIAL* serial;
316 RDPDR_PRINTER* printer;
317 RDPDR_PARALLEL* parallel;
318 RDPDR_SMARTCARD* smartcard;
319 } device;
320
321 device.base = NULL;
322 WINPR_ASSERT(args || (count == 0));
323
324 switch (Type)
325 {
326 case RDPDR_DTYP_PRINT:
327 size = sizeof(RDPDR_PRINTER);
328 break;
329 case RDPDR_DTYP_SERIAL:
330 size = sizeof(RDPDR_SERIAL);
331 break;
332 case RDPDR_DTYP_PARALLEL:
333 size = sizeof(RDPDR_PARALLEL);
334 break;
335 case RDPDR_DTYP_SMARTCARD:
336 size = sizeof(RDPDR_SMARTCARD);
337 break;
338 case RDPDR_DTYP_FILESYSTEM:
339 size = sizeof(RDPDR_DRIVE);
340 break;
341 default:
342 goto fail;
343 }
344
345 device.base = calloc(1, size);
346 if (!device.base)
347 goto fail;
348 device.base->Id = 0;
349 device.base->Type = Type;
350
351 if (count > 0)
352 {
353 device.base->Name = _strdup(args[0]);
354 if (!device.base->Name)
355 goto fail;
356
357 switch (Type)
358 {
359 case RDPDR_DTYP_PRINT:
360 if (count > 1)
361 {
362 device.printer->DriverName = _strdup(args[1]);
363 if (!device.printer->DriverName)
364 goto fail;
365 }
366
367 if (count > 2)
368 {
369 device.printer->IsDefault = _stricmp(args[2], "default") == 0;
370 }
371 break;
372 case RDPDR_DTYP_SERIAL:
373 if (count > 1)
374 {
375 device.serial->Path = _strdup(args[1]);
376 if (!device.serial->Path)
377 goto fail;
378 }
379
380 if (count > 2)
381 {
382 device.serial->Driver = _strdup(args[2]);
383 if (!device.serial->Driver)
384 goto fail;
385 }
386
387 if (count > 3)
388 {
389 device.serial->Permissive = _strdup(args[3]);
390 if (!device.serial->Permissive)
391 goto fail;
392 }
393 break;
394 case RDPDR_DTYP_PARALLEL:
395 if (count > 1)
396 {
397 device.parallel->Path = _strdup(args[1]);
398 if (!device.serial->Path)
399 goto fail;
400 }
401 break;
402 case RDPDR_DTYP_SMARTCARD:
403 break;
404 case RDPDR_DTYP_FILESYSTEM:
405 if (count > 1)
406 {
407 device.drive->Path = _strdup(args[1]);
408 if (!device.drive->Path)
409 goto fail;
410 }
411 if (count > 2)
412 device.drive->automount = (args[2] == NULL) ? TRUE : FALSE;
413 break;
414 default:
415 goto fail;
416 }
417 }
418 return device.base;
419
420fail:
421 freerdp_device_free(device.base);
422 return NULL;
423}
424
425void freerdp_device_free(RDPDR_DEVICE* device)
426{
427 if (!device)
428 return;
429
430 union
431 {
432 RDPDR_DEVICE* dev;
433 RDPDR_DRIVE* drive;
434 RDPDR_SERIAL* serial;
435 RDPDR_PRINTER* printer;
436 RDPDR_PARALLEL* parallel;
437 RDPDR_SMARTCARD* smartcard;
438 } cnv;
439
440 cnv.dev = device;
441
442 switch (device->Type)
443 {
444 case RDPDR_DTYP_PRINT:
445 free(cnv.printer->DriverName);
446 break;
447 case RDPDR_DTYP_SERIAL:
448 free(cnv.serial->Path);
449 free(cnv.serial->Driver);
450 free(cnv.serial->Permissive);
451 break;
452 case RDPDR_DTYP_PARALLEL:
453 free(cnv.parallel->Path);
454 break;
455 case RDPDR_DTYP_SMARTCARD:
456 break;
457 case RDPDR_DTYP_FILESYSTEM:
458 free(cnv.drive->Path);
459 break;
460 default:
461 break;
462 }
463 free(cnv.dev->Name);
464 free(cnv.dev);
465}
466
467RDPDR_DEVICE* freerdp_device_clone(const RDPDR_DEVICE* device)
468{
469 union
470 {
471 const RDPDR_DEVICE* dev;
472 const RDPDR_DRIVE* drive;
473 const RDPDR_SERIAL* serial;
474 const RDPDR_PRINTER* printer;
475 const RDPDR_PARALLEL* parallel;
476 const RDPDR_SMARTCARD* smartcard;
477 } src;
478
479 union
480 {
481 RDPDR_DEVICE* dev;
482 RDPDR_DRIVE* drive;
483 RDPDR_SERIAL* serial;
484 RDPDR_PRINTER* printer;
485 RDPDR_PARALLEL* parallel;
486 RDPDR_SMARTCARD* smartcard;
487 } copy;
488 size_t count = 0;
489 const char* args[4] = { 0 };
490
491 copy.dev = NULL;
492 src.dev = device;
493
494 if (!device)
495 return NULL;
496
497 if (device->Name)
498 {
499 count = 1;
500 args[0] = device->Name;
501 }
502
503 switch (device->Type)
504 {
505 case RDPDR_DTYP_FILESYSTEM:
506 if (src.drive->Path)
507 {
508 args[1] = src.drive->Path;
509 count = 2;
510 }
511 break;
512
513 case RDPDR_DTYP_PRINT:
514 if (src.printer->DriverName)
515 {
516 args[1] = src.printer->DriverName;
517 count = 2;
518 }
519 break;
520
521 case RDPDR_DTYP_SMARTCARD:
522 break;
523
524 case RDPDR_DTYP_SERIAL:
525 if (src.serial->Path)
526 {
527 args[1] = src.serial->Path;
528 count = 2;
529 }
530
531 if (src.serial->Driver)
532 {
533 args[2] = src.serial->Driver;
534 count = 3;
535 }
536
537 if (src.serial->Permissive)
538 {
539 args[3] = src.serial->Permissive;
540 count = 4;
541 }
542 break;
543
544 case RDPDR_DTYP_PARALLEL:
545 if (src.parallel->Path)
546 {
547 args[1] = src.parallel->Path;
548 count = 2;
549 }
550 break;
551 default:
552 WLog_ERR(TAG, "unknown device type %" PRIu32 "", device->Type);
553 break;
554 }
555
556 copy.dev = freerdp_device_new(device->Type, count, args);
557 if (!copy.dev)
558 return NULL;
559
560 copy.dev->Id = device->Id;
561
562 return copy.dev;
563}
564
565void freerdp_device_collection_free(rdpSettings* settings)
566{
567 WINPR_ASSERT(settings);
568
569 if (settings->DeviceArray)
570 {
571 for (UINT32 index = 0; index < settings->DeviceArraySize; index++)
572 (void)freerdp_settings_set_pointer_array(settings, FreeRDP_DeviceArray, index, NULL);
573 }
574
575 free((void*)settings->DeviceArray);
576
577 (void)freerdp_settings_set_pointer(settings, FreeRDP_DeviceArray, NULL);
578 (void)freerdp_settings_set_uint32(settings, FreeRDP_DeviceArraySize, 0);
579 (void)freerdp_settings_set_uint32(settings, FreeRDP_DeviceCount, 0);
580}
581
582BOOL freerdp_static_channel_collection_del(rdpSettings* settings, const char* name)
583{
584 const UINT32 count = freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelCount);
585 if (!settings || !settings->StaticChannelArray)
586 return FALSE;
587
588 for (UINT32 x = 0; x < count; x++)
589 {
590 ADDIN_ARGV* cur = settings->StaticChannelArray[x];
591 if (cur && (cur->argc > 0))
592 {
593 if (strcmp(name, cur->argv[0]) == 0)
594 {
595 const size_t rem = settings->StaticChannelArraySize - count + 1;
596 memmove_s((void*)&settings->StaticChannelArray[x],
597 (count - x) * sizeof(ADDIN_ARGV*),
598 (void*)&settings->StaticChannelArray[x + 1],
599 (count - x - 1) * sizeof(ADDIN_ARGV*));
600 memset((void*)&settings->StaticChannelArray[count - 1], 0,
601 sizeof(ADDIN_ARGV*) * rem);
602
603 freerdp_addin_argv_free(cur);
604 return freerdp_settings_set_uint32(settings, FreeRDP_StaticChannelCount, count - 1);
605 }
606 }
607 }
608 {
609 const size_t rem = settings->StaticChannelArraySize - count;
610 memset((void*)&settings->StaticChannelArray[count], 0, sizeof(ADDIN_ARGV*) * rem);
611 }
612 return FALSE;
613}
614
615BOOL freerdp_static_channel_collection_add(rdpSettings* settings, ADDIN_ARGV* channel)
616{
617 UINT32 count = 0;
618
619 WINPR_ASSERT(settings);
620 WINPR_ASSERT(channel);
621
622 count = freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelCount) + 1;
623 if (freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelArraySize) < count)
624 {
625 const UINT32 oldSize =
626 freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelArraySize);
627 UINT32 new_size = oldSize * 2ul;
628 ADDIN_ARGV** new_array = NULL;
629 if (new_size == 0)
630 new_size = count * 2ul;
631
632 new_array = (ADDIN_ARGV**)realloc((void*)settings->StaticChannelArray,
633 new_size * sizeof(ADDIN_ARGV*));
634
635 if (!new_array)
636 return FALSE;
637
638 settings->StaticChannelArray = new_array;
639 {
640 const size_t rem = new_size - oldSize;
641 memset((void*)&settings->StaticChannelArray[oldSize], 0, sizeof(ADDIN_ARGV*) * rem);
642 }
643 if (!freerdp_settings_set_uint32(settings, FreeRDP_StaticChannelArraySize, new_size))
644 return FALSE;
645 }
646
647 count = freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelCount);
648
649 ADDIN_ARGV** cur = &settings->StaticChannelArray[count++];
650 freerdp_addin_argv_free(*cur);
651 *cur = channel;
652 return freerdp_settings_set_uint32(settings, FreeRDP_StaticChannelCount, count);
653}
654
655ADDIN_ARGV* freerdp_static_channel_collection_find(rdpSettings* settings, const char* name)
656{
657 ADDIN_ARGV* channel = NULL;
658
659 WINPR_ASSERT(settings);
660 WINPR_ASSERT(name);
661
662 for (UINT32 index = 0;
663 index < freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelCount); index++)
664 {
665 channel = settings->StaticChannelArray[index];
666
667 if (strcmp(channel->argv[0], name) == 0)
668 return channel;
669 }
670
671 return NULL;
672}
673
674void freerdp_static_channel_collection_free(rdpSettings* settings)
675{
676 if (!settings)
677 return;
678
679 if (settings->StaticChannelArray)
680 {
681 for (UINT32 i = 0;
682 i < freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelArraySize); i++)
683 freerdp_addin_argv_free(settings->StaticChannelArray[i]);
684 }
685
686 free((void*)settings->StaticChannelArray);
687 (void)freerdp_settings_set_uint32(settings, FreeRDP_StaticChannelArraySize, 0);
688 settings->StaticChannelArray = NULL;
689 (void)freerdp_settings_set_uint32(settings, FreeRDP_StaticChannelCount, 0);
690}
691
692BOOL freerdp_dynamic_channel_collection_del(rdpSettings* settings, const char* name)
693{
694 const UINT32 count = freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelCount);
695 if (!settings || !settings->DynamicChannelArray)
696 return FALSE;
697
698 for (UINT32 x = 0; x < count; x++)
699 {
700 ADDIN_ARGV* cur = settings->DynamicChannelArray[x];
701 if (cur && (cur->argc > 0))
702 {
703 if (strcmp(name, cur->argv[0]) == 0)
704 {
705 const size_t rem = settings->DynamicChannelArraySize - count + 1;
706 memmove_s((void*)&settings->DynamicChannelArray[x],
707 (count - x) * sizeof(ADDIN_ARGV*),
708 (void*)&settings->DynamicChannelArray[x + 1],
709 (count - x - 1) * sizeof(ADDIN_ARGV*));
710 memset((void*)&settings->DynamicChannelArray[count - 1], 0,
711 sizeof(ADDIN_ARGV*) * rem);
712
713 freerdp_addin_argv_free(cur);
714 return freerdp_settings_set_uint32(settings, FreeRDP_DynamicChannelCount,
715 count - 1);
716 }
717 }
718 }
719
720 return FALSE;
721}
722
723BOOL freerdp_dynamic_channel_collection_add(rdpSettings* settings, ADDIN_ARGV* channel)
724{
725 UINT32 count = 0;
726 UINT32 oldSize = 0;
727
728 WINPR_ASSERT(settings);
729 WINPR_ASSERT(channel);
730
731 count = freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelCount) + 1;
732 oldSize = freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelArraySize);
733 if (oldSize < count)
734 {
735 ADDIN_ARGV** new_array = NULL;
736 UINT32 size = oldSize * 2;
737 if (size == 0)
738 size = count * 2;
739
740 new_array =
741 (ADDIN_ARGV**)realloc((void*)settings->DynamicChannelArray, sizeof(ADDIN_ARGV*) * size);
742
743 if (!new_array)
744 return FALSE;
745
746 settings->DynamicChannelArray = new_array;
747 {
748 const size_t rem = size - oldSize;
749 memset((void*)&settings->DynamicChannelArray[oldSize], 0, sizeof(ADDIN_ARGV*) * rem);
750 }
751 if (!freerdp_settings_set_uint32(settings, FreeRDP_DynamicChannelArraySize, size))
752 return FALSE;
753 }
754
755 count = freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelCount);
756 settings->DynamicChannelArray[count++] = channel;
757 return freerdp_settings_set_uint32(settings, FreeRDP_DynamicChannelCount, count);
758}
759
760ADDIN_ARGV* freerdp_dynamic_channel_collection_find(const rdpSettings* settings, const char* name)
761{
762 WINPR_ASSERT(settings);
763 WINPR_ASSERT(name);
764
765 for (UINT32 index = 0;
766 index < freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelCount); index++)
767 {
768 ADDIN_ARGV* channel = settings->DynamicChannelArray[index];
769
770 if (strcmp(channel->argv[0], name) == 0)
771 return channel;
772 }
773
774 return NULL;
775}
776
777void freerdp_addin_argv_free(ADDIN_ARGV* args)
778{
779 if (!args)
780 return;
781
782 if (args->argv)
783 {
784 for (int index = 0; index < args->argc; index++)
785 free(args->argv[index]);
786 free((void*)args->argv);
787 }
788
789 free(args);
790}
791
792ADDIN_ARGV* freerdp_addin_argv_new(size_t argc, const char* const argv[])
793{
794 if (argc > INT32_MAX)
795 return NULL;
796
797 ADDIN_ARGV* args = calloc(1, sizeof(ADDIN_ARGV));
798 if (!args)
799 return NULL;
800 if (argc == 0)
801 return args;
802
803 args->argc = (int)argc;
804 args->argv = (char**)calloc(argc, sizeof(char*));
805 if (!args->argv)
806 goto fail;
807
808 if (argv)
809 {
810 for (size_t x = 0; x < argc; x++)
811 {
812 args->argv[x] = _strdup(argv[x]);
813 if (!args->argv[x])
814 goto fail;
815 }
816 }
817 return args;
818
819fail:
820 WINPR_PRAGMA_DIAG_PUSH
821 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
822 freerdp_addin_argv_free(args);
823 WINPR_PRAGMA_DIAG_POP
824 return NULL;
825}
826
827ADDIN_ARGV* freerdp_addin_argv_clone(const ADDIN_ARGV* args)
828{
829 union
830 {
831 char** c;
832 const char** cc;
833 } cnv;
834 if (!args)
835 return NULL;
836 cnv.c = args->argv;
837 return freerdp_addin_argv_new(WINPR_ASSERTING_INT_CAST(uint32_t, args->argc), cnv.cc);
838}
839
840void freerdp_dynamic_channel_collection_free(rdpSettings* settings)
841{
842 WINPR_ASSERT(settings);
843
844 if (settings->DynamicChannelArray)
845 {
846 for (UINT32 i = 0;
847 i < freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelArraySize); i++)
848 freerdp_addin_argv_free(settings->DynamicChannelArray[i]);
849 }
850
851 free((void*)settings->DynamicChannelArray);
852 (void)freerdp_settings_set_uint32(settings, FreeRDP_DynamicChannelArraySize, 0);
853 settings->DynamicChannelArray = NULL;
854 (void)freerdp_settings_set_uint32(settings, FreeRDP_DynamicChannelCount, 0);
855}
856
857void freerdp_capability_buffer_free(rdpSettings* settings)
858{
859 WINPR_ASSERT(settings);
860
861 if (settings->ReceivedCapabilityData)
862 {
863 for (UINT32 x = 0; x < settings->ReceivedCapabilitiesSize; x++)
864 {
865 free(settings->ReceivedCapabilityData[x]);
866 settings->ReceivedCapabilityData[x] = NULL;
867 }
868 }
869 settings->ReceivedCapabilitiesSize = 0;
870
871 free(settings->ReceivedCapabilityDataSizes);
872 settings->ReceivedCapabilityDataSizes = NULL;
873
874 free((void*)settings->ReceivedCapabilityData);
875 settings->ReceivedCapabilityData = NULL;
876 free(settings->ReceivedCapabilities);
877 settings->ReceivedCapabilities = NULL;
878}
879
880BOOL freerdp_capability_buffer_copy(rdpSettings* settings, const rdpSettings* src)
881{
882 WINPR_ASSERT(settings);
883 WINPR_ASSERT(src);
884
885 if (src->ReceivedCapabilitiesSize == 0)
886 return TRUE;
887
888 if (!freerdp_capability_buffer_allocate(settings, src->ReceivedCapabilitiesSize))
889 return FALSE;
890
891 for (UINT32 x = 0; x < src->ReceivedCapabilitiesSize; x++)
892 {
893 WINPR_ASSERT(settings->ReceivedCapabilities);
894 settings->ReceivedCapabilities[x] = src->ReceivedCapabilities[x];
895
896 WINPR_ASSERT(settings->ReceivedCapabilityDataSizes);
897 settings->ReceivedCapabilityDataSizes[x] = src->ReceivedCapabilityDataSizes[x];
898
899 WINPR_ASSERT(settings->ReceivedCapabilityData);
900 if (src->ReceivedCapabilityDataSizes[x] > 0)
901 {
902 void* tmp = realloc(settings->ReceivedCapabilityData[x],
903 settings->ReceivedCapabilityDataSizes[x]);
904 if (!tmp)
905 return FALSE;
906 memcpy(tmp, src->ReceivedCapabilityData[x], src->ReceivedCapabilityDataSizes[x]);
907 settings->ReceivedCapabilityData[x] = tmp;
908 }
909 else
910 {
911 free(settings->ReceivedCapabilityData[x]);
912 settings->ReceivedCapabilityData[x] = NULL;
913 }
914 }
915 return TRUE;
916}
917
918void freerdp_target_net_addresses_free(rdpSettings* settings)
919{
920 WINPR_ASSERT(settings);
921
922 if (settings->TargetNetAddresses)
923 {
924 for (UINT32 index = 0; index < settings->TargetNetAddressCount; index++)
925 free(settings->TargetNetAddresses[index]);
926 }
927
928 free((void*)settings->TargetNetAddresses);
929 free(settings->TargetNetPorts);
930 settings->TargetNetAddressCount = 0;
931 settings->TargetNetAddresses = NULL;
932 settings->TargetNetPorts = NULL;
933}
934
935void freerdp_server_license_issuers_free(rdpSettings* settings)
936{
937 WINPR_ASSERT(settings);
938
939 if (settings->ServerLicenseProductIssuers)
940 {
941 for (UINT32 x = 0; x < settings->ServerLicenseProductIssuersCount; x++)
942 free(settings->ServerLicenseProductIssuers[x]);
943 }
944 free((void*)settings->ServerLicenseProductIssuers);
945 settings->ServerLicenseProductIssuers = NULL;
946 settings->ServerLicenseProductIssuersCount = 0;
947}
948
949BOOL freerdp_server_license_issuers_copy(rdpSettings* settings, char** issuers, UINT32 count)
950{
951 WINPR_ASSERT(settings);
952 WINPR_ASSERT(issuers || (count == 0));
953
954 if (!freerdp_settings_set_pointer_len(settings, FreeRDP_ServerLicenseProductIssuers, NULL,
955 count))
956 return FALSE;
957
958 for (UINT32 x = 0; x < count; x++)
959 {
960 char* issuer = _strdup(issuers[x]);
961 if (!issuer)
962 return FALSE;
963 settings->ServerLicenseProductIssuers[x] = issuer;
964 }
965
966 return TRUE;
967}
968
969void freerdp_performance_flags_make(rdpSettings* settings)
970{
971 UINT32 PerformanceFlags = PERF_FLAG_NONE;
972
973 if (freerdp_settings_get_bool(settings, FreeRDP_AllowFontSmoothing))
974 PerformanceFlags |= PERF_ENABLE_FONT_SMOOTHING;
975
976 if (freerdp_settings_get_bool(settings, FreeRDP_AllowDesktopComposition))
977 PerformanceFlags |= PERF_ENABLE_DESKTOP_COMPOSITION;
978
979 if (freerdp_settings_get_bool(settings, FreeRDP_DisableWallpaper))
980 PerformanceFlags |= PERF_DISABLE_WALLPAPER;
981
982 if (freerdp_settings_get_bool(settings, FreeRDP_DisableFullWindowDrag))
983 PerformanceFlags |= PERF_DISABLE_FULLWINDOWDRAG;
984
985 if (freerdp_settings_get_bool(settings, FreeRDP_DisableMenuAnims))
986 PerformanceFlags |= PERF_DISABLE_MENUANIMATIONS;
987
988 if (freerdp_settings_get_bool(settings, FreeRDP_DisableThemes))
989 PerformanceFlags |= PERF_DISABLE_THEMING;
990 (void)freerdp_settings_set_uint32(settings, FreeRDP_PerformanceFlags, PerformanceFlags);
991}
992
993void freerdp_performance_flags_split(rdpSettings* settings)
994{
996 settings, FreeRDP_AllowFontSmoothing,
997 (freerdp_settings_get_uint32(settings, FreeRDP_PerformanceFlags) &
998 PERF_ENABLE_FONT_SMOOTHING)
999 ? TRUE
1000 : FALSE);
1002 settings, FreeRDP_AllowDesktopComposition,
1003 (freerdp_settings_get_uint32(settings, FreeRDP_PerformanceFlags) &
1004 PERF_ENABLE_DESKTOP_COMPOSITION)
1005 ? TRUE
1006 : FALSE);
1008 settings, FreeRDP_DisableWallpaper,
1009 (freerdp_settings_get_uint32(settings, FreeRDP_PerformanceFlags) & PERF_DISABLE_WALLPAPER)
1010 ? TRUE
1011 : FALSE);
1013 settings, FreeRDP_DisableFullWindowDrag,
1014 (freerdp_settings_get_uint32(settings, FreeRDP_PerformanceFlags) &
1015 PERF_DISABLE_FULLWINDOWDRAG)
1016 ? TRUE
1017 : FALSE);
1019 settings, FreeRDP_DisableMenuAnims,
1020 (freerdp_settings_get_uint32(settings, FreeRDP_PerformanceFlags) &
1021 PERF_DISABLE_MENUANIMATIONS)
1022 ? TRUE
1023 : FALSE);
1025 settings, FreeRDP_DisableThemes,
1026 (freerdp_settings_get_uint32(settings, FreeRDP_PerformanceFlags) & PERF_DISABLE_THEMING)
1027 ? TRUE
1028 : FALSE);
1029}
1030
1031BOOL freerdp_set_gateway_usage_method(rdpSettings* settings, UINT32 GatewayUsageMethod)
1032{
1033 if (!freerdp_settings_set_uint32(settings, FreeRDP_GatewayUsageMethod, GatewayUsageMethod))
1034 return FALSE;
1035
1036 if (GatewayUsageMethod == TSC_PROXY_MODE_NONE_DIRECT)
1037 {
1038 if (!freerdp_settings_set_bool(settings, FreeRDP_GatewayEnabled, FALSE) ||
1039 !freerdp_settings_set_bool(settings, FreeRDP_GatewayBypassLocal, FALSE))
1040 return FALSE;
1041 }
1042 else if (GatewayUsageMethod == TSC_PROXY_MODE_DIRECT)
1043 {
1044 if (!freerdp_settings_set_bool(settings, FreeRDP_GatewayEnabled, TRUE) ||
1045 !freerdp_settings_set_bool(settings, FreeRDP_GatewayBypassLocal, FALSE))
1046 return FALSE;
1047 }
1048 else if (GatewayUsageMethod == TSC_PROXY_MODE_DETECT)
1049 {
1050 if (!freerdp_settings_set_bool(settings, FreeRDP_GatewayEnabled, TRUE) ||
1051 !freerdp_settings_set_bool(settings, FreeRDP_GatewayBypassLocal, TRUE))
1052 return FALSE;
1053 }
1054 else if (GatewayUsageMethod == TSC_PROXY_MODE_DEFAULT)
1055 {
1061 if (!freerdp_settings_set_bool(settings, FreeRDP_GatewayEnabled, FALSE) ||
1062 !freerdp_settings_set_bool(settings, FreeRDP_GatewayBypassLocal, FALSE))
1063 return FALSE;
1064 }
1065 else if (GatewayUsageMethod == TSC_PROXY_MODE_NONE_DETECT)
1066 {
1067 if (!freerdp_settings_set_bool(settings, FreeRDP_GatewayEnabled, FALSE) ||
1068 !freerdp_settings_set_bool(settings, FreeRDP_GatewayBypassLocal, FALSE))
1069 return FALSE;
1070 }
1071
1072 return TRUE;
1073}
1074
1075void freerdp_update_gateway_usage_method(rdpSettings* settings, UINT32 GatewayEnabled,
1076 UINT32 GatewayBypassLocal)
1077{
1078 UINT32 GatewayUsageMethod = 0;
1079
1080 if (!GatewayEnabled && !GatewayBypassLocal)
1081 GatewayUsageMethod = TSC_PROXY_MODE_NONE_DIRECT;
1082 else if (GatewayEnabled && !GatewayBypassLocal)
1083 GatewayUsageMethod = TSC_PROXY_MODE_DIRECT;
1084 else if (GatewayEnabled && GatewayBypassLocal)
1085 GatewayUsageMethod = TSC_PROXY_MODE_DETECT;
1086
1087 freerdp_set_gateway_usage_method(settings, GatewayUsageMethod);
1088}
1089
1090#if defined(WITH_FREERDP_DEPRECATED)
1091BOOL freerdp_get_param_bool(const rdpSettings* settings, int id)
1092{
1093 return freerdp_settings_get_bool(settings, (FreeRDP_Settings_Keys_Bool)id);
1094}
1095
1096int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param)
1097{
1098 return freerdp_settings_set_bool(settings, (FreeRDP_Settings_Keys_Bool)id, param) ? 0 : -1;
1099}
1100
1101int freerdp_get_param_int(const rdpSettings* settings, int id)
1102{
1103 return freerdp_settings_get_int32(settings, (FreeRDP_Settings_Keys_Int32)id);
1104}
1105
1106int freerdp_set_param_int(rdpSettings* settings, int id, int param)
1107{
1108 return freerdp_settings_set_int32(settings, (FreeRDP_Settings_Keys_Int32)id, param) ? 0 : -1;
1109}
1110
1111UINT32 freerdp_get_param_uint32(const rdpSettings* settings, int id)
1112{
1113 return freerdp_settings_get_uint32(settings, (FreeRDP_Settings_Keys_UInt32)id);
1114}
1115
1116int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param)
1117{
1118 return freerdp_settings_set_uint32(settings, (FreeRDP_Settings_Keys_UInt32)id, param) ? 0 : -1;
1119}
1120
1121UINT64 freerdp_get_param_uint64(const rdpSettings* settings, int id)
1122{
1123 return freerdp_settings_get_uint64(settings, (FreeRDP_Settings_Keys_UInt64)id);
1124}
1125
1126int freerdp_set_param_uint64(rdpSettings* settings, int id, UINT64 param)
1127{
1128 return freerdp_settings_set_uint64(settings, (FreeRDP_Settings_Keys_UInt64)id, param) ? 0 : -1;
1129}
1130
1131char* freerdp_get_param_string(const rdpSettings* settings, int id)
1132{
1133 const char* str = freerdp_settings_get_string(settings, (FreeRDP_Settings_Keys_String)id);
1134 return WINPR_CAST_CONST_PTR_AWAY(str, char*);
1135}
1136
1137int freerdp_set_param_string(rdpSettings* settings, int id, const char* param)
1138{
1139 return freerdp_settings_set_string(settings, (FreeRDP_Settings_Keys_String)id, param) ? 0 : -1;
1140}
1141#endif
1142
1143static BOOL value_to_uint(const char* value, ULONGLONG* result, ULONGLONG min, ULONGLONG max)
1144{
1145 char* endptr = NULL;
1146 unsigned long long rc = 0;
1147
1148 if (!value || !result)
1149 return FALSE;
1150
1151 errno = 0;
1152 rc = _strtoui64(value, &endptr, 0);
1153
1154 if (errno != 0)
1155 return FALSE;
1156
1157 if (endptr == value)
1158 return FALSE;
1159
1160 if ((rc < min) || (rc > max))
1161 return FALSE;
1162
1163 *result = rc;
1164 return TRUE;
1165}
1166
1167static BOOL value_to_int(const char* value, LONGLONG* result, LONGLONG min, LONGLONG max)
1168{
1169 char* endptr = NULL;
1170 long long rc = 0;
1171
1172 if (!value || !result)
1173 return FALSE;
1174
1175 errno = 0;
1176 rc = _strtoi64(value, &endptr, 0);
1177
1178 if (errno != 0)
1179 return FALSE;
1180
1181 if (endptr == value)
1182 return FALSE;
1183
1184 if ((rc < min) || (rc > max))
1185 return FALSE;
1186
1187 *result = rc;
1188 return TRUE;
1189}
1190
1191static BOOL parsing_fail(const char* key, const char* type, const char* value)
1192{
1193 WLog_ERR(TAG, "Failed to parse key [%s] of type [%s]: value [%s]", key, type, value);
1194 return FALSE;
1195}
1196
1197BOOL freerdp_settings_set_value_for_name(rdpSettings* settings, const char* name, const char* value)
1198{
1199 ULONGLONG uval = 0;
1200 LONGLONG ival = 0;
1201 SSIZE_T type = 0;
1202
1203 if (!settings || !name)
1204 return FALSE;
1205
1206 const SSIZE_T i = freerdp_settings_get_key_for_name(name);
1207 if (i < 0)
1208 {
1209 WLog_ERR(TAG, "Invalid settings key [%s]", name);
1210 return FALSE;
1211 }
1212
1213 const SSIZE_T index = i;
1214
1216 switch (type)
1217 {
1218
1219 case RDP_SETTINGS_TYPE_BOOL:
1220 {
1221 const BOOL val = (_strnicmp(value, "TRUE", 5) == 0) || (_strnicmp(value, "ON", 5) == 0);
1222 const BOOL nval =
1223 (_strnicmp(value, "FALSE", 6) == 0) || (_strnicmp(value, "OFF", 6) == 0);
1224 if (!val && !nval)
1225 return parsing_fail(name, "BOOL", value);
1226
1227 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
1228 return freerdp_settings_set_bool(settings, (FreeRDP_Settings_Keys_Bool)index, val);
1229 }
1230 case RDP_SETTINGS_TYPE_UINT16:
1231 if (!value_to_uint(value, &uval, 0, UINT16_MAX))
1232 return parsing_fail(name, "UINT16", value);
1233
1234 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
1235 if (!freerdp_settings_set_uint16(settings, (FreeRDP_Settings_Keys_UInt16)index,
1236 (UINT16)uval))
1237 return parsing_fail(name, "UINT16", value);
1238 return TRUE;
1239
1240 case RDP_SETTINGS_TYPE_INT16:
1241 if (!value_to_int(value, &ival, INT16_MIN, INT16_MAX))
1242 return parsing_fail(name, "INT16", value);
1243
1244 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
1245 if (!freerdp_settings_set_int16(settings, (FreeRDP_Settings_Keys_Int16)index,
1246 (INT16)ival))
1247 return parsing_fail(name, "INT16", value);
1248 return TRUE;
1249 case RDP_SETTINGS_TYPE_UINT32:
1250 if (!value_to_uint(value, &uval, 0, UINT32_MAX))
1251 return parsing_fail(name, "UINT32", value);
1252
1253 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
1254 if (!freerdp_settings_set_uint32(settings, (FreeRDP_Settings_Keys_UInt32)index,
1255 (UINT32)uval))
1256 return parsing_fail(name, "UINT32", value);
1257 return TRUE;
1258 case RDP_SETTINGS_TYPE_INT32:
1259 if (!value_to_int(value, &ival, INT32_MIN, INT32_MAX))
1260 return parsing_fail(name, "INT32", value);
1261
1262 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
1263 if (!freerdp_settings_set_int32(settings, (FreeRDP_Settings_Keys_Int32)index,
1264 (INT32)ival))
1265 return parsing_fail(name, "INT32", value);
1266 return TRUE;
1267 case RDP_SETTINGS_TYPE_UINT64:
1268 if (!value_to_uint(value, &uval, 0, UINT64_MAX))
1269 return parsing_fail(name, "UINT64", value);
1270
1271 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
1272 if (!freerdp_settings_set_uint64(settings, (FreeRDP_Settings_Keys_UInt64)index, uval))
1273 return parsing_fail(name, "UINT64", value);
1274 return TRUE;
1275 case RDP_SETTINGS_TYPE_INT64:
1276 if (!value_to_int(value, &ival, INT64_MIN, INT64_MAX))
1277 return parsing_fail(name, "INT64", value);
1278
1279 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
1280 if (!freerdp_settings_set_int64(settings, (FreeRDP_Settings_Keys_Int64)index, ival))
1281 return parsing_fail(name, "INT64", value);
1282 return TRUE;
1283
1284 case RDP_SETTINGS_TYPE_STRING:
1285 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
1286 return freerdp_settings_set_string(settings, (FreeRDP_Settings_Keys_String)index,
1287 value);
1288 case RDP_SETTINGS_TYPE_POINTER:
1289 return parsing_fail(name, "POINTER", value);
1290 default:
1291 return FALSE;
1292 }
1293 return FALSE;
1294}
1295
1296BOOL freerdp_settings_set_pointer_len_(rdpSettings* settings, FreeRDP_Settings_Keys_Pointer id,
1297 FreeRDP_Settings_Keys_UInt32 lenId, const void* data,
1298 size_t len, size_t size)
1299{
1300 BOOL rc = FALSE;
1301 void* copy = NULL;
1302 void* old = freerdp_settings_get_pointer_writable(settings, id);
1303 free(old);
1304 if (!freerdp_settings_set_pointer(settings, id, NULL))
1305 return FALSE;
1306 if (lenId != FreeRDP_UINT32_UNUSED)
1307 {
1308 if (!freerdp_settings_set_uint32(settings, lenId, 0))
1309 return FALSE;
1310 }
1311
1312 if (len > UINT32_MAX)
1313 return FALSE;
1314 if (len == 0)
1315 return TRUE;
1316 copy = calloc(len, size);
1317 if (!copy)
1318 return FALSE;
1319 if (data)
1320 memcpy(copy, data, len * size);
1321 rc = freerdp_settings_set_pointer(settings, id, copy);
1322 if (!rc)
1323 {
1324 free(copy);
1325 return FALSE;
1326 }
1327
1328 // freerdp_settings_set_pointer takes ownership of copy
1329 // NOLINTNEXTLINE(clang-analyzer-unix.Malloc)
1330 if (lenId == FreeRDP_UINT32_UNUSED)
1331 return TRUE;
1332 return freerdp_settings_set_uint32(settings, lenId, (UINT32)len);
1333}
1334
1335const void* freerdp_settings_get_pointer(const rdpSettings* settings,
1336 FreeRDP_Settings_Keys_Pointer id)
1337{
1338 union
1339 {
1340 const rdpSettings* pc;
1341 rdpSettings* p;
1342 } cnv;
1343 cnv.pc = settings;
1344 return freerdp_settings_get_pointer_writable(cnv.p, id);
1345}
1346
1347BOOL freerdp_settings_set_pointer_len(rdpSettings* settings, FreeRDP_Settings_Keys_Pointer id,
1348 const void* data, size_t len)
1349{
1350 union
1351 {
1352 const void* cv;
1353 void* v;
1354 } cnv;
1355
1356 cnv.cv = data;
1357 if (!settings)
1358 return FALSE;
1359
1360 switch (id)
1361 {
1362 case FreeRDP_RdpServerCertificate:
1363 freerdp_certificate_free(settings->RdpServerCertificate);
1364
1365 if (len > 1)
1366 {
1367 WLog_ERR(TAG, "FreeRDP_RdpServerCertificate::len must be 0 or 1");
1368 return FALSE;
1369 }
1370 settings->RdpServerCertificate = cnv.v;
1371 if (!settings->RdpServerCertificate && (len > 0))
1372 {
1373 settings->RdpServerCertificate = freerdp_certificate_new();
1374 if (!settings->RdpServerCertificate)
1375 return FALSE;
1376 }
1377 return TRUE;
1378 case FreeRDP_RdpServerRsaKey:
1379 freerdp_key_free(settings->RdpServerRsaKey);
1380 if (len > 1)
1381 {
1382 WLog_ERR(TAG, "FreeRDP_RdpServerRsaKey::len must be 0 or 1");
1383 return FALSE;
1384 }
1385 settings->RdpServerRsaKey = (rdpPrivateKey*)cnv.v;
1386 if (!settings->RdpServerRsaKey && (len > 0))
1387 {
1388 settings->RdpServerRsaKey = freerdp_key_new();
1389 if (!settings->RdpServerRsaKey)
1390 return FALSE;
1391 }
1392 return TRUE;
1393 case FreeRDP_RedirectionPassword:
1394 return freerdp_settings_set_pointer_len_(
1395 settings, id, FreeRDP_RedirectionPasswordLength, data, len, sizeof(char));
1396 case FreeRDP_RedirectionTsvUrl:
1397 return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_RedirectionTsvUrlLength,
1398 data, len, sizeof(char));
1399 case FreeRDP_RedirectionTargetCertificate:
1400 freerdp_certificate_free(settings->RedirectionTargetCertificate);
1401
1402 if (len > 1)
1403 {
1404 WLog_ERR(TAG, "FreeRDP_RedirectionTargetCertificate::len must be 0 or 1");
1405 return FALSE;
1406 }
1407 settings->RedirectionTargetCertificate = cnv.v;
1408 if (!settings->RedirectionTargetCertificate && (len > 0))
1409 {
1410 settings->RedirectionTargetCertificate = freerdp_certificate_new();
1411 if (!settings->RedirectionTargetCertificate)
1412 return FALSE;
1413 }
1414 return TRUE;
1415 case FreeRDP_RedirectionGuid:
1416 return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_RedirectionGuidLength,
1417 data, len, sizeof(BYTE));
1418 case FreeRDP_LoadBalanceInfo:
1419 return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_LoadBalanceInfoLength,
1420 data, len, sizeof(char));
1421 case FreeRDP_ServerRandom:
1422 return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_ServerRandomLength, data,
1423 len, sizeof(char));
1424 case FreeRDP_ClientRandom:
1425 return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_ClientRandomLength, data,
1426 len, sizeof(char));
1427 case FreeRDP_ServerCertificate:
1428 return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_ServerCertificateLength,
1429 data, len, sizeof(char));
1430 case FreeRDP_TargetNetAddresses:
1431 if ((data == NULL) && (len == 0))
1432 {
1433 freerdp_target_net_addresses_free(settings);
1434 return TRUE;
1435 }
1436 WLog_WARN(
1437 TAG,
1438 "[BUG] FreeRDP_TargetNetAddresses must not be resized from outside the library!");
1439 return FALSE;
1440 case FreeRDP_ServerLicenseProductIssuers:
1441 if (data == NULL)
1442 freerdp_server_license_issuers_free(settings);
1443 return freerdp_settings_set_pointer_len_(settings, FreeRDP_ServerLicenseProductIssuers,
1444 FreeRDP_ServerLicenseProductIssuersCount, data,
1445 len, sizeof(char*));
1446 case FreeRDP_TargetNetPorts:
1447 if ((data == NULL) && (len == 0))
1448 {
1449 freerdp_target_net_addresses_free(settings);
1450 return TRUE;
1451 }
1452 WLog_WARN(TAG,
1453 "[BUG] FreeRDP_TargetNetPorts must not be resized from outside the library!");
1454 return FALSE;
1455 case FreeRDP_DeviceArray:
1456 if (data == NULL)
1457 freerdp_device_collection_free(settings);
1458 return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_DeviceArraySize, data,
1459 len, sizeof(ADDIN_ARGV*));
1460 case FreeRDP_ChannelDefArray:
1461 if ((len > 0) && (len < CHANNEL_MAX_COUNT))
1462 WLog_WARN(TAG,
1463 "FreeRDP_ChannelDefArray::len expected to be >= %" PRIu32
1464 ", but have %" PRIu32,
1465 CHANNEL_MAX_COUNT, len);
1466 return freerdp_settings_set_pointer_len_(settings, FreeRDP_ChannelDefArray,
1467 FreeRDP_ChannelDefArraySize, data, len,
1468 sizeof(CHANNEL_DEF));
1469 case FreeRDP_MonitorDefArray:
1470 return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_MonitorDefArraySize,
1471 data, len, sizeof(rdpMonitor));
1472 case FreeRDP_ClientAutoReconnectCookie:
1473 return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_UINT32_UNUSED, data, len,
1474 sizeof(ARC_CS_PRIVATE_PACKET));
1475 case FreeRDP_ServerAutoReconnectCookie:
1476 return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_UINT32_UNUSED, data, len,
1477 sizeof(ARC_SC_PRIVATE_PACKET));
1478 case FreeRDP_ClientTimeZone:
1479 if (len > 1)
1480 {
1481 WLog_ERR(TAG, "FreeRDP_ClientTimeZone::len must be 0 or 1");
1482 return FALSE;
1483 }
1484 return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_UINT32_UNUSED, data, len,
1485 sizeof(TIME_ZONE_INFORMATION));
1486 case FreeRDP_BitmapCacheV2CellInfo:
1487 return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_BitmapCacheV2NumCells,
1488 data, len, sizeof(BITMAP_CACHE_V2_CELL_INFO));
1489 case FreeRDP_GlyphCache:
1490 if ((len != 0) && (len != 10))
1491 {
1492 WLog_ERR(TAG, "FreeRDP_GlyphCache::len must be 0 or 10");
1493 return FALSE;
1494 }
1495 return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_UINT32_UNUSED, data, len,
1496 sizeof(GLYPH_CACHE_DEFINITION));
1497 case FreeRDP_FragCache:
1498 if (len > 1)
1499 {
1500 WLog_ERR(TAG, "FreeRDP_FragCache::len must be 0 or 1");
1501 return FALSE;
1502 }
1503 return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_UINT32_UNUSED, data, len,
1504 sizeof(GLYPH_CACHE_DEFINITION));
1505 case FreeRDP_StaticChannelArray:
1506 if (data == NULL)
1507 freerdp_static_channel_collection_free(settings);
1508 return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_StaticChannelArraySize,
1509 data, len, sizeof(ADDIN_ARGV*));
1510 case FreeRDP_DynamicChannelArray:
1511 if (data == NULL)
1512 freerdp_dynamic_channel_collection_free(settings);
1513 return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_DynamicChannelArraySize,
1514 data, len, sizeof(ADDIN_ARGV*));
1515 case FreeRDP_ReceivedCapabilityData:
1516 if (data == NULL)
1517 freerdp_capability_buffer_free(settings);
1518 return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_ReceivedCapabilitiesSize,
1519 data, len, sizeof(BYTE*));
1520 case FreeRDP_ReceivedCapabilities:
1521 if (data == NULL)
1522 freerdp_capability_buffer_free(settings);
1523 return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_ReceivedCapabilitiesSize,
1524 data, len, sizeof(char));
1525 case FreeRDP_OrderSupport:
1526 return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_UINT32_UNUSED, data, len,
1527 sizeof(char));
1528
1529 case FreeRDP_MonitorIds:
1530 return freerdp_settings_set_pointer_len_(
1531 settings, FreeRDP_MonitorIds, FreeRDP_NumMonitorIds, data, len, sizeof(UINT32));
1532
1533 default:
1534 if ((data == NULL) && (len == 0))
1535 {
1536 freerdp_settings_set_pointer(settings, id, NULL);
1537 }
1538 else
1539 WLog_WARN(TAG, "Invalid id %" PRIuz, id);
1540 return FALSE;
1541 }
1542}
1543
1544void* freerdp_settings_get_pointer_array_writable(const rdpSettings* settings,
1545 FreeRDP_Settings_Keys_Pointer id, size_t offset)
1546{
1547 size_t max = 0;
1548 if (!settings)
1549 return NULL;
1550 switch (id)
1551 {
1552 case FreeRDP_ClientAutoReconnectCookie:
1553 max = 1;
1554 if ((offset >= max) || !settings->ClientAutoReconnectCookie)
1555 goto fail;
1556 return &settings->ClientAutoReconnectCookie[offset];
1557 case FreeRDP_ServerAutoReconnectCookie:
1558 max = 1;
1559 if ((offset >= max) || !settings->ServerAutoReconnectCookie)
1560 goto fail;
1561 return &settings->ServerAutoReconnectCookie[offset];
1562 case FreeRDP_ServerCertificate:
1563 max = freerdp_settings_get_uint32(settings, FreeRDP_ServerCertificateLength);
1564 if (offset >= max)
1565 goto fail;
1566 return &settings->ServerCertificate[offset];
1567 case FreeRDP_ServerRandom:
1568 max = freerdp_settings_get_uint32(settings, FreeRDP_ServerRandomLength);
1569 if (offset >= max)
1570 goto fail;
1571 return &settings->ServerRandom[offset];
1572 case FreeRDP_ClientRandom:
1573 max = freerdp_settings_get_uint32(settings, FreeRDP_ClientRandomLength);
1574 if (offset >= max)
1575 goto fail;
1576 return &settings->ClientRandom[offset];
1577 case FreeRDP_LoadBalanceInfo:
1578 max = freerdp_settings_get_uint32(settings, FreeRDP_LoadBalanceInfoLength);
1579 if (offset >= max)
1580 goto fail;
1581 return &settings->LoadBalanceInfo[offset];
1582
1583 case FreeRDP_RedirectionTsvUrl:
1584 max = freerdp_settings_get_uint32(settings, FreeRDP_RedirectionTsvUrlLength);
1585 if (offset >= max)
1586 goto fail;
1587 return &settings->RedirectionTsvUrl[offset];
1588
1589 case FreeRDP_RedirectionPassword:
1590 max = freerdp_settings_get_uint32(settings, FreeRDP_RedirectionPasswordLength);
1591 if (offset >= max)
1592 goto fail;
1593 return &settings->RedirectionPassword[offset];
1594
1595 case FreeRDP_OrderSupport:
1596 max = 32;
1597 if (offset >= max)
1598 goto fail;
1599 return &settings->OrderSupport[offset];
1600 case FreeRDP_MonitorIds:
1601 max = freerdp_settings_get_uint32(settings, FreeRDP_NumMonitorIds);
1602 if (offset >= max)
1603 goto fail;
1604 return &settings->MonitorIds[offset];
1605 case FreeRDP_MonitorDefArray:
1606 max = freerdp_settings_get_uint32(settings, FreeRDP_MonitorDefArraySize);
1607 if (offset >= max)
1608 goto fail;
1609 return &settings->MonitorDefArray[offset];
1610 case FreeRDP_ChannelDefArray:
1611 max = freerdp_settings_get_uint32(settings, FreeRDP_ChannelDefArraySize);
1612 if (offset >= max)
1613 goto fail;
1614 return &settings->ChannelDefArray[offset];
1615 case FreeRDP_DeviceArray:
1616 max = freerdp_settings_get_uint32(settings, FreeRDP_DeviceArraySize);
1617 if (offset >= max)
1618 goto fail;
1619 return settings->DeviceArray[offset];
1620 case FreeRDP_StaticChannelArray:
1621 max = freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelArraySize);
1622 if (offset >= max)
1623 goto fail;
1624 return settings->StaticChannelArray[offset];
1625 case FreeRDP_DynamicChannelArray:
1626 max = freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelArraySize);
1627 if (offset >= max)
1628 goto fail;
1629 return settings->DynamicChannelArray[offset];
1630 case FreeRDP_FragCache:
1631 max = 1;
1632 if (offset >= max)
1633 goto fail;
1634 return &settings->FragCache[offset];
1635 case FreeRDP_GlyphCache:
1636 max = 10;
1637 if (offset >= max)
1638 goto fail;
1639 return &settings->GlyphCache[offset];
1640 case FreeRDP_BitmapCacheV2CellInfo:
1641 max = freerdp_settings_get_uint32(settings, FreeRDP_BitmapCacheV2NumCells);
1642 if (offset >= max)
1643 goto fail;
1644 return &settings->BitmapCacheV2CellInfo[offset];
1645 case FreeRDP_ReceivedCapabilities:
1646 max = freerdp_settings_get_uint32(settings, FreeRDP_ReceivedCapabilitiesSize);
1647 if (offset >= max)
1648 goto fail;
1649 return &settings->ReceivedCapabilities[offset];
1650 case FreeRDP_TargetNetAddresses:
1651 max = freerdp_settings_get_uint32(settings, FreeRDP_TargetNetAddressCount);
1652 if (offset >= max)
1653 goto fail;
1654 return settings->TargetNetAddresses[offset];
1655 case FreeRDP_TargetNetPorts:
1656 max = freerdp_settings_get_uint32(settings, FreeRDP_TargetNetAddressCount);
1657 if (offset >= max)
1658 goto fail;
1659 return &settings->TargetNetPorts[offset];
1660 case FreeRDP_ClientTimeZone:
1661 max = 1;
1662 if (offset >= max)
1663 goto fail;
1664 return settings->ClientTimeZone;
1665 case FreeRDP_RdpServerCertificate:
1666 max = 1;
1667 if (offset >= max)
1668 goto fail;
1669 return settings->RdpServerCertificate;
1670 case FreeRDP_RdpServerRsaKey:
1671 max = 1;
1672 if (offset >= max)
1673 goto fail;
1674 return settings->RdpServerRsaKey;
1675 default:
1676 WLog_WARN(TAG, "Invalid id %s [%" PRIuz "]", freerdp_settings_get_name_for_key(id), id);
1677 return NULL;
1678 }
1679
1680fail:
1681 WLog_WARN(TAG, "Invalid offset for %s [%" PRIuz "]: size=%" PRIuz ", offset=%" PRIuz,
1682 freerdp_settings_get_name_for_key(id), id, max, offset);
1683 return NULL;
1684}
1685
1686BOOL freerdp_settings_set_pointer_array(rdpSettings* settings, FreeRDP_Settings_Keys_Pointer id,
1687 size_t offset, const void* data)
1688{
1689 size_t maxOffset = 0;
1690 if (!settings)
1691 return FALSE;
1692 switch (id)
1693 {
1694 case FreeRDP_ClientAutoReconnectCookie:
1695 maxOffset = 1;
1696 if ((offset >= maxOffset) || !data || !settings->ClientAutoReconnectCookie)
1697 goto fail;
1698 settings->ClientAutoReconnectCookie[offset] = *(const ARC_CS_PRIVATE_PACKET*)data;
1699 return TRUE;
1700 case FreeRDP_ServerAutoReconnectCookie:
1701 maxOffset = 1;
1702 if ((offset >= maxOffset) || !data || !settings->ServerAutoReconnectCookie)
1703 goto fail;
1704 settings->ServerAutoReconnectCookie[offset] = *(const ARC_SC_PRIVATE_PACKET*)data;
1705 return TRUE;
1706 case FreeRDP_ServerCertificate:
1707 maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_ServerCertificateLength);
1708 if ((offset >= maxOffset) || !data)
1709 goto fail;
1710 settings->ServerCertificate[offset] = *(const BYTE*)data;
1711 return TRUE;
1712 case FreeRDP_DeviceArray:
1713 maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_DeviceArraySize);
1714 if (offset >= maxOffset)
1715 goto fail;
1716 freerdp_device_free(settings->DeviceArray[offset]);
1717 settings->DeviceArray[offset] = freerdp_device_clone(data);
1718 return TRUE;
1719 case FreeRDP_TargetNetAddresses:
1720 maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_TargetNetAddressCount);
1721 if ((offset >= maxOffset) || !data)
1722 goto fail;
1723 free(settings->TargetNetAddresses[offset]);
1724 settings->TargetNetAddresses[offset] = _strdup((const char*)data);
1725 return settings->TargetNetAddresses[offset] != NULL;
1726 case FreeRDP_TargetNetPorts:
1727 maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_TargetNetAddressCount);
1728 if ((offset >= maxOffset) || !data)
1729 goto fail;
1730 settings->TargetNetPorts[offset] = *((const UINT32*)data);
1731 return TRUE;
1732 case FreeRDP_StaticChannelArray:
1733 maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelArraySize);
1734 if ((offset >= maxOffset) || !data)
1735 goto fail;
1736 freerdp_addin_argv_free(settings->StaticChannelArray[offset]);
1737 settings->StaticChannelArray[offset] = freerdp_addin_argv_clone(data);
1738 return TRUE;
1739 case FreeRDP_DynamicChannelArray:
1740 maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelArraySize);
1741 if ((offset >= maxOffset) || !data)
1742 goto fail;
1743 freerdp_addin_argv_free(settings->DynamicChannelArray[offset]);
1744 settings->DynamicChannelArray[offset] = freerdp_addin_argv_clone(data);
1745 return TRUE;
1746 case FreeRDP_BitmapCacheV2CellInfo:
1747 maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_BitmapCacheV2NumCells);
1748 if ((offset >= maxOffset) || !data)
1749 goto fail;
1750 {
1751 const BITMAP_CACHE_V2_CELL_INFO* cdata = (const BITMAP_CACHE_V2_CELL_INFO*)data;
1752 settings->BitmapCacheV2CellInfo[offset] = *cdata;
1753 }
1754 return TRUE;
1755 case FreeRDP_ServerRandom:
1756 maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_ServerRandomLength);
1757 if ((offset >= maxOffset) || !data)
1758 goto fail;
1759 settings->ServerRandom[offset] = *(const BYTE*)data;
1760 return TRUE;
1761 case FreeRDP_ClientRandom:
1762 maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_ClientRandomLength);
1763 if ((offset >= maxOffset) || !data)
1764 goto fail;
1765 settings->ClientRandom[offset] = *(const BYTE*)data;
1766 return TRUE;
1767 case FreeRDP_LoadBalanceInfo:
1768 maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_LoadBalanceInfoLength);
1769 if ((offset >= maxOffset) || !data)
1770 goto fail;
1771 settings->LoadBalanceInfo[offset] = *(const BYTE*)data;
1772 return TRUE;
1773 case FreeRDP_RedirectionTsvUrl:
1774 maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_RedirectionTsvUrlLength);
1775 if ((offset >= maxOffset) || !data)
1776 goto fail;
1777 settings->RedirectionTsvUrl[offset] = *(const BYTE*)data;
1778 return TRUE;
1779 case FreeRDP_RedirectionPassword:
1780 maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_RedirectionPasswordLength);
1781 if ((offset >= maxOffset) || !data)
1782 goto fail;
1783 settings->RedirectionPassword[offset] = *(const BYTE*)data;
1784 return TRUE;
1785 case FreeRDP_OrderSupport:
1786 maxOffset = 32;
1787 if (!settings->OrderSupport)
1788 goto fail;
1789 if ((offset >= maxOffset) || !data)
1790 goto fail;
1791 settings->OrderSupport[offset] = *(const BOOL*)data ? 1 : 0;
1792 return TRUE;
1793 case FreeRDP_GlyphCache:
1794 maxOffset = 10;
1795 if (!settings->GlyphCache)
1796 goto fail;
1797 if ((offset >= maxOffset) || !data)
1798 goto fail;
1799 settings->GlyphCache[offset] = *(const GLYPH_CACHE_DEFINITION*)data;
1800 return TRUE;
1801 case FreeRDP_FragCache:
1802 maxOffset = 1;
1803 if (!settings->FragCache)
1804 goto fail;
1805 if ((offset >= maxOffset) || !data)
1806 goto fail;
1807 settings->FragCache[offset] = *(const GLYPH_CACHE_DEFINITION*)data;
1808 return TRUE;
1809 case FreeRDP_MonitorIds:
1810 maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_NumMonitorIds);
1811 if ((offset >= maxOffset) || !data)
1812 goto fail;
1813 settings->MonitorIds[offset] = *(const UINT32*)data;
1814 return TRUE;
1815 case FreeRDP_ChannelDefArray:
1816 maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_ChannelDefArraySize);
1817 if ((offset >= maxOffset) || !data)
1818 goto fail;
1819 settings->ChannelDefArray[offset] = *(const CHANNEL_DEF*)data;
1820 return TRUE;
1821 case FreeRDP_MonitorDefArray:
1822 maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_MonitorDefArraySize);
1823 if ((offset >= maxOffset) || !data)
1824 goto fail;
1825 settings->MonitorDefArray[offset] = *(const rdpMonitor*)data;
1826 return TRUE;
1827
1828 case FreeRDP_ClientTimeZone:
1829 maxOffset = 1;
1830 if ((offset >= maxOffset) || !data || !settings->ClientTimeZone)
1831 goto fail;
1832 settings->ClientTimeZone[0] = *(const TIME_ZONE_INFORMATION*)data;
1833 return TRUE;
1834
1835 default:
1836 WLog_WARN(TAG, "Invalid id %s [%" PRIuz "]", freerdp_settings_get_name_for_key(id), id);
1837 return FALSE;
1838 }
1839
1840fail:
1841 WLog_WARN(TAG, "[%s] Invalid offset=%" PRIuz " [%" PRIuz "] or NULL data=%p",
1842 freerdp_settings_get_name_for_key(id), offset, maxOffset, data);
1843 return FALSE;
1844}
1845
1846const void* freerdp_settings_get_pointer_array(const rdpSettings* settings,
1847 FreeRDP_Settings_Keys_Pointer id, size_t offset)
1848{
1849 return freerdp_settings_get_pointer_array_writable(settings, id, offset);
1850}
1851
1852UINT32 freerdp_settings_get_codecs_flags(const rdpSettings* settings)
1853{
1854 UINT32 flags = FREERDP_CODEC_ALL;
1855 if (settings->RemoteFxCodec == FALSE)
1856 {
1857 flags &= (uint32_t)~FREERDP_CODEC_REMOTEFX;
1858 }
1859 if (settings->NSCodec == FALSE)
1860 {
1861 flags &= (uint32_t)~FREERDP_CODEC_NSCODEC;
1862 }
1863 /*TODO: check other codecs flags */
1864 return flags;
1865}
1866
1867const char* freerdp_settings_get_server_name(const rdpSettings* settings)
1868{
1869 WINPR_ASSERT(settings);
1870 const char* hostname = settings->ServerHostname;
1871
1872 if (settings->UserSpecifiedServerName)
1873 hostname = settings->UserSpecifiedServerName;
1874
1875 return hostname;
1876}
1877
1878#if defined(WITH_FREERDP_DEPRECATED)
1879ADDIN_ARGV* freerdp_static_channel_clone(ADDIN_ARGV* channel)
1880{
1881 return freerdp_addin_argv_clone(channel);
1882}
1883
1884ADDIN_ARGV* freerdp_dynamic_channel_clone(ADDIN_ARGV* channel)
1885{
1886 return freerdp_addin_argv_clone(channel);
1887}
1888#endif
1889
1890BOOL freerdp_target_net_addresses_copy(rdpSettings* settings, char** addresses, UINT32 count)
1891{
1892 WINPR_ASSERT(settings);
1893 WINPR_ASSERT(addresses);
1894
1895 if (!freerdp_target_net_adresses_reset(settings, count))
1896 return FALSE;
1897
1898 for (UINT32 i = 0; i < settings->TargetNetAddressCount; i++)
1899 {
1900 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_TargetNetAddresses, i,
1901 addresses[i]))
1902 {
1903 freerdp_target_net_addresses_free(settings);
1904 return FALSE;
1905 }
1906 }
1907
1908 return TRUE;
1909}
1910
1911BOOL freerdp_device_equal(const RDPDR_DEVICE* what, const RDPDR_DEVICE* expect)
1912{
1913 if (!what && !expect)
1914 return TRUE;
1915 if (!what || !expect)
1916 return FALSE;
1917
1918 if (what->Id != expect->Id)
1919 return FALSE;
1920 if (what->Type != expect->Type)
1921 return FALSE;
1922 if (what->Name && expect->Name)
1923 {
1924 if (strcmp(what->Name, expect->Name) != 0)
1925 return FALSE;
1926 }
1927 else
1928 {
1929 if (what->Name != expect->Name)
1930 return FALSE;
1931 }
1932
1933 switch (what->Type)
1934 {
1935 case RDPDR_DTYP_PRINT:
1936 {
1937 const RDPDR_PRINTER* a = (const RDPDR_PRINTER*)what;
1938 const RDPDR_PRINTER* b = (const RDPDR_PRINTER*)expect;
1939 if (a->DriverName && b->DriverName)
1940 return strcmp(a->DriverName, b->DriverName) == 0;
1941 return a->DriverName == b->DriverName;
1942 }
1943
1944 case RDPDR_DTYP_SERIAL:
1945 {
1946 const RDPDR_SERIAL* a = (const RDPDR_SERIAL*)what;
1947 const RDPDR_SERIAL* b = (const RDPDR_SERIAL*)expect;
1948
1949 if (a->Path && b->Path)
1950 {
1951 if (strcmp(a->Path, b->Path) != 0)
1952 return FALSE;
1953 }
1954 else if (a->Path != b->Path)
1955 return FALSE;
1956
1957 if (a->Driver && b->Driver)
1958 {
1959 if (strcmp(a->Driver, b->Driver) != 0)
1960 return FALSE;
1961 }
1962 else if (a->Driver != b->Driver)
1963 return FALSE;
1964 if (a->Permissive && b->Permissive)
1965 return strcmp(a->Permissive, b->Permissive) == 0;
1966 return a->Permissive == b->Permissive;
1967 }
1968
1969 case RDPDR_DTYP_PARALLEL:
1970 {
1971 const RDPDR_PARALLEL* a = (const RDPDR_PARALLEL*)what;
1972 const RDPDR_PARALLEL* b = (const RDPDR_PARALLEL*)expect;
1973 if (a->Path && b->Path)
1974 return strcmp(a->Path, b->Path) == 0;
1975 return a->Path == b->Path;
1976 }
1977
1978 case RDPDR_DTYP_SMARTCARD:
1979 break;
1980 case RDPDR_DTYP_FILESYSTEM:
1981 {
1982 const RDPDR_DRIVE* a = (const RDPDR_DRIVE*)what;
1983 const RDPDR_DRIVE* b = (const RDPDR_DRIVE*)expect;
1984 if (a->automount != b->automount)
1985 return FALSE;
1986 if (a->Path && b->Path)
1987 return strcmp(a->Path, b->Path) == 0;
1988 return a->Path == b->Path;
1989 }
1990
1991 default:
1992 return FALSE;
1993 }
1994
1995 return TRUE;
1996}
1997
1998const char* freerdp_rail_support_flags_to_string(UINT32 flags, char* buffer, size_t length)
1999{
2000 const UINT32 mask =
2001 RAIL_LEVEL_SUPPORTED | RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED |
2002 RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED | RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED |
2003 RAIL_LEVEL_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED | RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED |
2004 RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED | RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED;
2005
2006 if (flags & RAIL_LEVEL_SUPPORTED)
2007 winpr_str_append("RAIL_LEVEL_SUPPORTED", buffer, length, "|");
2008 if (flags & RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED)
2009 winpr_str_append("RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED", buffer, length, "|");
2010 if (flags & RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED)
2011 winpr_str_append("RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED", buffer, length, "|");
2012 if (flags & RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED)
2013 winpr_str_append("RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED", buffer, length, "|");
2014 if (flags & RAIL_LEVEL_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED)
2015 winpr_str_append("RAIL_LEVEL_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED", buffer, length, "|");
2016 if (flags & RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED)
2017 winpr_str_append("RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED", buffer, length, "|");
2018 if (flags & RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED)
2019 winpr_str_append("RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED", buffer, length, "|");
2020 if (flags & RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED)
2021 winpr_str_append("RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED", buffer, length, "|");
2022 if (flags & RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED)
2023 winpr_str_append("RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED", buffer, length, "|");
2024 if ((flags & ~mask) != 0)
2025 {
2026 char tbuffer[64] = { 0 };
2027 (void)_snprintf(tbuffer, sizeof(tbuffer), "RAIL_FLAG_UNKNOWN 0x%08" PRIx32, flags & mask);
2028 winpr_str_append(tbuffer, buffer, length, "|");
2029 }
2030 return buffer;
2031}
2032
2033BOOL freerdp_settings_update_from_caps(rdpSettings* settings, const BYTE* capsFlags,
2034 const BYTE** capsData, const UINT32* capsSizes,
2035 UINT32 capsCount, BOOL serverReceivedCaps)
2036{
2037 WINPR_ASSERT(settings);
2038 WINPR_ASSERT(capsFlags || (capsCount == 0));
2039 WINPR_ASSERT(capsData || (capsCount == 0));
2040 WINPR_ASSERT(capsSizes || (capsCount == 0));
2041 WINPR_ASSERT(capsCount <= UINT16_MAX);
2042
2043 wLog* log = WLog_Get(TAG);
2044
2045 for (UINT32 x = 0; x < capsCount; x++)
2046 {
2047 if (capsFlags[x])
2048 {
2049 wStream buffer = { 0 };
2050 wStream* sub = Stream_StaticConstInit(&buffer, capsData[x], capsSizes[x]);
2051
2052 if (!rdp_read_capability_set(log, sub, (UINT16)x, settings, serverReceivedCaps))
2053 return FALSE;
2054 }
2055 }
2056
2057 return TRUE;
2058}
2059
2060const char* freerdp_rdp_version_string(UINT32 version)
2061{
2062 switch (version)
2063 {
2064 case RDP_VERSION_4:
2065 return "RDP_VERSION_4";
2066 case RDP_VERSION_5_PLUS:
2067 return "RDP_VERSION_5_PLUS";
2068 case RDP_VERSION_10_0:
2069 return "RDP_VERSION_10_0";
2070 case RDP_VERSION_10_1:
2071 return "RDP_VERSION_10_1";
2072 case RDP_VERSION_10_2:
2073 return "RDP_VERSION_10_2";
2074 case RDP_VERSION_10_3:
2075 return "RDP_VERSION_10_3";
2076 case RDP_VERSION_10_4:
2077 return "RDP_VERSION_10_4";
2078 case RDP_VERSION_10_5:
2079 return "RDP_VERSION_10_5";
2080 case RDP_VERSION_10_6:
2081 return "RDP_VERSION_10_6";
2082 case RDP_VERSION_10_7:
2083 return "RDP_VERSION_10_7";
2084 case RDP_VERSION_10_8:
2085 return "RDP_VERSION_10_8";
2086 case RDP_VERSION_10_9:
2087 return "RDP_VERSION_10_9";
2088 case RDP_VERSION_10_10:
2089 return "RDP_VERSION_10_10";
2090 case RDP_VERSION_10_11:
2091 return "RDP_VERSION_10_11";
2092 case RDP_VERSION_10_12:
2093 return "RDP_VERSION_10_12";
2094 default:
2095 return "RDP_VERSION_UNKNOWN";
2096 }
2097}
2098
2099BOOL freerdp_settings_set_string_from_utf16(rdpSettings* settings, FreeRDP_Settings_Keys_String id,
2100 const WCHAR* param)
2101{
2102 WINPR_ASSERT(settings);
2103
2104 if (!param)
2105 return freerdp_settings_set_string_copy_(settings, id, NULL, 0, TRUE);
2106
2107 size_t len = 0;
2108
2109 char* str = ConvertWCharToUtf8Alloc(param, &len);
2110 if (!str && (len != 0))
2111 return FALSE;
2112
2113 return freerdp_settings_set_string_(settings, id, str, len);
2114}
2115
2116BOOL freerdp_settings_set_string_from_utf16N(rdpSettings* settings, FreeRDP_Settings_Keys_String id,
2117 const WCHAR* param, size_t length)
2118{
2119 size_t len = 0;
2120
2121 WINPR_ASSERT(settings);
2122
2123 if (!param)
2124 return freerdp_settings_set_string_copy_(settings, id, NULL, length, TRUE);
2125
2126 char* str = ConvertWCharNToUtf8Alloc(param, length, &len);
2127 if (!str && (length != 0))
2128 {
2129 /* If the input string is an empty string, but length > 0
2130 * consider the conversion a success */
2131 const size_t wlen = _wcsnlen(param, length);
2132 if (wlen != 0)
2133 return FALSE;
2134 }
2135
2136 return freerdp_settings_set_string_(settings, id, str, len);
2137}
2138
2139WCHAR* freerdp_settings_get_string_as_utf16(const rdpSettings* settings,
2140 FreeRDP_Settings_Keys_String id, size_t* pCharLen)
2141{
2142 const char* str = freerdp_settings_get_string(settings, id);
2143 if (pCharLen)
2144 *pCharLen = 0;
2145 if (!str)
2146 return NULL;
2147 return ConvertUtf8ToWCharAlloc(str, pCharLen);
2148}
2149
2150const char* freerdp_rdpdr_dtyp_string(UINT32 type)
2151{
2152 switch (type)
2153 {
2154 case RDPDR_DTYP_FILESYSTEM:
2155 return "RDPDR_DTYP_FILESYSTEM";
2156 case RDPDR_DTYP_PARALLEL:
2157 return "RDPDR_DTYP_PARALLEL";
2158 case RDPDR_DTYP_PRINT:
2159 return "RDPDR_DTYP_PRINT";
2160 case RDPDR_DTYP_SERIAL:
2161 return "RDPDR_DTYP_SERIAL";
2162 case RDPDR_DTYP_SMARTCARD:
2163 return "RDPDR_DTYP_SMARTCARD";
2164 default:
2165 return "RDPDR_DTYP_UNKNOWN";
2166 }
2167}
2168
2169const char* freerdp_encryption_level_string(UINT32 EncryptionLevel)
2170{
2171 switch (EncryptionLevel)
2172 {
2173 case ENCRYPTION_LEVEL_NONE:
2174 return "ENCRYPTION_LEVEL_NONE";
2175 case ENCRYPTION_LEVEL_LOW:
2176 return "ENCRYPTION_LEVEL_LOW";
2177 case ENCRYPTION_LEVEL_CLIENT_COMPATIBLE:
2178 return "ENCRYPTION_LEVEL_CLIENT_COMPATIBLE";
2179 case ENCRYPTION_LEVEL_HIGH:
2180 return "ENCRYPTION_LEVEL_HIGH";
2181 case ENCRYPTION_LEVEL_FIPS:
2182 return "ENCRYPTION_LEVEL_FIPS";
2183 default:
2184 return "ENCRYPTION_LEVEL_UNKNOWN";
2185 }
2186}
2187
2188const char* freerdp_encryption_methods_string(UINT32 EncryptionMethods, char* buffer, size_t size)
2189{
2190 if (EncryptionMethods == ENCRYPTION_METHOD_NONE)
2191 {
2192 winpr_str_append("ENCRYPTION_METHOD_NONE", buffer, size, "|");
2193 return buffer;
2194 }
2195
2196 if (EncryptionMethods & ENCRYPTION_METHOD_40BIT)
2197 {
2198 winpr_str_append("ENCRYPTION_METHOD_40BIT", buffer, size, "|");
2199 }
2200 if (EncryptionMethods & ENCRYPTION_METHOD_128BIT)
2201 {
2202 winpr_str_append("ENCRYPTION_METHOD_128BIT", buffer, size, "|");
2203 }
2204 if (EncryptionMethods & ENCRYPTION_METHOD_56BIT)
2205 {
2206 winpr_str_append("ENCRYPTION_METHOD_56BIT", buffer, size, "|");
2207 }
2208 if (EncryptionMethods & ENCRYPTION_METHOD_FIPS)
2209 {
2210 winpr_str_append("ENCRYPTION_METHOD_FIPS", buffer, size, "|");
2211 }
2212
2213 return buffer;
2214}
2215
2216const char* freerdp_supported_color_depths_string(UINT16 mask, char* buffer, size_t size)
2217{
2218 const UINT32 invalid = mask & ~(RNS_UD_32BPP_SUPPORT | RNS_UD_24BPP_SUPPORT |
2219 RNS_UD_16BPP_SUPPORT | RNS_UD_15BPP_SUPPORT);
2220
2221 if (mask & RNS_UD_32BPP_SUPPORT)
2222 winpr_str_append("RNS_UD_32BPP_SUPPORT", buffer, size, "|");
2223 if (mask & RNS_UD_24BPP_SUPPORT)
2224 winpr_str_append("RNS_UD_24BPP_SUPPORT", buffer, size, "|");
2225 if (mask & RNS_UD_16BPP_SUPPORT)
2226 winpr_str_append("RNS_UD_16BPP_SUPPORT", buffer, size, "|");
2227 if (mask & RNS_UD_15BPP_SUPPORT)
2228 winpr_str_append("RNS_UD_15BPP_SUPPORT", buffer, size, "|");
2229
2230 if (invalid != 0)
2231 {
2232 char str[32] = { 0 };
2233 (void)_snprintf(str, sizeof(str), "RNS_UD_INVALID[0x%04" PRIx32 "]", invalid);
2234 winpr_str_append(str, buffer, size, "|");
2235 }
2236 char hex[32] = { 0 };
2237 (void)_snprintf(hex, sizeof(hex), "[0x%04" PRIx16 "]", mask);
2238 return buffer;
2239}
2240
2241BOOL freerdp_settings_append_string(rdpSettings* settings, FreeRDP_Settings_Keys_String id,
2242 const char* separator, const char* param)
2243{
2244 const char* old = freerdp_settings_get_string(settings, id);
2245
2246 size_t len = 0;
2247 char* str = NULL;
2248
2249 if (!old)
2250 winpr_asprintf(&str, &len, "%s", param);
2251 else if (!separator)
2252 winpr_asprintf(&str, &len, "%s%s", old, param);
2253 else
2254 winpr_asprintf(&str, &len, "%s%s%s", old, separator, param);
2255
2256 const BOOL rc = freerdp_settings_set_string_len(settings, id, str, len);
2257 free(str);
2258 return rc;
2259}
2260
2261BOOL freerdp_settings_are_valid(const rdpSettings* settings)
2262{
2263 return settings != NULL;
2264}
2265
2266/* Function to sort rdpMonitor arrays:
2267 * 1. first element is primary monitor
2268 * 2. all others are sorted by coordinates of x/y
2269 */
2270static int sort_monitor_fn(const void* pva, const void* pvb)
2271{
2272 const rdpMonitor* a = pva;
2273 const rdpMonitor* b = pvb;
2274 WINPR_ASSERT(a);
2275 WINPR_ASSERT(b);
2276 if (a->is_primary && b->is_primary)
2277 return 0;
2278 if (a->is_primary)
2279 return -1;
2280 if (b->is_primary)
2281 return 1;
2282
2283 if (a->x != b->x)
2284 return a->x - b->x;
2285 if (a->y != b->y)
2286 return a->y - b->y;
2287 return 0;
2288}
2289
2291 const rdpMonitor* monitors, size_t count)
2292{
2293 WINPR_ASSERT(monitors || (count == 0));
2294 if (count == 0)
2295 {
2296 if (!freerdp_settings_set_int32(settings, FreeRDP_MonitorLocalShiftX, 0))
2297 return FALSE;
2298 if (!freerdp_settings_set_int32(settings, FreeRDP_MonitorLocalShiftY, 0))
2299 return FALSE;
2300 if (!freerdp_settings_set_pointer_len(settings, FreeRDP_MonitorDefArray, NULL, 0))
2301 return FALSE;
2302 return freerdp_settings_set_uint32(settings, FreeRDP_MonitorCount, 0);
2303 return TRUE;
2304 }
2305
2306 // Find primary or alternatively the monitor at 0/0
2307 const rdpMonitor* primary = NULL;
2308 for (size_t x = 0; x < count; x++)
2309 {
2310 const rdpMonitor* cur = &monitors[x];
2311 if (cur->is_primary)
2312 {
2313 primary = cur;
2314 break;
2315 }
2316 }
2317 if (!primary)
2318 {
2319 for (size_t x = 0; x < count; x++)
2320 {
2321 const rdpMonitor* cur = &monitors[x];
2322 if ((cur->x == 0) && (cur->y == 0))
2323 {
2324 primary = cur;
2325 break;
2326 }
2327 }
2328 }
2329
2330 if (!primary)
2331 {
2332 WLog_ERR(TAG, "Could not find primary monitor, aborting");
2333 return FALSE;
2334 }
2335
2336 if (!freerdp_settings_set_pointer_len(settings, FreeRDP_MonitorDefArray, NULL, count))
2337 return FALSE;
2338 rdpMonitor* sorted = freerdp_settings_get_pointer_writable(settings, FreeRDP_MonitorDefArray);
2339 WINPR_ASSERT(sorted);
2340
2341 size_t sortpos = 0;
2342
2343 /* Set primary. Ensure left/top is at 0/0 and flags contains MONITOR_PRIMARY */
2344 sorted[sortpos] = *primary;
2345 sorted[sortpos].x = 0;
2346 sorted[sortpos].y = 0;
2347 sorted[sortpos].is_primary = TRUE;
2348 sortpos++;
2349
2350 /* Set monitor shift to original layout */
2351 const INT32 offsetX = primary->x;
2352 const INT32 offsetY = primary->y;
2353 if (!freerdp_settings_set_int32(settings, FreeRDP_MonitorLocalShiftX, offsetX))
2354 return FALSE;
2355 if (!freerdp_settings_set_int32(settings, FreeRDP_MonitorLocalShiftY, offsetY))
2356 return FALSE;
2357
2358 for (size_t x = 0; x < count; x++)
2359 {
2360 const rdpMonitor* cur = &monitors[x];
2361 if (cur == primary)
2362 continue;
2363
2364 rdpMonitor m = monitors[x];
2365 m.x -= offsetX;
2366 m.y -= offsetY;
2367 sorted[sortpos++] = m;
2368 }
2369
2370 // Sort remaining monitors by x/y ?
2371 qsort(sorted, count, sizeof(rdpMonitor), sort_monitor_fn);
2372
2373 return freerdp_settings_set_uint32(settings, FreeRDP_MonitorCount,
2374 WINPR_ASSERTING_INT_CAST(uint32_t, count));
2375}
FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
const char * freerdp_rail_support_flags_to_string(UINT32 flags, char *buffer, size_t length)
Returns a stringified representation of RAIL support flags.
BOOL freerdp_settings_update_from_caps(rdpSettings *settings, const BYTE *capsFlags, const BYTE **capsData, const UINT32 *capsSizes, UINT32 capsCount, BOOL serverReceivedCaps)
Parse capability data and apply to settings.
FREERDP_API BOOL freerdp_settings_set_string(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *param)
Sets a string settings value. The param is copied.
FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.
const char * freerdp_supported_color_depths_string(UINT16 mask, char *buffer, size_t size)
returns a string representation of RNS_UD_XXBPP_SUPPORT values
BOOL freerdp_settings_set_string_from_utf16N(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const WCHAR *param, size_t length)
Sets a string settings value. The param is converted to UTF-8 and the copy stored.
const char * freerdp_rdp_version_string(UINT32 version)
Returns a stringified representation of the RDP protocol version.
FREERDP_API SSIZE_T freerdp_settings_get_type_for_key(SSIZE_T key)
Get a key type for the key index.
BOOL freerdp_settings_are_valid(const rdpSettings *settings)
Returns TRUE if settings are in a valid state, FALSE otherwise.
FREERDP_API UINT64 freerdp_settings_get_uint64(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt64 id)
Returns a UINT64 settings value.
FREERDP_API SSIZE_T freerdp_settings_get_key_for_name(const char *value)
Get a key index for the name string of that key.
BOOL freerdp_settings_set_pointer_len(rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id, const void *data, size_t len)
Set a pointer to value data.
FREERDP_API BOOL freerdp_settings_set_int32(rdpSettings *settings, FreeRDP_Settings_Keys_Int32 id, INT32 param)
Sets a INT32 settings value.
const char * freerdp_rdpdr_dtyp_string(UINT32 type)
Returns a string representation of RDPDR_DTYP_*.
BOOL freerdp_settings_set_monitor_def_array_sorted(rdpSettings *settings, const rdpMonitor *monitors, size_t count)
Sort monitor array according to:
FREERDP_API void * freerdp_settings_get_pointer_writable(rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id)
Returns a mutable pointer settings value.
WCHAR * freerdp_settings_get_string_as_utf16(const rdpSettings *settings, FreeRDP_Settings_Keys_String id, size_t *pCharLen)
Return an allocated UTF16 string.
BOOL freerdp_device_collection_del(rdpSettings *settings, const RDPDR_DEVICE *device)
Removed a device from the settings, returns ownership of the allocated device to caller.
BOOL freerdp_set_gateway_usage_method(rdpSettings *settings, UINT32 GatewayUsageMethod)
FREERDP_API BOOL freerdp_settings_set_uint64(rdpSettings *settings, FreeRDP_Settings_Keys_UInt64 id, UINT64 param)
Sets a UINT64 settings value.
FREERDP_API BOOL freerdp_settings_set_int16(rdpSettings *settings, FreeRDP_Settings_Keys_Int16 id, INT16 param)
Sets a INT16 settings value.
FREERDP_API BOOL freerdp_settings_set_int64(rdpSettings *settings, FreeRDP_Settings_Keys_Int64 id, INT64 param)
Sets a INT64 settings value.
BOOL freerdp_settings_set_string_from_utf16(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const WCHAR *param)
Sets a string settings value. The param is converted to UTF-8 and the copy stored.
FREERDP_API BOOL freerdp_settings_set_pointer(rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id, const void *data)
Set a pointer to value data.
FREERDP_API INT32 freerdp_settings_get_int32(const rdpSettings *settings, FreeRDP_Settings_Keys_Int32 id)
Returns a INT32 settings value.
const char * freerdp_settings_get_server_name(const rdpSettings *settings)
A helper function to return the correct server name.
const void * freerdp_settings_get_pointer(const rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id)
Returns a immutable pointer settings value.
UINT32 freerdp_settings_get_codecs_flags(const rdpSettings *settings)
helper function to get a mask of supported codec flags.
FREERDP_API BOOL freerdp_settings_set_string_len(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *param, size_t len)
Sets a string settings value. The param is copied.
FREERDP_API BOOL freerdp_settings_set_uint32(rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 param)
Sets a UINT32 settings value.
BOOL freerdp_settings_append_string(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *separator, const char *param)
appends a string to a settings value. The param is copied. If the initial value of the setting was no...
FREERDP_API const char * freerdp_settings_get_name_for_key(SSIZE_T key)
Returns the type name for a key.
FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.
FREERDP_API BOOL freerdp_settings_set_uint16(rdpSettings *settings, FreeRDP_Settings_Keys_UInt16 id, UINT16 param)
Sets a UINT16 settings value.
FREERDP_API BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL param)
Sets a BOOL settings value.