Coverage Report

Created: 2024-05-20 06:11

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