Coverage Report

Created: 2023-09-25 06:56

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