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