[NTOSKRNL]
[reactos.git] / reactos / ntoskrnl / config / ntapi.c
index 95f6116..b3bf0ec 100644 (file)
@@ -235,7 +235,7 @@ NtEnumerateKey(IN HANDLE KeyHandle,
     REG_ENUMERATE_KEY_INFORMATION EnumerateKeyInfo;
     REG_POST_OPERATION_INFORMATION PostOperationInfo;
     PAGED_CODE();
-    DPRINT("NtEnumerateKey() KH 0x%x, Index 0x%x, KIC %d, Length %d\n",
+    DPRINT("NtEnumerateKey() KH 0x%p, Index 0x%x, KIC %d, Length %lu\n",
            KeyHandle, Index, KeyInformationClass, Length);
 
     /* Reject classes we don't know about */
@@ -319,7 +319,7 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
     REG_ENUMERATE_VALUE_KEY_INFORMATION EnumerateValueKeyInfo;
     REG_POST_OPERATION_INFORMATION PostOperationInfo;
     PAGED_CODE();
-    DPRINT("NtEnumerateValueKey() KH 0x%x, Index 0x%x, KVIC %d, Length %d\n",
+    DPRINT("NtEnumerateValueKey() KH 0x%p, Index 0x%x, KVIC %d, Length %lu\n",
            KeyHandle, Index, KeyValueInformationClass, Length);
 
     /* Reject classes we don't know about */
@@ -404,7 +404,7 @@ NtQueryKey(IN HANDLE KeyHandle,
     REG_POST_OPERATION_INFORMATION PostOperationInfo;
     OBJECT_HANDLE_INFORMATION HandleInfo;
     PAGED_CODE();
-    DPRINT("NtQueryKey() KH 0x%x, KIC %d, Length %d\n",
+    DPRINT("NtQueryKey() KH 0x%p, KIC %d, Length %lu\n",
            KeyHandle, KeyInformationClass, Length);
 
     /* Reject invalid classes */
@@ -517,7 +517,7 @@ NtQueryValueKey(IN HANDLE KeyHandle,
     REG_POST_OPERATION_INFORMATION PostOperationInfo;
     UNICODE_STRING ValueNameCopy = *ValueName;
     PAGED_CODE();
-    DPRINT("NtQueryValueKey() KH 0x%x, VN '%wZ', KVIC %d, Length %d\n",
+    DPRINT("NtQueryValueKey() KH 0x%p, VN '%wZ', KVIC %d, Length %lu\n",
         KeyHandle, ValueName, KeyValueInformationClass, Length);
 
     /* Verify that the handle is valid and is a registry key */
@@ -610,7 +610,7 @@ NtSetValueKey(IN HANDLE KeyHandle,
     REG_POST_OPERATION_INFORMATION PostOperationInfo;
     UNICODE_STRING ValueNameCopy = *ValueName;
     PAGED_CODE();
-    DPRINT("NtSetValueKey() KH 0x%x, VN '%wZ', TI %x, T %d, DS %d\n",
+    DPRINT("NtSetValueKey() KH 0x%p, VN '%wZ', TI %x, T %lu, DS %lu\n",
         KeyHandle, ValueName, TitleIndex, Type, DataSize);
 
     /* Verify that the handle is valid and is a registry key */
@@ -1148,8 +1148,8 @@ NTAPI
 NtSaveKey(IN HANDLE KeyHandle,
           IN HANDLE FileHandle)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    /* Call the extended API */
+    return NtSaveKeyEx(KeyHandle, FileHandle, REG_STANDARD_FORMAT);
 }
 
 NTSTATUS
@@ -1158,8 +1158,43 @@ NtSaveKeyEx(IN HANDLE KeyHandle,
             IN HANDLE FileHandle,
             IN ULONG Flags)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    NTSTATUS Status;
+    PCM_KEY_BODY KeyObject;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+
+    PAGED_CODE();
+
+    DPRINT("NtSaveKeyEx(0x%08X, 0x%08X, %lu)\n", KeyHandle, FileHandle, Flags);
+
+    /* Verify the flags */
+    if ((Flags != REG_STANDARD_FORMAT)
+        && (Flags != REG_LATEST_FORMAT)
+        && (Flags != REG_NO_COMPRESSION))
+    {
+        /* Only one of these values can be specified */
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Check for the SeBackupPrivilege */
+    if (!SeSinglePrivilegeCheck(SeBackupPrivilege, PreviousMode))
+    {
+        return STATUS_PRIVILEGE_NOT_HELD;
+    }
+
+    /* Verify that the handle is valid and is a registry key */
+    Status = ObReferenceObjectByHandle(KeyHandle,
+                                       KEY_READ,
+                                       CmpKeyObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&KeyObject,
+                                       NULL);
+    if (!NT_SUCCESS(Status)) return Status;
+
+    /* Call the internal API */
+    Status = CmSaveKey(KeyObject->KeyControlBlock, FileHandle, Flags);
+
+    ObDereferenceObject(KeyObject);
+    return Status;
 }
 
 NTSTATUS