mirror of
https://github.com/reactos/reactos.git
synced 2025-04-19 20:19:26 +00:00
- 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:
parent
5419828b1a
commit
6dad5e16a9
26 changed files with 678 additions and 590 deletions
|
@ -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))
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
//
|
//
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
);
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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]);
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in a new issue