ReactOS  0.4.14-dev-552-g2fad488
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, "cmd /c if exist attr-test.txt attrib -H attr-test.txt" },
166  { __LINE__, 0, "cmd /c if exist attr-test.txt del /Q attr-test.txt" },
167 
168  /* /S /D attr-test.txt */
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  { __LINE__, 0, "cmd /c copy NUL attr-test.txt ", TRUE, FALSE },
172  { __LINE__, 0, "attrib /S /D attr-test.txt", TRUE, FALSE, NULL, NULL, " H " },
173  { __LINE__, 0, "attrib /S /D +H attr-test.txt", FALSE, FALSE },
174  { __LINE__, 0, "attrib /S /D attr-test.txt", TRUE, FALSE, " H " },
175  { __LINE__, 0, "attrib /S /D -H attr-test.txt", FALSE, FALSE },
176  { __LINE__, 0, "attrib /S /D attr-test.txt", TRUE, FALSE, NULL, NULL, " H " },
177  { __LINE__, 0, "attrib /S /D attr-te*.txt", TRUE, FALSE, NULL, NULL, " H " },
178  { __LINE__, 0, "attrib /S /D +H attr-te*.txt", FALSE, FALSE },
179  { __LINE__, 0, "attrib /S /D attr-te*.txt", TRUE, FALSE, " H " },
180  { __LINE__, 0, "attrib /S /D -H attr-te*.txt", FALSE, FALSE },
181  { __LINE__, 0, "attrib /S /D attr-te*.txt", TRUE, FALSE, NULL, NULL, " H " },
182  { __LINE__, 0, "cmd /c if exist attr-test.txt attrib -H attr-test.txt" },
183  { __LINE__, 0, "cmd /c if exist attr-test.txt del /Q attr-test.txt" },
184 
185  /* attr-dir, attr-dir/test.txt */
186  { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" },
187  { __LINE__, 0, "cmd /c mkdir attr-dir", FALSE, FALSE },
188  { __LINE__, 0, "cmd /c if exist attr-dir/test.txt attrib -H attr-dir/test.txt" },
189  { __LINE__, 0, "cmd /c if exist attr-dir/test.txt del /Q attr-dir/test.txt" },
190  { __LINE__, 1, "cmd /c copy NUL attr-dir/test.txt ", TRUE, FALSE },
191  { __LINE__, 0, "attrib attr-dir/test.txt", TRUE, FALSE, NULL, NULL, " H " },
192  { __LINE__, 0, "attrib +H attr-dir/test.txt", TRUE, FALSE },
193  { __LINE__, 0, "attrib attr-dir/test.txt", TRUE, FALSE, NULL, NULL, " H " },
194  { __LINE__, 0, "attrib -H attr-dir/test.txt", TRUE, FALSE, "test.txt" },
195  { __LINE__, 0, "attrib attr-dir/test.txt", TRUE, FALSE, NULL, NULL, " H " },
196  { __LINE__, 0, "attrib +H attr-dir", FALSE, FALSE, NULL, NULL, " H " },
197  { __LINE__, 0, "attrib attr-dir", TRUE, FALSE, " H " },
198  { __LINE__, 0, "attrib attr-dir/test.txt", TRUE, FALSE, NULL, NULL, " H " },
199  { __LINE__, 0, "attrib -H attr-dir", FALSE, FALSE, NULL, NULL, " H " },
200  { __LINE__, 0, "attrib attr-dir", TRUE, FALSE, NULL, NULL, " H " },
201  { __LINE__, 0, "cmd /c if exist attr-dir/test.txt attrib -H attr-dir/test.txt" },
202  { __LINE__, 0, "cmd /c if exist attr-dir/test.txt del /Q attr-dir/test.txt" },
203  { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" },
204 
205  /* attr-dir, attr-dir\\dir1 */
206  { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" },
207  { __LINE__, 0, "cmd /c mkdir attr-dir", FALSE, FALSE },
208  { __LINE__, 0, "attrib attr-dir", TRUE, FALSE, NULL, NULL, " H " },
209  { __LINE__, 0, "cmd /c if exist attr-dir echo OK", TRUE, FALSE, "OK" },
210  { __LINE__, 0, "cmd /c mkdir attr-dir\\dir1", FALSE, FALSE },
211  { __LINE__, 0, "cmd /c if exist attr-dir\\dir1 echo OK", TRUE, FALSE, "OK" },
212  { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
213  { __LINE__, 0, "attrib +H attr-dir\\dir1", FALSE, FALSE },
214  { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, " H " },
215  { __LINE__, 0, "attrib -H attr-dir\\dir1", FALSE, FALSE },
216  { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
217  { __LINE__, 0, "attrib +H attr-dir", FALSE, FALSE },
218  { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
219  { __LINE__, 0, "attrib -H attr-dir", FALSE, FALSE },
220  { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
221  { __LINE__, 0, "attrib +H attr-d*", TRUE, FALSE, "attr-d*" },
222  { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
223  { __LINE__, 0, "attrib -H attr-d*", TRUE, FALSE, "attr-d*" },
224  { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
225  { __LINE__, 0, "attrib +H attr-dir\\d*", TRUE, FALSE, "attr-dir\\d*" },
226  { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
227  { __LINE__, 0, "attrib -H attr-dir\\d*", TRUE, FALSE, "attr-dir\\d*" },
228  { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
229  { __LINE__, 0, "attrib -H attr-dir\\dir1", FALSE, FALSE },
230  { __LINE__, 0, "attrib -H attr-dir", FALSE, FALSE },
231  { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" },
232 
233  /* /S attr-dir, attr-dir\\dir1 */
234  { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" },
235  { __LINE__, 0, "cmd /c mkdir attr-dir", FALSE, FALSE },
236  { __LINE__, 0, "attrib /S attr-dir", TRUE, FALSE, NULL, NULL, " H " },
237  { __LINE__, 0, "cmd /c if exist attr-dir echo OK", TRUE, FALSE, "OK" },
238  { __LINE__, 0, "cmd /c mkdir attr-dir\\dir1", FALSE, FALSE },
239  { __LINE__, 0, "cmd /c if exist attr-dir\\dir1 echo OK", TRUE, FALSE, "OK" },
240  { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
241  { __LINE__, 0, "attrib /S +H attr-dir\\dir1", TRUE, FALSE, "attr-dir\\dir1", },
242  { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, "attr-dir\\dir1" },
243  { __LINE__, 0, "attrib /S -H attr-dir\\dir1", TRUE, FALSE, "attr-dir\\dir1" },
244  { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
245  { __LINE__, 0, "attrib /S +H attr-dir", TRUE, FALSE, "attr-dir" },
246  { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
247  { __LINE__, 0, "attrib /S -H attr-dir", TRUE, FALSE, "attr-dir" },
248  { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
249  { __LINE__, 0, "attrib /S +H attr-d*", TRUE, FALSE, "attr-d*" },
250  { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
251  { __LINE__, 0, "attrib /S -H attr-d*", TRUE, FALSE, "attr-d*" },
252  { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
253  { __LINE__, 0, "attrib /S +H attr-dir\\d*", TRUE, FALSE, "attr-dir\\d*" },
254  { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
255  { __LINE__, 0, "attrib /S -H attr-dir\\d*", TRUE, FALSE, "attr-dir\\d*" },
256  { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
257  { __LINE__, 0, "attrib /S -H attr-dir\\dir1", TRUE, FALSE, "attr-dir\\dir1" },
258  { __LINE__, 0, "attrib /S -H attr-dir", TRUE, FALSE, "attr-dir" },
259  { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" },
260 
261  /* /S /D attr-dir, attr-dir\\dir1 */
262  { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" },
263  { __LINE__, 0, "cmd /c mkdir attr-dir", FALSE, FALSE },
264  { __LINE__, 0, "attrib /S /D attr-dir", TRUE, FALSE, NULL, NULL, " H " },
265  { __LINE__, 0, "cmd /c if exist attr-dir echo OK", TRUE, FALSE, "OK" },
266  { __LINE__, 0, "cmd /c mkdir attr-dir\\dir1", FALSE, FALSE },
267  { __LINE__, 0, "cmd /c if exist attr-dir\\dir1 echo OK", TRUE, FALSE, "OK" },
268  { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
269  { __LINE__, 0, "attrib /S /D +H attr-dir\\dir1", FALSE, FALSE },
270  { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, " H " },
271  { __LINE__, 0, "attrib /S /D -H attr-dir\\dir1", FALSE, FALSE },
272  { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
273  { __LINE__, 0, "attrib /S /D +H attr-dir", FALSE, FALSE },
274  { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
275  { __LINE__, 0, "attrib /S /D -H attr-dir", FALSE, FALSE },
276  { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
277  { __LINE__, 0, "attrib /S /D +H attr-d*", FALSE, FALSE },
278  { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
279  { __LINE__, 0, "attrib /S /D -H attr-d*", FALSE, FALSE },
280  { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " },
281  { __LINE__, 0, "attrib /S /D +H attr-dir\\d*", FALSE, FALSE },
282  { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, " H " },
283  { __LINE__, 0, "attrib /S /D -H attr-dir\\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\\dir1", FALSE, FALSE },
286  { __LINE__, 0, "attrib /S /D -H attr-dir", FALSE, FALSE },
287  { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" },
288 };
289 
290 static BOOL MyDuplicateHandle(HANDLE hFile, PHANDLE phFile, BOOL bInherit)
291 {
293  return DuplicateHandle(hProcess, hFile, hProcess, phFile, 0,
294  bInherit, DUPLICATE_SAME_ACCESS);
295 }
296 
297 static BOOL PrepareForRedirect(STARTUPINFOA *psi, PHANDLE phInputWrite,
298  PHANDLE phOutputRead, PHANDLE phErrorRead)
299 {
300  HANDLE hInputRead = NULL, hInputWriteTmp = NULL;
301  HANDLE hOutputReadTmp = NULL, hOutputWrite = NULL;
302  HANDLE hErrorReadTmp = NULL, hErrorWrite = NULL;
303  SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, TRUE };
304 
305  psi->hStdInput = NULL;
306  psi->hStdOutput = NULL;
307  psi->hStdError = NULL;
308 
309  if (phInputWrite)
310  {
311  if (CreatePipe(&hInputRead, &hInputWriteTmp, &sa, 0))
312  {
313  if (!MyDuplicateHandle(hInputWriteTmp, phInputWrite, FALSE))
314  goto failed;
315 
316  CloseHandle(hInputWriteTmp);
317  }
318  else
319  goto failed;
320  }
321 
322  if (phOutputRead)
323  {
324  if (CreatePipe(&hOutputReadTmp, &hOutputWrite, &sa, 0))
325  {
326  if (!MyDuplicateHandle(hOutputReadTmp, phOutputRead, FALSE))
327  goto failed;
328 
329  CloseHandle(hOutputReadTmp);
330  }
331  else
332  goto failed;
333  }
334 
335  if (phOutputRead && phOutputRead == phErrorRead)
336  {
337  if (!MyDuplicateHandle(hOutputWrite, &hErrorWrite, TRUE))
338  goto failed;
339  }
340  else if (phErrorRead)
341  {
342  if (CreatePipe(&hErrorReadTmp, &hErrorWrite, &sa, 0))
343  {
344  if (!MyDuplicateHandle(hErrorReadTmp, phErrorRead, FALSE))
345  goto failed;
346  CloseHandle(hErrorReadTmp);
347  }
348  else
349  goto failed;
350  }
351 
352  if (phInputWrite)
353  psi->hStdInput = hInputRead;
354  if (phOutputRead)
355  psi->hStdOutput = hOutputWrite;
356  if (phErrorRead)
357  psi->hStdError = hErrorWrite;
358 
359  return TRUE;
360 
361 failed:
362  CloseHandle(hInputRead);
363  CloseHandle(hInputWriteTmp);
364  CloseHandle(hOutputReadTmp);
365  CloseHandle(hOutputWrite);
366  CloseHandle(hErrorReadTmp);
367  CloseHandle(hErrorWrite);
368  return FALSE;
369 }
370 
371 static void DoTestEntry(const TEST_ENTRY *pEntry)
372 {
373  STARTUPINFOA si;
375  DWORD dwExitCode, dwWait;
376  HANDLE hOutputRead = NULL;
377  HANDLE hErrorRead = NULL;
378  DWORD dwRead;
379  BOOL bStdOutput, bStdError;
380  CHAR szOut[512], szErr[512];
381 
382  memset(&si, 0, sizeof(si));
383  si.cb = sizeof(si);
385 
386  if (!PrepareForRedirect(&si, NULL, &hOutputRead, &hErrorRead))
387  {
388  skip("PrepareForRedirect failed\n");
389  return;
390  }
391 
392  if (CreateProcessA(NULL, (char *)pEntry->cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
393  {
395  dwWait = WaitForSingleObject(pi.hProcess, TIMEOUT);
396  if (dwWait == WAIT_TIMEOUT)
397  {
398  TerminateProcess(pi.hProcess, 9999);
399  }
400  GetExitCodeProcess(pi.hProcess, &dwExitCode);
401  CloseHandle(pi.hThread);
402  CloseHandle(pi.hProcess);
403  }
404  else
405  {
406  dwExitCode = 8888;
407  }
408 
409  ZeroMemory(szOut, sizeof(szOut));
410  PeekNamedPipe(hOutputRead, szOut, ARRAYSIZE(szOut), &dwRead, NULL, NULL);
411  szOut[ARRAYSIZE(szOut) - 1] = 0;
412  bStdOutput = dwRead != 0;
413 
414  ZeroMemory(szErr, sizeof(szErr));
415  PeekNamedPipe(hErrorRead, szErr, ARRAYSIZE(szErr), &dwRead, NULL, NULL);
416  szErr[ARRAYSIZE(szErr) - 1] = 0;
417  bStdError = dwRead != 0;
418 
419  if (si.hStdInput)
421  if (si.hStdOutput)
423  if (si.hStdError)
425 
426  ok(pEntry->bStdOutput == bStdOutput,
427  "Line %u: bStdOutput %d vs %d\n",
428  pEntry->line, pEntry->bStdOutput, bStdOutput);
429 
430  ok(pEntry->bStdError == bStdError,
431  "Line %u: bStdError %d vs %d\n",
432  pEntry->line, pEntry->bStdError, bStdError);
433 
434  ok(pEntry->dwExitCode == dwExitCode,
435  "Line %u: dwExitCode %ld vs %ld\n",
436  pEntry->line, pEntry->dwExitCode, dwExitCode);
437 
438  if (pEntry->OutputContains)
439  {
440  ok(strstr(szOut, pEntry->OutputContains) != NULL,
441  "Line %u: szOut was '%s'\n",
442  pEntry->line, szOut);
443  }
444 
445  if (pEntry->ErrorContains)
446  {
447  ok(strstr(szErr, pEntry->ErrorContains) != NULL,
448  "Line %u: szErr was '%s'\n",
449  pEntry->line, szErr);
450  }
451 
452  if (pEntry->OutputNotContains)
453  {
454  ok(strstr(szOut, pEntry->OutputNotContains) == NULL,
455  "Line %u: szOut was '%s'\n",
456  pEntry->line, szOut);
457  }
458 
459  if (pEntry->ErrorNotContains)
460  {
461  ok(strstr(szErr, pEntry->ErrorNotContains) == NULL,
462  "Line %u: szErr was '%s'\n",
463  pEntry->line, szErr);
464  }
465 }
466 
468 {
469  SIZE_T i;
470  for (i = 0; i < ARRAYSIZE(s_exit_entries); ++i)
471  {
473  }
474 }
475 
477 {
478  SIZE_T i;
479  for (i = 0; i < ARRAYSIZE(s_echo_entries); ++i)
480  {
482  }
483 }
484 
486 {
487  SIZE_T i;
488  for (i = 0; i < ARRAYSIZE(s_cd_entries); ++i)
489  {
491  }
492 }
493 
495 {
496  SIZE_T i;
497  for (i = 0; i < ARRAYSIZE(s_pushd_entries); ++i)
498  {
500  }
501 }
502 
503 START_TEST(attrib)
504 {
505  SIZE_T i;
506  for (i = 0; i < ARRAYSIZE(s_attrib_entries); ++i)
507  {
509  }
510 }
static void DoTestEntry(const TEST_ENTRY *pEntry)
Definition: cmd.c:371
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:406
static BOOL MyDuplicateHandle(HANDLE hFile, PHANDLE phFile, BOOL bInherit)
Definition: cmd.c:290
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:297
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
START_TEST(exit)
Definition: cmd.c:467
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
INT line
Definition: cmd.c:14
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