1 /*
2  * PROJECT:         ReactOS API tests
3  * LICENSE:         LGPLv2.1+ - See COPYING.LIB in the top level directory
4  * PURPOSE:         Test for NtCreateKey
5  * PROGRAMMER:      Thomas Faber <thomas.faber@reactos.org>
6  */
7 
8 #include "precomp.h"
9 
10 static
11 VOID
12 VerifyAccess_(
13     _In_ HANDLE Handle,
14     _In_ ACCESS_MASK ExpectedAccess,
15     _In_ PCSTR File,
16     _In_ INT Line)
17 {
18     NTSTATUS Status;
19     OBJECT_BASIC_INFORMATION BasicInfo;
20     ULONG Length;
21 
22     Status = NtQueryObject(Handle,
23                            ObjectBasicInformation,
24                            &BasicInfo,
25                            sizeof(BasicInfo),
26                            &Length);
27     ok_(File, Line)(Status == STATUS_SUCCESS, "NtQueryObject returned 0x%lx\n", Status);
28     ok_(File, Line)(BasicInfo.GrantedAccess == ExpectedAccess,
29                     "GrantedAccess is 0x%lx, expected 0x%lx\n",
30                     BasicInfo.GrantedAccess, ExpectedAccess);
31 }
32 #define VerifyAccess(h, e) VerifyAccess_(h, e, __FILE__, __LINE__)
33 
34 static
35 VOID
36 TestCreateOpen_(
37     _In_ ACCESS_MASK DesiredAccess,
38     _In_ ACCESS_MASK ExpectedAccess,
39     _In_ NTSTATUS ExpectedStatus,
40     _In_ PCSTR File,
41     _In_ INT Line)
42 {
43     NTSTATUS Status;
44     HANDLE KeyHandle;
45     UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software");
46     OBJECT_ATTRIBUTES ObjectAttributes;
47 
48     InitializeObjectAttributes(&ObjectAttributes,
49                                &KeyName,
50                                OBJ_CASE_INSENSITIVE,
51                                NULL,
52                                NULL);
53     Status = NtCreateKey(&KeyHandle,
54                          DesiredAccess,
55                          &ObjectAttributes,
56                          0,
57                          NULL,
58                          REG_OPTION_NON_VOLATILE,
59                          NULL);
60     ok_(File, Line)(Status == ExpectedStatus,
61                     "NtCreateKey returned 0x%lx, expected 0x%lx\n",
62                     Status, ExpectedStatus);
63     if (NT_SUCCESS(Status))
64     {
65         VerifyAccess_(KeyHandle, ExpectedAccess, File, Line);
66         Status = NtClose(KeyHandle);
67         ok_(File, Line)(Status == STATUS_SUCCESS,
68                         "NtClose from NtCreateKey returned 0x%lx\n",
69                         Status);
70     }
71     else if (NT_SUCCESS(ExpectedStatus))
72     {
73         skip_(File, Line)("NtCreateKey failed, skipping\n");
74     }
75 
76     Status = NtOpenKey(&KeyHandle,
77                        DesiredAccess,
78                        &ObjectAttributes);
79     ok_(File, Line)(Status == ExpectedStatus,
80                     "NtOpenKey returned 0x%lx, expected 0x%lx\n",
81                     Status, ExpectedStatus);
82     if (NT_SUCCESS(Status))
83     {
84         VerifyAccess_(KeyHandle, ExpectedAccess, File, Line);
85         Status = NtClose(KeyHandle);
86         ok_(File, Line)(Status == STATUS_SUCCESS,
87                         "NtClose from NtOpenKey returned 0x%lx\n",
88                         Status);
89     }
90     else if (NT_SUCCESS(ExpectedStatus))
91     {
92         skip_(File, Line)("NtOpenKey failed, skipping\n");
93     }
94 }
95 #define TestCreateOpen(d, ea, es) TestCreateOpen_(d, ea, es, __FILE__, __LINE__)
96 
97 START_TEST(NtCreateKey)
98 {
99     TestCreateOpen(0, 0, STATUS_ACCESS_DENIED);
100     TestCreateOpen(KEY_WOW64_32KEY, 0, STATUS_ACCESS_DENIED);
101     TestCreateOpen(KEY_WOW64_64KEY, 0, STATUS_ACCESS_DENIED);
102     TestCreateOpen(KEY_WOW64_32KEY | KEY_WOW64_64KEY, 0, STATUS_ACCESS_DENIED); // STATUS_INVALID_PARAMETER on Win7
103     TestCreateOpen(READ_CONTROL, READ_CONTROL, STATUS_SUCCESS);
104     TestCreateOpen(READ_CONTROL | KEY_WOW64_32KEY, READ_CONTROL, STATUS_SUCCESS);
105     TestCreateOpen(READ_CONTROL | KEY_WOW64_64KEY, READ_CONTROL, STATUS_SUCCESS);
106     TestCreateOpen(READ_CONTROL | KEY_WOW64_32KEY | KEY_WOW64_64KEY, READ_CONTROL, STATUS_SUCCESS); // STATUS_INVALID_PARAMETER on Win7
107 }
108