FreeRDP
Loading...
Searching...
No Matches
TestCmdLine.c
1#include <errno.h>
2#include <winpr/crt.h>
3#include <winpr/assert.h>
4#include <winpr/tchar.h>
5#include <winpr/cmdline.h>
6#include <winpr/strlst.h>
7
8static const char* testArgv[] = { "mstsc.exe",
9 "+z",
10 "/w:1024",
11 "/h:768",
12 "/bpp:32",
13 "/admin",
14 "/multimon",
15 "+fonts",
16 "-wallpaper",
17 "/v:localhost:3389",
18 "/valuelist:value1,value2",
19 "/valuelist-empty:",
20 0 };
21
22static const char testListAppName[] = "test app name";
23static const char* testListArgs[] = {
24 "g:some.gateway.server,u:some\\\"user,p:some\\\"password,d:some\\\"domain,type:auto",
25 "a,b,c,d",
26 "a:,\"b:xxx, yyy\",c",
27 "a:,,,b",
28 "a:,\",b",
29 "\"a,b,c,d d d,fff\"",
30 "",
31 NULL,
32 "'a,b,\",c'",
33 "\"a,b,',c\"",
34 "', a, ', b,c'",
35 "\"a,b,\",c\"",
36
37};
38
39static const char* testListArgs1[] = { testListAppName, "a", "b", "c", "d" };
40static const char* testListArgs2[] = { testListAppName, "a:", "b:xxx, yyy", "c" };
41// static const char* testListArgs3[] = {};
42// static const char* testListArgs4[] = {};
43static const char* testListArgs5[] = { testListAppName, "a", "b", "c", "d d d", "fff" };
44static const char* testListArgs6[] = { testListAppName };
45static const char* testListArgs7[] = { testListAppName };
46static const char* testListArgs8[] = { testListAppName, "a", "b", "\"", "c" };
47static const char* testListArgs9[] = { testListAppName, "a", "b", "'", "c" };
48// static const char* testListArgs10[] = {};
49// static const char* testListArgs11[] = {};
50static const char* testListArgs12[] = { testListAppName, "g:some.gateway.server",
51 "u:some\\\"user", "p:some\\\"password",
52 "d:some\\\"domain", "type:auto" };
53
54static const char** testListArgsResult[] = {
55 testListArgs12,
56 testListArgs1,
57 testListArgs2,
58 NULL /* testListArgs3 */,
59 NULL /* testListArgs4 */,
60 testListArgs5,
61 testListArgs6,
62 testListArgs7,
63 testListArgs8,
64 testListArgs9,
65 NULL /* testListArgs10 */,
66 NULL /* testListArgs11 */
67};
68static const size_t testListArgsCount[] = {
69 ARRAYSIZE(testListArgs12), ARRAYSIZE(testListArgs1),
70 ARRAYSIZE(testListArgs2), 0 /* ARRAYSIZE(testListArgs3) */,
71 0 /* ARRAYSIZE(testListArgs4) */, ARRAYSIZE(testListArgs5),
72 ARRAYSIZE(testListArgs6), ARRAYSIZE(testListArgs7),
73 ARRAYSIZE(testListArgs8), ARRAYSIZE(testListArgs9),
74 0 /* ARRAYSIZE(testListArgs10) */, 0 /* ARRAYSIZE(testListArgs11) */
75
76};
77
78static BOOL checkResult(size_t index, char** actual, size_t actualCount)
79{
80 const char** result = testListArgsResult[index];
81 const size_t resultCount = testListArgsCount[index];
82
83 if (resultCount != actualCount)
84 return FALSE;
85
86 if (actualCount == 0)
87 {
88 return (actual == NULL);
89 }
90 else
91 {
92 if (!actual)
93 return FALSE;
94
95 for (size_t x = 0; x < actualCount; x++)
96 {
97 const char* a = result[x];
98 const char* b = actual[x];
99
100 if (strcmp(a, b) != 0)
101 return FALSE;
102 }
103 }
104
105 return TRUE;
106}
107
108static BOOL TestCommandLineParseCommaSeparatedValuesEx(void)
109{
110 WINPR_ASSERT(ARRAYSIZE(testListArgs) == ARRAYSIZE(testListArgsResult));
111 WINPR_ASSERT(ARRAYSIZE(testListArgs) == ARRAYSIZE(testListArgsCount));
112
113 for (size_t x = 0; x < ARRAYSIZE(testListArgs); x++)
114 {
115 union
116 {
117 char* p;
118 char** pp;
119 const char** ppc;
120 } ptr;
121 const char* list = testListArgs[x];
122 size_t count = 42;
123 ptr.pp = CommandLineParseCommaSeparatedValuesEx(testListAppName, list, &count);
124 BOOL valid = checkResult(x, ptr.pp, count);
125 free(ptr.p);
126 if (!valid)
127 return FALSE;
128 }
129
130 return TRUE;
131}
132
133int TestCmdLine(int argc, char* argv[])
134{
135 int status = 0;
136 int ret = -1;
137 DWORD flags = 0;
138 long width = 0;
139 long height = 0;
140 const COMMAND_LINE_ARGUMENT_A* arg = NULL;
141 int testArgc = 0;
142 char** command_line = NULL;
143 COMMAND_LINE_ARGUMENT_A args[] = {
144 { "v", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "destination server" },
145 { "port", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "server port" },
146 { "w", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "width" },
147 { "h", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "height" },
148 { "f", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "fullscreen" },
149 { "bpp", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL,
150 "session bpp (color depth)" },
151 { "admin", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, "console",
152 "admin (or console) session" },
153 { "multimon", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "multi-monitor" },
154 { "a", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, "addin", "addin" },
155 { "u", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "username" },
156 { "p", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "password" },
157 { "d", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "domain" },
158 { "z", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "compression" },
159 { "audio", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "audio output mode" },
160 { "mic", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "audio input (microphone)" },
161 { "fonts", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL,
162 "smooth fonts (cleartype)" },
163 { "aero", COMMAND_LINE_VALUE_BOOL, NULL, NULL, BoolValueFalse, -1, NULL,
164 "desktop composition" },
165 { "window-drag", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL,
166 "full window drag" },
167 { "menu-anims", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL,
168 "menu animations" },
169 { "themes", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "themes" },
170 { "wallpaper", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "wallpaper" },
171 { "codec", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "codec" },
172 { "nego", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
173 "protocol security negotiation" },
174 { "sec", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL,
175 "force specific protocol security" },
176#if defined(WITH_FREERDP_DEPRECATED)
177 { "sec-rdp", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
178 "rdp protocol security" },
179 { "sec-tls", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
180 "tls protocol security" },
181 { "sec-nla", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
182 "nla protocol security" },
183 { "sec-ext", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL,
184 "nla extended protocol security" },
185 { "cert-name", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL,
186 "certificate name" },
187 { "cert-ignore", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL,
188 "ignore certificate" },
189#endif
190 { "valuelist", COMMAND_LINE_VALUE_REQUIRED, "<val1>,<val2>", NULL, NULL, -1, NULL,
191 "List of comma separated values." },
192 { "valuelist-empty", COMMAND_LINE_VALUE_REQUIRED, "<val1>,<val2>", NULL, NULL, -1, NULL,
193 "List of comma separated values. Used to test correct behavior if an empty list was "
194 "passed." },
195 { "version", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_VERSION, NULL, NULL, NULL, -1,
196 NULL, "print version" },
197 { "help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "?",
198 "print help" },
199 { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
200 };
201
202 WINPR_UNUSED(argc);
203 WINPR_UNUSED(argv);
204
205 flags = COMMAND_LINE_SIGIL_SLASH | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_SIGIL_PLUS_MINUS;
206 testArgc = string_list_length(testArgv);
207 command_line = string_list_copy(testArgv);
208
209 if (!command_line)
210 {
211 printf("Argument duplication failed (not enough memory?)\n");
212 return ret;
213 }
214
215 status = CommandLineParseArgumentsA(testArgc, command_line, args, flags, NULL, NULL, NULL);
216
217 if (status != 0)
218 {
219 printf("CommandLineParseArgumentsA failure: %d\n", status);
220 goto out;
221 }
222
223 arg = CommandLineFindArgumentA(args, "w");
224
225 if (strcmp("1024", arg->Value) != 0)
226 {
227 printf("CommandLineFindArgumentA: unexpected %s value %s\n", arg->Name, arg->Value);
228 goto out;
229 }
230
231 arg = CommandLineFindArgumentA(args, "h");
232
233 if (strcmp("768", arg->Value) != 0)
234 {
235 printf("CommandLineFindArgumentA: unexpected %s value %s\n", arg->Name, arg->Value);
236 goto out;
237 }
238
239 arg = CommandLineFindArgumentA(args, "f");
240
241 if (arg->Value)
242 {
243 printf("CommandLineFindArgumentA: unexpected %s value\n", arg->Name);
244 goto out;
245 }
246
247 arg = CommandLineFindArgumentA(args, "admin");
248
249 if (!arg->Value)
250 {
251 printf("CommandLineFindArgumentA: unexpected %s value\n", arg->Name);
252 goto out;
253 }
254
255 arg = CommandLineFindArgumentA(args, "multimon");
256
257 if (!arg->Value)
258 {
259 printf("CommandLineFindArgumentA: unexpected %s value\n", arg->Name);
260 goto out;
261 }
262
263 arg = CommandLineFindArgumentA(args, "v");
264
265 if (strcmp("localhost:3389", arg->Value) != 0)
266 {
267 printf("CommandLineFindArgumentA: unexpected %s value %s\n", arg->Name, arg->Value);
268 goto out;
269 }
270
271 arg = CommandLineFindArgumentA(args, "fonts");
272
273 if (!arg->Value)
274 {
275 printf("CommandLineFindArgumentA: unexpected %s value\n", arg->Name);
276 goto out;
277 }
278
279 arg = CommandLineFindArgumentA(args, "wallpaper");
280
281 if (arg->Value)
282 {
283 printf("CommandLineFindArgumentA: unexpected %s value\n", arg->Name);
284 goto out;
285 }
286
287 arg = CommandLineFindArgumentA(args, "help");
288
289 if (arg->Value)
290 {
291 printf("CommandLineFindArgumentA: unexpected %s value\n", arg->Name);
292 goto out;
293 }
294
295 arg = args;
296 errno = 0;
297
298 do
299 {
300 if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT))
301 continue;
302
303 printf("Argument: %s\n", arg->Name);
304 CommandLineSwitchStart(arg) CommandLineSwitchCase(arg, "v")
305 {
306 }
307 CommandLineSwitchCase(arg, "w")
308 {
309 width = strtol(arg->Value, NULL, 0);
310
311 if (errno != 0)
312 goto out;
313 }
314 CommandLineSwitchCase(arg, "h")
315 {
316 height = strtol(arg->Value, NULL, 0);
317
318 if (errno != 0)
319 goto out;
320 }
321 CommandLineSwitchCase(arg, "valuelist")
322 {
323 size_t count = 0;
324 char** p = CommandLineParseCommaSeparatedValuesEx(arg->Name, arg->Value, &count);
325 free((void*)p);
326
327 if (!p || count != 3)
328 {
329 printf("CommandLineParseCommaSeparatedValuesEx: invalid p or count (%" PRIuz
330 "!=3)\n",
331 count);
332 goto out;
333 }
334 }
335 CommandLineSwitchCase(arg, "valuelist-empty")
336 {
337 size_t count = 0;
338 char** p = CommandLineParseCommaSeparatedValuesEx(arg->Name, arg->Value, &count);
339 free((void*)p);
340
341 if (!p || count != 1)
342 {
343 printf("CommandLineParseCommaSeparatedValuesEx: invalid p or count (%" PRIuz
344 "!=1)\n",
345 count);
346 goto out;
347 }
348 }
349 CommandLineSwitchDefault(arg)
350 {
351 }
352 CommandLineSwitchEnd(arg)
353 } while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
354
355 if ((width != 1024) || (height != 768))
356 {
357 printf("Unexpected width and height: Actual: (%ldx%ld), Expected: (1024x768)\n", width,
358 height);
359 goto out;
360 }
361 ret = 0;
362
363out:
364 string_list_free(command_line);
365
366 if (!TestCommandLineParseCommaSeparatedValuesEx())
367 return -1;
368 return ret;
369}