1 #include <errno.h>
2 #include <winpr/crt.h>
3 #include <winpr/tchar.h>
4 #include <winpr/cmdline.h>
5 #include <winpr/strlst.h>
6 
7 static const char* testArgv[] = {
8 	"mstsc.exe", "+z",         "/w:1024",           "/h:768", "/bpp:32", "/admin", "/multimon",
9 	"+fonts",    "-wallpaper", "/v:localhost:3389", 0
10 };
11 
TestCmdLine(int argc,char * argv[])12 int TestCmdLine(int argc, char* argv[])
13 {
14 	int status;
15 	int ret = -1;
16 	DWORD flags;
17 	long width = 0;
18 	long height = 0;
19 	COMMAND_LINE_ARGUMENT_A* arg;
20 	int testArgc;
21 	char** command_line;
22 	COMMAND_LINE_ARGUMENT_A args[] = {
23 		{ "v", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "destination server" },
24 		{ "port", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "server port" },
25 		{ "w", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "width" },
26 		{ "h", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "height" },
27 		{ "f", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "fullscreen" },
28 		{ "bpp", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL,
29 		  "session bpp (color depth)" },
30 		{ "admin", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, "console",
31 		  "admin (or console) session" },
32 		{ "multimon", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "multi-monitor" },
33 		{ "a", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, "addin", "addin" },
34 		{ "u", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "username" },
35 		{ "p", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "password" },
36 		{ "d", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "domain" },
37 		{ "z", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "compression" },
38 		{ "audio", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "audio output mode" },
39 		{ "mic", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "audio input (microphone)" },
40 		{ "fonts", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL,
41 		  "smooth fonts (cleartype)" },
42 		{ "aero", COMMAND_LINE_VALUE_BOOL, NULL, NULL, BoolValueFalse, -1, NULL,
43 		  "desktop composition" },
44 		{ "window-drag", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL,
45 		  "full window drag" },
46 		{ "menu-anims", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL,
47 		  "menu animations" },
48 		{ "themes", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "themes" },
49 		{ "wallpaper", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "wallpaper" },
50 		{ "codec", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "codec" },
51 		{ "nego", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
52 		  "protocol security negotiation" },
53 		{ "sec", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL,
54 		  "force specific protocol security" },
55 		{ "sec-rdp", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
56 		  "rdp protocol security" },
57 		{ "sec-tls", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
58 		  "tls protocol security" },
59 		{ "sec-nla", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
60 		  "nla protocol security" },
61 		{ "sec-ext", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL,
62 		  "nla extended protocol security" },
63 		{ "cert-name", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL,
64 		  "certificate name" },
65 		{ "cert-ignore", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL,
66 		  "ignore certificate" },
67 		{ "version", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_VERSION, NULL, NULL, NULL, -1,
68 		  NULL, "print version" },
69 		{ "help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "?",
70 		  "print help" },
71 		{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
72 	};
73 
74 	flags = COMMAND_LINE_SIGIL_SLASH | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_SIGIL_PLUS_MINUS;
75 	testArgc = string_list_length(testArgv);
76 	command_line = string_list_copy(testArgv);
77 
78 	if (!command_line)
79 	{
80 		printf("Argument duplication failed (not enough memory?)\n");
81 		return ret;
82 	}
83 
84 	status = CommandLineParseArgumentsA(testArgc, command_line, args, flags, NULL, NULL, NULL);
85 
86 	if (status != 0)
87 	{
88 		printf("CommandLineParseArgumentsA failure: %d\n", status);
89 		goto out;
90 	}
91 
92 	arg = CommandLineFindArgumentA(args, "w");
93 
94 	if (strcmp("1024", arg->Value) != 0)
95 	{
96 		printf("CommandLineFindArgumentA: unexpected %s value %s\n", arg->Name, arg->Value);
97 		goto out;
98 	}
99 
100 	arg = CommandLineFindArgumentA(args, "h");
101 
102 	if (strcmp("768", arg->Value) != 0)
103 	{
104 		printf("CommandLineFindArgumentA: unexpected %s value %s\n", arg->Name, arg->Value);
105 		goto out;
106 	}
107 
108 	arg = CommandLineFindArgumentA(args, "f");
109 
110 	if (arg->Value)
111 	{
112 		printf("CommandLineFindArgumentA: unexpected %s value\n", arg->Name);
113 		goto out;
114 	}
115 
116 	arg = CommandLineFindArgumentA(args, "admin");
117 
118 	if (!arg->Value)
119 	{
120 		printf("CommandLineFindArgumentA: unexpected %s value\n", arg->Name);
121 		goto out;
122 	}
123 
124 	arg = CommandLineFindArgumentA(args, "multimon");
125 
126 	if (!arg->Value)
127 	{
128 		printf("CommandLineFindArgumentA: unexpected %s value\n", arg->Name);
129 		goto out;
130 	}
131 
132 	arg = CommandLineFindArgumentA(args, "v");
133 
134 	if (strcmp("localhost:3389", arg->Value) != 0)
135 	{
136 		printf("CommandLineFindArgumentA: unexpected %s value %s\n", arg->Name, arg->Value);
137 		goto out;
138 	}
139 
140 	arg = CommandLineFindArgumentA(args, "fonts");
141 
142 	if (!arg->Value)
143 	{
144 		printf("CommandLineFindArgumentA: unexpected %s value\n", arg->Name);
145 		goto out;
146 	}
147 
148 	arg = CommandLineFindArgumentA(args, "wallpaper");
149 
150 	if (arg->Value)
151 	{
152 		printf("CommandLineFindArgumentA: unexpected %s value\n", arg->Name);
153 		goto out;
154 	}
155 
156 	arg = CommandLineFindArgumentA(args, "help");
157 
158 	if (arg->Value)
159 	{
160 		printf("CommandLineFindArgumentA: unexpected %s value\n", arg->Name);
161 		goto out;
162 	}
163 
164 	arg = args;
165 	errno = 0;
166 
167 	do
168 	{
169 		if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT))
170 			continue;
171 
172 		printf("Argument: %s\n", arg->Name);
173 		CommandLineSwitchStart(arg) CommandLineSwitchCase(arg, "v")
174 		{
175 		}
176 		CommandLineSwitchCase(arg, "w")
177 		{
178 			width = strtol(arg->Value, NULL, 0);
179 
180 			if (errno != 0)
181 				goto out;
182 		}
183 		CommandLineSwitchCase(arg, "h")
184 		{
185 			height = strtol(arg->Value, NULL, 0);
186 
187 			if (errno != 0)
188 				goto out;
189 		}
190 		CommandLineSwitchDefault(arg)
191 		{
192 		}
193 		CommandLineSwitchEnd(arg)
194 	} while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
195 
196 	if ((width != 1024) || (height != 768))
197 	{
198 		printf("Unexpected width and height: Actual: (%ldx%ld), Expected: (1024x768)\n", width,
199 		       height);
200 		goto out;
201 	}
202 	ret = 0;
203 
204 out:
205 	string_list_free(command_line);
206 	return ret;
207 }
208