ReactOS 0.4.16-dev-334-g4d9f67c
cmd.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS API tests
3 * LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
4 * PURPOSE: Test for cmd.exe
5 * COPYRIGHT: Copyright 2019 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6 */
7
8#include "precomp.h"
9
10#define TIMEOUT 3000
11
12typedef struct TEST_ENTRY
13{
16 const char *cmdline;
19 const char *OutputContains;
20 const char *ErrorContains;
21 const char *OutputNotContains;
22 const char *ErrorNotContains;
24
25static const TEST_ENTRY s_exit_entries[] =
26{
27 { __LINE__, 0, "cmd /c exit" },
28 { __LINE__, 0, "cmd /c exit 0" },
29 { __LINE__, 0, "cmd /c exit \"\"" },
30 { __LINE__, 0, "cmd /c exit ABC" },
31 { __LINE__, 0, "cmd /c exit \"ABC" },
32 { __LINE__, 0, "cmd /c exit \"ABC\"" },
33 { __LINE__, 1234, "cmd /c exit 1234" },
34};
35
36static const TEST_ENTRY s_echo_entries[] =
37{
38// { __LINE__, 0, "cmd /c echo", TRUE, FALSE, NULL, "ECHO" },
39 { __LINE__, 0, "cmd /c echo.", TRUE, FALSE, "\r\n" },
40 { __LINE__, 0, "cmd /c echo ABC", TRUE, FALSE, "ABC\r\n" },
41};
42
43static const TEST_ENTRY s_cd_entries[] =
44{
45 { __LINE__, 0, "cmd /c cd \"C:\\ " },
46 { __LINE__, 0, "cmd /c cd C:/" },
47 { __LINE__, 0, "cmd /c cd \"\"", TRUE, FALSE },
48 { __LINE__, 0, "cmd /c cd", TRUE, FALSE },
49 { __LINE__, 1234, "cmd /c cd C:\\Program Files && exit 1234" },
50 { __LINE__, 1234, "cmd /c cd \"C:\\ \" && exit 1234" },
51 { __LINE__, 1234, "cmd /c cd \"C:\\Program Files\" && exit 1234" },
52 { __LINE__, 1234, "cmd /c cd \"\" && exit 1234", TRUE, FALSE },
53 { __LINE__, 1234, "cmd /c cd \\ && exit 1234" },
54};
55
57{
58 { __LINE__, 0, "cmd /c pushd C:\\ " },
59 { __LINE__, 0, "cmd /c pushd C:\\ \"" },
60 { __LINE__, 0, "cmd /c pushd C:\\ \"\"" },
61 { __LINE__, 0, "cmd /c pushd C:\\ \"\"\"" },
62 { __LINE__, 0, "cmd /c pushd C:\\ \"\"\"\"" },
63 { __LINE__, 0, "cmd /c pushd C:\\ \" " },
64 { __LINE__, 0, "cmd /c pushd C:\\ \"\" " },
65 { __LINE__, 0, "cmd /c pushd C:\\ \"\"\" " },
66 { __LINE__, 0, "cmd /c pushd C:\\ \"\"\"\" " },
67 { __LINE__, 0, "cmd /c pushd C:\\" },
68 { __LINE__, 0, "cmd /c pushd C:\\\"" },
69 { __LINE__, 0, "cmd /c pushd C:\\\"\"" },
70 { __LINE__, 0, "cmd /c pushd C:\\\"\"\"" },
71 { __LINE__, 0, "cmd /c pushd C:\\\"\"\"\"" },
72 { __LINE__, 0, "cmd /c pushd C:\\\" " },
73 { __LINE__, 0, "cmd /c pushd C:\\\"\" " },
74 { __LINE__, 0, "cmd /c pushd C:\\\"\"\" " },
75 { __LINE__, 0, "cmd /c pushd C:\\\"\"\"\" " },
76 { __LINE__, 0, "cmd /c pushd \"C:\\ " },
77 { __LINE__, 0, "cmd /c pushd \"C:\\ \"" },
78 { __LINE__, 0, "cmd /c pushd \"C:\\ \"\"" },
79 { __LINE__, 0, "cmd /c pushd \"C:\\ \"\"\"" },
80 { __LINE__, 0, "cmd /c pushd \"C:\\ \"\"\"\"" },
81 { __LINE__, 0, "cmd /c pushd \"C:\\ \" " },
82 { __LINE__, 0, "cmd /c pushd \"C:\\ \"\" " },
83 { __LINE__, 0, "cmd /c pushd \"C:\\ \"\"\" " },
84 { __LINE__, 0, "cmd /c pushd \"C:\\ \"\"\"\" " },
85 { __LINE__, 0, "cmd /c pushd \"C:\\" },
86 { __LINE__, 0, "cmd /c pushd \"C:\\\"" },
87 { __LINE__, 0, "cmd /c pushd \"C:\\\"\"" },
88 { __LINE__, 0, "cmd /c pushd \"C:\\\"\"\"" },
89 { __LINE__, 0, "cmd /c pushd \"C:\\\"\"\"\"" },
90 { __LINE__, 0, "cmd /c pushd \"C:\\\"" },
91 { __LINE__, 1, "cmd /c pushd \" C:\\ ", FALSE, TRUE },
92 { __LINE__, 1, "cmd /c pushd \" C:\\ \"", FALSE, TRUE },
93 { __LINE__, 1, "cmd /c pushd \" C:\\ \"\"", FALSE, TRUE },
94 { __LINE__, 1, "cmd /c pushd \" C:\\ \"\"\"", FALSE, TRUE },
95 { __LINE__, 1, "cmd /c pushd \" C:\\ \"\"\"\"", FALSE, TRUE },
96 { __LINE__, 1, "cmd /c pushd \"\" C:\\ ", FALSE, TRUE },
97 { __LINE__, 1, "cmd /c pushd \"\" C:\\ \"", FALSE, TRUE },
98 { __LINE__, 1, "cmd /c pushd \"\" C:\\ \"\"", FALSE, TRUE },
99 { __LINE__, 1, "cmd /c pushd \"\" C:\\ \"\"\"", FALSE, TRUE },
100 { __LINE__, 1, "cmd /c pushd \"\" C:\\ \"\"\"\"", FALSE, TRUE },
101 { __LINE__, 1, "cmd /c pushd \"\" C:\\\"", FALSE, TRUE },
102 { __LINE__, 1, "cmd /c popd ABC" },
103 { __LINE__, 1, "cmd /c popd \" " },
104 { __LINE__, 1, "cmd /c popd \"\"" },
105 { __LINE__, 1, "cmd /c popd" },
106 { __LINE__, 1, "cmd /c pushd ABC", FALSE, TRUE },
107 { __LINE__, 1, "cmd /c pushd C:/Program Files && popd && exit 1234", FALSE, TRUE },
108 { __LINE__, 1, "cmd /c pushd C:\\ C:\\ && popd && exit 1234", FALSE, TRUE },
109 { __LINE__, 1, "cmd /c pushd C:\\Invalid Directory && exit 1234", FALSE, TRUE },
110 { __LINE__, 1, "cmd /c pushd C:\\Invalid Directory && popd && exit 1234", FALSE, TRUE },
111 { __LINE__, 1, "cmd /c pushd \" C:\\ ", FALSE, TRUE },
112 { __LINE__, 1, "cmd /c pushd \"C:\\ C:\\\" && popd && exit 1234", FALSE, TRUE },
113 { __LINE__, 1234, "cmd /c pushd && exit 1234 " },
114 { __LINE__, 1234, "cmd /c pushd C:\\ && popd && exit 1234" },
115 { __LINE__, 1234, "cmd /c pushd C:\\ \"\" && popd && exit 1234" },
116 { __LINE__, 1234, "cmd /c pushd C:\\Program Files && popd && exit 1234" },
117// { __LINE__, 1234, "cmd /c pushd \"C:/Program Files/\" && popd && exit 1234" },
118// { __LINE__, 1234, "cmd /c pushd \"C:/Program Files\" && popd && exit 1234" },
119 { __LINE__, 1234, "cmd /c pushd \"C:\\ \" && popd && exit 1234" },
120 { __LINE__, 1234, "cmd /c pushd \"C:\\ \"\"\" && popd && exit 1234" },
121 { __LINE__, 1234, "cmd /c pushd \"C:\\ \"\"\"\"\" && popd && exit 1234" },
122 { __LINE__, 1234, "cmd /c pushd \"C:\\Program Files\" && popd && exit 1234" },
123 { __LINE__, 1234, "cmd /c pushd \"C:\\Program Files\\\" && popd && exit 1234" },
124 { __LINE__, 1234, "cmd /c pushd \"C:\\\" && popd && exit 1234" },
125};
126
128{
129 /* invalid-path.txt */
130 { __LINE__, 0, "attrib invalid-path.txt", TRUE, FALSE },
131 { __LINE__, 0, "attrib +H invalid-path.txt", TRUE, FALSE },
132 { __LINE__, 0, "attrib -H invalid-path.txt", TRUE, FALSE },
133
134 /* attr-test.txt */
135 { __LINE__, 0, "cmd /c if exist attr-test.txt attrib -H attr-test.txt" },
136 { __LINE__, 0, "cmd /c if exist attr-test.txt del /Q attr-test.txt" },
137 { __LINE__, 0, "cmd /c copy NUL attr-test.txt ", TRUE, FALSE },
138 { __LINE__, 0, "attrib attr-test.txt", TRUE, FALSE, NULL, NULL, " H " },
139 { __LINE__, 0, "attrib +H attr-test.txt", FALSE, FALSE },
140 { __LINE__, 0, "attrib attr-test.txt", TRUE, FALSE, " H " },
141 { __LINE__, 0, "attrib -H attr-test.txt", FALSE, FALSE },
142 { __LINE__, 0, "attrib attr-test.txt", TRUE, FALSE, NULL, NULL, " H " },
143 { __LINE__, 0, "attrib attr-te*.txt", TRUE, FALSE, NULL, NULL, " H " },
144 { __LINE__, 0, "attrib +H attr-te*.txt", FALSE, FALSE },
145 { __LINE__, 0, "attrib attr-te*.txt", TRUE, FALSE, " H " },
146 { __LINE__, 0, "attrib -H attr-te*.txt", FALSE, FALSE },
147 { __LINE__, 0, "attrib attr-te*.txt", TRUE, FALSE, NULL, NULL, " H " },
148 { __LINE__, 0, "cmd /c if exist attr-test.txt attrib -H attr-test.txt" },
149 { __LINE__, 0, "cmd /c if exist attr-test.txt del /Q attr-test.txt" },
150
151 /* /S attr-test.txt */
152 { __LINE__, 0, "cmd /c if exist attr-test.txt attrib -H attr-test.txt" },
153 { __LINE__, 0, "cmd /c if exist attr-test.txt del /Q attr-test.txt" },
154 { __LINE__, 0, "cmd /c copy NUL attr-test.txt ", TRUE, FALSE },
155 { __LINE__, 0, "attrib /S attr-test.txt", TRUE, FALSE, NULL, NULL, " H " },
156 { __LINE__, 0, "attrib /S +H attr-test.txt", FALSE, FALSE },
157 { __LINE__, 0, "attrib /S attr-test.txt", TRUE, FALSE, " H " },
158 { __LINE__, 0, "attrib /S -H attr-test.txt", FALSE, FALSE },
159 { __LINE__, 0, "attrib /S attr-test.txt", TRUE, FALSE, NULL, NULL, " H " },
160 { __LINE__, 0, "attrib /S attr-te*.txt", TRUE, FALSE, NULL, NULL, " H " },
161 { __LINE__, 0, "attrib /S +H attr-te*.txt", FALSE, FALSE },
162 { __LINE__, 0, "attrib /S attr-te*.txt", TRUE, FALSE, " H " },
163 { __LINE__, 0, "attrib /S -H attr-te*.txt", FALSE, FALSE },
164 { __LINE__, 0, "attrib /S attr-te*.txt", TRUE, FALSE, NULL, NULL, " H " },
165 { __LINE__, 0, "attrib /S +H", FALSE, FALSE },
166 { __LINE__, 0, "attrib /S attr-test.txt", TRUE, FALSE, " H " },
167 { __LINE__, 0, "attrib /S -H", FALSE, FALSE },
168 { __LINE__, 0, "attrib /S attr-test.txt", TRUE, FALSE, NULL, NULL, " H " },
169 { __LINE__, 0, "cmd /c if exist attr-test.txt attrib -H attr-test.txt" },
170 { __LINE__, 0, "cmd /c if exist attr-test.txt del /Q attr-test.txt" },
171
172 /* /S /D attr-test.txt */
173 { __LINE__, 0, "cmd /c if exist attr-test.txt attrib -H attr-test.txt" },
174 { __LINE__, 0, "cmd /c if exist attr-test.txt del /Q attr-test.txt" },
175 { __LINE__, 0, "cmd /c copy NUL attr-test.txt ", TRUE, FALSE },
176 { __LINE__, 0, "attrib /S /D attr-test.txt", TRUE, FALSE, NULL, NULL, " H " },
177 { __LINE__, 0, "attrib /S /D +H attr-test.txt", FALSE, FALSE },
178 { __LINE__, 0, "attrib /S /D attr-test.txt", TRUE, FALSE, " H " },
179 { __LINE__, 0, "attrib /S /D -H attr-test.txt", FALSE, FALSE },
180 { __LINE__, 0, "attrib /S /D attr-test.txt", TRUE, FALSE, NULL, NULL, " H " },
181 { __LINE__, 0, "attrib /S /D attr-te*.txt", TRUE, FALSE, NULL, NULL, " H " },
182 { __LINE__, 0, "attrib /S /D +H attr-te*.txt", FALSE, FALSE },
183 { __LINE__, 0, "attrib /S /D attr-te*.txt", TRUE, FALSE, " H " },
184 { __LINE__, 0, "attrib /S /D -H attr-te*.txt", FALSE, FALSE },
185 { __LINE__, 0, "attrib /S /D attr-te*.txt", TRUE, FALSE, NULL, NULL, " H " },
186 { __LINE__, 0, "cmd /c if exist attr-test.txt attrib -H attr-test.txt" },
187 { __LINE__, 0, "cmd /c if exist attr-test.txt del /Q attr-test.txt" },
188
189 /* attr-dir, attr-dir/test.txt */
190 { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" },
191 { __LINE__, 0, "cmd /c mkdir attr-dir", FALSE, FALSE },
192 { __LINE__, 0, "cmd /c if exist attr-dir/test.txt attrib -H attr-dir/test.txt" },
193 { __LINE__, 0, "cmd /c if exist attr-dir/test.txt del /Q attr-dir/test.txt" },
194 { __LINE__, 1, "cmd /c copy NUL attr-dir/test.txt ", TRUE, FALSE },
195 { __LINE__, 0, "attrib attr-dir/test.txt", TRUE, FALSE, NULL, NULL, " H " },
196 { __LINE__, 0, "attrib +H attr-dir/test.txt", TRUE, FALSE },
197 { __LINE__, 0, "attrib attr-dir/test.txt", TRUE, FALSE, NULL, NULL, " H " },
198 { __LINE__, 0, "attrib -H attr-dir/test.txt", TRUE, FALSE, "test.txt" },
199 { __LINE__, 0, "attrib attr-dir/test.txt", TRUE, FALSE, NULL, NULL, " H " },
200 { __LINE__, 0, "attrib +H attr-dir", FALSE, FALSE, NULL, NULL, " H " },
201 { __LINE__, 0, "attrib attr-dir", TRUE, FALSE, " H " },
202 { __LINE__, 0, "attrib attr-dir/test.txt", TRUE, FALSE, NULL, NULL, " H " },
203 { __LINE__, 0, "attrib -H attr-dir", FALSE, FALSE, NULL, NULL, " H " },
204 { __LINE__, 0, "attrib attr-dir", TRUE, FALSE, NULL, NULL, " H " },
205 { __LINE__, 0, "cmd /c if exist attr-dir/test.txt attrib -H attr-dir/test.txt" },
206 { __LINE__, 0, "cmd /c if exist attr-dir/test.txt del /Q attr-dir/test.txt" },
207 { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" },
208
209 /* attr-dir, attr-dir\\dir1 */
210 { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" },
211 { __LINE__, 0, "cmd /c mkdir attr-dir", FALSE, FALSE },
212 { __LINE__, 0, "attrib attr-dir", TRUE, FALSE, NULL, NULL, " H " },
213 { __LINE__, 0, "cmd /c if exist attr-dir echo OK", TRUE, FALSE, "OK" },
214 { __LINE__, 0, "cmd /c mkdir attr-dir\\dir1", FALSE, FALSE },
215 { __LINE__, 0, "cmd /c if exist attr-dir\\dir1 echo OK", TRUE, FALSE, "OK" },
216 { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
217 { __LINE__, 0, "attrib +H attr-dir\\dir1", FALSE, FALSE },
218 { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, " H " },
219 { __LINE__, 0, "attrib -H attr-dir\\dir1", FALSE, FALSE },
220 { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
221 { __LINE__, 0, "attrib +H attr-dir", FALSE, FALSE },
222 { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
223 { __LINE__, 0, "attrib -H attr-dir", FALSE, FALSE },
224 { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
225 { __LINE__, 0, "attrib +H attr-d*", TRUE, FALSE, "attr-d*" },
226 { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
227 { __LINE__, 0, "attrib -H attr-d*", TRUE, FALSE, "attr-d*" },
228 { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
229 { __LINE__, 0, "attrib +H attr-dir\\d*", TRUE, FALSE, "attr-dir\\d*" },
230 { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
231 { __LINE__, 0, "attrib -H attr-dir\\d*", TRUE, FALSE, "attr-dir\\d*" },
232 { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
233 { __LINE__, 0, "attrib -H attr-dir\\dir1", FALSE, FALSE },
234 { __LINE__, 0, "attrib -H attr-dir", FALSE, FALSE },
235 { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" },
236
237 /* /S attr-dir, attr-dir\\dir1 */
238 { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" },
239 { __LINE__, 0, "cmd /c mkdir attr-dir", FALSE, FALSE },
240 { __LINE__, 0, "attrib /S attr-dir", TRUE, FALSE, NULL, NULL, " H " },
241 { __LINE__, 0, "cmd /c if exist attr-dir echo OK", TRUE, FALSE, "OK" },
242 { __LINE__, 0, "cmd /c mkdir attr-dir\\dir1", FALSE, FALSE },
243 { __LINE__, 0, "cmd /c if exist attr-dir\\dir1 echo OK", TRUE, FALSE, "OK" },
244 { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
245 { __LINE__, 0, "attrib /S +H attr-dir\\dir1", TRUE, FALSE, "attr-dir\\dir1", },
246 { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, "attr-dir\\dir1" },
247 { __LINE__, 0, "attrib /S -H attr-dir\\dir1", TRUE, FALSE, "attr-dir\\dir1" },
248 { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
249 { __LINE__, 0, "attrib /S +H attr-dir", TRUE, FALSE, "attr-dir" },
250 { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
251 { __LINE__, 0, "attrib /S -H attr-dir", TRUE, FALSE, "attr-dir" },
252 { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
253 { __LINE__, 0, "attrib /S +H attr-d*", TRUE, FALSE, "attr-d*" },
254 { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
255 { __LINE__, 0, "attrib /S -H attr-d*", TRUE, FALSE, "attr-d*" },
256 { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
257 { __LINE__, 0, "attrib /S +H attr-dir\\d*", TRUE, FALSE, "attr-dir\\d*" },
258 { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
259 { __LINE__, 0, "attrib /S -H attr-dir\\d*", TRUE, FALSE, "attr-dir\\d*" },
260 { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
261 { __LINE__, 0, "attrib /S -H attr-dir\\dir1", TRUE, FALSE, "attr-dir\\dir1" },
262 { __LINE__, 0, "attrib /S -H attr-dir", TRUE, FALSE, "attr-dir" },
263 { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" },
264
265 /* /S /D attr-dir, attr-dir\\dir1 */
266 { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" },
267 { __LINE__, 0, "cmd /c mkdir attr-dir", FALSE, FALSE },
268 { __LINE__, 0, "attrib /S /D attr-dir", TRUE, FALSE, NULL, NULL, " H " },
269 { __LINE__, 0, "cmd /c if exist attr-dir echo OK", TRUE, FALSE, "OK" },
270 { __LINE__, 0, "cmd /c mkdir attr-dir\\dir1", FALSE, FALSE },
271 { __LINE__, 0, "cmd /c if exist attr-dir\\dir1 echo OK", TRUE, FALSE, "OK" },
272 { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
273 { __LINE__, 0, "attrib /S /D +H attr-dir\\dir1", FALSE, FALSE },
274 { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, " H " },
275 { __LINE__, 0, "attrib /S /D -H attr-dir\\dir1", FALSE, FALSE },
276 { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
277 { __LINE__, 0, "attrib /S /D +H attr-dir", FALSE, FALSE },
278 { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
279 { __LINE__, 0, "attrib /S /D -H attr-dir", FALSE, FALSE },
280 { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
281 { __LINE__, 0, "attrib /S /D +H attr-d*", FALSE, FALSE },
282 { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
283 { __LINE__, 0, "attrib /S /D -H attr-d*", FALSE, FALSE },
284 { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
285 { __LINE__, 0, "attrib /S /D +H attr-dir\\d*", FALSE, FALSE },
286 { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, " H " },
287 { __LINE__, 0, "attrib /S /D -H attr-dir\\d*", FALSE, FALSE },
288 { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
289 { __LINE__, 0, "attrib /S /D -H attr-dir\\dir1", FALSE, FALSE },
290 { __LINE__, 0, "attrib /S /D -H attr-dir", FALSE, FALSE },
291 { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" },
292
293 /* /S attr-dir, attr-dir\\dir1\\file.txt */
294 { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" },
295 { __LINE__, 0, "cmd /c mkdir attr-dir", FALSE, FALSE },
296 { __LINE__, 0, "attrib /S /D attr-dir", TRUE, FALSE, NULL, NULL, " H " },
297 { __LINE__, 0, "cmd /c if exist attr-dir echo OK", TRUE, FALSE, "OK" },
298 { __LINE__, 0, "cmd /c mkdir attr-dir\\dir1", FALSE, FALSE },
299 { __LINE__, 0, "cmd /c if exist attr-dir\\dir1 echo OK", TRUE, FALSE, "OK" },
300 { __LINE__, 0, "cmd /c copy NUL attr-dir\\dir1\\attr-test.txt ", TRUE, FALSE },
301 { __LINE__, 0, "attrib attr-dir\\dir1\\attr-test.txt", TRUE, FALSE, NULL, NULL, " H " },
302 { __LINE__, 0, "attrib /S +H attr-dir\\dir1\\attr-test.txt", FALSE, FALSE },
303 { __LINE__, 0, "attrib /S attr-test.txt", TRUE, FALSE, " H " },
304 { __LINE__, 0, "attrib /S -H attr-dir\\dir1\\attr-test.txt", FALSE, FALSE },
305 { __LINE__, 0, "attrib /S attr-test.txt", TRUE, FALSE, NULL, NULL, " H " },
306 { __LINE__, 0, "attrib /S +H attr-test.txt", FALSE, FALSE },
307 { __LINE__, 0, "attrib /S attr-test.txt", TRUE, FALSE, " H " },
308 { __LINE__, 0, "attrib /S -H attr-test.txt", FALSE, FALSE },
309 { __LINE__, 0, "attrib /S attr-test.txt", TRUE, FALSE, NULL, NULL, " H " },
310 { __LINE__, 0, "attrib /S +H", FALSE, FALSE },
311 { __LINE__, 0, "attrib /S attr-test.txt", TRUE, FALSE, " H " },
312 { __LINE__, 0, "attrib /S attr-tes*.*", TRUE, FALSE, " H " },
313 { __LINE__, 0, "attrib /S -H", FALSE, FALSE },
314 { __LINE__, 0, "attrib /S attr-test.txt", TRUE, FALSE, NULL, NULL, " H " },
315 { __LINE__, 0, "attrib /S attr-tes*.*", TRUE, FALSE, NULL, NULL, " H " },
316 { __LINE__, 0, "cmd /c if exist attr-dir/dir1/test.txt attrib -H attr-dir/dir1/test.txt" },
317 { __LINE__, 0, "cmd /c if exist attr-dir/dir1/test.txt del /Q attr-dir/dir1/test.txt" },
318 { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" },
319
320};
321
323{
325 return DuplicateHandle(hProcess, hFile, hProcess, phFile, 0,
326 bInherit, DUPLICATE_SAME_ACCESS);
327}
328
329static BOOL PrepareForRedirect(STARTUPINFOA *psi, PHANDLE phInputWrite,
330 PHANDLE phOutputRead, PHANDLE phErrorRead)
331{
332 HANDLE hInputRead = NULL, hInputWriteTmp = NULL;
333 HANDLE hOutputReadTmp = NULL, hOutputWrite = NULL;
334 HANDLE hErrorReadTmp = NULL, hErrorWrite = NULL;
335 SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, TRUE };
336
337 psi->hStdInput = NULL;
338 psi->hStdOutput = NULL;
339 psi->hStdError = NULL;
340
341 if (phInputWrite)
342 {
343 if (CreatePipe(&hInputRead, &hInputWriteTmp, &sa, 0))
344 {
345 if (!MyDuplicateHandle(hInputWriteTmp, phInputWrite, FALSE))
346 goto failed;
347
348 CloseHandle(hInputWriteTmp);
349 }
350 else
351 goto failed;
352 }
353
354 if (phOutputRead)
355 {
356 if (CreatePipe(&hOutputReadTmp, &hOutputWrite, &sa, 0))
357 {
358 if (!MyDuplicateHandle(hOutputReadTmp, phOutputRead, FALSE))
359 goto failed;
360
361 CloseHandle(hOutputReadTmp);
362 }
363 else
364 goto failed;
365 }
366
367 if (phOutputRead && phOutputRead == phErrorRead)
368 {
369 if (!MyDuplicateHandle(hOutputWrite, &hErrorWrite, TRUE))
370 goto failed;
371 }
372 else if (phErrorRead)
373 {
374 if (CreatePipe(&hErrorReadTmp, &hErrorWrite, &sa, 0))
375 {
376 if (!MyDuplicateHandle(hErrorReadTmp, phErrorRead, FALSE))
377 goto failed;
378 CloseHandle(hErrorReadTmp);
379 }
380 else
381 goto failed;
382 }
383
384 if (phInputWrite)
385 psi->hStdInput = hInputRead;
386 if (phOutputRead)
387 psi->hStdOutput = hOutputWrite;
388 if (phErrorRead)
389 psi->hStdError = hErrorWrite;
390
391 return TRUE;
392
393failed:
394 CloseHandle(hInputRead);
395 CloseHandle(hInputWriteTmp);
396 CloseHandle(hOutputReadTmp);
397 CloseHandle(hOutputWrite);
398 CloseHandle(hErrorReadTmp);
399 CloseHandle(hErrorWrite);
400 return FALSE;
401}
402
403static void DoTestEntry(const TEST_ENTRY *pEntry)
404{
405 STARTUPINFOA si;
407 DWORD dwExitCode, dwWait;
408 HANDLE hOutputRead = NULL;
409 HANDLE hErrorRead = NULL;
410 DWORD dwRead;
411 BOOL bStdOutput, bStdError;
412 CHAR szOut[512], szErr[512];
413
414 memset(&si, 0, sizeof(si));
415 si.cb = sizeof(si);
417
418 if (!PrepareForRedirect(&si, NULL, &hOutputRead, &hErrorRead))
419 {
420 skip("PrepareForRedirect failed\n");
421 return;
422 }
423
424 if (CreateProcessA(NULL, (char *)pEntry->cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
425 {
427 dwWait = WaitForSingleObject(pi.hProcess, TIMEOUT);
428 if (dwWait == WAIT_TIMEOUT)
429 {
430 TerminateProcess(pi.hProcess, 9999);
431 }
432 GetExitCodeProcess(pi.hProcess, &dwExitCode);
433 CloseHandle(pi.hThread);
434 CloseHandle(pi.hProcess);
435 }
436 else
437 {
438 dwExitCode = 8888;
439 }
440
441 ZeroMemory(szOut, sizeof(szOut));
442 PeekNamedPipe(hOutputRead, szOut, ARRAYSIZE(szOut), &dwRead, NULL, NULL);
443 szOut[ARRAYSIZE(szOut) - 1] = 0;
444 bStdOutput = dwRead != 0;
445
446 ZeroMemory(szErr, sizeof(szErr));
447 PeekNamedPipe(hErrorRead, szErr, ARRAYSIZE(szErr), &dwRead, NULL, NULL);
448 szErr[ARRAYSIZE(szErr) - 1] = 0;
449 bStdError = dwRead != 0;
450
451 if (si.hStdInput)
453 if (si.hStdOutput)
455 if (si.hStdError)
457
458 ok(pEntry->bStdOutput == bStdOutput,
459 "Line %u: bStdOutput %d vs %d\n",
460 pEntry->line, pEntry->bStdOutput, bStdOutput);
461
462 ok(pEntry->bStdError == bStdError,
463 "Line %u: bStdError %d vs %d\n",
464 pEntry->line, pEntry->bStdError, bStdError);
465
466 ok(pEntry->dwExitCode == dwExitCode,
467 "Line %u: dwExitCode %ld vs %ld\n",
468 pEntry->line, pEntry->dwExitCode, dwExitCode);
469
470 if (pEntry->OutputContains)
471 {
472 ok(strstr(szOut, pEntry->OutputContains) != NULL,
473 "Line %u: szOut was '%s'\n",
474 pEntry->line, szOut);
475 }
476
477 if (pEntry->ErrorContains)
478 {
479 ok(strstr(szErr, pEntry->ErrorContains) != NULL,
480 "Line %u: szErr was '%s'\n",
481 pEntry->line, szErr);
482 }
483
484 if (pEntry->OutputNotContains)
485 {
486 ok(strstr(szOut, pEntry->OutputNotContains) == NULL,
487 "Line %u: szOut was '%s'\n",
488 pEntry->line, szOut);
489 }
490
491 if (pEntry->ErrorNotContains)
492 {
493 ok(strstr(szErr, pEntry->ErrorNotContains) == NULL,
494 "Line %u: szErr was '%s'\n",
495 pEntry->line, szErr);
496 }
497}
498
500{
501 SIZE_T i;
502 for (i = 0; i < ARRAYSIZE(s_exit_entries); ++i)
503 {
505 }
506}
507
509{
510 SIZE_T i;
511 for (i = 0; i < ARRAYSIZE(s_echo_entries); ++i)
512 {
514 }
515}
516
518{
519 SIZE_T i;
520 for (i = 0; i < ARRAYSIZE(s_cd_entries); ++i)
521 {
523 }
524}
525
527{
528 SIZE_T i;
529 for (i = 0; i < ARRAYSIZE(s_pushd_entries); ++i)
530 {
532 }
533}
534
536{
537 SIZE_T i;
538 for (i = 0; i < ARRAYSIZE(s_attrib_entries); ++i)
539 {
541 }
542}
InitDirComponents & cd
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
TCHAR szErr[256]
Definition: service.c:38
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define CloseHandle
Definition: compat.h:739
#define GetCurrentProcess()
Definition: compat.h:759
BOOL WINAPI DuplicateHandle(IN HANDLE hSourceProcessHandle, IN HANDLE hSourceHandle, IN HANDLE hTargetProcessHandle, OUT LPHANDLE lpTargetHandle, IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwOptions)
Definition: handle.c:149
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1168
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4747
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1532
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:71
static const TEST_ENTRY s_pushd_entries[]
Definition: cmd.c:56
static BOOL PrepareForRedirect(STARTUPINFOA *psi, PHANDLE phInputWrite, PHANDLE phOutputRead, PHANDLE phErrorRead)
Definition: cmd.c:329
static const TEST_ENTRY s_attrib_entries[]
Definition: cmd.c:127
static void DoTestEntry(const TEST_ENTRY *pEntry)
Definition: cmd.c:403
#define TIMEOUT
Definition: cmd.c:10
static const TEST_ENTRY s_cd_entries[]
Definition: cmd.c:43
static BOOL MyDuplicateHandle(HANDLE hFile, PHANDLE phFile, BOOL bInherit)
Definition: cmd.c:322
static const TEST_ENTRY s_echo_entries[]
Definition: cmd.c:36
struct TEST_ENTRY TEST_ENTRY
static const TEST_ENTRY s_exit_entries[]
Definition: cmd.c:25
static refpint_t pi[]
Definition: server.c:96
_In_ HANDLE hFile
Definition: mswsock.h:90
BOOL WINAPI PeekNamedPipe(HANDLE hNamedPipe, LPVOID lpBuffer, DWORD nBufferSize, LPDWORD lpBytesRead, LPDWORD lpTotalBytesAvail, LPDWORD lpBytesLeftThisMessage)
Definition: npipe.c:1214
BOOL WINAPI CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize)
Definition: npipe.c:117
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define exit(n)
Definition: config.h:202
#define memset(x, y, z)
Definition: compat.h:39
Definition: cmd.c:13
INT line
Definition: cmd.c:14
const char * OutputContains
Definition: cmd.c:19
BOOL bStdOutput
Definition: cmd.c:17
DWORD dwExitCode
Definition: cmd.c:15
const char * ErrorNotContains
Definition: cmd.c:22
const char * ErrorContains
Definition: cmd.c:20
const char * cmdline
Definition: cmd.c:16
BOOL bStdError
Definition: cmd.c:18
const char * OutputNotContains
Definition: cmd.c:21
HANDLE hStdOutput
Definition: winbase.h:872
HANDLE hStdError
Definition: winbase.h:873
DWORD dwFlags
Definition: winbase.h:867
DWORD cb
Definition: winbase.h:856
HANDLE hStdInput
Definition: winbase.h:871
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
ULONG_PTR SIZE_T
Definition: typedefs.h:80
int32_t INT
Definition: typedefs.h:58
#define ZeroMemory
Definition: winbase.h:1737
#define STARTF_USESTDHANDLES
Definition: winbase.h:525
#define DUPLICATE_SAME_ACCESS
char CHAR
Definition: xmlstorage.h:175