mirror of
https://github.com/reactos/reactos.git
synced 2025-04-20 12:29:56 +00:00
- Get rid of CmiCopyKey since it was dead code. Make CmiScanKeyForValue and CmiScanForSubKey simple wrappers around the newer CmpFindSubKeyByName and CmpFindValueByName routines.
- Allow cmlib to support HINIT_FILE flag for HvInitializeHive. This means the kernel doesn't need to create a section for the hive, then call HvInitializeHive with HINIT_MEMORY anymore, and can simply send the file handle. I wrote a sneaky little hack in cmlib which actually ends up doing the same idea, albeit not by using a section, making it portable. - Fix a serious bug in CmpFindSubKeyInLeaf affected by our lack of alphabetically-sorted cells; the linear search I hacked was slightly broken. - Remove the need to hold a LogFileName in the hive structure, since we generate it dynamically now. svn path=/trunk/; revision=26712
This commit is contained in:
parent
6ef9f575cb
commit
ef1f549526
5 changed files with 205 additions and 435 deletions
|
@ -271,6 +271,130 @@ HvpInitializeMemoryInplaceHive(
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
typedef enum _RESULT
|
||||
{
|
||||
NotHive,
|
||||
Fail,
|
||||
NoMemory,
|
||||
HiveSuccess,
|
||||
RecoverHeader,
|
||||
RecoverData,
|
||||
SelfHeal
|
||||
} RESULT;
|
||||
|
||||
RESULT CMAPI
|
||||
HvpGetHiveHeader(IN PHHIVE Hive,
|
||||
IN PHBASE_BLOCK *BaseBlock,
|
||||
IN PLARGE_INTEGER TimeStamp)
|
||||
{
|
||||
PHBASE_BLOCK HiveHeader;
|
||||
ULONG Alignment;
|
||||
ULONG Result;
|
||||
ULONGLONG Offset = 0;
|
||||
ASSERT(sizeof(HBASE_BLOCK) >= (HV_BLOCK_SIZE * Hive->Cluster));
|
||||
|
||||
/* Assume failure and allocate the buffer */
|
||||
*BaseBlock = 0;
|
||||
HiveHeader = Hive->Allocate(sizeof(HBASE_BLOCK), TRUE);
|
||||
if (!HiveHeader) return NoMemory;
|
||||
|
||||
/* Check for, and enforce, alignment */
|
||||
Alignment = Hive->Cluster * HV_BLOCK_SIZE -1;
|
||||
if ((ULONG_PTR)HiveHeader & Alignment)
|
||||
{
|
||||
/* Free the old header */
|
||||
Hive->Free(HiveHeader);
|
||||
HiveHeader = Hive->Allocate(PAGE_SIZE, TRUE);
|
||||
if (!HiveHeader) return NoMemory;
|
||||
|
||||
//HiveHeader->Length = PAGE_SIZE; ??
|
||||
}
|
||||
|
||||
/* Clear it */
|
||||
RtlZeroMemory(HiveHeader, sizeof(HBASE_BLOCK));
|
||||
|
||||
/* Now read it from disk */
|
||||
Result = Hive->FileRead(Hive,
|
||||
HV_TYPE_PRIMARY,
|
||||
Offset,
|
||||
HiveHeader,
|
||||
Hive->Cluster * HV_BLOCK_SIZE);
|
||||
|
||||
/* Couldn't read: assume it's not a hive */
|
||||
if (!Result) return NotHive;
|
||||
|
||||
/* Do validation */
|
||||
if (!HvpVerifyHiveHeader(HiveHeader)) return NotHive;
|
||||
|
||||
/* Return information */
|
||||
*BaseBlock = HiveHeader;
|
||||
*TimeStamp = HiveHeader->TimeStamp;
|
||||
return HiveSuccess;
|
||||
}
|
||||
|
||||
NTSTATUS CMAPI
|
||||
HvLoadHive(IN PHHIVE Hive,
|
||||
IN ULONG FileSize)
|
||||
{
|
||||
PHBASE_BLOCK BaseBlock = NULL;
|
||||
ULONG Result;
|
||||
LARGE_INTEGER TimeStamp;
|
||||
ULONGLONG Offset = 0;
|
||||
PVOID HiveData;
|
||||
|
||||
/* Get the hive header */
|
||||
Result = HvpGetHiveHeader(Hive, &BaseBlock, &TimeStamp);
|
||||
switch (Result)
|
||||
{
|
||||
/* Out of memory */
|
||||
case NoMemory:
|
||||
|
||||
/* Fail */
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
/* Not a hive */
|
||||
case NotHive:
|
||||
|
||||
/* Fail */
|
||||
return STATUS_NOT_REGISTRY_FILE;
|
||||
|
||||
/* Has recovery data */
|
||||
case RecoverData:
|
||||
case RecoverHeader:
|
||||
|
||||
/* Fail */
|
||||
return STATUS_REGISTRY_CORRUPT;
|
||||
}
|
||||
|
||||
/* Set default boot type */
|
||||
BaseBlock->BootType = 0;
|
||||
|
||||
/* Setup hive data */
|
||||
Hive->HiveHeader = BaseBlock;
|
||||
Hive->Version = Hive->HiveHeader->Minor;
|
||||
|
||||
/* Allocate a buffer large enough to hold the hive */
|
||||
HiveData = Hive->Allocate(FileSize, TRUE);
|
||||
if (!HiveData) return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
/* Now read the whole hive */
|
||||
Result = Hive->FileRead(Hive,
|
||||
HV_TYPE_PRIMARY,
|
||||
Offset,
|
||||
HiveData,
|
||||
FileSize);
|
||||
if (!Result) return STATUS_NOT_REGISTRY_FILE;
|
||||
|
||||
/* Apply "US National Debt" hack */
|
||||
((PHBASE_BLOCK)HiveData)->Length = FileSize;
|
||||
|
||||
/* Free our base block... it's usless in this implementation */
|
||||
Hive->Free(BaseBlock);
|
||||
|
||||
/* Initialize the hive directly from memory */
|
||||
return HvpInitializeMemoryHive(Hive, (ULONG_PTR)HiveData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name HvInitialize
|
||||
*
|
||||
|
@ -334,6 +458,7 @@ HvInitialize(
|
|||
Hive->FileSetSize = FileSetSize;
|
||||
Hive->FileFlush = FileFlush;
|
||||
Hive->StorageTypeCount = 2;
|
||||
Hive->Cluster = 1;
|
||||
|
||||
switch (Operation)
|
||||
{
|
||||
|
@ -349,6 +474,21 @@ HvInitialize(
|
|||
Status = HvpInitializeMemoryInplaceHive(Hive, HiveData);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
||||
/* Hack of doom: Cluster is actually the file size. */
|
||||
Status = HvLoadHive(Hive, Cluster);
|
||||
if ((Status != STATUS_SUCCESS) &&
|
||||
(Status != STATUS_REGISTRY_RECOVERED))
|
||||
{
|
||||
/* Unrecoverable failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Check for previous damage */
|
||||
if (Status == STATUS_REGISTRY_RECOVERED) ASSERT(FALSE);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* FIXME: A better return status value is needed */
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
|
|
|
@ -332,6 +332,22 @@ CmiComparePackedNames(IN PUNICODE_STRING Name,
|
|||
IN USHORT NameBufferSize,
|
||||
IN BOOLEAN NamePacked);
|
||||
|
||||
HCELL_INDEX
|
||||
NTAPI
|
||||
CmpFindValueByName(
|
||||
IN PHHIVE Hive,
|
||||
IN PCM_KEY_NODE KeyNode,
|
||||
IN PUNICODE_STRING Name
|
||||
);
|
||||
|
||||
HCELL_INDEX
|
||||
NTAPI
|
||||
CmpFindSubKeyByName(
|
||||
IN PHHIVE Hive,
|
||||
IN PCM_KEY_NODE Parent,
|
||||
IN PUNICODE_STRING SearchName
|
||||
);
|
||||
|
||||
VOID
|
||||
CmiCopyPackedName(PWCHAR NameBuffer,
|
||||
PUCHAR PackedNameBuffer,
|
||||
|
@ -361,12 +377,6 @@ CmiSyncHives(VOID);
|
|||
NTSTATUS
|
||||
CmiCreateTempHive(PEREGISTRY_HIVE *RegistryHive);
|
||||
|
||||
NTSTATUS
|
||||
CmiCopyKey (PEREGISTRY_HIVE DstHive,
|
||||
PCM_KEY_NODE DstKeyCell,
|
||||
PEREGISTRY_HIVE SrcHive,
|
||||
PCM_KEY_NODE SrcKeyCell);
|
||||
|
||||
NTSTATUS
|
||||
CmiSaveTempHive (PEREGISTRY_HIVE Hive,
|
||||
HANDLE FileHandle);
|
||||
|
|
|
@ -64,10 +64,8 @@ CmiInitNonVolatileRegistryHive (PEREGISTRY_HIVE RegistryHive,
|
|||
ULONG CreateDisposition;
|
||||
IO_STATUS_BLOCK IoSB;
|
||||
HANDLE FileHandle;
|
||||
PVOID SectionObject;
|
||||
PUCHAR ViewBase;
|
||||
ULONG ViewSize;
|
||||
NTSTATUS Status;
|
||||
FILE_STANDARD_INFORMATION FileInformation;
|
||||
|
||||
DPRINT("CmiInitNonVolatileRegistryHive(%p, %S) called\n",
|
||||
RegistryHive, Filename);
|
||||
|
@ -81,23 +79,6 @@ CmiInitNonVolatileRegistryHive (PEREGISTRY_HIVE RegistryHive,
|
|||
return(Status);
|
||||
}
|
||||
|
||||
/* Create log file name */
|
||||
RegistryHive->LogFileName.Length = (wcslen(Filename) + 4) * sizeof(WCHAR);
|
||||
RegistryHive->LogFileName.MaximumLength = RegistryHive->LogFileName.Length + sizeof(WCHAR);
|
||||
RegistryHive->LogFileName.Buffer = ExAllocatePoolWithTag(PagedPool,
|
||||
RegistryHive->LogFileName.MaximumLength,
|
||||
TAG('U', 'S', 'T', 'R'));
|
||||
if (RegistryHive->LogFileName.Buffer == NULL)
|
||||
{
|
||||
RtlFreeUnicodeString(&RegistryHive->HiveFileName);
|
||||
DPRINT("ExAllocatePool() failed\n");
|
||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
wcscpy(RegistryHive->LogFileName.Buffer,
|
||||
Filename);
|
||||
wcscat(RegistryHive->LogFileName.Buffer,
|
||||
L".log");
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&RegistryHive->HiveFileName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
|
@ -119,7 +100,6 @@ CmiInitNonVolatileRegistryHive (PEREGISTRY_HIVE RegistryHive,
|
|||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
RtlFreeUnicodeString(&RegistryHive->HiveFileName);
|
||||
RtlFreeUnicodeString(&RegistryHive->LogFileName);
|
||||
DPRINT("ZwCreateFile() failed (Status %lx)\n", Status);
|
||||
return(Status);
|
||||
}
|
||||
|
@ -132,77 +112,33 @@ CmiInitNonVolatileRegistryHive (PEREGISTRY_HIVE RegistryHive,
|
|||
DPRINT("CmiCreateNewRegFile() failed (Status %lx)\n", Status);
|
||||
ZwClose(FileHandle);
|
||||
RtlFreeUnicodeString(&RegistryHive->HiveFileName);
|
||||
RtlFreeUnicodeString(&RegistryHive->LogFileName);
|
||||
return(Status);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create the hive section */
|
||||
Status = MmCreateSection(&SectionObject,
|
||||
SECTION_ALL_ACCESS,
|
||||
NULL,
|
||||
NULL,
|
||||
PAGE_READWRITE,
|
||||
SEC_COMMIT,
|
||||
FileHandle,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("MmCreateSection() failed (Status %lx)\n", Status);
|
||||
RtlFreeUnicodeString(&RegistryHive->HiveFileName);
|
||||
RtlFreeUnicodeString(&RegistryHive->LogFileName);
|
||||
return(Status);
|
||||
}
|
||||
RegistryHive->HiveHandle = FileHandle;
|
||||
|
||||
/* Map the hive file */
|
||||
ViewBase = NULL;
|
||||
ViewSize = 0;
|
||||
Status = MmMapViewOfSection(SectionObject,
|
||||
PsGetCurrentProcess(),
|
||||
(PVOID*)&ViewBase,
|
||||
0,
|
||||
ViewSize,
|
||||
NULL,
|
||||
&ViewSize,
|
||||
0,
|
||||
MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("MmMapViewOfSection() failed (Status %lx)\n", Status);
|
||||
ObDereferenceObject(SectionObject);
|
||||
RtlFreeUnicodeString(&RegistryHive->HiveFileName);
|
||||
RtlFreeUnicodeString(&RegistryHive->LogFileName);
|
||||
ZwClose(FileHandle);
|
||||
return(Status);
|
||||
}
|
||||
DPRINT("ViewBase %p ViewSize %lx\n", ViewBase, ViewSize);
|
||||
|
||||
((PHBASE_BLOCK)ViewBase)->Length = ViewSize;
|
||||
Status = HvInitialize(&RegistryHive->Hive, HV_OPERATION_MEMORY, 0, 0,
|
||||
(ULONG_PTR)ViewBase, 0,
|
||||
/* Check how large the file is */
|
||||
ZwQueryInformationFile(FileHandle,
|
||||
&IoSB,
|
||||
&FileInformation,
|
||||
sizeof(FileInformation),
|
||||
FileStandardInformation);
|
||||
Status = HvInitialize(&RegistryHive->Hive, HINIT_FILE, 0, 0,
|
||||
0, FileInformation.EndOfFile.LowPart,
|
||||
CmpAllocate, CmpFree,
|
||||
CmpFileRead, CmpFileWrite, CmpFileSetSize,
|
||||
CmpFileFlush, NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to open hive\n");
|
||||
MmUnmapViewOfSection(PsGetCurrentProcess(),
|
||||
ViewBase);
|
||||
ObDereferenceObject(SectionObject);
|
||||
RtlFreeUnicodeString(&RegistryHive->HiveFileName);
|
||||
RtlFreeUnicodeString(&RegistryHive->LogFileName);
|
||||
ZwClose(FileHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
CmPrepareHive(&RegistryHive->Hive);
|
||||
|
||||
/* Unmap and dereference the hive section */
|
||||
MmUnmapViewOfSection(PsGetCurrentProcess(),
|
||||
ViewBase);
|
||||
ObDereferenceObject(SectionObject);
|
||||
|
||||
/* Close the hive file */
|
||||
ZwClose(FileHandle);
|
||||
|
||||
|
@ -275,7 +211,6 @@ CmiRemoveRegistryHive(PEREGISTRY_HIVE RegistryHive)
|
|||
|
||||
/* Release file names */
|
||||
RtlFreeUnicodeString (&RegistryHive->HiveFileName);
|
||||
RtlFreeUnicodeString (&RegistryHive->LogFileName);
|
||||
|
||||
/* Release hive */
|
||||
HvFree (&RegistryHive->Hive);
|
||||
|
@ -511,82 +446,53 @@ CmiGetMaxValueDataLength(PEREGISTRY_HIVE RegistryHive,
|
|||
return MaxValueData;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
CmiScanKeyForValue(IN PEREGISTRY_HIVE RegistryHive,
|
||||
IN PCM_KEY_NODE KeyCell,
|
||||
IN PUNICODE_STRING ValueName,
|
||||
OUT PCM_KEY_VALUE *ValueCell,
|
||||
OUT HCELL_INDEX *ValueCellOffset)
|
||||
{
|
||||
HCELL_INDEX CellIndex;
|
||||
|
||||
/* Assume failure */
|
||||
*ValueCell = NULL;
|
||||
if (ValueCellOffset) *ValueCellOffset = HCELL_NIL;
|
||||
|
||||
/* Call newer Cm API */
|
||||
CellIndex = CmpFindValueByName(&RegistryHive->Hive, KeyCell, ValueName);
|
||||
if (CellIndex == HCELL_NIL) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
/* Otherwise, get the cell data back too */
|
||||
if (ValueCellOffset) *ValueCellOffset = CellIndex;
|
||||
*ValueCell = HvGetCell(&RegistryHive->Hive, CellIndex);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
CmiScanForSubKey(IN PEREGISTRY_HIVE RegistryHive,
|
||||
IN PCM_KEY_NODE KeyCell,
|
||||
OUT PCM_KEY_NODE *SubKeyCell,
|
||||
OUT HCELL_INDEX *BlockOffset,
|
||||
IN PUNICODE_STRING KeyName,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN ULONG Attributes)
|
||||
IN PCM_KEY_NODE KeyCell,
|
||||
OUT PCM_KEY_NODE *SubKeyCell,
|
||||
OUT HCELL_INDEX *BlockOffset,
|
||||
IN PUNICODE_STRING KeyName,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN ULONG Attributes)
|
||||
{
|
||||
PHASH_TABLE_CELL HashBlock;
|
||||
PCM_KEY_NODE CurSubKeyCell;
|
||||
ULONG Storage;
|
||||
ULONG i;
|
||||
HCELL_INDEX CellIndex;
|
||||
|
||||
VERIFY_KEY_CELL(KeyCell);
|
||||
/* Assume failure */
|
||||
*SubKeyCell = NULL;
|
||||
|
||||
DPRINT("Scanning for sub key %wZ\n", KeyName);
|
||||
/* Call newer Cm API */
|
||||
CellIndex = CmpFindSubKeyByName(&RegistryHive->Hive, KeyCell, KeyName);
|
||||
if (CellIndex == HCELL_NIL) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
ASSERT(RegistryHive);
|
||||
|
||||
*SubKeyCell = NULL;
|
||||
|
||||
for (Storage = HvStable; Storage < HvMaxStorageType; Storage++)
|
||||
{
|
||||
/* The key does not have any subkeys */
|
||||
if (KeyCell->SubKeyLists[Storage] == HCELL_NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Get hash table */
|
||||
HashBlock = HvGetCell (&RegistryHive->Hive, KeyCell->SubKeyLists[Storage]);
|
||||
ASSERT(HashBlock->Id == REG_HASH_TABLE_CELL_ID);
|
||||
|
||||
for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++)
|
||||
{
|
||||
if (Attributes & OBJ_CASE_INSENSITIVE)
|
||||
{
|
||||
if ((HashBlock->Table[i].HashValue == 0 ||
|
||||
CmiCompareHashI(KeyName, (PCHAR)&HashBlock->Table[i].HashValue)))
|
||||
{
|
||||
CurSubKeyCell = HvGetCell (&RegistryHive->Hive,
|
||||
HashBlock->Table[i].KeyOffset);
|
||||
|
||||
if (CmiCompareKeyNamesI(KeyName, CurSubKeyCell))
|
||||
{
|
||||
*SubKeyCell = CurSubKeyCell;
|
||||
*BlockOffset = HashBlock->Table[i].KeyOffset;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((HashBlock->Table[i].HashValue == 0 ||
|
||||
CmiCompareHash(KeyName, (PCHAR)&HashBlock->Table[i].HashValue)))
|
||||
{
|
||||
CurSubKeyCell = HvGetCell (&RegistryHive->Hive,
|
||||
HashBlock->Table[i].KeyOffset);
|
||||
|
||||
if (CmiCompareKeyNames(KeyName, CurSubKeyCell))
|
||||
{
|
||||
*SubKeyCell = CurSubKeyCell;
|
||||
*BlockOffset = HashBlock->Table[i].KeyOffset;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
/* Otherwise, get the cell data back too */
|
||||
*BlockOffset = CellIndex;
|
||||
*SubKeyCell = HvGetCell(&RegistryHive->Hive, CellIndex);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
CmiAddSubKey(PEREGISTRY_HIVE RegistryHive,
|
||||
PKEY_OBJECT ParentKey,
|
||||
|
@ -884,54 +790,6 @@ CmiRemoveSubKey(PEREGISTRY_HIVE RegistryHive,
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
CmiScanKeyForValue(IN PEREGISTRY_HIVE RegistryHive,
|
||||
IN PCM_KEY_NODE KeyCell,
|
||||
IN PUNICODE_STRING ValueName,
|
||||
OUT PCM_KEY_VALUE *ValueCell,
|
||||
OUT HCELL_INDEX *ValueCellOffset)
|
||||
{
|
||||
PVALUE_LIST_CELL ValueListCell;
|
||||
PCM_KEY_VALUE CurValueCell;
|
||||
ULONG i;
|
||||
|
||||
*ValueCell = NULL;
|
||||
if (ValueCellOffset != NULL)
|
||||
*ValueCellOffset = (HCELL_INDEX)-1;
|
||||
|
||||
/* The key does not have any values */
|
||||
if (KeyCell->ValueList.List == (HCELL_INDEX)-1)
|
||||
{
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
ValueListCell = HvGetCell (&RegistryHive->Hive, KeyCell->ValueList.List);
|
||||
|
||||
VERIFY_VALUE_LIST_CELL(ValueListCell);
|
||||
|
||||
for (i = 0; i < KeyCell->ValueList.Count; i++)
|
||||
{
|
||||
CurValueCell = HvGetCell (&RegistryHive->Hive,
|
||||
ValueListCell->ValueOffset[i]);
|
||||
|
||||
if (CmiComparePackedNames(ValueName,
|
||||
CurValueCell->Name,
|
||||
CurValueCell->NameSize,
|
||||
(BOOLEAN)((CurValueCell->Flags & REG_VALUE_NAME_PACKED) ? TRUE : FALSE)))
|
||||
{
|
||||
*ValueCell = CurValueCell;
|
||||
if (ValueCellOffset != NULL)
|
||||
*ValueCellOffset = ValueListCell->ValueOffset[i];
|
||||
//DPRINT("Found value %s\n", ValueName);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
CmiGetValueFromKeyByIndex(IN PEREGISTRY_HIVE RegistryHive,
|
||||
IN PCM_KEY_NODE KeyCell,
|
||||
|
@ -1480,241 +1338,6 @@ CmiCompareKeyNamesI(PUNICODE_STRING KeyName,
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
CmiCopyKey (PEREGISTRY_HIVE DstHive,
|
||||
PCM_KEY_NODE DstKeyCell,
|
||||
PEREGISTRY_HIVE SrcHive,
|
||||
PCM_KEY_NODE SrcKeyCell)
|
||||
{
|
||||
PCM_KEY_NODE NewKeyCell;
|
||||
ULONG NewKeyCellSize;
|
||||
HCELL_INDEX NewKeyCellOffset;
|
||||
PHASH_TABLE_CELL NewHashTableCell;
|
||||
ULONG NewHashTableSize;
|
||||
HCELL_INDEX NewHashTableOffset;
|
||||
ULONG i;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
DPRINT ("CmiCopyKey() called\n");
|
||||
|
||||
if (DstKeyCell == NULL)
|
||||
{
|
||||
/* Allocate and copy key cell */
|
||||
NewKeyCellSize = sizeof(CM_KEY_NODE) + SrcKeyCell->NameSize;
|
||||
NewKeyCellOffset = HvAllocateCell (&DstHive->Hive, NewKeyCellSize, HvStable);
|
||||
if (NewKeyCellOffset == HCELL_NULL)
|
||||
{
|
||||
DPRINT1 ("Failed to allocate a key cell\n");
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
NewKeyCell = HvGetCell (&DstHive->Hive, NewKeyCellOffset);
|
||||
RtlCopyMemory (NewKeyCell,
|
||||
SrcKeyCell,
|
||||
NewKeyCellSize);
|
||||
|
||||
DstHive->Hive.HiveHeader->RootCell = NewKeyCellOffset;
|
||||
|
||||
/* Copy class name */
|
||||
if (SrcKeyCell->ClassNameOffset != (HCELL_INDEX) -1)
|
||||
{
|
||||
PVOID SrcClassNameCell;
|
||||
PVOID NewClassNameCell;
|
||||
HCELL_INDEX NewClassNameOffset;
|
||||
|
||||
SrcClassNameCell = HvGetCell (&SrcHive->Hive, SrcKeyCell->ClassNameOffset);
|
||||
|
||||
NewKeyCell->ClassSize = SrcKeyCell->ClassSize;
|
||||
NewClassNameOffset = HvAllocateCell (&DstHive->Hive, NewKeyCell->ClassSize, HvStable);
|
||||
if (NewClassNameOffset == HCELL_NULL)
|
||||
{
|
||||
DPRINT1 ("CmiAllocateBlock() failed\n");
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
NewClassNameCell = HvGetCell (&DstHive->Hive, NewClassNameOffset);
|
||||
RtlCopyMemory (NewClassNameCell,
|
||||
SrcClassNameCell,
|
||||
NewKeyCell->ClassSize);
|
||||
NewKeyCell->ClassNameOffset = NewClassNameOffset;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NewKeyCell = DstKeyCell;
|
||||
}
|
||||
|
||||
/* Allocate hash table */
|
||||
if (SrcKeyCell->SubKeyCounts[HvStable] > 0)
|
||||
{
|
||||
NewHashTableSize = ROUND_UP(SrcKeyCell->SubKeyCounts[HvStable] + 1, 4) - 1;
|
||||
Status = CmiAllocateHashTableCell (DstHive,
|
||||
&NewHashTableCell,
|
||||
&NewHashTableOffset,
|
||||
NewHashTableSize,
|
||||
HvStable);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1 ("CmiAllocateHashTableBlock() failed (Status %lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
NewKeyCell->SubKeyLists[HvStable] = NewHashTableOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
NewHashTableCell = NULL;
|
||||
}
|
||||
|
||||
/* Allocate and copy value list and values */
|
||||
if (SrcKeyCell->ValueList.Count != 0)
|
||||
{
|
||||
PVALUE_LIST_CELL NewValueListCell;
|
||||
PVALUE_LIST_CELL SrcValueListCell;
|
||||
PCM_KEY_VALUE NewValueCell;
|
||||
PCM_KEY_VALUE SrcValueCell;
|
||||
PVOID SrcValueDataCell;
|
||||
PVOID NewValueDataCell;
|
||||
HCELL_INDEX ValueCellOffset;
|
||||
HCELL_INDEX ValueDataCellOffset;
|
||||
ULONG NewValueListCellSize;
|
||||
ULONG NewValueCellSize;
|
||||
|
||||
|
||||
NewValueListCellSize =
|
||||
ROUND_UP(SrcKeyCell->ValueList.Count, 4) * sizeof(HCELL_INDEX);
|
||||
NewKeyCell->ValueList.List = HvAllocateCell (&DstHive->Hive,
|
||||
NewValueListCellSize,
|
||||
HvStable);
|
||||
if (NewKeyCell->ValueList.List == HCELL_NULL)
|
||||
{
|
||||
DPRINT1 ("HvAllocateCell() failed\n");
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
DPRINT1("KeyCell->ValueList.List: %x\n", NewKeyCell->ValueList.List);
|
||||
|
||||
NewValueListCell = HvGetCell (&DstHive->Hive, NewKeyCell->ValueList.List);
|
||||
RtlZeroMemory (NewValueListCell,
|
||||
NewValueListCellSize);
|
||||
|
||||
/* Copy values */
|
||||
SrcValueListCell = HvGetCell (&SrcHive->Hive, SrcKeyCell->ValueList.List);
|
||||
for (i = 0; i < SrcKeyCell->ValueList.Count; i++)
|
||||
{
|
||||
/* Copy value cell */
|
||||
SrcValueCell = HvGetCell (&SrcHive->Hive, SrcValueListCell->ValueOffset[i]);
|
||||
|
||||
NewValueCellSize = sizeof(CM_KEY_VALUE) + SrcValueCell->NameSize;
|
||||
ValueCellOffset = HvAllocateCell (&DstHive->Hive, NewValueCellSize, HvStable);
|
||||
if (ValueCellOffset == HCELL_NULL)
|
||||
{
|
||||
DPRINT1 ("HvAllocateCell() failed (Status %lx)\n", Status);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
NewValueCell = HvGetCell (&DstHive->Hive, ValueCellOffset);
|
||||
NewValueListCell->ValueOffset[i] = ValueCellOffset;
|
||||
RtlCopyMemory (NewValueCell,
|
||||
SrcValueCell,
|
||||
NewValueCellSize);
|
||||
|
||||
/* Copy value data cell */
|
||||
if (SrcValueCell->DataSize > (LONG) sizeof(PVOID))
|
||||
{
|
||||
SrcValueDataCell = HvGetCell (&SrcHive->Hive, SrcValueCell->DataOffset);
|
||||
|
||||
ValueDataCellOffset = HvAllocateCell (&DstHive->Hive, SrcValueCell->DataSize, HvStable);
|
||||
if (ValueDataCellOffset == HCELL_NULL)
|
||||
{
|
||||
DPRINT1 ("HvAllocateCell() failed\n");
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
NewValueDataCell = HvGetCell (&DstHive->Hive, ValueDataCellOffset);
|
||||
RtlCopyMemory (NewValueDataCell,
|
||||
SrcValueDataCell,
|
||||
SrcValueCell->DataSize);
|
||||
NewValueCell->DataOffset = ValueDataCellOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy subkeys */
|
||||
if (SrcKeyCell->SubKeyCounts[HvStable] > 0)
|
||||
{
|
||||
PHASH_TABLE_CELL SrcHashTableCell;
|
||||
PCM_KEY_NODE SrcSubKeyCell;
|
||||
PCM_KEY_NODE NewSubKeyCell;
|
||||
ULONG NewSubKeyCellSize;
|
||||
HCELL_INDEX NewSubKeyCellOffset;
|
||||
PHASH_RECORD SrcHashRecord;
|
||||
|
||||
SrcHashTableCell = HvGetCell (&SrcHive->Hive, SrcKeyCell->SubKeyLists[HvStable]);
|
||||
|
||||
for (i = 0; i < SrcKeyCell->SubKeyCounts[HvStable]; i++)
|
||||
{
|
||||
SrcHashRecord = &SrcHashTableCell->Table[i];
|
||||
SrcSubKeyCell = HvGetCell (&SrcHive->Hive, SrcHashRecord->KeyOffset);
|
||||
|
||||
/* Allocate and copy key cell */
|
||||
NewSubKeyCellSize = sizeof(CM_KEY_NODE) + SrcSubKeyCell->NameSize;
|
||||
NewSubKeyCellOffset = HvAllocateCell (&DstHive->Hive, NewSubKeyCellSize, HvStable);
|
||||
if (NewSubKeyCellOffset == HCELL_NULL)
|
||||
{
|
||||
DPRINT1 ("Failed to allocate a sub key cell\n");
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
NewSubKeyCell = HvGetCell (&DstHive->Hive, NewSubKeyCellOffset);
|
||||
NewHashTableCell->Table[i].KeyOffset = NewSubKeyCellOffset;
|
||||
NewHashTableCell->Table[i].HashValue = SrcHashRecord->HashValue;
|
||||
|
||||
RtlCopyMemory (NewSubKeyCell,
|
||||
SrcSubKeyCell,
|
||||
NewSubKeyCellSize);
|
||||
|
||||
/* Copy class name */
|
||||
if (SrcSubKeyCell->ClassNameOffset != (HCELL_INDEX) -1)
|
||||
{
|
||||
PVOID SrcClassNameCell;
|
||||
PVOID NewClassNameCell;
|
||||
HCELL_INDEX NewClassNameOffset;
|
||||
|
||||
SrcClassNameCell = HvGetCell (&SrcHive->Hive,
|
||||
SrcSubKeyCell->ClassNameOffset);
|
||||
|
||||
NewSubKeyCell->ClassSize = SrcSubKeyCell->ClassSize;
|
||||
NewClassNameOffset = HvAllocateCell (&DstHive->Hive,
|
||||
NewSubKeyCell->ClassSize,
|
||||
HvStable);
|
||||
if (NewClassNameOffset == HCELL_NULL)
|
||||
{
|
||||
DPRINT1 ("HvAllocateCell() failed (Status %lx)\n", Status);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
NewClassNameCell = HvGetCell (&DstHive->Hive, NewClassNameOffset);
|
||||
NewSubKeyCell->ClassNameOffset = NewClassNameOffset;
|
||||
RtlCopyMemory (NewClassNameCell,
|
||||
SrcClassNameCell,
|
||||
NewSubKeyCell->ClassSize);
|
||||
}
|
||||
|
||||
/* Copy subkey data and subkeys */
|
||||
Status = CmiCopyKey (DstHive,
|
||||
NewSubKeyCell,
|
||||
SrcHive,
|
||||
SrcSubKeyCell);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1 ("CmiAllocateBlock() failed (Status %lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
CmiSaveTempHive (PEREGISTRY_HIVE Hive,
|
||||
HANDLE FileHandle)
|
||||
|
|
|
@ -391,6 +391,7 @@ CmpFindSubKeyInLeaf(IN PHHIVE Hive,
|
|||
/* Check if we got lucky and found it */
|
||||
if (!Result) return i;
|
||||
|
||||
#ifdef SOMEONE_WAS_NICE_ENOUGH_TO_MAKE_OUR_CELLS_LEXICALLY_SORTED
|
||||
/* Check if the result is below us */
|
||||
if (Result < 0)
|
||||
{
|
||||
|
@ -405,7 +406,6 @@ CmpFindSubKeyInLeaf(IN PHHIVE Hive,
|
|||
Low = i;
|
||||
}
|
||||
|
||||
#ifdef SOMEONE_WAS_NICE_ENOUGH_TO_MAKE_OUR_CELLS_LEXICALLY_SORTED
|
||||
/* Check if this is the last entry, if so, break out and handle it */
|
||||
if ((High - Low) <= 1) break;
|
||||
|
||||
|
|
|
@ -364,9 +364,6 @@ CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
|||
/* Set the hive filename */
|
||||
RtlCreateUnicodeString(&SystemHive->HiveFileName, SYSTEM_REG_FILE);
|
||||
|
||||
/* Set the log filename */
|
||||
RtlCreateUnicodeString(&SystemHive->LogFileName, SYSTEM_LOG_FILE);
|
||||
|
||||
/* We imported, no need to create a new hive */
|
||||
Allocate = FALSE;
|
||||
|
||||
|
|
Loading…
Reference in a new issue