reg/tests: Test output of keys with a trailing backslash.
[wine.git] / programs / reg / tests / query.c
blobc475d288fd80f582a4ceeb62eaf57de42795825d
1 /*
2 * Copyright 2014 Akihiro Sagawa
3 * Copyright 2016-2018, 2021 Hugh McMaster
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "reg_test.h"
22 static void read_from_pipe(HANDLE child_proc_stdout, BYTE *buf, DWORD buf_size)
24 DWORD read, len = 0;
25 BOOL ret;
27 while (1)
29 ret = ReadFile(child_proc_stdout, buf + len, buf_size - len, &read, NULL);
30 if (!ret || !read) break;
32 len += read;
35 buf[len] = 0;
38 #define read_reg_output(c,b,s,r) read_reg_output_(__FILE__,__LINE__,c,b,s,r)
39 static BOOL read_reg_output_(const char *file, unsigned line, const char *cmd,
40 BYTE *buf, DWORD buf_size, DWORD *rc)
42 SECURITY_ATTRIBUTES sa;
43 HANDLE pipe_stdout_rd, pipe_stdout_wr;
44 STARTUPINFOA si = {0};
45 PROCESS_INFORMATION pi;
46 char cmdline[256];
47 BOOL bret;
48 DWORD ret;
50 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
51 sa.bInheritHandle = TRUE;
52 sa.lpSecurityDescriptor = NULL;
54 if (!CreatePipe(&pipe_stdout_rd, &pipe_stdout_wr, &sa, 0))
55 return FALSE;
57 if (!SetHandleInformation(pipe_stdout_rd, HANDLE_FLAG_INHERIT, 0))
58 return FALSE;
60 si.cb = sizeof(si);
61 si.dwFlags = STARTF_USESTDHANDLES;
62 si.hStdInput = INVALID_HANDLE_VALUE;
63 si.hStdOutput = pipe_stdout_wr;
64 si.hStdError = INVALID_HANDLE_VALUE;
66 strcpy(cmdline, cmd);
67 if (!CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
68 return FALSE;
70 CloseHandle(pipe_stdout_wr);
72 read_from_pipe(pipe_stdout_rd, buf, buf_size);
74 ret = WaitForSingleObject(pi.hProcess, 10000);
75 if (ret == WAIT_TIMEOUT)
76 TerminateProcess(pi.hProcess, 1);
78 bret = GetExitCodeProcess(pi.hProcess, rc);
79 lok(bret, "GetExitCodeProcess failed: %d\n", GetLastError());
81 CloseHandle(pipe_stdout_rd);
82 CloseHandle(pi.hThread);
83 CloseHandle(pi.hProcess);
84 return bret;
87 #define compare_query(b,e,c,todo) compare_query_(__FILE__,__LINE__,b,e,c,todo)
88 static void compare_query_(const char *file, unsigned line, const BYTE *buf,
89 const char *expected, BOOL cmp_len, DWORD todo)
91 const char *str = (const char *)buf;
92 const char *err = "query output does not match expected output";
94 if (!cmp_len)
96 todo_wine_if (todo & TODO_REG_COMPARE)
97 lok(!strcmp(str, expected), "%s\n", err);
99 else
101 todo_wine_if (todo & TODO_REG_COMPARE)
102 lok(!strncmp(str, expected, strlen(expected)), "%s\n", err);
106 /* Unit tests */
108 static void test_query(void)
110 const char *test1 = "\r\n"
111 "HKEY_CURRENT_USER\\" KEY_BASE "\r\n"
112 " Test1 REG_SZ Hello, World\r\n"
113 " Test2 REG_DWORD 0x123\r\n\r\n";
115 const char *test2 = "\r\n"
116 "HKEY_CURRENT_USER\\" KEY_BASE "\r\n"
117 " Test1 REG_SZ Hello, World\r\n\r\n";
119 const char *test3 = "\r\n"
120 "HKEY_CURRENT_USER\\" KEY_BASE "\r\n"
121 " Test1 REG_SZ Hello, World\r\n"
122 " Test2 REG_DWORD 0x123\r\n"
123 " Wine REG_SZ First instance\r\n\r\n"
124 "HKEY_CURRENT_USER\\" KEY_BASE "\\subkey\r\n";
126 const char *test4 = "\r\n"
127 "HKEY_CURRENT_USER\\" KEY_BASE "\\subkey\r\n"
128 " Test3 REG_SZ Some string data\r\n"
129 " Test4 REG_DWORD 0xabc\r\n\r\n";
131 const char *test5 = "\r\n"
132 "HKEY_CURRENT_USER\\" KEY_BASE "\\subkey\r\n"
133 " Test4 REG_DWORD 0xabc\r\n\r\n";
135 const char *test6 = "\r\n"
136 "HKEY_CURRENT_USER\\" KEY_BASE "\r\n"
137 " Test1 REG_SZ Hello, World\r\n"
138 " Test2 REG_DWORD 0x123\r\n"
139 " Wine REG_SZ First instance\r\n\r\n"
140 "HKEY_CURRENT_USER\\" KEY_BASE "\\subkey\r\n"
141 " Test3 REG_SZ Some string data\r\n"
142 " Test4 REG_DWORD 0xabc\r\n"
143 " Wine REG_SZ Second instance\r\n\r\n";
145 const char *test7 = "\r\n"
146 "HKEY_CURRENT_USER\\" KEY_BASE "\r\n"
147 " Wine REG_SZ First instance\r\n\r\n"
148 "HKEY_CURRENT_USER\\" KEY_BASE "\\subkey\r\n"
149 " Wine REG_SZ Second instance\r\n\r\n";
151 DWORD r, dword = 0x123;
152 HKEY key, subkey;
153 BYTE buf[512];
155 delete_tree(HKEY_CURRENT_USER, KEY_BASE);
156 verify_key_nonexist(HKEY_CURRENT_USER, KEY_BASE);
158 run_reg_exe("reg query", &r);
159 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
161 run_reg_exe("reg query /?", &r);
162 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
164 run_reg_exe("reg query /h", &r);
165 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
167 run_reg_exe("reg query -H", &r);
168 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
170 /* Create a test key */
171 add_key(HKEY_CURRENT_USER, KEY_BASE, &key);
172 add_value(key, "Test1", REG_SZ, "Hello, World", 13);
173 add_value(key, "Test2", REG_DWORD, &dword, sizeof(dword));
175 run_reg_exe("reg query HKCU\\" KEY_BASE " /v", &r);
176 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
178 run_reg_exe("reg query HKCU\\" KEY_BASE " /v Missing", &r);
179 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
181 run_reg_exe("reg query HKCU\\" KEY_BASE " /v Test1 /v Test2", &r);
182 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
184 run_reg_exe("reg query HKCU\\" KEY_BASE " /v Test1 /ve", &r);
185 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
187 run_reg_exe("reg query HKCU\\" KEY_BASE " /s /s", &r);
188 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
190 read_reg_output("reg query HKCU\\" KEY_BASE, buf, sizeof(buf), &r);
191 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
192 compare_query(buf, test1, FALSE, 0);
194 run_reg_exe("reg query HKCU\\" KEY_BASE " /ve", &r);
195 ok(r == REG_EXIT_SUCCESS || broken(r == REG_EXIT_FAILURE /* WinXP */),
196 "got exit code %d, expected 0\n", r);
198 read_reg_output("reg query HKCU\\" KEY_BASE " /v Test1", buf, sizeof(buf), &r);
199 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
200 compare_query(buf, test2, FALSE, 0);
202 run_reg_exe("reg query HKCU\\" KEY_BASE " /v Test2", &r);
203 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
205 add_value(key, "Wine", REG_SZ, "First instance", 15);
207 /* Create a test subkey */
208 add_key(key, "subkey", &subkey);
210 read_reg_output("reg query HKCU\\" KEY_BASE, buf, sizeof(buf), &r);
211 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
212 compare_query(buf, test3, FALSE, TODO_REG_COMPARE);
214 add_value(subkey, "Test3", REG_SZ, "Some string data", 16);
215 dword = 0xabc;
216 add_value(subkey, "Test4", REG_DWORD, &dword, sizeof(dword));
218 read_reg_output("reg query HKCU\\" KEY_BASE "\\subkey", buf, sizeof(buf), &r);
219 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
220 compare_query(buf, test4, FALSE, 0);
222 run_reg_exe("reg query HKCU\\" KEY_BASE "\\subkey /v Test3", &r);
223 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
225 read_reg_output("reg query HKCU\\" KEY_BASE "\\subkey /v Test4", buf, sizeof(buf), &r);
226 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
227 compare_query(buf, test5, FALSE, 0);
229 add_value(subkey, "Wine", REG_SZ, "Second instance", 16);
231 /* Test recursion */
232 read_reg_output("reg query HKCU\\" KEY_BASE " /s", buf, sizeof(buf), &r);
233 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
234 compare_query(buf, test6, FALSE, 0);
236 read_reg_output("reg query HKCU\\" KEY_BASE "\\ /s", buf, sizeof(buf), &r);
237 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
238 compare_query(buf, test6, FALSE, TODO_REG_COMPARE);
240 read_reg_output("reg query HKCU\\" KEY_BASE " /v Wine /s", buf, sizeof(buf), &r);
241 ok(r == REG_EXIT_SUCCESS || r == REG_EXIT_FAILURE /* WinXP */,
242 "got exit code %d, expected 0\n", r);
243 compare_query(buf, test7, TRUE, 0);
245 add_value(key, NULL, REG_SZ, "Empty", 6);
246 add_value(subkey, NULL, REG_SZ, "Empty", 6);
247 close_key(subkey);
249 run_reg_exe("reg query HKCU\\" KEY_BASE "\\subkey /ve", &r);
250 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
252 run_reg_exe("reg query HKCU\\" KEY_BASE " /ve /s", &r);
253 ok(r == REG_EXIT_SUCCESS || r == REG_EXIT_FAILURE /* WinXP */,
254 "got exit code %d, expected 0\n", r);
256 /* Clean-up, then query */
257 delete_key(key, "subkey");
258 close_key(key);
260 run_reg_exe("reg query HKCU\\" KEY_BASE "\\subkey", &r);
261 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
263 delete_key(HKEY_CURRENT_USER, KEY_BASE);
265 run_reg_exe("reg query HKCU\\" KEY_BASE, &r);
266 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
269 START_TEST(query)
271 DWORD r;
273 if (!run_reg_exe("reg.exe /?", &r)) {
274 win_skip("reg.exe not available, skipping 'query' tests\n");
275 return;
278 test_query();