[NTOSKRNL]

Implement NtSaveMergedKeys and its backend CmSaveMergedKeys.

svn path=/trunk/; revision=66205
This commit is contained in:
Eric Kohl 2015-02-08 11:49:58 +00:00
parent f142ee5329
commit f2772f2806
3 changed files with 135 additions and 3 deletions

View file

@ -2444,3 +2444,79 @@ Cleanup:
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;
}

View file

@ -1258,7 +1258,7 @@ NtSaveKeyEx(IN HANDLE KeyHandle,
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 @@ NtSaveMergedKeys(IN HANDLE HighPrecedenceKeyHandle,
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

View file

@ -1575,6 +1575,14 @@ CmSaveKey(
IN ULONG Flags
);
NTSTATUS
NTAPI
CmSaveMergedKeys(
IN PCM_KEY_CONTROL_BLOCK HighKcb,
IN PCM_KEY_CONTROL_BLOCK LowKcb,
IN HANDLE FileHandle
);
//
// Startup and Shutdown
//