mirror of
https://github.com/reactos/reactos.git
synced 2025-06-10 04:14:53 +00:00
[CMLIB]
- 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:
parent
36a7330eee
commit
734bc29142
1 changed files with 175 additions and 93 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue