mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 17:44:45 +00:00
Implemented NtSaveKey().
svn path=/trunk/; revision=4852
This commit is contained in:
parent
2730a5ab14
commit
b694b8942b
3 changed files with 561 additions and 35 deletions
|
@ -616,4 +616,18 @@ CmiCompareKeyNamesI(PUNICODE_STRING KeyName,
|
|||
VOID
|
||||
CmiSyncHives(VOID);
|
||||
|
||||
|
||||
NTSTATUS
|
||||
CmiCreateTempHive(PREGISTRY_HIVE *RegistryHive);
|
||||
|
||||
NTSTATUS
|
||||
CmiCopyKey (PREGISTRY_HIVE DstHive,
|
||||
PKEY_CELL DstKeyCell,
|
||||
PREGISTRY_HIVE SrcHive,
|
||||
PKEY_CELL SrcKeyCell);
|
||||
|
||||
NTSTATUS
|
||||
CmiSaveTempHive (PREGISTRY_HIVE Hive,
|
||||
HANDLE FileHandle);
|
||||
|
||||
#endif /*__INCLUDE_CM_H*/
|
||||
|
|
|
@ -1697,8 +1697,81 @@ NTSTATUS STDCALL
|
|||
NtSaveKey (IN HANDLE KeyHandle,
|
||||
IN HANDLE FileHandle)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return(STATUS_NOT_IMPLEMENTED);
|
||||
PREGISTRY_HIVE TempHive;
|
||||
PKEY_OBJECT KeyObject;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT ("NtSaveKey() called\n");
|
||||
|
||||
#if 0
|
||||
if (!SeSinglePrivilegeCheck (SeBackupPrivilege, KeGetPreviousMode ()))
|
||||
return STATUS_PRIVILEGE_NOT_HELD;
|
||||
#endif
|
||||
|
||||
Status = ObReferenceObjectByHandle (KeyHandle,
|
||||
0,
|
||||
CmiKeyType,
|
||||
KeGetPreviousMode(),
|
||||
(PVOID *)&KeyObject,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1 ("ObReferenceObjectByHandle() failed (Status %lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Acquire hive lock exclucively */
|
||||
ExAcquireResourceExclusiveLite (&KeyObject->RegistryHive->HiveResource,
|
||||
TRUE);
|
||||
|
||||
/* Refuse to save a volatile key */
|
||||
if (KeyObject->RegistryHive == CmiVolatileHive)
|
||||
{
|
||||
DPRINT1 ("Cannot save a volatile key\n");
|
||||
ExReleaseResourceLite (&KeyObject->RegistryHive->HiveResource);
|
||||
ObDereferenceObject (KeyObject);
|
||||
return STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
Status = CmiCreateTempHive(&TempHive);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1 ("CmiCreateTempHive() failed (Status %lx)\n", Status);
|
||||
ExReleaseResourceLite (&KeyObject->RegistryHive->HiveResource);
|
||||
ObDereferenceObject (KeyObject);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
Status = CmiCopyKey (TempHive,
|
||||
NULL,
|
||||
KeyObject->RegistryHive,
|
||||
KeyObject->KeyCell);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1 ("CmiCopyKey() failed (Status %lx)\n", Status);
|
||||
CmiRemoveRegistryHive (TempHive);
|
||||
ExReleaseResourceLite (&KeyObject->RegistryHive->HiveResource);
|
||||
ObDereferenceObject (KeyObject);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
Status = CmiSaveTempHive (TempHive,
|
||||
FileHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1 ("CmiSaveTempHive() failed (Status %lx)\n", Status);
|
||||
}
|
||||
|
||||
CmiRemoveRegistryHive (TempHive);
|
||||
|
||||
/* Release hive lock */
|
||||
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||
|
||||
ObDereferenceObject (KeyObject);
|
||||
|
||||
DPRINT ("NtSaveKey() done\n");
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1726,6 +1799,11 @@ NtUnloadKey (IN POBJECT_ATTRIBUTES KeyObjectAttributes)
|
|||
|
||||
DPRINT ("NtUnloadKey() called\n");
|
||||
|
||||
#if 0
|
||||
if (!SeSinglePrivilegeCheck (SeRestorePrivilege, KeGetPreviousMode ()))
|
||||
return STATUS_PRIVILEGE_NOT_HELD;
|
||||
#endif
|
||||
|
||||
Status = CmiDisconnectHive (KeyObjectAttributes,
|
||||
&RegistryHive);
|
||||
if (!NT_SUCCESS (Status))
|
||||
|
@ -1746,35 +1824,10 @@ NtUnloadKey (IN POBJECT_ATTRIBUTES KeyObjectAttributes)
|
|||
CmiFlushRegistryHive (RegistryHive);
|
||||
#endif
|
||||
|
||||
/* Remove hive from hive list */
|
||||
RemoveEntryList (&RegistryHive->HiveList);
|
||||
|
||||
/* Release hive list lock */
|
||||
ExReleaseResourceLite (&CmiHiveListLock);
|
||||
|
||||
/* Release file names */
|
||||
RtlFreeUnicodeString (&RegistryHive->HiveFileName);
|
||||
RtlFreeUnicodeString (&RegistryHive->LogFileName);
|
||||
|
||||
/* Release hive bitmap */
|
||||
ExFreePool (RegistryHive->BitmapBuffer);
|
||||
|
||||
/* Release free cell list */
|
||||
ExFreePool (RegistryHive->FreeList);
|
||||
ExFreePool (RegistryHive->FreeListOffset);
|
||||
|
||||
/* Release hive resource */
|
||||
ExDeleteResource (&RegistryHive->HiveResource);
|
||||
|
||||
/* Release bins and bin list */
|
||||
CmiFreeHiveBins (RegistryHive);
|
||||
ExFreePool (RegistryHive->BlockList);
|
||||
|
||||
/* Release hive header */
|
||||
ExFreePool (RegistryHive->HiveHeader);
|
||||
|
||||
/* Release hive */
|
||||
ExFreePool (RegistryHive);
|
||||
CmiRemoveRegistryHive (RegistryHive);
|
||||
|
||||
DPRINT ("NtUnloadKey() done\n");
|
||||
|
||||
|
|
|
@ -1112,6 +1112,128 @@ CmiCreateVolatileHive(PREGISTRY_HIVE *RegistryHive)
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
CmiCreateTempHive(PREGISTRY_HIVE *RegistryHive)
|
||||
{
|
||||
PHBIN BinCell;
|
||||
PCELL_HEADER FreeCell;
|
||||
PREGISTRY_HIVE Hive;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT1 ("CmiCreateTempHive() called\n");
|
||||
|
||||
*RegistryHive = NULL;
|
||||
|
||||
Hive = ExAllocatePool (NonPagedPool,
|
||||
sizeof(REGISTRY_HIVE));
|
||||
if (Hive == NULL)
|
||||
{
|
||||
DPRINT1 ("Failed to allocate registry hive block\n");
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
RtlZeroMemory (Hive,
|
||||
sizeof(REGISTRY_HIVE));
|
||||
|
||||
DPRINT ("Hive %x\n", Hive);
|
||||
|
||||
Hive->HiveHeader = (PHIVE_HEADER)ExAllocatePool (NonPagedPool,
|
||||
REG_BLOCK_SIZE);
|
||||
if (Hive->HiveHeader == NULL)
|
||||
{
|
||||
DPRINT1 ("Failed to allocate hive header block\n");
|
||||
ExFreePool (Hive);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
RtlZeroMemory (Hive->HiveHeader,
|
||||
REG_BLOCK_SIZE);
|
||||
|
||||
DPRINT1 ("HiveHeader %x\n", Hive->HiveHeader);
|
||||
|
||||
Hive->Flags = HIVE_NO_FILE;
|
||||
|
||||
RtlInitUnicodeString (&Hive->HiveFileName,
|
||||
NULL);
|
||||
RtlInitUnicodeString (&Hive->LogFileName,
|
||||
NULL);
|
||||
|
||||
CmiCreateDefaultHiveHeader (Hive->HiveHeader);
|
||||
|
||||
/* Allocate hive block list */
|
||||
Hive->BlockList = ExAllocatePool (NonPagedPool,
|
||||
sizeof(PHBIN *));
|
||||
if (Hive->BlockList == NULL)
|
||||
{
|
||||
DPRINT1 ("Failed to allocate hive block list\n");
|
||||
ExFreePool(Hive->HiveHeader);
|
||||
ExFreePool(Hive);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* Allocate first Bin */
|
||||
Hive->BlockList[0] = ExAllocatePool (NonPagedPool,
|
||||
REG_BLOCK_SIZE);
|
||||
if (Hive->BlockList[0] == NULL)
|
||||
{
|
||||
DPRINT1 ("Failed to allocate first bin\n");
|
||||
ExFreePool(Hive->BlockList);
|
||||
ExFreePool(Hive->HiveHeader);
|
||||
ExFreePool(Hive);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
Hive->FileSize = 2* REG_BLOCK_SIZE;
|
||||
Hive->BlockListSize = 1;
|
||||
Hive->UpdateCounter = Hive->HiveHeader->UpdateCounter1;
|
||||
|
||||
|
||||
BinCell = (PHBIN)Hive->BlockList[0];
|
||||
FreeCell = (PCELL_HEADER)((ULONG_PTR)BinCell + REG_HBIN_DATA_OFFSET);
|
||||
|
||||
CmiCreateDefaultBinCell (BinCell);
|
||||
|
||||
/* First block */
|
||||
BinCell->BlockOffset = 0;
|
||||
|
||||
/* Offset to root key block */
|
||||
Hive->HiveHeader->RootKeyCell = -1;
|
||||
|
||||
/* The rest of the block is free */
|
||||
FreeCell->CellSize = REG_BLOCK_SIZE - REG_HBIN_DATA_OFFSET;
|
||||
|
||||
/* Create the free cell list */
|
||||
Status = CmiCreateHiveFreeCellList (Hive);
|
||||
if (Hive->BlockList[0] == NULL)
|
||||
{
|
||||
DPRINT1 ("CmiCreateHiveFreeCellList() failed (Status %lx)\n", Status);
|
||||
ExFreePool(Hive->BlockList[0]);
|
||||
ExFreePool(Hive->BlockList);
|
||||
ExFreePool(Hive->HiveHeader);
|
||||
ExFreePool(Hive);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
ExInitializeResourceLite (&Hive->HiveResource);
|
||||
|
||||
/* Acquire hive list lock exclusively */
|
||||
ExAcquireResourceExclusiveLite (&CmiHiveListLock,
|
||||
TRUE);
|
||||
|
||||
/* Add the new hive to the hive list */
|
||||
InsertTailList (&CmiHiveListHead,
|
||||
&Hive->HiveList);
|
||||
|
||||
/* Release hive list lock */
|
||||
ExReleaseResourceLite (&CmiHiveListLock);
|
||||
|
||||
VERIFY_REGISTRY_HIVE (Hive);
|
||||
|
||||
*RegistryHive = Hive;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
CmiLoadHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
|
||||
IN PUNICODE_STRING FileName,
|
||||
|
@ -1187,27 +1309,44 @@ CmiLoadHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
|
|||
NTSTATUS
|
||||
CmiRemoveRegistryHive(PREGISTRY_HIVE RegistryHive)
|
||||
{
|
||||
if (RegistryHive->Flags & HIVE_POINTER)
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
|
||||
/* Acquire hive list lock exclusively */
|
||||
ExAcquireResourceExclusiveLite(&CmiHiveListLock, TRUE);
|
||||
ExAcquireResourceExclusiveLite (&CmiHiveListLock,
|
||||
TRUE);
|
||||
|
||||
/* Remove hive from hive list */
|
||||
RemoveEntryList(&RegistryHive->HiveList);
|
||||
RemoveEntryList (&RegistryHive->HiveList);
|
||||
|
||||
/* Release hive list lock */
|
||||
ExReleaseResourceLite(&CmiHiveListLock);
|
||||
ExReleaseResourceLite (&CmiHiveListLock);
|
||||
|
||||
/* Release file names */
|
||||
RtlFreeUnicodeString (&RegistryHive->HiveFileName);
|
||||
RtlFreeUnicodeString (&RegistryHive->LogFileName);
|
||||
|
||||
/* FIXME: Remove attached keys and values */
|
||||
/* Release hive bitmap */
|
||||
ExFreePool (RegistryHive->BitmapBuffer);
|
||||
|
||||
/* Release free cell list */
|
||||
ExFreePool (RegistryHive->FreeList);
|
||||
ExFreePool (RegistryHive->FreeListOffset);
|
||||
|
||||
/* Release hive resource */
|
||||
ExDeleteResource (&RegistryHive->HiveResource);
|
||||
|
||||
/* Release bins and bin list */
|
||||
CmiFreeHiveBins (RegistryHive);
|
||||
ExFreePool (RegistryHive->BlockList);
|
||||
|
||||
/* Release hive header */
|
||||
ExFreePool(RegistryHive->HiveHeader);
|
||||
ExFreePool (RegistryHive->HiveHeader);
|
||||
|
||||
/* Release hive */
|
||||
ExFreePool(RegistryHive);
|
||||
ExFreePool (RegistryHive);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -3659,4 +3798,324 @@ CmiCompareKeyNamesI(PUNICODE_STRING KeyName,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
CmiCopyKey (PREGISTRY_HIVE DstHive,
|
||||
PKEY_CELL DstKeyCell,
|
||||
PREGISTRY_HIVE SrcHive,
|
||||
PKEY_CELL SrcKeyCell)
|
||||
{
|
||||
PKEY_CELL NewKeyCell;
|
||||
ULONG NewKeyCellSize;
|
||||
BLOCK_OFFSET NewKeyCellOffset;
|
||||
PHASH_TABLE_CELL NewHashTableCell;
|
||||
ULONG NewHashTableSize;
|
||||
BLOCK_OFFSET NewHashTableOffset;
|
||||
ULONG i;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT1 ("CmiCopyKey() called\n");
|
||||
|
||||
if (DstKeyCell == NULL)
|
||||
{
|
||||
/* Allocate and copy key cell */
|
||||
NewKeyCellSize = sizeof(KEY_CELL) + SrcKeyCell->NameSize;
|
||||
Status = CmiAllocateBlock (DstHive,
|
||||
(PVOID) &NewKeyCell,
|
||||
NewKeyCellSize,
|
||||
&NewKeyCellOffset);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
if (NewKeyCell == NULL)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
RtlCopyMemory (NewKeyCell,
|
||||
SrcKeyCell,
|
||||
NewKeyCellSize);
|
||||
|
||||
DstHive->HiveHeader->RootKeyCell = NewKeyCellOffset;
|
||||
|
||||
/* Copy class name */
|
||||
if (SrcKeyCell->ClassNameOffset != -1)
|
||||
{
|
||||
PDATA_CELL SrcClassNameCell;
|
||||
PDATA_CELL NewClassNameCell;
|
||||
BLOCK_OFFSET NewClassNameOffset;
|
||||
|
||||
SrcClassNameCell = CmiGetBlock (SrcHive, SrcKeyCell->ClassNameOffset, NULL),
|
||||
|
||||
NewKeyCell->ClassSize = SrcKeyCell->ClassSize;
|
||||
Status = CmiAllocateBlock (DstHive,
|
||||
(PVOID)&NewClassNameCell,
|
||||
NewKeyCell->ClassSize,
|
||||
&NewClassNameOffset);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
CHECKPOINT1;
|
||||
return Status;
|
||||
}
|
||||
|
||||
RtlCopyMemory (NewClassNameCell,
|
||||
SrcClassNameCell,
|
||||
NewKeyCell->ClassSize);
|
||||
NewKeyCell->ClassNameOffset = NewClassNameOffset;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NewKeyCell = DstKeyCell;
|
||||
}
|
||||
|
||||
/* Allocate hash table */
|
||||
if (SrcKeyCell->NumberOfSubKeys > 0)
|
||||
{
|
||||
NewHashTableSize = ROUND_UP(SrcKeyCell->NumberOfSubKeys + 1, 4) - 1;
|
||||
Status = CmiAllocateHashTableBlock (DstHive,
|
||||
&NewHashTableCell,
|
||||
&NewHashTableOffset,
|
||||
NewHashTableSize);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
CHECKPOINT1;
|
||||
return Status;
|
||||
}
|
||||
NewKeyCell->HashTableOffset = NewHashTableOffset;
|
||||
}
|
||||
|
||||
/* Allocate and copy value list and values */
|
||||
if (SrcKeyCell->NumberOfValues != 0)
|
||||
{
|
||||
PVALUE_LIST_CELL NewValueListCell;
|
||||
PVALUE_LIST_CELL SrcValueListCell;
|
||||
PVALUE_CELL NewValueCell;
|
||||
PVALUE_CELL SrcValueCell;
|
||||
PDATA_CELL SrcValueDataCell;
|
||||
PDATA_CELL NewValueDataCell;
|
||||
BLOCK_OFFSET ValueCellOffset;
|
||||
BLOCK_OFFSET ValueDataCellOffset;
|
||||
ULONG NewValueListCellSize;
|
||||
ULONG NewValueCellSize;
|
||||
|
||||
|
||||
NewValueListCellSize =
|
||||
ROUND_UP(SrcKeyCell->NumberOfValues, 4) * sizeof(BLOCK_OFFSET);
|
||||
Status = CmiAllocateBlock (DstHive,
|
||||
(PVOID)&NewValueListCell,
|
||||
NewValueListCellSize,
|
||||
&NewKeyCell->ValuesOffset);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
CHECKPOINT1;
|
||||
return Status;
|
||||
}
|
||||
|
||||
RtlZeroMemory (NewValueListCell,
|
||||
NewValueListCellSize);
|
||||
|
||||
/* Copy values */
|
||||
SrcValueListCell = CmiGetBlock (SrcHive, SrcKeyCell->ValuesOffset, NULL);
|
||||
for (i = 0; i < SrcKeyCell->NumberOfValues; i++)
|
||||
{
|
||||
/* Copy value cell */
|
||||
SrcValueCell = CmiGetBlock (SrcHive, SrcValueListCell->Values[i], NULL);
|
||||
|
||||
NewValueCellSize = sizeof(VALUE_CELL) + SrcValueCell->NameSize;
|
||||
Status = CmiAllocateBlock (DstHive,
|
||||
(PVOID*) &NewValueCell,
|
||||
NewValueCellSize,
|
||||
&ValueCellOffset);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
CHECKPOINT1;
|
||||
return Status;
|
||||
}
|
||||
|
||||
NewValueListCell->Values[i] = ValueCellOffset;
|
||||
RtlCopyMemory (NewValueCell,
|
||||
SrcValueCell,
|
||||
NewValueCellSize);
|
||||
|
||||
/* Copy value data cell */
|
||||
if (SrcValueCell->DataSize > sizeof(PVOID))
|
||||
{
|
||||
SrcValueDataCell = CmiGetBlock (SrcHive, SrcValueCell->DataOffset, NULL);
|
||||
|
||||
Status = CmiAllocateBlock (DstHive,
|
||||
(PVOID*) &NewValueDataCell,
|
||||
SrcValueCell->DataSize,
|
||||
&ValueDataCellOffset);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
CHECKPOINT1;
|
||||
return Status;
|
||||
}
|
||||
RtlCopyMemory (NewValueDataCell,
|
||||
SrcValueDataCell,
|
||||
SrcValueCell->DataSize);
|
||||
NewValueCell->DataOffset = ValueDataCellOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy subkeys */
|
||||
if (SrcKeyCell->NumberOfSubKeys > 0)
|
||||
{
|
||||
PHASH_TABLE_CELL SrcHashTableCell;
|
||||
PKEY_CELL SrcSubKeyCell;
|
||||
PKEY_CELL NewSubKeyCell;
|
||||
ULONG NewSubKeyCellSize;
|
||||
BLOCK_OFFSET NewSubKeyCellOffset;
|
||||
PHASH_RECORD SrcHashRecord;
|
||||
|
||||
SrcHashTableCell = CmiGetBlock (SrcHive,
|
||||
SrcKeyCell->HashTableOffset,
|
||||
NULL);
|
||||
|
||||
for (i = 0; i < SrcKeyCell->NumberOfSubKeys; i++)
|
||||
{
|
||||
SrcHashRecord = &SrcHashTableCell->Table[i];
|
||||
SrcSubKeyCell = CmiGetBlock (SrcHive, SrcHashRecord->KeyOffset, NULL);
|
||||
|
||||
/* Allocate and copy key cell */
|
||||
NewSubKeyCellSize = sizeof(KEY_CELL) + SrcSubKeyCell->NameSize;
|
||||
Status = CmiAllocateBlock (DstHive,
|
||||
(PVOID)&NewSubKeyCell,
|
||||
NewSubKeyCellSize,
|
||||
&NewSubKeyCellOffset);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
CHECKPOINT1;
|
||||
return Status;
|
||||
}
|
||||
if (NewKeyCell == NULL)
|
||||
{
|
||||
CHECKPOINT1;
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
NewHashTableCell->Table[i].KeyOffset = NewSubKeyCellOffset;
|
||||
NewHashTableCell->Table[i].HashValue = SrcHashRecord->HashValue;
|
||||
|
||||
RtlCopyMemory (NewSubKeyCell,
|
||||
SrcSubKeyCell,
|
||||
NewSubKeyCellSize);
|
||||
|
||||
/* Copy class name */
|
||||
if (SrcSubKeyCell->ClassNameOffset != -1)
|
||||
{
|
||||
PDATA_CELL SrcClassNameCell;
|
||||
PDATA_CELL NewClassNameCell;
|
||||
BLOCK_OFFSET NewClassNameOffset;
|
||||
|
||||
SrcClassNameCell = CmiGetBlock (SrcHive,
|
||||
SrcSubKeyCell->ClassNameOffset,
|
||||
NULL),
|
||||
|
||||
NewSubKeyCell->ClassSize = SrcSubKeyCell->ClassSize;
|
||||
Status = CmiAllocateBlock (DstHive,
|
||||
(PVOID)&NewClassNameCell,
|
||||
NewSubKeyCell->ClassSize,
|
||||
&NewClassNameOffset);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
CHECKPOINT1;
|
||||
return Status;
|
||||
}
|
||||
|
||||
NewSubKeyCell->ClassNameOffset = NewClassNameOffset;
|
||||
RtlCopyMemory (NewClassNameCell,
|
||||
SrcClassNameCell,
|
||||
NewSubKeyCell->ClassSize);
|
||||
}
|
||||
|
||||
/* Copy subkey data and subkeys */
|
||||
Status = CmiCopyKey (DstHive,
|
||||
NewSubKeyCell,
|
||||
SrcHive,
|
||||
SrcSubKeyCell);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
CHECKPOINT1;
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
CmiSaveTempHive (PREGISTRY_HIVE Hive,
|
||||
HANDLE FileHandle)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
LARGE_INTEGER FileOffset;
|
||||
ULONG BlockIndex;
|
||||
PVOID BlockPtr;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT ("CmiSaveTempHive() called\n");
|
||||
|
||||
Hive->HiveHeader->Checksum = CmiCalcChecksum ((PULONG)Hive->HiveHeader);
|
||||
|
||||
/* Write hive block */
|
||||
FileOffset.QuadPart = 0ULL;
|
||||
Status = NtWriteFile (FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
Hive->HiveHeader,
|
||||
sizeof(HIVE_HEADER),
|
||||
&FileOffset,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1 ("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
DPRINT ("Saving %lu blocks\n", Hive->BlockListSize);
|
||||
for (BlockIndex = 0; BlockIndex < Hive->BlockListSize; BlockIndex++)
|
||||
{
|
||||
BlockPtr = Hive->BlockList[BlockIndex];
|
||||
DPRINT ("BlockPtr %p\n", BlockPtr);
|
||||
|
||||
FileOffset.QuadPart = (ULONGLONG)(BlockIndex + 1) * 4096ULL;
|
||||
DPRINT ("File offset %I64x\n", FileOffset.QuadPart);
|
||||
|
||||
/* Write hive block */
|
||||
Status = NtWriteFile (FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
BlockPtr,
|
||||
REG_BLOCK_SIZE,
|
||||
&FileOffset,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1 ("NtWriteFile() failed (Status %lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
Status = NtFlushBuffersFile (FileHandle,
|
||||
&IoStatusBlock);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1 ("NtFlushBuffersFile() failed (Status %lx)\n", Status);
|
||||
}
|
||||
|
||||
DPRINT ("CmiSaveTempHive() done\n");
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
Loading…
Reference in a new issue