Author: ekohl Date: Sun Feb 8 11:49:58 2015 New Revision: 66205 URL: http://svn.reactos.org/svn/reactos?rev=66205&view=rev Log: [NTOSKRNL] Implement NtSaveMergedKeys and its backend CmSaveMergedKeys.
Modified: trunk/reactos/ntoskrnl/config/cmapi.c trunk/reactos/ntoskrnl/config/ntapi.c trunk/reactos/ntoskrnl/include/internal/cm.h Modified: trunk/reactos/ntoskrnl/config/cmapi.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmapi.c?rev=66205&r1=66204&r2=66205&view=diff ============================================================================== --- trunk/reactos/ntoskrnl/config/cmapi.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/config/cmapi.c [iso-8859-1] Sun Feb 8 11:49:58 2015 @@ -2444,3 +2444,79 @@ return Status; } + +NTSTATUS +NTAPI +CmSaveMergedKeys(IN PCM_KEY_CONTROL_BLOCK HighKcb, + IN PCM_KEY_CONTROL_BLOCK LowKcb, + IN HANDLE FileHandle) +{ + PCMHIVE KeyHive = NULL; + NTSTATUS Status = STATUS_SUCCESS; + + PAGED_CODE(); + + DPRINT("CmSaveKey(%p, %p, %p)\n", HighKcb, LowKcb, FileHandle); + + /* Lock the registry and the KCBs */ + CmpLockRegistry(); + CmpAcquireKcbLockShared(HighKcb); + CmpAcquireKcbLockShared(LowKcb); + + if (LowKcb->Delete || HighKcb->Delete) + { + /* The source key has been deleted, do nothing */ + Status = STATUS_KEY_DELETED; + goto done; + } + + /* Create a new hive that will hold the key */ + Status = CmpInitializeHive(&KeyHive, + HINIT_CREATE, + HIVE_VOLATILE, + HFILE_TYPE_PRIMARY, + NULL, + NULL, + NULL, + NULL, + NULL, + 0); + if (!NT_SUCCESS(Status)) + goto done; + + /* Copy the low precedence key recursively into the new hive */ + Status = CmpDeepCopyKey(LowKcb->KeyHive, + LowKcb->KeyCell, + &KeyHive->Hive, + Stable, + &KeyHive->Hive.BaseBlock->RootCell); + if (!NT_SUCCESS(Status)) + goto done; + + /* Copy the high precedence key recursively into the new hive */ + Status = CmpDeepCopyKey(HighKcb->KeyHive, + HighKcb->KeyCell, + &KeyHive->Hive, + Stable, + &KeyHive->Hive.BaseBlock->RootCell); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the primary handle of the hive */ + KeyHive->FileHandles[HFILE_TYPE_PRIMARY] = FileHandle; + + /* Dump the hive into the file */ + HvWriteHive(&KeyHive->Hive); + +done: + /* Free the hive */ + if (KeyHive) + CmpDestroyHive(KeyHive); + + /* Release the locks */ + CmpReleaseKcbLock(LowKcb); + CmpReleaseKcbLock(HighKcb); + CmpUnlockRegistry(); + + return Status; +} Modified: trunk/reactos/ntoskrnl/config/ntapi.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/ntapi.c?rev=66205&r1=66204&r2=66205&view=diff ============================================================================== --- trunk/reactos/ntoskrnl/config/ntapi.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/config/ntapi.c [iso-8859-1] Sun Feb 8 11:49:58 2015 @@ -1258,7 +1258,7 @@ PAGED_CODE(); - DPRINT("NtSaveKeyEx(0x%08X, 0x%08X, %lu)\n", KeyHandle, FileHandle, Flags); + DPRINT("NtSaveKeyEx(0x%p, 0x%p, %lu)\n", KeyHandle, FileHandle, Flags); /* Verify the flags */ if ((Flags != REG_STANDARD_FORMAT) @@ -1297,8 +1297,56 @@ IN HANDLE LowPrecedenceKeyHandle, IN HANDLE FileHandle) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + KPROCESSOR_MODE PreviousMode; + PCM_KEY_BODY HighPrecedenceKeyObject = NULL; + PCM_KEY_BODY LowPrecedenceKeyObject = NULL; + NTSTATUS Status; + + PAGED_CODE(); + + DPRINT("NtSaveMergedKeys(0x%p, 0x%p, 0x%p)\n", + HighPrecedenceKeyHandle, LowPrecedenceKeyHandle, FileHandle); + + PreviousMode = ExGetPreviousMode(); + + /* Check for the SeBackupPrivilege */ + if (!SeSinglePrivilegeCheck(SeBackupPrivilege, PreviousMode)) + { + return STATUS_PRIVILEGE_NOT_HELD; + } + + /* Verify that the handles are valid and are registry keys */ + Status = ObReferenceObjectByHandle(HighPrecedenceKeyHandle, + KEY_READ, + CmpKeyObjectType, + PreviousMode, + (PVOID*)&HighPrecedenceKeyObject, + NULL); + if (!NT_SUCCESS(Status)) + goto done; + + Status = ObReferenceObjectByHandle(LowPrecedenceKeyHandle, + KEY_READ, + CmpKeyObjectType, + PreviousMode, + (PVOID*)&LowPrecedenceKeyObject, + NULL); + if (!NT_SUCCESS(Status)) + goto done; + + /* Call the internal API */ + Status = CmSaveMergedKeys(HighPrecedenceKeyObject->KeyControlBlock, + LowPrecedenceKeyObject->KeyControlBlock, + FileHandle); + +done: + if (LowPrecedenceKeyObject) + ObDereferenceObject(LowPrecedenceKeyObject); + + if (HighPrecedenceKeyObject) + ObDereferenceObject(HighPrecedenceKeyObject); + + return Status; } NTSTATUS Modified: trunk/reactos/ntoskrnl/include/internal/cm.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/cm.h?rev=66205&r1=66204&r2=66205&view=diff ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/cm.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/cm.h [iso-8859-1] Sun Feb 8 11:49:58 2015 @@ -1575,6 +1575,14 @@ IN ULONG Flags ); +NTSTATUS +NTAPI +CmSaveMergedKeys( + IN PCM_KEY_CONTROL_BLOCK HighKcb, + IN PCM_KEY_CONTROL_BLOCK LowKcb, + IN HANDLE FileHandle +); + // // Startup and Shutdown //