cmd/tests: Add dir built-in command test.
[wine.git] / programs / cmd / tests / directory.c
blob7b965f068b086c7171754197f2819cc84be0e521
1 /*
2 * Copyright 2023 Akihiro Sagawa
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <windows.h>
20 #include "wine/test.h"
22 #define MAX_BUFFER 65536
24 static char stdout_buffer[MAX_BUFFER], stderr_buffer[MAX_BUFFER];
25 static DWORD stdout_size, stderr_size;
26 static char work_dir[MAX_PATH];
28 static void read_all_from_handle(HANDLE handle, char *buffer, DWORD *size)
30 char bytes[4096];
31 DWORD bytes_read;
33 memset(buffer, 0, MAX_BUFFER);
34 *size = 0;
35 for (;;)
37 BOOL success = ReadFile(handle, bytes, sizeof(bytes), &bytes_read, NULL);
38 if (!success || !bytes_read)
39 break;
40 if (*size + bytes_read > MAX_BUFFER)
42 ok(FALSE, "Insufficient buffer.\n");
43 break;
45 memcpy(buffer + *size, bytes, bytes_read);
46 *size += bytes_read;
50 #define run_dir(a, b) _run_dir(__FILE__, __LINE__, a, b)
51 static void _run_dir(const char *file, int line, const char *commandline, int exitcode_expected)
53 HANDLE child_stdout_write, child_stderr_write, parent_stdout_read, parent_stderr_read;
54 SECURITY_ATTRIBUTES security_attributes = {0};
55 PROCESS_INFORMATION process_info = {0};
56 STARTUPINFOA startup_info = {0};
57 DWORD exitcode;
58 char cmd[256];
60 security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
61 security_attributes.bInheritHandle = TRUE;
63 CreatePipe(&parent_stdout_read, &child_stdout_write, &security_attributes, 0);
64 CreatePipe(&parent_stderr_read, &child_stderr_write, &security_attributes, 0);
65 SetHandleInformation(parent_stdout_read, HANDLE_FLAG_INHERIT, 0);
66 SetHandleInformation(parent_stderr_read, HANDLE_FLAG_INHERIT, 0);
68 startup_info.cb = sizeof(STARTUPINFOA);
69 startup_info.hStdOutput = child_stdout_write;
70 startup_info.hStdError = child_stderr_write;
71 startup_info.dwFlags |= STARTF_USESTDHANDLES;
73 sprintf(cmd, "cmd.exe /d /c dir %s", commandline);
74 CreateProcessA(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &startup_info, &process_info);
75 CloseHandle(child_stdout_write);
76 CloseHandle(child_stderr_write);
78 read_all_from_handle(parent_stdout_read, stdout_buffer, &stdout_size);
79 read_all_from_handle(parent_stderr_read, stderr_buffer, &stderr_size);
80 CloseHandle(parent_stdout_read);
81 CloseHandle(parent_stderr_read);
83 WaitForSingleObject(process_info.hProcess, INFINITE);
84 GetExitCodeProcess(process_info.hProcess, &exitcode);
85 CloseHandle(process_info.hProcess);
86 CloseHandle(process_info.hThread);
87 ok_(file, line)(exitcode == exitcode_expected, "expected exitcode %d, got %ld\n",
88 exitcode_expected, exitcode);
91 static void test_basic(void)
93 /* no options */
94 run_dir("", 0);
95 ok(stdout_size > 0, "unexpected stdout buffer size %ld.\n", stdout_size);
96 ok(stderr_size == 0, "unexpected stderr buffer size %ld.\n", stderr_size);
98 /* if file doesn't exist, cmd.exe prints an error message to stderr. */
99 run_dir("nonexistent", 1);
100 ok(stdout_size > 0, "unexpected stdout buffer size %ld.\n", stdout_size);
101 ok(stderr_size > 0, "unexpected stderr buffer size %ld.\n", stderr_size);
103 /* unknown option produces an error message to stderr. */
104 run_dir("/*", 1);
105 ok(stdout_size == 0, "unexpected stdout buffer size %ld.\n", stdout_size);
106 ok(stderr_size > 0, "unexpected stderr buffer size %ld.\n", stderr_size);
108 /* errorlevel for usage is 0. But, cmd.exe's exit code is 1. */
109 todo_wine run_dir("/?", 1);
110 ok(stdout_size > 0, "unexpected stdout buffer size %ld.\n", stdout_size);
111 ok(stderr_size == 0, "unexpected stderr buffer size %ld.\n", stderr_size);
114 START_TEST(directory)
116 WCHAR curdir[MAX_PATH];
117 BOOL ret;
119 GetCurrentDirectoryW(ARRAY_SIZE(curdir), curdir);
120 GetTempPathA(ARRAY_SIZE(work_dir), work_dir);
121 lstrcatA(work_dir, "winetest.dir");
122 ret = CreateDirectoryA(work_dir, NULL);
123 ok(ret, "Failed to create %s\n", work_dir);
124 ret = SetCurrentDirectoryA(work_dir);
125 ok(ret, "Failed to set the working directory\n");
127 test_basic();
129 ret = SetCurrentDirectoryW(curdir);
130 ok(ret, "Failed to restore the current directory\n");
131 ret = RemoveDirectoryA(work_dir);
132 ok(ret, "Failed to remove the working directory\n");