- 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:
Alex Ionescu 2007-05-12 03:28:04 +00:00
parent 6ef9f575cb
commit ef1f549526
5 changed files with 205 additions and 435 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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)

View file

@ -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;

View file

@ -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;