Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545/* * PROJECT: ReactOS API tests * LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+) * PURPOSE: Test for cmd.exe * COPYRIGHT: Copyright 2019 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> */
#include "precomp.h"
#define TIMEOUT 3000
typedef struct TEST_ENTRY{ INT line; DWORD dwExitCode; const char *cmdline; BOOL bStdOutput; BOOL bStdError; const char *OutputContains; const char *ErrorContains; const char *OutputNotContains; const char *ErrorNotContains;} TEST_ENTRY;
#define TRISTATE 2
static const TEST_ENTRY s_exit_entries[] ={ { __LINE__, 0, "cmd /c exit" }, { __LINE__, 0, "cmd /c exit 0" }, { __LINE__, 0, "cmd /c exit \"\"" }, { __LINE__, 0, "cmd /c exit ABC" }, { __LINE__, 0, "cmd /c exit \"ABC" }, { __LINE__, 0, "cmd /c exit \"ABC\"" }, { __LINE__, 1234, "cmd /c exit 1234" },};
static const TEST_ENTRY s_echo_entries[] ={// { __LINE__, 0, "cmd /c echo", TRUE, FALSE, NULL, "ECHO" }, { __LINE__, 0, "cmd /c echo.", TRUE, FALSE, "\r\n" }, { __LINE__, 0, "cmd /c echo ABC", TRUE, FALSE, "ABC\r\n" },};
static const TEST_ENTRY s_cd_entries[] ={ { __LINE__, 0, "cmd /c cd \"C:\\ " }, { __LINE__, 0, "cmd /c cd C:/" }, { __LINE__, 0, "cmd /c cd \"\"", TRUE, FALSE }, { __LINE__, 0, "cmd /c cd", TRUE, FALSE }, { __LINE__, 1234, "cmd /c cd C:\\Program Files && exit 1234" }, { __LINE__, 1234, "cmd /c cd \"C:\\ \" && exit 1234" }, { __LINE__, 1234, "cmd /c cd \"C:\\Program Files\" && exit 1234" }, { __LINE__, 1234, "cmd /c cd \"\" && exit 1234", TRUE, FALSE }, { __LINE__, 1234, "cmd /c cd \\ && exit 1234" },};
static const TEST_ENTRY s_pushd_entries[] ={ { __LINE__, 0, "cmd /c pushd C:\\ " }, { __LINE__, 0, "cmd /c pushd C:\\ \"" }, { __LINE__, 0, "cmd /c pushd C:\\ \"\"" }, { __LINE__, 0, "cmd /c pushd C:\\ \"\"\"" }, { __LINE__, 0, "cmd /c pushd C:\\ \"\"\"\"" }, { __LINE__, 0, "cmd /c pushd C:\\ \" " }, { __LINE__, 0, "cmd /c pushd C:\\ \"\" " }, { __LINE__, 0, "cmd /c pushd C:\\ \"\"\" " }, { __LINE__, 0, "cmd /c pushd C:\\ \"\"\"\" " }, { __LINE__, 0, "cmd /c pushd C:\\" }, { __LINE__, 0, "cmd /c pushd C:\\\"" }, { __LINE__, 0, "cmd /c pushd C:\\\"\"" }, { __LINE__, 0, "cmd /c pushd C:\\\"\"\"" }, { __LINE__, 0, "cmd /c pushd C:\\\"\"\"\"" }, { __LINE__, 0, "cmd /c pushd C:\\\" " }, { __LINE__, 0, "cmd /c pushd C:\\\"\" " }, { __LINE__, 0, "cmd /c pushd C:\\\"\"\" " }, { __LINE__, 0, "cmd /c pushd C:\\\"\"\"\" " }, { __LINE__, 0, "cmd /c pushd \"C:\\ " }, { __LINE__, 0, "cmd /c pushd \"C:\\ \"" }, { __LINE__, 0, "cmd /c pushd \"C:\\ \"\"" }, { __LINE__, 0, "cmd /c pushd \"C:\\ \"\"\"" }, { __LINE__, 0, "cmd /c pushd \"C:\\ \"\"\"\"" }, { __LINE__, 0, "cmd /c pushd \"C:\\ \" " }, { __LINE__, 0, "cmd /c pushd \"C:\\ \"\" " }, { __LINE__, 0, "cmd /c pushd \"C:\\ \"\"\" " }, { __LINE__, 0, "cmd /c pushd \"C:\\ \"\"\"\" " }, { __LINE__, 0, "cmd /c pushd \"C:\\" }, { __LINE__, 0, "cmd /c pushd \"C:\\\"" }, { __LINE__, 0, "cmd /c pushd \"C:\\\"\"" }, { __LINE__, 0, "cmd /c pushd \"C:\\\"\"\"" }, { __LINE__, 0, "cmd /c pushd \"C:\\\"\"\"\"" }, { __LINE__, 0, "cmd /c pushd \"C:\\\"" }, { __LINE__, 1, "cmd /c pushd \" C:\\ ", FALSE, TRUE }, { __LINE__, 1, "cmd /c pushd \" C:\\ \"", FALSE, TRUE }, { __LINE__, 1, "cmd /c pushd \" C:\\ \"\"", FALSE, TRUE }, { __LINE__, 1, "cmd /c pushd \" C:\\ \"\"\"", FALSE, TRUE }, { __LINE__, 1, "cmd /c pushd \" C:\\ \"\"\"\"", FALSE, TRUE }, { __LINE__, 1, "cmd /c pushd \"\" C:\\ ", FALSE, TRUE }, { __LINE__, 1, "cmd /c pushd \"\" C:\\ \"", FALSE, TRUE }, { __LINE__, 1, "cmd /c pushd \"\" C:\\ \"\"", FALSE, TRUE }, { __LINE__, 1, "cmd /c pushd \"\" C:\\ \"\"\"", FALSE, TRUE }, { __LINE__, 1, "cmd /c pushd \"\" C:\\ \"\"\"\"", FALSE, TRUE }, { __LINE__, 1, "cmd /c pushd \"\" C:\\\"", FALSE, TRUE }, { __LINE__, 1, "cmd /c popd ABC" }, { __LINE__, 1, "cmd /c popd \" " }, { __LINE__, 1, "cmd /c popd \"\"" }, { __LINE__, 1, "cmd /c popd" }, { __LINE__, 1, "cmd /c pushd ABC", FALSE, TRUE }, { __LINE__, 1, "cmd /c pushd C:/Program Files && popd && exit 1234", FALSE, TRUE }, { __LINE__, 1, "cmd /c pushd C:\\ C:\\ && popd && exit 1234", FALSE, TRUE }, { __LINE__, 1, "cmd /c pushd C:\\Invalid Directory && exit 1234", FALSE, TRUE }, { __LINE__, 1, "cmd /c pushd C:\\Invalid Directory && popd && exit 1234", FALSE, TRUE }, { __LINE__, 1, "cmd /c pushd \" C:\\ ", FALSE, TRUE }, { __LINE__, 1, "cmd /c pushd \"C:\\ C:\\\" && popd && exit 1234", FALSE, TRUE }, { __LINE__, 1234, "cmd /c pushd && exit 1234 " }, { __LINE__, 1234, "cmd /c pushd C:\\ && popd && exit 1234" }, { __LINE__, 1234, "cmd /c pushd C:\\ \"\" && popd && exit 1234" }, { __LINE__, 1234, "cmd /c pushd C:\\Program Files && popd && exit 1234" },// { __LINE__, 1234, "cmd /c pushd \"C:/Program Files/\" && popd && exit 1234" },// { __LINE__, 1234, "cmd /c pushd \"C:/Program Files\" && popd && exit 1234" }, { __LINE__, 1234, "cmd /c pushd \"C:\\ \" && popd && exit 1234" }, { __LINE__, 1234, "cmd /c pushd \"C:\\ \"\"\" && popd && exit 1234" }, { __LINE__, 1234, "cmd /c pushd \"C:\\ \"\"\"\"\" && popd && exit 1234" }, { __LINE__, 1234, "cmd /c pushd \"C:\\Program Files\" && popd && exit 1234" }, { __LINE__, 1234, "cmd /c pushd \"C:\\Program Files\\\" && popd && exit 1234" }, { __LINE__, 1234, "cmd /c pushd \"C:\\\" && popd && exit 1234" },};
static const TEST_ENTRY s_attrib_entries[] ={ /* invalid-path.txt */ { __LINE__, 0, "attrib invalid-path.txt", TRUE, FALSE }, { __LINE__, 0, "attrib +H invalid-path.txt", TRUE, FALSE }, { __LINE__, 0, "attrib -H invalid-path.txt", TRUE, FALSE },
/* attr-test.txt */ { __LINE__, 0, "cmd /c if exist attr-test.txt attrib -H attr-test.txt" }, { __LINE__, 0, "cmd /c if exist attr-test.txt del /Q attr-test.txt" }, { __LINE__, 0, "cmd /c copy NUL attr-test.txt ", TRUE, FALSE }, { __LINE__, 0, "attrib attr-test.txt", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib +H attr-test.txt", FALSE, FALSE }, { __LINE__, 0, "attrib attr-test.txt", TRUE, FALSE, " H " }, { __LINE__, 0, "attrib -H attr-test.txt", FALSE, FALSE }, { __LINE__, 0, "attrib attr-test.txt", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib attr-te*.txt", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib +H attr-te*.txt", FALSE, FALSE }, { __LINE__, 0, "attrib attr-te*.txt", TRUE, FALSE, " H " }, { __LINE__, 0, "attrib -H attr-te*.txt", FALSE, FALSE }, { __LINE__, 0, "attrib attr-te*.txt", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "cmd /c if exist attr-test.txt attrib -H attr-test.txt" }, { __LINE__, 0, "cmd /c if exist attr-test.txt del /Q attr-test.txt" },
/* /S attr-test.txt */ { __LINE__, 0, "cmd /c if exist attr-test.txt attrib -H attr-test.txt" }, { __LINE__, 0, "cmd /c if exist attr-test.txt del /Q attr-test.txt" }, { __LINE__, 0, "cmd /c copy NUL attr-test.txt ", TRUE, FALSE }, { __LINE__, 0, "attrib /S attr-test.txt", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S +H attr-test.txt", FALSE, FALSE }, { __LINE__, 0, "attrib /S attr-test.txt", TRUE, FALSE, " H " }, { __LINE__, 0, "attrib /S -H attr-test.txt", FALSE, FALSE }, { __LINE__, 0, "attrib /S attr-test.txt", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S attr-te*.txt", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S +H attr-te*.txt", FALSE, FALSE }, { __LINE__, 0, "attrib /S attr-te*.txt", TRUE, FALSE, " H " }, { __LINE__, 0, "attrib /S -H attr-te*.txt", FALSE, FALSE }, { __LINE__, 0, "attrib /S attr-te*.txt", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S +H", TRISTATE, FALSE }, { __LINE__, 0, "attrib /S attr-test.txt", TRUE, FALSE, " H " }, { __LINE__, 0, "attrib /S -H", TRISTATE, FALSE }, { __LINE__, 0, "attrib /S attr-test.txt", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "cmd /c if exist attr-test.txt attrib -H attr-test.txt" }, { __LINE__, 0, "cmd /c if exist attr-test.txt del /Q attr-test.txt" },
/* /S /D attr-test.txt */ { __LINE__, 0, "cmd /c if exist attr-test.txt attrib -H attr-test.txt" }, { __LINE__, 0, "cmd /c if exist attr-test.txt del /Q attr-test.txt" }, { __LINE__, 0, "cmd /c copy NUL attr-test.txt ", TRUE, FALSE }, { __LINE__, 0, "attrib /S /D attr-test.txt", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S /D +H attr-test.txt", FALSE, FALSE }, { __LINE__, 0, "attrib /S /D attr-test.txt", TRUE, FALSE, " H " }, { __LINE__, 0, "attrib /S /D -H attr-test.txt", FALSE, FALSE }, { __LINE__, 0, "attrib /S /D attr-test.txt", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S /D attr-te*.txt", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S /D +H attr-te*.txt", FALSE, FALSE }, { __LINE__, 0, "attrib /S /D attr-te*.txt", TRUE, FALSE, " H " }, { __LINE__, 0, "attrib /S /D -H attr-te*.txt", FALSE, FALSE }, { __LINE__, 0, "attrib /S /D attr-te*.txt", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "cmd /c if exist attr-test.txt attrib -H attr-test.txt" }, { __LINE__, 0, "cmd /c if exist attr-test.txt del /Q attr-test.txt" },
/* attr-dir, attr-dir/test.txt */ { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" }, { __LINE__, 0, "cmd /c mkdir attr-dir", FALSE, FALSE }, { __LINE__, 0, "cmd /c if exist attr-dir/test.txt attrib -H attr-dir/test.txt" }, { __LINE__, 0, "cmd /c if exist attr-dir/test.txt del /Q attr-dir/test.txt" }, { __LINE__, 1, "cmd /c copy NUL attr-dir/test.txt ", TRUE, FALSE }, { __LINE__, 0, "attrib attr-dir/test.txt", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib +H attr-dir/test.txt", TRUE, FALSE }, { __LINE__, 0, "attrib attr-dir/test.txt", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib -H attr-dir/test.txt", TRUE, FALSE, "test.txt" }, { __LINE__, 0, "attrib attr-dir/test.txt", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib +H attr-dir", FALSE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib attr-dir", TRUE, FALSE, " H " }, { __LINE__, 0, "attrib attr-dir/test.txt", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib -H attr-dir", FALSE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib attr-dir", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "cmd /c if exist attr-dir/test.txt attrib -H attr-dir/test.txt" }, { __LINE__, 0, "cmd /c if exist attr-dir/test.txt del /Q attr-dir/test.txt" }, { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" },
/* attr-dir, attr-dir\\dir1 */ { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" }, { __LINE__, 0, "cmd /c mkdir attr-dir", FALSE, FALSE }, { __LINE__, 0, "attrib attr-dir", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "cmd /c if exist attr-dir echo OK", TRUE, FALSE, "OK" }, { __LINE__, 0, "cmd /c mkdir attr-dir\\dir1", FALSE, FALSE }, { __LINE__, 0, "cmd /c if exist attr-dir\\dir1 echo OK", TRUE, FALSE, "OK" }, { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib +H attr-dir\\dir1", FALSE, FALSE }, { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, " H " }, { __LINE__, 0, "attrib -H attr-dir\\dir1", FALSE, FALSE }, { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib +H attr-dir", FALSE, FALSE }, { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib -H attr-dir", FALSE, FALSE }, { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib +H attr-d*", TRUE, FALSE, "attr-d*" }, { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib -H attr-d*", TRUE, FALSE, "attr-d*" }, { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib +H attr-dir\\d*", TRUE, FALSE, "attr-dir\\d*" }, { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib -H attr-dir\\d*", TRUE, FALSE, "attr-dir\\d*" }, { __LINE__, 0, "attrib attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib -H attr-dir\\dir1", FALSE, FALSE }, { __LINE__, 0, "attrib -H attr-dir", FALSE, FALSE }, { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" },
/* /S attr-dir, attr-dir\\dir1 */ { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" }, { __LINE__, 0, "cmd /c mkdir attr-dir", FALSE, FALSE }, { __LINE__, 0, "attrib /S attr-dir", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "cmd /c if exist attr-dir echo OK", TRUE, FALSE, "OK" }, { __LINE__, 0, "cmd /c mkdir attr-dir\\dir1", FALSE, FALSE }, { __LINE__, 0, "cmd /c if exist attr-dir\\dir1 echo OK", TRUE, FALSE, "OK" }, { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S +H attr-dir\\dir1", TRUE, FALSE, "attr-dir\\dir1", }, { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, "attr-dir\\dir1" }, { __LINE__, 0, "attrib /S -H attr-dir\\dir1", TRUE, FALSE, "attr-dir\\dir1" }, { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S +H attr-dir", TRUE, FALSE, "attr-dir" }, { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S -H attr-dir", TRUE, FALSE, "attr-dir" }, { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S +H attr-d*", TRUE, FALSE, "attr-d*" }, { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S -H attr-d*", TRUE, FALSE, "attr-d*" }, { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S +H attr-dir\\d*", TRUE, FALSE, "attr-dir\\d*" }, { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S -H attr-dir\\d*", TRUE, FALSE, "attr-dir\\d*" }, { __LINE__, 0, "attrib /S attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S -H attr-dir\\dir1", TRUE, FALSE, "attr-dir\\dir1" }, { __LINE__, 0, "attrib /S -H attr-dir", TRUE, FALSE, "attr-dir" }, { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" },
/* /S /D attr-dir, attr-dir\\dir1 */ { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" }, { __LINE__, 0, "cmd /c mkdir attr-dir", FALSE, FALSE }, { __LINE__, 0, "attrib /S /D attr-dir", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "cmd /c if exist attr-dir echo OK", TRUE, FALSE, "OK" }, { __LINE__, 0, "cmd /c mkdir attr-dir\\dir1", FALSE, FALSE }, { __LINE__, 0, "cmd /c if exist attr-dir\\dir1 echo OK", TRUE, FALSE, "OK" }, { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S /D +H attr-dir\\dir1", FALSE, FALSE }, { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, " H " }, { __LINE__, 0, "attrib /S /D -H attr-dir\\dir1", FALSE, FALSE }, { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S /D +H attr-dir", FALSE, FALSE }, { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S /D -H attr-dir", FALSE, FALSE }, { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S /D +H attr-d*", FALSE, FALSE }, { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S /D -H attr-d*", FALSE, FALSE }, { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S /D +H attr-dir\\d*", FALSE, FALSE }, { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, " H " }, { __LINE__, 0, "attrib /S /D -H attr-dir\\d*", FALSE, FALSE }, { __LINE__, 0, "attrib /S /D attr-dir\\dir1", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S /D -H attr-dir\\dir1", FALSE, FALSE }, { __LINE__, 0, "attrib /S /D -H attr-dir", FALSE, FALSE }, { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" },
/* /S attr-dir, attr-dir\\dir1\\file.txt */ { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" }, { __LINE__, 0, "cmd /c mkdir attr-dir", FALSE, FALSE }, { __LINE__, 0, "attrib /S /D attr-dir", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "cmd /c if exist attr-dir echo OK", TRUE, FALSE, "OK" }, { __LINE__, 0, "cmd /c mkdir attr-dir\\dir1", FALSE, FALSE }, { __LINE__, 0, "cmd /c if exist attr-dir\\dir1 echo OK", TRUE, FALSE, "OK" }, { __LINE__, 0, "cmd /c copy NUL attr-dir\\dir1\\attr-test.txt ", TRUE, FALSE }, { __LINE__, 0, "attrib attr-dir\\dir1\\attr-test.txt", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S +H attr-dir\\dir1\\attr-test.txt", FALSE, FALSE }, { __LINE__, 0, "attrib /S attr-test.txt", TRUE, FALSE, " H " }, { __LINE__, 0, "attrib /S -H attr-dir\\dir1\\attr-test.txt", FALSE, FALSE }, { __LINE__, 0, "attrib /S attr-test.txt", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S +H attr-test.txt", FALSE, FALSE }, { __LINE__, 0, "attrib /S attr-test.txt", TRUE, FALSE, " H " }, { __LINE__, 0, "attrib /S -H attr-test.txt", FALSE, FALSE }, { __LINE__, 0, "attrib /S attr-test.txt", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S +H", TRISTATE, FALSE }, { __LINE__, 0, "attrib /S attr-test.txt", TRUE, FALSE, " H " }, { __LINE__, 0, "attrib /S attr-tes*.*", TRUE, FALSE, " H " }, { __LINE__, 0, "attrib /S -H", TRISTATE, FALSE }, { __LINE__, 0, "attrib /S attr-test.txt", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "attrib /S attr-tes*.*", TRUE, FALSE, NULL, NULL, " H " }, { __LINE__, 0, "cmd /c if exist attr-dir/dir1/test.txt attrib -H attr-dir/dir1/test.txt" }, { __LINE__, 0, "cmd /c if exist attr-dir/dir1/test.txt del /Q attr-dir/dir1/test.txt" }, { __LINE__, 0, "cmd /c if exist attr-dir rmdir /s /q attr-dir" },
};
static BOOL MyDuplicateHandle(HANDLE hFile, PHANDLE phFile, BOOL bInherit){ HANDLE hProcess = GetCurrentProcess(); return DuplicateHandle(hProcess, hFile, hProcess, phFile, 0, bInherit, DUPLICATE_SAME_ACCESS);}
static BOOL PrepareForRedirect(STARTUPINFOA *psi, PHANDLE phInputWrite, PHANDLE phOutputRead, PHANDLE phErrorRead){ HANDLE hInputRead = NULL, hInputWriteTmp = NULL; HANDLE hOutputReadTmp = NULL, hOutputWrite = NULL; HANDLE hErrorReadTmp = NULL, hErrorWrite = NULL; SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, TRUE };
psi->hStdInput = NULL; psi->hStdOutput = NULL; psi->hStdError = NULL;
if (phInputWrite) { if (CreatePipe(&hInputRead, &hInputWriteTmp, &sa, 0)) { if (!MyDuplicateHandle(hInputWriteTmp, phInputWrite, FALSE)) goto failed;
CloseHandle(hInputWriteTmp); } else goto failed; }
if (phOutputRead) { if (CreatePipe(&hOutputReadTmp, &hOutputWrite, &sa, 0)) { if (!MyDuplicateHandle(hOutputReadTmp, phOutputRead, FALSE)) goto failed;
CloseHandle(hOutputReadTmp); } else goto failed; }
if (phOutputRead && phOutputRead == phErrorRead) { if (!MyDuplicateHandle(hOutputWrite, &hErrorWrite, TRUE)) goto failed; } else if (phErrorRead) { if (CreatePipe(&hErrorReadTmp, &hErrorWrite, &sa, 0)) { if (!MyDuplicateHandle(hErrorReadTmp, phErrorRead, FALSE)) goto failed; CloseHandle(hErrorReadTmp); } else goto failed; }
if (phInputWrite) psi->hStdInput = hInputRead; if (phOutputRead) psi->hStdOutput = hOutputWrite; if (phErrorRead) psi->hStdError = hErrorWrite;
return TRUE;
failed: CloseHandle(hInputRead); CloseHandle(hInputWriteTmp); CloseHandle(hOutputReadTmp); CloseHandle(hOutputWrite); CloseHandle(hErrorReadTmp); CloseHandle(hErrorWrite); return FALSE;}
static void DoTestEntry(const TEST_ENTRY *pEntry){ STARTUPINFOA si; PROCESS_INFORMATION pi; DWORD dwExitCode, dwWait; HANDLE hOutputRead = NULL; HANDLE hErrorRead = NULL; DWORD dwRead; BOOL bStdOutput, bStdError; CHAR szOut[512], szErr[512];
memset(&si, 0, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES;
if (!PrepareForRedirect(&si, NULL, &hOutputRead, &hErrorRead)) { skip("PrepareForRedirect failed\n"); return; }
if (CreateProcessA(NULL, (char *)pEntry->cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) { CloseHandle(si.hStdInput); dwWait = WaitForSingleObject(pi.hProcess, TIMEOUT); if (dwWait == WAIT_TIMEOUT) { TerminateProcess(pi.hProcess, 9999); } GetExitCodeProcess(pi.hProcess, &dwExitCode); CloseHandle(pi.hThread); CloseHandle(pi.hProcess); } else { dwExitCode = 8888; }
ZeroMemory(szOut, sizeof(szOut)); PeekNamedPipe(hOutputRead, szOut, ARRAYSIZE(szOut), &dwRead, NULL, NULL); szOut[ARRAYSIZE(szOut) - 1] = 0; bStdOutput = dwRead != 0;
ZeroMemory(szErr, sizeof(szErr)); PeekNamedPipe(hErrorRead, szErr, ARRAYSIZE(szErr), &dwRead, NULL, NULL); szErr[ARRAYSIZE(szErr) - 1] = 0; bStdError = dwRead != 0;
if (si.hStdInput) CloseHandle(si.hStdInput); if (si.hStdOutput) CloseHandle(si.hStdOutput); if (si.hStdError) CloseHandle(si.hStdError);
ok(pEntry->bStdOutput == bStdOutput || pEntry->bStdOutput == TRISTATE, "Line %u: bStdOutput %d vs %d\n", pEntry->line, pEntry->bStdOutput, bStdOutput);
ok(pEntry->bStdError == bStdError || pEntry->bStdOutput == TRISTATE, "Line %u: bStdError %d vs %d\n", pEntry->line, pEntry->bStdError, bStdError);
ok(pEntry->dwExitCode == dwExitCode, "Line %u: dwExitCode %ld vs %ld\n", pEntry->line, pEntry->dwExitCode, dwExitCode);
if (pEntry->OutputContains) { ok(strstr(szOut, pEntry->OutputContains) != NULL, "Line %u: szOut was '%s'\n", pEntry->line, szOut); }
if (pEntry->ErrorContains) { ok(strstr(szErr, pEntry->ErrorContains) != NULL, "Line %u: szErr was '%s'\n", pEntry->line, szErr); }
if (pEntry->OutputNotContains) { ok(strstr(szOut, pEntry->OutputNotContains) == NULL, "Line %u: szOut was '%s'\n", pEntry->line, szOut); }
if (pEntry->ErrorNotContains) { ok(strstr(szErr, pEntry->ErrorNotContains) == NULL, "Line %u: szErr was '%s'\n", pEntry->line, szErr); }}
START_TEST(exit){ SIZE_T i; for (i = 0; i < ARRAYSIZE(s_exit_entries); ++i) { DoTestEntry(&s_exit_entries[i]); }}
START_TEST(echo){ SIZE_T i; for (i = 0; i < ARRAYSIZE(s_echo_entries); ++i) { DoTestEntry(&s_echo_entries[i]); }}
START_TEST(cd){ SIZE_T i; for (i = 0; i < ARRAYSIZE(s_cd_entries); ++i) { DoTestEntry(&s_cd_entries[i]); }}
START_TEST(pushd){ SIZE_T i; for (i = 0; i < ARRAYSIZE(s_pushd_entries); ++i) { DoTestEntry(&s_pushd_entries[i]); }}
START_TEST(attrib){ SIZE_T i; for (i = 0; i < ARRAYSIZE(s_attrib_entries); ++i) { DoTestEntry(&s_attrib_entries[i]); }}