ReactOS  0.4.14-dev-831-gef8c9239
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 
12 typedef struct TEST_ENTRY
13 {
16  const char *cmdline;
19  const char *OutputContains;
20  const char *ErrorContains;
21  const char *OutputNotContains;
22  const char *ErrorNotContains;
23 } TEST_ENTRY;
24 
25 static 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 
36 static 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 
43 static 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 
56 static const TEST_ENTRY s_pushd_entries[] =
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 
127 static const TEST_ENTRY s_attrib_entries[] =
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 
322 static BOOL MyDuplicateHandle(HANDLE hFile, PHANDLE phFile, BOOL bInherit)
323 {
325  return DuplicateHandle(hProcess, hFile, hProcess, phFile, 0,
326  bInherit, DUPLICATE_SAME_ACCESS);
327 }
328 
329 static 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 
393 failed:
394  CloseHandle(hInputRead);
395  CloseHandle(hInputWriteTmp);
396  CloseHandle(hOutputReadTmp);
397  CloseHandle(hOutputWrite);
398  CloseHandle(hErrorReadTmp);
399  CloseHandle(hErrorWrite);
400  return FALSE;
401 }
402 
403 static 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 
535 START_TEST(attrib)
536 {
537  SIZE_T i;
538  for (i = 0; i < ARRAYSIZE(s_attrib_entries); ++i)
539  {
541  }
542 }
static void DoTestEntry(const TEST_ENTRY *pEntry)
Definition: cmd.c:403
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:406
static BOOL MyDuplicateHandle(HANDLE hFile, PHANDLE phFile, BOOL bInherit)
Definition: cmd.c:322
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1168
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
static struct cd_image cd
Definition: cdmake.c:182
char CHAR
Definition: xmlstorage.h:175
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define ZeroMemory
Definition: winbase.h:1642
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:70
DWORD dwFlags
Definition: winbase.h:814
static const TEST_ENTRY s_echo_entries[]
Definition: cmd.c:36
#define TIMEOUT
Definition: cmd.c:10
int32_t INT
Definition: typedefs.h:56
struct TEST_ENTRY TEST_ENTRY
static const TEST_ENTRY s_attrib_entries[]
Definition: cmd.c:127
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
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
#define DUPLICATE_SAME_ACCESS
unsigned int BOOL
Definition: ntddk_ex.h:94
const char * OutputContains
Definition: cmd.c:19
static const TEST_ENTRY s_cd_entries[]
Definition: cmd.c:43
const char * ErrorContains
Definition: cmd.c:20
smooth NULL
Definition: ftsmooth.c:416
static const TEST_ENTRY s_exit_entries[]
Definition: cmd.c:25
DWORD dwExitCode
Definition: cmd.c:15
#define STARTF_USESTDHANDLES
Definition: winbase.h:480
DWORD cb
Definition: winbase.h:803
static BOOL PrepareForRedirect(STARTUPINFOA *psi, PHANDLE phInputWrite, PHANDLE phOutputRead, PHANDLE phErrorRead)
Definition: cmd.c:329
static refpint_t pi[]
Definition: server.c:96
HANDLE WINAPI GetCurrentProcess(VOID)
Definition: proc.c:1138
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:4742
INT line
Definition: cmd.c:14
START_TEST(exit)
Definition: cmd.c:499
unsigned long DWORD
Definition: ntddk_ex.h:95
HANDLE hStdOutput
Definition: winbase.h:819
#define WAIT_TIMEOUT
Definition: dderror.h:14
Definition: cmd.c:12
BOOL bStdError
Definition: cmd.c:18
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:414
_In_ HANDLE hFile
Definition: mswsock.h:90
BOOL WINAPI CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize)
Definition: npipe.c:117
const char * ErrorNotContains
Definition: cmd.c:22
ULONG_PTR SIZE_T
Definition: typedefs.h:78
HANDLE hStdInput
Definition: winbase.h:818
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1532
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
const char * OutputNotContains
Definition: cmd.c:21
TCHAR szErr[256]
Definition: service.c:38
const char * cmdline
Definition: cmd.c:16
void exit(int exitcode)
Definition: _exit.c:33
#define memset(x, y, z)
Definition: compat.h:39
HANDLE hStdError
Definition: winbase.h:820
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
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
static const TEST_ENTRY s_pushd_entries[]
Definition: cmd.c:56
BOOL WINAPI PeekNamedPipe(HANDLE hNamedPipe, LPVOID lpBuffer, DWORD nBufferSize, LPDWORD lpBytesRead, LPDWORD lpTotalBytesAvail, LPDWORD lpBytesLeftThisMessage)
Definition: npipe.c:1214
BOOL bStdOutput
Definition: cmd.c:17