3#include <winpr/assert.h>
4#include <winpr/tchar.h>
5#include <winpr/cmdline.h>
6#include <winpr/strlst.h>
8static const char* testArgv[] = {
"mstsc.exe",
18 "/valuelist:value1,value2",
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",
26 "a:,\"b:xxx, yyy\",c",
29 "\"a,b,c,d d d,fff\"",
39static const char* testListArgs1[] = { testListAppName,
"a",
"b",
"c",
"d" };
40static const char* testListArgs2[] = { testListAppName,
"a:",
"b:xxx, yyy",
"c" };
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" };
50static const char* testListArgs12[] = { testListAppName,
"g:some.gateway.server",
51 "u:some\\\"user",
"p:some\\\"password",
52 "d:some\\\"domain",
"type:auto" };
54static const char** testListArgsResult[] = {
68static const size_t testListArgsCount[] = {
69 ARRAYSIZE(testListArgs12), ARRAYSIZE(testListArgs1),
70 ARRAYSIZE(testListArgs2), 0 ,
71 0 , ARRAYSIZE(testListArgs5),
72 ARRAYSIZE(testListArgs6), ARRAYSIZE(testListArgs7),
73 ARRAYSIZE(testListArgs8), ARRAYSIZE(testListArgs9),
78static BOOL checkResult(
size_t index,
char** actual,
size_t actualCount)
80 const char** result = testListArgsResult[index];
81 const size_t resultCount = testListArgsCount[index];
83 if (resultCount != actualCount)
88 return (actual ==
nullptr);
95 for (
size_t x = 0; x < actualCount; x++)
97 const char* a = result[x];
98 const char* b = actual[x];
100 if (strcmp(a, b) != 0)
108static BOOL TestCommandLineParseCommaSeparatedValuesEx(
void)
110 WINPR_ASSERT(ARRAYSIZE(testListArgs) == ARRAYSIZE(testListArgsResult));
111 WINPR_ASSERT(ARRAYSIZE(testListArgs) == ARRAYSIZE(testListArgsCount));
113 for (
size_t x = 0; x < ARRAYSIZE(testListArgs); x++)
121 const char* list = testListArgs[x];
123 ptr.pp = CommandLineParseCommaSeparatedValuesEx(testListAppName, list, &count);
124 BOOL valid = checkResult(x, ptr.pp, count);
133int TestCmdLine(
int argc,
char* argv[])
142 char** command_line =
nullptr;
144 {
"v", COMMAND_LINE_VALUE_REQUIRED,
nullptr,
nullptr,
nullptr, -1,
nullptr,
145 "destination server" },
146 {
"port", COMMAND_LINE_VALUE_REQUIRED,
nullptr,
nullptr,
nullptr, -1,
nullptr,
148 {
"w", COMMAND_LINE_VALUE_REQUIRED,
nullptr,
nullptr,
nullptr, -1,
nullptr,
"width" },
149 {
"h", COMMAND_LINE_VALUE_REQUIRED,
nullptr,
nullptr,
nullptr, -1,
nullptr,
"height" },
150 {
"f", COMMAND_LINE_VALUE_FLAG,
nullptr,
nullptr,
nullptr, -1,
nullptr,
"fullscreen" },
151 {
"bpp", COMMAND_LINE_VALUE_REQUIRED,
nullptr,
nullptr,
nullptr, -1,
nullptr,
152 "session bpp (color depth)" },
153 {
"admin", COMMAND_LINE_VALUE_FLAG,
nullptr,
nullptr,
nullptr, -1,
"console",
154 "admin (or console) session" },
155 {
"multimon", COMMAND_LINE_VALUE_FLAG,
nullptr,
nullptr,
nullptr, -1,
nullptr,
157 {
"a", COMMAND_LINE_VALUE_REQUIRED,
nullptr,
nullptr,
nullptr, -1,
"addin",
"addin" },
158 {
"u", COMMAND_LINE_VALUE_REQUIRED,
nullptr,
nullptr,
nullptr, -1,
nullptr,
"username" },
159 {
"p", COMMAND_LINE_VALUE_REQUIRED,
nullptr,
nullptr,
nullptr, -1,
nullptr,
"password" },
160 {
"d", COMMAND_LINE_VALUE_REQUIRED,
nullptr,
nullptr,
nullptr, -1,
nullptr,
"domain" },
161 {
"z", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueFalse,
nullptr, -1,
nullptr,
163 {
"audio", COMMAND_LINE_VALUE_REQUIRED,
nullptr,
nullptr,
nullptr, -1,
nullptr,
164 "audio output mode" },
165 {
"mic", COMMAND_LINE_VALUE_FLAG,
nullptr,
nullptr,
nullptr, -1,
nullptr,
166 "audio input (microphone)" },
167 {
"fonts", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueFalse,
nullptr, -1,
nullptr,
168 "smooth fonts (cleartype)" },
169 {
"aero", COMMAND_LINE_VALUE_BOOL,
nullptr,
nullptr, BoolValueFalse, -1,
nullptr,
170 "desktop composition" },
171 {
"window-drag", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueFalse,
nullptr, -1,
nullptr,
172 "full window drag" },
173 {
"menu-anims", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueFalse,
nullptr, -1,
nullptr,
175 {
"themes", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueTrue,
nullptr, -1,
nullptr,
177 {
"wallpaper", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueTrue,
nullptr, -1,
nullptr,
179 {
"codec", COMMAND_LINE_VALUE_REQUIRED,
nullptr,
nullptr,
nullptr, -1,
nullptr,
"codec" },
180 {
"nego", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueTrue,
nullptr, -1,
nullptr,
181 "protocol security negotiation" },
182 {
"sec", COMMAND_LINE_VALUE_REQUIRED,
nullptr,
nullptr,
nullptr, -1,
nullptr,
183 "force specific protocol security" },
184#if defined(WITH_FREERDP_DEPRECATED)
185 {
"sec-rdp", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueTrue,
nullptr, -1,
nullptr,
186 "rdp protocol security" },
187 {
"sec-tls", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueTrue,
nullptr, -1,
nullptr,
188 "tls protocol security" },
189 {
"sec-nla", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueTrue,
nullptr, -1,
nullptr,
190 "nla protocol security" },
191 {
"sec-ext", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueFalse,
nullptr, -1,
nullptr,
192 "nla extended protocol security" },
193 {
"cert-name", COMMAND_LINE_VALUE_REQUIRED,
nullptr,
nullptr,
nullptr, -1,
nullptr,
194 "certificate name" },
195 {
"cert-ignore", COMMAND_LINE_VALUE_FLAG,
nullptr,
nullptr,
nullptr, -1,
nullptr,
196 "ignore certificate" },
198 {
"valuelist", COMMAND_LINE_VALUE_REQUIRED,
"<val1>,<val2>",
nullptr,
nullptr, -1,
nullptr,
199 "List of comma separated values." },
200 {
"valuelist-empty", COMMAND_LINE_VALUE_REQUIRED,
"<val1>,<val2>",
nullptr,
nullptr, -1,
202 "List of comma separated values. Used to test correct behavior if an empty list was "
204 {
"version", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_VERSION,
nullptr,
nullptr,
205 nullptr, -1,
nullptr,
"print version" },
206 {
"help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP,
nullptr,
nullptr,
nullptr, -1,
208 {
nullptr, 0,
nullptr,
nullptr,
nullptr, -1,
nullptr,
nullptr }
214 flags = COMMAND_LINE_SIGIL_SLASH | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_SIGIL_PLUS_MINUS;
215 testArgc = string_list_length(testArgv);
216 command_line = string_list_copy(testArgv);
220 printf(
"Argument duplication failed (not enough memory?)\n");
225 CommandLineParseArgumentsA(testArgc, command_line, args, flags,
nullptr,
nullptr,
nullptr);
229 printf(
"CommandLineParseArgumentsA failure: %d\n", status);
233 arg = CommandLineFindArgumentA(args,
"w");
235 if (strcmp(
"1024", arg->Value) != 0)
237 printf(
"CommandLineFindArgumentA: unexpected %s value %s\n", arg->Name, arg->Value);
241 arg = CommandLineFindArgumentA(args,
"h");
243 if (strcmp(
"768", arg->Value) != 0)
245 printf(
"CommandLineFindArgumentA: unexpected %s value %s\n", arg->Name, arg->Value);
249 arg = CommandLineFindArgumentA(args,
"f");
253 printf(
"CommandLineFindArgumentA: unexpected %s value\n", arg->Name);
257 arg = CommandLineFindArgumentA(args,
"admin");
261 printf(
"CommandLineFindArgumentA: unexpected %s value\n", arg->Name);
265 arg = CommandLineFindArgumentA(args,
"multimon");
269 printf(
"CommandLineFindArgumentA: unexpected %s value\n", arg->Name);
273 arg = CommandLineFindArgumentA(args,
"v");
275 if (strcmp(
"localhost:3389", arg->Value) != 0)
277 printf(
"CommandLineFindArgumentA: unexpected %s value %s\n", arg->Name, arg->Value);
281 arg = CommandLineFindArgumentA(args,
"fonts");
285 printf(
"CommandLineFindArgumentA: unexpected %s value\n", arg->Name);
289 arg = CommandLineFindArgumentA(args,
"wallpaper");
293 printf(
"CommandLineFindArgumentA: unexpected %s value\n", arg->Name);
297 arg = CommandLineFindArgumentA(args,
"help");
301 printf(
"CommandLineFindArgumentA: unexpected %s value\n", arg->Name);
310 if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT))
313 printf(
"Argument: %s\n", arg->Name);
314 CommandLineSwitchStart(arg) CommandLineSwitchCase(arg,
"v")
317 CommandLineSwitchCase(arg,
"w")
319 width = strtol(arg->Value,
nullptr, 0);
324 CommandLineSwitchCase(arg,
"h")
326 height = strtol(arg->Value,
nullptr, 0);
331 CommandLineSwitchCase(arg,
"valuelist")
334 char** p = CommandLineParseCommaSeparatedValuesEx(arg->Name, arg->Value, &count);
337 if (!p || count != 3)
339 printf(
"CommandLineParseCommaSeparatedValuesEx: invalid p or count (%" PRIuz
345 CommandLineSwitchCase(arg,
"valuelist-empty")
348 char** p = CommandLineParseCommaSeparatedValuesEx(arg->Name, arg->Value, &count);
351 if (!p || count != 1)
353 printf(
"CommandLineParseCommaSeparatedValuesEx: invalid p or count (%" PRIuz
359 CommandLineSwitchDefault(arg)
362 CommandLineSwitchEnd(arg)
363 }
while ((arg = CommandLineFindNextArgumentA(arg)) !=
nullptr);
365 if ((width != 1024) || (height != 768))
367 printf(
"Unexpected width and height: Actual: (%ldx%ld), Expected: (1024x768)\n", width,
374 string_list_free(command_line);
376 if (!TestCommandLineParseCommaSeparatedValuesEx())