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