1 /*
2  * PROJECT:         ReactOS API Tests
3  * LICENSE:         GPLv2+ - See COPYING in the top level directory
4  * PURPOSE:         Test for NtSaveKey
5  * PROGRAMMERS:     Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
6  */
7 
8 #include "precomp.h"
9 
10 static
11 NTSTATUS
12 OpenRegistryKeyHandle(PHANDLE KeyHandle,
13                       ACCESS_MASK AccessMask,
14                       PWCHAR RegistryPath)
15 {
16     UNICODE_STRING KeyName;
17     OBJECT_ATTRIBUTES Attributes;
18 
19     RtlInitUnicodeString(&KeyName, RegistryPath);
20     InitializeObjectAttributes(&Attributes,
21                                &KeyName,
22                                OBJ_CASE_INSENSITIVE,
23                                NULL,
24                                NULL);
25 
26     return NtOpenKey(KeyHandle, AccessMask, &Attributes);
27 }
28 
29 START_TEST(NtSaveKey)
30 {
31     NTSTATUS Status;
32     HANDLE KeyHandle;
33     HANDLE FileHandle;
34     BOOLEAN PrivilegeEnabled = FALSE;
35     BOOLEAN OldPrivilegeStatus;
36 
37     /* Make sure we don't have backup privileges initially, otherwise WHS testbot fails */
38     Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, FALSE, FALSE, &PrivilegeEnabled);
39     ok(Status == STATUS_SUCCESS, "RtlAdjustPrivilege returned %lx\n", Status);
40 
41     /* Open the file */
42     FileHandle = CreateFileW(L"saved_key.dat",
43                              GENERIC_READ | GENERIC_WRITE,
44                              0,
45                              NULL,
46                              CREATE_ALWAYS,
47                              FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
48                              NULL);
49     if (FileHandle == INVALID_HANDLE_VALUE)
50     {
51         skip("CreateFileW failed with error: %lu\n", GetLastError());
52         return;
53     }
54 
55     /* Try saving HKEY_LOCAL_MACHINE\Hardware */
56     Status = OpenRegistryKeyHandle(&KeyHandle, KEY_READ, L"\\Registry\\Machine\\Hardware");
57     if (!NT_SUCCESS(Status))
58     {
59         skip("NtOpenKey failed with status: 0x%08lX\n", Status);
60         NtClose(FileHandle);
61         return;
62     }
63 
64     Status = NtSaveKey(KeyHandle, FileHandle);
65     ok_ntstatus(Status, STATUS_PRIVILEGE_NOT_HELD);
66 
67     NtClose(KeyHandle);
68 
69     /* Set the SeBackupPrivilege */
70     Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE,
71                                 TRUE,
72                                 FALSE,
73                                 &OldPrivilegeStatus);
74     if (!NT_SUCCESS(Status))
75     {
76         skip("RtlAdjustPrivilege failed with status: 0x%08lX\n", (ULONG)Status);
77         NtClose(FileHandle);
78         return;
79     }
80 
81     /* Try saving HKEY_LOCAL_MACHINE\Hardware again */
82     Status = OpenRegistryKeyHandle(&KeyHandle, KEY_READ, L"\\Registry\\Machine\\Hardware");
83     if (!NT_SUCCESS(Status))
84     {
85         skip("NtOpenKey failed with status: 0x%08lX\n", Status);
86         goto Cleanup;
87     }
88 
89     Status = NtSaveKey(KeyHandle, FileHandle);
90     ok_ntstatus(Status, STATUS_SUCCESS);
91 
92     NtClose(KeyHandle);
93 
94     /* Try saving HKEY_LOCAL_MACHINE */
95     Status = OpenRegistryKeyHandle(&KeyHandle, KEY_READ, L"\\Registry\\Machine");
96     if (!NT_SUCCESS(Status))
97     {
98         skip("NtOpenKey failed with status: 0x%08lX\n", Status);
99         goto Cleanup;
100     }
101 
102     Status = NtSaveKey(KeyHandle, FileHandle);
103     ok_ntstatus(Status, STATUS_ACCESS_DENIED);
104 
105     NtClose(KeyHandle);
106 
107     /* Try saving HKEY_USERS */
108     Status = OpenRegistryKeyHandle(&KeyHandle, KEY_READ, L"\\Registry\\User");
109     if (!NT_SUCCESS(Status))
110     {
111         skip("NtOpenKey failed with status: 0x%08lX\n", Status);
112         goto Cleanup;
113     }
114 
115     Status = NtSaveKey(KeyHandle, FileHandle);
116     ok_ntstatus(Status, STATUS_ACCESS_DENIED);
117 
118     NtClose(KeyHandle);
119 
120 Cleanup:
121 
122     /* Restore the SeBackupPrivilege */
123     RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE,
124                        OldPrivilegeStatus,
125                        FALSE,
126                        &OldPrivilegeStatus);
127 
128     /* Close the file handle */
129     NtClose(FileHandle);
130 }
131