Coverage Report

Created: 2024-05-20 06:11

/src/FreeRDP/client/common/file.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * FreeRDP: A Remote Desktop Protocol Implementation
3
 * .rdp file
4
 *
5
 * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6
 *
7
 * Licensed under the Apache License, Version 2.0 (the "License");
8
 * you may not use this file except in compliance with the License.
9
 * You may obtain a copy of the License at
10
 *
11
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing, software
14
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 * See the License for the specific language governing permissions and
17
 * limitations under the License.
18
 */
19
20
#include <freerdp/config.h>
21
22
#include <errno.h>
23
#include <ctype.h>
24
#include <stdlib.h>
25
26
#include <winpr/string.h>
27
#include <winpr/file.h>
28
29
#include <freerdp/client.h>
30
#include <freerdp/client/file.h>
31
#include <freerdp/client/cmdline.h>
32
33
#include <freerdp/channels/urbdrc.h>
34
#include <freerdp/channels/rdpecam.h>
35
#include <freerdp/channels/location.h>
36
37
/**
38
 * Remote Desktop Plus - Overview of .rdp file settings:
39
 * http://www.donkz.nl/files/rdpsettings.html
40
 *
41
 * RDP Settings for Remote Desktop Services in Windows Server 2008 R2:
42
 * http://technet.microsoft.com/en-us/library/ff393699/
43
 *
44
 * https://docs.microsoft.com/en-us/windows-server/remote/remote-desktop-services/clients/rdp-files
45
 */
46
47
#include <stdio.h>
48
#include <string.h>
49
50
#include <winpr/wtypes.h>
51
#include <winpr/crt.h>
52
#include <winpr/path.h>
53
#include <freerdp/log.h>
54
#define TAG CLIENT_TAG("common")
55
56
/*#define DEBUG_CLIENT_FILE 1*/
57
58
static const BYTE BOM_UTF16_LE[2] = { 0xFF, 0xFE };
59
60
#define INVALID_INTEGER_VALUE 0xFFFFFFFF
61
62
0
#define RDP_FILE_LINE_FLAG_FORMATTED 0x00000001
63
#define RDP_FILE_LINE_FLAG_STANDARD 0x00000002
64
0
#define RDP_FILE_LINE_FLAG_TYPE_STRING 0x00000010
65
0
#define RDP_FILE_LINE_FLAG_TYPE_INTEGER 0x00000020
66
#define RDP_FILE_LINE_FLAG_TYPE_BINARY 0x00000040
67
68
struct rdp_file_line
69
{
70
  char* name;
71
  LPSTR sValue;
72
  PBYTE bValue;
73
74
  size_t index;
75
76
  long iValue;
77
  DWORD flags;
78
  int valueLength;
79
};
80
typedef struct rdp_file_line rdpFileLine;
81
82
struct rdp_file
83
{
84
  DWORD UseMultiMon;                 /* use multimon */
85
  LPSTR SelectedMonitors;            /* selectedmonitors */
86
  DWORD MaximizeToCurrentDisplays;   /* maximizetocurrentdisplays */
87
  DWORD SingleMonInWindowedMode;     /* singlemoninwindowedmode */
88
  DWORD ScreenModeId;                /* screen mode id */
89
  DWORD SpanMonitors;                /* span monitors */
90
  DWORD SmartSizing;                 /* smartsizing */
91
  DWORD DynamicResolution;           /* dynamic resolution */
92
  DWORD EnableSuperSpan;             /* enablesuperpan */
93
  DWORD SuperSpanAccelerationFactor; /* superpanaccelerationfactor */
94
95
  DWORD DesktopWidth;       /* desktopwidth */
96
  DWORD DesktopHeight;      /* desktopheight */
97
  DWORD DesktopSizeId;      /* desktop size id */
98
  DWORD SessionBpp;         /* session bpp */
99
  DWORD DesktopScaleFactor; /* desktopscalefactor */
100
101
  DWORD Compression;       /* compression */
102
  DWORD KeyboardHook;      /* keyboardhook */
103
  DWORD DisableCtrlAltDel; /* disable ctrl+alt+del */
104
105
  DWORD AudioMode;                             /* audiomode */
106
  DWORD AudioQualityMode;                      /* audioqualitymode */
107
  DWORD AudioCaptureMode;                      /* audiocapturemode */
108
  DWORD EncodeRedirectedVideoCapture;          /* encode redirected video capture */
109
  DWORD RedirectedVideoCaptureEncodingQuality; /* redirected video capture encoding quality */
110
  DWORD VideoPlaybackMode;                     /* videoplaybackmode */
111
112
  DWORD ConnectionType; /* connection type */
113
114
  DWORD NetworkAutoDetect;   /* networkautodetect */
115
  DWORD BandwidthAutoDetect; /* bandwidthautodetect */
116
117
  DWORD PinConnectionBar;     /* pinconnectionbar */
118
  DWORD DisplayConnectionBar; /* displayconnectionbar */
119
120
  DWORD WorkspaceId;              /* workspaceid */
121
  DWORD EnableWorkspaceReconnect; /* enableworkspacereconnect */
122
123
  DWORD DisableWallpaper;        /* disable wallpaper */
124
  DWORD AllowFontSmoothing;      /* allow font smoothing */
125
  DWORD AllowDesktopComposition; /* allow desktop composition */
126
  DWORD DisableFullWindowDrag;   /* disable full window drag */
127
  DWORD DisableMenuAnims;        /* disable menu anims */
128
  DWORD DisableThemes;           /* disable themes */
129
  DWORD DisableCursorSetting;    /* disable cursor setting */
130
131
  DWORD BitmapCacheSize;          /* bitmapcachesize */
132
  DWORD BitmapCachePersistEnable; /* bitmapcachepersistenable */
133
134
  DWORD ServerPort; /* server port */
135
136
  LPSTR Username;   /* username */
137
  LPSTR Domain;     /* domain */
138
  LPSTR Password;   /*password*/
139
  PBYTE Password51; /* password 51 */
140
141
  LPSTR FullAddress;          /* full address */
142
  LPSTR AlternateFullAddress; /* alternate full address */
143
144
  LPSTR UsbDevicesToRedirect;        /* usbdevicestoredirect */
145
  DWORD RedirectDrives;              /* redirectdrives */
146
  DWORD RedirectPrinters;            /* redirectprinters */
147
  DWORD RedirectComPorts;            /* redirectcomports */
148
  DWORD RedirectLocation;            /* redirectlocation */
149
  DWORD RedirectSmartCards;          /* redirectsmartcards */
150
  DWORD RedirectWebauthN;            /* redirectwebauthn */
151
  LPSTR RedirectCameras;             /* camerastoredirect */
152
  DWORD RedirectClipboard;           /* redirectclipboard */
153
  DWORD RedirectPosDevices;          /* redirectposdevices */
154
  DWORD RedirectDirectX;             /* redirectdirectx */
155
  DWORD DisablePrinterRedirection;   /* disableprinterredirection */
156
  DWORD DisableClipboardRedirection; /* disableclipboardredirection */
157
158
  DWORD ConnectToConsole;        /* connect to console */
159
  DWORD AdministrativeSession;   /* administrative session */
160
  DWORD AutoReconnectionEnabled; /* autoreconnection enabled */
161
  DWORD AutoReconnectMaxRetries; /* autoreconnect max retries */
162
163
  DWORD PublicMode;             /* public mode */
164
  DWORD AuthenticationLevel;    /* authentication level */
165
  DWORD PromptCredentialOnce;   /* promptcredentialonce */
166
  DWORD PromptForCredentials;   /* prompt for credentials */
167
  DWORD NegotiateSecurityLayer; /* negotiate security layer */
168
  DWORD EnableCredSSPSupport;   /* enablecredsspsupport */
169
  DWORD EnableRdsAadAuth;       /* enablerdsaadauth */
170
171
  DWORD RemoteApplicationMode; /* remoteapplicationmode */
172
  LPSTR LoadBalanceInfo;       /* loadbalanceinfo */
173
174
  LPSTR RemoteApplicationName;             /* remoteapplicationname */
175
  LPSTR RemoteApplicationIcon;             /* remoteapplicationicon */
176
  LPSTR RemoteApplicationProgram;          /* remoteapplicationprogram */
177
  LPSTR RemoteApplicationFile;             /* remoteapplicationfile */
178
  LPSTR RemoteApplicationGuid;             /* remoteapplicationguid */
179
  LPSTR RemoteApplicationCmdLine;          /* remoteapplicationcmdline */
180
  DWORD RemoteApplicationExpandCmdLine;    /* remoteapplicationexpandcmdline */
181
  DWORD RemoteApplicationExpandWorkingDir; /* remoteapplicationexpandworkingdir */
182
  DWORD DisableConnectionSharing;          /* disableconnectionsharing */
183
  DWORD DisableRemoteAppCapsCheck;         /* disableremoteappcapscheck */
184
185
  LPSTR AlternateShell;        /* alternate shell */
186
  LPSTR ShellWorkingDirectory; /* shell working directory */
187
188
  LPSTR GatewayHostname;           /* gatewayhostname */
189
  DWORD GatewayUsageMethod;        /* gatewayusagemethod */
190
  DWORD GatewayProfileUsageMethod; /* gatewayprofileusagemethod */
191
  DWORD GatewayCredentialsSource;  /* gatewaycredentialssource */
192
193
  LPSTR ResourceProvider; /* resourceprovider */
194
195
  LPSTR WvdEndpointPool;      /* wvd endpoint pool */
196
  LPSTR geo;                  /* geo */
197
  LPSTR armpath;              /* armpath */
198
  LPSTR aadtenantid;          /* aadtenantid" */
199
  LPSTR diagnosticserviceurl; /* diagnosticserviceurl */
200
  LPSTR hubdiscoverygeourl;   /* hubdiscoverygeourl" */
201
  LPSTR activityhint;         /* activityhint */
202
203
  DWORD UseRedirectionServerName; /* use redirection server name */
204
205
  LPSTR GatewayAccessToken; /* gatewayaccesstoken */
206
207
  LPSTR DrivesToRedirect;  /* drivestoredirect */
208
  LPSTR DevicesToRedirect; /* devicestoredirect */
209
  LPSTR WinPosStr;         /* winposstr */
210
211
  LPSTR PreconnectionBlob; /* pcb */
212
213
  LPSTR KdcProxyName;  /* kdcproxyname */
214
  DWORD RdgIsKdcProxy; /* rdgiskdcproxy */
215
216
  DWORD align1;
217
218
  size_t lineCount;
219
  size_t lineSize;
220
  rdpFileLine* lines;
221
222
  ADDIN_ARGV* args;
223
  void* context;
224
225
  DWORD flags;
226
};
227
228
static const char key_str_username[] = "username";
229
static const char key_str_domain[] = "domain";
230
static const char key_str_password[] = "password";
231
static const char key_str_full_address[] = "full address";
232
static const char key_str_alternate_full_address[] = "alternate full address";
233
static const char key_str_usbdevicestoredirect[] = "usbdevicestoredirect";
234
static const char key_str_camerastoredirect[] = "camerastoredirect";
235
static const char key_str_loadbalanceinfo[] = "loadbalanceinfo";
236
static const char key_str_remoteapplicationname[] = "remoteapplicationname";
237
static const char key_str_remoteapplicationicon[] = "remoteapplicationicon";
238
static const char key_str_remoteapplicationprogram[] = "remoteapplicationprogram";
239
static const char key_str_remoteapplicationfile[] = "remoteapplicationfile";
240
static const char key_str_remoteapplicationguid[] = "remoteapplicationguid";
241
static const char key_str_remoteapplicationcmdline[] = "remoteapplicationcmdline";
242
static const char key_str_alternate_shell[] = "alternate shell";
243
static const char key_str_shell_working_directory[] = "shell working directory";
244
static const char key_str_gatewayhostname[] = "gatewayhostname";
245
static const char key_str_gatewayaccesstoken[] = "gatewayaccesstoken";
246
static const char key_str_resourceprovider[] = "resourceprovider";
247
static const char str_resourceprovider_arm[] = "arm";
248
static const char key_str_kdcproxyname[] = "kdcproxyname";
249
static const char key_str_drivestoredirect[] = "drivestoredirect";
250
static const char key_str_devicestoredirect[] = "devicestoredirect";
251
static const char key_str_winposstr[] = "winposstr";
252
static const char key_str_pcb[] = "pcb";
253
static const char key_str_selectedmonitors[] = "selectedmonitors";
254
255
static const char key_str_wvd[] = "wvd endpoint pool";
256
static const char key_str_geo[] = "geo";
257
static const char key_str_armpath[] = "armpath";
258
static const char key_str_aadtenantid[] = "aadtenantid";
259
260
static const char key_str_diagnosticserviceurl[] = "diagnosticserviceurl";
261
static const char key_str_hubdiscoverygeourl[] = "hubdiscoverygeourl";
262
263
static const char key_str_activityhint[] = "activityhint";
264
265
static const char key_int_rdgiskdcproxy[] = "rdgiskdcproxy";
266
static const char key_int_use_redirection_server_name[] = "use redirection server name";
267
static const char key_int_gatewaycredentialssource[] = "gatewaycredentialssource";
268
static const char key_int_gatewayprofileusagemethod[] = "gatewayprofileusagemethod";
269
static const char key_int_gatewayusagemethod[] = "gatewayusagemethod";
270
static const char key_int_disableremoteappcapscheck[] = "disableremoteappcapscheck";
271
static const char key_int_disableconnectionsharing[] = "disableconnectionsharing";
272
static const char key_int_remoteapplicationexpandworkingdir[] = "remoteapplicationexpandworkingdir";
273
static const char key_int_remoteapplicationexpandcmdline[] = "remoteapplicationexpandcmdline";
274
static const char key_int_remoteapplicationmode[] = "remoteapplicationmode";
275
static const char key_int_enablecredsspsupport[] = "enablecredsspsupport";
276
static const char key_int_enablerdsaadauth[] = "enablerdsaadauth";
277
static const char key_int_negotiate_security_layer[] = "negotiate security layer";
278
static const char key_int_prompt_for_credentials[] = "prompt for credentials";
279
static const char key_int_promptcredentialonce[] = "promptcredentialonce";
280
static const char key_int_authentication_level[] = "authentication level";
281
static const char key_int_public_mode[] = "public mode";
282
static const char key_int_autoreconnect_max_retries[] = "autoreconnect max retries";
283
static const char key_int_autoreconnection_enabled[] = "autoreconnection enabled";
284
static const char key_int_administrative_session[] = "administrative session";
285
static const char key_int_connect_to_console[] = "connect to console";
286
static const char key_int_disableclipboardredirection[] = "disableclipboardredirection";
287
static const char key_int_disableprinterredirection[] = "disableprinterredirection";
288
static const char key_int_redirectdirectx[] = "redirectdirectx";
289
static const char key_int_redirectposdevices[] = "redirectposdevices";
290
static const char key_int_redirectclipboard[] = "redirectclipboard";
291
static const char key_int_redirectsmartcards[] = "redirectsmartcards";
292
static const char key_int_redirectcomports[] = "redirectcomports";
293
static const char key_int_redirectlocation[] = "redirectlocation";
294
static const char key_int_redirectprinters[] = "redirectprinters";
295
static const char key_int_redirectdrives[] = "redirectdrives";
296
static const char key_int_server_port[] = "server port";
297
static const char key_int_bitmapcachepersistenable[] = "bitmapcachepersistenable";
298
static const char key_int_bitmapcachesize[] = "bitmapcachesize";
299
static const char key_int_disable_cursor_setting[] = "disable cursor setting";
300
static const char key_int_disable_themes[] = "disable themes";
301
static const char key_int_disable_menu_anims[] = "disable menu anims";
302
static const char key_int_disable_full_window_drag[] = "disable full window drag";
303
static const char key_int_allow_desktop_composition[] = "allow desktop composition";
304
static const char key_int_allow_font_smoothing[] = "allow font smoothing";
305
static const char key_int_disable_wallpaper[] = "disable wallpaper";
306
static const char key_int_enableworkspacereconnect[] = "enableworkspacereconnect";
307
static const char key_int_workspaceid[] = "workspaceid";
308
static const char key_int_displayconnectionbar[] = "displayconnectionbar";
309
static const char key_int_pinconnectionbar[] = "pinconnectionbar";
310
static const char key_int_bandwidthautodetect[] = "bandwidthautodetect";
311
static const char key_int_networkautodetect[] = "networkautodetect";
312
static const char key_int_connection_type[] = "connection type";
313
static const char key_int_videoplaybackmode[] = "videoplaybackmode";
314
static const char key_int_redirected_video_capture_encoding_quality[] =
315
    "redirected video capture encoding quality";
316
static const char key_int_encode_redirected_video_capture[] = "encode redirected video capture";
317
static const char key_int_audiocapturemode[] = "audiocapturemode";
318
static const char key_int_audioqualitymode[] = "audioqualitymode";
319
static const char key_int_audiomode[] = "audiomode";
320
static const char key_int_disable_ctrl_alt_del[] = "disable ctrl+alt+del";
321
static const char key_int_keyboardhook[] = "keyboardhook";
322
static const char key_int_compression[] = "compression";
323
static const char key_int_desktopscalefactor[] = "desktopscalefactor";
324
static const char key_int_session_bpp[] = "session bpp";
325
static const char key_int_desktop_size_id[] = "desktop size id";
326
static const char key_int_desktopheight[] = "desktopheight";
327
static const char key_int_desktopwidth[] = "desktopwidth";
328
static const char key_int_superpanaccelerationfactor[] = "superpanaccelerationfactor";
329
static const char key_int_enablesuperpan[] = "enablesuperpan";
330
static const char key_int_dynamic_resolution[] = "dynamic resolution";
331
static const char key_int_smart_sizing[] = "smart sizing";
332
static const char key_int_span_monitors[] = "span monitors";
333
static const char key_int_screen_mode_id[] = "screen mode id";
334
static const char key_int_singlemoninwindowedmode[] = "singlemoninwindowedmode";
335
static const char key_int_maximizetocurrentdisplays[] = "maximizetocurrentdisplays";
336
static const char key_int_use_multimon[] = "use multimon";
337
static const char key_int_redirectwebauthn[] = "redirectwebauthn";
338
339
static SSIZE_T freerdp_client_rdp_file_add_line(rdpFile* file);
340
static rdpFileLine* freerdp_client_rdp_file_find_line_by_name(const rdpFile* file,
341
                                                              const char* name);
342
static void freerdp_client_file_string_check_free(LPSTR str);
343
344
static BOOL freerdp_client_rdp_file_find_integer_entry(rdpFile* file, const char* name,
345
                                                       DWORD** outValue, rdpFileLine** outLine)
346
0
{
347
0
  WINPR_ASSERT(file);
348
0
  WINPR_ASSERT(name);
349
0
  WINPR_ASSERT(outValue);
350
0
  WINPR_ASSERT(outLine);
351
352
0
  *outValue = NULL;
353
0
  *outLine = NULL;
354
355
0
  if (_stricmp(name, key_int_use_multimon) == 0)
356
0
    *outValue = &file->UseMultiMon;
357
0
  else if (_stricmp(name, key_int_maximizetocurrentdisplays) == 0)
358
0
    *outValue = &file->MaximizeToCurrentDisplays;
359
0
  else if (_stricmp(name, key_int_singlemoninwindowedmode) == 0)
360
0
    *outValue = &file->SingleMonInWindowedMode;
361
0
  else if (_stricmp(name, key_int_screen_mode_id) == 0)
362
0
    *outValue = &file->ScreenModeId;
363
0
  else if (_stricmp(name, key_int_span_monitors) == 0)
364
0
    *outValue = &file->SpanMonitors;
365
0
  else if (_stricmp(name, key_int_smart_sizing) == 0)
366
0
    *outValue = &file->SmartSizing;
367
0
  else if (_stricmp(name, key_int_dynamic_resolution) == 0)
368
0
    *outValue = &file->DynamicResolution;
369
0
  else if (_stricmp(name, key_int_enablesuperpan) == 0)
370
0
    *outValue = &file->EnableSuperSpan;
371
0
  else if (_stricmp(name, key_int_superpanaccelerationfactor) == 0)
372
0
    *outValue = &file->SuperSpanAccelerationFactor;
373
0
  else if (_stricmp(name, key_int_desktopwidth) == 0)
374
0
    *outValue = &file->DesktopWidth;
375
0
  else if (_stricmp(name, key_int_desktopheight) == 0)
376
0
    *outValue = &file->DesktopHeight;
377
0
  else if (_stricmp(name, key_int_desktop_size_id) == 0)
378
0
    *outValue = &file->DesktopSizeId;
379
0
  else if (_stricmp(name, key_int_session_bpp) == 0)
380
0
    *outValue = &file->SessionBpp;
381
0
  else if (_stricmp(name, key_int_desktopscalefactor) == 0)
382
0
    *outValue = &file->DesktopScaleFactor;
383
0
  else if (_stricmp(name, key_int_compression) == 0)
384
0
    *outValue = &file->Compression;
385
0
  else if (_stricmp(name, key_int_keyboardhook) == 0)
386
0
    *outValue = &file->KeyboardHook;
387
0
  else if (_stricmp(name, key_int_disable_ctrl_alt_del) == 0)
388
0
    *outValue = &file->DisableCtrlAltDel;
389
0
  else if (_stricmp(name, key_int_audiomode) == 0)
390
0
    *outValue = &file->AudioMode;
391
0
  else if (_stricmp(name, key_int_audioqualitymode) == 0)
392
0
    *outValue = &file->AudioQualityMode;
393
0
  else if (_stricmp(name, key_int_audiocapturemode) == 0)
394
0
    *outValue = &file->AudioCaptureMode;
395
0
  else if (_stricmp(name, key_int_encode_redirected_video_capture) == 0)
396
0
    *outValue = &file->EncodeRedirectedVideoCapture;
397
0
  else if (_stricmp(name, key_int_redirected_video_capture_encoding_quality) == 0)
398
0
    *outValue = &file->RedirectedVideoCaptureEncodingQuality;
399
0
  else if (_stricmp(name, key_int_videoplaybackmode) == 0)
400
0
    *outValue = &file->VideoPlaybackMode;
401
0
  else if (_stricmp(name, key_int_connection_type) == 0)
402
0
    *outValue = &file->ConnectionType;
403
0
  else if (_stricmp(name, key_int_networkautodetect) == 0)
404
0
    *outValue = &file->NetworkAutoDetect;
405
0
  else if (_stricmp(name, key_int_bandwidthautodetect) == 0)
406
0
    *outValue = &file->BandwidthAutoDetect;
407
0
  else if (_stricmp(name, key_int_pinconnectionbar) == 0)
408
0
    *outValue = &file->PinConnectionBar;
409
0
  else if (_stricmp(name, key_int_displayconnectionbar) == 0)
410
0
    *outValue = &file->DisplayConnectionBar;
411
0
  else if (_stricmp(name, key_int_workspaceid) == 0)
412
0
    *outValue = &file->WorkspaceId;
413
0
  else if (_stricmp(name, key_int_enableworkspacereconnect) == 0)
414
0
    *outValue = &file->EnableWorkspaceReconnect;
415
0
  else if (_stricmp(name, key_int_disable_wallpaper) == 0)
416
0
    *outValue = &file->DisableWallpaper;
417
0
  else if (_stricmp(name, key_int_allow_font_smoothing) == 0)
418
0
    *outValue = &file->AllowFontSmoothing;
419
0
  else if (_stricmp(name, key_int_allow_desktop_composition) == 0)
420
0
    *outValue = &file->AllowDesktopComposition;
421
0
  else if (_stricmp(name, key_int_disable_full_window_drag) == 0)
422
0
    *outValue = &file->DisableFullWindowDrag;
423
0
  else if (_stricmp(name, key_int_disable_menu_anims) == 0)
424
0
    *outValue = &file->DisableMenuAnims;
425
0
  else if (_stricmp(name, key_int_disable_themes) == 0)
426
0
    *outValue = &file->DisableThemes;
427
0
  else if (_stricmp(name, key_int_disable_cursor_setting) == 0)
428
0
    *outValue = &file->DisableCursorSetting;
429
0
  else if (_stricmp(name, key_int_bitmapcachesize) == 0)
430
0
    *outValue = &file->BitmapCacheSize;
431
0
  else if (_stricmp(name, key_int_bitmapcachepersistenable) == 0)
432
0
    *outValue = &file->BitmapCachePersistEnable;
433
0
  else if (_stricmp(name, key_int_server_port) == 0)
434
0
    *outValue = &file->ServerPort;
435
0
  else if (_stricmp(name, key_int_redirectdrives) == 0)
436
0
    *outValue = &file->RedirectDrives;
437
0
  else if (_stricmp(name, key_int_redirectprinters) == 0)
438
0
    *outValue = &file->RedirectPrinters;
439
0
  else if (_stricmp(name, key_int_redirectcomports) == 0)
440
0
    *outValue = &file->RedirectComPorts;
441
0
  else if (_stricmp(name, key_int_redirectlocation) == 0)
442
0
    *outValue = &file->RedirectLocation;
443
0
  else if (_stricmp(name, key_int_redirectsmartcards) == 0)
444
0
    *outValue = &file->RedirectSmartCards;
445
0
  else if (_stricmp(name, key_int_redirectclipboard) == 0)
446
0
    *outValue = &file->RedirectClipboard;
447
0
  else if (_stricmp(name, key_int_redirectposdevices) == 0)
448
0
    *outValue = &file->RedirectPosDevices;
449
0
  else if (_stricmp(name, key_int_redirectdirectx) == 0)
450
0
    *outValue = &file->RedirectDirectX;
451
0
  else if (_stricmp(name, key_int_disableprinterredirection) == 0)
452
0
    *outValue = &file->DisablePrinterRedirection;
453
0
  else if (_stricmp(name, key_int_disableclipboardredirection) == 0)
454
0
    *outValue = &file->DisableClipboardRedirection;
455
0
  else if (_stricmp(name, key_int_connect_to_console) == 0)
456
0
    *outValue = &file->ConnectToConsole;
457
0
  else if (_stricmp(name, key_int_administrative_session) == 0)
458
0
    *outValue = &file->AdministrativeSession;
459
0
  else if (_stricmp(name, key_int_autoreconnection_enabled) == 0)
460
0
    *outValue = &file->AutoReconnectionEnabled;
461
0
  else if (_stricmp(name, key_int_autoreconnect_max_retries) == 0)
462
0
    *outValue = &file->AutoReconnectMaxRetries;
463
0
  else if (_stricmp(name, key_int_public_mode) == 0)
464
0
    *outValue = &file->PublicMode;
465
0
  else if (_stricmp(name, key_int_authentication_level) == 0)
466
0
    *outValue = &file->AuthenticationLevel;
467
0
  else if (_stricmp(name, key_int_promptcredentialonce) == 0)
468
0
    *outValue = &file->PromptCredentialOnce;
469
0
  else if ((_stricmp(name, key_int_prompt_for_credentials) == 0))
470
0
    *outValue = &file->PromptForCredentials;
471
0
  else if (_stricmp(name, key_int_negotiate_security_layer) == 0)
472
0
    *outValue = &file->NegotiateSecurityLayer;
473
0
  else if (_stricmp(name, key_int_enablecredsspsupport) == 0)
474
0
    *outValue = &file->EnableCredSSPSupport;
475
0
  else if (_stricmp(name, key_int_enablerdsaadauth) == 0)
476
0
    *outValue = &file->EnableRdsAadAuth;
477
0
  else if (_stricmp(name, key_int_remoteapplicationmode) == 0)
478
0
    *outValue = &file->RemoteApplicationMode;
479
0
  else if (_stricmp(name, key_int_remoteapplicationexpandcmdline) == 0)
480
0
    *outValue = &file->RemoteApplicationExpandCmdLine;
481
0
  else if (_stricmp(name, key_int_remoteapplicationexpandworkingdir) == 0)
482
0
    *outValue = &file->RemoteApplicationExpandWorkingDir;
483
0
  else if (_stricmp(name, key_int_disableconnectionsharing) == 0)
484
0
    *outValue = &file->DisableConnectionSharing;
485
0
  else if (_stricmp(name, key_int_disableremoteappcapscheck) == 0)
486
0
    *outValue = &file->DisableRemoteAppCapsCheck;
487
0
  else if (_stricmp(name, key_int_gatewayusagemethod) == 0)
488
0
    *outValue = &file->GatewayUsageMethod;
489
0
  else if (_stricmp(name, key_int_gatewayprofileusagemethod) == 0)
490
0
    *outValue = &file->GatewayProfileUsageMethod;
491
0
  else if (_stricmp(name, key_int_gatewaycredentialssource) == 0)
492
0
    *outValue = &file->GatewayCredentialsSource;
493
0
  else if (_stricmp(name, key_int_use_redirection_server_name) == 0)
494
0
    *outValue = &file->UseRedirectionServerName;
495
0
  else if (_stricmp(name, key_int_rdgiskdcproxy) == 0)
496
0
    *outValue = &file->RdgIsKdcProxy;
497
0
  else if (_stricmp(name, key_int_redirectwebauthn) == 0)
498
0
    *outValue = &file->RedirectWebauthN;
499
0
  else
500
0
  {
501
0
    rdpFileLine* line = freerdp_client_rdp_file_find_line_by_name(file, name);
502
0
    if (!line)
503
0
      return FALSE;
504
0
    if (!(line->flags & RDP_FILE_LINE_FLAG_TYPE_INTEGER))
505
0
      return FALSE;
506
507
0
    *outLine = line;
508
0
  }
509
510
0
  return TRUE;
511
0
}
512
513
static BOOL freerdp_client_rdp_file_find_string_entry(rdpFile* file, const char* name,
514
                                                      LPSTR** outValue, rdpFileLine** outLine)
515
0
{
516
0
  WINPR_ASSERT(file);
517
0
  WINPR_ASSERT(name);
518
0
  WINPR_ASSERT(outValue);
519
0
  WINPR_ASSERT(outLine);
520
521
0
  *outValue = NULL;
522
0
  *outLine = NULL;
523
524
0
  if (_stricmp(name, key_str_username) == 0)
525
0
    *outValue = &file->Username;
526
0
  else if (_stricmp(name, key_str_domain) == 0)
527
0
    *outValue = &file->Domain;
528
0
  else if (_stricmp(name, key_str_password) == 0)
529
0
    *outValue = &file->Password;
530
0
  else if (_stricmp(name, key_str_full_address) == 0)
531
0
    *outValue = &file->FullAddress;
532
0
  else if (_stricmp(name, key_str_alternate_full_address) == 0)
533
0
    *outValue = &file->AlternateFullAddress;
534
0
  else if (_stricmp(name, key_str_usbdevicestoredirect) == 0)
535
0
    *outValue = &file->UsbDevicesToRedirect;
536
0
  else if (_stricmp(name, key_str_camerastoredirect) == 0)
537
0
    *outValue = &file->RedirectCameras;
538
0
  else if (_stricmp(name, key_str_loadbalanceinfo) == 0)
539
0
    *outValue = &file->LoadBalanceInfo;
540
0
  else if (_stricmp(name, key_str_remoteapplicationname) == 0)
541
0
    *outValue = &file->RemoteApplicationName;
542
0
  else if (_stricmp(name, key_str_remoteapplicationicon) == 0)
543
0
    *outValue = &file->RemoteApplicationIcon;
544
0
  else if (_stricmp(name, key_str_remoteapplicationprogram) == 0)
545
0
    *outValue = &file->RemoteApplicationProgram;
546
0
  else if (_stricmp(name, key_str_remoteapplicationfile) == 0)
547
0
    *outValue = &file->RemoteApplicationFile;
548
0
  else if (_stricmp(name, key_str_remoteapplicationguid) == 0)
549
0
    *outValue = &file->RemoteApplicationGuid;
550
0
  else if (_stricmp(name, key_str_remoteapplicationcmdline) == 0)
551
0
    *outValue = &file->RemoteApplicationCmdLine;
552
0
  else if (_stricmp(name, key_str_alternate_shell) == 0)
553
0
    *outValue = &file->AlternateShell;
554
0
  else if (_stricmp(name, key_str_shell_working_directory) == 0)
555
0
    *outValue = &file->ShellWorkingDirectory;
556
0
  else if (_stricmp(name, key_str_gatewayhostname) == 0)
557
0
    *outValue = &file->GatewayHostname;
558
0
  else if (_stricmp(name, key_str_resourceprovider) == 0)
559
0
    *outValue = &file->ResourceProvider;
560
0
  else if (_stricmp(name, key_str_wvd) == 0)
561
0
    *outValue = &file->WvdEndpointPool;
562
0
  else if (_stricmp(name, key_str_geo) == 0)
563
0
    *outValue = &file->geo;
564
0
  else if (_stricmp(name, key_str_armpath) == 0)
565
0
    *outValue = &file->armpath;
566
0
  else if (_stricmp(name, key_str_aadtenantid) == 0)
567
0
    *outValue = &file->aadtenantid;
568
0
  else if (_stricmp(name, key_str_diagnosticserviceurl) == 0)
569
0
    *outValue = &file->diagnosticserviceurl;
570
0
  else if (_stricmp(name, key_str_hubdiscoverygeourl) == 0)
571
0
    *outValue = &file->hubdiscoverygeourl;
572
0
  else if (_stricmp(name, key_str_activityhint) == 0)
573
0
    *outValue = &file->activityhint;
574
0
  else if (_stricmp(name, key_str_gatewayaccesstoken) == 0)
575
0
    *outValue = &file->GatewayAccessToken;
576
0
  else if (_stricmp(name, key_str_kdcproxyname) == 0)
577
0
    *outValue = &file->KdcProxyName;
578
0
  else if (_stricmp(name, key_str_drivestoredirect) == 0)
579
0
    *outValue = &file->DrivesToRedirect;
580
0
  else if (_stricmp(name, key_str_devicestoredirect) == 0)
581
0
    *outValue = &file->DevicesToRedirect;
582
0
  else if (_stricmp(name, key_str_winposstr) == 0)
583
0
    *outValue = &file->WinPosStr;
584
0
  else if (_stricmp(name, key_str_pcb) == 0)
585
0
    *outValue = &file->PreconnectionBlob;
586
0
  else if (_stricmp(name, key_str_selectedmonitors) == 0)
587
0
    *outValue = &file->SelectedMonitors;
588
0
  else
589
0
  {
590
0
    rdpFileLine* line = freerdp_client_rdp_file_find_line_by_name(file, name);
591
0
    if (!line)
592
0
      return FALSE;
593
0
    if (!(line->flags & RDP_FILE_LINE_FLAG_TYPE_STRING))
594
0
      return FALSE;
595
596
0
    *outLine = line;
597
0
  }
598
599
0
  return TRUE;
600
0
}
601
602
/*
603
 * Set an integer in a rdpFile
604
 *
605
 * @return FALSE if a standard name was set, TRUE for a non-standard name, FALSE on error
606
 *
607
 */
608
static BOOL freerdp_client_rdp_file_set_integer(rdpFile* file, const char* name, long value)
609
0
{
610
0
  DWORD* targetValue = NULL;
611
0
  rdpFileLine* line = NULL;
612
#ifdef DEBUG_CLIENT_FILE
613
  WLog_DBG(TAG, "%s:i:%ld", name, value);
614
#endif
615
616
0
  if (value < 0)
617
0
    return FALSE;
618
619
0
  if (!freerdp_client_rdp_file_find_integer_entry(file, name, &targetValue, &line))
620
0
  {
621
0
    SSIZE_T index = freerdp_client_rdp_file_add_line(file);
622
0
    if (index == -1)
623
0
      return FALSE;
624
0
    line = &file->lines[index];
625
0
  }
626
627
0
  if (targetValue)
628
0
  {
629
0
    *targetValue = (DWORD)value;
630
0
    return TRUE;
631
0
  }
632
633
0
  if (line)
634
0
  {
635
0
    free(line->name);
636
0
    line->name = _strdup(name);
637
0
    if (!line->name)
638
0
    {
639
0
      free(line->name);
640
0
      line->name = NULL;
641
0
      return FALSE;
642
0
    }
643
644
0
    line->iValue = value;
645
0
    line->flags = RDP_FILE_LINE_FLAG_FORMATTED;
646
0
    line->flags |= RDP_FILE_LINE_FLAG_TYPE_INTEGER;
647
0
    line->valueLength = 0;
648
0
    return TRUE;
649
0
  }
650
651
0
  return FALSE;
652
0
}
653
654
static BOOL freerdp_client_parse_rdp_file_integer(rdpFile* file, const char* name,
655
                                                  const char* value)
656
0
{
657
0
  char* endptr = NULL;
658
0
  long ivalue = 0;
659
0
  errno = 0;
660
0
  ivalue = strtol(value, &endptr, 0);
661
662
0
  if ((endptr == NULL) || (errno != 0) || (endptr == value) || (ivalue > INT32_MAX) ||
663
0
      (ivalue < INT32_MIN))
664
0
  {
665
0
    if (file->flags & RDP_FILE_FLAG_PARSE_INT_RELAXED)
666
0
    {
667
0
      WLog_WARN(TAG, "Integer option %s has invalid value %s, using default", name, value);
668
0
      return TRUE;
669
0
    }
670
0
    else
671
0
    {
672
0
      WLog_ERR(TAG, "Failed to convert RDP file integer option %s [value=%s]", name, value);
673
0
      return FALSE;
674
0
    }
675
0
  }
676
677
0
  return freerdp_client_rdp_file_set_integer(file, name, ivalue);
678
0
}
679
680
/** set a string value in the provided rdp file context
681
 *
682
 * @param file rdpFile
683
 * @param name name of the string
684
 * @param value value of the string to set
685
 * @return 0 on success, 1 if the key wasn't found (not a standard key), -1 on error
686
 */
687
688
static BOOL freerdp_client_rdp_file_set_string(rdpFile* file, const char* name, const char* value)
689
0
{
690
0
  LPSTR* targetValue = NULL;
691
0
  rdpFileLine* line = NULL;
692
#ifdef DEBUG_CLIENT_FILE
693
  WLog_DBG(TAG, "%s:s:%s", name, value);
694
#endif
695
696
0
  if (!name || !value)
697
0
    return FALSE;
698
699
0
  if (!freerdp_client_rdp_file_find_string_entry(file, name, &targetValue, &line))
700
0
  {
701
0
    SSIZE_T index = freerdp_client_rdp_file_add_line(file);
702
0
    if (index == -1)
703
0
      return FALSE;
704
0
    line = &file->lines[index];
705
0
  }
706
707
0
  if (targetValue)
708
0
  {
709
0
    *targetValue = _strdup(value);
710
0
    if (!(*targetValue))
711
0
      return FALSE;
712
0
    return TRUE;
713
0
  }
714
715
0
  if (line)
716
0
  {
717
0
    free(line->name);
718
0
    free(line->sValue);
719
0
    line->name = _strdup(name);
720
0
    line->sValue = _strdup(value);
721
0
    if (!line->name || !line->sValue)
722
0
    {
723
0
      free(line->name);
724
0
      free(line->sValue);
725
0
      line->name = NULL;
726
0
      line->sValue = NULL;
727
0
      return FALSE;
728
0
    }
729
730
0
    line->flags = RDP_FILE_LINE_FLAG_FORMATTED;
731
0
    line->flags |= RDP_FILE_LINE_FLAG_TYPE_STRING;
732
0
    line->valueLength = 0;
733
0
    return TRUE;
734
0
  }
735
736
0
  return FALSE;
737
0
}
738
739
static BOOL freerdp_client_add_option(rdpFile* file, const char* option)
740
0
{
741
0
  return freerdp_addin_argv_add_argument(file->args, option);
742
0
}
743
744
static SSIZE_T freerdp_client_rdp_file_add_line(rdpFile* file)
745
0
{
746
0
  SSIZE_T index = (SSIZE_T)file->lineCount;
747
748
0
  while ((file->lineCount + 1) > file->lineSize)
749
0
  {
750
0
    size_t new_size = 0;
751
0
    rdpFileLine* new_line = NULL;
752
0
    new_size = file->lineSize * 2;
753
0
    new_line = (rdpFileLine*)realloc(file->lines, new_size * sizeof(rdpFileLine));
754
755
0
    if (!new_line)
756
0
      return -1;
757
758
0
    file->lines = new_line;
759
0
    file->lineSize = new_size;
760
0
  }
761
762
0
  ZeroMemory(&(file->lines[file->lineCount]), sizeof(rdpFileLine));
763
0
  file->lines[file->lineCount].index = (size_t)index;
764
0
  (file->lineCount)++;
765
0
  return index;
766
0
}
767
768
static BOOL freerdp_client_parse_rdp_file_string(rdpFile* file, char* name, char* value)
769
0
{
770
0
  return freerdp_client_rdp_file_set_string(file, name, value);
771
0
}
772
773
static BOOL freerdp_client_parse_rdp_file_option(rdpFile* file, const char* option)
774
0
{
775
0
  return freerdp_client_add_option(file, option);
776
0
}
777
778
BOOL freerdp_client_parse_rdp_file_buffer(rdpFile* file, const BYTE* buffer, size_t size)
779
0
{
780
0
  return freerdp_client_parse_rdp_file_buffer_ex(file, buffer, size, NULL);
781
0
}
782
783
static BOOL trim(char** strptr)
784
0
{
785
0
  char* start = NULL;
786
0
  char* str = NULL;
787
0
  char* end = NULL;
788
789
0
  start = str = *strptr;
790
0
  if (!str)
791
0
    return TRUE;
792
0
  if (!(~((size_t)str)))
793
0
    return TRUE;
794
0
  end = str + strlen(str) - 1;
795
796
0
  while (isspace(*str))
797
0
    str++;
798
799
0
  while ((end > str) && isspace(*end))
800
0
    end--;
801
0
  end[1] = '\0';
802
0
  if (start == str)
803
0
    *strptr = str;
804
0
  else
805
0
  {
806
0
    *strptr = _strdup(str);
807
0
    free(start);
808
0
    return *strptr != NULL;
809
0
  }
810
811
0
  return TRUE;
812
0
}
813
814
static BOOL trim_strings(rdpFile* file)
815
0
{
816
0
  if (!trim(&file->Username))
817
0
    return FALSE;
818
0
  if (!trim(&file->Domain))
819
0
    return FALSE;
820
0
  if (!trim(&file->AlternateFullAddress))
821
0
    return FALSE;
822
0
  if (!trim(&file->FullAddress))
823
0
    return FALSE;
824
0
  if (!trim(&file->UsbDevicesToRedirect))
825
0
    return FALSE;
826
0
  if (!trim(&file->RedirectCameras))
827
0
    return FALSE;
828
0
  if (!trim(&file->LoadBalanceInfo))
829
0
    return FALSE;
830
0
  if (!trim(&file->GatewayHostname))
831
0
    return FALSE;
832
0
  if (!trim(&file->GatewayAccessToken))
833
0
    return FALSE;
834
0
  if (!trim(&file->RemoteApplicationName))
835
0
    return FALSE;
836
0
  if (!trim(&file->RemoteApplicationIcon))
837
0
    return FALSE;
838
0
  if (!trim(&file->RemoteApplicationProgram))
839
0
    return FALSE;
840
0
  if (!trim(&file->RemoteApplicationFile))
841
0
    return FALSE;
842
0
  if (!trim(&file->RemoteApplicationGuid))
843
0
    return FALSE;
844
0
  if (!trim(&file->RemoteApplicationCmdLine))
845
0
    return FALSE;
846
0
  if (!trim(&file->AlternateShell))
847
0
    return FALSE;
848
0
  if (!trim(&file->ShellWorkingDirectory))
849
0
    return FALSE;
850
0
  if (!trim(&file->DrivesToRedirect))
851
0
    return FALSE;
852
0
  if (!trim(&file->DevicesToRedirect))
853
0
    return FALSE;
854
0
  if (!trim(&file->DevicesToRedirect))
855
0
    return FALSE;
856
0
  if (!trim(&file->WinPosStr))
857
0
    return FALSE;
858
0
  if (!trim(&file->PreconnectionBlob))
859
0
    return FALSE;
860
0
  if (!trim(&file->KdcProxyName))
861
0
    return FALSE;
862
0
  if (!trim(&file->SelectedMonitors))
863
0
    return FALSE;
864
865
0
  for (size_t i = 0; i < file->lineCount; ++i)
866
0
  {
867
0
    rdpFileLine* curLine = &file->lines[i];
868
0
    if (curLine->flags & RDP_FILE_LINE_FLAG_TYPE_STRING)
869
0
    {
870
0
      if (!trim(&curLine->sValue))
871
0
        return FALSE;
872
0
    }
873
0
  }
874
875
0
  return TRUE;
876
0
}
877
878
BOOL freerdp_client_parse_rdp_file_buffer_ex(rdpFile* file, const BYTE* buffer, size_t size,
879
                                             rdp_file_fkt_parse parse)
880
0
{
881
0
  BOOL rc = FALSE;
882
0
  size_t length = 0;
883
0
  char* line = NULL;
884
0
  char* type = NULL;
885
0
  char* context = NULL;
886
0
  char* d1 = NULL;
887
0
  char* d2 = NULL;
888
0
  char* beg = NULL;
889
0
  char* name = NULL;
890
0
  char* value = NULL;
891
0
  char* copy = NULL;
892
893
0
  if (!file)
894
0
    return FALSE;
895
0
  if (size < 2)
896
0
    return FALSE;
897
898
0
  if ((buffer[0] == BOM_UTF16_LE[0]) && (buffer[1] == BOM_UTF16_LE[1]))
899
0
  {
900
0
    LPCWSTR uc = (LPCWSTR)(&buffer[2]);
901
0
    size = size / sizeof(WCHAR) - 1;
902
903
0
    copy = ConvertWCharNToUtf8Alloc(uc, size, NULL);
904
0
    if (!copy)
905
0
    {
906
0
      WLog_ERR(TAG, "Failed to convert RDP file from UCS2 to UTF8");
907
0
      return FALSE;
908
0
    }
909
0
  }
910
0
  else
911
0
  {
912
0
    copy = calloc(1, size + sizeof(BYTE));
913
914
0
    if (!copy)
915
0
      return FALSE;
916
917
0
    memcpy(copy, buffer, size);
918
0
  }
919
920
0
  line = strtok_s(copy, "\r\n", &context);
921
922
0
  while (line)
923
0
  {
924
0
    length = strnlen(line, size);
925
926
0
    if (length > 1)
927
0
    {
928
0
      beg = line;
929
0
      if (beg[0] == '/')
930
0
      {
931
0
        if (!freerdp_client_parse_rdp_file_option(file, line))
932
0
          goto fail;
933
934
0
        goto next_line; /* FreeRDP option */
935
0
      }
936
937
0
      d1 = strchr(line, ':');
938
939
0
      if (!d1)
940
0
        goto next_line; /* not first delimiter */
941
942
0
      type = &d1[1];
943
0
      d2 = strchr(type, ':');
944
945
0
      if (!d2)
946
0
        goto next_line; /* no second delimiter */
947
948
0
      if ((d2 - d1) != 2)
949
0
        goto next_line; /* improper type length */
950
951
0
      *d1 = 0;
952
0
      *d2 = 0;
953
0
      name = beg;
954
0
      value = &d2[1];
955
956
0
      if (parse && parse(file->context, name, *type, value))
957
0
      {
958
0
      }
959
0
      else if (*type == 'i')
960
0
      {
961
        /* integer type */
962
0
        if (!freerdp_client_parse_rdp_file_integer(file, name, value))
963
0
          goto fail;
964
0
      }
965
0
      else if (*type == 's')
966
0
      {
967
        /* string type */
968
0
        if (!freerdp_client_parse_rdp_file_string(file, name, value))
969
0
          goto fail;
970
0
      }
971
0
      else if (*type == 'b')
972
0
      {
973
        /* binary type */
974
0
        WLog_ERR(TAG, "Unsupported RDP file binary option %s [value=%s]", name, value);
975
0
      }
976
0
    }
977
978
0
  next_line:
979
0
    line = strtok_s(NULL, "\r\n", &context);
980
0
  }
981
982
0
  rc = trim_strings(file);
983
0
fail:
984
0
  free(copy);
985
0
  return rc;
986
0
}
987
988
BOOL freerdp_client_parse_rdp_file(rdpFile* file, const char* name)
989
0
{
990
0
  return freerdp_client_parse_rdp_file_ex(file, name, NULL);
991
0
}
992
993
BOOL freerdp_client_parse_rdp_file_ex(rdpFile* file, const char* name, rdp_file_fkt_parse parse)
994
0
{
995
0
  BOOL status = 0;
996
0
  BYTE* buffer = NULL;
997
0
  FILE* fp = NULL;
998
0
  size_t read_size = 0;
999
0
  INT64 file_size = 0;
1000
0
  const char* fname = name;
1001
1002
0
  if (!file || !name)
1003
0
    return FALSE;
1004
1005
0
  if (_strnicmp(fname, "file://", 7) == 0)
1006
0
    fname = &name[7];
1007
1008
0
  fp = winpr_fopen(fname, "r");
1009
0
  if (!fp)
1010
0
  {
1011
0
    WLog_ERR(TAG, "Failed to open RDP file %s", name);
1012
0
    return FALSE;
1013
0
  }
1014
1015
0
  _fseeki64(fp, 0, SEEK_END);
1016
0
  file_size = _ftelli64(fp);
1017
0
  _fseeki64(fp, 0, SEEK_SET);
1018
1019
0
  if (file_size < 1)
1020
0
  {
1021
0
    WLog_ERR(TAG, "RDP file %s is empty", name);
1022
0
    fclose(fp);
1023
0
    return FALSE;
1024
0
  }
1025
1026
0
  buffer = (BYTE*)malloc((size_t)file_size + 2);
1027
1028
0
  if (!buffer)
1029
0
  {
1030
0
    fclose(fp);
1031
0
    return FALSE;
1032
0
  }
1033
1034
0
  read_size = fread(buffer, (size_t)file_size, 1, fp);
1035
1036
0
  if (!read_size)
1037
0
  {
1038
0
    if (!ferror(fp))
1039
0
      read_size = (size_t)file_size;
1040
0
  }
1041
1042
0
  fclose(fp);
1043
1044
0
  if (read_size < 1)
1045
0
  {
1046
0
    WLog_ERR(TAG, "Could not read from RDP file %s", name);
1047
0
    free(buffer);
1048
0
    return FALSE;
1049
0
  }
1050
1051
0
  buffer[file_size] = '\0';
1052
0
  buffer[file_size + 1] = '\0';
1053
0
  status = freerdp_client_parse_rdp_file_buffer_ex(file, buffer, (size_t)file_size, parse);
1054
0
  free(buffer);
1055
0
  return status;
1056
0
}
1057
1058
static INLINE BOOL FILE_POPULATE_STRING(char** _target, const rdpSettings* _settings,
1059
                                        FreeRDP_Settings_Keys_String _option)
1060
0
{
1061
0
  WINPR_ASSERT(_target);
1062
0
  WINPR_ASSERT(_settings);
1063
1064
0
  const char* str = freerdp_settings_get_string(_settings, _option);
1065
0
  freerdp_client_file_string_check_free(*_target);
1066
0
  *_target = (void*)~((size_t)NULL);
1067
0
  if (str)
1068
0
  {
1069
0
    *_target = _strdup(str);
1070
0
    if (!_target)
1071
0
      return FALSE;
1072
0
  }
1073
0
  return TRUE;
1074
0
}
1075
1076
static char* freerdp_client_channel_args_to_string(const rdpSettings* settings, const char* channel,
1077
                                                   const char* option)
1078
0
{
1079
0
  ADDIN_ARGV* args = freerdp_dynamic_channel_collection_find(settings, channel);
1080
0
  const char* filters[] = { option };
1081
0
  if (!args || (args->argc < 2))
1082
0
    return NULL;
1083
1084
0
  return CommandLineToCommaSeparatedValuesEx(args->argc - 1, args->argv + 1, filters,
1085
0
                                             ARRAYSIZE(filters));
1086
0
}
1087
1088
static BOOL rdp_opt_duplicate(const rdpSettings* _settings, FreeRDP_Settings_Keys_String _id,
1089
                              char** _key)
1090
0
{
1091
0
  WINPR_ASSERT(_settings);
1092
0
  WINPR_ASSERT(_key);
1093
0
  const char* tmp = freerdp_settings_get_string(_settings, _id);
1094
1095
0
  if (tmp)
1096
0
  {
1097
0
    *_key = _strdup(tmp);
1098
0
    if (!*_key)
1099
0
      return FALSE;
1100
0
  }
1101
1102
0
  return TRUE;
1103
0
}
1104
1105
BOOL freerdp_client_populate_rdp_file_from_settings(rdpFile* file, const rdpSettings* settings)
1106
0
{
1107
0
  FreeRDP_Settings_Keys_String index = FreeRDP_STRING_UNUSED;
1108
0
  UINT32 LoadBalanceInfoLength = 0;
1109
0
  const char* GatewayHostname = NULL;
1110
0
  char* redirectCameras = NULL;
1111
0
  char* redirectUsb = NULL;
1112
1113
0
  if (!file || !settings)
1114
0
    return FALSE;
1115
1116
0
  if (!FILE_POPULATE_STRING(&file->Domain, settings, FreeRDP_Domain) ||
1117
0
      !FILE_POPULATE_STRING(&file->Username, settings, FreeRDP_Username) ||
1118
0
      !FILE_POPULATE_STRING(&file->Password, settings, FreeRDP_Password) ||
1119
0
      !FILE_POPULATE_STRING(&file->FullAddress, settings, FreeRDP_ServerHostname) ||
1120
0
      !FILE_POPULATE_STRING(&file->AlternateFullAddress, settings, FreeRDP_ServerHostname) ||
1121
0
      !FILE_POPULATE_STRING(&file->AlternateShell, settings, FreeRDP_AlternateShell) ||
1122
0
      !FILE_POPULATE_STRING(&file->DrivesToRedirect, settings, FreeRDP_DrivesToRedirect))
1123
1124
0
    return FALSE;
1125
0
  file->ServerPort = freerdp_settings_get_uint32(settings, FreeRDP_ServerPort);
1126
1127
0
  file->DesktopWidth = freerdp_settings_get_uint32(settings, FreeRDP_DesktopWidth);
1128
0
  file->DesktopHeight = freerdp_settings_get_uint32(settings, FreeRDP_DesktopHeight);
1129
0
  file->SessionBpp = freerdp_settings_get_uint32(settings, FreeRDP_ColorDepth);
1130
0
  file->DesktopScaleFactor = freerdp_settings_get_uint32(settings, FreeRDP_DesktopScaleFactor);
1131
0
  file->DynamicResolution = freerdp_settings_get_bool(settings, FreeRDP_DynamicResolutionUpdate);
1132
0
  file->VideoPlaybackMode = freerdp_settings_get_bool(settings, FreeRDP_SupportVideoOptimized);
1133
1134
  // TODO file->MaximizeToCurrentDisplays;
1135
  // TODO file->SingleMonInWindowedMode;
1136
  // TODO file->EncodeRedirectedVideoCapture;
1137
  // TODO file->RedirectedVideoCaptureEncodingQuality;
1138
0
  file->ConnectToConsole = freerdp_settings_get_bool(settings, FreeRDP_ConsoleSession);
1139
0
  file->NegotiateSecurityLayer =
1140
0
      freerdp_settings_get_bool(settings, FreeRDP_NegotiateSecurityLayer);
1141
0
  file->EnableCredSSPSupport = freerdp_settings_get_bool(settings, FreeRDP_NlaSecurity);
1142
0
  file->EnableRdsAadAuth = freerdp_settings_get_bool(settings, FreeRDP_AadSecurity);
1143
1144
0
  if (freerdp_settings_get_bool(settings, FreeRDP_RemoteApplicationMode))
1145
0
    index = FreeRDP_RemoteApplicationWorkingDir;
1146
0
  else
1147
0
    index = FreeRDP_ShellWorkingDirectory;
1148
0
  if (!FILE_POPULATE_STRING(&file->ShellWorkingDirectory, settings, index))
1149
0
    return FALSE;
1150
0
  file->ConnectionType = freerdp_settings_get_uint32(settings, FreeRDP_ConnectionType);
1151
1152
0
  file->ScreenModeId = freerdp_settings_get_bool(settings, FreeRDP_Fullscreen) ? 2 : 1;
1153
1154
0
  LoadBalanceInfoLength = freerdp_settings_get_uint32(settings, FreeRDP_LoadBalanceInfoLength);
1155
0
  if (LoadBalanceInfoLength > 0)
1156
0
  {
1157
0
    const BYTE* LoadBalanceInfo =
1158
0
        freerdp_settings_get_pointer(settings, FreeRDP_LoadBalanceInfo);
1159
0
    file->LoadBalanceInfo = calloc(LoadBalanceInfoLength + 1, 1);
1160
0
    if (!file->LoadBalanceInfo)
1161
0
      return FALSE;
1162
0
    memcpy(file->LoadBalanceInfo, LoadBalanceInfo, LoadBalanceInfoLength);
1163
0
  }
1164
1165
0
  if (freerdp_settings_get_bool(settings, FreeRDP_AudioPlayback))
1166
0
    file->AudioMode = AUDIO_MODE_REDIRECT;
1167
0
  else if (freerdp_settings_get_bool(settings, FreeRDP_RemoteConsoleAudio))
1168
0
    file->AudioMode = AUDIO_MODE_PLAY_ON_SERVER;
1169
0
  else
1170
0
    file->AudioMode = AUDIO_MODE_NONE;
1171
1172
  /* The gateway hostname should also contain a port specifier unless it is the default port 443
1173
   */
1174
0
  GatewayHostname = freerdp_settings_get_string(settings, FreeRDP_GatewayHostname);
1175
0
  if (GatewayHostname)
1176
0
  {
1177
0
    const UINT32 GatewayPort = freerdp_settings_get_uint32(settings, FreeRDP_GatewayPort);
1178
0
    freerdp_client_file_string_check_free(file->GatewayHostname);
1179
0
    if (GatewayPort == 443)
1180
0
      file->GatewayHostname = _strdup(GatewayHostname);
1181
0
    else
1182
0
    {
1183
0
      int length = _scprintf("%s:%" PRIu32, GatewayHostname, GatewayPort);
1184
0
      if (length < 0)
1185
0
        return FALSE;
1186
1187
0
      file->GatewayHostname = (char*)malloc((size_t)length + 1);
1188
0
      if (!file->GatewayHostname)
1189
0
        return FALSE;
1190
1191
0
      if (sprintf_s(file->GatewayHostname, (size_t)length + 1, "%s:%" PRIu32, GatewayHostname,
1192
0
                    GatewayPort) < 0)
1193
0
        return FALSE;
1194
0
    }
1195
0
    if (!file->GatewayHostname)
1196
0
      return FALSE;
1197
0
  }
1198
1199
0
  if (freerdp_settings_get_bool(settings, FreeRDP_GatewayArmTransport))
1200
0
    file->ResourceProvider = _strdup(str_resourceprovider_arm);
1201
1202
0
  if (!rdp_opt_duplicate(settings, FreeRDP_GatewayAvdWvdEndpointPool, &file->WvdEndpointPool))
1203
0
    return FALSE;
1204
0
  if (!rdp_opt_duplicate(settings, FreeRDP_GatewayAvdGeo, &file->geo))
1205
0
    return FALSE;
1206
0
  if (!rdp_opt_duplicate(settings, FreeRDP_GatewayAvdArmpath, &file->armpath))
1207
0
    return FALSE;
1208
0
  if (!rdp_opt_duplicate(settings, FreeRDP_GatewayAvdAadtenantid, &file->aadtenantid))
1209
0
    return FALSE;
1210
0
  if (!rdp_opt_duplicate(settings, FreeRDP_GatewayAvdDiagnosticserviceurl,
1211
0
                         &file->diagnosticserviceurl))
1212
0
    return FALSE;
1213
0
  if (!rdp_opt_duplicate(settings, FreeRDP_GatewayAvdHubdiscoverygeourl,
1214
0
                         &file->hubdiscoverygeourl))
1215
0
    return FALSE;
1216
0
  if (!rdp_opt_duplicate(settings, FreeRDP_GatewayAvdActivityhint, &file->activityhint))
1217
0
    return FALSE;
1218
1219
0
  file->AudioCaptureMode = freerdp_settings_get_bool(settings, FreeRDP_AudioCapture);
1220
0
  file->BitmapCachePersistEnable =
1221
0
      freerdp_settings_get_bool(settings, FreeRDP_BitmapCachePersistEnabled);
1222
0
  file->Compression = freerdp_settings_get_bool(settings, FreeRDP_CompressionEnabled);
1223
0
  file->AuthenticationLevel = freerdp_settings_get_uint32(settings, FreeRDP_AuthenticationLevel);
1224
0
  file->GatewayUsageMethod = freerdp_settings_get_uint32(settings, FreeRDP_GatewayUsageMethod);
1225
0
  file->GatewayCredentialsSource =
1226
0
      freerdp_settings_get_uint32(settings, FreeRDP_GatewayCredentialsSource);
1227
0
  file->PromptCredentialOnce =
1228
0
      freerdp_settings_get_bool(settings, FreeRDP_GatewayUseSameCredentials);
1229
0
  file->PromptForCredentials = freerdp_settings_get_bool(settings, FreeRDP_PromptForCredentials);
1230
0
  file->RemoteApplicationMode =
1231
0
      freerdp_settings_get_bool(settings, FreeRDP_RemoteApplicationMode);
1232
0
  if (!FILE_POPULATE_STRING(&file->GatewayAccessToken, settings, FreeRDP_GatewayAccessToken) ||
1233
0
      !FILE_POPULATE_STRING(&file->RemoteApplicationProgram, settings,
1234
0
                            FreeRDP_RemoteApplicationProgram) ||
1235
0
      !FILE_POPULATE_STRING(&file->RemoteApplicationName, settings,
1236
0
                            FreeRDP_RemoteApplicationName) ||
1237
0
      !FILE_POPULATE_STRING(&file->RemoteApplicationIcon, settings,
1238
0
                            FreeRDP_RemoteApplicationIcon) ||
1239
0
      !FILE_POPULATE_STRING(&file->RemoteApplicationFile, settings,
1240
0
                            FreeRDP_RemoteApplicationFile) ||
1241
0
      !FILE_POPULATE_STRING(&file->RemoteApplicationGuid, settings,
1242
0
                            FreeRDP_RemoteApplicationGuid) ||
1243
0
      !FILE_POPULATE_STRING(&file->RemoteApplicationCmdLine, settings,
1244
0
                            FreeRDP_RemoteApplicationCmdLine))
1245
0
    return FALSE;
1246
0
  file->SpanMonitors = freerdp_settings_get_bool(settings, FreeRDP_SpanMonitors);
1247
0
  file->UseMultiMon = freerdp_settings_get_bool(settings, FreeRDP_UseMultimon);
1248
0
  file->AllowDesktopComposition =
1249
0
      freerdp_settings_get_bool(settings, FreeRDP_AllowDesktopComposition);
1250
0
  file->AllowFontSmoothing = freerdp_settings_get_bool(settings, FreeRDP_AllowFontSmoothing);
1251
0
  file->DisableWallpaper = freerdp_settings_get_bool(settings, FreeRDP_DisableWallpaper);
1252
0
  file->DisableFullWindowDrag =
1253
0
      freerdp_settings_get_bool(settings, FreeRDP_DisableFullWindowDrag);
1254
0
  file->DisableMenuAnims = freerdp_settings_get_bool(settings, FreeRDP_DisableMenuAnims);
1255
0
  file->DisableThemes = freerdp_settings_get_bool(settings, FreeRDP_DisableThemes);
1256
0
  file->BandwidthAutoDetect = (freerdp_settings_get_uint32(settings, FreeRDP_ConnectionType) >=
1257
0
                               CONNECTION_TYPE_AUTODETECT)
1258
0
                                  ? TRUE
1259
0
                                  : FALSE;
1260
0
  file->NetworkAutoDetect =
1261
0
      freerdp_settings_get_bool(settings, FreeRDP_NetworkAutoDetect) ? 1 : 0;
1262
0
  file->AutoReconnectionEnabled =
1263
0
      freerdp_settings_get_bool(settings, FreeRDP_AutoReconnectionEnabled);
1264
0
  file->RedirectSmartCards = freerdp_settings_get_bool(settings, FreeRDP_RedirectSmartCards);
1265
0
  file->RedirectWebauthN = freerdp_settings_get_bool(settings, FreeRDP_RedirectWebAuthN);
1266
1267
0
  redirectCameras =
1268
0
      freerdp_client_channel_args_to_string(settings, RDPECAM_DVC_CHANNEL_NAME, "device:");
1269
0
  if (redirectCameras)
1270
0
  {
1271
0
    char* str =
1272
0
        freerdp_client_channel_args_to_string(settings, RDPECAM_DVC_CHANNEL_NAME, "encode:");
1273
0
    file->EncodeRedirectedVideoCapture = 0;
1274
0
    if (str)
1275
0
    {
1276
0
      unsigned long val = 0;
1277
0
      errno = 0;
1278
0
      val = strtoul(str, NULL, 0);
1279
0
      if ((val < UINT32_MAX) && (errno == 0))
1280
0
        file->EncodeRedirectedVideoCapture = val;
1281
0
    }
1282
0
    free(str);
1283
1284
0
    str = freerdp_client_channel_args_to_string(settings, RDPECAM_DVC_CHANNEL_NAME, "quality:");
1285
0
    file->RedirectedVideoCaptureEncodingQuality = 0;
1286
0
    if (str)
1287
0
    {
1288
0
      unsigned long val = 0;
1289
0
      errno = 0;
1290
0
      val = strtoul(str, NULL, 0);
1291
0
      if ((val <= 2) && (errno == 0))
1292
0
      {
1293
0
        file->RedirectedVideoCaptureEncodingQuality = val;
1294
0
      }
1295
0
    }
1296
0
    free(str);
1297
1298
0
    file->RedirectCameras = redirectCameras;
1299
0
  }
1300
#ifdef CHANNEL_URBDRC_CLIENT
1301
  redirectUsb = freerdp_client_channel_args_to_string(settings, URBDRC_CHANNEL_NAME, "device:");
1302
  if (redirectUsb)
1303
    file->UsbDevicesToRedirect = redirectUsb;
1304
1305
#endif
1306
0
  file->RedirectClipboard =
1307
0
      freerdp_settings_get_bool(settings, FreeRDP_RedirectClipboard) ? 1 : 0;
1308
0
  file->RedirectPrinters = freerdp_settings_get_bool(settings, FreeRDP_RedirectPrinters) ? 1 : 0;
1309
0
  file->RedirectDrives = freerdp_settings_get_bool(settings, FreeRDP_RedirectDrives) ? 1 : 0;
1310
0
  file->RdgIsKdcProxy = freerdp_settings_get_bool(settings, FreeRDP_KerberosRdgIsProxy) ? 1 : 0;
1311
0
  file->RedirectComPorts = (freerdp_settings_get_bool(settings, FreeRDP_RedirectSerialPorts) ||
1312
0
                            freerdp_settings_get_bool(settings, FreeRDP_RedirectParallelPorts));
1313
0
  file->RedirectLocation =
1314
0
      freerdp_dynamic_channel_collection_find(settings, LOCATION_CHANNEL_NAME) ? TRUE : FALSE;
1315
0
  if (!FILE_POPULATE_STRING(&file->DrivesToRedirect, settings, FreeRDP_DrivesToRedirect) ||
1316
0
      !FILE_POPULATE_STRING(&file->PreconnectionBlob, settings, FreeRDP_PreconnectionBlob) ||
1317
0
      !FILE_POPULATE_STRING(&file->KdcProxyName, settings, FreeRDP_KerberosKdcUrl))
1318
0
    return FALSE;
1319
1320
0
  {
1321
0
    size_t offset = 0;
1322
0
    UINT32 count = freerdp_settings_get_uint32(settings, FreeRDP_NumMonitorIds);
1323
0
    const UINT32* MonitorIds = freerdp_settings_get_pointer(settings, FreeRDP_MonitorIds);
1324
    /* String size: 10 char UINT32 max string length, 1 char separator, one element NULL */
1325
0
    size_t size = count * (10 + 1) + 1;
1326
1327
0
    char* str = calloc(size, sizeof(char));
1328
0
    for (UINT32 x = 0; x < count; x++)
1329
0
    {
1330
0
      int rc = _snprintf(&str[offset], size - offset, "%" PRIu32 ",", MonitorIds[x]);
1331
0
      if (rc <= 0)
1332
0
      {
1333
0
        free(str);
1334
0
        return FALSE;
1335
0
      }
1336
0
      offset += (size_t)rc;
1337
0
    }
1338
0
    if (offset > 0)
1339
0
      str[offset - 1] = '\0';
1340
0
    freerdp_client_file_string_check_free(file->SelectedMonitors);
1341
0
    file->SelectedMonitors = str;
1342
0
  }
1343
1344
0
  file->KeyboardHook = freerdp_settings_get_uint32(settings, FreeRDP_KeyboardHook);
1345
1346
0
  return TRUE;
1347
0
}
1348
1349
BOOL freerdp_client_write_rdp_file(const rdpFile* file, const char* name, BOOL unicode)
1350
0
{
1351
0
  FILE* fp = NULL;
1352
0
  size_t size = 0;
1353
0
  char* buffer = NULL;
1354
0
  int status = 0;
1355
0
  WCHAR* unicodestr = NULL;
1356
1357
0
  if (!file || !name)
1358
0
    return FALSE;
1359
1360
0
  size = freerdp_client_write_rdp_file_buffer(file, NULL, 0);
1361
0
  if (size == 0)
1362
0
    return FALSE;
1363
0
  buffer = (char*)calloc((size_t)(size + 1), sizeof(char));
1364
1365
0
  if (freerdp_client_write_rdp_file_buffer(file, buffer, (size_t)size + 1) != size)
1366
0
  {
1367
0
    WLog_ERR(TAG, "freerdp_client_write_rdp_file: error writing to output buffer");
1368
0
    free(buffer);
1369
0
    return FALSE;
1370
0
  }
1371
1372
0
  fp = winpr_fopen(name, "w+b");
1373
1374
0
  if (fp)
1375
0
  {
1376
0
    if (unicode)
1377
0
    {
1378
0
      size_t len = 0;
1379
0
      unicodestr = ConvertUtf8NToWCharAlloc(buffer, size, &len);
1380
1381
0
      if (!unicodestr)
1382
0
      {
1383
0
        free(buffer);
1384
0
        fclose(fp);
1385
0
        return FALSE;
1386
0
      }
1387
1388
      /* Write multi-byte header */
1389
0
      if ((fwrite(BOM_UTF16_LE, sizeof(BYTE), 2, fp) != 2) ||
1390
0
          (fwrite(unicodestr, sizeof(WCHAR), len, fp) != len))
1391
0
      {
1392
0
        free(buffer);
1393
0
        free(unicodestr);
1394
0
        fclose(fp);
1395
0
        return FALSE;
1396
0
      }
1397
1398
0
      free(unicodestr);
1399
0
    }
1400
0
    else
1401
0
    {
1402
0
      if (fwrite(buffer, 1, (size_t)size, fp) != (size_t)size)
1403
0
      {
1404
0
        free(buffer);
1405
0
        fclose(fp);
1406
0
        return FALSE;
1407
0
      }
1408
0
    }
1409
1410
0
    fflush(fp);
1411
0
    status = fclose(fp);
1412
0
  }
1413
1414
0
  free(buffer);
1415
0
  return (status == 0) ? TRUE : FALSE;
1416
0
}
1417
1418
WINPR_ATTR_FORMAT_ARG(3, 4)
1419
static SSIZE_T freerdp_client_write_setting_to_buffer(char** buffer, size_t* bufferSize,
1420
                                                      WINPR_FORMAT_ARG const char* fmt, ...)
1421
0
{
1422
0
  va_list ap;
1423
0
  SSIZE_T len = 0;
1424
0
  char* buf = NULL;
1425
0
  size_t bufSize = 0;
1426
1427
0
  if (!buffer || !bufferSize || !fmt)
1428
0
    return -1;
1429
1430
0
  buf = *buffer;
1431
0
  bufSize = *bufferSize;
1432
1433
0
  va_start(ap, fmt);
1434
0
  len = vsnprintf(buf, bufSize, fmt, ap);
1435
0
  va_end(ap);
1436
0
  if (len < 0)
1437
0
    return -1;
1438
1439
  /* _snprintf doesn't add the ending \0 to its return value */
1440
0
  ++len;
1441
1442
  /* we just want to know the size - return it */
1443
0
  if (!buf && !bufSize)
1444
0
    return len;
1445
1446
0
  if (!buf)
1447
0
    return -1;
1448
1449
  /* update buffer size and buffer position and replace \0 with \n */
1450
0
  if (bufSize >= (size_t)len)
1451
0
  {
1452
0
    *bufferSize -= (size_t)len;
1453
0
    buf[len - 1] = '\n';
1454
0
    *buffer = buf + len;
1455
0
  }
1456
0
  else
1457
0
    return -1;
1458
1459
0
  return len;
1460
0
}
1461
1462
size_t freerdp_client_write_rdp_file_buffer(const rdpFile* file, char* buffer, size_t size)
1463
0
{
1464
0
  size_t totalSize = 0;
1465
1466
0
  if (!file)
1467
0
    return 0;
1468
1469
  /* either buffer and size are null or non-null */
1470
0
  if ((!buffer || !size) && (buffer || size))
1471
0
    return 0;
1472
1473
0
#define WRITE_SETTING_(fmt_, ...)                                                                \
1474
0
  {                                                                                            \
1475
0
    SSIZE_T res = freerdp_client_write_setting_to_buffer(&buffer, &size, fmt_, __VA_ARGS__); \
1476
0
    if (res < 0)                                                                             \
1477
0
      return 0;                                                                            \
1478
0
    totalSize += (size_t)res;                                                                \
1479
0
  }
1480
1481
0
#define WRITE_SETTING_INT(key_, param_)                   \
1482
0
  do                                                    \
1483
0
  {                                                     \
1484
0
    if (~(param_))                                    \
1485
0
      WRITE_SETTING_("%s:i:%" PRIu32, key_, param_) \
1486
0
  } while (0)
1487
1488
0
#define WRITE_SETTING_STR(key_, param_)             \
1489
0
  do                                              \
1490
0
  {                                               \
1491
0
    if (~(size_t)(param_))                      \
1492
0
      WRITE_SETTING_("%s:s:%s", key_, param_) \
1493
0
  } while (0)
1494
1495
  /* integer parameters */
1496
0
  WRITE_SETTING_INT(key_int_use_multimon, file->UseMultiMon);
1497
0
  WRITE_SETTING_INT(key_int_maximizetocurrentdisplays, file->MaximizeToCurrentDisplays);
1498
0
  WRITE_SETTING_INT(key_int_singlemoninwindowedmode, file->SingleMonInWindowedMode);
1499
0
  WRITE_SETTING_INT(key_int_screen_mode_id, file->ScreenModeId);
1500
0
  WRITE_SETTING_INT(key_int_span_monitors, file->SpanMonitors);
1501
0
  WRITE_SETTING_INT(key_int_smart_sizing, file->SmartSizing);
1502
0
  WRITE_SETTING_INT(key_int_dynamic_resolution, file->DynamicResolution);
1503
0
  WRITE_SETTING_INT(key_int_enablesuperpan, file->EnableSuperSpan);
1504
0
  WRITE_SETTING_INT(key_int_superpanaccelerationfactor, file->SuperSpanAccelerationFactor);
1505
0
  WRITE_SETTING_INT(key_int_desktopwidth, file->DesktopWidth);
1506
0
  WRITE_SETTING_INT(key_int_desktopheight, file->DesktopHeight);
1507
0
  WRITE_SETTING_INT(key_int_desktop_size_id, file->DesktopSizeId);
1508
0
  WRITE_SETTING_INT(key_int_session_bpp, file->SessionBpp);
1509
0
  WRITE_SETTING_INT(key_int_desktopscalefactor, file->DesktopScaleFactor);
1510
0
  WRITE_SETTING_INT(key_int_compression, file->Compression);
1511
0
  WRITE_SETTING_INT(key_int_keyboardhook, file->KeyboardHook);
1512
0
  WRITE_SETTING_INT(key_int_disable_ctrl_alt_del, file->DisableCtrlAltDel);
1513
0
  WRITE_SETTING_INT(key_int_audiomode, file->AudioMode);
1514
0
  WRITE_SETTING_INT(key_int_audioqualitymode, file->AudioQualityMode);
1515
0
  WRITE_SETTING_INT(key_int_audiocapturemode, file->AudioCaptureMode);
1516
0
  WRITE_SETTING_INT(key_int_encode_redirected_video_capture, file->EncodeRedirectedVideoCapture);
1517
0
  WRITE_SETTING_INT(key_int_redirected_video_capture_encoding_quality,
1518
0
                    file->RedirectedVideoCaptureEncodingQuality);
1519
0
  WRITE_SETTING_INT(key_int_videoplaybackmode, file->VideoPlaybackMode);
1520
0
  WRITE_SETTING_INT(key_int_connection_type, file->ConnectionType);
1521
0
  WRITE_SETTING_INT(key_int_networkautodetect, file->NetworkAutoDetect);
1522
0
  WRITE_SETTING_INT(key_int_bandwidthautodetect, file->BandwidthAutoDetect);
1523
0
  WRITE_SETTING_INT(key_int_pinconnectionbar, file->PinConnectionBar);
1524
0
  WRITE_SETTING_INT(key_int_displayconnectionbar, file->DisplayConnectionBar);
1525
0
  WRITE_SETTING_INT(key_int_workspaceid, file->WorkspaceId);
1526
0
  WRITE_SETTING_INT(key_int_enableworkspacereconnect, file->EnableWorkspaceReconnect);
1527
0
  WRITE_SETTING_INT(key_int_disable_wallpaper, file->DisableWallpaper);
1528
0
  WRITE_SETTING_INT(key_int_allow_font_smoothing, file->AllowFontSmoothing);
1529
0
  WRITE_SETTING_INT(key_int_allow_desktop_composition, file->AllowDesktopComposition);
1530
0
  WRITE_SETTING_INT(key_int_disable_full_window_drag, file->DisableFullWindowDrag);
1531
0
  WRITE_SETTING_INT(key_int_disable_menu_anims, file->DisableMenuAnims);
1532
0
  WRITE_SETTING_INT(key_int_disable_themes, file->DisableThemes);
1533
0
  WRITE_SETTING_INT(key_int_disable_cursor_setting, file->DisableCursorSetting);
1534
0
  WRITE_SETTING_INT(key_int_bitmapcachesize, file->BitmapCacheSize);
1535
0
  WRITE_SETTING_INT(key_int_bitmapcachepersistenable, file->BitmapCachePersistEnable);
1536
0
  WRITE_SETTING_INT(key_int_server_port, file->ServerPort);
1537
0
  WRITE_SETTING_INT(key_int_redirectdrives, file->RedirectDrives);
1538
0
  WRITE_SETTING_INT(key_int_redirectprinters, file->RedirectPrinters);
1539
0
  WRITE_SETTING_INT(key_int_redirectcomports, file->RedirectComPorts);
1540
0
  WRITE_SETTING_INT(key_int_redirectlocation, file->RedirectLocation);
1541
0
  WRITE_SETTING_INT(key_int_redirectsmartcards, file->RedirectSmartCards);
1542
0
  WRITE_SETTING_INT(key_int_redirectclipboard, file->RedirectClipboard);
1543
0
  WRITE_SETTING_INT(key_int_redirectposdevices, file->RedirectPosDevices);
1544
0
  WRITE_SETTING_INT(key_int_redirectdirectx, file->RedirectDirectX);
1545
0
  WRITE_SETTING_INT(key_int_disableprinterredirection, file->DisablePrinterRedirection);
1546
0
  WRITE_SETTING_INT(key_int_disableclipboardredirection, file->DisableClipboardRedirection);
1547
0
  WRITE_SETTING_INT(key_int_connect_to_console, file->ConnectToConsole);
1548
0
  WRITE_SETTING_INT(key_int_administrative_session, file->AdministrativeSession);
1549
0
  WRITE_SETTING_INT(key_int_autoreconnection_enabled, file->AutoReconnectionEnabled);
1550
0
  WRITE_SETTING_INT(key_int_autoreconnect_max_retries, file->AutoReconnectMaxRetries);
1551
0
  WRITE_SETTING_INT(key_int_public_mode, file->PublicMode);
1552
0
  WRITE_SETTING_INT(key_int_authentication_level, file->AuthenticationLevel);
1553
0
  WRITE_SETTING_INT(key_int_promptcredentialonce, file->PromptCredentialOnce);
1554
0
  WRITE_SETTING_INT(key_int_prompt_for_credentials, file->PromptForCredentials);
1555
0
  WRITE_SETTING_INT(key_int_negotiate_security_layer, file->NegotiateSecurityLayer);
1556
0
  WRITE_SETTING_INT(key_int_enablecredsspsupport, file->EnableCredSSPSupport);
1557
0
  WRITE_SETTING_INT(key_int_enablerdsaadauth, file->EnableRdsAadAuth);
1558
0
  WRITE_SETTING_INT(key_int_remoteapplicationmode, file->RemoteApplicationMode);
1559
0
  WRITE_SETTING_INT(key_int_remoteapplicationexpandcmdline, file->RemoteApplicationExpandCmdLine);
1560
0
  WRITE_SETTING_INT(key_int_remoteapplicationexpandworkingdir,
1561
0
                    file->RemoteApplicationExpandWorkingDir);
1562
0
  WRITE_SETTING_INT(key_int_disableconnectionsharing, file->DisableConnectionSharing);
1563
0
  WRITE_SETTING_INT(key_int_disableremoteappcapscheck, file->DisableRemoteAppCapsCheck);
1564
0
  WRITE_SETTING_INT(key_int_gatewayusagemethod, file->GatewayUsageMethod);
1565
0
  WRITE_SETTING_INT(key_int_gatewayprofileusagemethod, file->GatewayProfileUsageMethod);
1566
0
  WRITE_SETTING_INT(key_int_gatewaycredentialssource, file->GatewayCredentialsSource);
1567
0
  WRITE_SETTING_INT(key_int_use_redirection_server_name, file->UseRedirectionServerName);
1568
0
  WRITE_SETTING_INT(key_int_rdgiskdcproxy, file->RdgIsKdcProxy);
1569
0
  WRITE_SETTING_INT(key_int_redirectwebauthn, file->RedirectWebauthN);
1570
1571
  /* string parameters */
1572
0
  WRITE_SETTING_STR(key_str_username, file->Username);
1573
0
  WRITE_SETTING_STR(key_str_domain, file->Domain);
1574
0
  WRITE_SETTING_STR(key_str_password, file->Password);
1575
0
  WRITE_SETTING_STR(key_str_full_address, file->FullAddress);
1576
0
  WRITE_SETTING_STR(key_str_alternate_full_address, file->AlternateFullAddress);
1577
0
  WRITE_SETTING_STR(key_str_usbdevicestoredirect, file->UsbDevicesToRedirect);
1578
0
  WRITE_SETTING_STR(key_str_camerastoredirect, file->RedirectCameras);
1579
0
  WRITE_SETTING_STR(key_str_loadbalanceinfo, file->LoadBalanceInfo);
1580
0
  WRITE_SETTING_STR(key_str_remoteapplicationname, file->RemoteApplicationName);
1581
0
  WRITE_SETTING_STR(key_str_remoteapplicationicon, file->RemoteApplicationIcon);
1582
0
  WRITE_SETTING_STR(key_str_remoteapplicationprogram, file->RemoteApplicationProgram);
1583
0
  WRITE_SETTING_STR(key_str_remoteapplicationfile, file->RemoteApplicationFile);
1584
0
  WRITE_SETTING_STR(key_str_remoteapplicationguid, file->RemoteApplicationGuid);
1585
0
  WRITE_SETTING_STR(key_str_remoteapplicationcmdline, file->RemoteApplicationCmdLine);
1586
0
  WRITE_SETTING_STR(key_str_alternate_shell, file->AlternateShell);
1587
0
  WRITE_SETTING_STR(key_str_shell_working_directory, file->ShellWorkingDirectory);
1588
0
  WRITE_SETTING_STR(key_str_gatewayhostname, file->GatewayHostname);
1589
0
  WRITE_SETTING_STR(key_str_resourceprovider, file->ResourceProvider);
1590
0
  WRITE_SETTING_STR(key_str_wvd, file->WvdEndpointPool);
1591
0
  WRITE_SETTING_STR(key_str_geo, file->geo);
1592
0
  WRITE_SETTING_STR(key_str_armpath, file->armpath);
1593
0
  WRITE_SETTING_STR(key_str_aadtenantid, file->aadtenantid);
1594
0
  WRITE_SETTING_STR(key_str_diagnosticserviceurl, file->diagnosticserviceurl);
1595
0
  WRITE_SETTING_STR(key_str_hubdiscoverygeourl, file->hubdiscoverygeourl);
1596
0
  WRITE_SETTING_STR(key_str_activityhint, file->activityhint);
1597
0
  WRITE_SETTING_STR(key_str_gatewayaccesstoken, file->GatewayAccessToken);
1598
0
  WRITE_SETTING_STR(key_str_kdcproxyname, file->KdcProxyName);
1599
0
  WRITE_SETTING_STR(key_str_drivestoredirect, file->DrivesToRedirect);
1600
0
  WRITE_SETTING_STR(key_str_devicestoredirect, file->DevicesToRedirect);
1601
0
  WRITE_SETTING_STR(key_str_winposstr, file->WinPosStr);
1602
0
  WRITE_SETTING_STR(key_str_pcb, file->PreconnectionBlob);
1603
0
  WRITE_SETTING_STR(key_str_selectedmonitors, file->SelectedMonitors);
1604
1605
  /* custom parameters */
1606
0
  for (size_t i = 0; i < file->lineCount; ++i)
1607
0
  {
1608
0
    SSIZE_T res = -1;
1609
0
    const rdpFileLine* curLine = &file->lines[i];
1610
1611
0
    if (curLine->flags & RDP_FILE_LINE_FLAG_TYPE_INTEGER)
1612
0
      res = freerdp_client_write_setting_to_buffer(&buffer, &size, "%s:i:%" PRIu32,
1613
0
                                                   curLine->name, (UINT32)curLine->iValue);
1614
0
    else if (curLine->flags & RDP_FILE_LINE_FLAG_TYPE_STRING)
1615
0
      res = freerdp_client_write_setting_to_buffer(&buffer, &size, "%s:s:%s", curLine->name,
1616
0
                                                   curLine->sValue);
1617
0
    if (res < 0)
1618
0
      return 0;
1619
1620
0
    totalSize += (size_t)res;
1621
0
  }
1622
1623
0
  return totalSize;
1624
0
}
1625
1626
static ADDIN_ARGV* rdp_file_to_args(const char* channel, const char* values)
1627
0
{
1628
0
  size_t count = 0;
1629
0
  char** p = NULL;
1630
0
  ADDIN_ARGV* args = freerdp_addin_argv_new(0, NULL);
1631
0
  if (!args)
1632
0
    return NULL;
1633
0
  if (!freerdp_addin_argv_add_argument(args, channel))
1634
0
    goto fail;
1635
0
1636
0
  p = CommandLineParseCommaSeparatedValues(values, &count);
1637
0
  for (size_t x = 0; x < count; x++)
1638
0
  {
1639
0
    BOOL rc = 0;
1640
0
    const char* val = p[x];
1641
0
    const size_t len = strlen(val) + 8;
1642
0
    char* str = calloc(len, sizeof(char));
1643
0
    if (!str)
1644
0
      goto fail;
1645
0
1646
0
    _snprintf(str, len, "device:%s", val);
1647
0
    rc = freerdp_addin_argv_add_argument(args, str);
1648
0
    free(str);
1649
0
    if (!rc)
1650
0
      goto fail;
1651
0
  }
1652
0
  free(p);
1653
0
  return args;
1654
0
1655
0
fail:
1656
0
  free(p);
1657
0
  freerdp_addin_argv_free(args);
1658
0
  return NULL;
1659
0
}
1660
1661
BOOL freerdp_client_populate_settings_from_rdp_file(const rdpFile* file, rdpSettings* settings)
1662
0
{
1663
0
  BOOL setDefaultConnectionType = TRUE;
1664
1665
0
  if (!file || !settings)
1666
0
    return FALSE;
1667
1668
0
  if (~((size_t)file->Domain))
1669
0
  {
1670
0
    if (!freerdp_settings_set_string(settings, FreeRDP_Domain, file->Domain))
1671
0
      return FALSE;
1672
0
  }
1673
1674
0
  if (~((size_t)file->Username))
1675
0
  {
1676
0
    char* user = NULL;
1677
0
    char* domain = NULL;
1678
1679
0
    if (!freerdp_parse_username(file->Username, &user, &domain))
1680
0
      return FALSE;
1681
1682
0
    if (!freerdp_settings_set_string(settings, FreeRDP_Username, user))
1683
0
      return FALSE;
1684
1685
0
    if (!(~((size_t)file->Domain)) && domain)
1686
0
    {
1687
0
      if (!freerdp_settings_set_string(settings, FreeRDP_Domain, domain))
1688
0
        return FALSE;
1689
0
    }
1690
1691
0
    free(user);
1692
0
    free(domain);
1693
0
  }
1694
1695
0
  if (~((size_t)file->Password))
1696
0
  {
1697
0
    if (!freerdp_settings_set_string(settings, FreeRDP_Password, file->Password))
1698
0
      return FALSE;
1699
0
  }
1700
1701
0
  {
1702
0
    const char* address = NULL;
1703
1704
    /* With MSTSC alternate full address always wins,
1705
     * so mimic this. */
1706
0
    if (~((size_t)file->AlternateFullAddress))
1707
0
      address = file->AlternateFullAddress;
1708
0
    else if (~((size_t)file->FullAddress))
1709
0
      address = file->FullAddress;
1710
1711
0
    if (address)
1712
0
    {
1713
0
      int port = -1;
1714
0
      char* host = NULL;
1715
1716
0
      if (!freerdp_parse_hostname(address, &host, &port))
1717
0
        return FALSE;
1718
1719
0
      const BOOL rc = freerdp_settings_set_string(settings, FreeRDP_ServerHostname, host);
1720
0
      free(host);
1721
0
      if (!rc)
1722
0
        return FALSE;
1723
1724
0
      if (port > 0)
1725
0
      {
1726
0
        if (!freerdp_settings_set_uint32(settings, FreeRDP_ServerPort, (UINT32)port))
1727
0
          return FALSE;
1728
0
      }
1729
0
    }
1730
0
  }
1731
1732
0
  if (~file->ServerPort)
1733
0
  {
1734
0
    if (!freerdp_settings_set_uint32(settings, FreeRDP_ServerPort, file->ServerPort))
1735
0
      return FALSE;
1736
0
  }
1737
1738
0
  if (~file->DesktopSizeId)
1739
0
  {
1740
0
    switch (file->DesktopSizeId)
1741
0
    {
1742
0
      case 0:
1743
0
        if (!freerdp_settings_set_uint32(settings, FreeRDP_DesktopWidth, 640))
1744
0
          return FALSE;
1745
0
        if (!freerdp_settings_set_uint32(settings, FreeRDP_DesktopHeight, 480))
1746
0
          return FALSE;
1747
0
        break;
1748
0
      case 1:
1749
0
        if (!freerdp_settings_set_uint32(settings, FreeRDP_DesktopWidth, 800))
1750
0
          return FALSE;
1751
0
        if (!freerdp_settings_set_uint32(settings, FreeRDP_DesktopHeight, 600))
1752
0
          return FALSE;
1753
0
        break;
1754
0
      case 2:
1755
0
        if (!freerdp_settings_set_uint32(settings, FreeRDP_DesktopWidth, 1024))
1756
0
          return FALSE;
1757
0
        if (!freerdp_settings_set_uint32(settings, FreeRDP_DesktopHeight, 768))
1758
0
          return FALSE;
1759
0
        break;
1760
0
      case 3:
1761
0
        if (!freerdp_settings_set_uint32(settings, FreeRDP_DesktopWidth, 1280))
1762
0
          return FALSE;
1763
0
        if (!freerdp_settings_set_uint32(settings, FreeRDP_DesktopHeight, 1024))
1764
0
          return FALSE;
1765
0
        break;
1766
0
      case 4:
1767
0
        if (!freerdp_settings_set_uint32(settings, FreeRDP_DesktopWidth, 1600))
1768
0
          return FALSE;
1769
0
        if (!freerdp_settings_set_uint32(settings, FreeRDP_DesktopHeight, 1200))
1770
0
          return FALSE;
1771
0
        break;
1772
0
      default:
1773
0
        WLog_WARN(TAG, "Unsupported 'desktop size id' value %" PRIu32, file->DesktopSizeId);
1774
0
        break;
1775
0
    }
1776
0
  }
1777
0
  if (~file->DesktopWidth)
1778
0
  {
1779
0
    if (!freerdp_settings_set_uint32(settings, FreeRDP_DesktopWidth, file->DesktopWidth))
1780
0
      return FALSE;
1781
0
  }
1782
1783
0
  if (~file->DesktopHeight)
1784
0
  {
1785
0
    if (!freerdp_settings_set_uint32(settings, FreeRDP_DesktopHeight, file->DesktopHeight))
1786
0
      return FALSE;
1787
0
  }
1788
1789
0
  if (~file->SessionBpp)
1790
0
  {
1791
0
    if (!freerdp_settings_set_uint32(settings, FreeRDP_ColorDepth, file->SessionBpp))
1792
0
      return FALSE;
1793
0
  }
1794
1795
0
  if (~file->ConnectToConsole)
1796
0
  {
1797
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_ConsoleSession,
1798
0
                                   file->ConnectToConsole != 0))
1799
0
      return FALSE;
1800
0
  }
1801
1802
0
  if (~file->AdministrativeSession)
1803
0
  {
1804
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_ConsoleSession,
1805
0
                                   file->AdministrativeSession != 0))
1806
0
      return FALSE;
1807
0
  }
1808
1809
0
  if (~file->NegotiateSecurityLayer)
1810
0
  {
1811
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_NegotiateSecurityLayer,
1812
0
                                   file->NegotiateSecurityLayer != 0))
1813
0
      return FALSE;
1814
0
  }
1815
1816
0
  if (~file->EnableCredSSPSupport)
1817
0
  {
1818
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_NlaSecurity,
1819
0
                                   file->EnableCredSSPSupport != 0))
1820
0
      return FALSE;
1821
0
  }
1822
1823
0
  if (~file->EnableRdsAadAuth)
1824
0
  {
1825
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_AadSecurity, file->EnableRdsAadAuth != 0))
1826
0
      return FALSE;
1827
0
  }
1828
1829
0
  if (~((size_t)file->AlternateShell))
1830
0
  {
1831
0
    if (!freerdp_settings_set_string(settings, FreeRDP_AlternateShell, file->AlternateShell))
1832
0
      return FALSE;
1833
0
  }
1834
1835
0
  if (~((size_t)file->ShellWorkingDirectory))
1836
0
  {
1837
    /* ShellWorkingDir is used for either, shell working dir or remote app working dir */
1838
0
    FreeRDP_Settings_Keys_String targetId =
1839
0
        (~file->RemoteApplicationMode && file->RemoteApplicationMode != 0)
1840
0
            ? FreeRDP_RemoteApplicationWorkingDir
1841
0
            : FreeRDP_ShellWorkingDirectory;
1842
1843
0
    if (!freerdp_settings_set_string(settings, targetId, file->ShellWorkingDirectory))
1844
0
      return FALSE;
1845
0
  }
1846
1847
0
  if (~file->ScreenModeId)
1848
0
  {
1849
    /**
1850
     * Screen Mode Id:
1851
     * http://technet.microsoft.com/en-us/library/ff393692/
1852
     *
1853
     * This setting corresponds to the selection in the Display
1854
     * configuration slider on the Display tab under Options in RDC.
1855
     *
1856
     * Values:
1857
     *
1858
     * 1: The remote session will appear in a window.
1859
     * 2: The remote session will appear full screen.
1860
     */
1861
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_Fullscreen,
1862
0
                                   (file->ScreenModeId == 2) ? TRUE : FALSE))
1863
0
      return FALSE;
1864
0
  }
1865
1866
0
  if (~(file->SmartSizing))
1867
0
  {
1868
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_SmartSizing,
1869
0
                                   (file->SmartSizing == 1) ? TRUE : FALSE))
1870
0
      return FALSE;
1871
    /**
1872
     *  SmartSizingWidth and SmartSizingHeight:
1873
     *
1874
     *  Adding this option to use the DesktopHeight and DesktopWidth as
1875
     *  parameters for the SmartSizingWidth and SmartSizingHeight, as there
1876
     *  are no options for that in standard RDP files.
1877
     *
1878
     *  Equivalent of doing /smart-sizing:WxH
1879
     */
1880
0
    if (((~(file->DesktopWidth) && ~(file->DesktopHeight)) || ~(file->DesktopSizeId)) &&
1881
0
        (file->SmartSizing == 1))
1882
0
    {
1883
0
      if (!freerdp_settings_set_uint32(settings, FreeRDP_SmartSizingWidth,
1884
0
                                       file->DesktopWidth))
1885
0
        return FALSE;
1886
0
      if (!freerdp_settings_set_uint32(settings, FreeRDP_SmartSizingHeight,
1887
0
                                       file->DesktopHeight))
1888
0
        return FALSE;
1889
0
    }
1890
0
  }
1891
1892
0
  if (~((size_t)file->LoadBalanceInfo))
1893
0
  {
1894
0
    const size_t len = strlen(file->LoadBalanceInfo);
1895
0
    if (!freerdp_settings_set_pointer_len(settings, FreeRDP_LoadBalanceInfo,
1896
0
                                          file->LoadBalanceInfo, len))
1897
0
      return FALSE;
1898
0
  }
1899
1900
0
  if (~file->AuthenticationLevel)
1901
0
  {
1902
    /**
1903
     * Authentication Level:
1904
     * http://technet.microsoft.com/en-us/library/ff393709/
1905
     *
1906
     * This setting corresponds to the selection in the If server authentication
1907
     * fails drop-down list on the Advanced tab under Options in RDC.
1908
     *
1909
     * Values:
1910
     *
1911
     * 0: If server authentication fails, connect to the computer without warning (Connect and
1912
     * don’t warn me). 1: If server authentication fails, do not establish a connection (Do not
1913
     * connect). 2: If server authentication fails, show a warning and allow me to connect or
1914
     * refuse the connection (Warn me). 3: No authentication requirement is specified.
1915
     */
1916
0
    if (!freerdp_settings_set_uint32(settings, FreeRDP_AuthenticationLevel,
1917
0
                                     file->AuthenticationLevel))
1918
0
      return FALSE;
1919
0
  }
1920
1921
0
  if (~file->ConnectionType)
1922
0
  {
1923
0
    if (!freerdp_set_connection_type(settings, file->ConnectionType))
1924
0
      return FALSE;
1925
0
    setDefaultConnectionType = FALSE;
1926
0
  }
1927
1928
0
  if (~file->AudioMode)
1929
0
  {
1930
0
    switch (file->AudioMode)
1931
0
    {
1932
0
      case AUDIO_MODE_REDIRECT:
1933
0
        if (!freerdp_settings_set_bool(settings, FreeRDP_RemoteConsoleAudio, FALSE))
1934
0
          return FALSE;
1935
0
        if (!freerdp_settings_set_bool(settings, FreeRDP_AudioPlayback, TRUE))
1936
0
          return FALSE;
1937
0
        break;
1938
0
      case AUDIO_MODE_PLAY_ON_SERVER:
1939
0
        if (!freerdp_settings_set_bool(settings, FreeRDP_RemoteConsoleAudio, TRUE))
1940
0
          return FALSE;
1941
0
        if (!freerdp_settings_set_bool(settings, FreeRDP_AudioPlayback, FALSE))
1942
0
          return FALSE;
1943
0
        break;
1944
0
      case AUDIO_MODE_NONE:
1945
0
      default:
1946
0
        if (!freerdp_settings_set_bool(settings, FreeRDP_AudioPlayback, FALSE))
1947
0
          return FALSE;
1948
0
        if (!freerdp_settings_set_bool(settings, FreeRDP_RemoteConsoleAudio, FALSE))
1949
0
          return FALSE;
1950
0
        break;
1951
0
    }
1952
0
  }
1953
1954
0
  if (~file->AudioCaptureMode)
1955
0
  {
1956
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_AudioCapture, file->AudioCaptureMode != 0))
1957
0
      return FALSE;
1958
0
  }
1959
1960
0
  if (~file->Compression)
1961
0
  {
1962
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_CompressionEnabled,
1963
0
                                   file->Compression != 0))
1964
0
      return FALSE;
1965
0
  }
1966
1967
0
  if (~((size_t)file->GatewayHostname))
1968
0
  {
1969
0
    int port = -1;
1970
0
    char* host = NULL;
1971
1972
0
    if (!freerdp_parse_hostname(file->GatewayHostname, &host, &port))
1973
0
      return FALSE;
1974
1975
0
    const BOOL rc = freerdp_settings_set_string(settings, FreeRDP_GatewayHostname, host);
1976
0
    free(host);
1977
0
    if (!rc)
1978
0
      return FALSE;
1979
1980
0
    if (port > 0)
1981
0
    {
1982
0
      if (!freerdp_settings_set_uint32(settings, FreeRDP_GatewayPort, (UINT32)port))
1983
0
        return FALSE;
1984
0
    }
1985
0
  }
1986
1987
0
  if (~((size_t)file->ResourceProvider))
1988
0
  {
1989
0
    if (_stricmp(file->ResourceProvider, str_resourceprovider_arm) == 0)
1990
0
    {
1991
0
      if (!freerdp_settings_set_bool(settings, FreeRDP_GatewayArmTransport, TRUE))
1992
0
        return FALSE;
1993
0
    }
1994
0
  }
1995
1996
0
  if (~((size_t)file->WvdEndpointPool))
1997
0
  {
1998
0
    if (!freerdp_settings_set_string(settings, FreeRDP_GatewayAvdWvdEndpointPool,
1999
0
                                     file->WvdEndpointPool))
2000
0
      return FALSE;
2001
0
  }
2002
2003
0
  if (~((size_t)file->geo))
2004
0
  {
2005
0
    if (!freerdp_settings_set_string(settings, FreeRDP_GatewayAvdGeo, file->geo))
2006
0
      return FALSE;
2007
0
  }
2008
2009
0
  if (~((size_t)file->armpath))
2010
0
  {
2011
0
    if (!freerdp_settings_set_string(settings, FreeRDP_GatewayAvdArmpath, file->armpath))
2012
0
      return FALSE;
2013
0
  }
2014
2015
0
  if (~((size_t)file->aadtenantid))
2016
0
  {
2017
0
    if (!freerdp_settings_set_string(settings, FreeRDP_GatewayAvdAadtenantid,
2018
0
                                     file->aadtenantid))
2019
0
      return FALSE;
2020
0
  }
2021
2022
0
  if (~((size_t)file->diagnosticserviceurl))
2023
0
  {
2024
0
    if (!freerdp_settings_set_string(settings, FreeRDP_GatewayAvdDiagnosticserviceurl,
2025
0
                                     file->diagnosticserviceurl))
2026
0
      return FALSE;
2027
0
  }
2028
2029
0
  if (~((size_t)file->hubdiscoverygeourl))
2030
0
  {
2031
0
    if (!freerdp_settings_set_string(settings, FreeRDP_GatewayAvdHubdiscoverygeourl,
2032
0
                                     file->hubdiscoverygeourl))
2033
0
      return FALSE;
2034
0
  }
2035
2036
0
  if (~((size_t)file->activityhint))
2037
0
  {
2038
0
    if (!freerdp_settings_set_string(settings, FreeRDP_GatewayAvdActivityhint,
2039
0
                                     file->activityhint))
2040
0
      return FALSE;
2041
0
  }
2042
2043
0
  if (~((size_t)file->GatewayAccessToken))
2044
0
  {
2045
0
    if (!freerdp_settings_set_string(settings, FreeRDP_GatewayAccessToken,
2046
0
                                     file->GatewayAccessToken))
2047
0
      return FALSE;
2048
0
  }
2049
2050
0
  if (~file->GatewayUsageMethod)
2051
0
  {
2052
0
    if (!freerdp_set_gateway_usage_method(settings, file->GatewayUsageMethod))
2053
0
      return FALSE;
2054
0
  }
2055
2056
0
  if (~file->PromptCredentialOnce)
2057
0
  {
2058
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_GatewayUseSameCredentials,
2059
0
                                   file->PromptCredentialOnce != 0))
2060
0
      return FALSE;
2061
0
  }
2062
2063
0
  if (~file->PromptForCredentials)
2064
0
  {
2065
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_PromptForCredentials,
2066
0
                                   file->PromptForCredentials != 0))
2067
0
      return FALSE;
2068
0
  }
2069
2070
0
  if (~file->RemoteApplicationMode)
2071
0
  {
2072
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_RemoteApplicationMode,
2073
0
                                   file->RemoteApplicationMode != 0))
2074
0
      return FALSE;
2075
0
  }
2076
2077
0
  if (~((size_t)file->RemoteApplicationProgram))
2078
0
  {
2079
0
    if (!freerdp_settings_set_string(settings, FreeRDP_RemoteApplicationProgram,
2080
0
                                     file->RemoteApplicationProgram))
2081
0
      return FALSE;
2082
0
  }
2083
2084
0
  if (~((size_t)file->RemoteApplicationName))
2085
0
  {
2086
0
    if (!freerdp_settings_set_string(settings, FreeRDP_RemoteApplicationName,
2087
0
                                     file->RemoteApplicationName))
2088
0
      return FALSE;
2089
0
  }
2090
2091
0
  if (~((size_t)file->RemoteApplicationIcon))
2092
0
  {
2093
0
    if (!freerdp_settings_set_string(settings, FreeRDP_RemoteApplicationIcon,
2094
0
                                     file->RemoteApplicationIcon))
2095
0
      return FALSE;
2096
0
  }
2097
2098
0
  if (~((size_t)file->RemoteApplicationFile))
2099
0
  {
2100
0
    if (!freerdp_settings_set_string(settings, FreeRDP_RemoteApplicationFile,
2101
0
                                     file->RemoteApplicationFile))
2102
0
      return FALSE;
2103
0
  }
2104
2105
0
  if (~((size_t)file->RemoteApplicationGuid))
2106
0
  {
2107
0
    if (!freerdp_settings_set_string(settings, FreeRDP_RemoteApplicationGuid,
2108
0
                                     file->RemoteApplicationGuid))
2109
0
      return FALSE;
2110
0
  }
2111
2112
0
  if (~((size_t)file->RemoteApplicationCmdLine))
2113
0
  {
2114
0
    if (!freerdp_settings_set_string(settings, FreeRDP_RemoteApplicationCmdLine,
2115
0
                                     file->RemoteApplicationCmdLine))
2116
0
      return FALSE;
2117
0
  }
2118
2119
0
  if (~file->SpanMonitors)
2120
0
  {
2121
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_SpanMonitors, file->SpanMonitors != 0))
2122
0
      return FALSE;
2123
0
  }
2124
2125
0
  if (~file->UseMultiMon)
2126
0
  {
2127
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_UseMultimon, file->UseMultiMon != 0))
2128
0
      return FALSE;
2129
0
  }
2130
2131
0
  if (~file->AllowFontSmoothing)
2132
0
  {
2133
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_AllowFontSmoothing,
2134
0
                                   file->AllowFontSmoothing != 0))
2135
0
      return FALSE;
2136
0
  }
2137
2138
0
  if (~file->DisableWallpaper)
2139
0
  {
2140
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_DisableWallpaper,
2141
0
                                   file->DisableWallpaper != 0))
2142
0
      return FALSE;
2143
0
  }
2144
2145
0
  if (~file->DisableFullWindowDrag)
2146
0
  {
2147
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_DisableFullWindowDrag,
2148
0
                                   file->DisableFullWindowDrag != 0))
2149
0
      return FALSE;
2150
0
  }
2151
2152
0
  if (~file->DisableMenuAnims)
2153
0
  {
2154
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_DisableMenuAnims,
2155
0
                                   file->DisableMenuAnims != 0))
2156
0
      return FALSE;
2157
0
  }
2158
2159
0
  if (~file->DisableThemes)
2160
0
  {
2161
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_DisableThemes, file->DisableThemes != 0))
2162
0
      return FALSE;
2163
0
  }
2164
2165
0
  if (~file->AllowDesktopComposition)
2166
0
  {
2167
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_AllowDesktopComposition,
2168
0
                                   file->AllowDesktopComposition != 0))
2169
0
      return FALSE;
2170
0
  }
2171
2172
0
  if (~file->BitmapCachePersistEnable)
2173
0
  {
2174
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_BitmapCachePersistEnabled,
2175
0
                                   file->BitmapCachePersistEnable != 0))
2176
0
      return FALSE;
2177
0
  }
2178
2179
0
  if (~file->DisableRemoteAppCapsCheck)
2180
0
  {
2181
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_DisableRemoteAppCapsCheck,
2182
0
                                   file->DisableRemoteAppCapsCheck != 0))
2183
0
      return FALSE;
2184
0
  }
2185
2186
0
  if (~file->BandwidthAutoDetect)
2187
0
  {
2188
0
    if (file->BandwidthAutoDetect != 0)
2189
0
    {
2190
0
      if ((~file->NetworkAutoDetect) && (file->NetworkAutoDetect == 0))
2191
0
      {
2192
0
        WLog_WARN(TAG,
2193
0
                  "Got networkautodetect:i:%" PRIu32 " and bandwidthautodetect:i:%" PRIu32
2194
0
                  ". Correcting to networkautodetect:i:1",
2195
0
                  file->NetworkAutoDetect, file->BandwidthAutoDetect);
2196
0
        WLog_WARN(TAG,
2197
0
                  "Add networkautodetect:i:1 to your RDP file to eliminate this warning.");
2198
0
      }
2199
2200
0
      if (!freerdp_set_connection_type(settings, CONNECTION_TYPE_AUTODETECT))
2201
0
        return FALSE;
2202
0
      setDefaultConnectionType = FALSE;
2203
0
    }
2204
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_NetworkAutoDetect,
2205
0
                                   (file->BandwidthAutoDetect != 0) ||
2206
0
                                       (file->NetworkAutoDetect != 0)))
2207
0
      return FALSE;
2208
0
  }
2209
2210
0
  if (~file->NetworkAutoDetect)
2211
0
  {
2212
0
    if (file->NetworkAutoDetect != 0)
2213
0
    {
2214
0
      if ((~file->BandwidthAutoDetect) && (file->BandwidthAutoDetect == 0))
2215
0
      {
2216
0
        WLog_WARN(TAG,
2217
0
                  "Got networkautodetect:i:%" PRIu32 " and bandwidthautodetect:i:%" PRIu32
2218
0
                  ". Correcting to bandwidthautodetect:i:1",
2219
0
                  file->NetworkAutoDetect, file->BandwidthAutoDetect);
2220
0
        WLog_WARN(
2221
0
            TAG, "Add bandwidthautodetect:i:1 to your RDP file to eliminate this warning.");
2222
0
      }
2223
2224
0
      if (!freerdp_set_connection_type(settings, CONNECTION_TYPE_AUTODETECT))
2225
0
        return FALSE;
2226
2227
0
      setDefaultConnectionType = FALSE;
2228
0
    }
2229
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_NetworkAutoDetect,
2230
0
                                   (file->BandwidthAutoDetect != 0) ||
2231
0
                                       (file->NetworkAutoDetect != 0)))
2232
0
      return FALSE;
2233
0
  }
2234
2235
0
  if (~file->AutoReconnectionEnabled)
2236
0
  {
2237
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_AutoReconnectionEnabled,
2238
0
                                   file->AutoReconnectionEnabled != 0))
2239
0
      return FALSE;
2240
0
  }
2241
2242
0
  if (~file->AutoReconnectMaxRetries)
2243
0
  {
2244
0
    if (!freerdp_settings_set_uint32(settings, FreeRDP_AutoReconnectMaxRetries,
2245
0
                                     file->AutoReconnectMaxRetries))
2246
0
      return FALSE;
2247
0
  }
2248
2249
0
  if (~file->RedirectSmartCards)
2250
0
  {
2251
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectSmartCards,
2252
0
                                   file->RedirectSmartCards != 0))
2253
0
      return FALSE;
2254
0
  }
2255
2256
0
  if (~file->RedirectWebauthN)
2257
0
  {
2258
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectWebAuthN,
2259
0
                                   file->RedirectWebauthN != 0))
2260
0
      return FALSE;
2261
0
  }
2262
2263
0
  if (~file->RedirectClipboard)
2264
0
  {
2265
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectClipboard,
2266
0
                                   file->RedirectClipboard != 0))
2267
0
      return FALSE;
2268
0
  }
2269
2270
0
  if (~file->RedirectPrinters)
2271
0
  {
2272
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectPrinters,
2273
0
                                   file->RedirectPrinters != 0))
2274
0
      return FALSE;
2275
0
  }
2276
2277
0
  if (~file->RedirectDrives)
2278
0
  {
2279
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectDrives, file->RedirectDrives != 0))
2280
0
      return FALSE;
2281
0
  }
2282
2283
0
  if (~file->RedirectPosDevices)
2284
0
  {
2285
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectSerialPorts,
2286
0
                                   file->RedirectComPorts != 0) ||
2287
0
        !freerdp_settings_set_bool(settings, FreeRDP_RedirectParallelPorts,
2288
0
                                   file->RedirectComPorts != 0))
2289
0
      return FALSE;
2290
0
  }
2291
2292
0
  if (~file->RedirectComPorts)
2293
0
  {
2294
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectSerialPorts,
2295
0
                                   file->RedirectComPorts != 0) ||
2296
0
        !freerdp_settings_set_bool(settings, FreeRDP_RedirectParallelPorts,
2297
0
                                   file->RedirectComPorts != 0))
2298
0
      return FALSE;
2299
0
  }
2300
2301
0
  if (~file->RedirectLocation && file->RedirectLocation != 0)
2302
0
  {
2303
0
    size_t count = 0;
2304
0
    union
2305
0
    {
2306
0
      void* pv;
2307
0
      char** str;
2308
0
      const char** cstr;
2309
0
    } cnv;
2310
0
    cnv.str = CommandLineParseCommaSeparatedValuesEx(LOCATION_CHANNEL_NAME, NULL, &count);
2311
0
    const BOOL rc = freerdp_client_add_dynamic_channel(settings, count, cnv.cstr);
2312
0
    free(cnv.pv);
2313
0
    if (!rc)
2314
0
      return FALSE;
2315
0
  }
2316
2317
0
  if (~file->RedirectDirectX)
2318
0
  {
2319
    /* What is this?! */
2320
0
  }
2321
2322
0
  if (~((size_t)file->DevicesToRedirect))
2323
0
  {
2324
    /**
2325
     * Devices to redirect:
2326
     * http://technet.microsoft.com/en-us/library/ff393728/
2327
     *
2328
     * This setting corresponds to the selections for Other supported Plug and Play
2329
     * (PnP) devices under More on the Local Resources tab under Options in RDC.
2330
     *
2331
     * Values:
2332
     *
2333
     * '*':
2334
     *  Redirect all supported Plug and Play devices.
2335
     *
2336
     * 'DynamicDevices':
2337
     *  Redirect any supported Plug and Play devices that are connected later.
2338
     *
2339
     * The hardware ID for the supported Plug and Play device:
2340
     *  Redirect the specified supported Plug and Play device.
2341
     *
2342
     * Examples:
2343
     *  devicestoredirect:s:*
2344
     *  devicestoredirect:s:DynamicDevices
2345
     *  devicestoredirect:s:USB\VID_04A9&PID_30C1\6&4BD985D&0&2;,DynamicDevices
2346
     *
2347
     */
2348
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_DeviceRedirection, TRUE))
2349
0
      return FALSE;
2350
0
  }
2351
2352
0
  if (~((size_t)file->DrivesToRedirect))
2353
0
  {
2354
0
    if (!freerdp_settings_set_string(settings, FreeRDP_DrivesToRedirect,
2355
0
                                     file->DrivesToRedirect))
2356
0
      return FALSE;
2357
0
  }
2358
2359
0
  if (~((size_t)file->RedirectCameras))
2360
0
  {
2361
#if defined(CHANNEL_RDPECAM_CLIENT)
2362
    union
2363
    {
2364
      char** c;
2365
      const char** cc;
2366
    } cnv;
2367
    ADDIN_ARGV* args = rdp_file_to_args(RDPECAM_DVC_CHANNEL_NAME, file->RedirectCameras);
2368
    if (!args)
2369
      return FALSE;
2370
2371
    if (~file->EncodeRedirectedVideoCapture)
2372
    {
2373
      char encode[64];
2374
      _snprintf(encode, sizeof(encode), "encode:%" PRIu32,
2375
                file->EncodeRedirectedVideoCapture);
2376
      freerdp_addin_argv_add_argument(args, encode);
2377
    }
2378
    if (~file->RedirectedVideoCaptureEncodingQuality)
2379
    {
2380
      char quality[64];
2381
      _snprintf(quality, sizeof(quality), "quality:%" PRIu32,
2382
                file->RedirectedVideoCaptureEncodingQuality);
2383
      freerdp_addin_argv_add_argument(args, quality);
2384
    }
2385
2386
    cnv.c = args->argv;
2387
    const BOOL status = freerdp_client_add_dynamic_channel(settings, args->argc, cnv.cc);
2388
    freerdp_addin_argv_free(args);
2389
    if (!status)
2390
      return FALSE;
2391
#else
2392
0
    WLog_WARN(
2393
0
        TAG,
2394
0
        "This build does not support [MS-RDPECAM] camera redirection channel. Ignoring '%s'",
2395
0
        key_str_camerastoredirect);
2396
0
#endif
2397
0
  }
2398
2399
0
  if (~((size_t)file->UsbDevicesToRedirect))
2400
0
  {
2401
#ifdef CHANNEL_URBDRC_CLIENT
2402
    union
2403
    {
2404
      char** c;
2405
      const char** cc;
2406
    } cnv;
2407
    ADDIN_ARGV* args = rdp_file_to_args(URBDRC_CHANNEL_NAME, file->UsbDevicesToRedirect);
2408
    if (!args)
2409
      return FALSE;
2410
    cnv.c = args->argv;
2411
    const BOOL status = freerdp_client_add_dynamic_channel(settings, args->argc, cnv.cc);
2412
    freerdp_addin_argv_free(args);
2413
    if (!status)
2414
      return FALSE;
2415
#else
2416
0
    WLog_WARN(TAG,
2417
0
              "This build does not support [MS-RDPEUSB] usb redirection channel. Ignoring '%s'",
2418
0
              key_str_usbdevicestoredirect);
2419
0
#endif
2420
0
  }
2421
2422
0
  if (~file->KeyboardHook)
2423
0
  {
2424
0
    if (!freerdp_settings_set_uint32(settings, FreeRDP_KeyboardHook, file->KeyboardHook))
2425
0
      return FALSE;
2426
0
  }
2427
2428
0
  if (~(size_t)file->SelectedMonitors)
2429
0
  {
2430
0
    size_t count = 0;
2431
0
    char** args = CommandLineParseCommaSeparatedValues(file->SelectedMonitors, &count);
2432
0
    UINT32* list = NULL;
2433
2434
0
    if (!freerdp_settings_set_pointer_len(settings, FreeRDP_MonitorIds, NULL, count))
2435
0
    {
2436
0
      free(args);
2437
0
      return FALSE;
2438
0
    }
2439
0
    list = freerdp_settings_get_pointer_writable(settings, FreeRDP_MonitorIds);
2440
0
    if (!list && (count > 0))
2441
0
    {
2442
0
      free(args);
2443
0
      return FALSE;
2444
0
    }
2445
0
    for (size_t x = 0; x < count; x++)
2446
0
    {
2447
0
      unsigned long val = 0;
2448
0
      errno = 0;
2449
0
      val = strtoul(args[x], NULL, 0);
2450
0
      if ((val >= UINT32_MAX) && (errno != 0))
2451
0
      {
2452
0
        free(args);
2453
0
        free(list);
2454
0
        return FALSE;
2455
0
      }
2456
0
      list[x] = val;
2457
0
    }
2458
0
    free(args);
2459
0
  }
2460
2461
0
  if (~file->DynamicResolution)
2462
0
  {
2463
0
    const BOOL val = file->DynamicResolution != 0;
2464
0
    if (val)
2465
0
    {
2466
0
      if (!freerdp_settings_set_bool(settings, FreeRDP_SupportDisplayControl, TRUE))
2467
0
        return FALSE;
2468
0
    }
2469
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_DynamicResolutionUpdate, val))
2470
0
      return FALSE;
2471
0
  }
2472
2473
0
  if (~file->DesktopScaleFactor)
2474
0
  {
2475
0
    if (!freerdp_settings_set_uint32(settings, FreeRDP_DesktopScaleFactor,
2476
0
                                     file->DesktopScaleFactor))
2477
0
      return FALSE;
2478
0
  }
2479
2480
0
  if (~file->VideoPlaybackMode)
2481
0
  {
2482
0
    if (file->VideoPlaybackMode != 0)
2483
0
    {
2484
0
      if (!freerdp_settings_set_bool(settings, FreeRDP_SupportGeometryTracking, TRUE) ||
2485
0
          !freerdp_settings_set_bool(settings, FreeRDP_SupportVideoOptimized, TRUE))
2486
0
        return FALSE;
2487
0
    }
2488
0
    else
2489
0
    {
2490
0
      if (!freerdp_settings_set_bool(settings, FreeRDP_SupportVideoOptimized, FALSE))
2491
0
        return FALSE;
2492
0
    }
2493
0
  }
2494
  // TODO file->MaximizeToCurrentDisplays;
2495
  // TODO file->SingleMonInWindowedMode;
2496
  // TODO file->EncodeRedirectedVideoCapture;
2497
  // TODO file->RedirectedVideoCaptureEncodingQuality;
2498
2499
0
  if (~((size_t)file->PreconnectionBlob))
2500
0
  {
2501
0
    if (!freerdp_settings_set_string(settings, FreeRDP_PreconnectionBlob,
2502
0
                                     file->PreconnectionBlob) ||
2503
0
        !freerdp_settings_set_bool(settings, FreeRDP_SendPreconnectionPdu, TRUE))
2504
0
      return FALSE;
2505
0
  }
2506
2507
0
  if (~((size_t)file->KdcProxyName))
2508
0
  {
2509
0
    if (!freerdp_settings_set_string(settings, FreeRDP_KerberosKdcUrl, file->KdcProxyName))
2510
0
      return FALSE;
2511
0
  }
2512
2513
0
  if (~((size_t)file->RdgIsKdcProxy))
2514
0
  {
2515
0
    if (!freerdp_settings_set_bool(settings, FreeRDP_KerberosRdgIsProxy,
2516
0
                                   file->RdgIsKdcProxy != 0))
2517
0
      return FALSE;
2518
0
  }
2519
2520
0
  if (file->args->argc > 1)
2521
0
  {
2522
0
    WCHAR* ConnectionFile =
2523
0
        freerdp_settings_get_string_as_utf16(settings, FreeRDP_ConnectionFile, NULL);
2524
2525
0
    if (freerdp_client_settings_parse_command_line(settings, file->args->argc, file->args->argv,
2526
0
                                                   FALSE) < 0)
2527
0
    {
2528
0
      free(ConnectionFile);
2529
0
      return FALSE;
2530
0
    }
2531
2532
0
    BOOL rc = freerdp_settings_set_string_from_utf16(settings, FreeRDP_ConnectionFile,
2533
0
                                                     ConnectionFile);
2534
0
    free(ConnectionFile);
2535
0
    if (!rc)
2536
0
      return FALSE;
2537
0
  }
2538
2539
0
  if (setDefaultConnectionType)
2540
0
  {
2541
0
    if (!freerdp_set_connection_type(settings, CONNECTION_TYPE_AUTODETECT))
2542
0
      return FALSE;
2543
0
  }
2544
2545
0
  return TRUE;
2546
0
}
2547
2548
static rdpFileLine* freerdp_client_rdp_file_find_line_by_name(const rdpFile* file, const char* name)
2549
0
{
2550
0
  BOOL bFound = FALSE;
2551
0
  rdpFileLine* line = NULL;
2552
2553
0
  for (size_t index = 0; index < file->lineCount; index++)
2554
0
  {
2555
0
    line = &(file->lines[index]);
2556
2557
0
    if (line->flags & RDP_FILE_LINE_FLAG_FORMATTED)
2558
0
    {
2559
0
      if (_stricmp(name, line->name) == 0)
2560
0
      {
2561
0
        bFound = TRUE;
2562
0
        break;
2563
0
      }
2564
0
    }
2565
0
  }
2566
2567
0
  return (bFound) ? line : NULL;
2568
0
}
2569
/**
2570
 * Set a string option to a rdpFile
2571
 * @param file rdpFile
2572
 * @param name name of the option
2573
 * @param value value of the option
2574
 * @return 0 on success
2575
 */
2576
int freerdp_client_rdp_file_set_string_option(rdpFile* file, const char* name, const char* value)
2577
0
{
2578
0
  return freerdp_client_rdp_file_set_string(file, name, value);
2579
0
}
2580
2581
const char* freerdp_client_rdp_file_get_string_option(const rdpFile* file, const char* name)
2582
0
{
2583
0
  LPSTR* value = NULL;
2584
0
  rdpFileLine* line = NULL;
2585
2586
0
  if (freerdp_client_rdp_file_find_string_entry((rdpFile*)file, name, &value, &line))
2587
0
  {
2588
0
    if (value && ~(size_t)(*value))
2589
0
      return *value;
2590
0
    if (line)
2591
0
      return line->sValue;
2592
0
  }
2593
2594
0
  return NULL;
2595
0
}
2596
2597
int freerdp_client_rdp_file_set_integer_option(rdpFile* file, const char* name, int value)
2598
0
{
2599
0
  return freerdp_client_rdp_file_set_integer(file, name, value);
2600
0
}
2601
2602
int freerdp_client_rdp_file_get_integer_option(const rdpFile* file, const char* name)
2603
0
{
2604
0
  DWORD* value = NULL;
2605
0
  rdpFileLine* line = NULL;
2606
2607
0
  if (freerdp_client_rdp_file_find_integer_entry((rdpFile*)file, name, &value, &line))
2608
0
  {
2609
0
    if (value && ~(*value))
2610
0
      return *value;
2611
0
    if (line)
2612
0
      return (int)line->iValue;
2613
0
  }
2614
2615
0
  return -1;
2616
0
}
2617
2618
static void freerdp_client_file_string_check_free(LPSTR str)
2619
0
{
2620
0
  if (~((size_t)str))
2621
0
    free(str);
2622
0
}
2623
2624
rdpFile* freerdp_client_rdp_file_new(void)
2625
0
{
2626
0
  return freerdp_client_rdp_file_new_ex(0);
2627
0
}
2628
2629
rdpFile* freerdp_client_rdp_file_new_ex(DWORD flags)
2630
0
{
2631
0
  rdpFile* file = (rdpFile*)calloc(1, sizeof(rdpFile));
2632
2633
0
  if (!file)
2634
0
    return NULL;
2635
2636
0
  file->flags = flags;
2637
2638
0
  FillMemory(file, sizeof(rdpFile), 0xFF);
2639
0
  file->lines = NULL;
2640
0
  file->lineCount = 0;
2641
0
  file->lineSize = 32;
2642
0
  file->GatewayProfileUsageMethod = 1;
2643
0
  file->lines = (rdpFileLine*)calloc(file->lineSize, sizeof(rdpFileLine));
2644
2645
0
  file->args = freerdp_addin_argv_new(0, NULL);
2646
0
  if (!file->lines || !file->args)
2647
0
    goto fail;
2648
2649
0
  if (!freerdp_client_add_option(file, "freerdp"))
2650
0
    goto fail;
2651
2652
0
  return file;
2653
0
fail:
2654
0
  WINPR_PRAGMA_DIAG_PUSH
2655
0
  WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
2656
0
  freerdp_client_rdp_file_free(file);
2657
0
  WINPR_PRAGMA_DIAG_POP
2658
0
  return NULL;
2659
0
}
2660
void freerdp_client_rdp_file_free(rdpFile* file)
2661
0
{
2662
0
  if (file)
2663
0
  {
2664
0
    if (file->lineCount)
2665
0
    {
2666
0
      for (size_t i = 0; i < file->lineCount; i++)
2667
0
      {
2668
0
        free(file->lines[i].name);
2669
0
        free(file->lines[i].sValue);
2670
0
      }
2671
0
    }
2672
0
    free(file->lines);
2673
2674
0
    freerdp_addin_argv_free(file->args);
2675
2676
0
    freerdp_client_file_string_check_free(file->Username);
2677
0
    freerdp_client_file_string_check_free(file->Domain);
2678
0
    freerdp_client_file_string_check_free(file->Password);
2679
0
    freerdp_client_file_string_check_free(file->FullAddress);
2680
0
    freerdp_client_file_string_check_free(file->AlternateFullAddress);
2681
0
    freerdp_client_file_string_check_free(file->UsbDevicesToRedirect);
2682
0
    freerdp_client_file_string_check_free(file->RedirectCameras);
2683
0
    freerdp_client_file_string_check_free(file->SelectedMonitors);
2684
0
    freerdp_client_file_string_check_free(file->LoadBalanceInfo);
2685
0
    freerdp_client_file_string_check_free(file->RemoteApplicationName);
2686
0
    freerdp_client_file_string_check_free(file->RemoteApplicationIcon);
2687
0
    freerdp_client_file_string_check_free(file->RemoteApplicationProgram);
2688
0
    freerdp_client_file_string_check_free(file->RemoteApplicationFile);
2689
0
    freerdp_client_file_string_check_free(file->RemoteApplicationGuid);
2690
0
    freerdp_client_file_string_check_free(file->RemoteApplicationCmdLine);
2691
0
    freerdp_client_file_string_check_free(file->AlternateShell);
2692
0
    freerdp_client_file_string_check_free(file->ShellWorkingDirectory);
2693
0
    freerdp_client_file_string_check_free(file->GatewayHostname);
2694
0
    freerdp_client_file_string_check_free(file->GatewayAccessToken);
2695
0
    freerdp_client_file_string_check_free(file->KdcProxyName);
2696
0
    freerdp_client_file_string_check_free(file->DrivesToRedirect);
2697
0
    freerdp_client_file_string_check_free(file->DevicesToRedirect);
2698
0
    freerdp_client_file_string_check_free(file->WinPosStr);
2699
0
    freerdp_client_file_string_check_free(file->ResourceProvider);
2700
0
    freerdp_client_file_string_check_free(file->WvdEndpointPool);
2701
0
    freerdp_client_file_string_check_free(file->geo);
2702
0
    freerdp_client_file_string_check_free(file->armpath);
2703
0
    freerdp_client_file_string_check_free(file->aadtenantid);
2704
0
    freerdp_client_file_string_check_free(file->diagnosticserviceurl);
2705
0
    freerdp_client_file_string_check_free(file->hubdiscoverygeourl);
2706
0
    freerdp_client_file_string_check_free(file->activityhint);
2707
0
    free(file);
2708
0
  }
2709
0
}
2710
2711
void freerdp_client_rdp_file_set_callback_context(rdpFile* file, void* context)
2712
0
{
2713
0
  file->context = context;
2714
0
}