- Fix HBLOCK_SIZE vs. HSECTOR_SIZE mix-ups in HvpGetHiveHeader.
- Add a function to create cluster-aligned hive base blocks (HBASE_BLOCK) based on the existing code of HvpGetHiveHeader, and use it everytime we need to allocate HBASE_BLOCKs.
- Keep the actual base block size in the BaseBlockAlloc member, and use this value for the "quota" parameter when we free the blocks.
- Introduce & use a function to initialize the hive file name array (mainly used for debugging purposes).
- "HvpInitializeMemoryInplaceHive" should read "HvpInitializeFlatHive" instead since this function is used to initialize a flat hive. Memory-in-place hives are a different thing.
- Fix some memory leaks in the error paths of HvLoadHive.
- Initialize some additional hive members in HvInitialize(Hive).

svn path=/trunk/; revision=70582
This commit is contained in:
Hermès Bélusca-Maïto 2016-01-13 01:40:58 +00:00
parent 36a7330eee
commit 734bc29142

View file

@ -14,10 +14,9 @@
* *
* Internal function to verify that a hive header has valid format. * Internal function to verify that a hive header has valid format.
*/ */
BOOLEAN CMAPI BOOLEAN CMAPI
HvpVerifyHiveHeader( HvpVerifyHiveHeader(
PHBASE_BLOCK BaseBlock) IN PHBASE_BLOCK BaseBlock)
{ {
if (BaseBlock->Signature != HV_SIGNATURE || if (BaseBlock->Signature != HV_SIGNATURE ||
BaseBlock->Major != HSYS_MAJOR || BaseBlock->Major != HSYS_MAJOR ||
@ -31,7 +30,7 @@ HvpVerifyHiveHeader(
DPRINT1("Verify Hive Header failed:\n"); DPRINT1("Verify Hive Header failed:\n");
DPRINT1(" Signature: 0x%x, expected 0x%x; Major: 0x%x, expected 0x%x\n", DPRINT1(" Signature: 0x%x, expected 0x%x; Major: 0x%x, expected 0x%x\n",
BaseBlock->Signature, HV_SIGNATURE, BaseBlock->Major, HSYS_MAJOR); BaseBlock->Signature, HV_SIGNATURE, BaseBlock->Major, HSYS_MAJOR);
DPRINT1(" Minor: 0x%x is not >= 0x%x; Type: 0x%x, expected 0x%x\n", DPRINT1(" Minor: 0x%x expected to be >= 0x%x; Type: 0x%x, expected 0x%x\n",
BaseBlock->Minor, HSYS_MINOR, BaseBlock->Type, HFILE_TYPE_PRIMARY); BaseBlock->Minor, HSYS_MINOR, BaseBlock->Type, HFILE_TYPE_PRIMARY);
DPRINT1(" Format: 0x%x, expected 0x%x; Cluster: 0x%x, expected 1\n", DPRINT1(" Format: 0x%x, expected 0x%x; Cluster: 0x%x, expected 1\n",
BaseBlock->Format, HBASE_FORMAT_MEMORY, BaseBlock->Cluster); BaseBlock->Format, HBASE_FORMAT_MEMORY, BaseBlock->Cluster);
@ -48,10 +47,8 @@ HvpVerifyHiveHeader(
/** /**
* @name HvpFreeHiveBins * @name HvpFreeHiveBins
* *
* Internal function to free all bin storage associated with hive * Internal function to free all bin storage associated with a hive descriptor.
* descriptor.
*/ */
VOID CMAPI VOID CMAPI
HvpFreeHiveBins( HvpFreeHiveBins(
PHHIVE Hive) PHHIVE Hive)
@ -81,28 +78,99 @@ HvpFreeHiveBins(
} }
} }
/**
* @name HvpAllocBaseBlockAligned
*
* Internal helper function to allocate cluster-aligned hive base blocks.
*/
static __inline PHBASE_BLOCK
HvpAllocBaseBlockAligned(
IN PHHIVE Hive,
IN BOOLEAN Paged,
IN ULONG Tag)
{
PHBASE_BLOCK BaseBlock;
ULONG Alignment;
ASSERT(sizeof(HBASE_BLOCK) >= (HSECTOR_SIZE * Hive->Cluster));
/* Allocate the buffer */
BaseBlock = Hive->Allocate(Hive->BaseBlockAlloc, Paged, Tag);
if (!BaseBlock) return NULL;
/* Check for, and enforce, alignment */
Alignment = Hive->Cluster * HSECTOR_SIZE -1;
if ((ULONG_PTR)BaseBlock & Alignment)
{
/* Free the old header and reallocate a new one, always paged */
Hive->Free(BaseBlock, Hive->BaseBlockAlloc);
BaseBlock = Hive->Allocate(PAGE_SIZE, TRUE, Tag);
if (!BaseBlock) return NULL;
Hive->BaseBlockAlloc = PAGE_SIZE;
}
return BaseBlock;
}
/**
* @name HvpInitFileName
*
* Internal function to initialize the UNICODE NULL-terminated hive file name
* member of a hive header by copying the last 31 characters of the file name.
* Mainly used for debugging purposes.
*/
static VOID
HvpInitFileName(
IN OUT PHBASE_BLOCK BaseBlock,
IN PCUNICODE_STRING FileName OPTIONAL)
{
ULONG_PTR Offset;
SIZE_T Length;
/* Always NULL-initialize */
RtlZeroMemory(BaseBlock->FileName, (HIVE_FILENAME_MAXLEN + 1) * sizeof(WCHAR));
/* Copy the 31 last characters of the hive file name if any */
if (!FileName) return;
if (FileName->Length / sizeof(WCHAR) <= HIVE_FILENAME_MAXLEN)
{
Offset = 0;
Length = FileName->Length;
}
else
{
Offset = FileName->Length / sizeof(WCHAR) - HIVE_FILENAME_MAXLEN;
Length = HIVE_FILENAME_MAXLEN * sizeof(WCHAR);
}
RtlCopyMemory(BaseBlock->FileName, FileName->Buffer + Offset, Length);
}
/** /**
* @name HvpCreateHive * @name HvpCreateHive
* *
* Internal helper function to initialize hive descriptor structure for * Internal helper function to initialize a hive descriptor structure
* newly created hive. * for a newly created hive in memory.
* *
* @see HvInitialize * @see HvInitialize
*/ */
NTSTATUS CMAPI NTSTATUS CMAPI
HvpCreateHive( HvpCreateHive(
PHHIVE RegistryHive, IN OUT PHHIVE RegistryHive,
PCUNICODE_STRING FileName OPTIONAL) IN PCUNICODE_STRING FileName OPTIONAL)
{ {
PHBASE_BLOCK BaseBlock; PHBASE_BLOCK BaseBlock;
ULONG Index; ULONG Index;
BaseBlock = RegistryHive->Allocate(sizeof(HBASE_BLOCK), FALSE, TAG_CM); /* Allocate the base block */
BaseBlock = HvpAllocBaseBlockAligned(RegistryHive, FALSE, TAG_CM);
if (BaseBlock == NULL) if (BaseBlock == NULL)
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
RtlZeroMemory(BaseBlock, sizeof(HBASE_BLOCK)); /* Clear it */
RtlZeroMemory(BaseBlock, RegistryHive->BaseBlockAlloc);
BaseBlock->Signature = HV_SIGNATURE; BaseBlock->Signature = HV_SIGNATURE;
BaseBlock->Major = HSYS_MAJOR; BaseBlock->Major = HSYS_MAJOR;
@ -114,37 +182,29 @@ HvpCreateHive(
BaseBlock->Length = 0; BaseBlock->Length = 0;
BaseBlock->Sequence1 = 1; BaseBlock->Sequence1 = 1;
BaseBlock->Sequence2 = 1; BaseBlock->Sequence2 = 1;
BaseBlock->TimeStamp.QuadPart = 0ULL;
/* Copy the 31 last characters of the hive file name if any */ /*
if (FileName) * No need to compute the checksum since
{ * the hive resides only in memory so far.
if (FileName->Length / sizeof(WCHAR) <= HIVE_FILENAME_MAXLEN) */
{ BaseBlock->CheckSum = 0;
RtlCopyMemory(BaseBlock->FileName,
FileName->Buffer,
FileName->Length);
}
else
{
RtlCopyMemory(BaseBlock->FileName,
FileName->Buffer +
FileName->Length / sizeof(WCHAR) - HIVE_FILENAME_MAXLEN,
HIVE_FILENAME_MAXLEN * sizeof(WCHAR));
}
/* NULL-terminate */ /* Set default boot type */
BaseBlock->FileName[HIVE_FILENAME_MAXLEN] = L'\0'; BaseBlock->BootType = 0;
}
BaseBlock->CheckSum = HvpHiveHeaderChecksum(BaseBlock);
/* Setup hive data */
RegistryHive->BaseBlock = BaseBlock; RegistryHive->BaseBlock = BaseBlock;
RegistryHive->Version = BaseBlock->Minor; // == HSYS_MINOR
for (Index = 0; Index < 24; Index++) for (Index = 0; Index < 24; Index++)
{ {
RegistryHive->Storage[Stable].FreeDisplay[Index] = HCELL_NIL; RegistryHive->Storage[Stable].FreeDisplay[Index] = HCELL_NIL;
RegistryHive->Storage[Volatile].FreeDisplay[Index] = HCELL_NIL; RegistryHive->Storage[Volatile].FreeDisplay[Index] = HCELL_NIL;
} }
HvpInitFileName(BaseBlock, FileName);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -152,16 +212,16 @@ HvpCreateHive(
* @name HvpInitializeMemoryHive * @name HvpInitializeMemoryHive
* *
* Internal helper function to initialize hive descriptor structure for * Internal helper function to initialize hive descriptor structure for
* a hive stored in memory. The data of the hive are copied and it is * an existing hive stored in memory. The data of the hive is copied
* prepared for read/write access. * and it is prepared for read/write access.
* *
* @see HvInitialize * @see HvInitialize
*/ */
NTSTATUS CMAPI NTSTATUS CMAPI
HvpInitializeMemoryHive( HvpInitializeMemoryHive(
PHHIVE Hive, PHHIVE Hive,
PVOID ChunkBase) PHBASE_BLOCK ChunkBase,
IN PCUNICODE_STRING FileName OPTIONAL)
{ {
SIZE_T BlockIndex; SIZE_T BlockIndex;
PHBIN Bin, NewBin; PHBIN Bin, NewBin;
@ -170,24 +230,27 @@ HvpInitializeMemoryHive(
PULONG BitmapBuffer; PULONG BitmapBuffer;
SIZE_T ChunkSize; SIZE_T ChunkSize;
ChunkSize = ((PHBASE_BLOCK)ChunkBase)->Length; ChunkSize = ChunkBase->Length;
DPRINT("ChunkSize: %lx\n", ChunkSize); DPRINT("ChunkSize: %lx\n", ChunkSize);
if (ChunkSize < sizeof(HBASE_BLOCK) || if (ChunkSize < sizeof(HBASE_BLOCK) ||
!HvpVerifyHiveHeader((PHBASE_BLOCK)ChunkBase)) !HvpVerifyHiveHeader(ChunkBase))
{ {
DPRINT1("Registry is corrupt: ChunkSize %lu < sizeof(HBASE_BLOCK) %lu, " DPRINT1("Registry is corrupt: ChunkSize %lu < sizeof(HBASE_BLOCK) %lu, "
"or HvpVerifyHiveHeader() failed\n", ChunkSize, (SIZE_T)sizeof(HBASE_BLOCK)); "or HvpVerifyHiveHeader() failed\n", ChunkSize, sizeof(HBASE_BLOCK));
return STATUS_REGISTRY_CORRUPT; return STATUS_REGISTRY_CORRUPT;
} }
Hive->BaseBlock = Hive->Allocate(sizeof(HBASE_BLOCK), FALSE, TAG_CM); /* Allocate the base block */
Hive->BaseBlock = HvpAllocBaseBlockAligned(Hive, FALSE, TAG_CM);
if (Hive->BaseBlock == NULL) if (Hive->BaseBlock == NULL)
{
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
}
RtlCopyMemory(Hive->BaseBlock, ChunkBase, sizeof(HBASE_BLOCK)); RtlCopyMemory(Hive->BaseBlock, ChunkBase, sizeof(HBASE_BLOCK));
/* Setup hive data */
Hive->Version = ChunkBase->Minor;
/* /*
* Build a block list from the in-memory chunk and copy the data as * Build a block list from the in-memory chunk and copy the data as
* we go. * we go.
@ -200,7 +263,7 @@ HvpInitializeMemoryHive(
if (Hive->Storage[Stable].BlockList == NULL) if (Hive->Storage[Stable].BlockList == NULL)
{ {
DPRINT1("Allocating block list failed\n"); DPRINT1("Allocating block list failed\n");
Hive->Free(Hive->BaseBlock, 0); Hive->Free(Hive->BaseBlock, Hive->BaseBlockAlloc);
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
} }
@ -212,16 +275,16 @@ HvpInitializeMemoryHive(
{ {
DPRINT1("Invalid bin at BlockIndex %lu, Signature 0x%x, Size 0x%x\n", DPRINT1("Invalid bin at BlockIndex %lu, Signature 0x%x, Size 0x%x\n",
(unsigned long)BlockIndex, (unsigned)Bin->Signature, (unsigned)Bin->Size); (unsigned long)BlockIndex, (unsigned)Bin->Signature, (unsigned)Bin->Size);
Hive->Free(Hive->BaseBlock, 0);
Hive->Free(Hive->Storage[Stable].BlockList, 0); Hive->Free(Hive->Storage[Stable].BlockList, 0);
Hive->Free(Hive->BaseBlock, Hive->BaseBlockAlloc);
return STATUS_REGISTRY_CORRUPT; return STATUS_REGISTRY_CORRUPT;
} }
NewBin = Hive->Allocate(Bin->Size, TRUE, TAG_CM); NewBin = Hive->Allocate(Bin->Size, TRUE, TAG_CM);
if (NewBin == NULL) if (NewBin == NULL)
{ {
Hive->Free(Hive->BaseBlock, 0);
Hive->Free(Hive->Storage[Stable].BlockList, 0); Hive->Free(Hive->Storage[Stable].BlockList, 0);
Hive->Free(Hive->BaseBlock, Hive->BaseBlockAlloc);
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
} }
@ -246,7 +309,7 @@ HvpInitializeMemoryHive(
if (HvpCreateHiveFreeCellList(Hive)) if (HvpCreateHiveFreeCellList(Hive))
{ {
HvpFreeHiveBins(Hive); HvpFreeHiveBins(Hive);
Hive->Free(Hive->BaseBlock, 0); Hive->Free(Hive->BaseBlock, Hive->BaseBlockAlloc);
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
} }
@ -256,18 +319,20 @@ HvpInitializeMemoryHive(
if (BitmapBuffer == NULL) if (BitmapBuffer == NULL)
{ {
HvpFreeHiveBins(Hive); HvpFreeHiveBins(Hive);
Hive->Free(Hive->BaseBlock, 0); Hive->Free(Hive->BaseBlock, Hive->BaseBlockAlloc);
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
} }
RtlInitializeBitMap(&Hive->DirtyVector, BitmapBuffer, BitmapSize * 8); RtlInitializeBitMap(&Hive->DirtyVector, BitmapBuffer, BitmapSize * 8);
RtlClearAllBits(&Hive->DirtyVector); RtlClearAllBits(&Hive->DirtyVector);
HvpInitFileName(Hive->BaseBlock, FileName);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
/** /**
* @name HvpInitializeMemoryInplaceHive * @name HvpInitializeFlatHive
* *
* Internal helper function to initialize hive descriptor structure for * Internal helper function to initialize hive descriptor structure for
* a hive stored in memory. The in-memory data of the hive are directly * a hive stored in memory. The in-memory data of the hive are directly
@ -275,20 +340,22 @@ HvpInitializeMemoryHive(
* *
* @see HvInitialize * @see HvInitialize
*/ */
NTSTATUS CMAPI NTSTATUS CMAPI
HvpInitializeMemoryInplaceHive( HvpInitializeFlatHive(
PHHIVE Hive, PHHIVE Hive,
PVOID ChunkBase) PHBASE_BLOCK ChunkBase)
{
if (!HvpVerifyHiveHeader((PHBASE_BLOCK)ChunkBase))
{ {
if (!HvpVerifyHiveHeader(ChunkBase))
return STATUS_REGISTRY_CORRUPT; return STATUS_REGISTRY_CORRUPT;
}
Hive->BaseBlock = (PHBASE_BLOCK)ChunkBase; /* Setup hive data */
Hive->ReadOnly = TRUE; Hive->BaseBlock = ChunkBase;
Hive->Version = ChunkBase->Minor;
Hive->Flat = TRUE; Hive->Flat = TRUE;
Hive->ReadOnly = TRUE;
/* Set default boot type */
ChunkBase->BootType = 0;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -310,25 +377,15 @@ HvpGetHiveHeader(IN PHHIVE Hive,
IN PLARGE_INTEGER TimeStamp) IN PLARGE_INTEGER TimeStamp)
{ {
PHBASE_BLOCK BaseBlock; PHBASE_BLOCK BaseBlock;
ULONG Alignment;
ULONG Result; ULONG Result;
ULONG Offset = 0; ULONG Offset = 0;
ASSERT(sizeof(HBASE_BLOCK) >= (HBLOCK_SIZE * Hive->Cluster));
/* Assume failure and allocate the buffer */ ASSERT(sizeof(HBASE_BLOCK) >= (HSECTOR_SIZE * Hive->Cluster));
*HiveBaseBlock = 0;
BaseBlock = Hive->Allocate(sizeof(HBASE_BLOCK), TRUE, TAG_CM);
if (!BaseBlock) return NoMemory;
/* Check for, and enforce, alignment */ /* Assume failure and allocate the base block */
Alignment = Hive->Cluster * HBLOCK_SIZE -1; *HiveBaseBlock = NULL;
if ((ULONG_PTR)BaseBlock & Alignment) BaseBlock = HvpAllocBaseBlockAligned(Hive, TRUE, TAG_CM);
{
/* Free the old header */
Hive->Free(BaseBlock, 0);
BaseBlock = Hive->Allocate(PAGE_SIZE, TRUE, TAG_CM);
if (!BaseBlock) return NoMemory; if (!BaseBlock) return NoMemory;
}
/* Clear it */ /* Clear it */
RtlZeroMemory(BaseBlock, sizeof(HBASE_BLOCK)); RtlZeroMemory(BaseBlock, sizeof(HBASE_BLOCK));
@ -338,7 +395,7 @@ HvpGetHiveHeader(IN PHHIVE Hive,
HFILE_TYPE_PRIMARY, HFILE_TYPE_PRIMARY,
&Offset, &Offset,
BaseBlock, BaseBlock,
Hive->Cluster * HBLOCK_SIZE); Hive->Cluster * HSECTOR_SIZE);
/* Couldn't read: assume it's not a hive */ /* Couldn't read: assume it's not a hive */
if (!Result) return NotHive; if (!Result) return NotHive;
@ -353,8 +410,10 @@ HvpGetHiveHeader(IN PHHIVE Hive,
} }
NTSTATUS CMAPI NTSTATUS CMAPI
HvLoadHive(IN PHHIVE Hive) HvLoadHive(IN PHHIVE Hive,
IN PCUNICODE_STRING FileName OPTIONAL)
{ {
NTSTATUS Status;
PHBASE_BLOCK BaseBlock = NULL; PHBASE_BLOCK BaseBlock = NULL;
ULONG Result; ULONG Result;
LARGE_INTEGER TimeStamp; LARGE_INTEGER TimeStamp;
@ -391,12 +450,16 @@ HvLoadHive(IN PHHIVE Hive)
/* Setup hive data */ /* Setup hive data */
Hive->BaseBlock = BaseBlock; Hive->BaseBlock = BaseBlock;
Hive->Version = Hive->BaseBlock->Minor; Hive->Version = BaseBlock->Minor;
/* Allocate a buffer large enough to hold the hive */ /* Allocate a buffer large enough to hold the hive */
FileSize = HBLOCK_SIZE + BaseBlock->Length; FileSize = HBLOCK_SIZE + BaseBlock->Length; // == sizeof(HBASE_BLOCK) + BaseBlock->Length;
HiveData = Hive->Allocate(FileSize, TRUE, TAG_CM); HiveData = Hive->Allocate(FileSize, TRUE, TAG_CM);
if (!HiveData) return STATUS_INSUFFICIENT_RESOURCES; if (!HiveData)
{
Hive->Free(BaseBlock, Hive->BaseBlockAlloc);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Now read the whole hive */ /* Now read the whole hive */
Result = Hive->FileRead(Hive, Result = Hive->FileRead(Hive,
@ -404,14 +467,23 @@ HvLoadHive(IN PHHIVE Hive)
&Offset, &Offset,
HiveData, HiveData,
FileSize); FileSize);
if (!Result) return STATUS_NOT_REGISTRY_FILE; if (!Result)
{
Hive->Free(HiveData, FileSize);
Hive->Free(BaseBlock, Hive->BaseBlockAlloc);
return STATUS_NOT_REGISTRY_FILE;
}
// This is a HACK! // This is a HACK!
/* Free our base block... it's usless in this implementation */ /* Free our base block... it's usless in this implementation */
Hive->Free(BaseBlock, 0); Hive->Free(BaseBlock, Hive->BaseBlockAlloc);
/* Initialize the hive directly from memory */ /* Initialize the hive directly from memory */
return HvpInitializeMemoryHive(Hive, HiveData); Status = HvpInitializeMemoryHive(Hive, HiveData, FileName);
if (!NT_SUCCESS(Status))
Hive->Free(HiveData, FileSize);
return Status;
} }
/** /**
@ -444,7 +516,6 @@ HvLoadHive(IN PHHIVE Hive)
* *
* @see HvFree * @see HvFree
*/ */
NTSTATUS CMAPI NTSTATUS CMAPI
HvInitialize( HvInitialize(
PHHIVE RegistryHive, PHHIVE RegistryHive,
@ -464,8 +535,6 @@ HvInitialize(
NTSTATUS Status; NTSTATUS Status;
PHHIVE Hive = RegistryHive; PHHIVE Hive = RegistryHive;
UNREFERENCED_PARAMETER(FileType);
/* /*
* Create a new hive structure that will hold all the maintenance data. * Create a new hive structure that will hold all the maintenance data.
*/ */
@ -474,13 +543,18 @@ HvInitialize(
Hive->Allocate = Allocate; Hive->Allocate = Allocate;
Hive->Free = Free; Hive->Free = Free;
Hive->FileRead = FileRead;
Hive->FileWrite = FileWrite;
Hive->FileSetSize = FileSetSize; Hive->FileSetSize = FileSetSize;
Hive->FileWrite = FileWrite;
Hive->FileRead = FileRead;
Hive->FileFlush = FileFlush; Hive->FileFlush = FileFlush;
Hive->RefreshCount = 0;
Hive->StorageTypeCount = HTYPE_COUNT; Hive->StorageTypeCount = HTYPE_COUNT;
Hive->Cluster = 1; Hive->Cluster = Cluster;
Hive->BaseBlockAlloc = sizeof(HBASE_BLOCK); // == HBLOCK_SIZE
Hive->Version = HSYS_MINOR; Hive->Version = HSYS_MINOR;
Hive->Log = (FileType == HFILE_TYPE_LOG);
Hive->HiveFlags = HiveFlags & ~HIVE_NOLAZYFLUSH; Hive->HiveFlags = HiveFlags & ~HIVE_NOLAZYFLUSH;
switch (OperationType) switch (OperationType)
@ -490,16 +564,16 @@ HvInitialize(
break; break;
case HINIT_MEMORY: case HINIT_MEMORY:
Status = HvpInitializeMemoryHive(Hive, HiveData); Status = HvpInitializeMemoryHive(Hive, HiveData, FileName);
break; break;
case HINIT_FLAT: case HINIT_FLAT:
Status = HvpInitializeMemoryInplaceHive(Hive, HiveData); Status = HvpInitializeFlatHive(Hive, HiveData);
break; break;
case HINIT_FILE: case HINIT_FILE:
{ {
Status = HvLoadHive(Hive); Status = HvLoadHive(Hive, FileName);
if ((Status != STATUS_SUCCESS) && if ((Status != STATUS_SUCCESS) &&
(Status != STATUS_REGISTRY_RECOVERED)) (Status != STATUS_REGISTRY_RECOVERED))
{ {
@ -512,6 +586,12 @@ HvInitialize(
break; break;
} }
case HINIT_MEMORY_INPLACE:
// Status = HvpInitializeMemoryInplaceHive(Hive, HiveData);
// break;
case HINIT_MAPFILE:
default: default:
/* FIXME: A better return status value is needed */ /* FIXME: A better return status value is needed */
Status = STATUS_NOT_IMPLEMENTED; Status = STATUS_NOT_IMPLEMENTED;
@ -520,6 +600,9 @@ HvInitialize(
if (!NT_SUCCESS(Status)) return Status; if (!NT_SUCCESS(Status)) return Status;
/* HACK: ROS: Init root key cell and prepare the hive */
// r31253
// if (OperationType == HINIT_CREATE) CmCreateRootNode(Hive, L"");
if (OperationType != HINIT_CREATE) CmPrepareHive(Hive); if (OperationType != HINIT_CREATE) CmPrepareHive(Hive);
return Status; return Status;
@ -531,7 +614,6 @@ HvInitialize(
* Free all stroage and handles associated with hive descriptor. * Free all stroage and handles associated with hive descriptor.
* But do not free the hive descriptor itself. * But do not free the hive descriptor itself.
*/ */
VOID CMAPI VOID CMAPI
HvFree( HvFree(
PHHIVE RegistryHive) PHHIVE RegistryHive)
@ -549,7 +631,7 @@ HvFree(
/* Free the BaseBlock */ /* Free the BaseBlock */
if (RegistryHive->BaseBlock) if (RegistryHive->BaseBlock)
{ {
RegistryHive->Free(RegistryHive->BaseBlock, 0); RegistryHive->Free(RegistryHive->BaseBlock, RegistryHive->BaseBlockAlloc);
RegistryHive->BaseBlock = NULL; RegistryHive->BaseBlock = NULL;
} }
} }