Reactos
1/*
2 * PROJECT: ReactOS API tests
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Tests for the NtQueryOpenSubKeys API
5 * COPYRIGHT: Copyright 2023 George Bișoc <george.bisoc@reactos.org>
6 */
7
8#include "precomp.h"
9
10START_TEST(NtQueryOpenSubKeys)
11{
12 NTSTATUS Status;
13 OBJECT_ATTRIBUTES ObjectAttributes;
14 ULONG Subkeys;
15 UNICODE_STRING RegistryKey = RTL_CONSTANT_STRING(L"\\Registry");
16 UNICODE_STRING SystemKey = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM");
17 UNICODE_STRING SoftwareKey = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SOFTWARE");
18 UNICODE_STRING DefaultUserKey = RTL_CONSTANT_STRING(L"\\Registry\\User\\.DEFAULT");
19
20 /* We give no object attributes and no return variable */
21 Status = NtQueryOpenSubKeys(NULL, NULL);
22 ok_ntstatus(Status, STATUS_ACCESS_VIOLATION);
23
24 /* Build a key path to the main registry tree */
25 InitializeObjectAttributes(&ObjectAttributes,
26 &RegistryKey,
27 OBJ_CASE_INSENSITIVE,
28 NULL,
29 NULL);
30
31 /* We give object attributes but no return variable */
32 Status = NtQueryOpenSubKeys(&ObjectAttributes, NULL);
33 ok_ntstatus(Status, STATUS_ACCESS_VIOLATION);
34
35 /*
36 * We give no object attributes but return variable.
37 *
38 * NOTE: Windows 10 and Server 2003 return different kinds of status
39 * codes. In Server 2003 it returns STATUS_ACCESS_VIOLATION because
40 * this function implements more probe checks against the object
41 * attributes parameter (namely the path name of the object) so it
42 * fails earlier. In Windows 10 instead the function only probes the
43 * memory address of the object attributes so that it resides in the boundary
44 * of the UM memory range so the function lets this NULL parameter
45 * slide through until ObOpenObjectByName hits this parameter as being
46 * NULL and returns STATUS_INVALID_PARAMETER. Currently ReactOS follows
47 * the behavior of Windows 10.
48 */
49 Status = NtQueryOpenSubKeys(NULL, &Subkeys);
50 ok(Status == STATUS_ACCESS_VIOLATION || Status == STATUS_INVALID_PARAMETER,
51 "STATUS_ACCESS_VIOLATION or STATUS_INVALID_PARAMETER expected, got 0x%lx\n", Status);
52
53 /* Garbage return variable, this function doesn't check for alignment */
54 Status = NtQueryOpenSubKeys(&ObjectAttributes, (PVOID)1);
55 ok_ntstatus(Status, STATUS_ACCESS_VIOLATION);
56
57 /* Return the open subkeys of this key now */
58 Status = NtQueryOpenSubKeys(&ObjectAttributes, &Subkeys);
59 ok_ntstatus(Status, STATUS_SUCCESS);
60
61 trace("\\Registry has %lu opened subkeys\n", Subkeys);
62
63 /* Build a key path to the SYSTEM key */
64 InitializeObjectAttributes(&ObjectAttributes,
65 &SystemKey,
66 OBJ_CASE_INSENSITIVE,
67 NULL,
68 NULL);
69
70 /* Return the open subkeys of this key now */
71 Status = NtQueryOpenSubKeys(&ObjectAttributes, &Subkeys);
72 ok_ntstatus(Status, STATUS_SUCCESS);
73
74 trace("\\Registry\\Machine\\SYSTEM has %lu opened subkeys\n", Subkeys);
75
76 /* Build a key path to the SYSTEM key */
77 InitializeObjectAttributes(&ObjectAttributes,
78 &SoftwareKey,
79 OBJ_CASE_INSENSITIVE,
80 NULL,
81 NULL);
82
83 /* Return the open subkeys of this key now */
84 Status = NtQueryOpenSubKeys(&ObjectAttributes, &Subkeys);
85 ok_ntstatus(Status, STATUS_SUCCESS);
86
87 trace("\\Registry\\Machine\\SOFTWARE has %lu opened subkeys\n", Subkeys);
88
89 /* Build a key path to the default user key */
90 InitializeObjectAttributes(&ObjectAttributes,
91 &DefaultUserKey,
92 OBJ_CASE_INSENSITIVE,
93 NULL,
94 NULL);
95
96 /* Return the open subkeys of this key now */
97 Status = NtQueryOpenSubKeys(&ObjectAttributes, &Subkeys);
98 ok_ntstatus(Status, STATUS_SUCCESS);
99
100 trace("\\Registry\\User\\.DEFAULT has %lu opened subkeys\n", Subkeys);
101}