xref: /reactos/modules/rostests/winetests/reg/query.c (revision 1a6f523e)
17fcb8acaSwinesync /*
27fcb8acaSwinesync  * Copyright 2014 Akihiro Sagawa
37fcb8acaSwinesync  * Copyright 2016-2018, 2021 Hugh McMaster
47fcb8acaSwinesync  *
57fcb8acaSwinesync  * This library is free software; you can redistribute it and/or
67fcb8acaSwinesync  * modify it under the terms of the GNU Lesser General Public
77fcb8acaSwinesync  * License as published by the Free Software Foundation; either
87fcb8acaSwinesync  * version 2.1 of the License, or (at your option) any later version.
97fcb8acaSwinesync  *
107fcb8acaSwinesync  * This library is distributed in the hope that it will be useful,
117fcb8acaSwinesync  * but WITHOUT ANY WARRANTY; without even the implied warranty of
127fcb8acaSwinesync  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
137fcb8acaSwinesync  * Lesser General Public License for more details.
147fcb8acaSwinesync  *
157fcb8acaSwinesync  * You should have received a copy of the GNU Lesser General Public
167fcb8acaSwinesync  * License along with this library; if not, write to the Free Software
177fcb8acaSwinesync  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
187fcb8acaSwinesync  */
197fcb8acaSwinesync 
207fcb8acaSwinesync #include "reg_test.h"
217fcb8acaSwinesync 
read_from_pipe(HANDLE child_proc_stdout,BYTE * buf,DWORD buf_size)225132d26cSwinesync static void read_from_pipe(HANDLE child_proc_stdout, BYTE *buf, DWORD buf_size)
235132d26cSwinesync {
245132d26cSwinesync     DWORD read, len = 0;
255132d26cSwinesync     BOOL ret;
265132d26cSwinesync 
275132d26cSwinesync     while (1)
285132d26cSwinesync     {
295132d26cSwinesync         ret = ReadFile(child_proc_stdout, buf + len, buf_size - len, &read, NULL);
305132d26cSwinesync         if (!ret || !read) break;
315132d26cSwinesync 
325132d26cSwinesync         len += read;
335132d26cSwinesync     }
345132d26cSwinesync 
355132d26cSwinesync     buf[len] = 0;
365132d26cSwinesync }
375132d26cSwinesync 
385132d26cSwinesync #define read_reg_output(c,b,s,r) read_reg_output_(__FILE__,__LINE__,c,b,s,r)
read_reg_output_(const char * file,unsigned line,const char * cmd,BYTE * buf,DWORD buf_size,DWORD * rc)395132d26cSwinesync static BOOL read_reg_output_(const char *file, unsigned line, const char *cmd,
405132d26cSwinesync                              BYTE *buf, DWORD buf_size, DWORD *rc)
415132d26cSwinesync {
425132d26cSwinesync     SECURITY_ATTRIBUTES sa;
435132d26cSwinesync     HANDLE pipe_stdout_rd, pipe_stdout_wr;
445132d26cSwinesync     STARTUPINFOA si = {0};
455132d26cSwinesync     PROCESS_INFORMATION pi;
465132d26cSwinesync     char cmdline[256];
475132d26cSwinesync     BOOL bret;
485132d26cSwinesync     DWORD ret;
495132d26cSwinesync 
505132d26cSwinesync     sa.nLength = sizeof(SECURITY_ATTRIBUTES);
515132d26cSwinesync     sa.bInheritHandle = TRUE;
525132d26cSwinesync     sa.lpSecurityDescriptor = NULL;
535132d26cSwinesync 
545132d26cSwinesync     if (!CreatePipe(&pipe_stdout_rd, &pipe_stdout_wr, &sa, 0))
555132d26cSwinesync         return FALSE;
565132d26cSwinesync 
575132d26cSwinesync     if (!SetHandleInformation(pipe_stdout_rd, HANDLE_FLAG_INHERIT, 0))
585132d26cSwinesync         return FALSE;
595132d26cSwinesync 
605132d26cSwinesync     si.cb = sizeof(si);
615132d26cSwinesync     si.dwFlags = STARTF_USESTDHANDLES;
625132d26cSwinesync     si.hStdInput = INVALID_HANDLE_VALUE;
635132d26cSwinesync     si.hStdOutput = pipe_stdout_wr;
645132d26cSwinesync     si.hStdError = INVALID_HANDLE_VALUE;
655132d26cSwinesync 
665132d26cSwinesync     strcpy(cmdline, cmd);
675132d26cSwinesync     if (!CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
685132d26cSwinesync         return FALSE;
695132d26cSwinesync 
705132d26cSwinesync     CloseHandle(pipe_stdout_wr);
715132d26cSwinesync 
725132d26cSwinesync     read_from_pipe(pipe_stdout_rd, buf, buf_size);
735132d26cSwinesync 
745132d26cSwinesync     ret = WaitForSingleObject(pi.hProcess, 10000);
755132d26cSwinesync     if (ret == WAIT_TIMEOUT)
765132d26cSwinesync         TerminateProcess(pi.hProcess, 1);
775132d26cSwinesync 
785132d26cSwinesync     bret = GetExitCodeProcess(pi.hProcess, rc);
795132d26cSwinesync     lok(bret, "GetExitCodeProcess failed: %d\n", GetLastError());
805132d26cSwinesync 
815132d26cSwinesync     CloseHandle(pipe_stdout_rd);
825132d26cSwinesync     CloseHandle(pi.hThread);
835132d26cSwinesync     CloseHandle(pi.hProcess);
845132d26cSwinesync     return bret;
855132d26cSwinesync }
865132d26cSwinesync 
87e77afe91Swinesync #define compare_query(b,e,c,todo) compare_query_(__FILE__,__LINE__,b,e,c,todo)
compare_query_(const char * file,unsigned line,const BYTE * buf,const char * expected,BOOL cmp_len,DWORD todo)885132d26cSwinesync static void compare_query_(const char *file, unsigned line, const BYTE *buf,
89e77afe91Swinesync                            const char *expected, BOOL cmp_len, DWORD todo)
90e77afe91Swinesync {
91e77afe91Swinesync     const char *str = (const char *)buf;
92e77afe91Swinesync     const char *err = "query output does not match expected output";
93e77afe91Swinesync 
94e77afe91Swinesync     if (!cmp_len)
955132d26cSwinesync     {
965132d26cSwinesync         todo_wine_if (todo & TODO_REG_COMPARE)
97e77afe91Swinesync             lok(!strcmp(str, expected), "%s\n", err);
98e77afe91Swinesync     }
99e77afe91Swinesync     else
100e77afe91Swinesync     {
101e77afe91Swinesync         todo_wine_if (todo & TODO_REG_COMPARE)
102e77afe91Swinesync             lok(!strncmp(str, expected, strlen(expected)), "%s\n", err);
103e77afe91Swinesync     }
1045132d26cSwinesync }
1055132d26cSwinesync 
1065132d26cSwinesync /* Unit tests */
1075132d26cSwinesync 
test_command_syntax(void)108e8969684Swinesync static void test_command_syntax(void)
109e8969684Swinesync {
110e8969684Swinesync     DWORD r;
111e8969684Swinesync 
112e8969684Swinesync     run_reg_exe("reg query", &r);
113e8969684Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
114e8969684Swinesync 
115e8969684Swinesync     run_reg_exe("reg query /?", &r);
116e8969684Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
117e8969684Swinesync 
118e8969684Swinesync     run_reg_exe("reg query /h", &r);
119e8969684Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
120e8969684Swinesync 
121e8969684Swinesync     run_reg_exe("reg query -H", &r);
122e8969684Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
123e8969684Swinesync 
124e8969684Swinesync     run_reg_exe("reg query HKCU\\" KEY_BASE " /v", &r);
125e8969684Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
126e8969684Swinesync 
127e8969684Swinesync     run_reg_exe("reg query HKCU\\" KEY_BASE " /v Test1 /v Test2", &r);
128e8969684Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
129e8969684Swinesync 
130e8969684Swinesync     run_reg_exe("reg query HKCU\\" KEY_BASE " /v Test1 /ve", &r);
131e8969684Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
132e8969684Swinesync 
133e8969684Swinesync     run_reg_exe("reg query HKCU\\" KEY_BASE " /s /s", &r);
134e8969684Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
1354e13fbcfSwinesync 
1364e13fbcfSwinesync     /* Test registry view */
1374e13fbcfSwinesync     run_reg_exe("reg query HKCU\\" KEY_BASE " /reg:32 /reg:32", &r);
1384e13fbcfSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
1394e13fbcfSwinesync 
1404e13fbcfSwinesync     run_reg_exe("reg query HKCU\\" KEY_BASE " /reg:32 /reg:64", &r);
1414e13fbcfSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
1424e13fbcfSwinesync 
1434e13fbcfSwinesync     run_reg_exe("reg query HKCU\\" KEY_BASE " /reg:64 /reg:64", &r);
1444e13fbcfSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
145e8969684Swinesync }
146e8969684Swinesync 
test_query(void)1477fcb8acaSwinesync static void test_query(void)
1487fcb8acaSwinesync {
1495132d26cSwinesync     const char *test1 = "\r\n"
1505132d26cSwinesync         "HKEY_CURRENT_USER\\" KEY_BASE "\r\n"
1515132d26cSwinesync         "    Test1    REG_SZ    Hello, World\r\n"
1525132d26cSwinesync         "    Test2    REG_DWORD    0x123\r\n\r\n";
1535132d26cSwinesync 
1545132d26cSwinesync     const char *test2 = "\r\n"
1555132d26cSwinesync         "HKEY_CURRENT_USER\\" KEY_BASE "\r\n"
1565132d26cSwinesync         "    Test1    REG_SZ    Hello, World\r\n\r\n";
1575132d26cSwinesync 
1585132d26cSwinesync     const char *test3 = "\r\n"
1595132d26cSwinesync         "HKEY_CURRENT_USER\\" KEY_BASE "\r\n"
1605132d26cSwinesync         "    Test1    REG_SZ    Hello, World\r\n"
1615132d26cSwinesync         "    Test2    REG_DWORD    0x123\r\n"
1625132d26cSwinesync         "    Wine    REG_SZ    First instance\r\n\r\n"
1635132d26cSwinesync         "HKEY_CURRENT_USER\\" KEY_BASE "\\subkey\r\n";
1645132d26cSwinesync 
1655132d26cSwinesync     const char *test4 = "\r\n"
1665132d26cSwinesync         "HKEY_CURRENT_USER\\" KEY_BASE "\\subkey\r\n"
1675132d26cSwinesync         "    Test3    REG_SZ    Some string data\r\n"
1685132d26cSwinesync         "    Test4    REG_DWORD    0xabc\r\n\r\n";
1695132d26cSwinesync 
1705132d26cSwinesync     const char *test5 = "\r\n"
1715132d26cSwinesync         "HKEY_CURRENT_USER\\" KEY_BASE "\\subkey\r\n"
1725132d26cSwinesync         "    Test4    REG_DWORD    0xabc\r\n\r\n";
1735132d26cSwinesync 
174e77afe91Swinesync     const char *test6 = "\r\n"
175e77afe91Swinesync         "HKEY_CURRENT_USER\\" KEY_BASE "\r\n"
176e77afe91Swinesync         "    Test1    REG_SZ    Hello, World\r\n"
177e77afe91Swinesync         "    Test2    REG_DWORD    0x123\r\n"
178e77afe91Swinesync         "    Wine    REG_SZ    First instance\r\n\r\n"
179e77afe91Swinesync         "HKEY_CURRENT_USER\\" KEY_BASE "\\subkey\r\n"
180e77afe91Swinesync         "    Test3    REG_SZ    Some string data\r\n"
181e77afe91Swinesync         "    Test4    REG_DWORD    0xabc\r\n"
182e77afe91Swinesync         "    Wine    REG_SZ    Second instance\r\n\r\n";
183e77afe91Swinesync 
184e77afe91Swinesync     const char *test7 = "\r\n"
185e77afe91Swinesync         "HKEY_CURRENT_USER\\" KEY_BASE "\r\n"
186e77afe91Swinesync         "    Wine    REG_SZ    First instance\r\n\r\n"
187e77afe91Swinesync         "HKEY_CURRENT_USER\\" KEY_BASE "\\subkey\r\n"
188e77afe91Swinesync         "    Wine    REG_SZ    Second instance\r\n\r\n";
189e77afe91Swinesync 
1904771673cSwinesync     const char *test8a = "\r\n"
1914771673cSwinesync         "HKEY_CURRENT_USER\\" KEY_BASE "\\subkey1\r\n"
1924771673cSwinesync         "HKEY_CURRENT_USER\\" KEY_BASE "\\subkey2\r\n"
1934771673cSwinesync         "HKEY_CURRENT_USER\\" KEY_BASE "\\subkey3\r\n"
1944771673cSwinesync         "HKEY_CURRENT_USER\\" KEY_BASE "\\subkey4\r\n";
1954771673cSwinesync 
1964771673cSwinesync     const char *test8b = "\r\n"
1974771673cSwinesync         "HKEY_CURRENT_USER\\" KEY_BASE "\\subkey1\r\n\r\n"
1984771673cSwinesync         "HKEY_CURRENT_USER\\" KEY_BASE "\\subkey2\r\n\r\n"
1994771673cSwinesync         "HKEY_CURRENT_USER\\" KEY_BASE "\\subkey3\r\n\r\n"
2004771673cSwinesync         "HKEY_CURRENT_USER\\" KEY_BASE "\\subkey4\r\n\r\n";
2014771673cSwinesync 
202a12c8448Swinesync     DWORD r, dword = 0x123;
203d552b44fSwinesync     HKEY hkey, subkey;
2045132d26cSwinesync     BYTE buf[512];
2057fcb8acaSwinesync 
20644c2f0d9Swinesync     delete_tree(HKEY_CURRENT_USER, KEY_BASE, 0);
2077fcb8acaSwinesync 
2082535ff3fSwinesync     /* Key not present */
2092535ff3fSwinesync     run_reg_exe("reg query HKCU\\" KEY_BASE, &r);
2102535ff3fSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
2112535ff3fSwinesync 
2127fcb8acaSwinesync     /* Create a test key */
21377b2d21eSwinesync     add_key(HKEY_CURRENT_USER, KEY_BASE, 0, &hkey);
214d552b44fSwinesync     add_value(hkey, "Test1", REG_SZ, "Hello, World", 13);
215d552b44fSwinesync     add_value(hkey, "Test2", REG_DWORD, &dword, sizeof(dword));
2167fcb8acaSwinesync 
2177fcb8acaSwinesync     run_reg_exe("reg query HKCU\\" KEY_BASE " /v Missing", &r);
2187fcb8acaSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
2197fcb8acaSwinesync 
2205132d26cSwinesync     read_reg_output("reg query HKCU\\" KEY_BASE, buf, sizeof(buf), &r);
221a12c8448Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
222e77afe91Swinesync     compare_query(buf, test1, FALSE, 0);
223a12c8448Swinesync 
224b12d7980Swinesync     run_reg_exe("reg query HKCU\\" KEY_BASE " /ve", &r);
225b12d7980Swinesync     ok(r == REG_EXIT_SUCCESS || broken(r == REG_EXIT_FAILURE /* WinXP */),
226b12d7980Swinesync        "got exit code %d, expected 0\n", r);
227b12d7980Swinesync 
2285132d26cSwinesync     read_reg_output("reg query HKCU\\" KEY_BASE " /v Test1", buf, sizeof(buf), &r);
229b12d7980Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
230e77afe91Swinesync     compare_query(buf, test2, FALSE, 0);
231b12d7980Swinesync 
232a12c8448Swinesync     run_reg_exe("reg query HKCU\\" KEY_BASE " /v Test2", &r);
2337fcb8acaSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
2347fcb8acaSwinesync 
235d552b44fSwinesync     add_value(hkey, "Wine", REG_SZ, "First instance", 15);
2367fcb8acaSwinesync 
2377fcb8acaSwinesync     /* Create a test subkey */
23877b2d21eSwinesync     add_key(hkey, "subkey", 0, &subkey);
2395132d26cSwinesync 
2405132d26cSwinesync     read_reg_output("reg query HKCU\\" KEY_BASE, buf, sizeof(buf), &r);
2415132d26cSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
242a3bf868eSwinesync     compare_query(buf, test3, FALSE, 0);
2435132d26cSwinesync 
244a12c8448Swinesync     add_value(subkey, "Test3", REG_SZ, "Some string data", 16);
245a12c8448Swinesync     dword = 0xabc;
246a12c8448Swinesync     add_value(subkey, "Test4", REG_DWORD, &dword, sizeof(dword));
2477fcb8acaSwinesync 
2485132d26cSwinesync     read_reg_output("reg query HKCU\\" KEY_BASE "\\subkey", buf, sizeof(buf), &r);
2497fcb8acaSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
250e77afe91Swinesync     compare_query(buf, test4, FALSE, 0);
2517fcb8acaSwinesync 
252a12c8448Swinesync     run_reg_exe("reg query HKCU\\" KEY_BASE "\\subkey /v Test3", &r);
2537fcb8acaSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
2547fcb8acaSwinesync 
2555132d26cSwinesync     read_reg_output("reg query HKCU\\" KEY_BASE "\\subkey /v Test4", buf, sizeof(buf), &r);
2567fcb8acaSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
257e77afe91Swinesync     compare_query(buf, test5, FALSE, 0);
2587fcb8acaSwinesync 
259a12c8448Swinesync     add_value(subkey, "Wine", REG_SZ, "Second instance", 16);
2607fcb8acaSwinesync 
2617fcb8acaSwinesync     /* Test recursion */
262e77afe91Swinesync     read_reg_output("reg query HKCU\\" KEY_BASE " /s", buf, sizeof(buf), &r);
2637fcb8acaSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
264e77afe91Swinesync     compare_query(buf, test6, FALSE, 0);
2657fcb8acaSwinesync 
26616cc1ad7Swinesync     read_reg_output("reg query HKCU\\" KEY_BASE "\\ /s", buf, sizeof(buf), &r);
26716cc1ad7Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
268a0060cdcSwinesync     compare_query(buf, test6, FALSE, 0);
26916cc1ad7Swinesync 
270e77afe91Swinesync     read_reg_output("reg query HKCU\\" KEY_BASE " /v Wine /s", buf, sizeof(buf), &r);
2717fcb8acaSwinesync     ok(r == REG_EXIT_SUCCESS || r == REG_EXIT_FAILURE /* WinXP */,
2727fcb8acaSwinesync        "got exit code %d, expected 0\n", r);
273e77afe91Swinesync     compare_query(buf, test7, TRUE, 0);
2747fcb8acaSwinesync 
275d552b44fSwinesync     add_value(hkey, NULL, REG_SZ, "Empty", 6);
276a12c8448Swinesync     add_value(subkey, NULL, REG_SZ, "Empty", 6);
277a12c8448Swinesync     close_key(subkey);
278d552b44fSwinesync     close_key(hkey);
279a12c8448Swinesync 
280a12c8448Swinesync     run_reg_exe("reg query HKCU\\" KEY_BASE "\\subkey /ve", &r);
281a12c8448Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
282a12c8448Swinesync 
2837fcb8acaSwinesync     run_reg_exe("reg query HKCU\\" KEY_BASE " /ve /s", &r);
2847fcb8acaSwinesync     ok(r == REG_EXIT_SUCCESS || r == REG_EXIT_FAILURE /* WinXP */,
2857fcb8acaSwinesync        "got exit code %d, expected 0\n", r);
2867fcb8acaSwinesync 
28744c2f0d9Swinesync     delete_tree(HKEY_CURRENT_USER, KEY_BASE, 0);
2884771673cSwinesync 
2894771673cSwinesync     /* Subkeys only */
29077b2d21eSwinesync     add_key(HKEY_CURRENT_USER, KEY_BASE, 0, &hkey);
29177b2d21eSwinesync     add_key(hkey, "subkey1", 0, NULL);
29277b2d21eSwinesync     add_key(hkey, "subkey2", 0, NULL);
29377b2d21eSwinesync     add_key(hkey, "subkey3", 0, NULL);
29477b2d21eSwinesync     add_key(hkey, "subkey4", 0, NULL);
2954771673cSwinesync     close_key(hkey);
2964771673cSwinesync 
2974771673cSwinesync     read_reg_output("reg query HKCU\\" KEY_BASE, buf, sizeof(buf), &r);
2984771673cSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
29914b77379Swinesync     compare_query(buf, test8a, FALSE, 0);
3004771673cSwinesync 
3014771673cSwinesync     read_reg_output("reg query HKCU\\" KEY_BASE " /s", buf, sizeof(buf), &r);
3024771673cSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
3033dbd4208Swinesync     compare_query(buf, test8b, FALSE, 0);
3044771673cSwinesync 
30544c2f0d9Swinesync     delete_tree(HKEY_CURRENT_USER, KEY_BASE, 0);
3067fcb8acaSwinesync }
3077fcb8acaSwinesync 
308*1a6f523eSThomas Csovcsity #if 0
3094e13fbcfSwinesync static const char *test9a = "\r\n"
3104e13fbcfSwinesync     "HKEY_LOCAL_MACHINE\\" KEY_BASE "\r\n"
3114e13fbcfSwinesync     "    Test1    REG_SZ    Hello, World\r\n"
3124e13fbcfSwinesync     "    Test2    REG_DWORD    0x123\r\n"
3134e13fbcfSwinesync     "    Wine    REG_SZ    First instance\r\n\r\n"
3144e13fbcfSwinesync     "HKEY_LOCAL_MACHINE\\" KEY_BASE "\\subkey\r\n";
3154e13fbcfSwinesync 
3164e13fbcfSwinesync static const char *test9b = "\r\n"
3174e13fbcfSwinesync     "HKEY_LOCAL_MACHINE\\" KEY_BASE "\r\n"
3184e13fbcfSwinesync     "    Test1    REG_SZ    Hello, World\r\n"
3194e13fbcfSwinesync     "    Test2    REG_DWORD    0x123\r\n"
3204e13fbcfSwinesync     "    Wine    REG_SZ    First instance\r\n\r\n"
3214e13fbcfSwinesync     "HKEY_LOCAL_MACHINE\\" KEY_BASE "\\subkey\r\n"
3224e13fbcfSwinesync     "    Test3    REG_SZ    Some string data\r\n"
3234e13fbcfSwinesync     "    Test4    REG_DWORD    0xabc\r\n"
3244e13fbcfSwinesync     "    Wine    REG_SZ    Second instance\r\n\r\n";
3254e13fbcfSwinesync 
3262592a360Swinesync static const char *test9c = "\r\n"
3272592a360Swinesync     "HKEY_LOCAL_MACHINE\\" KEY_BASE "\r\n"
3282592a360Swinesync     "    Wine    REG_SZ    First instance\r\n\r\n"
3292592a360Swinesync     "HKEY_LOCAL_MACHINE\\" KEY_BASE "\\subkey\r\n"
3302592a360Swinesync     "    Wine    REG_SZ    Second instance\r\n\r\n";
3312592a360Swinesync 
3324e13fbcfSwinesync static void create_test_key(REGSAM sam)
3334e13fbcfSwinesync {
3344e13fbcfSwinesync     HKEY hkey, subkey;
3354e13fbcfSwinesync     DWORD dword;
3364e13fbcfSwinesync 
3374e13fbcfSwinesync     add_key(HKEY_LOCAL_MACHINE, KEY_BASE, sam, &hkey);
3384e13fbcfSwinesync     add_value(hkey, "Test1", REG_SZ, "Hello, World", 13);
3394e13fbcfSwinesync     dword = 0x123;
3404e13fbcfSwinesync     add_value(hkey, "Test2", REG_DWORD, &dword, sizeof(dword));
3414e13fbcfSwinesync     add_value(hkey, "Wine", REG_SZ, "First instance", 15);
3424e13fbcfSwinesync 
3434e13fbcfSwinesync     add_key(hkey, "subkey", sam, &subkey);
3444e13fbcfSwinesync     add_value(subkey, "Test3", REG_SZ, "Some string data", 16);
3454e13fbcfSwinesync     dword = 0xabc;
3464e13fbcfSwinesync     add_value(subkey, "Test4", REG_DWORD, &dword, sizeof(dword));
3474e13fbcfSwinesync     add_value(subkey, "Wine", REG_SZ, "Second instance", 16);
3484e13fbcfSwinesync 
3494e13fbcfSwinesync     close_key(subkey);
3504e13fbcfSwinesync     close_key(hkey);
3514e13fbcfSwinesync }
3524e13fbcfSwinesync 
3534e13fbcfSwinesync static void test_registry_view_win32(void)
3544e13fbcfSwinesync {
3554e13fbcfSwinesync     BOOL is_wow64, is_win32;
3564e13fbcfSwinesync     DWORD r;
3574e13fbcfSwinesync     BYTE buf[512];
3584e13fbcfSwinesync 
3594e13fbcfSwinesync     IsWow64Process(GetCurrentProcess(), &is_wow64);
3604e13fbcfSwinesync     is_win32 = !is_wow64 && (sizeof(void *) == sizeof(int));
3614e13fbcfSwinesync 
3624e13fbcfSwinesync     if (!is_win32) return;
3634e13fbcfSwinesync 
3644e13fbcfSwinesync     delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY);
3654e13fbcfSwinesync 
3664e13fbcfSwinesync     /* Try querying the 32-bit registry view (32-bit Windows) */
3674e13fbcfSwinesync     create_test_key(KEY_WOW64_32KEY);
3684e13fbcfSwinesync 
3694e13fbcfSwinesync     read_reg_output("reg query HKLM\\" KEY_BASE " /reg:32", buf, sizeof(buf), &r);
3704e13fbcfSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
3714e13fbcfSwinesync     compare_query(buf, test9a, FALSE, 0);
3724e13fbcfSwinesync 
3734e13fbcfSwinesync     read_reg_output("reg query HKLM\\" KEY_BASE " /s /reg:32", buf, sizeof(buf), &r);
3744e13fbcfSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
3754e13fbcfSwinesync     compare_query(buf, test9b, FALSE, 0);
3764e13fbcfSwinesync 
3772592a360Swinesync     read_reg_output("reg query HKLM\\" KEY_BASE " /v Wine /s /reg:32", buf, sizeof(buf), &r);
3782592a360Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
3792592a360Swinesync     compare_query(buf, test9c, TRUE, 0);
3802592a360Swinesync 
3814e13fbcfSwinesync     delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY);
3824e13fbcfSwinesync 
3834e13fbcfSwinesync     /* Try querying the 64-bit registry view, which doesn't exist on 32-bit Windows */
3844e13fbcfSwinesync     create_test_key(KEY_WOW64_64KEY);
3854e13fbcfSwinesync 
3864e13fbcfSwinesync     read_reg_output("reg query HKLM\\" KEY_BASE " /reg:64", buf, sizeof(buf), &r);
3874e13fbcfSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
3884e13fbcfSwinesync     compare_query(buf, test9a, FALSE, 0);
3894e13fbcfSwinesync 
3904e13fbcfSwinesync     read_reg_output("reg query HKLM\\" KEY_BASE " /s /reg:64", buf, sizeof(buf), &r);
3914e13fbcfSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
3924e13fbcfSwinesync     compare_query(buf, test9b, FALSE, 0);
3934e13fbcfSwinesync 
3942592a360Swinesync     read_reg_output("reg query HKLM\\" KEY_BASE " /v Wine /s /reg:64", buf, sizeof(buf), &r);
3952592a360Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
3962592a360Swinesync     compare_query(buf, test9c, TRUE, 0);
3972592a360Swinesync 
3984e13fbcfSwinesync     delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_64KEY);
3994e13fbcfSwinesync }
4004e13fbcfSwinesync 
4014e13fbcfSwinesync static void test_registry_view_win64(void)
4024e13fbcfSwinesync {
4034e13fbcfSwinesync     BOOL is_wow64, is_win64;
4044e13fbcfSwinesync     DWORD r;
4054e13fbcfSwinesync     BYTE buf[512];
4064e13fbcfSwinesync 
4074e13fbcfSwinesync     IsWow64Process(GetCurrentProcess(), &is_wow64);
4084e13fbcfSwinesync     is_win64 = !is_wow64 && (sizeof(void *) > sizeof(int));
4094e13fbcfSwinesync 
4104e13fbcfSwinesync     if (!is_win64) return;
4114e13fbcfSwinesync 
4124e13fbcfSwinesync     delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY);
4134e13fbcfSwinesync 
4144e13fbcfSwinesync     /* Try querying the 32-bit registry view (64-bit Windows) */
4154e13fbcfSwinesync     create_test_key(KEY_WOW64_32KEY);
4164e13fbcfSwinesync 
4174e13fbcfSwinesync     read_reg_output("reg query HKLM\\" KEY_BASE " /reg:32", buf, sizeof(buf), &r);
418c6993373Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
419c6993373Swinesync     compare_query(buf, test9a, FALSE, 0);
4204e13fbcfSwinesync 
4214e13fbcfSwinesync     read_reg_output("reg query HKLM\\" KEY_BASE " /s /reg:32", buf, sizeof(buf), &r);
422c6993373Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
423c6993373Swinesync     compare_query(buf, test9b, FALSE, 0);
4244e13fbcfSwinesync 
4252592a360Swinesync     read_reg_output("reg query HKLM\\" KEY_BASE " /v Wine /s /reg:32", buf, sizeof(buf), &r);
426c6993373Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
427c6993373Swinesync     compare_query(buf, test9c, TRUE, 0);
4282592a360Swinesync 
4294e13fbcfSwinesync     delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY);
4304e13fbcfSwinesync     delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_64KEY);
4314e13fbcfSwinesync 
4324e13fbcfSwinesync     /* Try querying the 64-bit registry view (64-bit Windows) */
4334e13fbcfSwinesync     create_test_key(KEY_WOW64_64KEY);
4344e13fbcfSwinesync 
4354e13fbcfSwinesync     read_reg_output("reg query HKLM\\" KEY_BASE " /reg:64", buf, sizeof(buf), &r);
4364e13fbcfSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
4374e13fbcfSwinesync     compare_query(buf, test9a, FALSE, 0);
4384e13fbcfSwinesync 
4394e13fbcfSwinesync     read_reg_output("reg query HKLM\\" KEY_BASE " /s /reg:64", buf, sizeof(buf), &r);
4404e13fbcfSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
4414e13fbcfSwinesync     compare_query(buf, test9b, FALSE, 0);
4424e13fbcfSwinesync 
4432592a360Swinesync     read_reg_output("reg query HKLM\\" KEY_BASE " /v Wine /s /reg:64", buf, sizeof(buf), &r);
4442592a360Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
4452592a360Swinesync     compare_query(buf, test9c, TRUE, 0);
4462592a360Swinesync 
4474e13fbcfSwinesync     delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_64KEY);
4484e13fbcfSwinesync }
4494e13fbcfSwinesync 
4504e13fbcfSwinesync static void test_registry_view_wow64(void)
4514e13fbcfSwinesync {
4524e13fbcfSwinesync     BOOL is_wow64;
4534e13fbcfSwinesync     DWORD r;
4544e13fbcfSwinesync     BYTE buf[512];
4554e13fbcfSwinesync 
4564e13fbcfSwinesync     IsWow64Process(GetCurrentProcess(), &is_wow64);
4574e13fbcfSwinesync 
4584e13fbcfSwinesync     if (!is_wow64) return;
4594e13fbcfSwinesync 
4604e13fbcfSwinesync     delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY);
4614e13fbcfSwinesync 
4624e13fbcfSwinesync     /* Try querying the 32-bit registry view (WOW64) */
4634e13fbcfSwinesync     create_test_key(KEY_WOW64_32KEY);
4644e13fbcfSwinesync 
4654e13fbcfSwinesync     read_reg_output("reg query HKLM\\" KEY_BASE " /reg:32", buf, sizeof(buf), &r);
4664e13fbcfSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
4674e13fbcfSwinesync     compare_query(buf, test9a, FALSE, 0);
4684e13fbcfSwinesync 
4694e13fbcfSwinesync     read_reg_output("reg query HKLM\\" KEY_BASE " /s /reg:32", buf, sizeof(buf), &r);
4704e13fbcfSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
4714e13fbcfSwinesync     compare_query(buf, test9b, FALSE, 0);
4724e13fbcfSwinesync 
4732592a360Swinesync     read_reg_output("reg query HKLM\\" KEY_BASE " /v Wine /s /reg:32", buf, sizeof(buf), &r);
4742592a360Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
4752592a360Swinesync     compare_query(buf, test9c, TRUE, 0);
4762592a360Swinesync 
4774e13fbcfSwinesync     delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY);
4784e13fbcfSwinesync     delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_64KEY);
4794e13fbcfSwinesync 
4804e13fbcfSwinesync     /* Try querying the 64-bit registry view (WOW64) */
4814e13fbcfSwinesync     create_test_key(KEY_WOW64_64KEY);
4824e13fbcfSwinesync 
4834e13fbcfSwinesync     read_reg_output("reg query HKLM\\" KEY_BASE " /reg:64", buf, sizeof(buf), &r);
484c6993373Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
485c6993373Swinesync     compare_query(buf, test9a, FALSE, 0);
4864e13fbcfSwinesync 
4874e13fbcfSwinesync     read_reg_output("reg query HKLM\\" KEY_BASE " /s /reg:64", buf, sizeof(buf), &r);
488c6993373Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
489c6993373Swinesync     compare_query(buf, test9b, FALSE, 0);
4904e13fbcfSwinesync 
4912592a360Swinesync     read_reg_output("reg query HKLM\\" KEY_BASE " /v Wine /s /reg:64", buf, sizeof(buf), &r);
492c6993373Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
493c6993373Swinesync     compare_query(buf, test9c, TRUE, 0);
4942592a360Swinesync 
4954e13fbcfSwinesync     delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_64KEY);
4964e13fbcfSwinesync }
497*1a6f523eSThomas Csovcsity #endif
4984e13fbcfSwinesync 
START_TEST(query)4997fcb8acaSwinesync START_TEST(query)
5007fcb8acaSwinesync {
5017fcb8acaSwinesync     DWORD r;
5027fcb8acaSwinesync 
5037fcb8acaSwinesync     if (!run_reg_exe("reg.exe /?", &r)) {
5047fcb8acaSwinesync         win_skip("reg.exe not available, skipping 'query' tests\n");
5057fcb8acaSwinesync         return;
5067fcb8acaSwinesync     }
5077fcb8acaSwinesync 
508e8969684Swinesync     test_command_syntax();
5097fcb8acaSwinesync     test_query();
5104e13fbcfSwinesync 
5114e13fbcfSwinesync     /* Check if reg.exe is running with elevated privileges */
5124e13fbcfSwinesync     if (!is_elevated_process())
5134e13fbcfSwinesync     {
5144e13fbcfSwinesync         win_skip("reg.exe is not running with elevated privileges; "
5154e13fbcfSwinesync                  "skipping registry view tests\n");
5164e13fbcfSwinesync         return;
5174e13fbcfSwinesync     }
5184e13fbcfSwinesync 
519*1a6f523eSThomas Csovcsity #if 0
5204e13fbcfSwinesync     test_registry_view_win32();
5214e13fbcfSwinesync     test_registry_view_win64();
5224e13fbcfSwinesync     test_registry_view_wow64();
523*1a6f523eSThomas Csovcsity #endif
524*1a6f523eSThomas Csovcsity 
5257fcb8acaSwinesync }
526