mirror of
https://github.com/reactos/reactos.git
synced 2025-08-01 23:53:07 +00:00
[CMLIB]: Go from 3-space indentation to 4-space.
svn path=/trunk/; revision=70562
This commit is contained in:
parent
c55976dada
commit
c8688507db
10 changed files with 1047 additions and 1047 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* PROJECT: Registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2001 - 2005 Eric Kohl
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* PROJECT: Registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2001 - 2005 Eric Kohl
|
||||
|
@ -13,124 +13,124 @@ ULONG CmlibTraceLevel = 0;
|
|||
|
||||
BOOLEAN CMAPI
|
||||
CmCreateRootNode(
|
||||
PHHIVE Hive,
|
||||
PCWSTR Name)
|
||||
PHHIVE Hive,
|
||||
PCWSTR Name)
|
||||
{
|
||||
PCM_KEY_NODE KeyCell;
|
||||
HCELL_INDEX RootCellIndex;
|
||||
ULONG NameSize;
|
||||
PCM_KEY_NODE KeyCell;
|
||||
HCELL_INDEX RootCellIndex;
|
||||
ULONG NameSize;
|
||||
|
||||
/* Allocate the cell */
|
||||
NameSize = (ULONG)strlenW(Name) * sizeof(WCHAR);
|
||||
RootCellIndex = HvAllocateCell(Hive,
|
||||
FIELD_OFFSET(CM_KEY_NODE, Name) + NameSize,
|
||||
Stable,
|
||||
HCELL_NIL);
|
||||
if (RootCellIndex == HCELL_NIL) return FALSE;
|
||||
/* Allocate the cell */
|
||||
NameSize = (ULONG)strlenW(Name) * sizeof(WCHAR);
|
||||
RootCellIndex = HvAllocateCell(Hive,
|
||||
FIELD_OFFSET(CM_KEY_NODE, Name) + NameSize,
|
||||
Stable,
|
||||
HCELL_NIL);
|
||||
if (RootCellIndex == HCELL_NIL) return FALSE;
|
||||
|
||||
/* Seutp the base block */
|
||||
Hive->BaseBlock->RootCell = RootCellIndex;
|
||||
Hive->BaseBlock->CheckSum = HvpHiveHeaderChecksum(Hive->BaseBlock);
|
||||
/* Seutp the base block */
|
||||
Hive->BaseBlock->RootCell = RootCellIndex;
|
||||
Hive->BaseBlock->CheckSum = HvpHiveHeaderChecksum(Hive->BaseBlock);
|
||||
|
||||
/* Get the key cell */
|
||||
KeyCell = (PCM_KEY_NODE)HvGetCell(Hive, RootCellIndex);
|
||||
if (!KeyCell) return FALSE;
|
||||
/* Get the key cell */
|
||||
KeyCell = (PCM_KEY_NODE)HvGetCell(Hive, RootCellIndex);
|
||||
if (!KeyCell) return FALSE;
|
||||
|
||||
/* Setup the cell */
|
||||
KeyCell->Signature = (USHORT)CM_KEY_NODE_SIGNATURE;
|
||||
KeyCell->Flags = KEY_HIVE_ENTRY | KEY_NO_DELETE;
|
||||
KeyCell->LastWriteTime.QuadPart = 0;
|
||||
KeyCell->Parent = HCELL_NIL;
|
||||
KeyCell->SubKeyCounts[Stable] = 0;
|
||||
KeyCell->SubKeyCounts[Volatile] = 0;
|
||||
KeyCell->SubKeyLists[Stable] = HCELL_NIL;
|
||||
KeyCell->SubKeyLists[Volatile] = HCELL_NIL;
|
||||
KeyCell->ValueList.Count = 0;
|
||||
KeyCell->ValueList.List = HCELL_NIL;
|
||||
KeyCell->Security = HCELL_NIL;
|
||||
KeyCell->Class = HCELL_NIL;
|
||||
KeyCell->ClassLength = 0;
|
||||
KeyCell->MaxNameLen = 0;
|
||||
KeyCell->MaxClassLen = 0;
|
||||
KeyCell->MaxValueNameLen = 0;
|
||||
KeyCell->MaxValueDataLen = 0;
|
||||
/* Setup the cell */
|
||||
KeyCell->Signature = (USHORT)CM_KEY_NODE_SIGNATURE;
|
||||
KeyCell->Flags = KEY_HIVE_ENTRY | KEY_NO_DELETE;
|
||||
KeyCell->LastWriteTime.QuadPart = 0;
|
||||
KeyCell->Parent = HCELL_NIL;
|
||||
KeyCell->SubKeyCounts[Stable] = 0;
|
||||
KeyCell->SubKeyCounts[Volatile] = 0;
|
||||
KeyCell->SubKeyLists[Stable] = HCELL_NIL;
|
||||
KeyCell->SubKeyLists[Volatile] = HCELL_NIL;
|
||||
KeyCell->ValueList.Count = 0;
|
||||
KeyCell->ValueList.List = HCELL_NIL;
|
||||
KeyCell->Security = HCELL_NIL;
|
||||
KeyCell->Class = HCELL_NIL;
|
||||
KeyCell->ClassLength = 0;
|
||||
KeyCell->MaxNameLen = 0;
|
||||
KeyCell->MaxClassLen = 0;
|
||||
KeyCell->MaxValueNameLen = 0;
|
||||
KeyCell->MaxValueDataLen = 0;
|
||||
|
||||
/* Write the name */
|
||||
KeyCell->NameLength = (USHORT)NameSize;
|
||||
RtlCopyMemory(KeyCell->Name, Name, NameSize);
|
||||
/* Write the name */
|
||||
KeyCell->NameLength = (USHORT)NameSize;
|
||||
RtlCopyMemory(KeyCell->Name, Name, NameSize);
|
||||
|
||||
/* Return success */
|
||||
HvReleaseCell(Hive, RootCellIndex);
|
||||
return TRUE;
|
||||
/* Return success */
|
||||
HvReleaseCell(Hive, RootCellIndex);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static VOID CMAPI
|
||||
CmpPrepareKey(
|
||||
PHHIVE RegistryHive,
|
||||
PCM_KEY_NODE KeyCell);
|
||||
PHHIVE RegistryHive,
|
||||
PCM_KEY_NODE KeyCell);
|
||||
|
||||
static VOID CMAPI
|
||||
CmpPrepareIndexOfKeys(
|
||||
PHHIVE RegistryHive,
|
||||
PCM_KEY_INDEX IndexCell)
|
||||
PHHIVE RegistryHive,
|
||||
PCM_KEY_INDEX IndexCell)
|
||||
{
|
||||
ULONG i;
|
||||
ULONG i;
|
||||
|
||||
if (IndexCell->Signature == CM_KEY_INDEX_ROOT ||
|
||||
IndexCell->Signature == CM_KEY_INDEX_LEAF)
|
||||
{
|
||||
for (i = 0; i < IndexCell->Count; i++)
|
||||
{
|
||||
PCM_KEY_INDEX SubIndexCell = HvGetCell(RegistryHive, IndexCell->List[i]);
|
||||
if (SubIndexCell->Signature == CM_KEY_NODE_SIGNATURE)
|
||||
CmpPrepareKey(RegistryHive, (PCM_KEY_NODE)SubIndexCell);
|
||||
else
|
||||
CmpPrepareIndexOfKeys(RegistryHive, SubIndexCell);
|
||||
}
|
||||
}
|
||||
else if (IndexCell->Signature == CM_KEY_FAST_LEAF ||
|
||||
IndexCell->Signature == CM_KEY_HASH_LEAF)
|
||||
{
|
||||
PCM_KEY_FAST_INDEX HashCell = (PCM_KEY_FAST_INDEX)IndexCell;
|
||||
for (i = 0; i < HashCell->Count; i++)
|
||||
{
|
||||
PCM_KEY_NODE SubKeyCell = HvGetCell(RegistryHive, HashCell->List[i].Cell);
|
||||
CmpPrepareKey(RegistryHive, SubKeyCell);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("IndexCell->Signature %x\n", IndexCell->Signature);
|
||||
ASSERT(FALSE);
|
||||
if (IndexCell->Signature == CM_KEY_INDEX_ROOT ||
|
||||
IndexCell->Signature == CM_KEY_INDEX_LEAF)
|
||||
{
|
||||
for (i = 0; i < IndexCell->Count; i++)
|
||||
{
|
||||
PCM_KEY_INDEX SubIndexCell = HvGetCell(RegistryHive, IndexCell->List[i]);
|
||||
if (SubIndexCell->Signature == CM_KEY_NODE_SIGNATURE)
|
||||
CmpPrepareKey(RegistryHive, (PCM_KEY_NODE)SubIndexCell);
|
||||
else
|
||||
CmpPrepareIndexOfKeys(RegistryHive, SubIndexCell);
|
||||
}
|
||||
}
|
||||
else if (IndexCell->Signature == CM_KEY_FAST_LEAF ||
|
||||
IndexCell->Signature == CM_KEY_HASH_LEAF)
|
||||
{
|
||||
PCM_KEY_FAST_INDEX HashCell = (PCM_KEY_FAST_INDEX)IndexCell;
|
||||
for (i = 0; i < HashCell->Count; i++)
|
||||
{
|
||||
PCM_KEY_NODE SubKeyCell = HvGetCell(RegistryHive, HashCell->List[i].Cell);
|
||||
CmpPrepareKey(RegistryHive, SubKeyCell);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("IndexCell->Signature %x\n", IndexCell->Signature);
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static VOID CMAPI
|
||||
CmpPrepareKey(
|
||||
PHHIVE RegistryHive,
|
||||
PCM_KEY_NODE KeyCell)
|
||||
PHHIVE RegistryHive,
|
||||
PCM_KEY_NODE KeyCell)
|
||||
{
|
||||
PCM_KEY_INDEX IndexCell;
|
||||
PCM_KEY_INDEX IndexCell;
|
||||
|
||||
ASSERT(KeyCell->Signature == CM_KEY_NODE_SIGNATURE);
|
||||
ASSERT(KeyCell->Signature == CM_KEY_NODE_SIGNATURE);
|
||||
|
||||
KeyCell->SubKeyLists[Volatile] = HCELL_NIL;
|
||||
KeyCell->SubKeyCounts[Volatile] = 0;
|
||||
KeyCell->SubKeyLists[Volatile] = HCELL_NIL;
|
||||
KeyCell->SubKeyCounts[Volatile] = 0;
|
||||
|
||||
/* Enumerate and add subkeys */
|
||||
if (KeyCell->SubKeyCounts[Stable] > 0)
|
||||
{
|
||||
IndexCell = HvGetCell(RegistryHive, KeyCell->SubKeyLists[Stable]);
|
||||
CmpPrepareIndexOfKeys(RegistryHive, IndexCell);
|
||||
}
|
||||
/* Enumerate and add subkeys */
|
||||
if (KeyCell->SubKeyCounts[Stable] > 0)
|
||||
{
|
||||
IndexCell = HvGetCell(RegistryHive, KeyCell->SubKeyLists[Stable]);
|
||||
CmpPrepareIndexOfKeys(RegistryHive, IndexCell);
|
||||
}
|
||||
}
|
||||
|
||||
VOID CMAPI
|
||||
CmPrepareHive(
|
||||
PHHIVE RegistryHive)
|
||||
PHHIVE RegistryHive)
|
||||
{
|
||||
PCM_KEY_NODE RootCell;
|
||||
PCM_KEY_NODE RootCell;
|
||||
|
||||
RootCell = HvGetCell(RegistryHive, RegistryHive->BaseBlock->RootCell);
|
||||
CmpPrepareKey(RegistryHive, RootCell);
|
||||
RootCell = HvGetCell(RegistryHive, RegistryHive->BaseBlock->RootCell);
|
||||
CmpPrepareKey(RegistryHive, RootCell);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* PROJECT: Registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2001 - 2005 Eric Kohl
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* PROJECT: Registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2001 - 2005 Eric Kohl
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* PROJECT: Registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2005 Hartmut Birr
|
||||
|
@ -10,98 +10,98 @@
|
|||
|
||||
PHBIN CMAPI
|
||||
HvpAddBin(
|
||||
PHHIVE RegistryHive,
|
||||
ULONG Size,
|
||||
HSTORAGE_TYPE Storage)
|
||||
PHHIVE RegistryHive,
|
||||
ULONG Size,
|
||||
HSTORAGE_TYPE Storage)
|
||||
{
|
||||
PHMAP_ENTRY BlockList;
|
||||
PHBIN Bin;
|
||||
SIZE_T BinSize;
|
||||
ULONG i;
|
||||
ULONG BitmapSize;
|
||||
ULONG BlockCount;
|
||||
ULONG OldBlockListSize;
|
||||
PHCELL Block;
|
||||
PHMAP_ENTRY BlockList;
|
||||
PHBIN Bin;
|
||||
SIZE_T BinSize;
|
||||
ULONG i;
|
||||
ULONG BitmapSize;
|
||||
ULONG BlockCount;
|
||||
ULONG OldBlockListSize;
|
||||
PHCELL Block;
|
||||
|
||||
BinSize = ROUND_UP(Size + sizeof(HBIN), HBLOCK_SIZE);
|
||||
BlockCount = (ULONG)(BinSize / HBLOCK_SIZE);
|
||||
BinSize = ROUND_UP(Size + sizeof(HBIN), HBLOCK_SIZE);
|
||||
BlockCount = (ULONG)(BinSize / HBLOCK_SIZE);
|
||||
|
||||
Bin = RegistryHive->Allocate(BinSize, TRUE, TAG_CM);
|
||||
if (Bin == NULL)
|
||||
return NULL;
|
||||
RtlZeroMemory(Bin, BinSize);
|
||||
Bin = RegistryHive->Allocate(BinSize, TRUE, TAG_CM);
|
||||
if (Bin == NULL)
|
||||
return NULL;
|
||||
RtlZeroMemory(Bin, BinSize);
|
||||
|
||||
Bin->Signature = HV_BIN_SIGNATURE;
|
||||
Bin->FileOffset = RegistryHive->Storage[Storage].Length *
|
||||
HBLOCK_SIZE;
|
||||
Bin->Size = (ULONG)BinSize;
|
||||
Bin->Signature = HV_BIN_SIGNATURE;
|
||||
Bin->FileOffset = RegistryHive->Storage[Storage].Length *
|
||||
HBLOCK_SIZE;
|
||||
Bin->Size = (ULONG)BinSize;
|
||||
|
||||
/* Allocate new block list */
|
||||
OldBlockListSize = RegistryHive->Storage[Storage].Length;
|
||||
BlockList = RegistryHive->Allocate(sizeof(HMAP_ENTRY) *
|
||||
(OldBlockListSize + BlockCount),
|
||||
TRUE,
|
||||
TAG_CM);
|
||||
if (BlockList == NULL)
|
||||
{
|
||||
RegistryHive->Free(Bin, 0);
|
||||
return NULL;
|
||||
}
|
||||
/* Allocate new block list */
|
||||
OldBlockListSize = RegistryHive->Storage[Storage].Length;
|
||||
BlockList = RegistryHive->Allocate(sizeof(HMAP_ENTRY) *
|
||||
(OldBlockListSize + BlockCount),
|
||||
TRUE,
|
||||
TAG_CM);
|
||||
if (BlockList == NULL)
|
||||
{
|
||||
RegistryHive->Free(Bin, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (OldBlockListSize > 0)
|
||||
{
|
||||
RtlCopyMemory(BlockList, RegistryHive->Storage[Storage].BlockList,
|
||||
OldBlockListSize * sizeof(HMAP_ENTRY));
|
||||
RegistryHive->Free(RegistryHive->Storage[Storage].BlockList, 0);
|
||||
}
|
||||
if (OldBlockListSize > 0)
|
||||
{
|
||||
RtlCopyMemory(BlockList, RegistryHive->Storage[Storage].BlockList,
|
||||
OldBlockListSize * sizeof(HMAP_ENTRY));
|
||||
RegistryHive->Free(RegistryHive->Storage[Storage].BlockList, 0);
|
||||
}
|
||||
|
||||
RegistryHive->Storage[Storage].BlockList = BlockList;
|
||||
RegistryHive->Storage[Storage].Length += BlockCount;
|
||||
RegistryHive->Storage[Storage].BlockList = BlockList;
|
||||
RegistryHive->Storage[Storage].Length += BlockCount;
|
||||
|
||||
for (i = 0; i < BlockCount; i++)
|
||||
{
|
||||
RegistryHive->Storage[Storage].BlockList[OldBlockListSize + i].BlockAddress =
|
||||
((ULONG_PTR)Bin + (i * HBLOCK_SIZE));
|
||||
RegistryHive->Storage[Storage].BlockList[OldBlockListSize + i].BinAddress = (ULONG_PTR)Bin;
|
||||
}
|
||||
for (i = 0; i < BlockCount; i++)
|
||||
{
|
||||
RegistryHive->Storage[Storage].BlockList[OldBlockListSize + i].BlockAddress =
|
||||
((ULONG_PTR)Bin + (i * HBLOCK_SIZE));
|
||||
RegistryHive->Storage[Storage].BlockList[OldBlockListSize + i].BinAddress = (ULONG_PTR)Bin;
|
||||
}
|
||||
|
||||
/* Initialize a free block in this heap. */
|
||||
Block = (PHCELL)(Bin + 1);
|
||||
Block->Size = (LONG)(BinSize - sizeof(HBIN));
|
||||
/* Initialize a free block in this heap. */
|
||||
Block = (PHCELL)(Bin + 1);
|
||||
Block->Size = (LONG)(BinSize - sizeof(HBIN));
|
||||
|
||||
if (Storage == Stable)
|
||||
{
|
||||
/* Calculate bitmap size in bytes (always a multiple of 32 bits). */
|
||||
BitmapSize = ROUND_UP(RegistryHive->Storage[Stable].Length,
|
||||
sizeof(ULONG) * 8) / 8;
|
||||
if (Storage == Stable)
|
||||
{
|
||||
/* Calculate bitmap size in bytes (always a multiple of 32 bits). */
|
||||
BitmapSize = ROUND_UP(RegistryHive->Storage[Stable].Length,
|
||||
sizeof(ULONG) * 8) / 8;
|
||||
|
||||
/* Grow bitmap if necessary. */
|
||||
if (BitmapSize > RegistryHive->DirtyVector.SizeOfBitMap / 8)
|
||||
{
|
||||
PULONG BitmapBuffer;
|
||||
/* Grow bitmap if necessary. */
|
||||
if (BitmapSize > RegistryHive->DirtyVector.SizeOfBitMap / 8)
|
||||
{
|
||||
PULONG BitmapBuffer;
|
||||
|
||||
BitmapBuffer = RegistryHive->Allocate(BitmapSize, TRUE, TAG_CM);
|
||||
RtlZeroMemory(BitmapBuffer, BitmapSize);
|
||||
if (RegistryHive->DirtyVector.SizeOfBitMap > 0)
|
||||
{
|
||||
ASSERT(RegistryHive->DirtyVector.Buffer);
|
||||
RtlCopyMemory(BitmapBuffer,
|
||||
RegistryHive->DirtyVector.Buffer,
|
||||
RegistryHive->DirtyVector.SizeOfBitMap / 8);
|
||||
RegistryHive->Free(RegistryHive->DirtyVector.Buffer, 0);
|
||||
}
|
||||
RtlInitializeBitMap(&RegistryHive->DirtyVector, BitmapBuffer,
|
||||
BitmapSize * 8);
|
||||
}
|
||||
BitmapBuffer = RegistryHive->Allocate(BitmapSize, TRUE, TAG_CM);
|
||||
RtlZeroMemory(BitmapBuffer, BitmapSize);
|
||||
if (RegistryHive->DirtyVector.SizeOfBitMap > 0)
|
||||
{
|
||||
ASSERT(RegistryHive->DirtyVector.Buffer);
|
||||
RtlCopyMemory(BitmapBuffer,
|
||||
RegistryHive->DirtyVector.Buffer,
|
||||
RegistryHive->DirtyVector.SizeOfBitMap / 8);
|
||||
RegistryHive->Free(RegistryHive->DirtyVector.Buffer, 0);
|
||||
}
|
||||
RtlInitializeBitMap(&RegistryHive->DirtyVector, BitmapBuffer,
|
||||
BitmapSize * 8);
|
||||
}
|
||||
|
||||
/* Mark new bin dirty. */
|
||||
RtlSetBits(&RegistryHive->DirtyVector,
|
||||
Bin->FileOffset / HBLOCK_SIZE,
|
||||
BlockCount);
|
||||
/* Mark new bin dirty. */
|
||||
RtlSetBits(&RegistryHive->DirtyVector,
|
||||
Bin->FileOffset / HBLOCK_SIZE,
|
||||
BlockCount);
|
||||
|
||||
/* Update size in the base block */
|
||||
RegistryHive->BaseBlock->Length += BinSize;
|
||||
}
|
||||
/* Update size in the base block */
|
||||
RegistryHive->BaseBlock->Length += BinSize;
|
||||
}
|
||||
|
||||
return Bin;
|
||||
return Bin;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* PROJECT: Registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2001 - 2005 Eric Kohl
|
||||
|
@ -11,514 +11,515 @@
|
|||
|
||||
static __inline PHCELL CMAPI
|
||||
HvpGetCellHeader(
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellIndex)
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellIndex)
|
||||
{
|
||||
PVOID Block;
|
||||
PVOID Block;
|
||||
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, CellIndex %08lx\n",
|
||||
__FUNCTION__, RegistryHive, CellIndex);
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, CellIndex %08lx\n",
|
||||
__FUNCTION__, RegistryHive, CellIndex);
|
||||
|
||||
ASSERT(CellIndex != HCELL_NIL);
|
||||
if (!RegistryHive->Flat)
|
||||
{
|
||||
ULONG CellType;
|
||||
ULONG CellBlock;
|
||||
ULONG CellOffset;
|
||||
ASSERT(CellIndex != HCELL_NIL);
|
||||
if (!RegistryHive->Flat)
|
||||
{
|
||||
ULONG CellType;
|
||||
ULONG CellBlock;
|
||||
ULONG CellOffset;
|
||||
|
||||
CellType = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
|
||||
CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
|
||||
CellOffset = (CellIndex & HCELL_OFFSET_MASK) >> HCELL_OFFSET_SHIFT;
|
||||
ASSERT(CellBlock < RegistryHive->Storage[CellType].Length);
|
||||
Block = (PVOID)RegistryHive->Storage[CellType].BlockList[CellBlock].BlockAddress;
|
||||
ASSERT(Block != NULL);
|
||||
return (PVOID)((ULONG_PTR)Block + CellOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT((CellIndex & HCELL_TYPE_MASK) == Stable);
|
||||
return (PVOID)((ULONG_PTR)RegistryHive->BaseBlock + HBLOCK_SIZE +
|
||||
CellIndex);
|
||||
}
|
||||
CellType = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
|
||||
CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
|
||||
CellOffset = (CellIndex & HCELL_OFFSET_MASK) >> HCELL_OFFSET_SHIFT;
|
||||
ASSERT(CellBlock < RegistryHive->Storage[CellType].Length);
|
||||
Block = (PVOID)RegistryHive->Storage[CellType].BlockList[CellBlock].BlockAddress;
|
||||
ASSERT(Block != NULL);
|
||||
return (PVOID)((ULONG_PTR)Block + CellOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT((CellIndex & HCELL_TYPE_MASK) == Stable);
|
||||
return (PVOID)((ULONG_PTR)RegistryHive->BaseBlock + HBLOCK_SIZE +
|
||||
CellIndex);
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN CMAPI
|
||||
HvIsCellAllocated(IN PHHIVE RegistryHive,
|
||||
IN HCELL_INDEX CellIndex)
|
||||
{
|
||||
ULONG Type, Block;
|
||||
ULONG Type, Block;
|
||||
|
||||
/* If it's a flat hive, the cell is always allocated */
|
||||
if (RegistryHive->Flat)
|
||||
return TRUE;
|
||||
/* If it's a flat hive, the cell is always allocated */
|
||||
if (RegistryHive->Flat)
|
||||
return TRUE;
|
||||
|
||||
/* Otherwise, get the type and make sure it's valid */
|
||||
Type = HvGetCellType(CellIndex);
|
||||
Block = HvGetCellBlock(CellIndex);
|
||||
if (Block >= RegistryHive->Storage[Type].Length)
|
||||
return FALSE;
|
||||
/* Otherwise, get the type and make sure it's valid */
|
||||
Type = HvGetCellType(CellIndex);
|
||||
Block = HvGetCellBlock(CellIndex);
|
||||
if (Block >= RegistryHive->Storage[Type].Length)
|
||||
return FALSE;
|
||||
|
||||
/* Try to get the cell block */
|
||||
if (RegistryHive->Storage[Type].BlockList[Block].BlockAddress)
|
||||
return TRUE;
|
||||
/* Try to get the cell block */
|
||||
if (RegistryHive->Storage[Type].BlockList[Block].BlockAddress)
|
||||
return TRUE;
|
||||
|
||||
/* No valid block, fail */
|
||||
return FALSE;
|
||||
/* No valid block, fail */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
PVOID CMAPI
|
||||
HvGetCell(
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellIndex)
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellIndex)
|
||||
{
|
||||
ASSERT(CellIndex != HCELL_NIL);
|
||||
return (PVOID)(HvpGetCellHeader(RegistryHive, CellIndex) + 1);
|
||||
ASSERT(CellIndex != HCELL_NIL);
|
||||
return (PVOID)(HvpGetCellHeader(RegistryHive, CellIndex) + 1);
|
||||
}
|
||||
|
||||
static __inline LONG CMAPI
|
||||
HvpGetCellFullSize(
|
||||
PHHIVE RegistryHive,
|
||||
PVOID Cell)
|
||||
PHHIVE RegistryHive,
|
||||
PVOID Cell)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(RegistryHive);
|
||||
return ((PHCELL)Cell - 1)->Size;
|
||||
UNREFERENCED_PARAMETER(RegistryHive);
|
||||
return ((PHCELL)Cell - 1)->Size;
|
||||
}
|
||||
|
||||
LONG CMAPI
|
||||
HvGetCellSize(IN PHHIVE Hive,
|
||||
IN PVOID Address)
|
||||
{
|
||||
PHCELL CellHeader;
|
||||
LONG Size;
|
||||
PHCELL CellHeader;
|
||||
LONG Size;
|
||||
|
||||
UNREFERENCED_PARAMETER(Hive);
|
||||
UNREFERENCED_PARAMETER(Hive);
|
||||
|
||||
CellHeader = (PHCELL)Address - 1;
|
||||
Size = CellHeader->Size * -1;
|
||||
Size -= sizeof(HCELL);
|
||||
return Size;
|
||||
CellHeader = (PHCELL)Address - 1;
|
||||
Size = CellHeader->Size * -1;
|
||||
Size -= sizeof(HCELL);
|
||||
return Size;
|
||||
}
|
||||
|
||||
BOOLEAN CMAPI
|
||||
HvMarkCellDirty(
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellIndex,
|
||||
BOOLEAN HoldingLock)
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellIndex,
|
||||
BOOLEAN HoldingLock)
|
||||
{
|
||||
ULONG CellBlock;
|
||||
ULONG CellLastBlock;
|
||||
ULONG CellBlock;
|
||||
ULONG CellLastBlock;
|
||||
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, CellIndex %08lx, HoldingLock %u\n",
|
||||
__FUNCTION__, RegistryHive, CellIndex, HoldingLock);
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, CellIndex %08lx, HoldingLock %u\n",
|
||||
__FUNCTION__, RegistryHive, CellIndex, HoldingLock);
|
||||
|
||||
if ((CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT != Stable)
|
||||
return TRUE;
|
||||
if ((CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT != Stable)
|
||||
return TRUE;
|
||||
|
||||
CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
|
||||
CellLastBlock = ((CellIndex + HBLOCK_SIZE - 1) & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
|
||||
CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
|
||||
CellLastBlock = ((CellIndex + HBLOCK_SIZE - 1) & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
|
||||
|
||||
RtlSetBits(&RegistryHive->DirtyVector,
|
||||
CellBlock, CellLastBlock - CellBlock);
|
||||
RegistryHive->DirtyCount++;
|
||||
return TRUE;
|
||||
RtlSetBits(&RegistryHive->DirtyVector,
|
||||
CellBlock, CellLastBlock - CellBlock);
|
||||
RegistryHive->DirtyCount++;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN CMAPI
|
||||
HvIsCellDirty(IN PHHIVE Hive,
|
||||
IN HCELL_INDEX Cell)
|
||||
{
|
||||
BOOLEAN IsDirty = FALSE;
|
||||
BOOLEAN IsDirty = FALSE;
|
||||
|
||||
/* Sanity checks */
|
||||
ASSERT(Hive->ReadOnly == FALSE);
|
||||
/* Sanity checks */
|
||||
ASSERT(Hive->ReadOnly == FALSE);
|
||||
|
||||
/* Volatile cells are always "dirty" */
|
||||
if (HvGetCellType(Cell) == Volatile)
|
||||
return TRUE;
|
||||
/* Volatile cells are always "dirty" */
|
||||
if (HvGetCellType(Cell) == Volatile)
|
||||
return TRUE;
|
||||
|
||||
/* Check if the dirty bit is set */
|
||||
if (RtlCheckBit(&Hive->DirtyVector, Cell / HBLOCK_SIZE))
|
||||
IsDirty = TRUE;
|
||||
/* Check if the dirty bit is set */
|
||||
if (RtlCheckBit(&Hive->DirtyVector, Cell / HBLOCK_SIZE))
|
||||
IsDirty = TRUE;
|
||||
|
||||
/* Return result as boolean*/
|
||||
return IsDirty;
|
||||
/* Return result as boolean*/
|
||||
return IsDirty;
|
||||
}
|
||||
|
||||
static __inline ULONG CMAPI
|
||||
HvpComputeFreeListIndex(
|
||||
ULONG Size)
|
||||
ULONG Size)
|
||||
{
|
||||
ULONG Index;
|
||||
static CCHAR FindFirstSet[128] = {
|
||||
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6};
|
||||
ULONG Index;
|
||||
static CCHAR FindFirstSet[128] = {
|
||||
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6};
|
||||
|
||||
ASSERT(Size >= (1 << 3));
|
||||
Index = (Size >> 3) - 1;
|
||||
if (Index >= 16)
|
||||
{
|
||||
if (Index > 127)
|
||||
Index = 23;
|
||||
else
|
||||
Index = FindFirstSet[Index] + 16;
|
||||
}
|
||||
ASSERT(Size >= (1 << 3));
|
||||
Index = (Size >> 3) - 1;
|
||||
if (Index >= 16)
|
||||
{
|
||||
if (Index > 127)
|
||||
Index = 23;
|
||||
else
|
||||
Index = FindFirstSet[Index] + 16;
|
||||
}
|
||||
|
||||
return Index;
|
||||
return Index;
|
||||
}
|
||||
|
||||
static NTSTATUS CMAPI
|
||||
HvpAddFree(
|
||||
PHHIVE RegistryHive,
|
||||
PHCELL FreeBlock,
|
||||
HCELL_INDEX FreeIndex)
|
||||
PHHIVE RegistryHive,
|
||||
PHCELL FreeBlock,
|
||||
HCELL_INDEX FreeIndex)
|
||||
{
|
||||
PHCELL_INDEX FreeBlockData;
|
||||
HSTORAGE_TYPE Storage;
|
||||
ULONG Index;
|
||||
PHCELL_INDEX FreeBlockData;
|
||||
HSTORAGE_TYPE Storage;
|
||||
ULONG Index;
|
||||
|
||||
ASSERT(RegistryHive != NULL);
|
||||
ASSERT(FreeBlock != NULL);
|
||||
ASSERT(RegistryHive != NULL);
|
||||
ASSERT(FreeBlock != NULL);
|
||||
|
||||
Storage = (FreeIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
|
||||
Index = HvpComputeFreeListIndex((ULONG)FreeBlock->Size);
|
||||
Storage = (FreeIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
|
||||
Index = HvpComputeFreeListIndex((ULONG)FreeBlock->Size);
|
||||
|
||||
FreeBlockData = (PHCELL_INDEX)(FreeBlock + 1);
|
||||
*FreeBlockData = RegistryHive->Storage[Storage].FreeDisplay[Index];
|
||||
RegistryHive->Storage[Storage].FreeDisplay[Index] = FreeIndex;
|
||||
FreeBlockData = (PHCELL_INDEX)(FreeBlock + 1);
|
||||
*FreeBlockData = RegistryHive->Storage[Storage].FreeDisplay[Index];
|
||||
RegistryHive->Storage[Storage].FreeDisplay[Index] = FreeIndex;
|
||||
|
||||
/* FIXME: Eventually get rid of free bins. */
|
||||
/* FIXME: Eventually get rid of free bins. */
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static VOID CMAPI
|
||||
HvpRemoveFree(
|
||||
PHHIVE RegistryHive,
|
||||
PHCELL CellBlock,
|
||||
HCELL_INDEX CellIndex)
|
||||
PHHIVE RegistryHive,
|
||||
PHCELL CellBlock,
|
||||
HCELL_INDEX CellIndex)
|
||||
{
|
||||
PHCELL_INDEX FreeCellData;
|
||||
PHCELL_INDEX pFreeCellOffset;
|
||||
HSTORAGE_TYPE Storage;
|
||||
ULONG Index, FreeListIndex;
|
||||
PHCELL_INDEX FreeCellData;
|
||||
PHCELL_INDEX pFreeCellOffset;
|
||||
HSTORAGE_TYPE Storage;
|
||||
ULONG Index, FreeListIndex;
|
||||
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
|
||||
Storage = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
|
||||
Index = HvpComputeFreeListIndex((ULONG)CellBlock->Size);
|
||||
Storage = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
|
||||
Index = HvpComputeFreeListIndex((ULONG)CellBlock->Size);
|
||||
|
||||
pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[Index];
|
||||
while (*pFreeCellOffset != HCELL_NIL)
|
||||
{
|
||||
FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset);
|
||||
if (*pFreeCellOffset == CellIndex)
|
||||
{
|
||||
*pFreeCellOffset = *FreeCellData;
|
||||
return;
|
||||
}
|
||||
pFreeCellOffset = FreeCellData;
|
||||
}
|
||||
pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[Index];
|
||||
while (*pFreeCellOffset != HCELL_NIL)
|
||||
{
|
||||
FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset);
|
||||
if (*pFreeCellOffset == CellIndex)
|
||||
{
|
||||
*pFreeCellOffset = *FreeCellData;
|
||||
return;
|
||||
}
|
||||
pFreeCellOffset = FreeCellData;
|
||||
}
|
||||
|
||||
/* Something bad happened, print a useful trace info and bugcheck */
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "-- beginning of HvpRemoveFree trace --\n");
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "block we are about to free: %08x\n", CellIndex);
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "chosen free list index: %u\n", Index);
|
||||
for (FreeListIndex = 0; FreeListIndex < 24; FreeListIndex++)
|
||||
{
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "free list [%u]: ", FreeListIndex);
|
||||
pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[FreeListIndex];
|
||||
while (*pFreeCellOffset != HCELL_NIL)
|
||||
{
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "%08x ", *pFreeCellOffset);
|
||||
FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset);
|
||||
pFreeCellOffset = FreeCellData;
|
||||
}
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "\n");
|
||||
}
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "-- end of HvpRemoveFree trace --\n");
|
||||
/* Something bad happened, print a useful trace info and bugcheck */
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "-- beginning of HvpRemoveFree trace --\n");
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "block we are about to free: %08x\n", CellIndex);
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "chosen free list index: %u\n", Index);
|
||||
for (FreeListIndex = 0; FreeListIndex < 24; FreeListIndex++)
|
||||
{
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "free list [%u]: ", FreeListIndex);
|
||||
pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[FreeListIndex];
|
||||
while (*pFreeCellOffset != HCELL_NIL)
|
||||
{
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "%08x ", *pFreeCellOffset);
|
||||
FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset);
|
||||
pFreeCellOffset = FreeCellData;
|
||||
}
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "\n");
|
||||
}
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "-- end of HvpRemoveFree trace --\n");
|
||||
|
||||
ASSERT(FALSE);
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
static HCELL_INDEX CMAPI
|
||||
HvpFindFree(
|
||||
PHHIVE RegistryHive,
|
||||
ULONG Size,
|
||||
HSTORAGE_TYPE Storage)
|
||||
PHHIVE RegistryHive,
|
||||
ULONG Size,
|
||||
HSTORAGE_TYPE Storage)
|
||||
{
|
||||
PHCELL_INDEX FreeCellData;
|
||||
HCELL_INDEX FreeCellOffset;
|
||||
PHCELL_INDEX pFreeCellOffset;
|
||||
ULONG Index;
|
||||
PHCELL_INDEX FreeCellData;
|
||||
HCELL_INDEX FreeCellOffset;
|
||||
PHCELL_INDEX pFreeCellOffset;
|
||||
ULONG Index;
|
||||
|
||||
for (Index = HvpComputeFreeListIndex(Size); Index < 24; Index++)
|
||||
{
|
||||
pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[Index];
|
||||
while (*pFreeCellOffset != HCELL_NIL)
|
||||
{
|
||||
FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset);
|
||||
if ((ULONG)HvpGetCellFullSize(RegistryHive, FreeCellData) >= Size)
|
||||
{
|
||||
FreeCellOffset = *pFreeCellOffset;
|
||||
*pFreeCellOffset = *FreeCellData;
|
||||
return FreeCellOffset;
|
||||
}
|
||||
pFreeCellOffset = FreeCellData;
|
||||
}
|
||||
}
|
||||
for (Index = HvpComputeFreeListIndex(Size); Index < 24; Index++)
|
||||
{
|
||||
pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[Index];
|
||||
while (*pFreeCellOffset != HCELL_NIL)
|
||||
{
|
||||
FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset);
|
||||
if ((ULONG)HvpGetCellFullSize(RegistryHive, FreeCellData) >= Size)
|
||||
{
|
||||
FreeCellOffset = *pFreeCellOffset;
|
||||
*pFreeCellOffset = *FreeCellData;
|
||||
return FreeCellOffset;
|
||||
}
|
||||
pFreeCellOffset = FreeCellData;
|
||||
}
|
||||
}
|
||||
|
||||
return HCELL_NIL;
|
||||
return HCELL_NIL;
|
||||
}
|
||||
|
||||
NTSTATUS CMAPI
|
||||
HvpCreateHiveFreeCellList(
|
||||
PHHIVE Hive)
|
||||
PHHIVE Hive)
|
||||
{
|
||||
HCELL_INDEX BlockOffset;
|
||||
PHCELL FreeBlock;
|
||||
ULONG BlockIndex;
|
||||
ULONG FreeOffset;
|
||||
PHBIN Bin;
|
||||
NTSTATUS Status;
|
||||
ULONG Index;
|
||||
HCELL_INDEX BlockOffset;
|
||||
PHCELL FreeBlock;
|
||||
ULONG BlockIndex;
|
||||
ULONG FreeOffset;
|
||||
PHBIN Bin;
|
||||
NTSTATUS Status;
|
||||
ULONG Index;
|
||||
|
||||
/* Initialize the free cell list */
|
||||
for (Index = 0; Index < 24; Index++)
|
||||
{
|
||||
Hive->Storage[Stable].FreeDisplay[Index] = HCELL_NIL;
|
||||
Hive->Storage[Volatile].FreeDisplay[Index] = HCELL_NIL;
|
||||
}
|
||||
/* Initialize the free cell list */
|
||||
for (Index = 0; Index < 24; Index++)
|
||||
{
|
||||
Hive->Storage[Stable].FreeDisplay[Index] = HCELL_NIL;
|
||||
Hive->Storage[Volatile].FreeDisplay[Index] = HCELL_NIL;
|
||||
}
|
||||
|
||||
BlockOffset = 0;
|
||||
BlockIndex = 0;
|
||||
while (BlockIndex < Hive->Storage[Stable].Length)
|
||||
{
|
||||
Bin = (PHBIN)Hive->Storage[Stable].BlockList[BlockIndex].BinAddress;
|
||||
BlockOffset = 0;
|
||||
BlockIndex = 0;
|
||||
while (BlockIndex < Hive->Storage[Stable].Length)
|
||||
{
|
||||
Bin = (PHBIN)Hive->Storage[Stable].BlockList[BlockIndex].BinAddress;
|
||||
|
||||
/* Search free blocks and add to list */
|
||||
FreeOffset = sizeof(HBIN);
|
||||
while (FreeOffset < Bin->Size)
|
||||
{
|
||||
FreeBlock = (PHCELL)((ULONG_PTR)Bin + FreeOffset);
|
||||
if (FreeBlock->Size > 0)
|
||||
{
|
||||
Status = HvpAddFree(Hive, FreeBlock, Bin->FileOffset + FreeOffset);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
/* Search free blocks and add to list */
|
||||
FreeOffset = sizeof(HBIN);
|
||||
while (FreeOffset < Bin->Size)
|
||||
{
|
||||
FreeBlock = (PHCELL)((ULONG_PTR)Bin + FreeOffset);
|
||||
if (FreeBlock->Size > 0)
|
||||
{
|
||||
Status = HvpAddFree(Hive, FreeBlock, Bin->FileOffset + FreeOffset);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
FreeOffset += FreeBlock->Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
FreeOffset -= FreeBlock->Size;
|
||||
}
|
||||
}
|
||||
FreeOffset += FreeBlock->Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
FreeOffset -= FreeBlock->Size;
|
||||
}
|
||||
}
|
||||
|
||||
BlockIndex += Bin->Size / HBLOCK_SIZE;
|
||||
BlockOffset += Bin->Size;
|
||||
}
|
||||
BlockIndex += Bin->Size / HBLOCK_SIZE;
|
||||
BlockOffset += Bin->Size;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
HCELL_INDEX CMAPI
|
||||
HvAllocateCell(
|
||||
PHHIVE RegistryHive,
|
||||
ULONG Size,
|
||||
HSTORAGE_TYPE Storage,
|
||||
HCELL_INDEX Vicinity)
|
||||
PHHIVE RegistryHive,
|
||||
ULONG Size,
|
||||
HSTORAGE_TYPE Storage,
|
||||
HCELL_INDEX Vicinity)
|
||||
{
|
||||
PHCELL FreeCell;
|
||||
HCELL_INDEX FreeCellOffset;
|
||||
PHCELL NewCell;
|
||||
PHBIN Bin;
|
||||
PHCELL FreeCell;
|
||||
HCELL_INDEX FreeCellOffset;
|
||||
PHCELL NewCell;
|
||||
PHBIN Bin;
|
||||
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, Size %x, %s, Vicinity %08lx\n",
|
||||
__FUNCTION__, RegistryHive, Size, (Storage == 0) ? "Stable" : "Volatile", Vicinity);
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, Size %x, %s, Vicinity %08lx\n",
|
||||
__FUNCTION__, RegistryHive, Size, (Storage == 0) ? "Stable" : "Volatile", Vicinity);
|
||||
|
||||
/* Round to 16 bytes multiple. */
|
||||
Size = ROUND_UP(Size + sizeof(HCELL), 16);
|
||||
/* Round to 16 bytes multiple. */
|
||||
Size = ROUND_UP(Size + sizeof(HCELL), 16);
|
||||
|
||||
/* First search in free blocks. */
|
||||
FreeCellOffset = HvpFindFree(RegistryHive, Size, Storage);
|
||||
/* First search in free blocks. */
|
||||
FreeCellOffset = HvpFindFree(RegistryHive, Size, Storage);
|
||||
|
||||
/* If no free cell was found we need to extend the hive file. */
|
||||
if (FreeCellOffset == HCELL_NIL)
|
||||
{
|
||||
Bin = HvpAddBin(RegistryHive, Size, Storage);
|
||||
if (Bin == NULL)
|
||||
return HCELL_NIL;
|
||||
FreeCellOffset = Bin->FileOffset + sizeof(HBIN);
|
||||
FreeCellOffset |= Storage << HCELL_TYPE_SHIFT;
|
||||
}
|
||||
/* If no free cell was found we need to extend the hive file. */
|
||||
if (FreeCellOffset == HCELL_NIL)
|
||||
{
|
||||
Bin = HvpAddBin(RegistryHive, Size, Storage);
|
||||
if (Bin == NULL)
|
||||
return HCELL_NIL;
|
||||
FreeCellOffset = Bin->FileOffset + sizeof(HBIN);
|
||||
FreeCellOffset |= Storage << HCELL_TYPE_SHIFT;
|
||||
}
|
||||
|
||||
FreeCell = HvpGetCellHeader(RegistryHive, FreeCellOffset);
|
||||
FreeCell = HvpGetCellHeader(RegistryHive, FreeCellOffset);
|
||||
|
||||
/* Split the block in two parts */
|
||||
/* Split the block in two parts */
|
||||
|
||||
/* The free block that is created has to be at least
|
||||
sizeof(HCELL) + sizeof(HCELL_INDEX) big, so that free
|
||||
cell list code can work. Moreover we round cell sizes
|
||||
to 16 bytes, so creating a smaller block would result in
|
||||
a cell that would never be allocated. */
|
||||
if ((ULONG)FreeCell->Size > Size + 16)
|
||||
{
|
||||
NewCell = (PHCELL)((ULONG_PTR)FreeCell + Size);
|
||||
NewCell->Size = FreeCell->Size - Size;
|
||||
FreeCell->Size = Size;
|
||||
HvpAddFree(RegistryHive, NewCell, FreeCellOffset + Size);
|
||||
if (Storage == Stable)
|
||||
HvMarkCellDirty(RegistryHive, FreeCellOffset + Size, FALSE);
|
||||
}
|
||||
/* The free block that is created has to be at least
|
||||
sizeof(HCELL) + sizeof(HCELL_INDEX) big, so that free
|
||||
cell list code can work. Moreover we round cell sizes
|
||||
to 16 bytes, so creating a smaller block would result in
|
||||
a cell that would never be allocated. */
|
||||
if ((ULONG)FreeCell->Size > Size + 16)
|
||||
{
|
||||
NewCell = (PHCELL)((ULONG_PTR)FreeCell + Size);
|
||||
NewCell->Size = FreeCell->Size - Size;
|
||||
FreeCell->Size = Size;
|
||||
HvpAddFree(RegistryHive, NewCell, FreeCellOffset + Size);
|
||||
if (Storage == Stable)
|
||||
HvMarkCellDirty(RegistryHive, FreeCellOffset + Size, FALSE);
|
||||
}
|
||||
|
||||
if (Storage == Stable)
|
||||
HvMarkCellDirty(RegistryHive, FreeCellOffset, FALSE);
|
||||
FreeCell->Size = -FreeCell->Size;
|
||||
RtlZeroMemory(FreeCell + 1, Size - sizeof(HCELL));
|
||||
if (Storage == Stable)
|
||||
HvMarkCellDirty(RegistryHive, FreeCellOffset, FALSE);
|
||||
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "%s - CellIndex %08lx\n",
|
||||
__FUNCTION__, FreeCellOffset);
|
||||
FreeCell->Size = -FreeCell->Size;
|
||||
RtlZeroMemory(FreeCell + 1, Size - sizeof(HCELL));
|
||||
|
||||
return FreeCellOffset;
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "%s - CellIndex %08lx\n",
|
||||
__FUNCTION__, FreeCellOffset);
|
||||
|
||||
return FreeCellOffset;
|
||||
}
|
||||
|
||||
HCELL_INDEX CMAPI
|
||||
HvReallocateCell(
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellIndex,
|
||||
ULONG Size)
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellIndex,
|
||||
ULONG Size)
|
||||
{
|
||||
PVOID OldCell;
|
||||
PVOID NewCell;
|
||||
LONG OldCellSize;
|
||||
HCELL_INDEX NewCellIndex;
|
||||
HSTORAGE_TYPE Storage;
|
||||
PVOID OldCell;
|
||||
PVOID NewCell;
|
||||
LONG OldCellSize;
|
||||
HCELL_INDEX NewCellIndex;
|
||||
HSTORAGE_TYPE Storage;
|
||||
|
||||
ASSERT(CellIndex != HCELL_NIL);
|
||||
ASSERT(CellIndex != HCELL_NIL);
|
||||
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, CellIndex %08lx, Size %x\n",
|
||||
__FUNCTION__, RegistryHive, CellIndex, Size);
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, CellIndex %08lx, Size %x\n",
|
||||
__FUNCTION__, RegistryHive, CellIndex, Size);
|
||||
|
||||
Storage = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
|
||||
Storage = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
|
||||
|
||||
OldCell = HvGetCell(RegistryHive, CellIndex);
|
||||
OldCellSize = HvGetCellSize(RegistryHive, OldCell);
|
||||
ASSERT(OldCellSize > 0);
|
||||
OldCell = HvGetCell(RegistryHive, CellIndex);
|
||||
OldCellSize = HvGetCellSize(RegistryHive, OldCell);
|
||||
ASSERT(OldCellSize > 0);
|
||||
|
||||
/*
|
||||
* If new data size is larger than the current, destroy current
|
||||
* data block and allocate a new one.
|
||||
*
|
||||
* FIXME: Merge with adjacent free cell if possible.
|
||||
* FIXME: Implement shrinking.
|
||||
*/
|
||||
if (Size > (ULONG)OldCellSize)
|
||||
{
|
||||
NewCellIndex = HvAllocateCell(RegistryHive, Size, Storage, HCELL_NIL);
|
||||
if (NewCellIndex == HCELL_NIL)
|
||||
return HCELL_NIL;
|
||||
/*
|
||||
* If new data size is larger than the current, destroy current
|
||||
* data block and allocate a new one.
|
||||
*
|
||||
* FIXME: Merge with adjacent free cell if possible.
|
||||
* FIXME: Implement shrinking.
|
||||
*/
|
||||
if (Size > (ULONG)OldCellSize)
|
||||
{
|
||||
NewCellIndex = HvAllocateCell(RegistryHive, Size, Storage, HCELL_NIL);
|
||||
if (NewCellIndex == HCELL_NIL)
|
||||
return HCELL_NIL;
|
||||
|
||||
NewCell = HvGetCell(RegistryHive, NewCellIndex);
|
||||
RtlCopyMemory(NewCell, OldCell, (SIZE_T)OldCellSize);
|
||||
NewCell = HvGetCell(RegistryHive, NewCellIndex);
|
||||
RtlCopyMemory(NewCell, OldCell, (SIZE_T)OldCellSize);
|
||||
|
||||
HvFreeCell(RegistryHive, CellIndex);
|
||||
HvFreeCell(RegistryHive, CellIndex);
|
||||
|
||||
return NewCellIndex;
|
||||
}
|
||||
return NewCellIndex;
|
||||
}
|
||||
|
||||
return CellIndex;
|
||||
return CellIndex;
|
||||
}
|
||||
|
||||
VOID CMAPI
|
||||
HvFreeCell(
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellIndex)
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellIndex)
|
||||
{
|
||||
PHCELL Free;
|
||||
PHCELL Neighbor;
|
||||
PHBIN Bin;
|
||||
ULONG CellType;
|
||||
ULONG CellBlock;
|
||||
PHCELL Free;
|
||||
PHCELL Neighbor;
|
||||
PHBIN Bin;
|
||||
ULONG CellType;
|
||||
ULONG CellBlock;
|
||||
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, CellIndex %08lx\n",
|
||||
__FUNCTION__, RegistryHive, CellIndex);
|
||||
CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, CellIndex %08lx\n",
|
||||
__FUNCTION__, RegistryHive, CellIndex);
|
||||
|
||||
Free = HvpGetCellHeader(RegistryHive, CellIndex);
|
||||
Free = HvpGetCellHeader(RegistryHive, CellIndex);
|
||||
|
||||
ASSERT(Free->Size < 0);
|
||||
ASSERT(Free->Size < 0);
|
||||
|
||||
Free->Size = -Free->Size;
|
||||
Free->Size = -Free->Size;
|
||||
|
||||
CellType = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
|
||||
CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
|
||||
CellType = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
|
||||
CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
|
||||
|
||||
/* FIXME: Merge free blocks */
|
||||
Bin = (PHBIN)RegistryHive->Storage[CellType].BlockList[CellBlock].BinAddress;
|
||||
/* FIXME: Merge free blocks */
|
||||
Bin = (PHBIN)RegistryHive->Storage[CellType].BlockList[CellBlock].BinAddress;
|
||||
|
||||
if ((CellIndex & ~HCELL_TYPE_MASK) + Free->Size <
|
||||
Bin->FileOffset + Bin->Size)
|
||||
{
|
||||
Neighbor = (PHCELL)((ULONG_PTR)Free + Free->Size);
|
||||
if (Neighbor->Size > 0)
|
||||
{
|
||||
HvpRemoveFree(RegistryHive, Neighbor,
|
||||
((HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin +
|
||||
Bin->FileOffset)) | (CellIndex & HCELL_TYPE_MASK));
|
||||
Free->Size += Neighbor->Size;
|
||||
}
|
||||
}
|
||||
if ((CellIndex & ~HCELL_TYPE_MASK) + Free->Size <
|
||||
Bin->FileOffset + Bin->Size)
|
||||
{
|
||||
Neighbor = (PHCELL)((ULONG_PTR)Free + Free->Size);
|
||||
if (Neighbor->Size > 0)
|
||||
{
|
||||
HvpRemoveFree(RegistryHive, Neighbor,
|
||||
((HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin +
|
||||
Bin->FileOffset)) | (CellIndex & HCELL_TYPE_MASK));
|
||||
Free->Size += Neighbor->Size;
|
||||
}
|
||||
}
|
||||
|
||||
Neighbor = (PHCELL)(Bin + 1);
|
||||
while (Neighbor < Free)
|
||||
{
|
||||
if (Neighbor->Size > 0)
|
||||
{
|
||||
if ((ULONG_PTR)Neighbor + Neighbor->Size == (ULONG_PTR)Free)
|
||||
{
|
||||
HCELL_INDEX NeighborCellIndex =
|
||||
(HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin +
|
||||
Bin->FileOffset) | (CellIndex & HCELL_TYPE_MASK);
|
||||
|
||||
if (HvpComputeFreeListIndex(Neighbor->Size) !=
|
||||
HvpComputeFreeListIndex(Neighbor->Size + Free->Size))
|
||||
Neighbor = (PHCELL)(Bin + 1);
|
||||
while (Neighbor < Free)
|
||||
{
|
||||
if (Neighbor->Size > 0)
|
||||
{
|
||||
if ((ULONG_PTR)Neighbor + Neighbor->Size == (ULONG_PTR)Free)
|
||||
{
|
||||
HvpRemoveFree(RegistryHive, Neighbor, NeighborCellIndex);
|
||||
Neighbor->Size += Free->Size;
|
||||
HvpAddFree(RegistryHive, Neighbor, NeighborCellIndex);
|
||||
HCELL_INDEX NeighborCellIndex =
|
||||
((HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin +
|
||||
Bin->FileOffset)) | (CellIndex & HCELL_TYPE_MASK);
|
||||
|
||||
if (HvpComputeFreeListIndex(Neighbor->Size) !=
|
||||
HvpComputeFreeListIndex(Neighbor->Size + Free->Size))
|
||||
{
|
||||
HvpRemoveFree(RegistryHive, Neighbor, NeighborCellIndex);
|
||||
Neighbor->Size += Free->Size;
|
||||
HvpAddFree(RegistryHive, Neighbor, NeighborCellIndex);
|
||||
}
|
||||
else
|
||||
Neighbor->Size += Free->Size;
|
||||
|
||||
if (CellType == Stable)
|
||||
HvMarkCellDirty(RegistryHive, NeighborCellIndex, FALSE);
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
Neighbor->Size += Free->Size;
|
||||
Neighbor = (PHCELL)((ULONG_PTR)Neighbor + Neighbor->Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
Neighbor = (PHCELL)((ULONG_PTR)Neighbor - Neighbor->Size);
|
||||
}
|
||||
}
|
||||
|
||||
if (CellType == Stable)
|
||||
HvMarkCellDirty(RegistryHive, NeighborCellIndex, FALSE);
|
||||
/* Add block to the list of free blocks */
|
||||
HvpAddFree(RegistryHive, Free, CellIndex);
|
||||
|
||||
return;
|
||||
}
|
||||
Neighbor = (PHCELL)((ULONG_PTR)Neighbor + Neighbor->Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
Neighbor = (PHCELL)((ULONG_PTR)Neighbor - Neighbor->Size);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add block to the list of free blocks */
|
||||
HvpAddFree(RegistryHive, Free, CellIndex);
|
||||
|
||||
if (CellType == Stable)
|
||||
HvMarkCellDirty(RegistryHive, CellIndex, FALSE);
|
||||
if (CellType == Stable)
|
||||
HvMarkCellDirty(RegistryHive, CellIndex, FALSE);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* PROJECT: Registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2001 - 2005 Eric Kohl
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* PROJECT: Registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2001 - 2005 Eric Kohl
|
||||
|
@ -17,32 +17,32 @@
|
|||
|
||||
BOOLEAN CMAPI
|
||||
HvpVerifyHiveHeader(
|
||||
PHBASE_BLOCK BaseBlock)
|
||||
PHBASE_BLOCK BaseBlock)
|
||||
{
|
||||
if (BaseBlock->Signature != HV_SIGNATURE ||
|
||||
BaseBlock->Major != HSYS_MAJOR ||
|
||||
BaseBlock->Minor < HSYS_MINOR ||
|
||||
BaseBlock->Type != HFILE_TYPE_PRIMARY ||
|
||||
BaseBlock->Format != HBASE_FORMAT_MEMORY ||
|
||||
BaseBlock->Cluster != 1 ||
|
||||
BaseBlock->Sequence1 != BaseBlock->Sequence2 ||
|
||||
HvpHiveHeaderChecksum(BaseBlock) != BaseBlock->CheckSum)
|
||||
{
|
||||
DPRINT1("Verify Hive Header failed: \n");
|
||||
DPRINT1(" Signature: 0x%x, expected 0x%x; Major: 0x%x, expected 0x%x\n",
|
||||
BaseBlock->Signature, HV_SIGNATURE, BaseBlock->Major, HSYS_MAJOR);
|
||||
DPRINT1(" Minor: 0x%x is not >= 0x%x; Type: 0x%x, expected 0x%x\n",
|
||||
BaseBlock->Minor, HSYS_MINOR, BaseBlock->Type, HFILE_TYPE_PRIMARY);
|
||||
DPRINT1(" Format: 0x%x, expected 0x%x; Cluster: 0x%x, expected 1\n",
|
||||
BaseBlock->Format, HBASE_FORMAT_MEMORY, BaseBlock->Cluster);
|
||||
DPRINT1(" Sequence: 0x%x, expected 0x%x; Checksum: 0x%x, expected 0x%x\n",
|
||||
BaseBlock->Sequence1, BaseBlock->Sequence2,
|
||||
HvpHiveHeaderChecksum(BaseBlock), BaseBlock->CheckSum);
|
||||
if (BaseBlock->Signature != HV_SIGNATURE ||
|
||||
BaseBlock->Major != HSYS_MAJOR ||
|
||||
BaseBlock->Minor < HSYS_MINOR ||
|
||||
BaseBlock->Type != HFILE_TYPE_PRIMARY ||
|
||||
BaseBlock->Format != HBASE_FORMAT_MEMORY ||
|
||||
BaseBlock->Cluster != 1 ||
|
||||
BaseBlock->Sequence1 != BaseBlock->Sequence2 ||
|
||||
HvpHiveHeaderChecksum(BaseBlock) != BaseBlock->CheckSum)
|
||||
{
|
||||
DPRINT1("Verify Hive Header failed: \n");
|
||||
DPRINT1(" Signature: 0x%x, expected 0x%x; Major: 0x%x, expected 0x%x\n",
|
||||
BaseBlock->Signature, HV_SIGNATURE, BaseBlock->Major, HSYS_MAJOR);
|
||||
DPRINT1(" Minor: 0x%x is not >= 0x%x; Type: 0x%x, expected 0x%x\n",
|
||||
BaseBlock->Minor, HSYS_MINOR, BaseBlock->Type, HFILE_TYPE_PRIMARY);
|
||||
DPRINT1(" Format: 0x%x, expected 0x%x; Cluster: 0x%x, expected 1\n",
|
||||
BaseBlock->Format, HBASE_FORMAT_MEMORY, BaseBlock->Cluster);
|
||||
DPRINT1(" Sequence: 0x%x, expected 0x%x; Checksum: 0x%x, expected 0x%x\n",
|
||||
BaseBlock->Sequence1, BaseBlock->Sequence2,
|
||||
HvpHiveHeaderChecksum(BaseBlock), BaseBlock->CheckSum);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,31 +54,31 @@ HvpVerifyHiveHeader(
|
|||
|
||||
VOID CMAPI
|
||||
HvpFreeHiveBins(
|
||||
PHHIVE Hive)
|
||||
PHHIVE Hive)
|
||||
{
|
||||
ULONG i;
|
||||
PHBIN Bin;
|
||||
ULONG Storage;
|
||||
ULONG i;
|
||||
PHBIN Bin;
|
||||
ULONG Storage;
|
||||
|
||||
for (Storage = Stable; Storage < HTYPE_COUNT; Storage++)
|
||||
{
|
||||
Bin = NULL;
|
||||
for (i = 0; i < Hive->Storage[Storage].Length; i++)
|
||||
{
|
||||
if (Hive->Storage[Storage].BlockList[i].BinAddress == (ULONG_PTR)NULL)
|
||||
continue;
|
||||
if (Hive->Storage[Storage].BlockList[i].BinAddress != (ULONG_PTR)Bin)
|
||||
{
|
||||
Bin = (PHBIN)Hive->Storage[Storage].BlockList[i].BinAddress;
|
||||
Hive->Free((PHBIN)Hive->Storage[Storage].BlockList[i].BinAddress, 0);
|
||||
}
|
||||
Hive->Storage[Storage].BlockList[i].BinAddress = (ULONG_PTR)NULL;
|
||||
Hive->Storage[Storage].BlockList[i].BlockAddress = (ULONG_PTR)NULL;
|
||||
}
|
||||
for (Storage = Stable; Storage < HTYPE_COUNT; Storage++)
|
||||
{
|
||||
Bin = NULL;
|
||||
for (i = 0; i < Hive->Storage[Storage].Length; i++)
|
||||
{
|
||||
if (Hive->Storage[Storage].BlockList[i].BinAddress == (ULONG_PTR)NULL)
|
||||
continue;
|
||||
if (Hive->Storage[Storage].BlockList[i].BinAddress != (ULONG_PTR)Bin)
|
||||
{
|
||||
Bin = (PHBIN)Hive->Storage[Storage].BlockList[i].BinAddress;
|
||||
Hive->Free((PHBIN)Hive->Storage[Storage].BlockList[i].BinAddress, 0);
|
||||
}
|
||||
Hive->Storage[Storage].BlockList[i].BinAddress = (ULONG_PTR)NULL;
|
||||
Hive->Storage[Storage].BlockList[i].BlockAddress = (ULONG_PTR)NULL;
|
||||
}
|
||||
|
||||
if (Hive->Storage[Storage].Length)
|
||||
Hive->Free(Hive->Storage[Storage].BlockList, 0);
|
||||
}
|
||||
if (Hive->Storage[Storage].Length)
|
||||
Hive->Free(Hive->Storage[Storage].BlockList, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -92,60 +92,60 @@ HvpFreeHiveBins(
|
|||
|
||||
NTSTATUS CMAPI
|
||||
HvpCreateHive(
|
||||
PHHIVE RegistryHive,
|
||||
PCUNICODE_STRING FileName OPTIONAL)
|
||||
PHHIVE RegistryHive,
|
||||
PCUNICODE_STRING FileName OPTIONAL)
|
||||
{
|
||||
PHBASE_BLOCK BaseBlock;
|
||||
ULONG Index;
|
||||
PHBASE_BLOCK BaseBlock;
|
||||
ULONG Index;
|
||||
|
||||
BaseBlock = RegistryHive->Allocate(sizeof(HBASE_BLOCK), FALSE, TAG_CM);
|
||||
if (BaseBlock == NULL)
|
||||
return STATUS_NO_MEMORY;
|
||||
BaseBlock = RegistryHive->Allocate(sizeof(HBASE_BLOCK), FALSE, TAG_CM);
|
||||
if (BaseBlock == NULL)
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
RtlZeroMemory(BaseBlock, sizeof(HBASE_BLOCK));
|
||||
RtlZeroMemory(BaseBlock, sizeof(HBASE_BLOCK));
|
||||
|
||||
BaseBlock->Signature = HV_SIGNATURE;
|
||||
BaseBlock->Major = HSYS_MAJOR;
|
||||
BaseBlock->Minor = HSYS_MINOR;
|
||||
BaseBlock->Type = HFILE_TYPE_PRIMARY;
|
||||
BaseBlock->Format = HBASE_FORMAT_MEMORY;
|
||||
BaseBlock->Cluster = 1;
|
||||
BaseBlock->RootCell = HCELL_NIL;
|
||||
BaseBlock->Length = 0;
|
||||
BaseBlock->Sequence1 = 1;
|
||||
BaseBlock->Sequence2 = 1;
|
||||
BaseBlock->Signature = HV_SIGNATURE;
|
||||
BaseBlock->Major = HSYS_MAJOR;
|
||||
BaseBlock->Minor = HSYS_MINOR;
|
||||
BaseBlock->Type = HFILE_TYPE_PRIMARY;
|
||||
BaseBlock->Format = HBASE_FORMAT_MEMORY;
|
||||
BaseBlock->Cluster = 1;
|
||||
BaseBlock->RootCell = HCELL_NIL;
|
||||
BaseBlock->Length = 0;
|
||||
BaseBlock->Sequence1 = 1;
|
||||
BaseBlock->Sequence2 = 1;
|
||||
|
||||
/* Copy the 31 last characters of the hive file name if any */
|
||||
if (FileName)
|
||||
{
|
||||
if (FileName->Length / sizeof(WCHAR) <= HIVE_FILENAME_MAXLEN)
|
||||
{
|
||||
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));
|
||||
}
|
||||
/* Copy the 31 last characters of the hive file name if any */
|
||||
if (FileName)
|
||||
{
|
||||
if (FileName->Length / sizeof(WCHAR) <= HIVE_FILENAME_MAXLEN)
|
||||
{
|
||||
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 */
|
||||
BaseBlock->FileName[HIVE_FILENAME_MAXLEN] = L'\0';
|
||||
}
|
||||
/* NULL-terminate */
|
||||
BaseBlock->FileName[HIVE_FILENAME_MAXLEN] = L'\0';
|
||||
}
|
||||
|
||||
BaseBlock->CheckSum = HvpHiveHeaderChecksum(BaseBlock);
|
||||
BaseBlock->CheckSum = HvpHiveHeaderChecksum(BaseBlock);
|
||||
|
||||
RegistryHive->BaseBlock = BaseBlock;
|
||||
for (Index = 0; Index < 24; Index++)
|
||||
{
|
||||
RegistryHive->Storage[Stable].FreeDisplay[Index] = HCELL_NIL;
|
||||
RegistryHive->Storage[Volatile].FreeDisplay[Index] = HCELL_NIL;
|
||||
}
|
||||
RegistryHive->BaseBlock = BaseBlock;
|
||||
for (Index = 0; Index < 24; Index++)
|
||||
{
|
||||
RegistryHive->Storage[Stable].FreeDisplay[Index] = HCELL_NIL;
|
||||
RegistryHive->Storage[Volatile].FreeDisplay[Index] = HCELL_NIL;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -160,110 +160,110 @@ HvpCreateHive(
|
|||
|
||||
NTSTATUS CMAPI
|
||||
HvpInitializeMemoryHive(
|
||||
PHHIVE Hive,
|
||||
PVOID ChunkBase)
|
||||
PHHIVE Hive,
|
||||
PVOID ChunkBase)
|
||||
{
|
||||
SIZE_T BlockIndex;
|
||||
PHBIN Bin, NewBin;
|
||||
ULONG i;
|
||||
ULONG BitmapSize;
|
||||
PULONG BitmapBuffer;
|
||||
SIZE_T ChunkSize;
|
||||
SIZE_T BlockIndex;
|
||||
PHBIN Bin, NewBin;
|
||||
ULONG i;
|
||||
ULONG BitmapSize;
|
||||
PULONG BitmapBuffer;
|
||||
SIZE_T ChunkSize;
|
||||
|
||||
ChunkSize = ((PHBASE_BLOCK)ChunkBase)->Length;
|
||||
DPRINT("ChunkSize: %lx\n", ChunkSize);
|
||||
ChunkSize = ((PHBASE_BLOCK)ChunkBase)->Length;
|
||||
DPRINT("ChunkSize: %lx\n", ChunkSize);
|
||||
|
||||
if (ChunkSize < sizeof(HBASE_BLOCK) ||
|
||||
!HvpVerifyHiveHeader((PHBASE_BLOCK)ChunkBase))
|
||||
{
|
||||
DPRINT1("Registry is corrupt: ChunkSize %lu < sizeof(HBASE_BLOCK) %lu, "
|
||||
"or HvpVerifyHiveHeader() failed\n", ChunkSize, (SIZE_T)sizeof(HBASE_BLOCK));
|
||||
return STATUS_REGISTRY_CORRUPT;
|
||||
}
|
||||
if (ChunkSize < sizeof(HBASE_BLOCK) ||
|
||||
!HvpVerifyHiveHeader((PHBASE_BLOCK)ChunkBase))
|
||||
{
|
||||
DPRINT1("Registry is corrupt: ChunkSize %lu < sizeof(HBASE_BLOCK) %lu, "
|
||||
"or HvpVerifyHiveHeader() failed\n", ChunkSize, (SIZE_T)sizeof(HBASE_BLOCK));
|
||||
return STATUS_REGISTRY_CORRUPT;
|
||||
}
|
||||
|
||||
Hive->BaseBlock = Hive->Allocate(sizeof(HBASE_BLOCK), FALSE, TAG_CM);
|
||||
if (Hive->BaseBlock == NULL)
|
||||
{
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
RtlCopyMemory(Hive->BaseBlock, ChunkBase, sizeof(HBASE_BLOCK));
|
||||
Hive->BaseBlock = Hive->Allocate(sizeof(HBASE_BLOCK), FALSE, TAG_CM);
|
||||
if (Hive->BaseBlock == NULL)
|
||||
{
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
RtlCopyMemory(Hive->BaseBlock, ChunkBase, sizeof(HBASE_BLOCK));
|
||||
|
||||
/*
|
||||
* Build a block list from the in-memory chunk and copy the data as
|
||||
* we go.
|
||||
*/
|
||||
/*
|
||||
* Build a block list from the in-memory chunk and copy the data as
|
||||
* we go.
|
||||
*/
|
||||
|
||||
Hive->Storage[Stable].Length = (ULONG)(ChunkSize / HBLOCK_SIZE);
|
||||
Hive->Storage[Stable].BlockList =
|
||||
Hive->Allocate(Hive->Storage[Stable].Length *
|
||||
sizeof(HMAP_ENTRY), FALSE, TAG_CM);
|
||||
if (Hive->Storage[Stable].BlockList == NULL)
|
||||
{
|
||||
DPRINT1("Allocating block list failed\n");
|
||||
Hive->Free(Hive->BaseBlock, 0);
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
Hive->Storage[Stable].Length = (ULONG)(ChunkSize / HBLOCK_SIZE);
|
||||
Hive->Storage[Stable].BlockList =
|
||||
Hive->Allocate(Hive->Storage[Stable].Length *
|
||||
sizeof(HMAP_ENTRY), FALSE, TAG_CM);
|
||||
if (Hive->Storage[Stable].BlockList == NULL)
|
||||
{
|
||||
DPRINT1("Allocating block list failed\n");
|
||||
Hive->Free(Hive->BaseBlock, 0);
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
for (BlockIndex = 0; BlockIndex < Hive->Storage[Stable].Length; )
|
||||
{
|
||||
Bin = (PHBIN)((ULONG_PTR)ChunkBase + (BlockIndex + 1) * HBLOCK_SIZE);
|
||||
if (Bin->Signature != HV_BIN_SIGNATURE ||
|
||||
(Bin->Size % HBLOCK_SIZE) != 0)
|
||||
{
|
||||
DPRINT1("Invalid bin at BlockIndex %lu, Signature 0x%x, Size 0x%x\n",
|
||||
(unsigned long)BlockIndex, (unsigned)Bin->Signature, (unsigned)Bin->Size);
|
||||
Hive->Free(Hive->BaseBlock, 0);
|
||||
Hive->Free(Hive->Storage[Stable].BlockList, 0);
|
||||
return STATUS_REGISTRY_CORRUPT;
|
||||
}
|
||||
for (BlockIndex = 0; BlockIndex < Hive->Storage[Stable].Length; )
|
||||
{
|
||||
Bin = (PHBIN)((ULONG_PTR)ChunkBase + (BlockIndex + 1) * HBLOCK_SIZE);
|
||||
if (Bin->Signature != HV_BIN_SIGNATURE ||
|
||||
(Bin->Size % HBLOCK_SIZE) != 0)
|
||||
{
|
||||
DPRINT1("Invalid bin at BlockIndex %lu, Signature 0x%x, Size 0x%x\n",
|
||||
(unsigned long)BlockIndex, (unsigned)Bin->Signature, (unsigned)Bin->Size);
|
||||
Hive->Free(Hive->BaseBlock, 0);
|
||||
Hive->Free(Hive->Storage[Stable].BlockList, 0);
|
||||
return STATUS_REGISTRY_CORRUPT;
|
||||
}
|
||||
|
||||
NewBin = Hive->Allocate(Bin->Size, TRUE, TAG_CM);
|
||||
if (NewBin == NULL)
|
||||
{
|
||||
Hive->Free(Hive->BaseBlock, 0);
|
||||
Hive->Free(Hive->Storage[Stable].BlockList, 0);
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
NewBin = Hive->Allocate(Bin->Size, TRUE, TAG_CM);
|
||||
if (NewBin == NULL)
|
||||
{
|
||||
Hive->Free(Hive->BaseBlock, 0);
|
||||
Hive->Free(Hive->Storage[Stable].BlockList, 0);
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
Hive->Storage[Stable].BlockList[BlockIndex].BinAddress = (ULONG_PTR)NewBin;
|
||||
Hive->Storage[Stable].BlockList[BlockIndex].BlockAddress = (ULONG_PTR)NewBin;
|
||||
Hive->Storage[Stable].BlockList[BlockIndex].BinAddress = (ULONG_PTR)NewBin;
|
||||
Hive->Storage[Stable].BlockList[BlockIndex].BlockAddress = (ULONG_PTR)NewBin;
|
||||
|
||||
RtlCopyMemory(NewBin, Bin, Bin->Size);
|
||||
RtlCopyMemory(NewBin, Bin, Bin->Size);
|
||||
|
||||
if (Bin->Size > HBLOCK_SIZE)
|
||||
{
|
||||
for (i = 1; i < Bin->Size / HBLOCK_SIZE; i++)
|
||||
{
|
||||
Hive->Storage[Stable].BlockList[BlockIndex + i].BinAddress = (ULONG_PTR)NewBin;
|
||||
Hive->Storage[Stable].BlockList[BlockIndex + i].BlockAddress =
|
||||
((ULONG_PTR)NewBin + (i * HBLOCK_SIZE));
|
||||
}
|
||||
}
|
||||
if (Bin->Size > HBLOCK_SIZE)
|
||||
{
|
||||
for (i = 1; i < Bin->Size / HBLOCK_SIZE; i++)
|
||||
{
|
||||
Hive->Storage[Stable].BlockList[BlockIndex + i].BinAddress = (ULONG_PTR)NewBin;
|
||||
Hive->Storage[Stable].BlockList[BlockIndex + i].BlockAddress =
|
||||
((ULONG_PTR)NewBin + (i * HBLOCK_SIZE));
|
||||
}
|
||||
}
|
||||
|
||||
BlockIndex += Bin->Size / HBLOCK_SIZE;
|
||||
}
|
||||
BlockIndex += Bin->Size / HBLOCK_SIZE;
|
||||
}
|
||||
|
||||
if (HvpCreateHiveFreeCellList(Hive))
|
||||
{
|
||||
HvpFreeHiveBins(Hive);
|
||||
Hive->Free(Hive->BaseBlock, 0);
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
if (HvpCreateHiveFreeCellList(Hive))
|
||||
{
|
||||
HvpFreeHiveBins(Hive);
|
||||
Hive->Free(Hive->BaseBlock, 0);
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
BitmapSize = ROUND_UP(Hive->Storage[Stable].Length,
|
||||
sizeof(ULONG) * 8) / 8;
|
||||
BitmapBuffer = (PULONG)Hive->Allocate(BitmapSize, TRUE, TAG_CM);
|
||||
if (BitmapBuffer == NULL)
|
||||
{
|
||||
HvpFreeHiveBins(Hive);
|
||||
Hive->Free(Hive->BaseBlock, 0);
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
BitmapSize = ROUND_UP(Hive->Storage[Stable].Length,
|
||||
sizeof(ULONG) * 8) / 8;
|
||||
BitmapBuffer = (PULONG)Hive->Allocate(BitmapSize, TRUE, TAG_CM);
|
||||
if (BitmapBuffer == NULL)
|
||||
{
|
||||
HvpFreeHiveBins(Hive);
|
||||
Hive->Free(Hive->BaseBlock, 0);
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
RtlInitializeBitMap(&Hive->DirtyVector, BitmapBuffer, BitmapSize * 8);
|
||||
RtlClearAllBits(&Hive->DirtyVector);
|
||||
RtlInitializeBitMap(&Hive->DirtyVector, BitmapBuffer, BitmapSize * 8);
|
||||
RtlClearAllBits(&Hive->DirtyVector);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -278,19 +278,19 @@ HvpInitializeMemoryHive(
|
|||
|
||||
NTSTATUS CMAPI
|
||||
HvpInitializeMemoryInplaceHive(
|
||||
PHHIVE Hive,
|
||||
PVOID ChunkBase)
|
||||
PHHIVE Hive,
|
||||
PVOID ChunkBase)
|
||||
{
|
||||
if (!HvpVerifyHiveHeader((PHBASE_BLOCK)ChunkBase))
|
||||
{
|
||||
return STATUS_REGISTRY_CORRUPT;
|
||||
}
|
||||
if (!HvpVerifyHiveHeader((PHBASE_BLOCK)ChunkBase))
|
||||
{
|
||||
return STATUS_REGISTRY_CORRUPT;
|
||||
}
|
||||
|
||||
Hive->BaseBlock = (PHBASE_BLOCK)ChunkBase;
|
||||
Hive->ReadOnly = TRUE;
|
||||
Hive->Flat = TRUE;
|
||||
Hive->BaseBlock = (PHBASE_BLOCK)ChunkBase;
|
||||
Hive->ReadOnly = TRUE;
|
||||
Hive->Flat = TRUE;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
typedef enum _RESULT
|
||||
|
@ -446,83 +446,83 @@ HvLoadHive(IN PHHIVE Hive,
|
|||
|
||||
NTSTATUS CMAPI
|
||||
HvInitialize(
|
||||
PHHIVE RegistryHive,
|
||||
ULONG Operation,
|
||||
ULONG HiveType,
|
||||
ULONG HiveFlags,
|
||||
PVOID HiveData OPTIONAL,
|
||||
PALLOCATE_ROUTINE Allocate,
|
||||
PFREE_ROUTINE Free,
|
||||
PFILE_SET_SIZE_ROUTINE FileSetSize,
|
||||
PFILE_WRITE_ROUTINE FileWrite,
|
||||
PFILE_READ_ROUTINE FileRead,
|
||||
PFILE_FLUSH_ROUTINE FileFlush,
|
||||
ULONG Cluster OPTIONAL,
|
||||
PCUNICODE_STRING FileName OPTIONAL)
|
||||
PHHIVE RegistryHive,
|
||||
ULONG Operation,
|
||||
ULONG HiveType,
|
||||
ULONG HiveFlags,
|
||||
PVOID HiveData OPTIONAL,
|
||||
PALLOCATE_ROUTINE Allocate,
|
||||
PFREE_ROUTINE Free,
|
||||
PFILE_SET_SIZE_ROUTINE FileSetSize,
|
||||
PFILE_WRITE_ROUTINE FileWrite,
|
||||
PFILE_READ_ROUTINE FileRead,
|
||||
PFILE_FLUSH_ROUTINE FileFlush,
|
||||
ULONG Cluster OPTIONAL,
|
||||
PCUNICODE_STRING FileName OPTIONAL)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PHHIVE Hive = RegistryHive;
|
||||
NTSTATUS Status;
|
||||
PHHIVE Hive = RegistryHive;
|
||||
|
||||
UNREFERENCED_PARAMETER(HiveType);
|
||||
UNREFERENCED_PARAMETER(HiveType);
|
||||
|
||||
/*
|
||||
* Create a new hive structure that will hold all the maintenance data.
|
||||
*/
|
||||
/*
|
||||
* Create a new hive structure that will hold all the maintenance data.
|
||||
*/
|
||||
|
||||
RtlZeroMemory(Hive, sizeof(HHIVE));
|
||||
RtlZeroMemory(Hive, sizeof(HHIVE));
|
||||
|
||||
Hive->Allocate = Allocate;
|
||||
Hive->Free = Free;
|
||||
Hive->FileRead = FileRead;
|
||||
Hive->FileWrite = FileWrite;
|
||||
Hive->FileSetSize = FileSetSize;
|
||||
Hive->FileFlush = FileFlush;
|
||||
Hive->StorageTypeCount = HTYPE_COUNT;
|
||||
Hive->Cluster = 1;
|
||||
Hive->Version = HSYS_MINOR;
|
||||
Hive->HiveFlags = HiveFlags &~ HIVE_NOLAZYFLUSH;
|
||||
Hive->Allocate = Allocate;
|
||||
Hive->Free = Free;
|
||||
Hive->FileRead = FileRead;
|
||||
Hive->FileWrite = FileWrite;
|
||||
Hive->FileSetSize = FileSetSize;
|
||||
Hive->FileFlush = FileFlush;
|
||||
Hive->StorageTypeCount = HTYPE_COUNT;
|
||||
Hive->Cluster = 1;
|
||||
Hive->Version = HSYS_MINOR;
|
||||
Hive->HiveFlags = HiveFlags &~ HIVE_NOLAZYFLUSH;
|
||||
|
||||
switch (Operation)
|
||||
{
|
||||
case HINIT_CREATE:
|
||||
Status = HvpCreateHive(Hive, FileName);
|
||||
break;
|
||||
switch (Operation)
|
||||
{
|
||||
case HINIT_CREATE:
|
||||
Status = HvpCreateHive(Hive, FileName);
|
||||
break;
|
||||
|
||||
case HINIT_MEMORY:
|
||||
Status = HvpInitializeMemoryHive(Hive, HiveData);
|
||||
break;
|
||||
case HINIT_MEMORY:
|
||||
Status = HvpInitializeMemoryHive(Hive, HiveData);
|
||||
break;
|
||||
|
||||
case HINIT_FLAT:
|
||||
Status = HvpInitializeMemoryInplaceHive(Hive, HiveData);
|
||||
break;
|
||||
case HINIT_FLAT:
|
||||
Status = HvpInitializeMemoryInplaceHive(Hive, HiveData);
|
||||
break;
|
||||
|
||||
case HINIT_FILE:
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
case HINIT_FILE:
|
||||
{
|
||||
/* 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 */
|
||||
ASSERT(Status != STATUS_REGISTRY_RECOVERED);
|
||||
break;
|
||||
}
|
||||
/* Check for previous damage */
|
||||
ASSERT(Status != STATUS_REGISTRY_RECOVERED);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
/* FIXME: A better return status value is needed */
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
default:
|
||||
/* FIXME: A better return status value is needed */
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
if (Operation != HINIT_CREATE) CmPrepareHive(Hive);
|
||||
if (Operation != HINIT_CREATE) CmPrepareHive(Hive);
|
||||
|
||||
return Status;
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -534,25 +534,25 @@ HvInitialize(
|
|||
|
||||
VOID CMAPI
|
||||
HvFree(
|
||||
PHHIVE RegistryHive)
|
||||
PHHIVE RegistryHive)
|
||||
{
|
||||
if (!RegistryHive->ReadOnly)
|
||||
{
|
||||
/* Release hive bitmap */
|
||||
if (RegistryHive->DirtyVector.Buffer)
|
||||
{
|
||||
RegistryHive->Free(RegistryHive->DirtyVector.Buffer, 0);
|
||||
}
|
||||
if (!RegistryHive->ReadOnly)
|
||||
{
|
||||
/* Release hive bitmap */
|
||||
if (RegistryHive->DirtyVector.Buffer)
|
||||
{
|
||||
RegistryHive->Free(RegistryHive->DirtyVector.Buffer, 0);
|
||||
}
|
||||
|
||||
HvpFreeHiveBins(RegistryHive);
|
||||
HvpFreeHiveBins(RegistryHive);
|
||||
|
||||
/* Free the BaseBlock */
|
||||
if (RegistryHive->BaseBlock)
|
||||
{
|
||||
RegistryHive->Free(RegistryHive->BaseBlock, 0);
|
||||
RegistryHive->BaseBlock = NULL;
|
||||
}
|
||||
}
|
||||
/* Free the BaseBlock */
|
||||
if (RegistryHive->BaseBlock)
|
||||
{
|
||||
RegistryHive->Free(RegistryHive->BaseBlock, 0);
|
||||
RegistryHive->BaseBlock = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* PROJECT: Registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2001 - 2005 Eric Kohl
|
||||
|
@ -15,18 +15,18 @@
|
|||
|
||||
ULONG CMAPI
|
||||
HvpHiveHeaderChecksum(
|
||||
PHBASE_BLOCK HiveHeader)
|
||||
PHBASE_BLOCK HiveHeader)
|
||||
{
|
||||
PULONG Buffer = (PULONG)HiveHeader;
|
||||
ULONG Sum = 0;
|
||||
ULONG i;
|
||||
PULONG Buffer = (PULONG)HiveHeader;
|
||||
ULONG Sum = 0;
|
||||
ULONG i;
|
||||
|
||||
for (i = 0; i < 127; i++)
|
||||
Sum ^= Buffer[i];
|
||||
if (Sum == (ULONG)-1)
|
||||
Sum = (ULONG)-2;
|
||||
if (Sum == 0)
|
||||
Sum = 1;
|
||||
for (i = 0; i < 127; i++)
|
||||
Sum ^= Buffer[i];
|
||||
if (Sum == (ULONG)-1)
|
||||
Sum = (ULONG)-2;
|
||||
if (Sum == 0)
|
||||
Sum = 1;
|
||||
|
||||
return Sum;
|
||||
return Sum;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* PROJECT: Registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2001 - 2005 Eric Kohl
|
||||
|
@ -11,267 +11,265 @@
|
|||
|
||||
static BOOLEAN CMAPI
|
||||
HvpWriteLog(
|
||||
PHHIVE RegistryHive)
|
||||
PHHIVE RegistryHive)
|
||||
{
|
||||
ULONG FileOffset;
|
||||
UINT32 BufferSize;
|
||||
UINT32 BitmapSize;
|
||||
PUCHAR Buffer;
|
||||
PUCHAR Ptr;
|
||||
ULONG BlockIndex;
|
||||
ULONG LastIndex;
|
||||
PVOID BlockPtr;
|
||||
BOOLEAN Success;
|
||||
static ULONG PrintCount = 0;
|
||||
ULONG FileOffset;
|
||||
UINT32 BufferSize;
|
||||
UINT32 BitmapSize;
|
||||
PUCHAR Buffer;
|
||||
PUCHAR Ptr;
|
||||
ULONG BlockIndex;
|
||||
ULONG LastIndex;
|
||||
PVOID BlockPtr;
|
||||
BOOLEAN Success;
|
||||
static ULONG PrintCount = 0;
|
||||
|
||||
if (PrintCount++ == 0)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
return TRUE;
|
||||
if (PrintCount++ == 0)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
ASSERT(RegistryHive->BaseBlock->Length ==
|
||||
RegistryHive->Storage[Stable].Length * HBLOCK_SIZE);
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
ASSERT(RegistryHive->BaseBlock->Length ==
|
||||
RegistryHive->Storage[Stable].Length * HBLOCK_SIZE);
|
||||
|
||||
DPRINT("HvpWriteLog called\n");
|
||||
DPRINT("HvpWriteLog called\n");
|
||||
|
||||
if (RegistryHive->BaseBlock->Sequence1 !=
|
||||
RegistryHive->BaseBlock->Sequence2)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BitmapSize = RegistryHive->DirtyVector.SizeOfBitMap;
|
||||
BufferSize = HV_LOG_HEADER_SIZE + sizeof(ULONG) + BitmapSize;
|
||||
BufferSize = ROUND_UP(BufferSize, HBLOCK_SIZE);
|
||||
|
||||
DPRINT("Bitmap size %u buffer size: %u\n", BitmapSize, BufferSize);
|
||||
|
||||
Buffer = RegistryHive->Allocate(BufferSize, TRUE, TAG_CM);
|
||||
if (Buffer == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Update first update counter and CheckSum */
|
||||
RegistryHive->BaseBlock->Type = HFILE_TYPE_LOG;
|
||||
RegistryHive->BaseBlock->Sequence1++;
|
||||
RegistryHive->BaseBlock->CheckSum =
|
||||
HvpHiveHeaderChecksum(RegistryHive->BaseBlock);
|
||||
|
||||
/* Copy hive header */
|
||||
RtlCopyMemory(Buffer, RegistryHive->BaseBlock, HV_LOG_HEADER_SIZE);
|
||||
Ptr = Buffer + HV_LOG_HEADER_SIZE;
|
||||
RtlCopyMemory(Ptr, "DIRT", 4);
|
||||
Ptr += 4;
|
||||
RtlCopyMemory(Ptr, RegistryHive->DirtyVector.Buffer, BitmapSize);
|
||||
|
||||
/* Write hive block and block bitmap */
|
||||
FileOffset = 0;
|
||||
Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_LOG,
|
||||
&FileOffset, Buffer, BufferSize);
|
||||
RegistryHive->Free(Buffer, 0);
|
||||
|
||||
if (!Success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Write dirty blocks */
|
||||
FileOffset = BufferSize;
|
||||
BlockIndex = 0;
|
||||
while (BlockIndex < RegistryHive->Storage[Stable].Length)
|
||||
{
|
||||
LastIndex = BlockIndex;
|
||||
BlockIndex = RtlFindSetBits(&RegistryHive->DirtyVector, 1, BlockIndex);
|
||||
if (BlockIndex == ~0U || BlockIndex < LastIndex)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
BlockPtr = (PVOID)RegistryHive->Storage[Stable].BlockList[BlockIndex].BlockAddress;
|
||||
|
||||
/* Write hive block */
|
||||
Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_LOG,
|
||||
&FileOffset, BlockPtr,
|
||||
HBLOCK_SIZE);
|
||||
if (!Success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BlockIndex++;
|
||||
FileOffset += HBLOCK_SIZE;
|
||||
if (RegistryHive->BaseBlock->Sequence1 !=
|
||||
RegistryHive->BaseBlock->Sequence2)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Success = RegistryHive->FileSetSize(RegistryHive, HFILE_TYPE_LOG, FileOffset, FileOffset);
|
||||
if (!Success)
|
||||
{
|
||||
DPRINT("FileSetSize failed\n");
|
||||
return FALSE;
|
||||
BitmapSize = RegistryHive->DirtyVector.SizeOfBitMap;
|
||||
BufferSize = HV_LOG_HEADER_SIZE + sizeof(ULONG) + BitmapSize;
|
||||
BufferSize = ROUND_UP(BufferSize, HBLOCK_SIZE);
|
||||
|
||||
DPRINT("Bitmap size %u buffer size: %u\n", BitmapSize, BufferSize);
|
||||
|
||||
Buffer = RegistryHive->Allocate(BufferSize, TRUE, TAG_CM);
|
||||
if (Buffer == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Flush the log file */
|
||||
Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_LOG, NULL, 0);
|
||||
if (!Success)
|
||||
{
|
||||
DPRINT("FileFlush failed\n");
|
||||
}
|
||||
/* Update first update counter and CheckSum */
|
||||
RegistryHive->BaseBlock->Type = HFILE_TYPE_LOG;
|
||||
RegistryHive->BaseBlock->Sequence1++;
|
||||
RegistryHive->BaseBlock->CheckSum =
|
||||
HvpHiveHeaderChecksum(RegistryHive->BaseBlock);
|
||||
|
||||
/* Update second update counter and CheckSum. */
|
||||
RegistryHive->BaseBlock->Sequence2++;
|
||||
RegistryHive->BaseBlock->CheckSum =
|
||||
HvpHiveHeaderChecksum(RegistryHive->BaseBlock);
|
||||
/* Copy hive header */
|
||||
RtlCopyMemory(Buffer, RegistryHive->BaseBlock, HV_LOG_HEADER_SIZE);
|
||||
Ptr = Buffer + HV_LOG_HEADER_SIZE;
|
||||
RtlCopyMemory(Ptr, "DIRT", 4);
|
||||
Ptr += 4;
|
||||
RtlCopyMemory(Ptr, RegistryHive->DirtyVector.Buffer, BitmapSize);
|
||||
|
||||
/* Write hive header again with updated sequence counter. */
|
||||
FileOffset = 0;
|
||||
Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_LOG,
|
||||
&FileOffset, RegistryHive->BaseBlock,
|
||||
HV_LOG_HEADER_SIZE);
|
||||
if (!Success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
/* Write hive block and block bitmap */
|
||||
FileOffset = 0;
|
||||
Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_LOG,
|
||||
&FileOffset, Buffer, BufferSize);
|
||||
RegistryHive->Free(Buffer, 0);
|
||||
|
||||
/* Flush the log file */
|
||||
Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_LOG, NULL, 0);
|
||||
if (!Success)
|
||||
{
|
||||
DPRINT("FileFlush failed\n");
|
||||
}
|
||||
if (!Success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
/* Write dirty blocks */
|
||||
FileOffset = BufferSize;
|
||||
BlockIndex = 0;
|
||||
while (BlockIndex < RegistryHive->Storage[Stable].Length)
|
||||
{
|
||||
LastIndex = BlockIndex;
|
||||
BlockIndex = RtlFindSetBits(&RegistryHive->DirtyVector, 1, BlockIndex);
|
||||
if (BlockIndex == ~0U || BlockIndex < LastIndex)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
BlockPtr = (PVOID)RegistryHive->Storage[Stable].BlockList[BlockIndex].BlockAddress;
|
||||
|
||||
/* Write hive block */
|
||||
Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_LOG,
|
||||
&FileOffset, BlockPtr, HBLOCK_SIZE);
|
||||
if (!Success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BlockIndex++;
|
||||
FileOffset += HBLOCK_SIZE;
|
||||
}
|
||||
|
||||
Success = RegistryHive->FileSetSize(RegistryHive, HFILE_TYPE_LOG, FileOffset, FileOffset);
|
||||
if (!Success)
|
||||
{
|
||||
DPRINT("FileSetSize failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Flush the log file */
|
||||
Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_LOG, NULL, 0);
|
||||
if (!Success)
|
||||
{
|
||||
DPRINT("FileFlush failed\n");
|
||||
}
|
||||
|
||||
/* Update second update counter and CheckSum. */
|
||||
RegistryHive->BaseBlock->Sequence2++;
|
||||
RegistryHive->BaseBlock->CheckSum =
|
||||
HvpHiveHeaderChecksum(RegistryHive->BaseBlock);
|
||||
|
||||
/* Write hive header again with updated sequence counter. */
|
||||
FileOffset = 0;
|
||||
Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_LOG,
|
||||
&FileOffset, RegistryHive->BaseBlock,
|
||||
HV_LOG_HEADER_SIZE);
|
||||
if (!Success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Flush the log file */
|
||||
Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_LOG, NULL, 0);
|
||||
if (!Success)
|
||||
{
|
||||
DPRINT("FileFlush failed\n");
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOLEAN CMAPI
|
||||
HvpWriteHive(
|
||||
PHHIVE RegistryHive,
|
||||
BOOLEAN OnlyDirty)
|
||||
PHHIVE RegistryHive,
|
||||
BOOLEAN OnlyDirty)
|
||||
{
|
||||
ULONG FileOffset;
|
||||
ULONG BlockIndex;
|
||||
ULONG LastIndex;
|
||||
PVOID BlockPtr;
|
||||
BOOLEAN Success;
|
||||
ULONG FileOffset;
|
||||
ULONG BlockIndex;
|
||||
ULONG LastIndex;
|
||||
PVOID BlockPtr;
|
||||
BOOLEAN Success;
|
||||
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
ASSERT(RegistryHive->BaseBlock->Length ==
|
||||
RegistryHive->Storage[Stable].Length * HBLOCK_SIZE);
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
ASSERT(RegistryHive->BaseBlock->Length ==
|
||||
RegistryHive->Storage[Stable].Length * HBLOCK_SIZE);
|
||||
|
||||
DPRINT("HvpWriteHive called\n");
|
||||
DPRINT("HvpWriteHive called\n");
|
||||
|
||||
if (RegistryHive->BaseBlock->Sequence1 !=
|
||||
RegistryHive->BaseBlock->Sequence2)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (RegistryHive->BaseBlock->Sequence1 !=
|
||||
RegistryHive->BaseBlock->Sequence2)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Update first update counter and CheckSum */
|
||||
RegistryHive->BaseBlock->Type = HFILE_TYPE_PRIMARY;
|
||||
RegistryHive->BaseBlock->Sequence1++;
|
||||
RegistryHive->BaseBlock->CheckSum =
|
||||
HvpHiveHeaderChecksum(RegistryHive->BaseBlock);
|
||||
/* Update first update counter and CheckSum */
|
||||
RegistryHive->BaseBlock->Type = HFILE_TYPE_PRIMARY;
|
||||
RegistryHive->BaseBlock->Sequence1++;
|
||||
RegistryHive->BaseBlock->CheckSum =
|
||||
HvpHiveHeaderChecksum(RegistryHive->BaseBlock);
|
||||
|
||||
/* Write hive block */
|
||||
FileOffset = 0;
|
||||
Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_PRIMARY,
|
||||
&FileOffset, RegistryHive->BaseBlock,
|
||||
sizeof(HBASE_BLOCK));
|
||||
if (!Success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
/* Write hive block */
|
||||
FileOffset = 0;
|
||||
Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_PRIMARY,
|
||||
&FileOffset, RegistryHive->BaseBlock,
|
||||
sizeof(HBASE_BLOCK));
|
||||
if (!Success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BlockIndex = 0;
|
||||
while (BlockIndex < RegistryHive->Storage[Stable].Length)
|
||||
{
|
||||
if (OnlyDirty)
|
||||
{
|
||||
LastIndex = BlockIndex;
|
||||
BlockIndex = RtlFindSetBits(&RegistryHive->DirtyVector, 1, BlockIndex);
|
||||
if (BlockIndex == ~0U || BlockIndex < LastIndex)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
BlockIndex = 0;
|
||||
while (BlockIndex < RegistryHive->Storage[Stable].Length)
|
||||
{
|
||||
if (OnlyDirty)
|
||||
{
|
||||
LastIndex = BlockIndex;
|
||||
BlockIndex = RtlFindSetBits(&RegistryHive->DirtyVector, 1, BlockIndex);
|
||||
if (BlockIndex == ~0U || BlockIndex < LastIndex)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BlockPtr = (PVOID)RegistryHive->Storage[Stable].BlockList[BlockIndex].BlockAddress;
|
||||
FileOffset = (BlockIndex + 1) * HBLOCK_SIZE;
|
||||
BlockPtr = (PVOID)RegistryHive->Storage[Stable].BlockList[BlockIndex].BlockAddress;
|
||||
FileOffset = (BlockIndex + 1) * HBLOCK_SIZE;
|
||||
|
||||
/* Write hive block */
|
||||
Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_PRIMARY,
|
||||
&FileOffset, BlockPtr,
|
||||
HBLOCK_SIZE);
|
||||
if (!Success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
/* Write hive block */
|
||||
Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_PRIMARY,
|
||||
&FileOffset, BlockPtr, HBLOCK_SIZE);
|
||||
if (!Success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BlockIndex++;
|
||||
}
|
||||
BlockIndex++;
|
||||
}
|
||||
|
||||
Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_PRIMARY, NULL, 0);
|
||||
if (!Success)
|
||||
{
|
||||
DPRINT("FileFlush failed\n");
|
||||
}
|
||||
Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_PRIMARY, NULL, 0);
|
||||
if (!Success)
|
||||
{
|
||||
DPRINT("FileFlush failed\n");
|
||||
}
|
||||
|
||||
/* Update second update counter and CheckSum */
|
||||
RegistryHive->BaseBlock->Sequence2++;
|
||||
RegistryHive->BaseBlock->CheckSum =
|
||||
HvpHiveHeaderChecksum(RegistryHive->BaseBlock);
|
||||
/* Update second update counter and CheckSum */
|
||||
RegistryHive->BaseBlock->Sequence2++;
|
||||
RegistryHive->BaseBlock->CheckSum =
|
||||
HvpHiveHeaderChecksum(RegistryHive->BaseBlock);
|
||||
|
||||
/* Write hive block */
|
||||
FileOffset = 0;
|
||||
Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_PRIMARY,
|
||||
&FileOffset, RegistryHive->BaseBlock,
|
||||
sizeof(HBASE_BLOCK));
|
||||
if (!Success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
/* Write hive block */
|
||||
FileOffset = 0;
|
||||
Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_PRIMARY,
|
||||
&FileOffset, RegistryHive->BaseBlock,
|
||||
sizeof(HBASE_BLOCK));
|
||||
if (!Success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_PRIMARY, NULL, 0);
|
||||
if (!Success)
|
||||
{
|
||||
DPRINT("FileFlush failed\n");
|
||||
}
|
||||
Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_PRIMARY, NULL, 0);
|
||||
if (!Success)
|
||||
{
|
||||
DPRINT("FileFlush failed\n");
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN CMAPI
|
||||
HvSyncHive(
|
||||
PHHIVE RegistryHive)
|
||||
PHHIVE RegistryHive)
|
||||
{
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
|
||||
if (RtlFindSetBits(&RegistryHive->DirtyVector, 1, 0) == ~0U)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if (RtlFindSetBits(&RegistryHive->DirtyVector, 1, 0) == ~0U)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Update hive header modification time */
|
||||
KeQuerySystemTime(&RegistryHive->BaseBlock->TimeStamp);
|
||||
/* Update hive header modification time */
|
||||
KeQuerySystemTime(&RegistryHive->BaseBlock->TimeStamp);
|
||||
|
||||
/* Update log file */
|
||||
if (!HvpWriteLog(RegistryHive))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
/* Update log file */
|
||||
if (!HvpWriteLog(RegistryHive))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Update hive file */
|
||||
if (!HvpWriteHive(RegistryHive, TRUE))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
/* Update hive file */
|
||||
if (!HvpWriteHive(RegistryHive, TRUE))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Clear dirty bitmap. */
|
||||
RtlClearAllBits(&RegistryHive->DirtyVector);
|
||||
RegistryHive->DirtyCount = 0;
|
||||
/* Clear dirty bitmap. */
|
||||
RtlClearAllBits(&RegistryHive->DirtyVector);
|
||||
RegistryHive->DirtyCount = 0;
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
|
@ -279,23 +277,24 @@ CMAPI
|
|||
HvHiveWillShrink(IN PHHIVE RegistryHive)
|
||||
{
|
||||
/* No shrinking yet */
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN CMAPI
|
||||
HvWriteHive(
|
||||
PHHIVE RegistryHive)
|
||||
PHHIVE RegistryHive)
|
||||
{
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
|
||||
/* Update hive header modification time */
|
||||
KeQuerySystemTime(&RegistryHive->BaseBlock->TimeStamp);
|
||||
/* Update hive header modification time */
|
||||
KeQuerySystemTime(&RegistryHive->BaseBlock->TimeStamp);
|
||||
|
||||
/* Update hive file */
|
||||
if (!HvpWriteHive(RegistryHive, FALSE))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
/* Update hive file */
|
||||
if (!HvpWriteHive(RegistryHive, FALSE))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue