- Update cmlib interface to NT 5.2.

- Fix a bug in CmpInitializeHive which was calling HvInitializeHive with inverted params.
- Fix some host header issues.

svn path=/trunk/; revision=29879
This commit is contained in:
Aleksey Bragin 2007-10-25 15:53:51 +00:00
parent 5419828b1a
commit 6dad5e16a9
26 changed files with 678 additions and 590 deletions

View file

@ -27,7 +27,7 @@
static PVOID static PVOID
NTAPI NTAPI
CmpAllocate (SIZE_T Size, BOOLEAN Paged) CmpAllocate (SIZE_T Size, BOOLEAN Paged, ULONG Tag)
{ {
return MmAllocateMemory(Size); return MmAllocateMemory(Size);
} }
@ -35,7 +35,7 @@ CmpAllocate (SIZE_T Size, BOOLEAN Paged)
static VOID static VOID
NTAPI NTAPI
CmpFree (PVOID Ptr) CmpFree (PVOID Ptr, IN ULONG Quota)
{ {
return MmFreeMemory(Ptr); return MmFreeMemory(Ptr);
} }
@ -51,13 +51,13 @@ CmiAllocateHashTableCell (PHHIVE Hive,
NewHashSize = sizeof(HASH_TABLE_CELL) + NewHashSize = sizeof(HASH_TABLE_CELL) +
(SubKeyCount * sizeof(HASH_RECORD)); (SubKeyCount * sizeof(HASH_RECORD));
*HBOffset = HvAllocateCell (Hive, NewHashSize, HvStable); *HBOffset = HvAllocateCell (Hive, NewHashSize, Stable, HCELL_NIL);
if (*HBOffset == HCELL_NULL) if (*HBOffset == HCELL_NIL)
{ {
return FALSE; return FALSE;
} }
HashCell = HvGetCell (Hive, *HBOffset); HashCell = (PHASH_TABLE_CELL)HvGetCell (Hive, *HBOffset);
HashCell->Id = REG_HASH_TABLE_CELL_ID; HashCell->Id = REG_HASH_TABLE_CELL_ID;
HashCell->HashTableSize = SubKeyCount; HashCell->HashTableSize = SubKeyCount;
@ -75,8 +75,8 @@ CmiAddKeyToParentHashTable (PHHIVE Hive,
PCM_KEY_NODE ParentKeyCell; PCM_KEY_NODE ParentKeyCell;
ULONG i; ULONG i;
ParentKeyCell = HvGetCell (Hive, Parent); ParentKeyCell = (PVOID)HvGetCell (Hive, Parent);
HashBlock = HvGetCell (Hive, ParentKeyCell->SubKeyLists[HvStable]); HashBlock = (PVOID)HvGetCell (Hive, ParentKeyCell->SubKeyLists[Stable]);
for (i = 0; i < HashBlock->HashTableSize; i++) for (i = 0; i < HashBlock->HashTableSize; i++)
{ {
@ -86,7 +86,7 @@ CmiAddKeyToParentHashTable (PHHIVE Hive,
memcpy (&HashBlock->Table[i].HashValue, memcpy (&HashBlock->Table[i].HashValue,
NewKeyCell->Name, NewKeyCell->Name,
min(NewKeyCell->NameSize, sizeof(ULONG))); min(NewKeyCell->NameSize, sizeof(ULONG)));
ParentKeyCell->SubKeyCounts[HvStable]++; ParentKeyCell->SubKeyCounts[Stable]++;
return TRUE; return TRUE;
} }
} }
@ -104,8 +104,8 @@ CmiAllocateValueListCell (PHHIVE Hive,
ValueListSize = sizeof(VALUE_LIST_CELL) + ValueListSize = sizeof(VALUE_LIST_CELL) +
(ValueCount * sizeof(HCELL_INDEX)); (ValueCount * sizeof(HCELL_INDEX));
*ValueListOffset = HvAllocateCell (Hive, ValueListSize, HvStable); *ValueListOffset = HvAllocateCell (Hive, ValueListSize, Stable, HCELL_NIL);
if (*ValueListOffset == HCELL_NULL) if (*ValueListOffset == HCELL_NIL)
{ {
DbgPrint((DPRINT_REGISTRY, "HvAllocateCell() failed\n")); DbgPrint((DPRINT_REGISTRY, "HvAllocateCell() failed\n"));
return FALSE; return FALSE;
@ -136,8 +136,8 @@ CmiAllocateValueCell(PHHIVE Hive,
break; break;
} }
} }
*ValueCellOffset = HvAllocateCell (Hive, sizeof(CM_KEY_VALUE) + NameSize, HvStable); *ValueCellOffset = HvAllocateCell (Hive, sizeof(CM_KEY_VALUE) + NameSize, Stable, HCELL_NIL);
if (*ValueCellOffset == HCELL_NULL) if (*ValueCellOffset == HCELL_NIL)
{ {
DbgPrint((DPRINT_REGISTRY, "CmiAllocateCell() failed\n")); DbgPrint((DPRINT_REGISTRY, "CmiAllocateCell() failed\n"));
return FALSE; return FALSE;
@ -182,14 +182,14 @@ CmiAddValueToKeyValueList(PHHIVE Hive,
PVALUE_LIST_CELL ValueListCell; PVALUE_LIST_CELL ValueListCell;
PCM_KEY_NODE KeyCell; PCM_KEY_NODE KeyCell;
KeyCell = HvGetCell (Hive, KeyCellOffset); KeyCell = (PCM_KEY_NODE)HvGetCell (Hive, KeyCellOffset);
if (KeyCell == NULL) if (KeyCell == NULL)
{ {
DbgPrint((DPRINT_REGISTRY, "HvGetCell() failed\n")); DbgPrint((DPRINT_REGISTRY, "HvGetCell() failed\n"));
return FALSE; return FALSE;
} }
ValueListCell = HvGetCell (Hive, KeyCell->ValueList.List); ValueListCell = (PVALUE_LIST_CELL)HvGetCell (Hive, KeyCell->ValueList.List);
if (ValueListCell == NULL) if (ValueListCell == NULL)
{ {
DbgPrint((DPRINT_REGISTRY, "HvGetCell() failed\n")); DbgPrint((DPRINT_REGISTRY, "HvGetCell() failed\n"));
@ -256,8 +256,8 @@ CmiExportValue (PHHIVE Hive,
else else
{ {
/* Allocate data cell */ /* Allocate data cell */
DataCellOffset = HvAllocateCell (Hive, DataSize, HvStable); DataCellOffset = HvAllocateCell (Hive, DataSize, Stable, HCELL_NIL);
if (DataCellOffset == HCELL_NULL) if (DataCellOffset == HCELL_NIL)
{ {
return FALSE; return FALSE;
} }
@ -266,7 +266,7 @@ CmiExportValue (PHHIVE Hive,
ValueCell->DataSize = DataSize; ValueCell->DataSize = DataSize;
ValueCell->DataType = DataType; ValueCell->DataType = DataType;
DataCell = HvGetCell (Hive, DataCellOffset); DataCell = (PVOID)HvGetCell (Hive, DataCellOffset);
memcpy (DataCell, memcpy (DataCell,
Data, Data,
DataSize); DataSize);
@ -313,8 +313,8 @@ CmiExportSubKey (PHHIVE Hive,
/* Allocate key cell */ /* Allocate key cell */
KeyCellSize = sizeof(CM_KEY_NODE) + NameSize; KeyCellSize = sizeof(CM_KEY_NODE) + NameSize;
NKBOffset = HvAllocateCell (Hive, KeyCellSize, HvStable); NKBOffset = HvAllocateCell (Hive, KeyCellSize, Stable, HCELL_NIL);
if (NKBOffset == HCELL_NULL) if (NKBOffset == HCELL_NIL)
{ {
DbgPrint((DPRINT_REGISTRY, "HvAllocateCell() failed\n")); DbgPrint((DPRINT_REGISTRY, "HvAllocateCell() failed\n"));
return FALSE; return FALSE;
@ -326,8 +326,8 @@ CmiExportSubKey (PHHIVE Hive,
NewKeyCell->Flags = 0; NewKeyCell->Flags = 0;
NewKeyCell->LastWriteTime.QuadPart = 0ULL; NewKeyCell->LastWriteTime.QuadPart = 0ULL;
NewKeyCell->Parent = Parent; NewKeyCell->Parent = Parent;
NewKeyCell->SubKeyCounts[HvStable] = 0; NewKeyCell->SubKeyCounts[Stable] = 0;
NewKeyCell->SubKeyLists[HvStable] = -1; NewKeyCell->SubKeyLists[Stable] = -1;
NewKeyCell->ValueList.Count = 0; NewKeyCell->ValueList.Count = 0;
NewKeyCell->ValueList.List = -1; NewKeyCell->ValueList.List = -1;
NewKeyCell->SecurityKeyOffset = -1; NewKeyCell->SecurityKeyOffset = -1;
@ -400,7 +400,7 @@ CmiExportSubKey (PHHIVE Hive,
{ {
/* Allocate hash table cell */ /* Allocate hash table cell */
if (!CmiAllocateHashTableCell (Hive, if (!CmiAllocateHashTableCell (Hive,
&NewKeyCell->SubKeyLists[HvStable], &NewKeyCell->SubKeyLists[Stable],
SubKeyCount)) SubKeyCount))
{ {
DbgPrint((DPRINT_REGISTRY, "CmiAllocateHashTableCell() failed\n")); DbgPrint((DPRINT_REGISTRY, "CmiAllocateHashTableCell() failed\n"));
@ -446,7 +446,7 @@ CmiExportHive (PHHIVE Hive,
return FALSE; return FALSE;
} }
KeyCell = HvGetCell (Hive, Hive->HiveHeader->RootCell); KeyCell = (PCM_KEY_NODE)HvGetCell (Hive, Hive->BaseBlock->RootCell);
if (KeyCell == NULL) if (KeyCell == NULL)
{ {
DbgPrint((DPRINT_REGISTRY, "HvGetCell() failed\n")); DbgPrint((DPRINT_REGISTRY, "HvGetCell() failed\n"));
@ -468,7 +468,7 @@ CmiExportHive (PHHIVE Hive,
if (Key->DataSize != 0) if (Key->DataSize != 0)
{ {
if (!CmiExportValue (Hive, Hive->HiveHeader->RootCell, Key, NULL)) if (!CmiExportValue (Hive, Hive->BaseBlock->RootCell, Key, NULL))
return FALSE; return FALSE;
} }
@ -480,7 +480,7 @@ CmiExportHive (PHHIVE Hive,
VALUE, VALUE,
ValueList); ValueList);
if (!CmiExportValue (Hive, Hive->HiveHeader->RootCell, Key, Value)) if (!CmiExportValue (Hive, Hive->BaseBlock->RootCell, Key, Value))
return FALSE; return FALSE;
Entry = Entry->Flink; Entry = Entry->Flink;
@ -493,7 +493,7 @@ CmiExportHive (PHHIVE Hive,
{ {
/* Allocate hash table cell */ /* Allocate hash table cell */
if (!CmiAllocateHashTableCell (Hive, if (!CmiAllocateHashTableCell (Hive,
&KeyCell->SubKeyLists[HvStable], &KeyCell->SubKeyLists[Stable],
SubKeyCount)) SubKeyCount))
{ {
DbgPrint((DPRINT_REGISTRY, "CmiAllocateHashTableCell() failed\n")); DbgPrint((DPRINT_REGISTRY, "CmiAllocateHashTableCell() failed\n"));
@ -508,7 +508,7 @@ CmiExportHive (PHHIVE Hive,
KEY, KEY,
KeyList); KeyList);
if (!CmiExportSubKey (Hive, Hive->HiveHeader->RootCell, Key, SubKey)) if (!CmiExportSubKey (Hive, Hive->BaseBlock->RootCell, Key, SubKey))
return FALSE; return FALSE;
Entry = Entry->Flink; Entry = Entry->Flink;
@ -575,7 +575,7 @@ RegImportValue (PHHIVE Hive,
} }
else else
{ {
DataCell = HvGetCell (Hive, ValueCell->DataOffset); DataCell = (PVOID)HvGetCell (Hive, ValueCell->DataOffset);
DbgPrint((DPRINT_REGISTRY, "DataCell: %x\n", DataCell)); DbgPrint((DPRINT_REGISTRY, "DataCell: %x\n", DataCell));
Error = RegSetValue (Key, Error = RegSetValue (Key,
@ -674,13 +674,13 @@ RegImportSubKey(PHHIVE Hive,
} }
/* Enumerate and add subkeys */ /* Enumerate and add subkeys */
if (KeyCell->SubKeyCounts[HvStable] > 0) if (KeyCell->SubKeyCounts[Stable] > 0)
{ {
HashCell = (PHASH_TABLE_CELL) HvGetCell (Hive, KeyCell->SubKeyLists[HvStable]); HashCell = (PHASH_TABLE_CELL) HvGetCell (Hive, KeyCell->SubKeyLists[Stable]);
DbgPrint((DPRINT_REGISTRY, "HashCell: %x\n", HashCell)); DbgPrint((DPRINT_REGISTRY, "HashCell: %x\n", HashCell));
DbgPrint((DPRINT_REGISTRY, "SubKeyCounts: %x\n", KeyCell->SubKeyCounts)); DbgPrint((DPRINT_REGISTRY, "SubKeyCounts: %x\n", KeyCell->SubKeyCounts));
for (i = 0; i < KeyCell->SubKeyCounts[HvStable]; i++) for (i = 0; i < KeyCell->SubKeyCounts[Stable]; i++)
{ {
DbgPrint((DPRINT_REGISTRY, "KeyOffset[%d]: %x\n", i, HashCell->Table[i].KeyOffset)); DbgPrint((DPRINT_REGISTRY, "KeyOffset[%d]: %x\n", i, HashCell->Table[i].KeyOffset));
@ -713,11 +713,20 @@ RegImportBinaryHive(PCHAR ChunkBase,
DbgPrint((DPRINT_REGISTRY, "RegImportBinaryHive(%x, %u) called\n",ChunkBase,ChunkSize)); DbgPrint((DPRINT_REGISTRY, "RegImportBinaryHive(%x, %u) called\n",ChunkBase,ChunkSize));
CmHive = CmpAllocate(sizeof(EREGISTRY_HIVE), TRUE); CmHive = CmpAllocate(sizeof(EREGISTRY_HIVE), TRUE, 0);
Status = HvInitialize (&CmHive->Hive, HV_OPERATION_MEMORY_INPLACE, 0, 0, Status = HvInitialize (&CmHive->Hive,
(ULONG_PTR)ChunkBase, 0, HINIT_FLAT,
CmpAllocate, CmpFree, 0,
NULL, NULL, NULL, NULL, NULL); 0,
ChunkBase,
CmpAllocate,
CmpFree,
NULL,
NULL,
NULL,
NULL,
1,
NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DbgPrint((DPRINT_REGISTRY, "Invalid hive id!\n")); DbgPrint((DPRINT_REGISTRY, "Invalid hive id!\n"));
@ -725,7 +734,7 @@ RegImportBinaryHive(PCHAR ChunkBase,
} }
Hive = &CmHive->Hive; Hive = &CmHive->Hive;
KeyCell = HvGetCell (Hive, Hive->HiveHeader->RootCell); KeyCell = (PCM_KEY_NODE)HvGetCell (Hive, Hive->BaseBlock->RootCell);
DbgPrint((DPRINT_REGISTRY, "KeyCell: %x\n", KeyCell)); DbgPrint((DPRINT_REGISTRY, "KeyCell: %x\n", KeyCell));
DbgPrint((DPRINT_REGISTRY, "KeyCell->Id: %x\n", KeyCell->Id)); DbgPrint((DPRINT_REGISTRY, "KeyCell->Id: %x\n", KeyCell->Id));
if (KeyCell->Id != REG_KEY_CELL_ID) if (KeyCell->Id != REG_KEY_CELL_ID)
@ -748,17 +757,17 @@ RegImportBinaryHive(PCHAR ChunkBase,
} }
/* Enumerate and add subkeys */ /* Enumerate and add subkeys */
if (KeyCell->SubKeyCounts[HvStable] > 0) if (KeyCell->SubKeyCounts[Stable] > 0)
{ {
HashCell = HvGetCell (Hive, KeyCell->SubKeyLists[HvStable]); HashCell = (PHASH_TABLE_CELL)HvGetCell (Hive, KeyCell->SubKeyLists[Stable]);
DbgPrint((DPRINT_REGISTRY, "HashCell: %x\n", HashCell)); DbgPrint((DPRINT_REGISTRY, "HashCell: %x\n", HashCell));
DbgPrint((DPRINT_REGISTRY, "SubKeyCounts: %x\n", KeyCell->SubKeyCounts[HvStable])); DbgPrint((DPRINT_REGISTRY, "SubKeyCounts: %x\n", KeyCell->SubKeyCounts[Stable]));
for (i = 0; i < KeyCell->SubKeyCounts[HvStable]; i++) for (i = 0; i < KeyCell->SubKeyCounts[Stable]; i++)
{ {
DbgPrint((DPRINT_REGISTRY, "KeyOffset[%d]: %x\n", i, HashCell->Table[i].KeyOffset)); DbgPrint((DPRINT_REGISTRY, "KeyOffset[%d]: %x\n", i, HashCell->Table[i].KeyOffset));
SubKeyCell = HvGetCell (Hive, HashCell->Table[i].KeyOffset); SubKeyCell = (PCM_KEY_NODE)HvGetCell (Hive, HashCell->Table[i].KeyOffset);
DbgPrint((DPRINT_REGISTRY, "SubKeyCell[%d]: %x\n", i, SubKeyCell)); DbgPrint((DPRINT_REGISTRY, "SubKeyCell[%d]: %x\n", i, SubKeyCell));
@ -780,15 +789,15 @@ CmiWriteHive(PHHIVE Hive,
ULONG i, Size; ULONG i, Size;
/* Write hive header */ /* Write hive header */
memcpy (ChunkBase, Hive->HiveHeader, HV_BLOCK_SIZE); memcpy (ChunkBase, Hive->BaseBlock, HV_BLOCK_SIZE);
Size = HV_BLOCK_SIZE; Size = HV_BLOCK_SIZE;
Bin = NULL; Bin = NULL;
for (i = 0; i < Hive->Storage[HvStable].Length; i++) for (i = 0; i < Hive->Storage[Stable].Length; i++)
{ {
if (Hive->Storage[HvStable].BlockList[i].Bin != (ULONG_PTR)Bin) if (Hive->Storage[Stable].BlockList[i].BinAddress != (ULONG_PTR)Bin)
{ {
Bin = (PHBIN)Hive->Storage[HvStable].BlockList[i].Bin; Bin = (PHBIN)Hive->Storage[Stable].BlockList[i].BinAddress;
memcpy (ChunkBase + (i + 1) * HV_BLOCK_SIZE, memcpy (ChunkBase + (i + 1) * HV_BLOCK_SIZE,
Bin, Bin->Size); Bin, Bin->Size);
Size += Bin->Size; Size += Bin->Size;
@ -812,10 +821,20 @@ RegExportBinaryHive(PCWSTR KeyName,
DbgPrint((DPRINT_REGISTRY, "Creating binary hardware hive\n")); DbgPrint((DPRINT_REGISTRY, "Creating binary hardware hive\n"));
CmHive = CmpAllocate(sizeof(EREGISTRY_HIVE), TRUE); CmHive = CmpAllocate(sizeof(EREGISTRY_HIVE), TRUE, 0);
Status = HvInitialize (&CmHive->Hive, HV_OPERATION_CREATE_HIVE, 0, 0, 0, 0, Status = HvInitialize (&CmHive->Hive,
CmpAllocate, CmpFree, HINIT_CREATE,
NULL, NULL, NULL, NULL, NULL); 0,
0,
0,
CmpAllocate,
CmpFree,
NULL,
NULL,
NULL,
NULL,
0,
NULL);
Hive = &CmHive->Hive; Hive = &CmHive->Hive;
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {

View file

@ -33,6 +33,7 @@
#define UNIMPLEMENTED { printf("%s unimplemented\n", __FUNCTION__); exit(1); } #define UNIMPLEMENTED { printf("%s unimplemented\n", __FUNCTION__); exit(1); }
#define ASSERT(x) assert(x) #define ASSERT(x) assert(x)
#define ASSERTMSG(x, m) assert(x)
#define DPRINT if (0) printf #define DPRINT if (0) printf
#define DPRINT1 printf #define DPRINT1 printf
@ -94,7 +95,7 @@ typedef union _LARGE_INTEGER
{ {
DWORD LowPart; DWORD LowPart;
LONG HighPart; LONG HighPart;
} u; };
LONGLONG QuadPart; LONGLONG QuadPart;
} LARGE_INTEGER, *PLARGE_INTEGER; } LARGE_INTEGER, *PLARGE_INTEGER;
@ -124,6 +125,7 @@ typedef const UNICODE_STRING *PCUNICODE_STRING;
#define NT_SUCCESS(x) ((x)>=0) #define NT_SUCCESS(x) ((x)>=0)
#define FIELD_OFFSET(t,f) ((LONG_PTR)&(((t*)0)->f)) #define FIELD_OFFSET(t,f) ((LONG_PTR)&(((t*)0)->f))
#define RTL_CONSTANT_STRING(s) { sizeof(s)-sizeof((s)[0]), sizeof(s), s } #define RTL_CONSTANT_STRING(s) { sizeof(s)-sizeof((s)[0]), sizeof(s), s }
#define CONTAINING_RECORD(address, type, field) ((type *)(((ULONG_PTR)address) - (ULONG_PTR)(&(((type *)0)->field))))
#define RtlZeroMemory(Destination, Length) memset(Destination, 0, Length) #define RtlZeroMemory(Destination, Length) memset(Destination, 0, Length)
#define RtlCopyMemory(Destination, Source, Length) memcpy(Destination, Source, Length) #define RtlCopyMemory(Destination, Source, Length) memcpy(Destination, Source, Length)
#define RtlMoveMemory(Destination, Source, Length) memmove(Destination, Source, Length) #define RtlMoveMemory(Destination, Source, Length) memmove(Destination, Source, Length)

View file

@ -352,6 +352,13 @@ typedef struct _MMSUBSECTION_FLAGS
ULONG SectorEndOffset:12; ULONG SectorEndOffset:12;
} MMSUBSECTION_FLAGS, *PMMSUBSECTION_FLAGS; } MMSUBSECTION_FLAGS, *PMMSUBSECTION_FLAGS;
typedef struct _MMSUBSECTION_FLAGS2
{
ULONG SubsectionAccessed:1;
ULONG SubsectionConverted:1;
ULONG Reserved:30;
} MMSUBSECTION_FLAGS2;
// //
// Control Area Structures // Control Area Structures
// //
@ -403,7 +410,7 @@ typedef struct _LARGE_CONTROL_AREA
} LARGE_CONTROL_AREA, *PLARGE_CONTROL_AREA; } LARGE_CONTROL_AREA, *PLARGE_CONTROL_AREA;
// //
// Subsection // Subsection and Mapped Subsection
// //
typedef struct _SUBSECTION typedef struct _SUBSECTION
{ {
@ -418,9 +425,32 @@ typedef struct _SUBSECTION
PMMPTE SubsectionBase; PMMPTE SubsectionBase;
ULONG UnusedPtes; ULONG UnusedPtes;
ULONG PtesInSubsection; ULONG PtesInSubsection;
struct _SUBSECTION *NextSubSection; struct _SUBSECTION *NextSubsection;
} SUBSECTION, *PSUBSECTION; } SUBSECTION, *PSUBSECTION;
typedef struct _MSUBSECTION
{
PCONTROL_AREA ControlArea;
union
{
ULONG LongFlags;
MMSUBSECTION_FLAGS SubsectionFlags;
} u;
ULONG StartingSector;
ULONG NumberOfFullSectors;
PMMPTE SubsectionBase;
ULONG UnusedPtes;
ULONG PtesInSubsection;
struct _SUBSECTION *NextSubsection;
LIST_ENTRY DereferenceList;
ULONG_PTR NumberOfMappedViews;
union
{
ULONG LongFlags2;
MMSUBSECTION_FLAGS2 SubsectionFlags2;
} u2;
} MSUBSECTION, *PMSUBSECTION;
// //
// Segment Object // Segment Object
// //

View file

@ -60,10 +60,10 @@ typedef struct _CM_KEY_NODE
HCELL_INDEX Parent; HCELL_INDEX Parent;
/* Count of sub keys for the key in this key cell (stable & volatile) */ /* Count of sub keys for the key in this key cell (stable & volatile) */
ULONG SubKeyCounts[HvMaxStorageType]; ULONG SubKeyCounts[HTYPE_COUNT];
/* BlockAddress offset of has table for FIXME: subkeys/values? (stable & volatile) */ /* BlockAddress offset of has table for FIXME: subkeys/values? (stable & volatile) */
HCELL_INDEX SubKeyLists[HvMaxStorageType]; HCELL_INDEX SubKeyLists[HTYPE_COUNT];
CHILD_LIST ValueList; CHILD_LIST ValueList;

View file

@ -17,26 +17,29 @@ CmCreateRootNode(
SIZE_T NameSize; SIZE_T NameSize;
NameSize = wcslen(Name) * sizeof(WCHAR); NameSize = wcslen(Name) * sizeof(WCHAR);
RootCellIndex = HvAllocateCell(Hive, sizeof(CM_KEY_NODE) + NameSize, HvStable); RootCellIndex = HvAllocateCell(Hive,
if (RootCellIndex == HCELL_NULL) sizeof(CM_KEY_NODE) + NameSize,
Stable,
HCELL_NIL);
if (RootCellIndex == HCELL_NIL)
return FALSE; return FALSE;
Hive->HiveHeader->RootCell = RootCellIndex; Hive->BaseBlock->RootCell = RootCellIndex;
Hive->HiveHeader->Checksum = HvpHiveHeaderChecksum(Hive->HiveHeader); Hive->BaseBlock->CheckSum = HvpHiveHeaderChecksum(Hive->BaseBlock);
KeyCell = (PCM_KEY_NODE)HvGetCell(Hive, RootCellIndex); KeyCell = (PCM_KEY_NODE)HvGetCell(Hive, RootCellIndex);
KeyCell->Id = REG_KEY_CELL_ID; KeyCell->Id = REG_KEY_CELL_ID;
KeyCell->Flags = REG_KEY_ROOT_CELL; KeyCell->Flags = REG_KEY_ROOT_CELL;
KeyCell->LastWriteTime.QuadPart = 0; KeyCell->LastWriteTime.QuadPart = 0;
KeyCell->Parent = HCELL_NULL; KeyCell->Parent = HCELL_NIL;
KeyCell->SubKeyCounts[0] = 0; KeyCell->SubKeyCounts[0] = 0;
KeyCell->SubKeyCounts[1] = 0; KeyCell->SubKeyCounts[1] = 0;
KeyCell->SubKeyLists[0] = HCELL_NULL; KeyCell->SubKeyLists[0] = HCELL_NIL;
KeyCell->SubKeyLists[1] = HCELL_NULL; KeyCell->SubKeyLists[1] = HCELL_NIL;
KeyCell->ValueList.Count = 0; KeyCell->ValueList.Count = 0;
KeyCell->ValueList.List = HCELL_NULL; KeyCell->ValueList.List = HCELL_NIL;
KeyCell->SecurityKeyOffset = HCELL_NULL; KeyCell->SecurityKeyOffset = HCELL_NIL;
KeyCell->ClassNameOffset = HCELL_NULL; KeyCell->ClassNameOffset = HCELL_NIL;
KeyCell->NameSize = (USHORT)NameSize; KeyCell->NameSize = (USHORT)NameSize;
KeyCell->ClassSize = 0; KeyCell->ClassSize = 0;
memcpy(KeyCell->Name, Name, NameSize); memcpy(KeyCell->Name, Name, NameSize);
@ -55,15 +58,15 @@ CmpPrepareKey(
ASSERT(KeyCell->Id == REG_KEY_CELL_ID); ASSERT(KeyCell->Id == REG_KEY_CELL_ID);
KeyCell->SubKeyLists[HvVolatile] = HCELL_NULL; KeyCell->SubKeyLists[Volatile] = HCELL_NIL;
KeyCell->SubKeyCounts[HvVolatile] = 0; KeyCell->SubKeyCounts[Volatile] = 0;
/* Enumerate and add subkeys */ /* Enumerate and add subkeys */
if (KeyCell->SubKeyCounts[HvStable] > 0) if (KeyCell->SubKeyCounts[Stable] > 0)
{ {
HashCell = HvGetCell(RegistryHive, KeyCell->SubKeyLists[HvStable]); HashCell = HvGetCell(RegistryHive, KeyCell->SubKeyLists[Stable]);
for (i = 0; i < KeyCell->SubKeyCounts[HvStable]; i++) for (i = 0; i < KeyCell->SubKeyCounts[Stable]; i++)
{ {
SubKeyCell = HvGetCell(RegistryHive, HashCell->Table[i].KeyOffset); SubKeyCell = HvGetCell(RegistryHive, HashCell->Table[i].KeyOffset);
CmpPrepareKey(RegistryHive, SubKeyCell); CmpPrepareKey(RegistryHive, SubKeyCell);
@ -77,6 +80,6 @@ CmPrepareHive(
{ {
PCM_KEY_NODE RootCell; PCM_KEY_NODE RootCell;
RootCell = HvGetCell(RegistryHive, RegistryHive->HiveHeader->RootCell); RootCell = HvGetCell(RegistryHive, RegistryHive->BaseBlock->RootCell);
CmpPrepareKey(RegistryHive, RootCell); CmpPrepareKey(RegistryHive, RootCell);
} }

View file

@ -71,11 +71,13 @@ RtlClearAllBits(
#define ROUND_DOWN(a,b) (((a)/(b))*(b)) #define ROUND_DOWN(a,b) (((a)/(b))*(b))
#endif #endif
#define TAG_CM 0x68742020
#define CMAPI NTAPI #define CMAPI NTAPI
struct _HHIVE; struct _HHIVE;
typedef PVOID (CMAPI *PGET_CELL_ROUTINE)( typedef struct _CELL_DATA* (CMAPI *PGET_CELL_ROUTINE)(
struct _HHIVE *Hive, struct _HHIVE *Hive,
HCELL_INDEX Cell); HCELL_INDEX Cell);
@ -85,39 +87,44 @@ typedef VOID (CMAPI *PRELEASE_CELL_ROUTINE)(
typedef PVOID (CMAPI *PALLOCATE_ROUTINE)( typedef PVOID (CMAPI *PALLOCATE_ROUTINE)(
SIZE_T Size, SIZE_T Size,
BOOLEAN Paged); BOOLEAN Paged,
ULONG Tag);
typedef VOID (CMAPI *PFREE_ROUTINE)( typedef VOID (CMAPI *PFREE_ROUTINE)(
PVOID Ptr); PVOID Ptr,
ULONG Quota);
typedef BOOLEAN (CMAPI *PFILE_READ_ROUTINE)( typedef BOOLEAN (CMAPI *PFILE_READ_ROUTINE)(
struct _HHIVE *RegistryHive, struct _HHIVE *RegistryHive,
ULONG FileType, ULONG FileType,
ULONGLONG FileOffset, PULONG FileOffset,
PVOID Buffer, PVOID Buffer,
SIZE_T BufferLength); SIZE_T BufferLength);
typedef BOOLEAN (CMAPI *PFILE_WRITE_ROUTINE)( typedef BOOLEAN (CMAPI *PFILE_WRITE_ROUTINE)(
struct _HHIVE *RegistryHive, struct _HHIVE *RegistryHive,
ULONG FileType, ULONG FileType,
ULONGLONG FileOffset, PULONG FileOffset,
PVOID Buffer, PVOID Buffer,
SIZE_T BufferLength); SIZE_T BufferLength);
typedef BOOLEAN (CMAPI *PFILE_SET_SIZE_ROUTINE)( typedef BOOLEAN (CMAPI *PFILE_SET_SIZE_ROUTINE)(
struct _HHIVE *RegistryHive, struct _HHIVE *RegistryHive,
ULONG FileType, ULONG FileType,
ULONGLONG FileSize); ULONG FileSize,
ULONG OldfileSize);
typedef BOOLEAN (CMAPI *PFILE_FLUSH_ROUTINE)( typedef BOOLEAN (CMAPI *PFILE_FLUSH_ROUTINE)(
struct _HHIVE *RegistryHive, struct _HHIVE *RegistryHive,
ULONG FileType); ULONG FileType,
PLARGE_INTEGER FileOffset,
ULONG Length);
typedef struct _HMAP_ENTRY typedef struct _HMAP_ENTRY
{ {
ULONG_PTR Bin; ULONG_PTR BlockAddress;
ULONG_PTR Block; ULONG_PTR BinAddress;
struct _CM_VIEW_OF_FILE *CmHive; struct _CM_VIEW_OF_FILE *CmView;
ULONG MemAlloc; ULONG MemAlloc;
} HMAP_ENTRY, *PHMAP_ENTRY; } HMAP_ENTRY, *PHMAP_ENTRY;
@ -153,7 +160,7 @@ typedef struct _HHIVE
PFILE_WRITE_ROUTINE FileWrite; PFILE_WRITE_ROUTINE FileWrite;
PFILE_SET_SIZE_ROUTINE FileSetSize; PFILE_SET_SIZE_ROUTINE FileSetSize;
PFILE_FLUSH_ROUTINE FileFlush; PFILE_FLUSH_ROUTINE FileFlush;
PHBASE_BLOCK HiveHeader; PHBASE_BLOCK BaseBlock;
RTL_BITMAP DirtyVector; RTL_BITMAP DirtyVector;
ULONG DirtyCount; ULONG DirtyCount;
ULONG DirtyAlloc; ULONG DirtyAlloc;
@ -172,7 +179,7 @@ typedef struct _HHIVE
ULONG RefreshCount; ULONG RefreshCount;
ULONG StorageTypeCount; ULONG StorageTypeCount;
ULONG Version; ULONG Version;
DUAL Storage[HvMaxStorageType]; DUAL Storage[HTYPE_COUNT];
} HHIVE, *PHHIVE; } HHIVE, *PHHIVE;
#ifndef _CM_ #ifndef _CM_
@ -192,27 +199,21 @@ typedef struct _EREGISTRY_HIVE
/* /*
* Public functions. * Public functions.
*/ */
#define HV_OPERATION_CREATE_HIVE 0
#define HV_OPERATION_MEMORY 1
#define HV_OPERATION_MEMORY_INPLACE 3
NTSTATUS CMAPI NTSTATUS CMAPI
HvInitialize( HvInitialize(
PHHIVE RegistryHive, PHHIVE RegistryHive,
ULONG Operation, ULONG Operation,
ULONG HiveType, ULONG HiveType,
ULONG HiveFlags, ULONG HiveFlags,
ULONG_PTR HiveData OPTIONAL, PVOID HiveData OPTIONAL,
ULONG Cluster OPTIONAL,
PALLOCATE_ROUTINE Allocate, PALLOCATE_ROUTINE Allocate,
PFREE_ROUTINE Free, PFREE_ROUTINE Free,
PFILE_READ_ROUTINE FileRead,
PFILE_WRITE_ROUTINE FileWrite,
PFILE_SET_SIZE_ROUTINE FileSetSize, PFILE_SET_SIZE_ROUTINE FileSetSize,
PFILE_WRITE_ROUTINE FileWrite,
PFILE_READ_ROUTINE FileRead,
PFILE_FLUSH_ROUTINE FileFlush, PFILE_FLUSH_ROUTINE FileFlush,
IN const /*CONST*/ UNICODE_STRING* FileName); ULONG Cluster OPTIONAL,
/* NOTE: Can not use CONST here, as this file is used from user-mode too */ PUNICODE_STRING FileName);
VOID CMAPI VOID CMAPI
HvFree( HvFree(
@ -235,7 +236,8 @@ HCELL_INDEX CMAPI
HvAllocateCell( HvAllocateCell(
PHHIVE RegistryHive, PHHIVE RegistryHive,
SIZE_T Size, SIZE_T Size,
HV_STORAGE_TYPE Storage); HSTORAGE_TYPE Storage,
IN HCELL_INDEX Vicinity);
BOOLEAN CMAPI BOOLEAN CMAPI
HvIsCellAllocated( HvIsCellAllocated(
@ -254,10 +256,11 @@ HvFreeCell(
PHHIVE RegistryHive, PHHIVE RegistryHive,
HCELL_INDEX CellOffset); HCELL_INDEX CellOffset);
VOID CMAPI BOOLEAN CMAPI
HvMarkCellDirty( HvMarkCellDirty(
PHHIVE RegistryHive, PHHIVE RegistryHive,
HCELL_INDEX CellOffset); HCELL_INDEX CellOffset,
BOOLEAN HoldingLock);
BOOLEAN CMAPI BOOLEAN CMAPI
HvIsCellDirty( HvIsCellDirty(
@ -290,7 +293,7 @@ PHBIN CMAPI
HvpAddBin( HvpAddBin(
PHHIVE RegistryHive, PHHIVE RegistryHive,
ULONG Size, ULONG Size,
HV_STORAGE_TYPE Storage); HSTORAGE_TYPE Storage);
NTSTATUS CMAPI NTSTATUS CMAPI
HvpCreateHiveFreeCellList( HvpCreateHiveFreeCellList(

View file

@ -12,7 +12,7 @@ PHBIN CMAPI
HvpAddBin( HvpAddBin(
PHHIVE RegistryHive, PHHIVE RegistryHive,
ULONG Size, ULONG Size,
HV_STORAGE_TYPE Storage) HSTORAGE_TYPE Storage)
{ {
PHMAP_ENTRY BlockList; PHMAP_ENTRY BlockList;
PHBIN Bin; PHBIN Bin;
@ -26,7 +26,7 @@ HvpAddBin(
BinSize = ROUND_UP(Size + sizeof(HBIN), HV_BLOCK_SIZE); BinSize = ROUND_UP(Size + sizeof(HBIN), HV_BLOCK_SIZE);
BlockCount = (ULONG)(BinSize / HV_BLOCK_SIZE); BlockCount = (ULONG)(BinSize / HV_BLOCK_SIZE);
Bin = RegistryHive->Allocate(BinSize, TRUE); Bin = RegistryHive->Allocate(BinSize, TRUE, TAG_CM);
if (Bin == NULL) if (Bin == NULL)
return NULL; return NULL;
RtlZeroMemory(Bin, BinSize); RtlZeroMemory(Bin, BinSize);
@ -39,10 +39,12 @@ HvpAddBin(
/* Allocate new block list */ /* Allocate new block list */
OldBlockListSize = RegistryHive->Storage[Storage].Length; OldBlockListSize = RegistryHive->Storage[Storage].Length;
BlockList = RegistryHive->Allocate(sizeof(HMAP_ENTRY) * BlockList = RegistryHive->Allocate(sizeof(HMAP_ENTRY) *
(OldBlockListSize + BlockCount), TRUE); (OldBlockListSize + BlockCount),
TRUE,
TAG_CM);
if (BlockList == NULL) if (BlockList == NULL)
{ {
RegistryHive->Free(Bin); RegistryHive->Free(Bin, 0);
return NULL; return NULL;
} }
@ -50,7 +52,7 @@ HvpAddBin(
{ {
RtlCopyMemory(BlockList, RegistryHive->Storage[Storage].BlockList, RtlCopyMemory(BlockList, RegistryHive->Storage[Storage].BlockList,
OldBlockListSize * sizeof(HMAP_ENTRY)); OldBlockListSize * sizeof(HMAP_ENTRY));
RegistryHive->Free(RegistryHive->Storage[Storage].BlockList); RegistryHive->Free(RegistryHive->Storage[Storage].BlockList, 0);
} }
RegistryHive->Storage[Storage].BlockList = BlockList; RegistryHive->Storage[Storage].BlockList = BlockList;
@ -58,19 +60,19 @@ HvpAddBin(
for (i = 0; i < BlockCount; i++) for (i = 0; i < BlockCount; i++)
{ {
RegistryHive->Storage[Storage].BlockList[OldBlockListSize + i].Block = RegistryHive->Storage[Storage].BlockList[OldBlockListSize + i].BlockAddress =
((ULONG_PTR)Bin + (i * HV_BLOCK_SIZE)); ((ULONG_PTR)Bin + (i * HV_BLOCK_SIZE));
RegistryHive->Storage[Storage].BlockList[OldBlockListSize + i].Bin = (ULONG_PTR)Bin; RegistryHive->Storage[Storage].BlockList[OldBlockListSize + i].BinAddress = (ULONG_PTR)Bin;
} }
/* Initialize a free block in this heap. */ /* Initialize a free block in this heap. */
Block = (PHCELL)(Bin + 1); Block = (PHCELL)(Bin + 1);
Block->Size = (LONG)(BinSize - sizeof(HBIN)); Block->Size = (LONG)(BinSize - sizeof(HBIN));
if (Storage == HvStable) if (Storage == Stable)
{ {
/* Calculate bitmap size in bytes (always a multiple of 32 bits). */ /* Calculate bitmap size in bytes (always a multiple of 32 bits). */
BitmapSize = ROUND_UP(RegistryHive->Storage[HvStable].Length, BitmapSize = ROUND_UP(RegistryHive->Storage[Stable].Length,
sizeof(ULONG) * 8) / 8; sizeof(ULONG) * 8) / 8;
/* Grow bitmap if necessary. */ /* Grow bitmap if necessary. */
@ -78,7 +80,7 @@ HvpAddBin(
{ {
PULONG BitmapBuffer; PULONG BitmapBuffer;
BitmapBuffer = RegistryHive->Allocate(BitmapSize, TRUE); BitmapBuffer = RegistryHive->Allocate(BitmapSize, TRUE, TAG_CM);
RtlZeroMemory(BitmapBuffer, BitmapSize); RtlZeroMemory(BitmapBuffer, BitmapSize);
if (RegistryHive->DirtyVector.SizeOfBitMap > 0) if (RegistryHive->DirtyVector.SizeOfBitMap > 0)
{ {
@ -86,7 +88,7 @@ HvpAddBin(
RtlCopyMemory(BitmapBuffer, RtlCopyMemory(BitmapBuffer,
RegistryHive->DirtyVector.Buffer, RegistryHive->DirtyVector.Buffer,
RegistryHive->DirtyVector.SizeOfBitMap / 8); RegistryHive->DirtyVector.SizeOfBitMap / 8);
RegistryHive->Free(RegistryHive->DirtyVector.Buffer); RegistryHive->Free(RegistryHive->DirtyVector.Buffer, 0);
} }
RtlInitializeBitMap(&RegistryHive->DirtyVector, BitmapBuffer, RtlInitializeBitMap(&RegistryHive->DirtyVector, BitmapBuffer,
BitmapSize * 8); BitmapSize * 8);

View file

@ -16,7 +16,7 @@ HvpGetCellHeader(
{ {
PVOID Block; PVOID Block;
ASSERT(CellIndex != HCELL_NULL); ASSERT(CellIndex != HCELL_NIL);
if (!RegistryHive->Flat) if (!RegistryHive->Flat)
{ {
ULONG CellType; ULONG CellType;
@ -27,14 +27,14 @@ HvpGetCellHeader(
CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT; CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
CellOffset = (CellIndex & HCELL_OFFSET_MASK) >> HCELL_OFFSET_SHIFT; CellOffset = (CellIndex & HCELL_OFFSET_MASK) >> HCELL_OFFSET_SHIFT;
ASSERT(CellBlock < RegistryHive->Storage[CellType].Length); ASSERT(CellBlock < RegistryHive->Storage[CellType].Length);
Block = (PVOID)RegistryHive->Storage[CellType].BlockList[CellBlock].Block; Block = (PVOID)RegistryHive->Storage[CellType].BlockList[CellBlock].BlockAddress;
ASSERT(Block != NULL); ASSERT(Block != NULL);
return (PVOID)((ULONG_PTR)Block + CellOffset); return (PVOID)((ULONG_PTR)Block + CellOffset);
} }
else else
{ {
ASSERT((CellIndex & HCELL_TYPE_MASK) == HvStable); ASSERT((CellIndex & HCELL_TYPE_MASK) == Stable);
return (PVOID)((ULONG_PTR)RegistryHive->HiveHeader + HV_BLOCK_SIZE + return (PVOID)((ULONG_PTR)RegistryHive->BaseBlock + HV_BLOCK_SIZE +
CellIndex); CellIndex);
} }
} }
@ -59,7 +59,7 @@ HvIsCellAllocated(IN PHHIVE RegistryHive,
/* Try to get the cell block */ /* Try to get the cell block */
Block = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT; Block = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
if (RegistryHive->Storage[Type].BlockList[Block].Block) return TRUE; if (RegistryHive->Storage[Type].BlockList[Block].BlockAddress) return TRUE;
/* No valid block, fail */ /* No valid block, fail */
return FALSE; return FALSE;
@ -94,10 +94,11 @@ HvGetCellSize(IN PHHIVE Hive,
return Size; return Size;
} }
VOID CMAPI BOOLEAN CMAPI
HvMarkCellDirty( HvMarkCellDirty(
PHHIVE RegistryHive, PHHIVE RegistryHive,
HCELL_INDEX CellIndex) HCELL_INDEX CellIndex,
BOOLEAN HoldingLock)
{ {
LONG CellSize; LONG CellSize;
ULONG CellBlock; ULONG CellBlock;
@ -105,8 +106,8 @@ HvMarkCellDirty(
ASSERT(RegistryHive->ReadOnly == FALSE); ASSERT(RegistryHive->ReadOnly == FALSE);
if ((CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT != HvStable) if ((CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT != Stable)
return; return FALSE;
CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT; CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
CellLastBlock = ((CellIndex + HV_BLOCK_SIZE - 1) & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT; CellLastBlock = ((CellIndex + HV_BLOCK_SIZE - 1) & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
@ -117,6 +118,7 @@ HvMarkCellDirty(
RtlSetBits(&RegistryHive->DirtyVector, RtlSetBits(&RegistryHive->DirtyVector,
CellBlock, CellLastBlock - CellBlock); CellBlock, CellLastBlock - CellBlock);
return TRUE;
} }
BOOLEAN CMAPI BOOLEAN CMAPI
@ -127,7 +129,7 @@ HvIsCellDirty(IN PHHIVE Hive,
ASSERT(Hive->ReadOnly == FALSE); ASSERT(Hive->ReadOnly == FALSE);
/* Volatile cells are always "dirty" */ /* Volatile cells are always "dirty" */
if (HvGetCellType(Cell) == HvVolatile) return TRUE; if (HvGetCellType(Cell) == Volatile) return TRUE;
/* Check if the dirty bit is set */ /* Check if the dirty bit is set */
return RtlCheckBit(&Hive->DirtyVector, Cell / HV_BLOCK_SIZE); return RtlCheckBit(&Hive->DirtyVector, Cell / HV_BLOCK_SIZE);
@ -175,7 +177,7 @@ HvpAddFree(
HCELL_INDEX FreeIndex) HCELL_INDEX FreeIndex)
{ {
PHCELL_INDEX FreeBlockData; PHCELL_INDEX FreeBlockData;
HV_STORAGE_TYPE Storage; HSTORAGE_TYPE Storage;
ULONG Index; ULONG Index;
ASSERT(RegistryHive != NULL); ASSERT(RegistryHive != NULL);
@ -201,7 +203,7 @@ HvpRemoveFree(
{ {
PHCELL_INDEX FreeCellData; PHCELL_INDEX FreeCellData;
PHCELL_INDEX pFreeCellOffset; PHCELL_INDEX pFreeCellOffset;
HV_STORAGE_TYPE Storage; HSTORAGE_TYPE Storage;
ULONG Index; ULONG Index;
ASSERT(RegistryHive->ReadOnly == FALSE); ASSERT(RegistryHive->ReadOnly == FALSE);
@ -210,7 +212,7 @@ HvpRemoveFree(
Index = HvpComputeFreeListIndex((ULONG)CellBlock->Size); Index = HvpComputeFreeListIndex((ULONG)CellBlock->Size);
pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[Index]; pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[Index];
while (*pFreeCellOffset != HCELL_NULL) while (*pFreeCellOffset != HCELL_NIL)
{ {
FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset); FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset);
if (*pFreeCellOffset == CellIndex) if (*pFreeCellOffset == CellIndex)
@ -228,7 +230,7 @@ static HCELL_INDEX CMAPI
HvpFindFree( HvpFindFree(
PHHIVE RegistryHive, PHHIVE RegistryHive,
ULONG Size, ULONG Size,
HV_STORAGE_TYPE Storage) HSTORAGE_TYPE Storage)
{ {
PHCELL_INDEX FreeCellData; PHCELL_INDEX FreeCellData;
HCELL_INDEX FreeCellOffset; HCELL_INDEX FreeCellOffset;
@ -238,7 +240,7 @@ HvpFindFree(
for (Index = HvpComputeFreeListIndex(Size); Index < 24; Index++) for (Index = HvpComputeFreeListIndex(Size); Index < 24; Index++)
{ {
pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[Index]; pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[Index];
while (*pFreeCellOffset != HCELL_NULL) while (*pFreeCellOffset != HCELL_NIL)
{ {
FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset); FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset);
if ((ULONG)HvpGetCellFullSize(RegistryHive, FreeCellData) >= Size) if ((ULONG)HvpGetCellFullSize(RegistryHive, FreeCellData) >= Size)
@ -251,7 +253,7 @@ HvpFindFree(
} }
} }
return HCELL_NULL; return HCELL_NIL;
} }
NTSTATUS CMAPI NTSTATUS CMAPI
@ -269,15 +271,15 @@ HvpCreateHiveFreeCellList(
/* Initialize the free cell list */ /* Initialize the free cell list */
for (Index = 0; Index < 24; Index++) for (Index = 0; Index < 24; Index++)
{ {
Hive->Storage[HvStable].FreeDisplay[Index] = HCELL_NULL; Hive->Storage[Stable].FreeDisplay[Index] = HCELL_NIL;
Hive->Storage[HvVolatile].FreeDisplay[Index] = HCELL_NULL; Hive->Storage[Volatile].FreeDisplay[Index] = HCELL_NIL;
} }
BlockOffset = 0; BlockOffset = 0;
BlockIndex = 0; BlockIndex = 0;
while (BlockIndex < Hive->Storage[HvStable].Length) while (BlockIndex < Hive->Storage[Stable].Length)
{ {
Bin = (PHBIN)Hive->Storage[HvStable].BlockList[BlockIndex].Bin; Bin = (PHBIN)Hive->Storage[Stable].BlockList[BlockIndex].BinAddress;
/* Search free blocks and add to list */ /* Search free blocks and add to list */
FreeOffset = sizeof(HBIN); FreeOffset = sizeof(HBIN);
@ -309,7 +311,8 @@ HCELL_INDEX CMAPI
HvAllocateCell( HvAllocateCell(
PHHIVE RegistryHive, PHHIVE RegistryHive,
SIZE_T Size, SIZE_T Size,
HV_STORAGE_TYPE Storage) HSTORAGE_TYPE Storage,
HCELL_INDEX Vicinity)
{ {
PHCELL FreeCell; PHCELL FreeCell;
HCELL_INDEX FreeCellOffset; HCELL_INDEX FreeCellOffset;
@ -325,11 +328,11 @@ HvAllocateCell(
FreeCellOffset = HvpFindFree(RegistryHive, Size, Storage); FreeCellOffset = HvpFindFree(RegistryHive, Size, Storage);
/* If no free cell was found we need to extend the hive file. */ /* If no free cell was found we need to extend the hive file. */
if (FreeCellOffset == HCELL_NULL) if (FreeCellOffset == HCELL_NIL)
{ {
Bin = HvpAddBin(RegistryHive, Size, Storage); Bin = HvpAddBin(RegistryHive, Size, Storage);
if (Bin == NULL) if (Bin == NULL)
return HCELL_NULL; return HCELL_NIL;
FreeCellOffset = Bin->FileOffset + sizeof(HBIN); FreeCellOffset = Bin->FileOffset + sizeof(HBIN);
FreeCellOffset |= Storage << HCELL_TYPE_SHIFT; FreeCellOffset |= Storage << HCELL_TYPE_SHIFT;
} }
@ -344,12 +347,12 @@ HvAllocateCell(
NewCell->Size = FreeCell->Size - Size; NewCell->Size = FreeCell->Size - Size;
FreeCell->Size = Size; FreeCell->Size = Size;
HvpAddFree(RegistryHive, NewCell, FreeCellOffset + Size); HvpAddFree(RegistryHive, NewCell, FreeCellOffset + Size);
if (Storage == HvStable) if (Storage == Stable)
HvMarkCellDirty(RegistryHive, FreeCellOffset + Size); HvMarkCellDirty(RegistryHive, FreeCellOffset + Size, FALSE);
} }
if (Storage == HvStable) if (Storage == Stable)
HvMarkCellDirty(RegistryHive, FreeCellOffset); HvMarkCellDirty(RegistryHive, FreeCellOffset, FALSE);
FreeCell->Size = -FreeCell->Size; FreeCell->Size = -FreeCell->Size;
RtlZeroMemory(FreeCell + 1, Size - sizeof(HCELL)); RtlZeroMemory(FreeCell + 1, Size - sizeof(HCELL));
@ -366,9 +369,9 @@ HvReallocateCell(
PVOID NewCell; PVOID NewCell;
LONG OldCellSize; LONG OldCellSize;
HCELL_INDEX NewCellIndex; HCELL_INDEX NewCellIndex;
HV_STORAGE_TYPE Storage; HSTORAGE_TYPE Storage;
ASSERT(CellIndex != HCELL_NULL); ASSERT(CellIndex != HCELL_NIL);
Storage = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT; Storage = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
@ -385,9 +388,9 @@ HvReallocateCell(
*/ */
if (Size > OldCellSize) if (Size > OldCellSize)
{ {
NewCellIndex = HvAllocateCell(RegistryHive, Size, Storage); NewCellIndex = HvAllocateCell(RegistryHive, Size, Storage, HCELL_NIL);
if (NewCellIndex == HCELL_NULL) if (NewCellIndex == HCELL_NIL)
return HCELL_NULL; return HCELL_NIL;
NewCell = HvGetCell(RegistryHive, NewCellIndex); NewCell = HvGetCell(RegistryHive, NewCellIndex);
RtlCopyMemory(NewCell, OldCell, (SIZE_T)OldCellSize); RtlCopyMemory(NewCell, OldCell, (SIZE_T)OldCellSize);
@ -423,7 +426,7 @@ HvFreeCell(
CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT; CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
/* FIXME: Merge free blocks */ /* FIXME: Merge free blocks */
Bin = (PHBIN)RegistryHive->Storage[CellType].BlockList[CellBlock].Bin; Bin = (PHBIN)RegistryHive->Storage[CellType].BlockList[CellBlock].BinAddress;
if ((CellIndex & ~HCELL_TYPE_MASK) + Free->Size < if ((CellIndex & ~HCELL_TYPE_MASK) + Free->Size <
Bin->FileOffset + Bin->Size) Bin->FileOffset + Bin->Size)
@ -446,10 +449,10 @@ HvFreeCell(
if ((ULONG_PTR)Neighbor + Neighbor->Size == (ULONG_PTR)Free) if ((ULONG_PTR)Neighbor + Neighbor->Size == (ULONG_PTR)Free)
{ {
Neighbor->Size += Free->Size; Neighbor->Size += Free->Size;
if (CellType == HvStable) if (CellType == Stable)
HvMarkCellDirty(RegistryHive, HvMarkCellDirty(RegistryHive,
(HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin + (HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin +
Bin->FileOffset)); Bin->FileOffset), FALSE);
return; return;
} }
Neighbor = (PHCELL)((ULONG_PTR)Neighbor + Neighbor->Size); Neighbor = (PHCELL)((ULONG_PTR)Neighbor + Neighbor->Size);
@ -463,6 +466,6 @@ HvFreeCell(
/* Add block to the list of free blocks */ /* Add block to the list of free blocks */
HvpAddFree(RegistryHive, Free, CellIndex); HvpAddFree(RegistryHive, Free, CellIndex);
if (CellType == HvStable) if (CellType == Stable)
HvMarkCellDirty(RegistryHive, CellIndex); HvMarkCellDirty(RegistryHive, CellIndex, FALSE);
} }

View file

@ -8,20 +8,62 @@
#ifndef CMLIB_HIVEDATA_H #ifndef CMLIB_HIVEDATA_H
#define CMLIB_HIVEDATA_H #define CMLIB_HIVEDATA_H
//
// Hive operations
//
#define HINIT_CREATE 0
#define HINIT_MEMORY 1
#define HINIT_FILE 2
#define HINIT_MEMORY_INPLACE 3
#define HINIT_FLAT 4
#define HINIT_MAPFILE 5
//
// Hive flags
//
#define HIVE_VOLATILE 1
#define HIVE_NOLAZYFLUSH 2
#define HIVE_HAS_BEEN_REPLACED 4
//
// Hive types
//
#define HFILE_TYPE_PRIMARY 0
#define HFILE_TYPE_ALTERNATE 1
#define HFILE_TYPE_LOG 2
#define HFILE_TYPE_EXTERNAL 3
#define HFILE_TYPE_MAX 4
//
// Hive sizes
//
#define HBLOCK_SIZE 0x1000
#define HSECTOR_SIZE 0x200
#define HSECTOR_COUNT 8
#define HV_BLOCK_SIZE 4096 #define HV_BLOCK_SIZE 4096
#define HV_LOG_HEADER_SIZE FIELD_OFFSET(HBASE_BLOCK, Reserved2) #define HV_LOG_HEADER_SIZE FIELD_OFFSET(HBASE_BLOCK, Reserved2)
#define HV_SIGNATURE 0x66676572 #define HV_SIGNATURE 0x66676572
#define HV_BIN_SIGNATURE 0x6e696268 #define HV_BIN_SIGNATURE 0x6e696268
#define HV_MAJOR_VER 1 //
#define HV_MINOR_VER 3 // Hive versions
#define HV_FORMAT_MEMORY 1 //
#define HSYS_MAJOR 1
#define HSYS_MINOR 3
#define HSYS_WHISTLER_BETA1 4
#define HSYS_WHISTLER 5
#define HSYS_MINOR_SUPPORTED HSYS_WHISTLER
#define HV_TYPE_PRIMARY 0 //
#define HV_TYPE_ALTERNATE 1 // Hive formats
#define HV_TYPE_LOG 2 //
#define HV_TYPE_EXTERNAL 3 #define HBASE_FORMAT_MEMORY 1
#define HV_TYPE_MAX 4
//
// Hive storage
//
#define HTYPE_COUNT 2
/** /**
* @name HCELL_INDEX * @name HCELL_INDEX
@ -32,7 +74,12 @@
*/ */
typedef ULONG HCELL_INDEX, *PHCELL_INDEX; typedef ULONG HCELL_INDEX, *PHCELL_INDEX;
#define HCELL_NULL ((HCELL_INDEX)-1) //
// Cell Magic Values
//
#define HCELL_NIL -1
#define HCELL_CACHED 1
#define HCELL_TYPE_MASK 0x80000000 #define HCELL_TYPE_MASK 0x80000000
#define HCELL_BLOCK_MASK 0x7ffff000 #define HCELL_BLOCK_MASK 0x7ffff000
#define HCELL_OFFSET_MASK 0x00000fff #define HCELL_OFFSET_MASK 0x00000fff
@ -43,6 +90,12 @@ typedef ULONG HCELL_INDEX, *PHCELL_INDEX;
#define HvGetCellType(Cell) \ #define HvGetCellType(Cell) \
((ULONG)((Cell & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT)) ((ULONG)((Cell & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT))
typedef enum
{
Stable = 0,
Volatile = 1
} HSTORAGE_TYPE;
#ifdef CMLIB_HOST #ifdef CMLIB_HOST
#include <host/pshpack1.h> #include <host/pshpack1.h>
#else #else
@ -98,7 +151,7 @@ typedef struct _HBASE_BLOCK
ULONG Reserved1[99]; ULONG Reserved1[99];
/* Checksum of first 0x200 bytes */ /* Checksum of first 0x200 bytes */
ULONG Checksum; ULONG CheckSum;
ULONG Reserved2[0x37E]; ULONG Reserved2[0x37E];
ULONG BootType; ULONG BootType;
@ -122,7 +175,7 @@ typedef struct _HBIN
LARGE_INTEGER TimeStamp; LARGE_INTEGER TimeStamp;
/* ? (In-memory only) */ /* ? (In-memory only) */
ULONG MemAlloc; ULONG Spare;
} HBIN, *PHBIN; } HBIN, *PHBIN;
typedef struct _HCELL typedef struct _HCELL
@ -140,11 +193,4 @@ typedef struct _HCELL
#define IsFreeCell(Cell)(Cell->Size >= 0) #define IsFreeCell(Cell)(Cell->Size >= 0)
#define IsUsedCell(Cell)(Cell->Size < 0) #define IsUsedCell(Cell)(Cell->Size < 0)
typedef enum _HV_STORAGE_TYPE
{
HvStable = 0,
HvVolatile,
HvMaxStorageType
} HV_STORAGE_TYPE;
#endif /* CMLIB_HIVEDATA_H */ #endif /* CMLIB_HIVEDATA_H */

View file

@ -17,27 +17,27 @@
BOOLEAN CMAPI BOOLEAN CMAPI
HvpVerifyHiveHeader( HvpVerifyHiveHeader(
PHBASE_BLOCK HiveHeader) PHBASE_BLOCK BaseBlock)
{ {
if (HiveHeader->Signature != HV_SIGNATURE || if (BaseBlock->Signature != HV_SIGNATURE ||
HiveHeader->Major != HV_MAJOR_VER || BaseBlock->Major != HSYS_MAJOR ||
HiveHeader->Minor < HV_MINOR_VER || BaseBlock->Minor < HSYS_MINOR ||
HiveHeader->Type != HV_TYPE_PRIMARY || BaseBlock->Type != HFILE_TYPE_PRIMARY ||
HiveHeader->Format != HV_FORMAT_MEMORY || BaseBlock->Format != HBASE_FORMAT_MEMORY ||
HiveHeader->Cluster != 1 || BaseBlock->Cluster != 1 ||
HiveHeader->Sequence1 != HiveHeader->Sequence2 || BaseBlock->Sequence1 != BaseBlock->Sequence2 ||
HvpHiveHeaderChecksum(HiveHeader) != HiveHeader->Checksum) HvpHiveHeaderChecksum(BaseBlock) != BaseBlock->CheckSum)
{ {
DPRINT1("Verify Hive Header failed: \n"); DPRINT1("Verify Hive Header failed: \n");
DPRINT1(" Signature: 0x%x and not 0x%x, Major: 0x%x and not 0x%x\n", DPRINT1(" Signature: 0x%x and not 0x%x, Major: 0x%x and not 0x%x\n",
HiveHeader->Signature, HV_SIGNATURE, HiveHeader->Major, HV_MAJOR_VER); BaseBlock->Signature, HV_SIGNATURE, BaseBlock->Major, HSYS_MAJOR);
DPRINT1(" Minor: 0x%x is not >= 0x%x, Type: 0x%x and not 0x%x\n", DPRINT1(" Minor: 0x%x is not >= 0x%x, Type: 0x%x and not 0x%x\n",
HiveHeader->Minor, HV_MINOR_VER, HiveHeader->Type, HV_TYPE_PRIMARY); BaseBlock->Minor, HSYS_MINOR, BaseBlock->Type, HFILE_TYPE_PRIMARY);
DPRINT1(" Format: 0x%x and not 0x%x, Cluster: 0x%x and not 1\n", DPRINT1(" Format: 0x%x and not 0x%x, Cluster: 0x%x and not 1\n",
HiveHeader->Format, HV_FORMAT_MEMORY, HiveHeader->Cluster); BaseBlock->Format, HBASE_FORMAT_MEMORY, BaseBlock->Cluster);
DPRINT1(" Sequence: 0x%x and not 0x%x, Checksum: 0x%x and not 0x%x\n", DPRINT1(" Sequence: 0x%x and not 0x%x, Checksum: 0x%x and not 0x%x\n",
HiveHeader->Sequence1, HiveHeader->Sequence2, BaseBlock->Sequence1, BaseBlock->Sequence2,
HvpHiveHeaderChecksum(HiveHeader), HiveHeader->Checksum); HvpHiveHeaderChecksum(BaseBlock), BaseBlock->CheckSum);
return FALSE; return FALSE;
} }
@ -59,24 +59,24 @@ HvpFreeHiveBins(
PHBIN Bin; PHBIN Bin;
ULONG Storage; ULONG Storage;
for (Storage = HvStable; Storage < HvMaxStorageType; Storage++) for (Storage = Stable; Storage < HTYPE_COUNT; Storage++)
{ {
Bin = NULL; Bin = NULL;
for (i = 0; i < Hive->Storage[Storage].Length; i++) for (i = 0; i < Hive->Storage[Storage].Length; i++)
{ {
if (Hive->Storage[Storage].BlockList[i].Bin == (ULONG_PTR)NULL) if (Hive->Storage[Storage].BlockList[i].BinAddress == (ULONG_PTR)NULL)
continue; continue;
if (Hive->Storage[Storage].BlockList[i].Bin != (ULONG_PTR)Bin) if (Hive->Storage[Storage].BlockList[i].BinAddress != (ULONG_PTR)Bin)
{ {
Bin = (PHBIN)Hive->Storage[Storage].BlockList[i].Bin; Bin = (PHBIN)Hive->Storage[Storage].BlockList[i].BinAddress;
Hive->Free((PHBIN)Hive->Storage[Storage].BlockList[i].Bin); Hive->Free((PHBIN)Hive->Storage[Storage].BlockList[i].BinAddress, 0);
} }
Hive->Storage[Storage].BlockList[i].Bin = (ULONG_PTR)NULL; Hive->Storage[Storage].BlockList[i].BinAddress = (ULONG_PTR)NULL;
Hive->Storage[Storage].BlockList[i].Block = (ULONG_PTR)NULL; Hive->Storage[Storage].BlockList[i].BlockAddress = (ULONG_PTR)NULL;
} }
if (Hive->Storage[Storage].Length) if (Hive->Storage[Storage].Length)
Hive->Free(Hive->Storage[Storage].BlockList); Hive->Free(Hive->Storage[Storage].BlockList, 0);
} }
} }
@ -93,31 +93,31 @@ NTSTATUS CMAPI
HvpCreateHive( HvpCreateHive(
PHHIVE RegistryHive) PHHIVE RegistryHive)
{ {
PHBASE_BLOCK HiveHeader; PHBASE_BLOCK BaseBlock;
ULONG Index; ULONG Index;
HiveHeader = RegistryHive->Allocate(sizeof(HBASE_BLOCK), FALSE); BaseBlock = RegistryHive->Allocate(sizeof(HBASE_BLOCK), FALSE, TAG_CM);
if (HiveHeader == NULL) if (BaseBlock == NULL)
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
RtlZeroMemory(HiveHeader, sizeof(HBASE_BLOCK)); RtlZeroMemory(BaseBlock, sizeof(HBASE_BLOCK));
HiveHeader->Signature = HV_SIGNATURE; BaseBlock->Signature = HV_SIGNATURE;
HiveHeader->Major = HV_MAJOR_VER; BaseBlock->Major = HSYS_MAJOR;
HiveHeader->Minor = HV_MINOR_VER; BaseBlock->Minor = HSYS_MINOR;
HiveHeader->Type = HV_TYPE_PRIMARY; BaseBlock->Type = HFILE_TYPE_PRIMARY;
HiveHeader->Format = HV_FORMAT_MEMORY; BaseBlock->Format = HBASE_FORMAT_MEMORY;
HiveHeader->Cluster = 1; BaseBlock->Cluster = 1;
HiveHeader->RootCell = HCELL_NULL; BaseBlock->RootCell = HCELL_NIL;
HiveHeader->Length = HV_BLOCK_SIZE; BaseBlock->Length = HV_BLOCK_SIZE;
HiveHeader->Sequence1 = 1; BaseBlock->Sequence1 = 1;
HiveHeader->Sequence2 = 1; BaseBlock->Sequence2 = 1;
/* FIXME: Fill in the file name */ /* FIXME: Fill in the file name */
HiveHeader->Checksum = HvpHiveHeaderChecksum(HiveHeader); BaseBlock->CheckSum = HvpHiveHeaderChecksum(BaseBlock);
RegistryHive->HiveHeader = HiveHeader; RegistryHive->BaseBlock = BaseBlock;
for (Index = 0; Index < 24; Index++) for (Index = 0; Index < 24; Index++)
{ {
RegistryHive->Storage[HvStable].FreeDisplay[Index] = HCELL_NULL; RegistryHive->Storage[Stable].FreeDisplay[Index] = HCELL_NIL;
RegistryHive->Storage[HvVolatile].FreeDisplay[Index] = HCELL_NULL; RegistryHive->Storage[Volatile].FreeDisplay[Index] = HCELL_NIL;
} }
RtlInitializeBitMap(&RegistryHive->DirtyVector, NULL, 0); RtlInitializeBitMap(&RegistryHive->DirtyVector, NULL, 0);
@ -137,7 +137,7 @@ HvpCreateHive(
NTSTATUS CMAPI NTSTATUS CMAPI
HvpInitializeMemoryHive( HvpInitializeMemoryHive(
PHHIVE Hive, PHHIVE Hive,
ULONG_PTR ChunkBase) PVOID ChunkBase)
{ {
SIZE_T BlockIndex; SIZE_T BlockIndex;
PHBIN Bin, NewBin; PHBIN Bin, NewBin;
@ -161,50 +161,50 @@ HvpInitializeMemoryHive(
return STATUS_REGISTRY_CORRUPT; return STATUS_REGISTRY_CORRUPT;
} }
Hive->HiveHeader = Hive->Allocate(sizeof(HBASE_BLOCK), FALSE); Hive->BaseBlock = Hive->Allocate(sizeof(HBASE_BLOCK), FALSE, TAG_CM);
if (Hive->HiveHeader == NULL) if (Hive->BaseBlock == NULL)
{ {
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
} }
RtlCopyMemory(Hive->HiveHeader, (PVOID)ChunkBase, sizeof(HBASE_BLOCK)); RtlCopyMemory(Hive->BaseBlock, ChunkBase, sizeof(HBASE_BLOCK));
/* /*
* 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.
*/ */
Hive->Storage[HvStable].Length = (ULONG)(ChunkSize / HV_BLOCK_SIZE) - 1; Hive->Storage[Stable].Length = (ULONG)(ChunkSize / HV_BLOCK_SIZE) - 1;
Hive->Storage[HvStable].BlockList = Hive->Storage[Stable].BlockList =
Hive->Allocate(Hive->Storage[HvStable].Length * Hive->Allocate(Hive->Storage[Stable].Length *
sizeof(HMAP_ENTRY), FALSE); sizeof(HMAP_ENTRY), FALSE, TAG_CM);
if (Hive->Storage[HvStable].BlockList == NULL) if (Hive->Storage[Stable].BlockList == NULL)
{ {
DPRINT1("Allocating block list failed\n"); DPRINT1("Allocating block list failed\n");
Hive->Free(Hive->HiveHeader); Hive->Free(Hive->BaseBlock, 0);
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
} }
for (BlockIndex = 0; BlockIndex < Hive->Storage[HvStable].Length; ) for (BlockIndex = 0; BlockIndex < Hive->Storage[Stable].Length; )
{ {
Bin = (PHBIN)((ULONG_PTR)ChunkBase + (BlockIndex + 1) * HV_BLOCK_SIZE); Bin = (PHBIN)((ULONG_PTR)ChunkBase + (BlockIndex + 1) * HV_BLOCK_SIZE);
if (Bin->Signature != HV_BIN_SIGNATURE || if (Bin->Signature != HV_BIN_SIGNATURE ||
(Bin->Size % HV_BLOCK_SIZE) != 0) (Bin->Size % HV_BLOCK_SIZE) != 0)
{ {
Hive->Free(Hive->HiveHeader); Hive->Free(Hive->BaseBlock, 0);
Hive->Free(Hive->Storage[HvStable].BlockList); Hive->Free(Hive->Storage[Stable].BlockList, 0);
return STATUS_REGISTRY_CORRUPT; return STATUS_REGISTRY_CORRUPT;
} }
NewBin = Hive->Allocate(Bin->Size, TRUE); NewBin = Hive->Allocate(Bin->Size, TRUE, TAG_CM);
if (NewBin == NULL) if (NewBin == NULL)
{ {
Hive->Free(Hive->HiveHeader); Hive->Free(Hive->BaseBlock, 0);
Hive->Free(Hive->Storage[HvStable].BlockList); Hive->Free(Hive->Storage[Stable].BlockList, 0);
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
} }
Hive->Storage[HvStable].BlockList[BlockIndex].Bin = (ULONG_PTR)NewBin; Hive->Storage[Stable].BlockList[BlockIndex].BinAddress = (ULONG_PTR)NewBin;
Hive->Storage[HvStable].BlockList[BlockIndex].Block = (ULONG_PTR)NewBin; Hive->Storage[Stable].BlockList[BlockIndex].BlockAddress = (ULONG_PTR)NewBin;
RtlCopyMemory(NewBin, Bin, Bin->Size); RtlCopyMemory(NewBin, Bin, Bin->Size);
@ -212,8 +212,8 @@ HvpInitializeMemoryHive(
{ {
for (i = 1; i < Bin->Size / HV_BLOCK_SIZE; i++) for (i = 1; i < Bin->Size / HV_BLOCK_SIZE; i++)
{ {
Hive->Storage[HvStable].BlockList[BlockIndex + i].Bin = (ULONG_PTR)NewBin; Hive->Storage[Stable].BlockList[BlockIndex + i].BinAddress = (ULONG_PTR)NewBin;
Hive->Storage[HvStable].BlockList[BlockIndex + i].Block = Hive->Storage[Stable].BlockList[BlockIndex + i].BlockAddress =
((ULONG_PTR)NewBin + (i * HV_BLOCK_SIZE)); ((ULONG_PTR)NewBin + (i * HV_BLOCK_SIZE));
} }
} }
@ -224,17 +224,17 @@ HvpInitializeMemoryHive(
if (HvpCreateHiveFreeCellList(Hive)) if (HvpCreateHiveFreeCellList(Hive))
{ {
HvpFreeHiveBins(Hive); HvpFreeHiveBins(Hive);
Hive->Free(Hive->HiveHeader); Hive->Free(Hive->BaseBlock, 0);
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
} }
BitmapSize = ROUND_UP(Hive->Storage[HvStable].Length, BitmapSize = ROUND_UP(Hive->Storage[Stable].Length,
sizeof(ULONG) * 8) / 8; sizeof(ULONG) * 8) / 8;
BitmapBuffer = (PULONG)Hive->Allocate(BitmapSize, TRUE); BitmapBuffer = (PULONG)Hive->Allocate(BitmapSize, TRUE, TAG_CM);
if (BitmapBuffer == NULL) if (BitmapBuffer == NULL)
{ {
HvpFreeHiveBins(Hive); HvpFreeHiveBins(Hive);
Hive->Free(Hive->HiveHeader); Hive->Free(Hive->BaseBlock, 0);
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
} }
@ -257,14 +257,14 @@ HvpInitializeMemoryHive(
NTSTATUS CMAPI NTSTATUS CMAPI
HvpInitializeMemoryInplaceHive( HvpInitializeMemoryInplaceHive(
PHHIVE Hive, PHHIVE Hive,
ULONG_PTR ChunkBase) PVOID ChunkBase)
{ {
if (!HvpVerifyHiveHeader((PHBASE_BLOCK)ChunkBase)) if (!HvpVerifyHiveHeader((PHBASE_BLOCK)ChunkBase))
{ {
return STATUS_REGISTRY_CORRUPT; return STATUS_REGISTRY_CORRUPT;
} }
Hive->HiveHeader = (PHBASE_BLOCK)ChunkBase; Hive->BaseBlock = (PHBASE_BLOCK)ChunkBase;
Hive->ReadOnly = TRUE; Hive->ReadOnly = TRUE;
Hive->Flat = TRUE; Hive->Flat = TRUE;
@ -284,51 +284,51 @@ typedef enum _RESULT
RESULT CMAPI RESULT CMAPI
HvpGetHiveHeader(IN PHHIVE Hive, HvpGetHiveHeader(IN PHHIVE Hive,
IN PHBASE_BLOCK *BaseBlock, IN PHBASE_BLOCK *HiveBaseBlock,
IN PLARGE_INTEGER TimeStamp) IN PLARGE_INTEGER TimeStamp)
{ {
PHBASE_BLOCK HiveHeader; PHBASE_BLOCK BaseBlock;
ULONG Alignment; ULONG Alignment;
ULONG Result; ULONG Result;
ULONGLONG Offset = 0; ULONG Offset = 0;
ASSERT(sizeof(HBASE_BLOCK) >= (HV_BLOCK_SIZE * Hive->Cluster)); ASSERT(sizeof(HBASE_BLOCK) >= (HV_BLOCK_SIZE * Hive->Cluster));
/* Assume failure and allocate the buffer */ /* Assume failure and allocate the buffer */
*BaseBlock = 0; *HiveBaseBlock = 0;
HiveHeader = Hive->Allocate(sizeof(HBASE_BLOCK), TRUE); BaseBlock = Hive->Allocate(sizeof(HBASE_BLOCK), TRUE, TAG_CM);
if (!HiveHeader) return NoMemory; if (!BaseBlock) return NoMemory;
/* Check for, and enforce, alignment */ /* Check for, and enforce, alignment */
Alignment = Hive->Cluster * HV_BLOCK_SIZE -1; Alignment = Hive->Cluster * HV_BLOCK_SIZE -1;
if ((ULONG_PTR)HiveHeader & Alignment) if ((ULONG_PTR)BaseBlock & Alignment)
{ {
/* Free the old header */ /* Free the old header */
Hive->Free(HiveHeader); Hive->Free(BaseBlock, 0);
HiveHeader = Hive->Allocate(PAGE_SIZE, TRUE); BaseBlock = Hive->Allocate(PAGE_SIZE, TRUE, TAG_CM);
if (!HiveHeader) return NoMemory; if (!BaseBlock) return NoMemory;
//HiveHeader->Length = PAGE_SIZE; ?? //BaseBlock->Length = PAGE_SIZE; ??
} }
/* Clear it */ /* Clear it */
RtlZeroMemory(HiveHeader, sizeof(HBASE_BLOCK)); RtlZeroMemory(BaseBlock, sizeof(HBASE_BLOCK));
/* Now read it from disk */ /* Now read it from disk */
Result = Hive->FileRead(Hive, Result = Hive->FileRead(Hive,
HV_TYPE_PRIMARY, HFILE_TYPE_PRIMARY,
Offset, &Offset,
HiveHeader, BaseBlock,
Hive->Cluster * HV_BLOCK_SIZE); Hive->Cluster * HV_BLOCK_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;
/* Do validation */ /* Do validation */
if (!HvpVerifyHiveHeader(HiveHeader)) return NotHive; if (!HvpVerifyHiveHeader(BaseBlock)) return NotHive;
/* Return information */ /* Return information */
*BaseBlock = HiveHeader; *HiveBaseBlock = BaseBlock;
*TimeStamp = HiveHeader->TimeStamp; *TimeStamp = BaseBlock->TimeStamp;
return HiveSuccess; return HiveSuccess;
} }
@ -339,7 +339,7 @@ HvLoadHive(IN PHHIVE Hive,
PHBASE_BLOCK BaseBlock = NULL; PHBASE_BLOCK BaseBlock = NULL;
ULONG Result; ULONG Result;
LARGE_INTEGER TimeStamp; LARGE_INTEGER TimeStamp;
ULONGLONG Offset = 0; ULONG Offset = 0;
PVOID HiveData; PVOID HiveData;
/* Get the hive header */ /* Get the hive header */
@ -370,17 +370,17 @@ HvLoadHive(IN PHHIVE Hive,
BaseBlock->BootType = 0; BaseBlock->BootType = 0;
/* Setup hive data */ /* Setup hive data */
Hive->HiveHeader = BaseBlock; Hive->BaseBlock = BaseBlock;
Hive->Version = Hive->HiveHeader->Minor; Hive->Version = Hive->BaseBlock->Minor;
/* Allocate a buffer large enough to hold the hive */ /* Allocate a buffer large enough to hold the hive */
HiveData = Hive->Allocate(FileSize, TRUE); HiveData = Hive->Allocate(FileSize, TRUE, TAG_CM);
if (!HiveData) return STATUS_INSUFFICIENT_RESOURCES; if (!HiveData) return STATUS_INSUFFICIENT_RESOURCES;
/* Now read the whole hive */ /* Now read the whole hive */
Result = Hive->FileRead(Hive, Result = Hive->FileRead(Hive,
HV_TYPE_PRIMARY, HFILE_TYPE_PRIMARY,
Offset, &Offset,
HiveData, HiveData,
FileSize); FileSize);
if (!Result) return STATUS_NOT_REGISTRY_FILE; if (!Result) return STATUS_NOT_REGISTRY_FILE;
@ -389,10 +389,10 @@ HvLoadHive(IN PHHIVE Hive,
((PHBASE_BLOCK)HiveData)->Length = FileSize; ((PHBASE_BLOCK)HiveData)->Length = FileSize;
/* Free our base block... it's usless in this implementation */ /* Free our base block... it's usless in this implementation */
Hive->Free(BaseBlock); Hive->Free(BaseBlock, 0);
/* Initialize the hive directly from memory */ /* Initialize the hive directly from memory */
return HvpInitializeMemoryHive(Hive, (ULONG_PTR)HiveData); return HvpInitializeMemoryHive(Hive, HiveData);
} }
/** /**
@ -432,15 +432,15 @@ HvInitialize(
ULONG Operation, ULONG Operation,
ULONG HiveType, ULONG HiveType,
ULONG HiveFlags, ULONG HiveFlags,
ULONG_PTR HiveData OPTIONAL, PVOID HiveData OPTIONAL,
ULONG Cluster OPTIONAL,
PALLOCATE_ROUTINE Allocate, PALLOCATE_ROUTINE Allocate,
PFREE_ROUTINE Free, PFREE_ROUTINE Free,
PFILE_READ_ROUTINE FileRead,
PFILE_WRITE_ROUTINE FileWrite,
PFILE_SET_SIZE_ROUTINE FileSetSize, PFILE_SET_SIZE_ROUTINE FileSetSize,
PFILE_WRITE_ROUTINE FileWrite,
PFILE_READ_ROUTINE FileRead,
PFILE_FLUSH_ROUTINE FileFlush, PFILE_FLUSH_ROUTINE FileFlush,
IN PCUNICODE_STRING FileName) ULONG Cluster OPTIONAL,
PUNICODE_STRING FileName)
{ {
NTSTATUS Status; NTSTATUS Status;
PHHIVE Hive = RegistryHive; PHHIVE Hive = RegistryHive;
@ -457,25 +457,25 @@ HvInitialize(
Hive->FileWrite = FileWrite; Hive->FileWrite = FileWrite;
Hive->FileSetSize = FileSetSize; Hive->FileSetSize = FileSetSize;
Hive->FileFlush = FileFlush; Hive->FileFlush = FileFlush;
Hive->StorageTypeCount = 2; Hive->StorageTypeCount = HTYPE_COUNT;
Hive->Cluster = 1; Hive->Cluster = 1;
Hive->Version = HV_MINOR_VER; Hive->Version = HSYS_MINOR;
switch (Operation) switch (Operation)
{ {
case HV_OPERATION_CREATE_HIVE: case HINIT_CREATE:
Status = HvpCreateHive(Hive); Status = HvpCreateHive(Hive);
break; break;
case HV_OPERATION_MEMORY: case HINIT_MEMORY:
Status = HvpInitializeMemoryHive(Hive, HiveData); Status = HvpInitializeMemoryHive(Hive, HiveData);
break; break;
case HV_OPERATION_MEMORY_INPLACE: case HINIT_FLAT:
Status = HvpInitializeMemoryInplaceHive(Hive, HiveData); Status = HvpInitializeMemoryInplaceHive(Hive, HiveData);
break; break;
case 2: case HINIT_FILE:
/* Hack of doom: Cluster is actually the file size. */ /* Hack of doom: Cluster is actually the file size. */
Status = HvLoadHive(Hive, Cluster); Status = HvLoadHive(Hive, Cluster);
@ -498,7 +498,7 @@ HvInitialize(
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
Hive->Free(Hive); Hive->Free(Hive, 0);
return Status; return Status;
} }
@ -520,13 +520,13 @@ HvFree(
/* Release hive bitmap */ /* Release hive bitmap */
if (RegistryHive->DirtyVector.Buffer) if (RegistryHive->DirtyVector.Buffer)
{ {
RegistryHive->Free(RegistryHive->DirtyVector.Buffer); RegistryHive->Free(RegistryHive->DirtyVector.Buffer, 0);
} }
HvpFreeHiveBins(RegistryHive); HvpFreeHiveBins(RegistryHive);
} }
RegistryHive->Free(RegistryHive); RegistryHive->Free(RegistryHive, 0);
} }
/* EOF */ /* EOF */

View file

@ -13,7 +13,7 @@ static BOOLEAN CMAPI
HvpWriteLog( HvpWriteLog(
PHHIVE RegistryHive) PHHIVE RegistryHive)
{ {
ULONGLONG FileOffset; ULONG FileOffset;
SIZE_T BufferSize; SIZE_T BufferSize;
SIZE_T BitmapSize; SIZE_T BitmapSize;
PUCHAR Buffer; PUCHAR Buffer;
@ -30,8 +30,8 @@ HvpWriteLog(
DPRINT("HvpWriteLog called\n"); DPRINT("HvpWriteLog called\n");
if (RegistryHive->HiveHeader->Sequence1 != if (RegistryHive->BaseBlock->Sequence1 !=
RegistryHive->HiveHeader->Sequence2) RegistryHive->BaseBlock->Sequence2)
{ {
return FALSE; return FALSE;
} }
@ -42,29 +42,30 @@ HvpWriteLog(
DPRINT("Bitmap size %lu buffer size: %lu\n", BitmapSize, BufferSize); DPRINT("Bitmap size %lu buffer size: %lu\n", BitmapSize, BufferSize);
Buffer = RegistryHive->Allocate(BufferSize, TRUE); Buffer = RegistryHive->Allocate(BufferSize, TRUE, TAG_CM);
if (Buffer == NULL) if (Buffer == NULL)
{ {
return FALSE; return FALSE;
} }
/* Update first update counter and checksum */ /* Update first update counter and CheckSum */
RegistryHive->HiveHeader->Type = HV_TYPE_LOG; RegistryHive->BaseBlock->Type = HFILE_TYPE_LOG;
RegistryHive->HiveHeader->Sequence1++; RegistryHive->BaseBlock->Sequence1++;
RegistryHive->HiveHeader->Checksum = RegistryHive->BaseBlock->CheckSum =
HvpHiveHeaderChecksum(RegistryHive->HiveHeader); HvpHiveHeaderChecksum(RegistryHive->BaseBlock);
/* Copy hive header */ /* Copy hive header */
RtlCopyMemory(Buffer, RegistryHive->HiveHeader, HV_LOG_HEADER_SIZE); RtlCopyMemory(Buffer, RegistryHive->BaseBlock, HV_LOG_HEADER_SIZE);
Ptr = Buffer + HV_LOG_HEADER_SIZE; Ptr = Buffer + HV_LOG_HEADER_SIZE;
RtlCopyMemory(Ptr, "DIRT", 4); RtlCopyMemory(Ptr, "DIRT", 4);
Ptr += 4; Ptr += 4;
RtlCopyMemory(Ptr, RegistryHive->DirtyVector.Buffer, BitmapSize); RtlCopyMemory(Ptr, RegistryHive->DirtyVector.Buffer, BitmapSize);
/* Write hive block and block bitmap */ /* Write hive block and block bitmap */
Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_LOG, FileOffset = 0;
0, Buffer, BufferSize); Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_LOG,
RegistryHive->Free(Buffer); &FileOffset, Buffer, BufferSize);
RegistryHive->Free(Buffer, 0);
if (!Success) if (!Success)
{ {
@ -74,7 +75,7 @@ HvpWriteLog(
/* Write dirty blocks */ /* Write dirty blocks */
FileOffset = BufferSize; FileOffset = BufferSize;
BlockIndex = 0; BlockIndex = 0;
while (BlockIndex < RegistryHive->Storage[HvStable].Length) while (BlockIndex < RegistryHive->Storage[Stable].Length)
{ {
LastIndex = BlockIndex; LastIndex = BlockIndex;
BlockIndex = RtlFindSetBits(&RegistryHive->DirtyVector, 1, BlockIndex); BlockIndex = RtlFindSetBits(&RegistryHive->DirtyVector, 1, BlockIndex);
@ -83,11 +84,11 @@ HvpWriteLog(
break; break;
} }
BlockPtr = (PVOID)RegistryHive->Storage[HvStable].BlockList[BlockIndex].Block; BlockPtr = (PVOID)RegistryHive->Storage[Stable].BlockList[BlockIndex].BlockAddress;
/* Write hive block */ /* Write hive block */
Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_LOG, Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_LOG,
FileOffset, BlockPtr, &FileOffset, BlockPtr,
HV_BLOCK_SIZE); HV_BLOCK_SIZE);
if (!Success) if (!Success)
{ {
@ -98,7 +99,7 @@ HvpWriteLog(
FileOffset += HV_BLOCK_SIZE; FileOffset += HV_BLOCK_SIZE;
} }
Success = RegistryHive->FileSetSize(RegistryHive, HV_TYPE_LOG, FileOffset); Success = RegistryHive->FileSetSize(RegistryHive, HFILE_TYPE_LOG, FileOffset, FileOffset);
if (!Success) if (!Success)
{ {
DPRINT("FileSetSize failed\n"); DPRINT("FileSetSize failed\n");
@ -106,20 +107,21 @@ HvpWriteLog(
} }
/* Flush the log file */ /* Flush the log file */
Success = RegistryHive->FileFlush(RegistryHive, HV_TYPE_LOG); Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_LOG, NULL, 0);
if (!Success) if (!Success)
{ {
DPRINT("FileFlush failed\n"); DPRINT("FileFlush failed\n");
} }
/* Update first and second update counter and checksum. */ /* Update first and second update counter and CheckSum. */
RegistryHive->HiveHeader->Sequence2++; RegistryHive->BaseBlock->Sequence2++;
RegistryHive->HiveHeader->Checksum = RegistryHive->BaseBlock->CheckSum =
HvpHiveHeaderChecksum(RegistryHive->HiveHeader); HvpHiveHeaderChecksum(RegistryHive->BaseBlock);
/* Write hive header again with updated sequence counter. */ /* Write hive header again with updated sequence counter. */
Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_LOG, FileOffset = 0;
0, RegistryHive->HiveHeader, Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_LOG,
&FileOffset, RegistryHive->BaseBlock,
HV_LOG_HEADER_SIZE); HV_LOG_HEADER_SIZE);
if (!Success) if (!Success)
{ {
@ -127,7 +129,7 @@ HvpWriteLog(
} }
/* Flush the log file */ /* Flush the log file */
Success = RegistryHive->FileFlush(RegistryHive, HV_TYPE_LOG); Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_LOG, NULL, 0);
if (!Success) if (!Success)
{ {
DPRINT("FileFlush failed\n"); DPRINT("FileFlush failed\n");
@ -141,7 +143,7 @@ HvpWriteHive(
PHHIVE RegistryHive, PHHIVE RegistryHive,
BOOLEAN OnlyDirty) BOOLEAN OnlyDirty)
{ {
ULONGLONG FileOffset; ULONG FileOffset;
ULONG BlockIndex; ULONG BlockIndex;
ULONG LastIndex; ULONG LastIndex;
PVOID BlockPtr; PVOID BlockPtr;
@ -151,21 +153,22 @@ HvpWriteHive(
DPRINT("HvpWriteHive called\n"); DPRINT("HvpWriteHive called\n");
if (RegistryHive->HiveHeader->Sequence1 != if (RegistryHive->BaseBlock->Sequence1 !=
RegistryHive->HiveHeader->Sequence2) RegistryHive->BaseBlock->Sequence2)
{ {
return FALSE; return FALSE;
} }
/* Update first update counter and checksum */ /* Update first update counter and CheckSum */
RegistryHive->HiveHeader->Type = HV_TYPE_PRIMARY; RegistryHive->BaseBlock->Type = HFILE_TYPE_PRIMARY;
RegistryHive->HiveHeader->Sequence1++; RegistryHive->BaseBlock->Sequence1++;
RegistryHive->HiveHeader->Checksum = RegistryHive->BaseBlock->CheckSum =
HvpHiveHeaderChecksum(RegistryHive->HiveHeader); HvpHiveHeaderChecksum(RegistryHive->BaseBlock);
/* Write hive block */ /* Write hive block */
Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_PRIMARY, FileOffset = 0;
0, RegistryHive->HiveHeader, Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_PRIMARY,
&FileOffset, RegistryHive->BaseBlock,
sizeof(HBASE_BLOCK)); sizeof(HBASE_BLOCK));
if (!Success) if (!Success)
{ {
@ -173,7 +176,7 @@ HvpWriteHive(
} }
BlockIndex = 0; BlockIndex = 0;
while (BlockIndex < RegistryHive->Storage[HvStable].Length) while (BlockIndex < RegistryHive->Storage[Stable].Length)
{ {
if (OnlyDirty) if (OnlyDirty)
{ {
@ -185,12 +188,12 @@ HvpWriteHive(
} }
} }
BlockPtr = (PVOID)RegistryHive->Storage[HvStable].BlockList[BlockIndex].Block; BlockPtr = (PVOID)RegistryHive->Storage[Stable].BlockList[BlockIndex].BlockAddress;
FileOffset = (ULONGLONG)(BlockIndex + 1) * (ULONGLONG)HV_BLOCK_SIZE; FileOffset = (ULONGLONG)(BlockIndex + 1) * (ULONGLONG)HV_BLOCK_SIZE;
/* Write hive block */ /* Write hive block */
Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_PRIMARY, Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_PRIMARY,
FileOffset, BlockPtr, &FileOffset, BlockPtr,
HV_BLOCK_SIZE); HV_BLOCK_SIZE);
if (!Success) if (!Success)
{ {
@ -200,27 +203,28 @@ HvpWriteHive(
BlockIndex++; BlockIndex++;
} }
Success = RegistryHive->FileFlush(RegistryHive, HV_TYPE_PRIMARY); Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_PRIMARY, NULL, 0);
if (!Success) if (!Success)
{ {
DPRINT("FileFlush failed\n"); DPRINT("FileFlush failed\n");
} }
/* Update second update counter and checksum */ /* Update second update counter and CheckSum */
RegistryHive->HiveHeader->Sequence2++; RegistryHive->BaseBlock->Sequence2++;
RegistryHive->HiveHeader->Checksum = RegistryHive->BaseBlock->CheckSum =
HvpHiveHeaderChecksum(RegistryHive->HiveHeader); HvpHiveHeaderChecksum(RegistryHive->BaseBlock);
/* Write hive block */ /* Write hive block */
Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_PRIMARY, FileOffset = 0;
0, RegistryHive->HiveHeader, Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_PRIMARY,
&FileOffset, RegistryHive->BaseBlock,
sizeof(HBASE_BLOCK)); sizeof(HBASE_BLOCK));
if (!Success) if (!Success)
{ {
return FALSE; return FALSE;
} }
Success = RegistryHive->FileFlush(RegistryHive, HV_TYPE_PRIMARY); Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_PRIMARY, NULL, 0);
if (!Success) if (!Success)
{ {
DPRINT("FileFlush failed\n"); DPRINT("FileFlush failed\n");
@ -241,7 +245,7 @@ HvSyncHive(
} }
/* Update hive header modification time */ /* Update hive header modification time */
KeQuerySystemTime(&RegistryHive->HiveHeader->TimeStamp); KeQuerySystemTime(&RegistryHive->BaseBlock->TimeStamp);
/* Update log file */ /* Update log file */
if (!HvpWriteLog(RegistryHive)) if (!HvpWriteLog(RegistryHive))
@ -268,7 +272,7 @@ HvWriteHive(
ASSERT(RegistryHive->ReadOnly == FALSE); ASSERT(RegistryHive->ReadOnly == FALSE);
/* Update hive header modification time */ /* Update hive header modification time */
KeQuerySystemTime(&RegistryHive->HiveHeader->TimeStamp); KeQuerySystemTime(&RegistryHive->BaseBlock->TimeStamp);
/* Update hive file */ /* Update hive file */
if (!HvpWriteHive(RegistryHive, FALSE)) if (!HvpWriteHive(RegistryHive, FALSE))

View file

@ -277,13 +277,13 @@ CmiAllocateHashTableCell(IN PEREGISTRY_HIVE RegistryHive,
OUT PHASH_TABLE_CELL *HashBlock, OUT PHASH_TABLE_CELL *HashBlock,
OUT HCELL_INDEX *HBOffset, OUT HCELL_INDEX *HBOffset,
IN ULONG HashTableSize, IN ULONG HashTableSize,
IN HV_STORAGE_TYPE Storage); IN HSTORAGE_TYPE Storage);
NTSTATUS NTSTATUS
CmiAddKeyToHashTable(PEREGISTRY_HIVE RegistryHive, CmiAddKeyToHashTable(PEREGISTRY_HIVE RegistryHive,
PHASH_TABLE_CELL HashCell, PHASH_TABLE_CELL HashCell,
PCM_KEY_NODE KeyCell, PCM_KEY_NODE KeyCell,
HV_STORAGE_TYPE StorageType, HSTORAGE_TYPE StorageType,
PCM_KEY_NODE NewKeyCell, PCM_KEY_NODE NewKeyCell,
HCELL_INDEX NKBOffset); HCELL_INDEX NKBOffset);

View file

@ -113,16 +113,16 @@ CmiGetMaxNameLength(PHHIVE Hive,
ULONG Storage; ULONG Storage;
MaxName = 0; MaxName = 0;
for (Storage = HvStable; Storage < HvMaxStorageType; Storage++) for (Storage = Stable; Storage < HTYPE_COUNT; Storage++)
{ {
if (KeyCell->SubKeyLists[Storage] != HCELL_NULL) if (KeyCell->SubKeyLists[Storage] != HCELL_NIL)
{ {
HashBlock = HvGetCell (Hive, KeyCell->SubKeyLists[Storage]); HashBlock = (PHASH_TABLE_CELL)HvGetCell (Hive, KeyCell->SubKeyLists[Storage]);
ASSERT(HashBlock->Id == REG_HASH_TABLE_CELL_ID); ASSERT(HashBlock->Id == REG_HASH_TABLE_CELL_ID);
for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++) for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++)
{ {
CurSubKeyCell = HvGetCell (Hive, CurSubKeyCell = (PCM_KEY_NODE)HvGetCell (Hive,
HashBlock->Table[i].KeyOffset); HashBlock->Table[i].KeyOffset);
NameSize = CurSubKeyCell->NameSize; NameSize = CurSubKeyCell->NameSize;
if (CurSubKeyCell->Flags & REG_KEY_NAME_PACKED) if (CurSubKeyCell->Flags & REG_KEY_NAME_PACKED)
@ -149,17 +149,17 @@ CmiGetMaxClassLength(PHHIVE Hive,
ULONG Storage; ULONG Storage;
MaxClass = 0; MaxClass = 0;
for (Storage = HvStable; Storage < HvMaxStorageType; Storage++) for (Storage = Stable; Storage < HTYPE_COUNT; Storage++)
{ {
if (KeyCell->SubKeyLists[Storage] != HCELL_NULL) if (KeyCell->SubKeyLists[Storage] != HCELL_NIL)
{ {
HashBlock = HvGetCell (Hive, HashBlock = (PHASH_TABLE_CELL)HvGetCell (Hive,
KeyCell->SubKeyLists[Storage]); KeyCell->SubKeyLists[Storage]);
ASSERT(HashBlock->Id == REG_HASH_TABLE_CELL_ID); ASSERT(HashBlock->Id == REG_HASH_TABLE_CELL_ID);
for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++) for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++)
{ {
CurSubKeyCell = HvGetCell (Hive, CurSubKeyCell = (PCM_KEY_NODE)HvGetCell (Hive,
HashBlock->Table[i].KeyOffset); HashBlock->Table[i].KeyOffset);
if (MaxClass < CurSubKeyCell->ClassSize) if (MaxClass < CurSubKeyCell->ClassSize)
@ -185,18 +185,18 @@ CmiGetMaxValueNameLength(PHHIVE Hive,
VERIFY_KEY_CELL(KeyCell); VERIFY_KEY_CELL(KeyCell);
if (KeyCell->ValueList.List == HCELL_NULL) if (KeyCell->ValueList.List == HCELL_NIL)
{ {
return 0; return 0;
} }
MaxValueName = 0; MaxValueName = 0;
ValueListCell = HvGetCell (Hive, ValueListCell = (PVALUE_LIST_CELL)HvGetCell (Hive,
KeyCell->ValueList.List); KeyCell->ValueList.List);
for (i = 0; i < KeyCell->ValueList.Count; i++) for (i = 0; i < KeyCell->ValueList.Count; i++)
{ {
CurValueCell = HvGetCell (Hive, CurValueCell = (PCM_KEY_VALUE)HvGetCell (Hive,
ValueListCell->ValueOffset[i]); ValueListCell->ValueOffset[i]);
if (CurValueCell == NULL) if (CurValueCell == NULL)
{ {
@ -231,17 +231,17 @@ CmiGetMaxValueDataLength(PHHIVE Hive,
VERIFY_KEY_CELL(KeyCell); VERIFY_KEY_CELL(KeyCell);
if (KeyCell->ValueList.List == HCELL_NULL) if (KeyCell->ValueList.List == HCELL_NIL)
{ {
return 0; return 0;
} }
MaxValueData = 0; MaxValueData = 0;
ValueListCell = HvGetCell (Hive, KeyCell->ValueList.List); ValueListCell = (PVALUE_LIST_CELL)HvGetCell (Hive, KeyCell->ValueList.List);
for (i = 0; i < KeyCell->ValueList.Count; i++) for (i = 0; i < KeyCell->ValueList.Count; i++)
{ {
CurValueCell = HvGetCell (Hive, CurValueCell = (PCM_KEY_VALUE)HvGetCell (Hive,
ValueListCell->ValueOffset[i]); ValueListCell->ValueOffset[i]);
if ((MaxValueData < (LONG)(CurValueCell->DataSize & REG_DATA_SIZE_MASK))) if ((MaxValueData < (LONG)(CurValueCell->DataSize & REG_DATA_SIZE_MASK)))
{ {
@ -271,7 +271,7 @@ CmiScanKeyForValue(IN PEREGISTRY_HIVE RegistryHive,
/* Otherwise, get the cell data back too */ /* Otherwise, get the cell data back too */
if (ValueCellOffset) *ValueCellOffset = CellIndex; if (ValueCellOffset) *ValueCellOffset = CellIndex;
*ValueCell = HvGetCell(&RegistryHive->Hive, CellIndex); *ValueCell = (PCM_KEY_VALUE)HvGetCell(&RegistryHive->Hive, CellIndex);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -295,7 +295,7 @@ CmiScanForSubKey(IN PEREGISTRY_HIVE RegistryHive,
/* Otherwise, get the cell data back too */ /* Otherwise, get the cell data back too */
*BlockOffset = CellIndex; *BlockOffset = CellIndex;
*SubKeyCell = HvGetCell(&RegistryHive->Hive, CellIndex); *SubKeyCell = (PCM_KEY_NODE)HvGetCell(&RegistryHive->Hive, CellIndex);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -318,7 +318,7 @@ CmiAddSubKey(PEREGISTRY_HIVE RegistryHive,
USHORT NameSize; USHORT NameSize;
PWSTR NamePtr; PWSTR NamePtr;
BOOLEAN Packable; BOOLEAN Packable;
HV_STORAGE_TYPE Storage; HSTORAGE_TYPE Storage;
ULONG i; ULONG i;
ParentKeyCell = ParentKey->KeyCell; ParentKeyCell = ParentKey->KeyCell;
@ -358,16 +358,16 @@ CmiAddSubKey(PEREGISTRY_HIVE RegistryHive,
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
Storage = (CreateOptions & REG_OPTION_VOLATILE) ? HvVolatile : HvStable; Storage = (CreateOptions & REG_OPTION_VOLATILE) ? Volatile : Stable;
NewBlockSize = sizeof(CM_KEY_NODE) + NameSize; NewBlockSize = sizeof(CM_KEY_NODE) + NameSize;
NKBOffset = HvAllocateCell (&RegistryHive->Hive, NewBlockSize, Storage); NKBOffset = HvAllocateCell (&RegistryHive->Hive, NewBlockSize, Storage, HCELL_NIL);
if (NKBOffset == HCELL_NULL) if (NKBOffset == HCELL_NIL)
{ {
Status = STATUS_INSUFFICIENT_RESOURCES; Status = STATUS_INSUFFICIENT_RESOURCES;
} }
else else
{ {
NewKeyCell = HvGetCell (&RegistryHive->Hive, NKBOffset); NewKeyCell = (PCM_KEY_NODE)HvGetCell (&RegistryHive->Hive, NKBOffset);
NewKeyCell->Id = REG_KEY_CELL_ID; NewKeyCell->Id = REG_KEY_CELL_ID;
if (CreateOptions & REG_OPTION_VOLATILE) if (CreateOptions & REG_OPTION_VOLATILE)
{ {
@ -378,15 +378,15 @@ CmiAddSubKey(PEREGISTRY_HIVE RegistryHive,
NewKeyCell->Flags = 0; NewKeyCell->Flags = 0;
} }
KeQuerySystemTime(&NewKeyCell->LastWriteTime); KeQuerySystemTime(&NewKeyCell->LastWriteTime);
NewKeyCell->Parent = HCELL_NULL; NewKeyCell->Parent = HCELL_NIL;
NewKeyCell->SubKeyCounts[HvStable] = 0; NewKeyCell->SubKeyCounts[Stable] = 0;
NewKeyCell->SubKeyCounts[HvVolatile] = 0; NewKeyCell->SubKeyCounts[Volatile] = 0;
NewKeyCell->SubKeyLists[HvStable] = HCELL_NULL; NewKeyCell->SubKeyLists[Stable] = HCELL_NIL;
NewKeyCell->SubKeyLists[HvVolatile] = HCELL_NULL; NewKeyCell->SubKeyLists[Volatile] = HCELL_NIL;
NewKeyCell->ValueList.Count = 0; NewKeyCell->ValueList.Count = 0;
NewKeyCell->ValueList.List = HCELL_NULL; NewKeyCell->ValueList.List = HCELL_NIL;
NewKeyCell->SecurityKeyOffset = HCELL_NULL; NewKeyCell->SecurityKeyOffset = HCELL_NIL;
NewKeyCell->ClassNameOffset = HCELL_NULL; NewKeyCell->ClassNameOffset = HCELL_NIL;
/* Pack the key name */ /* Pack the key name */
NewKeyCell->NameSize = NameSize; NewKeyCell->NameSize = NameSize;
@ -411,10 +411,10 @@ CmiAddSubKey(PEREGISTRY_HIVE RegistryHive,
{ {
NewKeyCell->ClassSize = Class->Length; NewKeyCell->ClassSize = Class->Length;
NewKeyCell->ClassNameOffset = HvAllocateCell( NewKeyCell->ClassNameOffset = HvAllocateCell(
&RegistryHive->Hive, NewKeyCell->ClassSize, HvStable); &RegistryHive->Hive, NewKeyCell->ClassSize, Stable, HCELL_NIL);
ASSERT(NewKeyCell->ClassNameOffset != HCELL_NULL); /* FIXME */ ASSERT(NewKeyCell->ClassNameOffset != HCELL_NIL); /* FIXME */
ClassCell = HvGetCell(&RegistryHive->Hive, NewKeyCell->ClassNameOffset); ClassCell = (PVOID)HvGetCell(&RegistryHive->Hive, NewKeyCell->ClassNameOffset);
RtlCopyMemory (ClassCell, RtlCopyMemory (ClassCell,
Class->Buffer, Class->Buffer,
Class->Length); Class->Length);
@ -429,7 +429,7 @@ CmiAddSubKey(PEREGISTRY_HIVE RegistryHive,
SubKey->KeyCell = NewKeyCell; SubKey->KeyCell = NewKeyCell;
SubKey->KeyCellOffset = NKBOffset; SubKey->KeyCellOffset = NKBOffset;
if (ParentKeyCell->SubKeyLists[Storage] == HCELL_NULL) if (ParentKeyCell->SubKeyLists[Storage] == HCELL_NIL)
{ {
Status = CmiAllocateHashTableCell (RegistryHive, Status = CmiAllocateHashTableCell (RegistryHive,
&HashBlock, &HashBlock,
@ -443,7 +443,7 @@ CmiAddSubKey(PEREGISTRY_HIVE RegistryHive,
} }
else else
{ {
HashBlock = HvGetCell (&RegistryHive->Hive, HashBlock = (PHASH_TABLE_CELL)HvGetCell (&RegistryHive->Hive,
ParentKeyCell->SubKeyLists[Storage]); ParentKeyCell->SubKeyLists[Storage]);
ASSERT(HashBlock->Id == REG_HASH_TABLE_CELL_ID); ASSERT(HashBlock->Id == REG_HASH_TABLE_CELL_ID);
@ -487,7 +487,7 @@ CmiAddSubKey(PEREGISTRY_HIVE RegistryHive,
} }
KeQuerySystemTime (&ParentKeyCell->LastWriteTime); KeQuerySystemTime (&ParentKeyCell->LastWriteTime);
HvMarkCellDirty (&RegistryHive->Hive, ParentKey->KeyCellOffset); HvMarkCellDirty (&RegistryHive->Hive, ParentKey->KeyCellOffset, FALSE);
return(Status); return(Status);
} }
@ -497,7 +497,7 @@ CmiAllocateHashTableCell (IN PEREGISTRY_HIVE RegistryHive,
OUT PHASH_TABLE_CELL *HashBlock, OUT PHASH_TABLE_CELL *HashBlock,
OUT HCELL_INDEX *HBOffset, OUT HCELL_INDEX *HBOffset,
IN ULONG SubKeyCount, IN ULONG SubKeyCount,
IN HV_STORAGE_TYPE Storage) IN HSTORAGE_TYPE Storage)
{ {
PHASH_TABLE_CELL NewHashBlock; PHASH_TABLE_CELL NewHashBlock;
ULONG NewHashSize; ULONG NewHashSize;
@ -507,16 +507,16 @@ CmiAllocateHashTableCell (IN PEREGISTRY_HIVE RegistryHive,
*HashBlock = NULL; *HashBlock = NULL;
NewHashSize = sizeof(HASH_TABLE_CELL) + NewHashSize = sizeof(HASH_TABLE_CELL) +
(SubKeyCount * sizeof(HASH_RECORD)); (SubKeyCount * sizeof(HASH_RECORD));
*HBOffset = HvAllocateCell (&RegistryHive->Hive, NewHashSize, Storage); *HBOffset = HvAllocateCell (&RegistryHive->Hive, NewHashSize, Storage, HCELL_NIL);
if (*HBOffset == HCELL_NULL) if (*HBOffset == HCELL_NIL)
{ {
Status = STATUS_INSUFFICIENT_RESOURCES; Status = STATUS_INSUFFICIENT_RESOURCES;
} }
else else
{ {
ASSERT(SubKeyCount <= 0xffff); /* should really be USHORT_MAX or similar */ ASSERT(SubKeyCount <= 0xffff); /* should really be USHORT_MAX or similar */
NewHashBlock = HvGetCell (&RegistryHive->Hive, *HBOffset); NewHashBlock = (PHASH_TABLE_CELL)HvGetCell (&RegistryHive->Hive, *HBOffset);
NewHashBlock->Id = REG_HASH_TABLE_CELL_ID; NewHashBlock->Id = REG_HASH_TABLE_CELL_ID;
NewHashBlock->HashTableSize = (USHORT)SubKeyCount; NewHashBlock->HashTableSize = (USHORT)SubKeyCount;
*HashBlock = NewHashBlock; *HashBlock = NewHashBlock;
@ -529,7 +529,7 @@ NTSTATUS
CmiAddKeyToHashTable(PEREGISTRY_HIVE RegistryHive, CmiAddKeyToHashTable(PEREGISTRY_HIVE RegistryHive,
PHASH_TABLE_CELL HashCell, PHASH_TABLE_CELL HashCell,
PCM_KEY_NODE KeyCell, PCM_KEY_NODE KeyCell,
HV_STORAGE_TYPE StorageType, HSTORAGE_TYPE StorageType,
PCM_KEY_NODE NewKeyCell, PCM_KEY_NODE NewKeyCell,
HCELL_INDEX NKBOffset) HCELL_INDEX NKBOffset)
{ {
@ -543,7 +543,7 @@ CmiAddKeyToHashTable(PEREGISTRY_HIVE RegistryHive,
NewKeyCell->Name, NewKeyCell->Name,
min(NewKeyCell->NameSize, sizeof(ULONG))); min(NewKeyCell->NameSize, sizeof(ULONG)));
} }
HvMarkCellDirty(&RegistryHive->Hive, KeyCell->SubKeyLists[StorageType]); HvMarkCellDirty(&RegistryHive->Hive, KeyCell->SubKeyLists[StorageType], FALSE);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View file

@ -357,8 +357,8 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
NewKey->KeyCellOffset = RegistryHive->Hive.HiveHeader->RootCell; NewKey->KeyCellOffset = RegistryHive->Hive.BaseBlock->RootCell;
NewKey->KeyCell = HvGetCell (&RegistryHive->Hive, NewKey->KeyCellOffset); NewKey->KeyCell = (PVOID)HvGetCell(&RegistryHive->Hive, NewKey->KeyCellOffset);
NewKey->RegistryHive = RegistryHive; NewKey->RegistryHive = RegistryHive;
Status = RtlpCreateUnicodeString(&NewKey->Name, Status = RtlpCreateUnicodeString(&NewKey->Name,

View file

@ -43,57 +43,6 @@
#define ASSERT_VALUE_BIG(h, s) \ #define ASSERT_VALUE_BIG(h, s) \
ASSERTMSG("Big keys not supported!", !CmpIsKeyValueBig(h, s)); ASSERTMSG("Big keys not supported!", !CmpIsKeyValueBig(h, s));
//
// Tag for all registry allocations
//
#define TAG_CM \
TAG('C', 'm', ' ', ' ')
//
// Hive operations
//
#define HINIT_CREATE 0
#define HINIT_MEMORY 1
#define HINIT_FILE 2
#define HINIT_MEMORY_INPLACE 3
#define HINIT_FLAT 4
#define HINIT_MAPFILE 5
//
// Hive flags
//
#define HIVE_VOLATILE 1
#define HIVE_NOLAZYFLUSH 2
//
// Hive types
//
#define HFILE_TYPE_PRIMARY 0
#define HFILE_TYPE_ALTERNATE 1
#define HFILE_TYPE_LOG 2
#define HFILE_TYPE_EXTERNAL 3
#define HFILE_TYPE_MAX 4
//
// Hive sizes
//
#define HBLOCK_SIZE 0x1000
#define HSECTOR_SIZE 0x200
#define HSECTOR_COUNT 8
//
// Hive versions
//
#define HSYS_MAJOR 1
#define HSYS_MINOR 3
#define HSYS_WHISTLER_BETA1 4
//
// Cell Masks
//
#define HCELL_NIL -1
#define HCELL_CACHED 1
// //
// Key Types // Key Types
// //
@ -496,8 +445,8 @@ typedef struct _CM_KEY_NODE
LARGE_INTEGER LastWriteTime; LARGE_INTEGER LastWriteTime;
ULONG Spare; ULONG Spare;
HCELL_INDEX Parent; HCELL_INDEX Parent;
ULONG SubKeyCounts[HvMaxStorageType]; ULONG SubKeyCounts[HTYPE_COUNT];
HCELL_INDEX SubKeyLists[HvMaxStorageType]; HCELL_INDEX SubKeyLists[HTYPE_COUNT];
CHILD_LIST ValueList; CHILD_LIST ValueList;
HCELL_INDEX Security; HCELL_INDEX Security;
HCELL_INDEX Class; HCELL_INDEX Class;
@ -1303,13 +1252,15 @@ PVOID
NTAPI NTAPI
CmpAllocate( CmpAllocate(
IN ULONG Size, IN ULONG Size,
IN BOOLEAN Paged IN BOOLEAN Paged,
IN ULONG Tag
); );
VOID VOID
NTAPI NTAPI
CmpFree( CmpFree(
IN PVOID Ptr IN PVOID Ptr,
IN ULONG Quota
); );
BOOLEAN BOOLEAN
@ -1317,7 +1268,7 @@ NTAPI
CmpFileRead( CmpFileRead(
IN PHHIVE RegistryHive, IN PHHIVE RegistryHive,
IN ULONG FileType, IN ULONG FileType,
IN ULONGLONG FileOffset, IN OUT PULONG FileOffset,
OUT PVOID Buffer, OUT PVOID Buffer,
IN SIZE_T BufferLength IN SIZE_T BufferLength
); );
@ -1327,7 +1278,7 @@ NTAPI
CmpFileWrite( CmpFileWrite(
IN PHHIVE RegistryHive, IN PHHIVE RegistryHive,
IN ULONG FileType, IN ULONG FileType,
IN ULONGLONG FileOffset, IN OUT PULONG FileOffset,
IN PVOID Buffer, IN PVOID Buffer,
IN SIZE_T BufferLength IN SIZE_T BufferLength
); );
@ -1337,14 +1288,17 @@ NTAPI
CmpFileSetSize( CmpFileSetSize(
IN PHHIVE RegistryHive, IN PHHIVE RegistryHive,
IN ULONG FileType, IN ULONG FileType,
IN ULONGLONG FileSize IN ULONG FileSize,
IN ULONG OldFileSize
); );
BOOLEAN BOOLEAN
NTAPI NTAPI
CmpFileFlush( CmpFileFlush(
IN PHHIVE RegistryHive, IN PHHIVE RegistryHive,
IN ULONG FileType IN ULONG FileType,
IN OUT PLARGE_INTEGER FileOffset,
IN ULONG Length
); );
// //

View file

@ -36,14 +36,15 @@ CmpSetValueKeyNew(IN PHHIVE Hive,
{ {
/* Then make sure it's valid and dirty it */ /* Then make sure it's valid and dirty it */
ASSERT(Parent->ValueList.List != HCELL_NIL); ASSERT(Parent->ValueList.List != HCELL_NIL);
HvMarkCellDirty(Hive, Parent->ValueList.List); HvMarkCellDirty(Hive, Parent->ValueList.List, FALSE);
} }
/* Allocate avalue cell */ /* Allocate avalue cell */
ValueCell = HvAllocateCell(Hive, ValueCell = HvAllocateCell(Hive,
FIELD_OFFSET(CM_KEY_VALUE, Name) + FIELD_OFFSET(CM_KEY_VALUE, Name) +
CmpNameSize(Hive, ValueName), CmpNameSize(Hive, ValueName),
StorageType); StorageType,
HCELL_NIL);
if (ValueCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES; if (ValueCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES;
/* Get the actual data for it */ /* Get the actual data for it */
@ -126,7 +127,7 @@ CmpSetValueKeyExisting(IN PHHIVE Hive,
BOOLEAN WasSmall, IsSmall; BOOLEAN WasSmall, IsSmall;
/* Mark the old child cell dirty */ /* Mark the old child cell dirty */
HvMarkCellDirty(Hive, OldChild); HvMarkCellDirty(Hive, OldChild, FALSE);
/* See if this is a small or normal key */ /* See if this is a small or normal key */
WasSmall = CmpIsKeyValueSmall(&Length, Value->DataLength); WasSmall = CmpIsKeyValueSmall(&Length, Value->DataLength);
@ -190,7 +191,7 @@ CmpSetValueKeyExisting(IN PHHIVE Hive,
else else
{ {
/* This was a small key, or a key with no data, allocate a cell */ /* This was a small key, or a key with no data, allocate a cell */
NewCell = HvAllocateCell(Hive, DataSize, StorageType); NewCell = HvAllocateCell(Hive, DataSize, StorageType, HCELL_NIL);
if (NewCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES; if (NewCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES;
} }
@ -279,7 +280,7 @@ CmSetValueKey(IN PKEY_OBJECT KeyObject,
} }
/* Mark the cell dirty */ /* Mark the cell dirty */
HvMarkCellDirty(Hive, Cell); HvMarkCellDirty(Hive, Cell, FALSE);
/* Get the storage type */ /* Get the storage type */
Storage = HvGetCellType(Cell); Storage = HvGetCellType(Cell);
@ -392,9 +393,9 @@ CmDeleteValueKey(IN PKEY_OBJECT KeyObject,
if (ChildCell == HCELL_NIL) goto Quickie; if (ChildCell == HCELL_NIL) goto Quickie;
/* We found the value, mark all relevant cells dirty */ /* We found the value, mark all relevant cells dirty */
HvMarkCellDirty(Hive, Cell); HvMarkCellDirty(Hive, Cell, FALSE);
HvMarkCellDirty(Hive, Parent->ValueList.List); HvMarkCellDirty(Hive, Parent->ValueList.List, FALSE);
HvMarkCellDirty(Hive, ChildCell); HvMarkCellDirty(Hive, ChildCell, FALSE);
/* Get the key value */ /* Get the key value */
Value = (PCM_KEY_VALUE)HvGetCell(Hive,ChildCell); Value = (PCM_KEY_VALUE)HvGetCell(Hive,ChildCell);
@ -807,8 +808,8 @@ CmpQueryKeyData(IN PHHIVE Hive,
Info->KeyFullInformation.LastWriteTime = Node->LastWriteTime; Info->KeyFullInformation.LastWriteTime = Node->LastWriteTime;
Info->KeyFullInformation.TitleIndex = 0; Info->KeyFullInformation.TitleIndex = 0;
Info->KeyFullInformation.ClassLength = Node->ClassLength; Info->KeyFullInformation.ClassLength = Node->ClassLength;
Info->KeyFullInformation.SubKeys = Node->SubKeyCounts[HvStable] + Info->KeyFullInformation.SubKeys = Node->SubKeyCounts[Stable] +
Node->SubKeyCounts[HvVolatile]; Node->SubKeyCounts[Volatile];
Info->KeyFullInformation.Values = Node->ValueList.Count; Info->KeyFullInformation.Values = Node->ValueList.Count;
Info->KeyFullInformation.MaxNameLen = CmiGetMaxNameLength(Hive, Node); Info->KeyFullInformation.MaxNameLen = CmiGetMaxNameLength(Hive, Node);
Info->KeyFullInformation.MaxClassLen = CmiGetMaxClassLength(Hive, Node); Info->KeyFullInformation.MaxClassLen = CmiGetMaxClassLength(Hive, Node);
@ -1019,7 +1020,7 @@ CmDeleteKey(IN PKEY_OBJECT KeyObject)
} }
/* Check if we don't have any children */ /* Check if we don't have any children */
if (!(Node->SubKeyCounts[HvStable] + Node->SubKeyCounts[HvVolatile])) if (!(Node->SubKeyCounts[Stable] + Node->SubKeyCounts[Volatile]))
{ {
/* Get the parent and free the cell */ /* Get the parent and free the cell */
ParentCell = Node->Parent; ParentCell = Node->Parent;

View file

@ -122,17 +122,17 @@ CmGetSystemControlValues(IN PVOID SystemHiveData,
/* Initialize the Hive */ /* Initialize the Hive */
Status = HvInitialize(SystemHive, Status = HvInitialize(SystemHive,
HINIT_MEMORY_INPLACE, /* FIXME: Should be flat */ HINIT_FLAT,
HIVE_VOLATILE, HIVE_VOLATILE,
HFILE_TYPE_PRIMARY, HFILE_TYPE_PRIMARY,
(ULONG_PTR)SystemHiveData, SystemHiveData,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
1, 1,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL); NULL);
if (!NT_SUCCESS(Status)) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 1, 1, 0, 0); if (!NT_SUCCESS(Status)) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 1, 1, 0, 0);

View file

@ -27,7 +27,7 @@ ULONG CmpMaxIndexPerHblock =
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
static LONG LONG
NTAPI NTAPI
CmpDoCompareKeyName(IN PHHIVE Hive, CmpDoCompareKeyName(IN PHHIVE Hive,
IN PCUNICODE_STRING SearchName, IN PCUNICODE_STRING SearchName,
@ -63,7 +63,7 @@ CmpDoCompareKeyName(IN PHHIVE Hive,
return (Result == 0) ? Result : ((Result > 0) ? 1 : -1); return (Result == 0) ? Result : ((Result > 0) ? 1 : -1);
} }
static LONG LONG
NTAPI NTAPI
CmpCompareInIndex(IN PHHIVE Hive, CmpCompareInIndex(IN PHHIVE Hive,
IN PCUNICODE_STRING SearchName, IN PCUNICODE_STRING SearchName,
@ -139,7 +139,7 @@ CmpCompareInIndex(IN PHHIVE Hive,
return Result; return Result;
} }
static ULONG ULONG
NTAPI NTAPI
CmpFindSubKeyInRoot(IN PHHIVE Hive, CmpFindSubKeyInRoot(IN PHHIVE Hive,
IN PCM_KEY_INDEX Index, IN PCM_KEY_INDEX Index,
@ -355,7 +355,7 @@ Return:
return ReturnIndex; return ReturnIndex;
} }
static ULONG ULONG
NTAPI NTAPI
CmpFindSubKeyInLeaf(IN PHHIVE Hive, CmpFindSubKeyInLeaf(IN PHHIVE Hive,
IN PCM_KEY_INDEX Index, IN PCM_KEY_INDEX Index,
@ -620,35 +620,35 @@ CmpFindSubKeyByNumber(IN PHHIVE Hive,
HCELL_INDEX Result = HCELL_NIL; HCELL_INDEX Result = HCELL_NIL;
/* Check if it's in the stable list */ /* Check if it's in the stable list */
if (Number < Node->SubKeyCounts[HvStable]) if (Number < Node->SubKeyCounts[Stable])
{ {
/* Get the actual key index */ /* Get the actual key index */
Index = (PCM_KEY_INDEX)HvGetCell(Hive, Node->SubKeyLists[HvStable]); Index = (PCM_KEY_INDEX)HvGetCell(Hive, Node->SubKeyLists[Stable]);
if (!Index) return HCELL_NIL; if (!Index) return HCELL_NIL;
/* Do a search inside it */ /* Do a search inside it */
Result = CmpDoFindSubKeyByNumber(Hive, Index, Number); Result = CmpDoFindSubKeyByNumber(Hive, Index, Number);
/* Release the cell and return the result */ /* Release the cell and return the result */
HvReleaseCell(Hive, Node->SubKeyLists[HvStable]); HvReleaseCell(Hive, Node->SubKeyLists[Stable]);
return Result; return Result;
} }
else if (Hive->StorageTypeCount > HvVolatile) else if (Hive->StorageTypeCount > Volatile)
{ {
/* It's in the volatile list */ /* It's in the volatile list */
Number = Number - Node->SubKeyCounts[HvStable]; Number = Number - Node->SubKeyCounts[Stable];
if (Number < Node->SubKeyCounts[HvVolatile]) if (Number < Node->SubKeyCounts[Volatile])
{ {
/* Get the actual key index */ /* Get the actual key index */
Index = (PCM_KEY_INDEX)HvGetCell(Hive, Index = (PCM_KEY_INDEX)HvGetCell(Hive,
Node->SubKeyLists[HvVolatile]); Node->SubKeyLists[Volatile]);
if (!Index) return HCELL_NIL; if (!Index) return HCELL_NIL;
/* Do a search inside it */ /* Do a search inside it */
Result = CmpDoFindSubKeyByNumber(Hive, Index, Number); Result = CmpDoFindSubKeyByNumber(Hive, Index, Number);
/* Release the cell and return the result */ /* Release the cell and return the result */
HvReleaseCell(Hive, Node->SubKeyLists[HvVolatile]); HvReleaseCell(Hive, Node->SubKeyLists[Volatile]);
return Result; return Result;
} }
} }
@ -875,7 +875,7 @@ CmpMarkIndexDirty(IN PHHIVE Hive,
if (Child == HCELL_NIL) continue; if (Child == HCELL_NIL) continue;
/* We found it, mark the cell dirty */ /* We found it, mark the cell dirty */
HvMarkCellDirty(Hive, IndexCell); HvMarkCellDirty(Hive, IndexCell, FALSE);
/* Check if we had anything to release from before */ /* Check if we had anything to release from before */
if (CellToRelease != HCELL_NIL) if (CellToRelease != HCELL_NIL)
@ -918,7 +918,7 @@ CmpMarkIndexDirty(IN PHHIVE Hive,
} }
/* And mark the index cell dirty */ /* And mark the index cell dirty */
HvMarkCellDirty(Hive, IndexCell); HvMarkCellDirty(Hive, IndexCell, FALSE);
return TRUE; return TRUE;
} }
} }
@ -948,7 +948,7 @@ CmpAddToLeaf(IN PHHIVE Hive,
LONG Result; LONG Result;
/* Mark the leaf dirty */ /* Mark the leaf dirty */
HvMarkCellDirty(Hive, LeafCell); HvMarkCellDirty(Hive, LeafCell, FALSE);
/* Get the leaf cell */ /* Get the leaf cell */
Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell); Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell);
@ -1151,7 +1151,7 @@ CmpAddSubKey(IN PHHIVE Hive,
/* Create the compressed name and allocate it */ /* Create the compressed name and allocate it */
Name.Length = CmpCompressedNameSize(KeyNode->Name, KeyNode->NameLength); Name.Length = CmpCompressedNameSize(KeyNode->Name, KeyNode->NameLength);
Name.MaximumLength = Name.Length; Name.MaximumLength = Name.Length;
Name.Buffer = Hive->Allocate(Name.Length, TRUE); Name.Buffer = Hive->Allocate(Name.Length, TRUE, TAG_CM);
if (!Name.Buffer) if (!Name.Buffer)
{ {
/* Release the cell and fail */ /* Release the cell and fail */
@ -1193,7 +1193,7 @@ CmpAddSubKey(IN PHHIVE Hive,
if (!KeyNode->SubKeyCounts[Type]) if (!KeyNode->SubKeyCounts[Type])
{ {
/* Allocate a fast leaf */ /* Allocate a fast leaf */
IndexCell = HvAllocateCell(Hive, sizeof(CM_KEY_FAST_INDEX), Type); IndexCell = HvAllocateCell(Hive, sizeof(CM_KEY_FAST_INDEX), Type, HCELL_NIL);
if (IndexCell == HCELL_NIL) if (IndexCell == HCELL_NIL)
{ {
/* Not handled */ /* Not handled */
@ -1249,7 +1249,7 @@ CmpAddSubKey(IN PHHIVE Hive,
DPRINT("Doing Fast->Slow Leaf conversion\n"); DPRINT("Doing Fast->Slow Leaf conversion\n");
/* Mark this cell as dirty */ /* Mark this cell as dirty */
HvMarkCellDirty(Hive, CellToRelease); HvMarkCellDirty(Hive, CellToRelease, FALSE);
/* Convert */ /* Convert */
OldIndex = (PCM_KEY_FAST_INDEX)Index; OldIndex = (PCM_KEY_FAST_INDEX)Index;
@ -1270,7 +1270,8 @@ CmpAddSubKey(IN PHHIVE Hive,
IndexCell = HvAllocateCell(Hive, IndexCell = HvAllocateCell(Hive,
sizeof(CM_KEY_INDEX) + sizeof(CM_KEY_INDEX) +
sizeof(HCELL_INDEX), sizeof(HCELL_INDEX),
Type); Type,
HCELL_NIL);
if (IndexCell == HCELL_NIL) if (IndexCell == HCELL_NIL)
{ {
/* Not handled */ /* Not handled */
@ -1328,7 +1329,7 @@ CmpAddSubKey(IN PHHIVE Hive,
} }
/* If the name was compressed, free our copy */ /* If the name was compressed, free our copy */
if (IsCompressed) Hive->Free(Name.Buffer); if (IsCompressed) Hive->Free(Name.Buffer, 0);
/* Release all our cells */ /* Release all our cells */
if (IndexCell != HCELL_NIL) HvReleaseCell(Hive, IndexCell); if (IndexCell != HCELL_NIL) HvReleaseCell(Hive, IndexCell);

View file

@ -183,17 +183,17 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive,
/* Initialize it */ /* Initialize it */
Status = HvInitialize(&Hive->Hive, Status = HvInitialize(&Hive->Hive,
OperationType, OperationType,
HiveFlags,
FileType, FileType,
(ULONG_PTR)HiveData, HiveFlags,
Cluster, HiveData,
CmpAllocate, CmpAllocate,
CmpFree, CmpFree,
CmpFileRead,
CmpFileWrite,
CmpFileSetSize, CmpFileSetSize,
CmpFileWrite,
CmpFileRead,
CmpFileFlush, CmpFileFlush,
FileName); Cluster,
(PUNICODE_STRING)FileName);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
/* Clear allocations and fail */ /* Clear allocations and fail */

View file

@ -32,8 +32,8 @@ CmpMarkKeyDirty(IN PHHIVE Hive,
if (CheckNoSubkeys) if (CheckNoSubkeys)
{ {
/* Do them */ /* Do them */
ASSERT(CellData->u.KeyNode.SubKeyCounts[HvStable] == 0); ASSERT(CellData->u.KeyNode.SubKeyCounts[Stable] == 0);
ASSERT(CellData->u.KeyNode.SubKeyCounts[HvVolatile] == 0); ASSERT(CellData->u.KeyNode.SubKeyCounts[Volatile] == 0);
} }
/* If this is an exit hive, there's nothing to do */ /* If this is an exit hive, there's nothing to do */
@ -45,21 +45,21 @@ CmpMarkKeyDirty(IN PHHIVE Hive,
} }
/* Otherwise, mark it dirty and release it */ /* Otherwise, mark it dirty and release it */
HvMarkCellDirty(Hive, Cell); HvMarkCellDirty(Hive, Cell, FALSE);
HvReleaseCell(Hive, Cell); HvReleaseCell(Hive, Cell);
/* Check if we have a class */ /* Check if we have a class */
if (CellData->u.KeyNode.Class != HCELL_NIL) if (CellData->u.KeyNode.Class != HCELL_NIL)
{ {
/* Mark it dirty */ /* Mark it dirty */
HvMarkCellDirty(Hive, CellData->u.KeyNode.Class); HvMarkCellDirty(Hive, CellData->u.KeyNode.Class, FALSE);
} }
/* Check if we have security */ /* Check if we have security */
if (CellData->u.KeyNode.Security != HCELL_NIL) if (CellData->u.KeyNode.Security != HCELL_NIL)
{ {
/* Mark it dirty */ /* Mark it dirty */
HvMarkCellDirty(Hive, CellData->u.KeyNode.Security); HvMarkCellDirty(Hive, CellData->u.KeyNode.Security, FALSE);
/* Get the security data and release it */ /* Get the security data and release it */
SecurityData = HvGetCell(Hive, CellData->u.KeyNode.Security); SecurityData = HvGetCell(Hive, CellData->u.KeyNode.Security);
@ -67,15 +67,15 @@ CmpMarkKeyDirty(IN PHHIVE Hive,
HvReleaseCell(Hive, CellData->u.KeyNode.Security); HvReleaseCell(Hive, CellData->u.KeyNode.Security);
/* Mark the security links dirty too */ /* Mark the security links dirty too */
HvMarkCellDirty(Hive, SecurityData->u.KeySecurity.Flink); HvMarkCellDirty(Hive, SecurityData->u.KeySecurity.Flink, FALSE);
HvMarkCellDirty(Hive, SecurityData->u.KeySecurity.Blink); HvMarkCellDirty(Hive, SecurityData->u.KeySecurity.Blink, FALSE);
} }
/* Check if we have any values */ /* Check if we have any values */
if (CellData->u.KeyNode.ValueList.Count > 0) if (CellData->u.KeyNode.ValueList.Count > 0)
{ {
/* Dirty the value list */ /* Dirty the value list */
HvMarkCellDirty(Hive, CellData->u.KeyNode.ValueList.List); HvMarkCellDirty(Hive, CellData->u.KeyNode.ValueList.List, FALSE);
/* Get the list data itself, and release it */ /* Get the list data itself, and release it */
ListData = HvGetCell(Hive, CellData->u.KeyNode.ValueList.List); ListData = HvGetCell(Hive, CellData->u.KeyNode.ValueList.List);
@ -86,7 +86,7 @@ CmpMarkKeyDirty(IN PHHIVE Hive,
for (i = 0; i < CellData->u.KeyNode.ValueList.Count; i++) for (i = 0; i < CellData->u.KeyNode.ValueList.Count; i++)
{ {
/* Dirty each value */ /* Dirty each value */
HvMarkCellDirty(Hive, ListData->u.KeyList[i]); HvMarkCellDirty(Hive, ListData->u.KeyList[i], FALSE);
/* Get the value data and release it */ /* Get the value data and release it */
ValueData = HvGetCell(Hive, ListData->u.KeyList[i]); ValueData = HvGetCell(Hive, ListData->u.KeyList[i]);
@ -113,7 +113,7 @@ CmpMarkKeyDirty(IN PHHIVE Hive,
} }
/* Finally, mark the parent dirty */ /* Finally, mark the parent dirty */
HvMarkCellDirty(Hive, CellData->u.KeyNode.Parent); HvMarkCellDirty(Hive, CellData->u.KeyNode.Parent, FALSE);
return TRUE; return TRUE;
} }
@ -171,8 +171,8 @@ CmpFreeKeyByCell(IN PHHIVE Hive,
HvReleaseCell(Hive, Cell); HvReleaseCell(Hive, Cell);
/* Make sure we don't have subkeys */ /* Make sure we don't have subkeys */
ASSERT((CellData->u.KeyNode.SubKeyCounts[HvStable] + ASSERT((CellData->u.KeyNode.SubKeyCounts[Stable] +
CellData->u.KeyNode.SubKeyCounts[HvVolatile]) == 0); CellData->u.KeyNode.SubKeyCounts[Volatile]) == 0);
/* Check if we have to unlink */ /* Check if we have to unlink */
if (Unlink) if (Unlink)
@ -187,8 +187,8 @@ CmpFreeKeyByCell(IN PHHIVE Hive,
HvReleaseCell(Hive, CellData->u.KeyNode.Parent); HvReleaseCell(Hive, CellData->u.KeyNode.Parent);
/* Check if the parent node has no more subkeys */ /* Check if the parent node has no more subkeys */
if (!(ParentData->u.KeyNode.SubKeyCounts[HvStable] + if (!(ParentData->u.KeyNode.SubKeyCounts[Stable] +
ParentData->u.KeyNode.SubKeyCounts[HvVolatile])) ParentData->u.KeyNode.SubKeyCounts[Volatile]))
{ {
/* Then free the cached name/class lengths */ /* Then free the cached name/class lengths */
ParentData->u.KeyNode.MaxNameLen = 0; ParentData->u.KeyNode.MaxNameLen = 0;

View file

@ -108,14 +108,15 @@ CmpDoCreateChild(IN PHHIVE Hive,
} }
/* Get the storage type */ /* Get the storage type */
StorageType = HvStable; StorageType = Stable;
if (CreateOptions & REG_OPTION_VOLATILE) StorageType = HvVolatile; if (CreateOptions & REG_OPTION_VOLATILE) StorageType = Volatile;
/* Allocate the child */ /* Allocate the child */
*KeyCell = HvAllocateCell(Hive, *KeyCell = HvAllocateCell(Hive,
FIELD_OFFSET(CM_KEY_NODE, Name) + FIELD_OFFSET(CM_KEY_NODE, Name) +
CmpNameSize(Hive, Name), CmpNameSize(Hive, Name),
StorageType); StorageType,
HCELL_NIL);
if (*KeyCell == HCELL_NIL) if (*KeyCell == HCELL_NIL)
{ {
/* Fail */ /* Fail */
@ -140,7 +141,7 @@ CmpDoCreateChild(IN PHHIVE Hive,
if (Class->Length > 0) if (Class->Length > 0)
{ {
/* Allocate a class cell */ /* Allocate a class cell */
ClassCell = HvAllocateCell(Hive, Class->Length, StorageType); ClassCell = HvAllocateCell(Hive, Class->Length, StorageType, HCELL_NIL);
if (ClassCell == HCELL_NIL) if (ClassCell == HCELL_NIL)
{ {
/* Fail */ /* Fail */
@ -192,10 +193,10 @@ CmpDoCreateChild(IN PHHIVE Hive,
KeyNode->LastWriteTime = SystemTime; KeyNode->LastWriteTime = SystemTime;
KeyNode->Spare = 0; KeyNode->Spare = 0;
KeyNode->Parent = ParentCell; KeyNode->Parent = ParentCell;
KeyNode->SubKeyCounts[HvStable] = 0; KeyNode->SubKeyCounts[Stable] = 0;
KeyNode->SubKeyCounts[HvVolatile] = 0; KeyNode->SubKeyCounts[Volatile] = 0;
KeyNode->SubKeyLists[HvStable] = HCELL_NIL; KeyNode->SubKeyLists[Stable] = HCELL_NIL;
KeyNode->SubKeyLists[HvVolatile] = HCELL_NIL; KeyNode->SubKeyLists[Volatile] = HCELL_NIL;
KeyNode->ValueList.Count = 0; KeyNode->ValueList.Count = 0;
KeyNode->ValueList.List = HCELL_NIL; KeyNode->ValueList.List = HCELL_NIL;
KeyNode->Security = HCELL_NIL; KeyNode->Security = HCELL_NIL;
@ -302,7 +303,7 @@ CmpDoCreate(IN PHHIVE Hive,
/* Get the parent type */ /* Get the parent type */
ParentType = HvGetCellType(Cell); ParentType = HvGetCellType(Cell);
if ((ParentType == HvVolatile) && !(CreateOptions & REG_OPTION_VOLATILE)) if ((ParentType == Volatile) && !(CreateOptions & REG_OPTION_VOLATILE))
{ {
/* Children of volatile parents must also be volatile */ /* Children of volatile parents must also be volatile */
ASSERT(FALSE); ASSERT(FALSE);
@ -320,7 +321,7 @@ CmpDoCreate(IN PHHIVE Hive,
} }
/* Make the cell dirty for now */ /* Make the cell dirty for now */
HvMarkCellDirty(Hive, Cell); HvMarkCellDirty(Hive, Cell, FALSE);
/* Do the actual create operation */ /* Do the actual create operation */
Status = CmpDoCreateChild(Hive, Status = CmpDoCreateChild(Hive,

View file

@ -509,7 +509,7 @@ CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
} }
/* Save the boot type */ /* Save the boot type */
if (SystemHive) CmpBootType = SystemHive->Hive.HiveHeader->BootType; if (SystemHive) CmpBootType = SystemHive->Hive.BaseBlock->BootType;
/* Are we in self-healing mode? */ /* Are we in self-healing mode? */
if (!CmSelfHeal) if (!CmSelfHeal)
@ -597,11 +597,12 @@ CmpCreateRootNode(IN PHHIVE Hive,
*Index = HvAllocateCell(Hive, *Index = HvAllocateCell(Hive,
FIELD_OFFSET(CM_KEY_NODE, Name) + FIELD_OFFSET(CM_KEY_NODE, Name) +
CmpNameSize(Hive, &KeyName), CmpNameSize(Hive, &KeyName),
HvStable); // FIXME: , HCELL_NIL); Stable,
HCELL_NIL);
if (*Index == HCELL_NIL) return FALSE; if (*Index == HCELL_NIL) return FALSE;
/* Set the cell index and get the data */ /* Set the cell index and get the data */
Hive->HiveHeader->RootCell = *Index; Hive->BaseBlock->RootCell = *Index;
KeyCell = (PCM_KEY_NODE)HvGetCell(Hive, *Index); KeyCell = (PCM_KEY_NODE)HvGetCell(Hive, *Index);
if (!KeyCell) return FALSE; if (!KeyCell) return FALSE;
@ -611,10 +612,10 @@ CmpCreateRootNode(IN PHHIVE Hive,
KeQuerySystemTime(&SystemTime); KeQuerySystemTime(&SystemTime);
KeyCell->LastWriteTime = SystemTime; KeyCell->LastWriteTime = SystemTime;
KeyCell->Parent = HCELL_NIL; KeyCell->Parent = HCELL_NIL;
KeyCell->SubKeyCounts[HvStable] = 0; KeyCell->SubKeyCounts[Stable] = 0;
KeyCell->SubKeyCounts[HvVolatile] = 0; KeyCell->SubKeyCounts[Volatile] = 0;
KeyCell->SubKeyLists[HvStable] = HCELL_NIL; KeyCell->SubKeyLists[Stable] = HCELL_NIL;
KeyCell->SubKeyLists[HvVolatile] = HCELL_NIL; KeyCell->SubKeyLists[Volatile] = HCELL_NIL;
KeyCell->ValueList.Count = 0; KeyCell->ValueList.Count = 0;
KeyCell->ValueList.List = HCELL_NIL; KeyCell->ValueList.List = HCELL_NIL;
KeyCell->Security = HCELL_NIL; KeyCell->Security = HCELL_NIL;
@ -662,6 +663,7 @@ CmpCreateRegistryRoot(VOID)
if (!CmpCreateRootNode(&CmiVolatileHive->Hive, L"REGISTRY", &RootIndex)) if (!CmpCreateRootNode(&CmiVolatileHive->Hive, L"REGISTRY", &RootIndex))
{ {
/* We failed */ /* We failed */
DPRINT1("Fail\n");
return FALSE; return FALSE;
} }

View file

@ -33,7 +33,7 @@ CmpMarkValueDataDirty(IN PHHIVE Hive,
ASSERT_VALUE_BIG(Hive, KeySize); ASSERT_VALUE_BIG(Hive, KeySize);
/* Normal value, just mark it dirty */ /* Normal value, just mark it dirty */
HvMarkCellDirty(Hive, Value->Data); HvMarkCellDirty(Hive, Value->Data, FALSE);
} }
/* Operation complete */ /* Operation complete */
@ -244,11 +244,11 @@ CmpAddValueToList(IN PHHIVE Hive,
else else
{ {
/* This is our first child, so allocate a single cell */ /* This is our first child, so allocate a single cell */
ListCell = HvAllocateCell(Hive, sizeof(HCELL_INDEX), Type); ListCell = HvAllocateCell(Hive, sizeof(HCELL_INDEX), Type, HCELL_NIL);
} }
/* Fail if we couldn't get a cell */ /* Fail if we couldn't get a cell */
if (ListCell == HCELL_NULL) return STATUS_INSUFFICIENT_RESOURCES; if (ListCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES;
/* Set this cell as the child list's list cell */ /* Set this cell as the child list's list cell */
ChildList->List = ListCell; ChildList->List = ListCell;
@ -293,7 +293,7 @@ CmpSetValueDataNew(IN PHHIVE Hive,
ASSERT_VALUE_BIG(Hive, DataSize); ASSERT_VALUE_BIG(Hive, DataSize);
/* Allocate a data cell */ /* Allocate a data cell */
*DataCell = HvAllocateCell(Hive, DataSize, StorageType); *DataCell = HvAllocateCell(Hive, DataSize, StorageType, HCELL_NIL);
if (*DataCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES; if (*DataCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES;
/* Get the actual data */ /* Get the actual data */

View file

@ -53,16 +53,18 @@ CmpCreateEvent(IN EVENT_TYPE EventType,
PVOID PVOID
NTAPI NTAPI
CmpAllocate(IN ULONG Size, CmpAllocate(IN ULONG Size,
IN BOOLEAN Paged) IN BOOLEAN Paged,
IN ULONG Tag)
{ {
return ExAllocatePoolWithTag(Paged ? PagedPool : NonPagedPool, return ExAllocatePoolWithTag(Paged ? PagedPool : NonPagedPool,
Size, Size,
TAG('R','E','G',' ')); Tag);
} }
VOID VOID
NTAPI NTAPI
CmpFree(IN PVOID Ptr) CmpFree(IN PVOID Ptr,
IN ULONG Quota)
{ {
ExFreePool(Ptr); ExFreePool(Ptr);
} }
@ -71,17 +73,17 @@ BOOLEAN
NTAPI NTAPI
CmpFileRead(IN PHHIVE RegistryHive, CmpFileRead(IN PHHIVE RegistryHive,
IN ULONG FileType, IN ULONG FileType,
IN ULONGLONG FileOffset, IN PULONG FileOffset,
OUT PVOID Buffer, OUT PVOID Buffer,
IN SIZE_T BufferLength) IN SIZE_T BufferLength)
{ {
PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive; PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive;
HANDLE HiveHandle = FileType == HV_TYPE_PRIMARY ? CmHive->HiveHandle : CmHive->LogHandle; HANDLE HiveHandle = FileType == HFILE_TYPE_PRIMARY ? CmHive->HiveHandle : CmHive->LogHandle;
LARGE_INTEGER _FileOffset; LARGE_INTEGER _FileOffset;
IO_STATUS_BLOCK IoStatusBlock; IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status; NTSTATUS Status;
_FileOffset.QuadPart = FileOffset; _FileOffset.QuadPart = *FileOffset;
Status = ZwReadFile(HiveHandle, 0, 0, 0, &IoStatusBlock, Status = ZwReadFile(HiveHandle, 0, 0, 0, &IoStatusBlock,
Buffer, BufferLength, &_FileOffset, 0); Buffer, BufferLength, &_FileOffset, 0);
return NT_SUCCESS(Status) ? TRUE : FALSE; return NT_SUCCESS(Status) ? TRUE : FALSE;
@ -91,17 +93,17 @@ BOOLEAN
NTAPI NTAPI
CmpFileWrite(IN PHHIVE RegistryHive, CmpFileWrite(IN PHHIVE RegistryHive,
IN ULONG FileType, IN ULONG FileType,
IN ULONGLONG FileOffset, IN PULONG FileOffset,
IN PVOID Buffer, IN PVOID Buffer,
IN SIZE_T BufferLength) IN SIZE_T BufferLength)
{ {
PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive; PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive;
HANDLE HiveHandle = FileType == HV_TYPE_PRIMARY ? CmHive->HiveHandle : CmHive->LogHandle; HANDLE HiveHandle = FileType == HFILE_TYPE_PRIMARY ? CmHive->HiveHandle : CmHive->LogHandle;
LARGE_INTEGER _FileOffset; LARGE_INTEGER _FileOffset;
IO_STATUS_BLOCK IoStatusBlock; IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status; NTSTATUS Status;
_FileOffset.QuadPart = FileOffset; _FileOffset.QuadPart = *FileOffset;
Status = ZwWriteFile(HiveHandle, 0, 0, 0, &IoStatusBlock, Status = ZwWriteFile(HiveHandle, 0, 0, 0, &IoStatusBlock,
Buffer, BufferLength, &_FileOffset, 0); Buffer, BufferLength, &_FileOffset, 0);
return NT_SUCCESS(Status) ? TRUE : FALSE; return NT_SUCCESS(Status) ? TRUE : FALSE;
@ -111,10 +113,11 @@ BOOLEAN
NTAPI NTAPI
CmpFileSetSize(IN PHHIVE RegistryHive, CmpFileSetSize(IN PHHIVE RegistryHive,
IN ULONG FileType, IN ULONG FileType,
IN ULONGLONG FileSize) IN ULONG FileSize,
IN ULONG OldFileSize)
{ {
PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive; PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive;
HANDLE HiveHandle = FileType == HV_TYPE_PRIMARY ? CmHive->HiveHandle : CmHive->LogHandle; HANDLE HiveHandle = FileType == HFILE_TYPE_PRIMARY ? CmHive->HiveHandle : CmHive->LogHandle;
FILE_END_OF_FILE_INFORMATION EndOfFileInfo; FILE_END_OF_FILE_INFORMATION EndOfFileInfo;
FILE_ALLOCATION_INFORMATION FileAllocationInfo; FILE_ALLOCATION_INFORMATION FileAllocationInfo;
IO_STATUS_BLOCK IoStatusBlock; IO_STATUS_BLOCK IoStatusBlock;
@ -142,10 +145,12 @@ CmpFileSetSize(IN PHHIVE RegistryHive,
BOOLEAN BOOLEAN
NTAPI NTAPI
CmpFileFlush(IN PHHIVE RegistryHive, CmpFileFlush(IN PHHIVE RegistryHive,
IN ULONG FileType) IN ULONG FileType,
IN OUT PLARGE_INTEGER FileOffset,
IN ULONG Length)
{ {
PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive; PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive;
HANDLE HiveHandle = FileType == HV_TYPE_PRIMARY ? CmHive->HiveHandle : CmHive->LogHandle; HANDLE HiveHandle = FileType == HFILE_TYPE_PRIMARY ? CmHive->HiveHandle : CmHive->LogHandle;
IO_STATUS_BLOCK IoStatusBlock; IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status; NTSTATUS Status;

View file

@ -30,7 +30,8 @@ static PVOID
NTAPI NTAPI
CmpAllocate( CmpAllocate(
IN SIZE_T Size, IN SIZE_T Size,
IN BOOLEAN Paged) IN BOOLEAN Paged,
IN ULONG Tag)
{ {
return (PVOID) malloc((size_t)Size); return (PVOID) malloc((size_t)Size);
} }
@ -38,7 +39,8 @@ CmpAllocate(
static VOID static VOID
NTAPI NTAPI
CmpFree( CmpFree(
IN PVOID Ptr) IN PVOID Ptr,
IN ULONG Quota)
{ {
free(Ptr); free(Ptr);
} }
@ -48,7 +50,7 @@ NTAPI
CmpFileRead( CmpFileRead(
IN PHHIVE RegistryHive, IN PHHIVE RegistryHive,
IN ULONG FileType, IN ULONG FileType,
IN ULONGLONG FileOffset, IN PULONG FileOffset,
OUT PVOID Buffer, OUT PVOID Buffer,
IN SIZE_T BufferLength) IN SIZE_T BufferLength)
{ {
@ -61,13 +63,13 @@ NTAPI
CmpFileWrite( CmpFileWrite(
IN PHHIVE RegistryHive, IN PHHIVE RegistryHive,
IN ULONG FileType, IN ULONG FileType,
IN ULONGLONG FileOffset, IN PULONG FileOffset,
IN PVOID Buffer, IN PVOID Buffer,
IN SIZE_T BufferLength) IN SIZE_T BufferLength)
{ {
PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive; PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive;
FILE *File = CmHive->HiveHandle; FILE *File = CmHive->HiveHandle;
if (0 != fseek (File, (long)FileOffset, SEEK_SET)) if (0 != fseek (File, *FileOffset, SEEK_SET))
return FALSE; return FALSE;
return BufferLength == fwrite (Buffer, 1, BufferLength, File); return BufferLength == fwrite (Buffer, 1, BufferLength, File);
} }
@ -77,7 +79,8 @@ NTAPI
CmpFileSetSize( CmpFileSetSize(
IN PHHIVE RegistryHive, IN PHHIVE RegistryHive,
IN ULONG FileType, IN ULONG FileType,
IN ULONGLONG FileSize) IN ULONG FileSize,
IN ULONG OldFileSize)
{ {
DPRINT1("CmpFileSetSize() unimplemented\n"); DPRINT1("CmpFileSetSize() unimplemented\n");
return FALSE; return FALSE;
@ -87,7 +90,9 @@ static BOOLEAN
NTAPI NTAPI
CmpFileFlush( CmpFileFlush(
IN PHHIVE RegistryHive, IN PHHIVE RegistryHive,
IN ULONG FileType) IN ULONG FileType,
PLARGE_INTEGER FileOffset,
ULONG Length)
{ {
PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive; PEREGISTRY_HIVE CmHive = (PEREGISTRY_HIVE)RegistryHive;
FILE *File = CmHive->HiveHandle; FILE *File = CmHive->HiveHandle;
@ -106,12 +111,19 @@ CmiInitializeTempHive(
DPRINT("Hive 0x%p\n", Hive); DPRINT("Hive 0x%p\n", Hive);
Status = HvInitialize( Status = HvInitialize(&Hive->Hive,
&Hive->Hive, HINIT_CREATE,
HV_OPERATION_CREATE_HIVE, 0, 0, 0, 0, 0,
CmpAllocate, CmpFree, 0,
CmpFileRead, CmpFileWrite, CmpFileSetSize, 0,
CmpFileFlush, NULL); CmpAllocate,
CmpFree,
CmpFileSetSize,
CmpFileWrite,
CmpFileRead,
CmpFileFlush,
1,
NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return Status; return Status;
@ -140,7 +152,7 @@ CmiAddKeyToHashTable(
IN PEREGISTRY_HIVE RegistryHive, IN PEREGISTRY_HIVE RegistryHive,
IN OUT PHASH_TABLE_CELL HashCell, IN OUT PHASH_TABLE_CELL HashCell,
IN PCM_KEY_NODE KeyCell, IN PCM_KEY_NODE KeyCell,
IN HV_STORAGE_TYPE StorageType, IN HSTORAGE_TYPE StorageType,
IN PCM_KEY_NODE NewKeyCell, IN PCM_KEY_NODE NewKeyCell,
IN HCELL_INDEX NKBOffset) IN HCELL_INDEX NKBOffset)
{ {
@ -171,7 +183,7 @@ CmiAddKeyToHashTable(
HashCell->Table[i].KeyOffset = NKBOffset; HashCell->Table[i].KeyOffset = NKBOffset;
HashCell->Table[i].HashValue = HashValue; HashCell->Table[i].HashValue = HashValue;
HvMarkCellDirty(&RegistryHive->Hive, KeyCell->SubKeyLists[StorageType]); HvMarkCellDirty(&RegistryHive->Hive, KeyCell->SubKeyLists[StorageType], FALSE);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -181,7 +193,7 @@ CmiAllocateHashTableCell (
OUT PHASH_TABLE_CELL *HashBlock, OUT PHASH_TABLE_CELL *HashBlock,
OUT HCELL_INDEX *HBOffset, OUT HCELL_INDEX *HBOffset,
IN USHORT SubKeyCount, IN USHORT SubKeyCount,
IN HV_STORAGE_TYPE Storage) IN HSTORAGE_TYPE Storage)
{ {
PHASH_TABLE_CELL NewHashBlock; PHASH_TABLE_CELL NewHashBlock;
ULONG NewHashSize; ULONG NewHashSize;
@ -191,16 +203,16 @@ CmiAllocateHashTableCell (
*HashBlock = NULL; *HashBlock = NULL;
NewHashSize = sizeof(HASH_TABLE_CELL) + NewHashSize = sizeof(HASH_TABLE_CELL) +
(SubKeyCount * sizeof(HASH_RECORD)); (SubKeyCount * sizeof(HASH_RECORD));
*HBOffset = HvAllocateCell(&RegistryHive->Hive, NewHashSize, Storage); *HBOffset = HvAllocateCell(&RegistryHive->Hive, NewHashSize, Storage, HCELL_NIL);
if (*HBOffset == HCELL_NULL) if (*HBOffset == HCELL_NIL)
{ {
Status = STATUS_INSUFFICIENT_RESOURCES; Status = STATUS_INSUFFICIENT_RESOURCES;
} }
else else
{ {
ASSERT(SubKeyCount <= USHORT_MAX); ASSERT(SubKeyCount <= USHORT_MAX);
NewHashBlock = HvGetCell (&RegistryHive->Hive, *HBOffset); NewHashBlock = (PHASH_TABLE_CELL)HvGetCell (&RegistryHive->Hive, *HBOffset);
NewHashBlock->Id = REG_HASH_TABLE_CELL_ID; NewHashBlock->Id = REG_HASH_TABLE_CELL_ID;
NewHashBlock->HashTableSize = SubKeyCount; NewHashBlock->HashTableSize = SubKeyCount;
*HashBlock = NewHashBlock; *HashBlock = NewHashBlock;
@ -227,7 +239,7 @@ CmiAddSubKey(
USHORT NameSize; USHORT NameSize;
PWSTR NamePtr; PWSTR NamePtr;
BOOLEAN Packable; BOOLEAN Packable;
HV_STORAGE_TYPE Storage; HSTORAGE_TYPE Storage;
ULONG i; ULONG i;
DPRINT("CmiAddSubKey(%p '%wZ')\n", RegistryHive, SubKeyName); DPRINT("CmiAddSubKey(%p '%wZ')\n", RegistryHive, SubKeyName);
@ -265,16 +277,16 @@ CmiAddSubKey(
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
Storage = (CreateOptions & REG_OPTION_VOLATILE) ? HvVolatile : HvStable; Storage = (CreateOptions & REG_OPTION_VOLATILE) ? Volatile : Stable;
NewBlockSize = sizeof(CM_KEY_NODE) + NameSize; NewBlockSize = sizeof(CM_KEY_NODE) + NameSize;
NKBOffset = HvAllocateCell(&RegistryHive->Hive, NewBlockSize, Storage); NKBOffset = HvAllocateCell(&RegistryHive->Hive, NewBlockSize, Storage, HCELL_NIL);
if (NKBOffset == HCELL_NULL) if (NKBOffset == HCELL_NIL)
{ {
Status = STATUS_INSUFFICIENT_RESOURCES; Status = STATUS_INSUFFICIENT_RESOURCES;
} }
else else
{ {
NewKeyCell = HvGetCell (&RegistryHive->Hive, NKBOffset); NewKeyCell = (PCM_KEY_NODE)HvGetCell (&RegistryHive->Hive, NKBOffset);
NewKeyCell->Id = REG_KEY_CELL_ID; NewKeyCell->Id = REG_KEY_CELL_ID;
if (CreateOptions & REG_OPTION_VOLATILE) if (CreateOptions & REG_OPTION_VOLATILE)
{ {
@ -285,15 +297,15 @@ CmiAddSubKey(
NewKeyCell->Flags = 0; NewKeyCell->Flags = 0;
} }
KeQuerySystemTime(&NewKeyCell->LastWriteTime); KeQuerySystemTime(&NewKeyCell->LastWriteTime);
NewKeyCell->Parent = HCELL_NULL; NewKeyCell->Parent = HCELL_NIL;
NewKeyCell->SubKeyCounts[HvStable] = 0; NewKeyCell->SubKeyCounts[Stable] = 0;
NewKeyCell->SubKeyCounts[HvVolatile] = 0; NewKeyCell->SubKeyCounts[Volatile] = 0;
NewKeyCell->SubKeyLists[HvStable] = HCELL_NULL; NewKeyCell->SubKeyLists[Stable] = HCELL_NIL;
NewKeyCell->SubKeyLists[HvVolatile] = HCELL_NULL; NewKeyCell->SubKeyLists[Volatile] = HCELL_NIL;
NewKeyCell->ValueList.Count = 0; NewKeyCell->ValueList.Count = 0;
NewKeyCell->ValueList.List = HCELL_NULL; NewKeyCell->ValueList.List = HCELL_NIL;
NewKeyCell->SecurityKeyOffset = HCELL_NULL; NewKeyCell->SecurityKeyOffset = HCELL_NIL;
NewKeyCell->ClassNameOffset = HCELL_NULL; NewKeyCell->ClassNameOffset = HCELL_NIL;
/* Pack the key name */ /* Pack the key name */
NewKeyCell->NameSize = NameSize; NewKeyCell->NameSize = NameSize;
@ -321,7 +333,7 @@ CmiAddSubKey(
return Status; return Status;
} }
if (ParentKeyCell->SubKeyLists[Storage] == HCELL_NULL) if (ParentKeyCell->SubKeyLists[Storage] == HCELL_NIL)
{ {
Status = CmiAllocateHashTableCell ( Status = CmiAllocateHashTableCell (
RegistryHive, RegistryHive,
@ -336,7 +348,7 @@ CmiAddSubKey(
} }
else else
{ {
HashBlock = HvGetCell ( HashBlock = (PHASH_TABLE_CELL)HvGetCell (
&RegistryHive->Hive, &RegistryHive->Hive,
ParentKeyCell->SubKeyLists[Storage]); ParentKeyCell->SubKeyLists[Storage]);
ASSERT(HashBlock->Id == REG_HASH_TABLE_CELL_ID); ASSERT(HashBlock->Id == REG_HASH_TABLE_CELL_ID);
@ -387,7 +399,7 @@ CmiAddSubKey(
} }
KeQuerySystemTime(&ParentKeyCell->LastWriteTime); KeQuerySystemTime(&ParentKeyCell->LastWriteTime);
HvMarkCellDirty(&RegistryHive->Hive, ParentKeyCellOffset); HvMarkCellDirty(&RegistryHive->Hive, ParentKeyCellOffset, FALSE);
return Status; return Status;
} }
@ -521,16 +533,16 @@ CmiScanForSubKey(
*pSubKeyCell = NULL; *pSubKeyCell = NULL;
for (Storage = HvStable; Storage < HvMaxStorageType; Storage++) for (Storage = Stable; Storage < HTYPE_COUNT; Storage++)
{ {
if (KeyCell->SubKeyLists[Storage] == HCELL_NULL) if (KeyCell->SubKeyLists[Storage] == HCELL_NIL)
{ {
/* The key does not have any subkeys */ /* The key does not have any subkeys */
continue; continue;
} }
/* Get hash table */ /* Get hash table */
HashBlock = HvGetCell (&RegistryHive->Hive, KeyCell->SubKeyLists[Storage]); HashBlock = (PHASH_TABLE_CELL)HvGetCell (&RegistryHive->Hive, KeyCell->SubKeyLists[Storage]);
if (!HashBlock || HashBlock->Id != REG_HASH_TABLE_CELL_ID) if (!HashBlock || HashBlock->Id != REG_HASH_TABLE_CELL_ID)
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
@ -541,7 +553,7 @@ CmiScanForSubKey(
if ((HashBlock->Table[i].HashValue == 0 if ((HashBlock->Table[i].HashValue == 0
|| CmiCompareHashI(SubKeyName, (PCHAR)&HashBlock->Table[i].HashValue))) || CmiCompareHashI(SubKeyName, (PCHAR)&HashBlock->Table[i].HashValue)))
{ {
CurSubKeyCell = HvGetCell ( CurSubKeyCell = (PCM_KEY_NODE)HvGetCell (
&RegistryHive->Hive, &RegistryHive->Hive,
HashBlock->Table[i].KeyOffset); HashBlock->Table[i].KeyOffset);
@ -558,7 +570,7 @@ CmiScanForSubKey(
if ((HashBlock->Table[i].HashValue == 0 if ((HashBlock->Table[i].HashValue == 0
|| CmiCompareHash(SubKeyName, (PCHAR)&HashBlock->Table[i].HashValue))) || CmiCompareHash(SubKeyName, (PCHAR)&HashBlock->Table[i].HashValue)))
{ {
CurSubKeyCell = HvGetCell ( CurSubKeyCell = (PCM_KEY_NODE)HvGetCell (
&RegistryHive->Hive, &RegistryHive->Hive,
HashBlock->Table[i].KeyOffset); HashBlock->Table[i].KeyOffset);
@ -603,7 +615,7 @@ CmiAllocateValueCell(
OUT PCM_KEY_VALUE *ValueCell, OUT PCM_KEY_VALUE *ValueCell,
OUT HCELL_INDEX *VBOffset, OUT HCELL_INDEX *VBOffset,
IN PCUNICODE_STRING ValueName, IN PCUNICODE_STRING ValueName,
IN HV_STORAGE_TYPE Storage) IN HSTORAGE_TYPE Storage)
{ {
PCM_KEY_VALUE NewValueCell; PCM_KEY_VALUE NewValueCell;
BOOLEAN Packable; BOOLEAN Packable;
@ -616,15 +628,15 @@ CmiAllocateValueCell(
DPRINT("ValueName->Length %lu NameSize %lu\n", ValueName->Length, NameSize); DPRINT("ValueName->Length %lu NameSize %lu\n", ValueName->Length, NameSize);
*VBOffset = HvAllocateCell(&RegistryHive->Hive, sizeof(CM_KEY_VALUE) + NameSize, Storage); *VBOffset = HvAllocateCell(&RegistryHive->Hive, sizeof(CM_KEY_VALUE) + NameSize, Storage, HCELL_NIL);
if (*VBOffset == HCELL_NULL) if (*VBOffset == HCELL_NIL)
{ {
Status = STATUS_INSUFFICIENT_RESOURCES; Status = STATUS_INSUFFICIENT_RESOURCES;
} }
else else
{ {
ASSERT(NameSize <= USHORT_MAX); ASSERT(NameSize <= USHORT_MAX);
NewValueCell = HvGetCell (&RegistryHive->Hive, *VBOffset); NewValueCell = (PCM_KEY_VALUE)HvGetCell (&RegistryHive->Hive, *VBOffset);
NewValueCell->Id = REG_VALUE_CELL_ID; NewValueCell->Id = REG_VALUE_CELL_ID;
NewValueCell->NameSize = (USHORT)NameSize; NewValueCell->NameSize = (USHORT)NameSize;
if (Packable) if (Packable)
@ -645,7 +657,7 @@ CmiAllocateValueCell(
} }
NewValueCell->DataType = 0; NewValueCell->DataType = 0;
NewValueCell->DataSize = 0; NewValueCell->DataSize = 0;
NewValueCell->DataOffset = HCELL_NULL; NewValueCell->DataOffset = HCELL_NIL;
*ValueCell = NewValueCell; *ValueCell = NewValueCell;
} }
@ -666,23 +678,23 @@ CmiAddValueKey(
HCELL_INDEX ValueListCellOffset; HCELL_INDEX ValueListCellOffset;
HCELL_INDEX NewValueCellOffset; HCELL_INDEX NewValueCellOffset;
ULONG CellSize; ULONG CellSize;
HV_STORAGE_TYPE Storage; HSTORAGE_TYPE Storage;
NTSTATUS Status; NTSTATUS Status;
Storage = (KeyCell->Flags & REG_KEY_VOLATILE_CELL) ? HvVolatile : HvStable; Storage = (KeyCell->Flags & REG_KEY_VOLATILE_CELL) ? Volatile : Stable;
if (KeyCell->ValueList.List == HCELL_NULL) if (KeyCell->ValueList.List == HCELL_NIL)
{ {
/* Allocate some room for the value list */ /* Allocate some room for the value list */
CellSize = sizeof(VALUE_LIST_CELL) + (3 * sizeof(HCELL_INDEX)); CellSize = sizeof(VALUE_LIST_CELL) + (3 * sizeof(HCELL_INDEX));
ValueListCellOffset = HvAllocateCell(&RegistryHive->Hive, CellSize, Storage); ValueListCellOffset = HvAllocateCell(&RegistryHive->Hive, CellSize, Storage, HCELL_NIL);
if (ValueListCellOffset == HCELL_NULL) if (ValueListCellOffset == HCELL_NIL)
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
ValueListCell = HvGetCell(&RegistryHive->Hive, ValueListCellOffset); ValueListCell = (PVALUE_LIST_CELL)HvGetCell(&RegistryHive->Hive, ValueListCellOffset);
if (!ValueListCell) if (!ValueListCell)
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
KeyCell->ValueList.List = ValueListCellOffset; KeyCell->ValueList.List = ValueListCellOffset;
HvMarkCellDirty(&RegistryHive->Hive, KeyCellOffset); HvMarkCellDirty(&RegistryHive->Hive, KeyCellOffset, FALSE);
} }
else else
{ {
@ -695,14 +707,14 @@ CmiAddValueKey(
{ {
CellSize *= 2; CellSize *= 2;
ValueListCellOffset = HvReallocateCell(&RegistryHive->Hive, KeyCell->ValueList.List, CellSize); ValueListCellOffset = HvReallocateCell(&RegistryHive->Hive, KeyCell->ValueList.List, CellSize);
if (ValueListCellOffset == HCELL_NULL) if (ValueListCellOffset == HCELL_NIL)
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
ValueListCell = HvGetCell(&RegistryHive->Hive, ValueListCellOffset); ValueListCell = (PVALUE_LIST_CELL)HvGetCell(&RegistryHive->Hive, ValueListCellOffset);
if (!ValueListCell) if (!ValueListCell)
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
KeyCell->ValueList.List = ValueListCellOffset; KeyCell->ValueList.List = ValueListCellOffset;
HvMarkCellDirty(&RegistryHive->Hive, KeyCellOffset); HvMarkCellDirty(&RegistryHive->Hive, KeyCellOffset, FALSE);
} }
} }
@ -718,9 +730,9 @@ CmiAddValueKey(
ValueListCell->ValueOffset[KeyCell->ValueList.Count] = NewValueCellOffset; ValueListCell->ValueOffset[KeyCell->ValueList.Count] = NewValueCellOffset;
KeyCell->ValueList.Count++; KeyCell->ValueList.Count++;
HvMarkCellDirty(&RegistryHive->Hive, KeyCellOffset); HvMarkCellDirty(&RegistryHive->Hive, KeyCellOffset, FALSE);
HvMarkCellDirty(&RegistryHive->Hive, KeyCell->ValueList.List); HvMarkCellDirty(&RegistryHive->Hive, KeyCell->ValueList.List, FALSE);
HvMarkCellDirty(&RegistryHive->Hive, NewValueCellOffset); HvMarkCellDirty(&RegistryHive->Hive, NewValueCellOffset, FALSE);
*pValueCell = NewValueCell; *pValueCell = NewValueCell;
*pValueCellOffset = NewValueCellOffset; *pValueCellOffset = NewValueCellOffset;
@ -779,21 +791,21 @@ CmiScanForValueKey(
ULONG i; ULONG i;
*pValueCell = NULL; *pValueCell = NULL;
*pValueCellOffset = HCELL_NULL; *pValueCellOffset = HCELL_NIL;
/* The key does not have any values */ /* The key does not have any values */
if (KeyCell->ValueList.List == HCELL_NULL) if (KeyCell->ValueList.List == HCELL_NIL)
{ {
return STATUS_OBJECT_NAME_NOT_FOUND; return STATUS_OBJECT_NAME_NOT_FOUND;
} }
ValueListCell = HvGetCell(&RegistryHive->Hive, KeyCell->ValueList.List); ValueListCell = (PVALUE_LIST_CELL)HvGetCell(&RegistryHive->Hive, KeyCell->ValueList.List);
VERIFY_VALUE_LIST_CELL(ValueListCell); VERIFY_VALUE_LIST_CELL(ValueListCell);
for (i = 0; i < KeyCell->ValueList.Count; i++) for (i = 0; i < KeyCell->ValueList.Count; i++)
{ {
CurValueCell = HvGetCell( CurValueCell = (PCM_KEY_VALUE)HvGetCell(
&RegistryHive->Hive, &RegistryHive->Hive,
ValueListCell->ValueOffset[i]); ValueListCell->ValueOffset[i]);

View file

@ -76,7 +76,7 @@ CreateInMemoryStructure(
Key->RegistryHive = RegistryHive; Key->RegistryHive = RegistryHive;
Key->KeyCellOffset = KeyCellOffset; Key->KeyCellOffset = KeyCellOffset;
Key->KeyCell = HvGetCell (&RegistryHive->Hive, Key->KeyCellOffset); Key->KeyCell = (PCM_KEY_NODE)HvGetCell (&RegistryHive->Hive, Key->KeyCellOffset);
if (!Key->KeyCell) if (!Key->KeyCell)
{ {
free(Key); free(Key);
@ -386,7 +386,7 @@ RegSetValueExW(
RtlCopyMemory(&ValueCell->DataOffset, lpData, cbData); RtlCopyMemory(&ValueCell->DataOffset, lpData, cbData);
ValueCell->DataSize = (ULONG)(cbData | REG_DATA_IN_OFFSET); ValueCell->DataSize = (ULONG)(cbData | REG_DATA_IN_OFFSET);
ValueCell->DataType = dwType; ValueCell->DataType = dwType;
HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCellOffset); HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCellOffset, FALSE);
} }
else else
{ {
@ -398,8 +398,8 @@ RegSetValueExW(
DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize); DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize);
NewOffset = HvAllocateCell(&Key->RegistryHive->Hive, cbData, HvStable); NewOffset = HvAllocateCell(&Key->RegistryHive->Hive, cbData, Stable, HCELL_NIL);
if (NewOffset == HCELL_NULL) if (NewOffset == HCELL_NIL)
{ {
DPRINT("HvAllocateCell() failed with status 0x%08lx\n", Status); DPRINT("HvAllocateCell() failed with status 0x%08lx\n", Status);
return ERROR_UNSUCCESSFUL; return ERROR_UNSUCCESSFUL;
@ -409,18 +409,18 @@ RegSetValueExW(
HvFreeCell(&Key->RegistryHive->Hive, ValueCell->DataOffset); HvFreeCell(&Key->RegistryHive->Hive, ValueCell->DataOffset);
ValueCell->DataOffset = NewOffset; ValueCell->DataOffset = NewOffset;
DataCell = HvGetCell(&Key->RegistryHive->Hive, NewOffset); DataCell = (PVOID)HvGetCell(&Key->RegistryHive->Hive, NewOffset);
} }
/* Copy new contents to cellule */ /* Copy new contents to cellule */
RtlCopyMemory(DataCell, lpData, cbData); RtlCopyMemory(DataCell, lpData, cbData);
ValueCell->DataSize = (ULONG)(cbData & REG_DATA_SIZE_MASK); ValueCell->DataSize = (ULONG)(cbData & REG_DATA_SIZE_MASK);
ValueCell->DataType = dwType; ValueCell->DataType = dwType;
HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCell->DataOffset); HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCell->DataOffset, FALSE);
HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCellOffset); HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCellOffset, FALSE);
} }
HvMarkCellDirty(&Key->RegistryHive->Hive, Key->KeyCellOffset); HvMarkCellDirty(&Key->RegistryHive->Hive, Key->KeyCellOffset, FALSE);
DPRINT("Return status 0x%08lx\n", Status); DPRINT("Return status 0x%08lx\n", Status);
return Status; return Status;
@ -589,8 +589,8 @@ ConnectRegistry(
return FALSE; return FALSE;
NewKey->RegistryHive = HiveToConnect; NewKey->RegistryHive = HiveToConnect;
NewKey->KeyCellOffset = HiveToConnect->Hive.HiveHeader->RootCell; NewKey->KeyCellOffset = HiveToConnect->Hive.BaseBlock->RootCell;
NewKey->KeyCell = HvGetCell (&HiveToConnect->Hive, NewKey->KeyCellOffset); NewKey->KeyCell = (PCM_KEY_NODE)HvGetCell (&HiveToConnect->Hive, NewKey->KeyCellOffset);
return TRUE; return TRUE;
} }
@ -637,7 +637,7 @@ RegInitializeRegistry(VOID)
RootKey = CreateInMemoryStructure( RootKey = CreateInMemoryStructure(
&RootHive, &RootHive,
RootHive.Hive.HiveHeader->RootCell, RootHive.Hive.BaseBlock->RootCell,
&RootKeyName); &RootKeyName);
/* Create DEFAULT key */ /* Create DEFAULT key */