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 OldPrivilegeStatus;
35 
36     /* Open the file */
37     FileHandle = CreateFileW(L"saved_key.dat",
38                              GENERIC_READ | GENERIC_WRITE,
39                              0,
40                              NULL,
41                              CREATE_ALWAYS,
42                              FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
43                              NULL);
44     if (FileHandle == INVALID_HANDLE_VALUE)
45     {
46         skip("CreateFileW failed with error: %lu\n", GetLastError());
47         return;
48     }
49 
50     /* Try saving HKEY_LOCAL_MACHINE\Hardware */
51     Status = OpenRegistryKeyHandle(&KeyHandle, KEY_READ, L"\\Registry\\Machine\\Hardware");
52     if (!NT_SUCCESS(Status))
53     {
54         skip("NtOpenKey failed with status: 0x%08lX\n", Status);
55         NtClose(FileHandle);
56         return;
57     }
58 
59     Status = NtSaveKey(KeyHandle, FileHandle);
60     ok_ntstatus(Status, STATUS_PRIVILEGE_NOT_HELD);
61 
62     NtClose(KeyHandle);
63 
64     /* Set the SeBackupPrivilege */
65     Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE,
66                                 TRUE,
67                                 FALSE,
68                                 &OldPrivilegeStatus);
69     if (!NT_SUCCESS(Status))
70     {
71         skip("RtlAdjustPrivilege failed with status: 0x%08lX\n", (ULONG)Status);
72         NtClose(FileHandle);
73         return;
74     }
75 
76     /* Try saving HKEY_LOCAL_MACHINE\Hardware again */
77     Status = OpenRegistryKeyHandle(&KeyHandle, KEY_READ, L"\\Registry\\Machine\\Hardware");
78     if (!NT_SUCCESS(Status))
79     {
80         skip("NtOpenKey failed with status: 0x%08lX\n", Status);
81         goto Cleanup;
82     }
83 
84     Status = NtSaveKey(KeyHandle, FileHandle);
85     ok_ntstatus(Status, STATUS_SUCCESS);
86 
87     NtClose(KeyHandle);
88 
89     /* Try saving HKEY_LOCAL_MACHINE */
90     Status = OpenRegistryKeyHandle(&KeyHandle, KEY_READ, L"\\Registry\\Machine");
91     if (!NT_SUCCESS(Status))
92     {
93         skip("NtOpenKey failed with status: 0x%08lX\n", Status);
94         goto Cleanup;
95     }
96 
97     Status = NtSaveKey(KeyHandle, FileHandle);
98     ok_ntstatus(Status, STATUS_ACCESS_DENIED);
99 
100     NtClose(KeyHandle);
101 
102     /* Try saving HKEY_USERS */
103     Status = OpenRegistryKeyHandle(&KeyHandle, KEY_READ, L"\\Registry\\User");
104     if (!NT_SUCCESS(Status))
105     {
106         skip("NtOpenKey failed with status: 0x%08lX\n", Status);
107         goto Cleanup;
108     }
109 
110     Status = NtSaveKey(KeyHandle, FileHandle);
111     ok_ntstatus(Status, STATUS_ACCESS_DENIED);
112 
113     NtClose(KeyHandle);
114 
115 Cleanup:
116 
117     /* Restore the SeBackupPrivilege */
118     RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE,
119                        OldPrivilegeStatus,
120                        FALSE,
121                        &OldPrivilegeStatus);
122 
123     /* Close the file handle */
124     NtClose(FileHandle);
125 }
126