--- /dev/null
+/*
+ * PROJECT: ReactOS API Tests
+ * LICENSE: GPLv2+ - See COPYING in the top level directory
+ * PURPOSE: Test for NtSaveKey
+ * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ */
+
+#include <apitest.h>
+
+#define WIN32_NO_STATUS
+#include <ndk/rtlfuncs.h>
+#include <ndk/cmfuncs.h>
+#include <ndk/obfuncs.h>
+#include <ndk/setypes.h>
+
+static
+NTSTATUS
+OpenRegistryKeyHandle(PHANDLE KeyHandle,
+ ACCESS_MASK AccessMask,
+ PWCHAR RegistryPath)
+{
+ UNICODE_STRING KeyName;
+ OBJECT_ATTRIBUTES Attributes;
+
+ RtlInitUnicodeString(&KeyName, RegistryPath);
+ InitializeObjectAttributes(&Attributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ return NtOpenKey(KeyHandle, AccessMask, &Attributes);
+}
+
+START_TEST(NtSaveKey)
+{
+ NTSTATUS Status;
+ HANDLE KeyHandle;
+ HANDLE FileHandle;
+ BOOLEAN OldPrivilegeStatus;
+
+ /* Open the file */
+ FileHandle = CreateFileW(L"saved_key.dat",
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
+ NULL);
+ if (FileHandle == INVALID_HANDLE_VALUE)
+ {
+ skip("CreateFileW failed with error: %lu\n", GetLastError());
+ return;
+ }
+
+ /* Try saving HKEY_LOCAL_MACHINE\Hardware */
+ Status = OpenRegistryKeyHandle(&KeyHandle, KEY_READ, L"\\Registry\\Machine\\Hardware");
+ if (!NT_SUCCESS(Status))
+ {
+ skip("NtOpenKey failed with status: 0x%08lX\n", Status);
+ NtClose(FileHandle);
+ return;
+ }
+
+ Status = NtSaveKey(KeyHandle, FileHandle);
+ ok_ntstatus(Status, STATUS_PRIVILEGE_NOT_HELD);
+
+ NtClose(KeyHandle);
+
+ /* Set the SeBackupPrivilege */
+ Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE,
+ TRUE,
+ FALSE,
+ &OldPrivilegeStatus);
+ if (!NT_SUCCESS(Status))
+ {
+ skip("RtlAdjustPrivilege failed with status: 0x%08lX\n", (ULONG)Status);
+ NtClose(FileHandle);
+ return;
+ }
+
+ /* Try saving HKEY_LOCAL_MACHINE\Hardware again */
+ Status = OpenRegistryKeyHandle(&KeyHandle, KEY_READ, L"\\Registry\\Machine\\Hardware");
+ if (!NT_SUCCESS(Status))
+ {
+ skip("NtOpenKey failed with status: 0x%08lX\n", Status);
+ goto Cleanup;
+ }
+
+ Status = NtSaveKey(KeyHandle, FileHandle);
+ ok_ntstatus(Status, STATUS_SUCCESS);
+
+ NtClose(KeyHandle);
+
+ /* Try saving HKEY_LOCAL_MACHINE */
+ Status = OpenRegistryKeyHandle(&KeyHandle, KEY_READ, L"\\Registry\\Machine");
+ if (!NT_SUCCESS(Status))
+ {
+ skip("NtOpenKey failed with status: 0x%08lX\n", Status);
+ goto Cleanup;
+ }
+
+ Status = NtSaveKey(KeyHandle, FileHandle);
+ ok_ntstatus(Status, STATUS_ACCESS_DENIED);
+
+ NtClose(KeyHandle);
+
+ /* Try saving HKEY_USERS */
+ Status = OpenRegistryKeyHandle(&KeyHandle, KEY_READ, L"\\Registry\\User");
+ if (!NT_SUCCESS(Status))
+ {
+ skip("NtOpenKey failed with status: 0x%08lX\n", Status);
+ goto Cleanup;
+ }
+
+ Status = NtSaveKey(KeyHandle, FileHandle);
+ ok_ntstatus(Status, STATUS_ACCESS_DENIED);
+
+ NtClose(KeyHandle);
+
+Cleanup:
+
+ /* Restore the SeBackupPrivilege */
+ RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE,
+ OldPrivilegeStatus,
+ FALSE,
+ &OldPrivilegeStatus);
+
+ /* Close the file handle */
+ NtClose(FileHandle);
+}
extern void func_NtProtectVirtualMemory(void);
extern void func_NtQuerySystemEnvironmentValue(void);
extern void func_NtQueryVolumeInformationFile(void);
+extern void func_NtSaveKey(void);
extern void func_NtSystemInformation(void);
extern void func_RtlBitmap(void);
extern void func_RtlDetermineDosPathNameType(void);
{ "NtProtectVirtualMemory", func_NtProtectVirtualMemory },
{ "NtQuerySystemEnvironmentValue", func_NtQuerySystemEnvironmentValue },
{ "NtQueryVolumeInformationFile", func_NtQueryVolumeInformationFile },
+ { "NtSaveKey", func_NtSaveKey},
{ "NtSystemInformation", func_NtSystemInformation },
{ "RtlBitmapApi", func_RtlBitmap },
{ "RtlDetermineDosPathNameType", func_RtlDetermineDosPathNameType },