mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 09:52:56 +00:00
- Move registry shareable types (not internal to ntoskrnl's configuration manager) to cmdata.h, so that freeldr/mkhive can access them too.
- Remove all the ReactOS-specific versions of those types. - Change all code referencing the ReactOS-specific versions to use the real NT versions, and fix any related code to properly use the new fields. svn path=/trunk/; revision=29943
This commit is contained in:
parent
45199dd0b1
commit
6b7c404e0b
14 changed files with 509 additions and 857 deletions
|
@ -23,6 +23,9 @@
|
||||||
#include <cmlib.h>
|
#include <cmlib.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
#define REG_DATA_SIZE_MASK 0x7FFFFFFF
|
||||||
|
#define REG_DATA_IN_OFFSET 0x80000000
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
static PVOID
|
static PVOID
|
||||||
|
@ -46,20 +49,20 @@ CmiAllocateHashTableCell (PHHIVE Hive,
|
||||||
PHCELL_INDEX HBOffset,
|
PHCELL_INDEX HBOffset,
|
||||||
ULONG SubKeyCount)
|
ULONG SubKeyCount)
|
||||||
{
|
{
|
||||||
PHASH_TABLE_CELL HashCell;
|
PCM_KEY_FAST_INDEX HashCell;
|
||||||
ULONG NewHashSize;
|
ULONG NewHashSize;
|
||||||
|
|
||||||
NewHashSize = sizeof(HASH_TABLE_CELL) +
|
NewHashSize = sizeof(CM_KEY_FAST_INDEX) +
|
||||||
(SubKeyCount * sizeof(HASH_RECORD));
|
(SubKeyCount * sizeof(CM_INDEX));
|
||||||
*HBOffset = HvAllocateCell (Hive, NewHashSize, Stable, HCELL_NIL);
|
*HBOffset = HvAllocateCell (Hive, NewHashSize, Stable, HCELL_NIL);
|
||||||
if (*HBOffset == HCELL_NIL)
|
if (*HBOffset == HCELL_NIL)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HashCell = (PHASH_TABLE_CELL)HvGetCell (Hive, *HBOffset);
|
HashCell = (PCM_KEY_FAST_INDEX)HvGetCell (Hive, *HBOffset);
|
||||||
HashCell->Id = REG_HASH_TABLE_CELL_ID;
|
HashCell->Signature = CM_KEY_FAST_LEAF;
|
||||||
HashCell->HashTableSize = SubKeyCount;
|
HashCell->Count = SubKeyCount;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -71,21 +74,21 @@ CmiAddKeyToParentHashTable (PHHIVE Hive,
|
||||||
PCM_KEY_NODE NewKeyCell,
|
PCM_KEY_NODE NewKeyCell,
|
||||||
HCELL_INDEX NKBOffset)
|
HCELL_INDEX NKBOffset)
|
||||||
{
|
{
|
||||||
PHASH_TABLE_CELL HashBlock;
|
PCM_KEY_FAST_INDEX HashBlock;
|
||||||
PCM_KEY_NODE ParentKeyCell;
|
PCM_KEY_NODE ParentKeyCell;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
||||||
ParentKeyCell = (PVOID)HvGetCell (Hive, Parent);
|
ParentKeyCell = (PVOID)HvGetCell (Hive, Parent);
|
||||||
HashBlock = (PVOID)HvGetCell (Hive, ParentKeyCell->SubKeyLists[Stable]);
|
HashBlock = (PVOID)HvGetCell (Hive, ParentKeyCell->SubKeyLists[Stable]);
|
||||||
|
|
||||||
for (i = 0; i < HashBlock->HashTableSize; i++)
|
for (i = 0; i < HashBlock->Count; i++)
|
||||||
{
|
{
|
||||||
if (HashBlock->Table[i].KeyOffset == 0)
|
if (HashBlock->List[i].Cell == 0)
|
||||||
{
|
{
|
||||||
HashBlock->Table[i].KeyOffset = NKBOffset;
|
HashBlock->List[i].Cell = NKBOffset;
|
||||||
memcpy (&HashBlock->Table[i].HashValue,
|
memcpy (&HashBlock->List[i].HashKey,
|
||||||
NewKeyCell->Name,
|
NewKeyCell->Name,
|
||||||
min(NewKeyCell->NameSize, sizeof(ULONG)));
|
min(NewKeyCell->NameLength, sizeof(ULONG)));
|
||||||
ParentKeyCell->SubKeyCounts[Stable]++;
|
ParentKeyCell->SubKeyCounts[Stable]++;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -122,21 +125,21 @@ CmiAllocateValueCell(PHHIVE Hive,
|
||||||
PWCHAR ValueName)
|
PWCHAR ValueName)
|
||||||
{
|
{
|
||||||
PCM_KEY_VALUE NewValueCell;
|
PCM_KEY_VALUE NewValueCell;
|
||||||
ULONG NameSize;
|
ULONG NameLength;
|
||||||
BOOLEAN Packable = TRUE;
|
BOOLEAN Packable = TRUE;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
||||||
NameSize = (ValueName == NULL) ? 0 : wcslen (ValueName);
|
NameLength = (ValueName == NULL) ? 0 : wcslen (ValueName);
|
||||||
for (i = 0; i < NameSize; i++)
|
for (i = 0; i < NameLength; i++)
|
||||||
{
|
{
|
||||||
if (ValueName[i] & 0xFF00)
|
if (ValueName[i] & 0xFF00)
|
||||||
{
|
{
|
||||||
NameSize *= sizeof(WCHAR);
|
NameLength *= sizeof(WCHAR);
|
||||||
Packable = FALSE;
|
Packable = FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*ValueCellOffset = HvAllocateCell (Hive, sizeof(CM_KEY_VALUE) + NameSize, Stable, HCELL_NIL);
|
*ValueCellOffset = HvAllocateCell (Hive, sizeof(CM_KEY_VALUE) + NameLength, Stable, HCELL_NIL);
|
||||||
if (*ValueCellOffset == HCELL_NIL)
|
if (*ValueCellOffset == HCELL_NIL)
|
||||||
{
|
{
|
||||||
DbgPrint((DPRINT_REGISTRY, "CmiAllocateCell() failed\n"));
|
DbgPrint((DPRINT_REGISTRY, "CmiAllocateCell() failed\n"));
|
||||||
|
@ -144,29 +147,29 @@ CmiAllocateValueCell(PHHIVE Hive,
|
||||||
}
|
}
|
||||||
|
|
||||||
NewValueCell = (PCM_KEY_VALUE) HvGetCell (Hive, *ValueCellOffset);
|
NewValueCell = (PCM_KEY_VALUE) HvGetCell (Hive, *ValueCellOffset);
|
||||||
NewValueCell->Id = REG_VALUE_CELL_ID;
|
NewValueCell->Signature = CM_KEY_VALUE_SIGNATURE;
|
||||||
NewValueCell->NameSize = NameSize;
|
NewValueCell->NameLength = NameLength;
|
||||||
NewValueCell->Flags = 0;
|
NewValueCell->Flags = 0;
|
||||||
if (NameSize > 0)
|
if (NameLength > 0)
|
||||||
{
|
{
|
||||||
if (Packable)
|
if (Packable)
|
||||||
{
|
{
|
||||||
for (i = 0; i < NameSize; i++)
|
for (i = 0; i < NameLength; i++)
|
||||||
{
|
{
|
||||||
((PCHAR)NewValueCell->Name)[i] = (CHAR)ValueName[i];
|
((PCHAR)NewValueCell->Name)[i] = (CHAR)ValueName[i];
|
||||||
}
|
}
|
||||||
NewValueCell->Flags |= REG_VALUE_NAME_PACKED;
|
NewValueCell->Flags |= VALUE_COMP_NAME;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy (NewValueCell->Name,
|
memcpy (NewValueCell->Name,
|
||||||
ValueName,
|
ValueName,
|
||||||
NameSize);
|
NameLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NewValueCell->DataType = 0;
|
NewValueCell->Type = 0;
|
||||||
NewValueCell->DataSize = 0;
|
NewValueCell->DataLength = 0;
|
||||||
NewValueCell->DataOffset = -1;
|
NewValueCell->Data = -1;
|
||||||
|
|
||||||
*ValueCell = NewValueCell;
|
*ValueCell = NewValueCell;
|
||||||
|
|
||||||
|
@ -212,13 +215,13 @@ CmiExportValue (PHHIVE Hive,
|
||||||
HCELL_INDEX DataCellOffset;
|
HCELL_INDEX DataCellOffset;
|
||||||
PCM_KEY_VALUE ValueCell;
|
PCM_KEY_VALUE ValueCell;
|
||||||
PVOID DataCell;
|
PVOID DataCell;
|
||||||
ULONG DataSize;
|
ULONG DataLength;
|
||||||
ULONG DataType;
|
ULONG Type;
|
||||||
PCHAR Data;
|
PCHAR Data;
|
||||||
|
|
||||||
DbgPrint((DPRINT_REGISTRY, "CmiExportValue('%S') called\n",
|
DbgPrint((DPRINT_REGISTRY, "CmiExportValue('%S') called\n",
|
||||||
(Value == NULL) ? "<default>" : (PCHAR)Value->Name));
|
(Value == NULL) ? "<default>" : (PCHAR)Value->Name));
|
||||||
DbgPrint((DPRINT_REGISTRY, "DataSize %lu\n",
|
DbgPrint((DPRINT_REGISTRY, "DataLength %lu\n",
|
||||||
(Value == NULL) ? Key->DataSize : Value->DataSize));
|
(Value == NULL) ? Key->DataSize : Value->DataSize));
|
||||||
|
|
||||||
/* Allocate value cell */
|
/* Allocate value cell */
|
||||||
|
@ -234,42 +237,42 @@ CmiExportValue (PHHIVE Hive,
|
||||||
|
|
||||||
if (Value == NULL)
|
if (Value == NULL)
|
||||||
{
|
{
|
||||||
DataType = Key->DataType;
|
Type = Key->DataType;
|
||||||
DataSize = Key->DataSize;
|
DataLength = Key->DataSize;
|
||||||
Data = Key->Data;
|
Data = Key->Data;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DataType = Value->DataType;
|
Type = Value->DataType;
|
||||||
DataSize = Value->DataSize;
|
DataLength = Value->DataSize;
|
||||||
Data = Value->Data;
|
Data = Value->Data;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DataSize <= sizeof(HCELL_INDEX))
|
if (DataLength <= sizeof(HCELL_INDEX))
|
||||||
{
|
{
|
||||||
ValueCell->DataSize = DataSize | REG_DATA_IN_OFFSET;
|
ValueCell->DataLength = DataLength | REG_DATA_IN_OFFSET;
|
||||||
ValueCell->DataType = DataType;
|
ValueCell->Type = Type;
|
||||||
memcpy (&ValueCell->DataOffset,
|
memcpy (&ValueCell->Data,
|
||||||
&Data,
|
&Data,
|
||||||
DataSize);
|
DataLength);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Allocate data cell */
|
/* Allocate data cell */
|
||||||
DataCellOffset = HvAllocateCell (Hive, DataSize, Stable, HCELL_NIL);
|
DataCellOffset = HvAllocateCell (Hive, DataLength, Stable, HCELL_NIL);
|
||||||
if (DataCellOffset == HCELL_NIL)
|
if (DataCellOffset == HCELL_NIL)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueCell->DataOffset = DataCellOffset;
|
ValueCell->Data = DataCellOffset;
|
||||||
ValueCell->DataSize = DataSize;
|
ValueCell->DataLength = DataLength;
|
||||||
ValueCell->DataType = DataType;
|
ValueCell->Type = Type;
|
||||||
|
|
||||||
DataCell = (PVOID)HvGetCell (Hive, DataCellOffset);
|
DataCell = (PVOID)HvGetCell (Hive, DataCellOffset);
|
||||||
memcpy (DataCell,
|
memcpy (DataCell,
|
||||||
Data,
|
Data,
|
||||||
DataSize);
|
DataLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -292,7 +295,7 @@ CmiExportSubKey (PHHIVE Hive,
|
||||||
PVALUE Value;
|
PVALUE Value;
|
||||||
BOOLEAN Packable = TRUE;
|
BOOLEAN Packable = TRUE;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
ULONG NameSize;
|
ULONG NameLength;
|
||||||
|
|
||||||
DbgPrint((DPRINT_REGISTRY, "CmiExportSubKey('%S') called\n", Key->Name));
|
DbgPrint((DPRINT_REGISTRY, "CmiExportSubKey('%S') called\n", Key->Name));
|
||||||
|
|
||||||
|
@ -300,19 +303,19 @@ CmiExportSubKey (PHHIVE Hive,
|
||||||
if (Key->DataType == REG_LINK)
|
if (Key->DataType == REG_LINK)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
NameSize = (Key->NameSize - sizeof(WCHAR)) / sizeof(WCHAR);
|
NameLength = (Key->NameSize - sizeof(WCHAR)) / sizeof(WCHAR);
|
||||||
for (i = 0; i < NameSize; i++)
|
for (i = 0; i < NameLength; i++)
|
||||||
{
|
{
|
||||||
if (Key->Name[i] & 0xFF00)
|
if (Key->Name[i] & 0xFF00)
|
||||||
{
|
{
|
||||||
Packable = FALSE;
|
Packable = FALSE;
|
||||||
NameSize *= sizeof(WCHAR);
|
NameLength *= sizeof(WCHAR);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate key cell */
|
/* Allocate key cell */
|
||||||
KeyCellSize = sizeof(CM_KEY_NODE) + NameSize;
|
KeyCellSize = sizeof(CM_KEY_NODE) + NameLength;
|
||||||
NKBOffset = HvAllocateCell (Hive, KeyCellSize, Stable, HCELL_NIL);
|
NKBOffset = HvAllocateCell (Hive, KeyCellSize, Stable, HCELL_NIL);
|
||||||
if (NKBOffset == HCELL_NIL)
|
if (NKBOffset == HCELL_NIL)
|
||||||
{
|
{
|
||||||
|
@ -322,7 +325,7 @@ CmiExportSubKey (PHHIVE Hive,
|
||||||
|
|
||||||
/* Initialize key cell */
|
/* Initialize key cell */
|
||||||
NewKeyCell = (PCM_KEY_NODE) HvGetCell (Hive, NKBOffset);
|
NewKeyCell = (PCM_KEY_NODE) HvGetCell (Hive, NKBOffset);
|
||||||
NewKeyCell->Id = REG_KEY_CELL_ID;
|
NewKeyCell->Signature = CM_KEY_NODE_SIGNATURE;
|
||||||
NewKeyCell->Flags = 0;
|
NewKeyCell->Flags = 0;
|
||||||
NewKeyCell->LastWriteTime.QuadPart = 0ULL;
|
NewKeyCell->LastWriteTime.QuadPart = 0ULL;
|
||||||
NewKeyCell->Parent = Parent;
|
NewKeyCell->Parent = Parent;
|
||||||
|
@ -330,24 +333,24 @@ CmiExportSubKey (PHHIVE Hive,
|
||||||
NewKeyCell->SubKeyLists[Stable] = -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->Security = -1;
|
||||||
NewKeyCell->ClassNameOffset = -1;
|
NewKeyCell->Class = -1;
|
||||||
NewKeyCell->NameSize = NameSize;
|
NewKeyCell->NameLength = NameLength;
|
||||||
NewKeyCell->ClassSize = 0;
|
NewKeyCell->ClassLength = 0;
|
||||||
if (Packable)
|
if (Packable)
|
||||||
{
|
{
|
||||||
for (i = 0; i < NameSize; i++)
|
for (i = 0; i < NameLength; i++)
|
||||||
{
|
{
|
||||||
((PCHAR)NewKeyCell->Name)[i] = (CHAR)Key->Name[i];
|
((PCHAR)NewKeyCell->Name)[i] = (CHAR)Key->Name[i];
|
||||||
}
|
}
|
||||||
NewKeyCell->Flags |= REG_KEY_NAME_PACKED;
|
NewKeyCell->Flags |= KEY_COMP_NAME;
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy (NewKeyCell->Name,
|
memcpy (NewKeyCell->Name,
|
||||||
Key->Name,
|
Key->Name,
|
||||||
NameSize);
|
NameLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add key cell to the parent key's hash table */
|
/* Add key cell to the parent key's hash table */
|
||||||
|
@ -527,45 +530,45 @@ RegImportValue (PHHIVE Hive,
|
||||||
PVOID DataCell;
|
PVOID DataCell;
|
||||||
PWCHAR wName;
|
PWCHAR wName;
|
||||||
LONG Error;
|
LONG Error;
|
||||||
ULONG DataSize;
|
ULONG DataLength;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
||||||
if (ValueCell->Id != REG_VALUE_CELL_ID)
|
if (ValueCell->Signature != CM_KEY_VALUE_SIGNATURE)
|
||||||
{
|
{
|
||||||
DbgPrint((DPRINT_REGISTRY, "Invalid key cell!\n"));
|
DbgPrint((DPRINT_REGISTRY, "Invalid key cell!\n"));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
|
if (ValueCell->Flags & VALUE_COMP_NAME)
|
||||||
{
|
{
|
||||||
wName = MmAllocateMemory ((ValueCell->NameSize + 1)*sizeof(WCHAR));
|
wName = MmAllocateMemory ((ValueCell->NameLength + 1)*sizeof(WCHAR));
|
||||||
for (i = 0; i < ValueCell->NameSize; i++)
|
for (i = 0; i < ValueCell->NameLength; i++)
|
||||||
{
|
{
|
||||||
wName[i] = ((PCHAR)ValueCell->Name)[i];
|
wName[i] = ((PCHAR)ValueCell->Name)[i];
|
||||||
}
|
}
|
||||||
wName[ValueCell->NameSize] = 0;
|
wName[ValueCell->NameLength] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wName = MmAllocateMemory (ValueCell->NameSize + sizeof(WCHAR));
|
wName = MmAllocateMemory (ValueCell->NameLength + sizeof(WCHAR));
|
||||||
memcpy (wName,
|
memcpy (wName,
|
||||||
ValueCell->Name,
|
ValueCell->Name,
|
||||||
ValueCell->NameSize);
|
ValueCell->NameLength);
|
||||||
wName[ValueCell->NameSize / sizeof(WCHAR)] = 0;
|
wName[ValueCell->NameLength / sizeof(WCHAR)] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataSize = ValueCell->DataSize & REG_DATA_SIZE_MASK;
|
DataLength = ValueCell->DataLength & REG_DATA_SIZE_MASK;
|
||||||
|
|
||||||
DbgPrint((DPRINT_REGISTRY, "ValueName: '%S'\n", wName));
|
DbgPrint((DPRINT_REGISTRY, "ValueName: '%S'\n", wName));
|
||||||
DbgPrint((DPRINT_REGISTRY, "DataSize: %u\n", DataSize));
|
DbgPrint((DPRINT_REGISTRY, "DataLength: %u\n", DataLength));
|
||||||
|
|
||||||
if (DataSize <= sizeof(HCELL_INDEX) && (ValueCell->DataSize & REG_DATA_IN_OFFSET))
|
if (DataLength <= sizeof(HCELL_INDEX) && (ValueCell->DataLength & REG_DATA_IN_OFFSET))
|
||||||
{
|
{
|
||||||
Error = RegSetValue(Key,
|
Error = RegSetValue(Key,
|
||||||
wName,
|
wName,
|
||||||
ValueCell->DataType,
|
ValueCell->Type,
|
||||||
(PCHAR)&ValueCell->DataOffset,
|
(PCHAR)&ValueCell->Data,
|
||||||
DataSize);
|
DataLength);
|
||||||
if (Error != ERROR_SUCCESS)
|
if (Error != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
DbgPrint((DPRINT_REGISTRY, "RegSetValue() failed!\n"));
|
DbgPrint((DPRINT_REGISTRY, "RegSetValue() failed!\n"));
|
||||||
|
@ -575,14 +578,14 @@ RegImportValue (PHHIVE Hive,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DataCell = (PVOID)HvGetCell (Hive, ValueCell->DataOffset);
|
DataCell = (PVOID)HvGetCell (Hive, ValueCell->Data);
|
||||||
DbgPrint((DPRINT_REGISTRY, "DataCell: %x\n", DataCell));
|
DbgPrint((DPRINT_REGISTRY, "DataCell: %x\n", DataCell));
|
||||||
|
|
||||||
Error = RegSetValue (Key,
|
Error = RegSetValue (Key,
|
||||||
wName,
|
wName,
|
||||||
ValueCell->DataType,
|
ValueCell->Type,
|
||||||
DataCell,
|
DataCell,
|
||||||
DataSize);
|
DataLength);
|
||||||
|
|
||||||
if (Error != ERROR_SUCCESS)
|
if (Error != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -603,7 +606,7 @@ RegImportSubKey(PHHIVE Hive,
|
||||||
PCM_KEY_NODE KeyCell,
|
PCM_KEY_NODE KeyCell,
|
||||||
FRLDRHKEY ParentKey)
|
FRLDRHKEY ParentKey)
|
||||||
{
|
{
|
||||||
PHASH_TABLE_CELL HashCell;
|
PCM_KEY_FAST_INDEX HashCell;
|
||||||
PCM_KEY_NODE SubKeyCell;
|
PCM_KEY_NODE SubKeyCell;
|
||||||
PVALUE_LIST_CELL ValueListCell;
|
PVALUE_LIST_CELL ValueListCell;
|
||||||
PCM_KEY_VALUE ValueCell = NULL;
|
PCM_KEY_VALUE ValueCell = NULL;
|
||||||
|
@ -614,29 +617,29 @@ RegImportSubKey(PHHIVE Hive,
|
||||||
|
|
||||||
|
|
||||||
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->Signature: %x\n", KeyCell->Signature));
|
||||||
if (KeyCell->Id != REG_KEY_CELL_ID)
|
if (KeyCell->Signature != CM_KEY_NODE_SIGNATURE)
|
||||||
{
|
{
|
||||||
DbgPrint((DPRINT_REGISTRY, "Invalid key cell id!\n"));
|
DbgPrint((DPRINT_REGISTRY, "Invalid key cell Signature!\n"));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (KeyCell->Flags & REG_KEY_NAME_PACKED)
|
if (KeyCell->Flags & KEY_COMP_NAME)
|
||||||
{
|
{
|
||||||
wName = MmAllocateMemory ((KeyCell->NameSize + 1) * sizeof(WCHAR));
|
wName = MmAllocateMemory ((KeyCell->NameLength + 1) * sizeof(WCHAR));
|
||||||
for (i = 0; i < KeyCell->NameSize; i++)
|
for (i = 0; i < KeyCell->NameLength; i++)
|
||||||
{
|
{
|
||||||
wName[i] = ((PCHAR)KeyCell->Name)[i];
|
wName[i] = ((PCHAR)KeyCell->Name)[i];
|
||||||
}
|
}
|
||||||
wName[KeyCell->NameSize] = 0;
|
wName[KeyCell->NameLength] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wName = MmAllocateMemory (KeyCell->NameSize + sizeof(WCHAR));
|
wName = MmAllocateMemory (KeyCell->NameLength + sizeof(WCHAR));
|
||||||
memcpy (wName,
|
memcpy (wName,
|
||||||
KeyCell->Name,
|
KeyCell->Name,
|
||||||
KeyCell->NameSize);
|
KeyCell->NameLength);
|
||||||
wName[KeyCell->NameSize/sizeof(WCHAR)] = 0;
|
wName[KeyCell->NameLength/sizeof(WCHAR)] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgPrint((DPRINT_REGISTRY, "KeyName: '%S'\n", wName));
|
DbgPrint((DPRINT_REGISTRY, "KeyName: '%S'\n", wName));
|
||||||
|
@ -676,15 +679,15 @@ RegImportSubKey(PHHIVE Hive,
|
||||||
/* Enumerate and add subkeys */
|
/* Enumerate and add subkeys */
|
||||||
if (KeyCell->SubKeyCounts[Stable] > 0)
|
if (KeyCell->SubKeyCounts[Stable] > 0)
|
||||||
{
|
{
|
||||||
HashCell = (PHASH_TABLE_CELL) HvGetCell (Hive, KeyCell->SubKeyLists[Stable]);
|
HashCell = (PCM_KEY_FAST_INDEX) 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[Stable]; i++)
|
for (i = 0; i < KeyCell->SubKeyCounts[Stable]; i++)
|
||||||
{
|
{
|
||||||
DbgPrint((DPRINT_REGISTRY, "KeyOffset[%d]: %x\n", i, HashCell->Table[i].KeyOffset));
|
DbgPrint((DPRINT_REGISTRY, "Cell[%d]: %x\n", i, HashCell->List[i].Cell));
|
||||||
|
|
||||||
SubKeyCell = (PCM_KEY_NODE) HvGetCell (Hive, HashCell->Table[i].KeyOffset);
|
SubKeyCell = (PCM_KEY_NODE) HvGetCell (Hive, HashCell->List[i].Cell);
|
||||||
|
|
||||||
DbgPrint((DPRINT_REGISTRY, "SubKeyCell[%d]: %x\n", i, SubKeyCell));
|
DbgPrint((DPRINT_REGISTRY, "SubKeyCell[%d]: %x\n", i, SubKeyCell));
|
||||||
|
|
||||||
|
@ -702,7 +705,7 @@ RegImportBinaryHive(PCHAR ChunkBase,
|
||||||
ULONG ChunkSize)
|
ULONG ChunkSize)
|
||||||
{
|
{
|
||||||
PCM_KEY_NODE KeyCell;
|
PCM_KEY_NODE KeyCell;
|
||||||
PHASH_TABLE_CELL HashCell;
|
PCM_KEY_FAST_INDEX HashCell;
|
||||||
PCM_KEY_NODE SubKeyCell;
|
PCM_KEY_NODE SubKeyCell;
|
||||||
FRLDRHKEY SystemKey;
|
FRLDRHKEY SystemKey;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
@ -729,17 +732,17 @@ RegImportBinaryHive(PCHAR ChunkBase,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DbgPrint((DPRINT_REGISTRY, "Invalid hive id!\n"));
|
DbgPrint((DPRINT_REGISTRY, "Invalid hive Signature!\n"));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Hive = &CmHive->Hive;
|
Hive = &CmHive->Hive;
|
||||||
KeyCell = (PCM_KEY_NODE)HvGetCell (Hive, Hive->BaseBlock->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->Signature: %x\n", KeyCell->Signature));
|
||||||
if (KeyCell->Id != REG_KEY_CELL_ID)
|
if (KeyCell->Signature != CM_KEY_NODE_SIGNATURE)
|
||||||
{
|
{
|
||||||
DbgPrint((DPRINT_REGISTRY, "Invalid key cell id!\n"));
|
DbgPrint((DPRINT_REGISTRY, "Invalid key cell Signature!\n"));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -759,15 +762,15 @@ RegImportBinaryHive(PCHAR ChunkBase,
|
||||||
/* Enumerate and add subkeys */
|
/* Enumerate and add subkeys */
|
||||||
if (KeyCell->SubKeyCounts[Stable] > 0)
|
if (KeyCell->SubKeyCounts[Stable] > 0)
|
||||||
{
|
{
|
||||||
HashCell = (PHASH_TABLE_CELL)HvGetCell (Hive, KeyCell->SubKeyLists[Stable]);
|
HashCell = (PCM_KEY_FAST_INDEX)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[Stable]));
|
DbgPrint((DPRINT_REGISTRY, "SubKeyCounts: %x\n", KeyCell->SubKeyCounts[Stable]));
|
||||||
|
|
||||||
for (i = 0; i < KeyCell->SubKeyCounts[Stable]; i++)
|
for (i = 0; i < KeyCell->SubKeyCounts[Stable]; i++)
|
||||||
{
|
{
|
||||||
DbgPrint((DPRINT_REGISTRY, "KeyOffset[%d]: %x\n", i, HashCell->Table[i].KeyOffset));
|
DbgPrint((DPRINT_REGISTRY, "Cell[%d]: %x\n", i, HashCell->List[i].Cell));
|
||||||
|
|
||||||
SubKeyCell = (PCM_KEY_NODE)HvGetCell (Hive, HashCell->Table[i].KeyOffset);
|
SubKeyCell = (PCM_KEY_NODE)HvGetCell (Hive, HashCell->List[i].Cell);
|
||||||
|
|
||||||
DbgPrint((DPRINT_REGISTRY, "SubKeyCell[%d]: %x\n", i, SubKeyCell));
|
DbgPrint((DPRINT_REGISTRY, "SubKeyCell[%d]: %x\n", i, SubKeyCell));
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,8 @@
|
||||||
* and this line has to be removed */
|
* and this line has to be removed */
|
||||||
#define PAGE_SIZE 4096
|
#define PAGE_SIZE 4096
|
||||||
|
|
||||||
|
#define ANYSIZE_ARRAY 1
|
||||||
|
|
||||||
typedef void VOID, *PVOID, *HANDLE;
|
typedef void VOID, *PVOID, *HANDLE;
|
||||||
typedef HANDLE HKEY, *PHKEY;
|
typedef HANDLE HKEY, *PHKEY;
|
||||||
typedef unsigned char UCHAR, *PUCHAR, BYTE, *LPBYTE;
|
typedef unsigned char UCHAR, *PUCHAR, BYTE, *LPBYTE;
|
||||||
|
|
|
@ -13,12 +13,39 @@
|
||||||
#define REG_EXTEND_HASH_TABLE_SIZE 4
|
#define REG_EXTEND_HASH_TABLE_SIZE 4
|
||||||
#define REG_VALUE_LIST_CELL_MULTIPLE 4
|
#define REG_VALUE_LIST_CELL_MULTIPLE 4
|
||||||
|
|
||||||
#define REG_KEY_CELL_ID 0x6b6e
|
//
|
||||||
#define REG_HASH_TABLE_CELL_ID 0x666c
|
// Key Types
|
||||||
#define REG_VALUE_CELL_ID 0x6b76
|
//
|
||||||
#define REG_SECURITY_CELL_ID 0x6b73
|
#define CM_KEY_INDEX_ROOT 0x6972
|
||||||
|
#define CM_KEY_INDEX_LEAF 0x696c
|
||||||
|
#define CM_KEY_FAST_LEAF 0x666c
|
||||||
|
#define CM_KEY_HASH_LEAF 0x686c
|
||||||
|
|
||||||
#ifndef _CM_
|
//
|
||||||
|
// Key Signatures
|
||||||
|
//
|
||||||
|
#define CM_KEY_NODE_SIGNATURE 0x6B6E
|
||||||
|
#define CM_LINK_NODE_SIGNATURE 0x6B6C
|
||||||
|
#define CM_KEY_VALUE_SIGNATURE 0x6B76
|
||||||
|
|
||||||
|
//
|
||||||
|
// CM_KEY_NODE Flags
|
||||||
|
//
|
||||||
|
#define KEY_IS_VOLATILE 0x01
|
||||||
|
#define KEY_HIVE_EXIT 0x02
|
||||||
|
#define KEY_HIVE_ENTRY 0x04
|
||||||
|
#define KEY_NO_DELETE 0x08
|
||||||
|
#define KEY_SYM_LINK 0x10
|
||||||
|
#define KEY_COMP_NAME 0x20
|
||||||
|
#define KEY_PREFEF_HANDLE 0x40
|
||||||
|
#define KEY_VIRT_MIRRORED 0x80
|
||||||
|
#define KEY_VIRT_TARGET 0x100
|
||||||
|
#define KEY_VIRTUAL_STORE 0x200
|
||||||
|
|
||||||
|
//
|
||||||
|
// CM_KEY_VALUE Flags
|
||||||
|
//
|
||||||
|
#define VALUE_COMP_NAME 0x0001
|
||||||
|
|
||||||
#ifdef CMLIB_HOST
|
#ifdef CMLIB_HOST
|
||||||
#include <host/pshpack1.h>
|
#include <host/pshpack1.h>
|
||||||
|
@ -26,6 +53,9 @@
|
||||||
#include <pshpack1.h>
|
#include <pshpack1.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// For memory-mapped Hives
|
||||||
|
//
|
||||||
typedef struct _CM_VIEW_OF_FILE
|
typedef struct _CM_VIEW_OF_FILE
|
||||||
{
|
{
|
||||||
LIST_ENTRY LRUViewList;
|
LIST_ENTRY LRUViewList;
|
||||||
|
@ -37,111 +67,69 @@ typedef struct _CM_VIEW_OF_FILE
|
||||||
ULONG UseCount;
|
ULONG UseCount;
|
||||||
} CM_VIEW_OF_FILE, *PCM_VIEW_OF_FILE;
|
} CM_VIEW_OF_FILE, *PCM_VIEW_OF_FILE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Children of Key Notes
|
||||||
|
//
|
||||||
typedef struct _CHILD_LIST
|
typedef struct _CHILD_LIST
|
||||||
{
|
{
|
||||||
ULONG Count;
|
ULONG Count;
|
||||||
HCELL_INDEX List;
|
HCELL_INDEX List;
|
||||||
} CHILD_LIST, *PCHILD_LIST;
|
} CHILD_LIST, *PCHILD_LIST;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Node Key
|
||||||
|
//
|
||||||
typedef struct _CM_KEY_NODE
|
typedef struct _CM_KEY_NODE
|
||||||
{
|
{
|
||||||
/* Key cell identifier "kn" (0x6b6e) */
|
USHORT Signature;
|
||||||
USHORT Id;
|
|
||||||
|
|
||||||
/* Flags */
|
|
||||||
USHORT Flags;
|
USHORT Flags;
|
||||||
|
|
||||||
/* Time of last flush */
|
|
||||||
LARGE_INTEGER LastWriteTime;
|
LARGE_INTEGER LastWriteTime;
|
||||||
|
|
||||||
ULONG Spare;
|
ULONG Spare;
|
||||||
|
|
||||||
/* BlockAddress offset of parent key cell */
|
|
||||||
HCELL_INDEX Parent;
|
HCELL_INDEX Parent;
|
||||||
|
|
||||||
/* Count of sub keys for the key in this key cell (stable & volatile) */
|
|
||||||
ULONG SubKeyCounts[HTYPE_COUNT];
|
ULONG SubKeyCounts[HTYPE_COUNT];
|
||||||
|
|
||||||
/* BlockAddress offset of has table for FIXME: subkeys/values? (stable & volatile) */
|
|
||||||
HCELL_INDEX SubKeyLists[HTYPE_COUNT];
|
HCELL_INDEX SubKeyLists[HTYPE_COUNT];
|
||||||
|
|
||||||
CHILD_LIST ValueList;
|
CHILD_LIST ValueList;
|
||||||
|
HCELL_INDEX Security;
|
||||||
/* BlockAddress offset of security cell */
|
HCELL_INDEX Class;
|
||||||
HCELL_INDEX SecurityKeyOffset;
|
|
||||||
|
|
||||||
/* BlockAddress offset of registry key class */
|
|
||||||
HCELL_INDEX ClassNameOffset;
|
|
||||||
|
|
||||||
ULONG MaxNameLen;
|
ULONG MaxNameLen;
|
||||||
ULONG MaxClassLen;
|
ULONG MaxClassLen;
|
||||||
ULONG MaxValueNameLen;
|
ULONG MaxValueNameLen;
|
||||||
ULONG MaxValueDataLen;
|
ULONG MaxValueDataLen;
|
||||||
ULONG WorkVar;
|
ULONG WorkVar;
|
||||||
|
USHORT NameLength;
|
||||||
/* Size in bytes of key name */
|
USHORT ClassLength;
|
||||||
USHORT NameSize;
|
WCHAR Name[0];
|
||||||
|
|
||||||
/* Size of class name in bytes */
|
|
||||||
USHORT ClassSize;
|
|
||||||
|
|
||||||
/* Name of key (not zero terminated) */
|
|
||||||
UCHAR Name[0];
|
|
||||||
} CM_KEY_NODE, *PCM_KEY_NODE;
|
} CM_KEY_NODE, *PCM_KEY_NODE;
|
||||||
|
|
||||||
/* CM_KEY_NODE.Flags constants */
|
//
|
||||||
#define REG_KEY_VOLATILE_CELL 0x01
|
// Value List
|
||||||
#define REG_KEY_ROOT_CELL 0x0C
|
//
|
||||||
#define REG_KEY_LINK_CELL 0x10
|
|
||||||
#define REG_KEY_NAME_PACKED 0x20
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Hash record
|
|
||||||
*
|
|
||||||
* HashValue:
|
|
||||||
* packed name: four letters of value's name
|
|
||||||
* otherwise: Zero!
|
|
||||||
*/
|
|
||||||
typedef struct _HASH_RECORD
|
|
||||||
{
|
|
||||||
HCELL_INDEX KeyOffset;
|
|
||||||
ULONG HashValue;
|
|
||||||
} HASH_RECORD, *PHASH_RECORD;
|
|
||||||
|
|
||||||
typedef struct _HASH_TABLE_CELL
|
|
||||||
{
|
|
||||||
USHORT Id;
|
|
||||||
USHORT HashTableSize;
|
|
||||||
HASH_RECORD Table[0];
|
|
||||||
} HASH_TABLE_CELL, *PHASH_TABLE_CELL;
|
|
||||||
|
|
||||||
typedef struct _VALUE_LIST_CELL
|
typedef struct _VALUE_LIST_CELL
|
||||||
{
|
{
|
||||||
HCELL_INDEX ValueOffset[0];
|
HCELL_INDEX ValueOffset[0];
|
||||||
} VALUE_LIST_CELL, *PVALUE_LIST_CELL;
|
} VALUE_LIST_CELL, *PVALUE_LIST_CELL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Value Key
|
||||||
|
//
|
||||||
typedef struct _CM_KEY_VALUE
|
typedef struct _CM_KEY_VALUE
|
||||||
{
|
{
|
||||||
USHORT Id; // "kv"
|
USHORT Signature;
|
||||||
USHORT NameSize; // length of Name
|
USHORT NameLength;
|
||||||
ULONG DataSize; // length of datas in the cell pointed by DataOffset
|
ULONG DataLength;
|
||||||
HCELL_INDEX DataOffset;// datas are here if high bit of DataSize is set
|
HCELL_INDEX Data;
|
||||||
ULONG DataType;
|
ULONG Type;
|
||||||
USHORT Flags;
|
USHORT Flags;
|
||||||
USHORT Unused1;
|
USHORT Unused1;
|
||||||
UCHAR Name[0]; /* warning : not zero terminated */
|
WCHAR Name[0];
|
||||||
} CM_KEY_VALUE, *PCM_KEY_VALUE;
|
} CM_KEY_VALUE, *PCM_KEY_VALUE;
|
||||||
|
|
||||||
/* CM_KEY_VALUE.Flags constants */
|
//
|
||||||
#define REG_VALUE_NAME_PACKED 0x0001
|
// Security Key
|
||||||
|
//
|
||||||
/* CM_KEY_VALUE.DataSize mask constants */
|
|
||||||
#define REG_DATA_SIZE_MASK 0x7FFFFFFF
|
|
||||||
#define REG_DATA_IN_OFFSET 0x80000000
|
|
||||||
|
|
||||||
typedef struct _CM_KEY_SECURITY
|
typedef struct _CM_KEY_SECURITY
|
||||||
{
|
{
|
||||||
USHORT Signature; // "sk"
|
USHORT Signature;
|
||||||
USHORT Reserved;
|
USHORT Reserved;
|
||||||
HCELL_INDEX Flink;
|
HCELL_INDEX Flink;
|
||||||
HCELL_INDEX Blink;
|
HCELL_INDEX Blink;
|
||||||
|
@ -157,6 +145,53 @@ typedef struct _CM_KEY_SECURITY
|
||||||
#include <poppack.h>
|
#include <poppack.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
//
|
||||||
|
// Generic Index Entry
|
||||||
|
//
|
||||||
|
typedef struct _CM_INDEX
|
||||||
|
{
|
||||||
|
HCELL_INDEX Cell;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
UCHAR NameHint[4];
|
||||||
|
ULONG HashKey;
|
||||||
|
};
|
||||||
|
} CM_INDEX, *PCM_INDEX;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Key Index
|
||||||
|
//
|
||||||
|
typedef struct _CM_KEY_INDEX
|
||||||
|
{
|
||||||
|
USHORT Signature;
|
||||||
|
USHORT Count;
|
||||||
|
HCELL_INDEX List[ANYSIZE_ARRAY];
|
||||||
|
} CM_KEY_INDEX, *PCM_KEY_INDEX;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fast/Hash Key Index
|
||||||
|
//
|
||||||
|
typedef struct _CM_KEY_FAST_INDEX
|
||||||
|
{
|
||||||
|
USHORT Signature;
|
||||||
|
USHORT Count;
|
||||||
|
CM_INDEX List[ANYSIZE_ARRAY];
|
||||||
|
} CM_KEY_FAST_INDEX, *PCM_KEY_FAST_INDEX;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cell Data
|
||||||
|
//
|
||||||
|
typedef struct _CELL_DATA
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
CM_KEY_NODE KeyNode;
|
||||||
|
CM_KEY_VALUE KeyValue;
|
||||||
|
CM_KEY_SECURITY KeySecurity;
|
||||||
|
CM_KEY_INDEX KeyIndex;
|
||||||
|
HCELL_INDEX KeyList[ANYSIZE_ARRAY];
|
||||||
|
WCHAR KeyString[ANYSIZE_ARRAY];
|
||||||
|
} u;
|
||||||
|
} CELL_DATA, *PCELL_DATA;
|
||||||
|
|
||||||
#endif /* CMLIB_CMDATA_H */
|
#endif /* CMLIB_CMDATA_H */
|
||||||
|
|
|
@ -16,34 +16,47 @@ CmCreateRootNode(
|
||||||
HCELL_INDEX RootCellIndex;
|
HCELL_INDEX RootCellIndex;
|
||||||
SIZE_T NameSize;
|
SIZE_T NameSize;
|
||||||
|
|
||||||
|
/* Allocate the cell */
|
||||||
NameSize = wcslen(Name) * sizeof(WCHAR);
|
NameSize = wcslen(Name) * sizeof(WCHAR);
|
||||||
RootCellIndex = HvAllocateCell(Hive,
|
RootCellIndex = HvAllocateCell(Hive,
|
||||||
sizeof(CM_KEY_NODE) + NameSize,
|
FIELD_OFFSET(CM_KEY_NODE, Name) + NameSize,
|
||||||
Stable,
|
Stable,
|
||||||
HCELL_NIL);
|
HCELL_NIL);
|
||||||
if (RootCellIndex == HCELL_NIL)
|
if (RootCellIndex == HCELL_NIL) return FALSE;
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
|
/* Seutp the base block */
|
||||||
Hive->BaseBlock->RootCell = RootCellIndex;
|
Hive->BaseBlock->RootCell = RootCellIndex;
|
||||||
Hive->BaseBlock->CheckSum = HvpHiveHeaderChecksum(Hive->BaseBlock);
|
Hive->BaseBlock->CheckSum = HvpHiveHeaderChecksum(Hive->BaseBlock);
|
||||||
|
|
||||||
|
/* Get the key cell */
|
||||||
KeyCell = (PCM_KEY_NODE)HvGetCell(Hive, RootCellIndex);
|
KeyCell = (PCM_KEY_NODE)HvGetCell(Hive, RootCellIndex);
|
||||||
KeyCell->Id = REG_KEY_CELL_ID;
|
if (!KeyCell) return FALSE;
|
||||||
KeyCell->Flags = REG_KEY_ROOT_CELL;
|
|
||||||
|
/* Setup the cell */
|
||||||
|
KeyCell->Signature = (USHORT)CM_KEY_NODE_SIGNATURE;
|
||||||
|
KeyCell->Flags = KEY_HIVE_ENTRY | KEY_NO_DELETE;
|
||||||
KeyCell->LastWriteTime.QuadPart = 0;
|
KeyCell->LastWriteTime.QuadPart = 0;
|
||||||
KeyCell->Parent = HCELL_NIL;
|
KeyCell->Parent = HCELL_NIL;
|
||||||
KeyCell->SubKeyCounts[0] = 0;
|
KeyCell->SubKeyCounts[Stable] = 0;
|
||||||
KeyCell->SubKeyCounts[1] = 0;
|
KeyCell->SubKeyCounts[Volatile] = 0;
|
||||||
KeyCell->SubKeyLists[0] = HCELL_NIL;
|
KeyCell->SubKeyLists[Stable] = HCELL_NIL;
|
||||||
KeyCell->SubKeyLists[1] = 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->SecurityKeyOffset = HCELL_NIL;
|
KeyCell->Security = HCELL_NIL;
|
||||||
KeyCell->ClassNameOffset = HCELL_NIL;
|
KeyCell->Class = HCELL_NIL;
|
||||||
KeyCell->NameSize = (USHORT)NameSize;
|
KeyCell->ClassLength = 0;
|
||||||
KeyCell->ClassSize = 0;
|
KeyCell->MaxNameLen = 0;
|
||||||
|
KeyCell->MaxClassLen = 0;
|
||||||
|
KeyCell->MaxValueNameLen = 0;
|
||||||
|
KeyCell->MaxValueDataLen = 0;
|
||||||
|
|
||||||
|
/* Write the name */
|
||||||
|
KeyCell->NameLength = (USHORT)NameSize;
|
||||||
memcpy(KeyCell->Name, Name, NameSize);
|
memcpy(KeyCell->Name, Name, NameSize);
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
HvReleaseCell(Hive, RootCellIndex);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,10 +66,10 @@ CmpPrepareKey(
|
||||||
PCM_KEY_NODE KeyCell)
|
PCM_KEY_NODE KeyCell)
|
||||||
{
|
{
|
||||||
PCM_KEY_NODE SubKeyCell;
|
PCM_KEY_NODE SubKeyCell;
|
||||||
PHASH_TABLE_CELL HashCell;
|
PCM_KEY_FAST_INDEX HashCell;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
||||||
ASSERT(KeyCell->Id == REG_KEY_CELL_ID);
|
ASSERT(KeyCell->Signature == CM_KEY_NODE_SIGNATURE);
|
||||||
|
|
||||||
KeyCell->SubKeyLists[Volatile] = HCELL_NIL;
|
KeyCell->SubKeyLists[Volatile] = HCELL_NIL;
|
||||||
KeyCell->SubKeyCounts[Volatile] = 0;
|
KeyCell->SubKeyCounts[Volatile] = 0;
|
||||||
|
@ -68,7 +81,7 @@ CmpPrepareKey(
|
||||||
|
|
||||||
for (i = 0; i < KeyCell->SubKeyCounts[Stable]; i++)
|
for (i = 0; i < KeyCell->SubKeyCounts[Stable]; i++)
|
||||||
{
|
{
|
||||||
SubKeyCell = HvGetCell(RegistryHive, HashCell->Table[i].KeyOffset);
|
SubKeyCell = HvGetCell(RegistryHive, HashCell->List[i].Cell);
|
||||||
CmpPrepareKey(RegistryHive, SubKeyCell);
|
CmpPrepareKey(RegistryHive, SubKeyCell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,10 +62,6 @@ RtlClearAllBits(
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <wchar.h>
|
|
||||||
#include "hivedata.h"
|
|
||||||
#include "cmdata.h"
|
|
||||||
|
|
||||||
#ifndef ROUND_UP
|
#ifndef ROUND_UP
|
||||||
#define ROUND_UP(a,b) ((((a)+(b)-1)/(b))*(b))
|
#define ROUND_UP(a,b) ((((a)+(b)-1)/(b))*(b))
|
||||||
#define ROUND_DOWN(a,b) (((a)/(b))*(b))
|
#define ROUND_DOWN(a,b) (((a)/(b))*(b))
|
||||||
|
@ -75,112 +71,9 @@ RtlClearAllBits(
|
||||||
|
|
||||||
#define CMAPI NTAPI
|
#define CMAPI NTAPI
|
||||||
|
|
||||||
struct _HHIVE;
|
#include <wchar.h>
|
||||||
|
#include "hivedata.h"
|
||||||
typedef struct _CELL_DATA* (CMAPI *PGET_CELL_ROUTINE)(
|
#include "cmdata.h"
|
||||||
struct _HHIVE *Hive,
|
|
||||||
HCELL_INDEX Cell);
|
|
||||||
|
|
||||||
typedef VOID (CMAPI *PRELEASE_CELL_ROUTINE)(
|
|
||||||
struct _HHIVE *Hive,
|
|
||||||
HCELL_INDEX Cell);
|
|
||||||
|
|
||||||
typedef PVOID (CMAPI *PALLOCATE_ROUTINE)(
|
|
||||||
SIZE_T Size,
|
|
||||||
BOOLEAN Paged,
|
|
||||||
ULONG Tag);
|
|
||||||
|
|
||||||
typedef VOID (CMAPI *PFREE_ROUTINE)(
|
|
||||||
PVOID Ptr,
|
|
||||||
ULONG Quota);
|
|
||||||
|
|
||||||
typedef BOOLEAN (CMAPI *PFILE_READ_ROUTINE)(
|
|
||||||
struct _HHIVE *RegistryHive,
|
|
||||||
ULONG FileType,
|
|
||||||
PULONG FileOffset,
|
|
||||||
PVOID Buffer,
|
|
||||||
SIZE_T BufferLength);
|
|
||||||
|
|
||||||
typedef BOOLEAN (CMAPI *PFILE_WRITE_ROUTINE)(
|
|
||||||
struct _HHIVE *RegistryHive,
|
|
||||||
ULONG FileType,
|
|
||||||
PULONG FileOffset,
|
|
||||||
PVOID Buffer,
|
|
||||||
SIZE_T BufferLength);
|
|
||||||
|
|
||||||
typedef BOOLEAN (CMAPI *PFILE_SET_SIZE_ROUTINE)(
|
|
||||||
struct _HHIVE *RegistryHive,
|
|
||||||
ULONG FileType,
|
|
||||||
ULONG FileSize,
|
|
||||||
ULONG OldfileSize);
|
|
||||||
|
|
||||||
typedef BOOLEAN (CMAPI *PFILE_FLUSH_ROUTINE)(
|
|
||||||
struct _HHIVE *RegistryHive,
|
|
||||||
ULONG FileType,
|
|
||||||
PLARGE_INTEGER FileOffset,
|
|
||||||
ULONG Length);
|
|
||||||
|
|
||||||
typedef struct _HMAP_ENTRY
|
|
||||||
{
|
|
||||||
ULONG_PTR BlockAddress;
|
|
||||||
ULONG_PTR BinAddress;
|
|
||||||
struct _CM_VIEW_OF_FILE *CmView;
|
|
||||||
ULONG MemAlloc;
|
|
||||||
} HMAP_ENTRY, *PHMAP_ENTRY;
|
|
||||||
|
|
||||||
typedef struct _HMAP_TABLE
|
|
||||||
{
|
|
||||||
HMAP_ENTRY Table[512];
|
|
||||||
} HMAP_TABLE, *PHMAP_TABLE;
|
|
||||||
|
|
||||||
typedef struct _HMAP_DIRECTORY
|
|
||||||
{
|
|
||||||
PHMAP_TABLE Directory[2048];
|
|
||||||
} HMAP_DIRECTORY, *PHMAP_DIRECTORY;
|
|
||||||
|
|
||||||
typedef struct _DUAL
|
|
||||||
{
|
|
||||||
ULONG Length;
|
|
||||||
PHMAP_DIRECTORY Map;
|
|
||||||
PHMAP_ENTRY BlockList; // PHMAP_TABLE SmallDir;
|
|
||||||
ULONG Guard;
|
|
||||||
HCELL_INDEX FreeDisplay[24]; //FREE_DISPLAY FreeDisplay[24];
|
|
||||||
ULONG FreeSummary;
|
|
||||||
LIST_ENTRY FreeBins;
|
|
||||||
} DUAL, *PDUAL;
|
|
||||||
|
|
||||||
typedef struct _HHIVE
|
|
||||||
{
|
|
||||||
ULONG Signature;
|
|
||||||
PGET_CELL_ROUTINE GetCellRoutine;
|
|
||||||
PRELEASE_CELL_ROUTINE ReleaseCellRoutine;
|
|
||||||
PALLOCATE_ROUTINE Allocate;
|
|
||||||
PFREE_ROUTINE Free;
|
|
||||||
PFILE_READ_ROUTINE FileRead;
|
|
||||||
PFILE_WRITE_ROUTINE FileWrite;
|
|
||||||
PFILE_SET_SIZE_ROUTINE FileSetSize;
|
|
||||||
PFILE_FLUSH_ROUTINE FileFlush;
|
|
||||||
PHBASE_BLOCK BaseBlock;
|
|
||||||
RTL_BITMAP DirtyVector;
|
|
||||||
ULONG DirtyCount;
|
|
||||||
ULONG DirtyAlloc;
|
|
||||||
ULONG BaseBlockAlloc;
|
|
||||||
ULONG Cluster;
|
|
||||||
BOOLEAN Flat;
|
|
||||||
BOOLEAN ReadOnly;
|
|
||||||
BOOLEAN Log;
|
|
||||||
BOOLEAN DirtyFlag;
|
|
||||||
ULONG HvBinHeadersUse;
|
|
||||||
ULONG HvFreeCellsUse;
|
|
||||||
ULONG HvUsedcellsUse;
|
|
||||||
ULONG CmUsedCellsUse;
|
|
||||||
ULONG HiveFlags;
|
|
||||||
ULONG LogSize;
|
|
||||||
ULONG RefreshCount;
|
|
||||||
ULONG StorageTypeCount;
|
|
||||||
ULONG Version;
|
|
||||||
DUAL Storage[HTYPE_COUNT];
|
|
||||||
} HHIVE, *PHHIVE;
|
|
||||||
|
|
||||||
#ifndef _CM_
|
#ifndef _CM_
|
||||||
typedef struct _EREGISTRY_HIVE
|
typedef struct _EREGISTRY_HIVE
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
#define HIVE_VOLATILE 1
|
#define HIVE_VOLATILE 1
|
||||||
#define HIVE_NOLAZYFLUSH 2
|
#define HIVE_NOLAZYFLUSH 2
|
||||||
#define HIVE_HAS_BEEN_REPLACED 4
|
#define HIVE_HAS_BEEN_REPLACED 4
|
||||||
|
#define HIVE_HAS_BEEN_FREED 8
|
||||||
|
#define HIVE_UNKNOWN 0x10
|
||||||
|
#define HIVE_IS_UNLOADING 0x20
|
||||||
|
|
||||||
//
|
//
|
||||||
// Hive types
|
// Hive types
|
||||||
|
@ -190,6 +193,114 @@ typedef struct _HCELL
|
||||||
#include <poppack.h>
|
#include <poppack.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct _HHIVE;
|
||||||
|
|
||||||
|
typedef struct _CELL_DATA* (CMAPI *PGET_CELL_ROUTINE)(
|
||||||
|
struct _HHIVE *Hive,
|
||||||
|
HCELL_INDEX Cell);
|
||||||
|
|
||||||
|
typedef VOID (CMAPI *PRELEASE_CELL_ROUTINE)(
|
||||||
|
struct _HHIVE *Hive,
|
||||||
|
HCELL_INDEX Cell);
|
||||||
|
|
||||||
|
typedef PVOID (CMAPI *PALLOCATE_ROUTINE)(
|
||||||
|
SIZE_T Size,
|
||||||
|
BOOLEAN Paged,
|
||||||
|
ULONG Tag);
|
||||||
|
|
||||||
|
typedef VOID (CMAPI *PFREE_ROUTINE)(
|
||||||
|
PVOID Ptr,
|
||||||
|
ULONG Quota);
|
||||||
|
|
||||||
|
typedef BOOLEAN (CMAPI *PFILE_READ_ROUTINE)(
|
||||||
|
struct _HHIVE *RegistryHive,
|
||||||
|
ULONG FileType,
|
||||||
|
PULONG FileOffset,
|
||||||
|
PVOID Buffer,
|
||||||
|
SIZE_T BufferLength);
|
||||||
|
|
||||||
|
typedef BOOLEAN (CMAPI *PFILE_WRITE_ROUTINE)(
|
||||||
|
struct _HHIVE *RegistryHive,
|
||||||
|
ULONG FileType,
|
||||||
|
PULONG FileOffset,
|
||||||
|
PVOID Buffer,
|
||||||
|
SIZE_T BufferLength);
|
||||||
|
|
||||||
|
typedef BOOLEAN (CMAPI *PFILE_SET_SIZE_ROUTINE)(
|
||||||
|
struct _HHIVE *RegistryHive,
|
||||||
|
ULONG FileType,
|
||||||
|
ULONG FileSize,
|
||||||
|
ULONG OldfileSize);
|
||||||
|
|
||||||
|
typedef BOOLEAN (CMAPI *PFILE_FLUSH_ROUTINE)(
|
||||||
|
struct _HHIVE *RegistryHive,
|
||||||
|
ULONG FileType,
|
||||||
|
PLARGE_INTEGER FileOffset,
|
||||||
|
ULONG Length
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef struct _HMAP_ENTRY
|
||||||
|
{
|
||||||
|
ULONG_PTR BlockAddress;
|
||||||
|
ULONG_PTR BinAddress;
|
||||||
|
struct _CM_VIEW_OF_FILE *CmView;
|
||||||
|
ULONG MemAlloc;
|
||||||
|
} HMAP_ENTRY, *PHMAP_ENTRY;
|
||||||
|
|
||||||
|
typedef struct _HMAP_TABLE
|
||||||
|
{
|
||||||
|
HMAP_ENTRY Table[512];
|
||||||
|
} HMAP_TABLE, *PHMAP_TABLE;
|
||||||
|
|
||||||
|
typedef struct _HMAP_DIRECTORY
|
||||||
|
{
|
||||||
|
PHMAP_TABLE Directory[2048];
|
||||||
|
} HMAP_DIRECTORY, *PHMAP_DIRECTORY;
|
||||||
|
|
||||||
|
typedef struct _DUAL
|
||||||
|
{
|
||||||
|
ULONG Length;
|
||||||
|
PHMAP_DIRECTORY Map;
|
||||||
|
PHMAP_ENTRY BlockList; // PHMAP_TABLE SmallDir;
|
||||||
|
ULONG Guard;
|
||||||
|
HCELL_INDEX FreeDisplay[24]; //FREE_DISPLAY FreeDisplay[24];
|
||||||
|
ULONG FreeSummary;
|
||||||
|
LIST_ENTRY FreeBins;
|
||||||
|
} DUAL, *PDUAL;
|
||||||
|
|
||||||
|
typedef struct _HHIVE
|
||||||
|
{
|
||||||
|
ULONG Signature;
|
||||||
|
PGET_CELL_ROUTINE GetCellRoutine;
|
||||||
|
PRELEASE_CELL_ROUTINE ReleaseCellRoutine;
|
||||||
|
PALLOCATE_ROUTINE Allocate;
|
||||||
|
PFREE_ROUTINE Free;
|
||||||
|
PFILE_READ_ROUTINE FileRead;
|
||||||
|
PFILE_WRITE_ROUTINE FileWrite;
|
||||||
|
PFILE_SET_SIZE_ROUTINE FileSetSize;
|
||||||
|
PFILE_FLUSH_ROUTINE FileFlush;
|
||||||
|
PHBASE_BLOCK BaseBlock;
|
||||||
|
RTL_BITMAP DirtyVector;
|
||||||
|
ULONG DirtyCount;
|
||||||
|
ULONG DirtyAlloc;
|
||||||
|
ULONG BaseBlockAlloc;
|
||||||
|
ULONG Cluster;
|
||||||
|
BOOLEAN Flat;
|
||||||
|
BOOLEAN ReadOnly;
|
||||||
|
BOOLEAN Log;
|
||||||
|
BOOLEAN DirtyFlag;
|
||||||
|
ULONG HvBinHeadersUse;
|
||||||
|
ULONG HvFreeCellsUse;
|
||||||
|
ULONG HvUsedcellsUse;
|
||||||
|
ULONG CmUsedCellsUse;
|
||||||
|
ULONG HiveFlags;
|
||||||
|
ULONG LogSize;
|
||||||
|
ULONG RefreshCount;
|
||||||
|
ULONG StorageTypeCount;
|
||||||
|
ULONG Version;
|
||||||
|
DUAL Storage[HTYPE_COUNT];
|
||||||
|
} HHIVE, *PHHIVE;
|
||||||
|
|
||||||
#define IsFreeCell(Cell)(Cell->Size >= 0)
|
#define IsFreeCell(Cell)(Cell->Size >= 0)
|
||||||
#define IsUsedCell(Cell)(Cell->Size < 0)
|
#define IsUsedCell(Cell)(Cell->Size < 0)
|
||||||
|
|
||||||
|
|
|
@ -192,9 +192,9 @@ CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1,
|
||||||
IN PVOID Argument2);
|
IN PVOID Argument2);
|
||||||
|
|
||||||
#define VERIFY_BIN_HEADER(x) ASSERT(x->HeaderId == REG_BIN_ID)
|
#define VERIFY_BIN_HEADER(x) ASSERT(x->HeaderId == REG_BIN_ID)
|
||||||
#define VERIFY_KEY_CELL(x) ASSERT(x->Id == REG_KEY_CELL_ID)
|
#define VERIFY_KEY_CELL(x) ASSERT(x->Signature == CM_KEY_NODE_SIGNATURE)
|
||||||
#define VERIFY_ROOT_KEY_CELL(x) ASSERT(x->Id == REG_KEY_CELL_ID)
|
#define VERIFY_ROOT_KEY_CELL(x) ASSERT(x->Signature == CM_KEY_NODE_SIGNATURE)
|
||||||
#define VERIFY_VALUE_CELL(x) ASSERT(x->Id == REG_VALUE_CELL_ID)
|
#define VERIFY_VALUE_CELL(x) ASSERT(x->Signature == CM_KEY_VALUE_SIGNATURE)
|
||||||
#define VERIFY_VALUE_LIST_CELL(x)
|
#define VERIFY_VALUE_LIST_CELL(x)
|
||||||
#define VERIFY_KEY_OBJECT(x)
|
#define VERIFY_KEY_OBJECT(x)
|
||||||
#define VERIFY_REGISTRY_HIVE(x)
|
#define VERIFY_REGISTRY_HIVE(x)
|
||||||
|
@ -317,21 +317,6 @@ NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
CmDeleteKey(IN PCM_KEY_CONTROL_BLOCK Kcb);
|
CmDeleteKey(IN PCM_KEY_CONTROL_BLOCK Kcb);
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
CmiAllocateHashTableCell(IN PEREGISTRY_HIVE RegistryHive,
|
|
||||||
OUT PHASH_TABLE_CELL *HashBlock,
|
|
||||||
OUT HCELL_INDEX *HBOffset,
|
|
||||||
IN ULONG HashTableSize,
|
|
||||||
IN HSTORAGE_TYPE Storage);
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
CmiAddKeyToHashTable(PEREGISTRY_HIVE RegistryHive,
|
|
||||||
PHASH_TABLE_CELL HashCell,
|
|
||||||
PCM_KEY_NODE KeyCell,
|
|
||||||
HSTORAGE_TYPE StorageType,
|
|
||||||
PCM_KEY_NODE NewKeyCell,
|
|
||||||
HCELL_INDEX NKBOffset);
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CmiConnectHive(POBJECT_ATTRIBUTES KeyObjectAttributes,
|
CmiConnectHive(POBJECT_ATTRIBUTES KeyObjectAttributes,
|
||||||
PEREGISTRY_HIVE RegistryHive);
|
PEREGISTRY_HIVE RegistryHive);
|
||||||
|
|
|
@ -333,7 +333,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
RtlCreateUnicodeString(&KeyObject->Name, Start);
|
RtlCreateUnicodeString(&KeyObject->Name, Start);
|
||||||
|
|
||||||
KeyObject->KeyCell->Parent = KeyObject->ParentKey->KeyCellOffset;
|
KeyObject->KeyCell->Parent = KeyObject->ParentKey->KeyCellOffset;
|
||||||
KeyObject->KeyCell->SecurityKeyOffset = KeyObject->ParentKey->KeyCell->SecurityKeyOffset;
|
KeyObject->KeyCell->Security = KeyObject->ParentKey->KeyCell->Security;
|
||||||
KeyObject->ValueCache.ValueList = KeyObject->KeyCell->ValueList.List;
|
KeyObject->ValueCache.ValueList = KeyObject->KeyCell->ValueList.List;
|
||||||
KeyObject->ValueCache.Count = KeyObject->KeyCell->ValueList.Count;
|
KeyObject->ValueCache.Count = KeyObject->KeyCell->ValueList.Count;
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
/* LOCAL MACROS *************************************************************/
|
/* LOCAL MACROS *************************************************************/
|
||||||
|
|
||||||
#define ABS_VALUE(V) (((V) < 0) ? -(V) : (V))
|
#define ABS_VALUE(V) (((V) < 0) ? -(V) : (V))
|
||||||
|
#define REG_DATA_SIZE_MASK 0x7FFFFFFF
|
||||||
|
#define REG_DATA_IN_OFFSET 0x80000000
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
@ -105,10 +107,10 @@ ULONG
|
||||||
CmiGetMaxNameLength(PHHIVE Hive,
|
CmiGetMaxNameLength(PHHIVE Hive,
|
||||||
PCM_KEY_NODE KeyCell)
|
PCM_KEY_NODE KeyCell)
|
||||||
{
|
{
|
||||||
PHASH_TABLE_CELL HashBlock;
|
PCM_KEY_FAST_INDEX HashBlock;
|
||||||
PCM_KEY_NODE CurSubKeyCell;
|
PCM_KEY_NODE CurSubKeyCell;
|
||||||
ULONG MaxName;
|
ULONG MaxName;
|
||||||
ULONG NameSize;
|
ULONG NameLength;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
ULONG Storage;
|
ULONG Storage;
|
||||||
|
|
||||||
|
@ -117,18 +119,18 @@ CmiGetMaxNameLength(PHHIVE Hive,
|
||||||
{
|
{
|
||||||
if (KeyCell->SubKeyLists[Storage] != HCELL_NIL)
|
if (KeyCell->SubKeyLists[Storage] != HCELL_NIL)
|
||||||
{
|
{
|
||||||
HashBlock = (PHASH_TABLE_CELL)HvGetCell (Hive, KeyCell->SubKeyLists[Storage]);
|
HashBlock = (PCM_KEY_FAST_INDEX)HvGetCell (Hive, KeyCell->SubKeyLists[Storage]);
|
||||||
ASSERT(HashBlock->Id == REG_HASH_TABLE_CELL_ID);
|
ASSERT(HashBlock->Signature == CM_KEY_FAST_LEAF);
|
||||||
|
|
||||||
for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++)
|
for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++)
|
||||||
{
|
{
|
||||||
CurSubKeyCell = (PCM_KEY_NODE)HvGetCell (Hive,
|
CurSubKeyCell = (PCM_KEY_NODE)HvGetCell (Hive,
|
||||||
HashBlock->Table[i].KeyOffset);
|
HashBlock->List[i].Cell);
|
||||||
NameSize = CurSubKeyCell->NameSize;
|
NameLength = CurSubKeyCell->NameLength;
|
||||||
if (CurSubKeyCell->Flags & REG_KEY_NAME_PACKED)
|
if (CurSubKeyCell->Flags & KEY_COMP_NAME)
|
||||||
NameSize *= sizeof(WCHAR);
|
NameLength *= sizeof(WCHAR);
|
||||||
if (NameSize > MaxName)
|
if (NameLength > MaxName)
|
||||||
MaxName = NameSize;
|
MaxName = NameLength;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,7 +144,7 @@ ULONG
|
||||||
CmiGetMaxClassLength(PHHIVE Hive,
|
CmiGetMaxClassLength(PHHIVE Hive,
|
||||||
PCM_KEY_NODE KeyCell)
|
PCM_KEY_NODE KeyCell)
|
||||||
{
|
{
|
||||||
PHASH_TABLE_CELL HashBlock;
|
PCM_KEY_FAST_INDEX HashBlock;
|
||||||
PCM_KEY_NODE CurSubKeyCell;
|
PCM_KEY_NODE CurSubKeyCell;
|
||||||
ULONG MaxClass;
|
ULONG MaxClass;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
@ -153,18 +155,18 @@ CmiGetMaxClassLength(PHHIVE Hive,
|
||||||
{
|
{
|
||||||
if (KeyCell->SubKeyLists[Storage] != HCELL_NIL)
|
if (KeyCell->SubKeyLists[Storage] != HCELL_NIL)
|
||||||
{
|
{
|
||||||
HashBlock = (PHASH_TABLE_CELL)HvGetCell (Hive,
|
HashBlock = (PCM_KEY_FAST_INDEX)HvGetCell (Hive,
|
||||||
KeyCell->SubKeyLists[Storage]);
|
KeyCell->SubKeyLists[Storage]);
|
||||||
ASSERT(HashBlock->Id == REG_HASH_TABLE_CELL_ID);
|
ASSERT(HashBlock->Signature == CM_KEY_FAST_LEAF);
|
||||||
|
|
||||||
for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++)
|
for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++)
|
||||||
{
|
{
|
||||||
CurSubKeyCell = (PCM_KEY_NODE)HvGetCell (Hive,
|
CurSubKeyCell = (PCM_KEY_NODE)HvGetCell (Hive,
|
||||||
HashBlock->Table[i].KeyOffset);
|
HashBlock->List[i].Cell);
|
||||||
|
|
||||||
if (MaxClass < CurSubKeyCell->ClassSize)
|
if (MaxClass < CurSubKeyCell->ClassLength)
|
||||||
{
|
{
|
||||||
MaxClass = CurSubKeyCell->ClassSize;
|
MaxClass = CurSubKeyCell->ClassLength;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,8 +207,8 @@ CmiGetMaxValueNameLength(PHHIVE Hive,
|
||||||
|
|
||||||
if (CurValueCell != NULL)
|
if (CurValueCell != NULL)
|
||||||
{
|
{
|
||||||
Size = CurValueCell->NameSize;
|
Size = CurValueCell->NameLength;
|
||||||
if (CurValueCell->Flags & REG_VALUE_NAME_PACKED)
|
if (CurValueCell->Flags & VALUE_COMP_NAME)
|
||||||
{
|
{
|
||||||
Size *= sizeof(WCHAR);
|
Size *= sizeof(WCHAR);
|
||||||
}
|
}
|
||||||
|
@ -243,9 +245,9 @@ CmiGetMaxValueDataLength(PHHIVE Hive,
|
||||||
{
|
{
|
||||||
CurValueCell = (PCM_KEY_VALUE)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->DataLength & REG_DATA_SIZE_MASK)))
|
||||||
{
|
{
|
||||||
MaxValueData = CurValueCell->DataSize & REG_DATA_SIZE_MASK;
|
MaxValueData = CurValueCell->DataLength & REG_DATA_SIZE_MASK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,252 +301,4 @@ CmiScanForSubKey(IN PEREGISTRY_HIVE RegistryHive,
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
CmiAddSubKey(PEREGISTRY_HIVE RegistryHive,
|
|
||||||
PKEY_OBJECT ParentKey,
|
|
||||||
PKEY_OBJECT SubKey,
|
|
||||||
PUNICODE_STRING SubKeyName,
|
|
||||||
ULONG TitleIndex,
|
|
||||||
PUNICODE_STRING Class,
|
|
||||||
ULONG CreateOptions)
|
|
||||||
{
|
|
||||||
PHASH_TABLE_CELL HashBlock;
|
|
||||||
HCELL_INDEX NKBOffset;
|
|
||||||
PCM_KEY_NODE NewKeyCell;
|
|
||||||
ULONG NewBlockSize;
|
|
||||||
PCM_KEY_NODE ParentKeyCell;
|
|
||||||
PVOID ClassCell;
|
|
||||||
NTSTATUS Status;
|
|
||||||
USHORT NameSize;
|
|
||||||
PWSTR NamePtr;
|
|
||||||
BOOLEAN Packable;
|
|
||||||
HSTORAGE_TYPE Storage;
|
|
||||||
ULONG i;
|
|
||||||
|
|
||||||
ParentKeyCell = ParentKey->KeyCell;
|
|
||||||
|
|
||||||
VERIFY_KEY_CELL(ParentKeyCell);
|
|
||||||
|
|
||||||
/* Skip leading backslash */
|
|
||||||
if (SubKeyName->Buffer[0] == L'\\')
|
|
||||||
{
|
|
||||||
NamePtr = &SubKeyName->Buffer[1];
|
|
||||||
NameSize = SubKeyName->Length - sizeof(WCHAR);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NamePtr = SubKeyName->Buffer;
|
|
||||||
NameSize = SubKeyName->Length;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check whether key name can be packed */
|
|
||||||
Packable = TRUE;
|
|
||||||
for (i = 0; i < NameSize / sizeof(WCHAR); i++)
|
|
||||||
{
|
|
||||||
if (NamePtr[i] & 0xFF00)
|
|
||||||
{
|
|
||||||
Packable = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Adjust name size */
|
|
||||||
if (Packable)
|
|
||||||
{
|
|
||||||
NameSize = NameSize / sizeof(WCHAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("Key %S Length %lu %s\n", NamePtr, NameSize, (Packable)?"True":"False");
|
|
||||||
|
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
Storage = (CreateOptions & REG_OPTION_VOLATILE) ? Volatile : Stable;
|
|
||||||
NewBlockSize = sizeof(CM_KEY_NODE) + NameSize;
|
|
||||||
NKBOffset = HvAllocateCell (&RegistryHive->Hive, NewBlockSize, Storage, HCELL_NIL);
|
|
||||||
if (NKBOffset == HCELL_NIL)
|
|
||||||
{
|
|
||||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NewKeyCell = (PCM_KEY_NODE)HvGetCell (&RegistryHive->Hive, NKBOffset);
|
|
||||||
NewKeyCell->Id = REG_KEY_CELL_ID;
|
|
||||||
if (CreateOptions & REG_OPTION_VOLATILE)
|
|
||||||
{
|
|
||||||
NewKeyCell->Flags = REG_KEY_VOLATILE_CELL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NewKeyCell->Flags = 0;
|
|
||||||
}
|
|
||||||
KeQuerySystemTime(&NewKeyCell->LastWriteTime);
|
|
||||||
NewKeyCell->Parent = HCELL_NIL;
|
|
||||||
NewKeyCell->SubKeyCounts[Stable] = 0;
|
|
||||||
NewKeyCell->SubKeyCounts[Volatile] = 0;
|
|
||||||
NewKeyCell->SubKeyLists[Stable] = HCELL_NIL;
|
|
||||||
NewKeyCell->SubKeyLists[Volatile] = HCELL_NIL;
|
|
||||||
NewKeyCell->ValueList.Count = 0;
|
|
||||||
NewKeyCell->ValueList.List = HCELL_NIL;
|
|
||||||
NewKeyCell->SecurityKeyOffset = HCELL_NIL;
|
|
||||||
NewKeyCell->ClassNameOffset = HCELL_NIL;
|
|
||||||
|
|
||||||
/* Pack the key name */
|
|
||||||
NewKeyCell->NameSize = NameSize;
|
|
||||||
if (Packable)
|
|
||||||
{
|
|
||||||
NewKeyCell->Flags |= REG_KEY_NAME_PACKED;
|
|
||||||
for (i = 0; i < NameSize; i++)
|
|
||||||
{
|
|
||||||
NewKeyCell->Name[i] = (CHAR)(NamePtr[i] & 0x00FF);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RtlCopyMemory(NewKeyCell->Name,
|
|
||||||
NamePtr,
|
|
||||||
NameSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
VERIFY_KEY_CELL(NewKeyCell);
|
|
||||||
|
|
||||||
if (Class != NULL && Class->Length)
|
|
||||||
{
|
|
||||||
NewKeyCell->ClassSize = Class->Length;
|
|
||||||
NewKeyCell->ClassNameOffset = HvAllocateCell(
|
|
||||||
&RegistryHive->Hive, NewKeyCell->ClassSize, Stable, HCELL_NIL);
|
|
||||||
ASSERT(NewKeyCell->ClassNameOffset != HCELL_NIL); /* FIXME */
|
|
||||||
|
|
||||||
ClassCell = (PVOID)HvGetCell(&RegistryHive->Hive, NewKeyCell->ClassNameOffset);
|
|
||||||
RtlCopyMemory (ClassCell,
|
|
||||||
Class->Buffer,
|
|
||||||
Class->Length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
SubKey->KeyCell = NewKeyCell;
|
|
||||||
SubKey->KeyCellOffset = NKBOffset;
|
|
||||||
|
|
||||||
if (ParentKeyCell->SubKeyLists[Storage] == HCELL_NIL)
|
|
||||||
{
|
|
||||||
Status = CmiAllocateHashTableCell (RegistryHive,
|
|
||||||
&HashBlock,
|
|
||||||
&ParentKeyCell->SubKeyLists[Storage],
|
|
||||||
REG_INIT_HASH_TABLE_SIZE,
|
|
||||||
Storage);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HashBlock = (PHASH_TABLE_CELL)HvGetCell (&RegistryHive->Hive,
|
|
||||||
ParentKeyCell->SubKeyLists[Storage]);
|
|
||||||
ASSERT(HashBlock->Id == REG_HASH_TABLE_CELL_ID);
|
|
||||||
|
|
||||||
if (((ParentKeyCell->SubKeyCounts[Storage] + 1) >= HashBlock->HashTableSize))
|
|
||||||
{
|
|
||||||
PHASH_TABLE_CELL NewHashBlock;
|
|
||||||
HCELL_INDEX HTOffset;
|
|
||||||
|
|
||||||
/* Reallocate the hash table cell */
|
|
||||||
Status = CmiAllocateHashTableCell (RegistryHive,
|
|
||||||
&NewHashBlock,
|
|
||||||
&HTOffset,
|
|
||||||
HashBlock->HashTableSize +
|
|
||||||
REG_EXTEND_HASH_TABLE_SIZE,
|
|
||||||
Storage);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
RtlZeroMemory(&NewHashBlock->Table[0],
|
|
||||||
sizeof(NewHashBlock->Table[0]) * NewHashBlock->HashTableSize);
|
|
||||||
RtlCopyMemory(&NewHashBlock->Table[0],
|
|
||||||
&HashBlock->Table[0],
|
|
||||||
sizeof(NewHashBlock->Table[0]) * HashBlock->HashTableSize);
|
|
||||||
HvFreeCell (&RegistryHive->Hive, ParentKeyCell->SubKeyLists[Storage]);
|
|
||||||
ParentKeyCell->SubKeyLists[Storage] = HTOffset;
|
|
||||||
HashBlock = NewHashBlock;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = CmiAddKeyToHashTable(RegistryHive,
|
|
||||||
HashBlock,
|
|
||||||
ParentKeyCell,
|
|
||||||
Storage,
|
|
||||||
NewKeyCell,
|
|
||||||
NKBOffset);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
ParentKeyCell->SubKeyCounts[Storage]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
KeQuerySystemTime (&ParentKeyCell->LastWriteTime);
|
|
||||||
HvMarkCellDirty (&RegistryHive->Hive, ParentKey->KeyCellOffset, FALSE);
|
|
||||||
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
CmiAllocateHashTableCell (IN PEREGISTRY_HIVE RegistryHive,
|
|
||||||
OUT PHASH_TABLE_CELL *HashBlock,
|
|
||||||
OUT HCELL_INDEX *HBOffset,
|
|
||||||
IN ULONG SubKeyCount,
|
|
||||||
IN HSTORAGE_TYPE Storage)
|
|
||||||
{
|
|
||||||
PHASH_TABLE_CELL NewHashBlock;
|
|
||||||
ULONG NewHashSize;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
*HashBlock = NULL;
|
|
||||||
NewHashSize = sizeof(HASH_TABLE_CELL) +
|
|
||||||
(SubKeyCount * sizeof(HASH_RECORD));
|
|
||||||
*HBOffset = HvAllocateCell (&RegistryHive->Hive, NewHashSize, Storage, HCELL_NIL);
|
|
||||||
|
|
||||||
if (*HBOffset == HCELL_NIL)
|
|
||||||
{
|
|
||||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ASSERT(SubKeyCount <= 0xffff); /* should really be USHORT_MAX or similar */
|
|
||||||
NewHashBlock = (PHASH_TABLE_CELL)HvGetCell (&RegistryHive->Hive, *HBOffset);
|
|
||||||
NewHashBlock->Id = REG_HASH_TABLE_CELL_ID;
|
|
||||||
NewHashBlock->HashTableSize = (USHORT)SubKeyCount;
|
|
||||||
*HashBlock = NewHashBlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
CmiAddKeyToHashTable(PEREGISTRY_HIVE RegistryHive,
|
|
||||||
PHASH_TABLE_CELL HashCell,
|
|
||||||
PCM_KEY_NODE KeyCell,
|
|
||||||
HSTORAGE_TYPE StorageType,
|
|
||||||
PCM_KEY_NODE NewKeyCell,
|
|
||||||
HCELL_INDEX NKBOffset)
|
|
||||||
{
|
|
||||||
ULONG i = KeyCell->SubKeyCounts[StorageType];
|
|
||||||
|
|
||||||
HashCell->Table[i].KeyOffset = NKBOffset;
|
|
||||||
HashCell->Table[i].HashValue = 0;
|
|
||||||
if (NewKeyCell->Flags & REG_KEY_NAME_PACKED)
|
|
||||||
{
|
|
||||||
RtlCopyMemory(&HashCell->Table[i].HashValue,
|
|
||||||
NewKeyCell->Name,
|
|
||||||
min(NewKeyCell->NameSize, sizeof(ULONG)));
|
|
||||||
}
|
|
||||||
HvMarkCellDirty(&RegistryHive->Hive, KeyCell->SubKeyLists[StorageType], FALSE);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -432,7 +432,7 @@ CmpParseKey(IN PVOID ParsedObject,
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((SubKeyCell->Flags & REG_KEY_LINK_CELL) &&
|
if ((SubKeyCell->Flags & KEY_SYM_LINK) &&
|
||||||
!((Attributes & OBJ_OPENLINK) && (EndPtr == NULL)))
|
!((Attributes & OBJ_OPENLINK) && (EndPtr == NULL)))
|
||||||
{
|
{
|
||||||
RtlInitUnicodeString(&LinkPath, NULL);
|
RtlInitUnicodeString(&LinkPath, NULL);
|
||||||
|
@ -526,7 +526,7 @@ CmpParseKey(IN PVOID ParsedObject,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((FoundObject->KeyCell->Flags & REG_KEY_LINK_CELL) &&
|
if ((FoundObject->KeyCell->Flags & KEY_SYM_LINK) &&
|
||||||
!((Attributes & OBJ_OPENLINK) && (EndPtr == NULL)))
|
!((Attributes & OBJ_OPENLINK) && (EndPtr == NULL)))
|
||||||
{
|
{
|
||||||
DPRINT("Found link\n");
|
DPRINT("Found link\n");
|
||||||
|
@ -832,7 +832,7 @@ CmiGetLinkTarget(PEREGISTRY_HIVE RegistryHive,
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ValueCell->DataType != REG_LINK)
|
if (ValueCell->Type != REG_LINK)
|
||||||
{
|
{
|
||||||
DPRINT1("Type != REG_LINK\n!");
|
DPRINT1("Type != REG_LINK\n!");
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
@ -841,17 +841,17 @@ CmiGetLinkTarget(PEREGISTRY_HIVE RegistryHive,
|
||||||
if (TargetPath->Buffer == NULL && TargetPath->MaximumLength == 0)
|
if (TargetPath->Buffer == NULL && TargetPath->MaximumLength == 0)
|
||||||
{
|
{
|
||||||
TargetPath->Length = 0;
|
TargetPath->Length = 0;
|
||||||
TargetPath->MaximumLength = (USHORT)ValueCell->DataSize + sizeof(WCHAR);
|
TargetPath->MaximumLength = (USHORT)ValueCell->DataLength + sizeof(WCHAR);
|
||||||
TargetPath->Buffer = ExAllocatePool(NonPagedPool,
|
TargetPath->Buffer = ExAllocatePool(NonPagedPool,
|
||||||
TargetPath->MaximumLength);
|
TargetPath->MaximumLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetPath->Length = min((USHORT)TargetPath->MaximumLength - sizeof(WCHAR),
|
TargetPath->Length = min((USHORT)TargetPath->MaximumLength - sizeof(WCHAR),
|
||||||
(USHORT)ValueCell->DataSize);
|
(USHORT)ValueCell->DataLength);
|
||||||
|
|
||||||
if (ValueCell->DataSize > 0)
|
if (ValueCell->DataLength > 0)
|
||||||
{
|
{
|
||||||
DataCell = HvGetCell (&RegistryHive->Hive, ValueCell->DataOffset);
|
DataCell = HvGetCell (&RegistryHive->Hive, ValueCell->Data);
|
||||||
RtlCopyMemory(TargetPath->Buffer,
|
RtlCopyMemory(TargetPath->Buffer,
|
||||||
DataCell,
|
DataCell,
|
||||||
TargetPath->Length);
|
TargetPath->Length);
|
||||||
|
@ -860,7 +860,7 @@ CmiGetLinkTarget(PEREGISTRY_HIVE RegistryHive,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RtlCopyMemory(TargetPath->Buffer,
|
RtlCopyMemory(TargetPath->Buffer,
|
||||||
&ValueCell->DataOffset,
|
&ValueCell->Data,
|
||||||
TargetPath->Length);
|
TargetPath->Length);
|
||||||
TargetPath->Buffer[TargetPath->Length / sizeof(WCHAR)] = 0;
|
TargetPath->Buffer[TargetPath->Length / sizeof(WCHAR)] = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,14 +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));
|
||||||
|
|
||||||
//
|
|
||||||
// Key Types
|
|
||||||
//
|
|
||||||
#define CM_KEY_INDEX_ROOT 0x6972
|
|
||||||
#define CM_KEY_INDEX_LEAF 0x696c
|
|
||||||
#define CM_KEY_FAST_LEAF 0x666c
|
|
||||||
#define CM_KEY_HASH_LEAF 0x686c
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// CM_KEY_CONTROL_BLOCK Flags
|
// CM_KEY_CONTROL_BLOCK Flags
|
||||||
//
|
//
|
||||||
|
@ -64,29 +56,11 @@
|
||||||
#define CM_KEY_READ_ONLY_KEY 0x80
|
#define CM_KEY_READ_ONLY_KEY 0x80
|
||||||
|
|
||||||
//
|
//
|
||||||
// CM_KEY_NODE Signature and Flags
|
// CM_KEY_VALUE Types
|
||||||
//
|
//
|
||||||
#define CM_KEY_NODE_SIGNATURE 0x6B6E
|
|
||||||
#define CM_LINK_NODE_SIGNATURE 0x6B6C
|
|
||||||
#define KEY_IS_VOLATILE 0x01
|
|
||||||
#define KEY_HIVE_EXIT 0x02
|
|
||||||
#define KEY_HIVE_ENTRY 0x04
|
|
||||||
#define KEY_NO_DELETE 0x08
|
|
||||||
#define KEY_SYM_LINK 0x10
|
|
||||||
#define KEY_COMP_NAME 0x20
|
|
||||||
#define KEY_PREFEF_HANDLE 0x40
|
|
||||||
#define KEY_VIRT_MIRRORED 0x80
|
|
||||||
#define KEY_VIRT_TARGET 0x100
|
|
||||||
#define KEY_VIRTUAL_STORE 0x200
|
|
||||||
|
|
||||||
//
|
|
||||||
// CM_KEY_VALUE Signature and Flags
|
|
||||||
//
|
|
||||||
#define CM_KEY_VALUE_SIGNATURE 0x6b76
|
|
||||||
#define CM_KEY_VALUE_SMALL 0x4
|
#define CM_KEY_VALUE_SMALL 0x4
|
||||||
#define CM_KEY_VALUE_BIG 0x3FD8
|
#define CM_KEY_VALUE_BIG 0x3FD8
|
||||||
#define CM_KEY_VALUE_SPECIAL_SIZE 0x80000000
|
#define CM_KEY_VALUE_SPECIAL_SIZE 0x80000000
|
||||||
#define VALUE_COMP_NAME 0x0001
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Number of various lists and hashes
|
// Number of various lists and hashes
|
||||||
|
@ -419,127 +393,6 @@ typedef struct _CMHIVE
|
||||||
PKTHREAD CreatorOwner;
|
PKTHREAD CreatorOwner;
|
||||||
} CMHIVE, *PCMHIVE;
|
} CMHIVE, *PCMHIVE;
|
||||||
|
|
||||||
#include <pshpack1.h>
|
|
||||||
|
|
||||||
typedef struct _CM_VIEW_OF_FILE
|
|
||||||
{
|
|
||||||
LIST_ENTRY LRUViewList;
|
|
||||||
LIST_ENTRY PinViewList;
|
|
||||||
ULONG FileOffset;
|
|
||||||
ULONG Size;
|
|
||||||
PULONG ViewAddress;
|
|
||||||
PVOID Bcb;
|
|
||||||
ULONG UseCount;
|
|
||||||
} CM_VIEW_OF_FILE, *PCM_VIEW_OF_FILE;
|
|
||||||
|
|
||||||
typedef struct _CHILD_LIST
|
|
||||||
{
|
|
||||||
ULONG Count;
|
|
||||||
HCELL_INDEX List;
|
|
||||||
} CHILD_LIST, *PCHILD_LIST;
|
|
||||||
|
|
||||||
typedef struct _CM_KEY_NODE
|
|
||||||
{
|
|
||||||
USHORT Signature;
|
|
||||||
USHORT Flags;
|
|
||||||
LARGE_INTEGER LastWriteTime;
|
|
||||||
ULONG Spare;
|
|
||||||
HCELL_INDEX Parent;
|
|
||||||
ULONG SubKeyCounts[HTYPE_COUNT];
|
|
||||||
HCELL_INDEX SubKeyLists[HTYPE_COUNT];
|
|
||||||
CHILD_LIST ValueList;
|
|
||||||
HCELL_INDEX Security;
|
|
||||||
HCELL_INDEX Class;
|
|
||||||
ULONG MaxNameLen;
|
|
||||||
ULONG MaxClassLen;
|
|
||||||
ULONG MaxValueNameLen;
|
|
||||||
ULONG MaxValueDataLen;
|
|
||||||
ULONG WorkVar;
|
|
||||||
USHORT NameLength;
|
|
||||||
USHORT ClassLength;
|
|
||||||
WCHAR Name[0];
|
|
||||||
} CM_KEY_NODE, *PCM_KEY_NODE;
|
|
||||||
|
|
||||||
typedef struct _VALUE_LIST_CELL
|
|
||||||
{
|
|
||||||
HCELL_INDEX ValueOffset[0];
|
|
||||||
} VALUE_LIST_CELL, *PVALUE_LIST_CELL;
|
|
||||||
|
|
||||||
typedef struct _CM_KEY_VALUE
|
|
||||||
{
|
|
||||||
USHORT Signature; // "kv"
|
|
||||||
USHORT NameLength; // length of Name
|
|
||||||
ULONG DataLength; // length of datas in the cell pointed by DataOffset
|
|
||||||
HCELL_INDEX Data;// datas are here if high bit of DataSize is set
|
|
||||||
ULONG Type;
|
|
||||||
USHORT Flags;
|
|
||||||
USHORT Unused1;
|
|
||||||
WCHAR Name[0]; /* warning : not zero terminated */
|
|
||||||
} CM_KEY_VALUE, *PCM_KEY_VALUE;
|
|
||||||
|
|
||||||
typedef struct _CM_KEY_SECURITY
|
|
||||||
{
|
|
||||||
USHORT Signature; // "sk"
|
|
||||||
USHORT Reserved;
|
|
||||||
HCELL_INDEX Flink;
|
|
||||||
HCELL_INDEX Blink;
|
|
||||||
ULONG ReferenceCount;
|
|
||||||
ULONG DescriptorLength;
|
|
||||||
//SECURITY_DESCRIPTOR_RELATIVE Descriptor;
|
|
||||||
UCHAR Data[0];
|
|
||||||
} CM_KEY_SECURITY, *PCM_KEY_SECURITY;
|
|
||||||
|
|
||||||
#include <poppack.h>
|
|
||||||
|
|
||||||
//
|
|
||||||
// Generic Index Entry
|
|
||||||
//
|
|
||||||
typedef struct _CM_INDEX
|
|
||||||
{
|
|
||||||
HCELL_INDEX Cell;
|
|
||||||
union
|
|
||||||
{
|
|
||||||
UCHAR NameHint[4];
|
|
||||||
ULONG HashKey;
|
|
||||||
};
|
|
||||||
} CM_INDEX, *PCM_INDEX;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Key Index
|
|
||||||
//
|
|
||||||
typedef struct _CM_KEY_INDEX
|
|
||||||
{
|
|
||||||
USHORT Signature;
|
|
||||||
USHORT Count;
|
|
||||||
HCELL_INDEX List[ANYSIZE_ARRAY];
|
|
||||||
} CM_KEY_INDEX, *PCM_KEY_INDEX;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Fast/Hash Key Index
|
|
||||||
//
|
|
||||||
typedef struct _CM_KEY_FAST_INDEX
|
|
||||||
{
|
|
||||||
USHORT Signature;
|
|
||||||
USHORT Count;
|
|
||||||
CM_INDEX List[ANYSIZE_ARRAY];
|
|
||||||
} CM_KEY_FAST_INDEX, *PCM_KEY_FAST_INDEX;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Cell Data
|
|
||||||
//
|
|
||||||
typedef struct _CELL_DATA
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
CM_KEY_NODE KeyNode;
|
|
||||||
CM_KEY_VALUE KeyValue;
|
|
||||||
CM_KEY_SECURITY KeySecurity;
|
|
||||||
CM_KEY_INDEX KeyIndex;
|
|
||||||
HCELL_INDEX KeyList[ANYSIZE_ARRAY];
|
|
||||||
WCHAR KeyString[ANYSIZE_ARRAY];
|
|
||||||
} u;
|
|
||||||
} CELL_DATA, *PCELL_DATA;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Cached Value Index
|
// Cached Value Index
|
||||||
//
|
//
|
||||||
|
|
|
@ -607,7 +607,7 @@ CmpCreateRootNode(IN PHHIVE Hive,
|
||||||
if (!KeyCell) return FALSE;
|
if (!KeyCell) return FALSE;
|
||||||
|
|
||||||
/* Setup the cell */
|
/* Setup the cell */
|
||||||
KeyCell->Signature = (USHORT)CM_KEY_NODE_SIGNATURE;;
|
KeyCell->Signature = (USHORT)CM_KEY_NODE_SIGNATURE;
|
||||||
KeyCell->Flags = KEY_HIVE_ENTRY | KEY_NO_DELETE;
|
KeyCell->Flags = KEY_HIVE_ENTRY | KEY_NO_DELETE;
|
||||||
KeQuerySystemTime(&SystemTime);
|
KeQuerySystemTime(&SystemTime);
|
||||||
KeyCell->LastWriteTime = SystemTime;
|
KeyCell->LastWriteTime = SystemTime;
|
||||||
|
|
|
@ -150,39 +150,39 @@ CmiInitializeTempHive(
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
CmiAddKeyToHashTable(
|
CmiAddKeyToHashTable(
|
||||||
IN PEREGISTRY_HIVE RegistryHive,
|
IN PEREGISTRY_HIVE RegistryHive,
|
||||||
IN OUT PHASH_TABLE_CELL HashCell,
|
IN OUT PCM_KEY_FAST_INDEX HashCell,
|
||||||
IN PCM_KEY_NODE KeyCell,
|
IN PCM_KEY_NODE KeyCell,
|
||||||
IN HSTORAGE_TYPE StorageType,
|
IN HSTORAGE_TYPE StorageType,
|
||||||
IN PCM_KEY_NODE NewKeyCell,
|
IN PCM_KEY_NODE NewKeyCell,
|
||||||
IN HCELL_INDEX NKBOffset)
|
IN HCELL_INDEX NKBOffset)
|
||||||
{
|
{
|
||||||
ULONG i = KeyCell->SubKeyCounts[StorageType];
|
ULONG i = KeyCell->SubKeyCounts[StorageType];
|
||||||
ULONG HashValue;
|
ULONG HashKey;
|
||||||
|
|
||||||
if (NewKeyCell->Flags & REG_KEY_NAME_PACKED)
|
if (NewKeyCell->Flags & KEY_COMP_NAME)
|
||||||
{
|
{
|
||||||
RtlCopyMemory(
|
RtlCopyMemory(
|
||||||
&HashValue,
|
&HashKey,
|
||||||
NewKeyCell->Name,
|
NewKeyCell->Name,
|
||||||
min(NewKeyCell->NameSize, sizeof(ULONG)));
|
min(NewKeyCell->NameLength, sizeof(ULONG)));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < KeyCell->SubKeyCounts[StorageType]; i++)
|
for (i = 0; i < KeyCell->SubKeyCounts[StorageType]; i++)
|
||||||
{
|
{
|
||||||
if (HashCell->Table[i].HashValue > HashValue)
|
if (HashCell->List[i].HashKey > HashKey)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < KeyCell->SubKeyCounts[StorageType])
|
if (i < KeyCell->SubKeyCounts[StorageType])
|
||||||
{
|
{
|
||||||
RtlMoveMemory(HashCell->Table + i + 1,
|
RtlMoveMemory(HashCell->List + i + 1,
|
||||||
HashCell->Table + i,
|
HashCell->List + i,
|
||||||
(HashCell->HashTableSize - 1 - i) *
|
(HashCell->Count - 1 - i) *
|
||||||
sizeof(HashCell->Table[0]));
|
sizeof(HashCell->List[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
HashCell->Table[i].KeyOffset = NKBOffset;
|
HashCell->List[i].Cell = NKBOffset;
|
||||||
HashCell->Table[i].HashValue = HashValue;
|
HashCell->List[i].HashKey = HashKey;
|
||||||
HvMarkCellDirty(&RegistryHive->Hive, KeyCell->SubKeyLists[StorageType], FALSE);
|
HvMarkCellDirty(&RegistryHive->Hive, KeyCell->SubKeyLists[StorageType], FALSE);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -190,19 +190,19 @@ CmiAddKeyToHashTable(
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
CmiAllocateHashTableCell (
|
CmiAllocateHashTableCell (
|
||||||
IN PEREGISTRY_HIVE RegistryHive,
|
IN PEREGISTRY_HIVE RegistryHive,
|
||||||
OUT PHASH_TABLE_CELL *HashBlock,
|
OUT PCM_KEY_FAST_INDEX *HashBlock,
|
||||||
OUT HCELL_INDEX *HBOffset,
|
OUT HCELL_INDEX *HBOffset,
|
||||||
IN USHORT SubKeyCount,
|
IN USHORT SubKeyCount,
|
||||||
IN HSTORAGE_TYPE Storage)
|
IN HSTORAGE_TYPE Storage)
|
||||||
{
|
{
|
||||||
PHASH_TABLE_CELL NewHashBlock;
|
PCM_KEY_FAST_INDEX NewHashBlock;
|
||||||
ULONG NewHashSize;
|
ULONG NewHashSize;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
*HashBlock = NULL;
|
*HashBlock = NULL;
|
||||||
NewHashSize = sizeof(HASH_TABLE_CELL) +
|
NewHashSize = sizeof(CM_KEY_FAST_INDEX) +
|
||||||
(SubKeyCount * sizeof(HASH_RECORD));
|
(SubKeyCount * sizeof(CM_INDEX));
|
||||||
*HBOffset = HvAllocateCell(&RegistryHive->Hive, NewHashSize, Storage, HCELL_NIL);
|
*HBOffset = HvAllocateCell(&RegistryHive->Hive, NewHashSize, Storage, HCELL_NIL);
|
||||||
|
|
||||||
if (*HBOffset == HCELL_NIL)
|
if (*HBOffset == HCELL_NIL)
|
||||||
|
@ -212,9 +212,9 @@ CmiAllocateHashTableCell (
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ASSERT(SubKeyCount <= USHORT_MAX);
|
ASSERT(SubKeyCount <= USHORT_MAX);
|
||||||
NewHashBlock = (PHASH_TABLE_CELL)HvGetCell (&RegistryHive->Hive, *HBOffset);
|
NewHashBlock = (PCM_KEY_FAST_INDEX)HvGetCell (&RegistryHive->Hive, *HBOffset);
|
||||||
NewHashBlock->Id = REG_HASH_TABLE_CELL_ID;
|
NewHashBlock->Signature = CM_KEY_FAST_LEAF;
|
||||||
NewHashBlock->HashTableSize = SubKeyCount;
|
NewHashBlock->Count = SubKeyCount;
|
||||||
*HashBlock = NewHashBlock;
|
*HashBlock = NewHashBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,12 +231,12 @@ CmiAddSubKey(
|
||||||
OUT PCM_KEY_NODE *pSubKeyCell,
|
OUT PCM_KEY_NODE *pSubKeyCell,
|
||||||
OUT HCELL_INDEX *pBlockOffset)
|
OUT HCELL_INDEX *pBlockOffset)
|
||||||
{
|
{
|
||||||
PHASH_TABLE_CELL HashBlock;
|
PCM_KEY_FAST_INDEX HashBlock;
|
||||||
HCELL_INDEX NKBOffset;
|
HCELL_INDEX NKBOffset;
|
||||||
PCM_KEY_NODE NewKeyCell;
|
PCM_KEY_NODE NewKeyCell;
|
||||||
ULONG NewBlockSize;
|
ULONG NewBlockSize;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
USHORT NameSize;
|
USHORT NameLength;
|
||||||
PWSTR NamePtr;
|
PWSTR NamePtr;
|
||||||
BOOLEAN Packable;
|
BOOLEAN Packable;
|
||||||
HSTORAGE_TYPE Storage;
|
HSTORAGE_TYPE Storage;
|
||||||
|
@ -250,17 +250,17 @@ CmiAddSubKey(
|
||||||
if (SubKeyName->Buffer[0] == L'\\')
|
if (SubKeyName->Buffer[0] == L'\\')
|
||||||
{
|
{
|
||||||
NamePtr = &SubKeyName->Buffer[1];
|
NamePtr = &SubKeyName->Buffer[1];
|
||||||
NameSize = SubKeyName->Length - sizeof(WCHAR);
|
NameLength = SubKeyName->Length - sizeof(WCHAR);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NamePtr = SubKeyName->Buffer;
|
NamePtr = SubKeyName->Buffer;
|
||||||
NameSize = SubKeyName->Length;
|
NameLength = SubKeyName->Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check whether key name can be packed */
|
/* Check whether key name can be packed */
|
||||||
Packable = TRUE;
|
Packable = TRUE;
|
||||||
for (i = 0; i < NameSize / sizeof(WCHAR); i++)
|
for (i = 0; i < NameLength / sizeof(WCHAR); i++)
|
||||||
{
|
{
|
||||||
if (NamePtr[i] & 0xFF00)
|
if (NamePtr[i] & 0xFF00)
|
||||||
{
|
{
|
||||||
|
@ -272,13 +272,13 @@ CmiAddSubKey(
|
||||||
/* Adjust name size */
|
/* Adjust name size */
|
||||||
if (Packable)
|
if (Packable)
|
||||||
{
|
{
|
||||||
NameSize = NameSize / sizeof(WCHAR);
|
NameLength = NameLength / sizeof(WCHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
Storage = (CreateOptions & REG_OPTION_VOLATILE) ? Volatile : Stable;
|
Storage = (CreateOptions & REG_OPTION_VOLATILE) ? Volatile : Stable;
|
||||||
NewBlockSize = sizeof(CM_KEY_NODE) + NameSize;
|
NewBlockSize = sizeof(CM_KEY_NODE) + NameLength;
|
||||||
NKBOffset = HvAllocateCell(&RegistryHive->Hive, NewBlockSize, Storage, HCELL_NIL);
|
NKBOffset = HvAllocateCell(&RegistryHive->Hive, NewBlockSize, Storage, HCELL_NIL);
|
||||||
if (NKBOffset == HCELL_NIL)
|
if (NKBOffset == HCELL_NIL)
|
||||||
{
|
{
|
||||||
|
@ -287,10 +287,10 @@ CmiAddSubKey(
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NewKeyCell = (PCM_KEY_NODE)HvGetCell (&RegistryHive->Hive, NKBOffset);
|
NewKeyCell = (PCM_KEY_NODE)HvGetCell (&RegistryHive->Hive, NKBOffset);
|
||||||
NewKeyCell->Id = REG_KEY_CELL_ID;
|
NewKeyCell->Signature = CM_KEY_NODE_SIGNATURE;
|
||||||
if (CreateOptions & REG_OPTION_VOLATILE)
|
if (CreateOptions & REG_OPTION_VOLATILE)
|
||||||
{
|
{
|
||||||
NewKeyCell->Flags = REG_KEY_VOLATILE_CELL;
|
NewKeyCell->Flags = KEY_IS_VOLATILE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -304,17 +304,17 @@ CmiAddSubKey(
|
||||||
NewKeyCell->SubKeyLists[Volatile] = HCELL_NIL;
|
NewKeyCell->SubKeyLists[Volatile] = HCELL_NIL;
|
||||||
NewKeyCell->ValueList.Count = 0;
|
NewKeyCell->ValueList.Count = 0;
|
||||||
NewKeyCell->ValueList.List = HCELL_NIL;
|
NewKeyCell->ValueList.List = HCELL_NIL;
|
||||||
NewKeyCell->SecurityKeyOffset = HCELL_NIL;
|
NewKeyCell->Security = HCELL_NIL;
|
||||||
NewKeyCell->ClassNameOffset = HCELL_NIL;
|
NewKeyCell->Class = HCELL_NIL;
|
||||||
|
|
||||||
/* Pack the key name */
|
/* Pack the key name */
|
||||||
NewKeyCell->NameSize = NameSize;
|
NewKeyCell->NameLength = NameLength;
|
||||||
if (Packable)
|
if (Packable)
|
||||||
{
|
{
|
||||||
NewKeyCell->Flags |= REG_KEY_NAME_PACKED;
|
NewKeyCell->Flags |= KEY_COMP_NAME;
|
||||||
for (i = 0; i < NameSize; i++)
|
for (i = 0; i < NameLength; i++)
|
||||||
{
|
{
|
||||||
NewKeyCell->Name[i] = (CHAR)(NamePtr[i] & 0x00FF);
|
((PCHAR)NewKeyCell->Name)[i] = (CHAR)(NamePtr[i] & 0x00FF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -322,7 +322,7 @@ CmiAddSubKey(
|
||||||
RtlCopyMemory(
|
RtlCopyMemory(
|
||||||
NewKeyCell->Name,
|
NewKeyCell->Name,
|
||||||
NamePtr,
|
NamePtr,
|
||||||
NameSize);
|
NameLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
VERIFY_KEY_CELL(NewKeyCell);
|
VERIFY_KEY_CELL(NewKeyCell);
|
||||||
|
@ -348,14 +348,14 @@ CmiAddSubKey(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HashBlock = (PHASH_TABLE_CELL)HvGetCell (
|
HashBlock = (PCM_KEY_FAST_INDEX)HvGetCell (
|
||||||
&RegistryHive->Hive,
|
&RegistryHive->Hive,
|
||||||
ParentKeyCell->SubKeyLists[Storage]);
|
ParentKeyCell->SubKeyLists[Storage]);
|
||||||
ASSERT(HashBlock->Id == REG_HASH_TABLE_CELL_ID);
|
ASSERT(HashBlock->Signature == CM_KEY_FAST_LEAF);
|
||||||
|
|
||||||
if (((ParentKeyCell->SubKeyCounts[Storage] + 1) >= HashBlock->HashTableSize))
|
if (((ParentKeyCell->SubKeyCounts[Storage] + 1) >= HashBlock->Count))
|
||||||
{
|
{
|
||||||
PHASH_TABLE_CELL NewHashBlock;
|
PCM_KEY_FAST_INDEX NewHashBlock;
|
||||||
HCELL_INDEX HTOffset;
|
HCELL_INDEX HTOffset;
|
||||||
|
|
||||||
/* Reallocate the hash table cell */
|
/* Reallocate the hash table cell */
|
||||||
|
@ -363,7 +363,7 @@ CmiAddSubKey(
|
||||||
RegistryHive,
|
RegistryHive,
|
||||||
&NewHashBlock,
|
&NewHashBlock,
|
||||||
&HTOffset,
|
&HTOffset,
|
||||||
HashBlock->HashTableSize +
|
HashBlock->Count +
|
||||||
REG_EXTEND_HASH_TABLE_SIZE,
|
REG_EXTEND_HASH_TABLE_SIZE,
|
||||||
Storage);
|
Storage);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -372,12 +372,12 @@ CmiAddSubKey(
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlZeroMemory(
|
RtlZeroMemory(
|
||||||
&NewHashBlock->Table[0],
|
&NewHashBlock->List[0],
|
||||||
sizeof(NewHashBlock->Table[0]) * NewHashBlock->HashTableSize);
|
sizeof(NewHashBlock->List[0]) * NewHashBlock->Count);
|
||||||
RtlCopyMemory(
|
RtlCopyMemory(
|
||||||
&NewHashBlock->Table[0],
|
&NewHashBlock->List[0],
|
||||||
&HashBlock->Table[0],
|
&HashBlock->List[0],
|
||||||
sizeof(NewHashBlock->Table[0]) * HashBlock->HashTableSize);
|
sizeof(NewHashBlock->List[0]) * HashBlock->Count);
|
||||||
HvFreeCell (&RegistryHive->Hive, ParentKeyCell->SubKeyLists[Storage]);
|
HvFreeCell (&RegistryHive->Hive, ParentKeyCell->SubKeyLists[Storage]);
|
||||||
ParentKeyCell->SubKeyLists[Storage] = HTOffset;
|
ParentKeyCell->SubKeyLists[Storage] = HTOffset;
|
||||||
HashBlock = NewHashBlock;
|
HashBlock = NewHashBlock;
|
||||||
|
@ -443,24 +443,24 @@ CmiCompareKeyNames(
|
||||||
PWCHAR UnicodeName;
|
PWCHAR UnicodeName;
|
||||||
USHORT i;
|
USHORT i;
|
||||||
|
|
||||||
if (KeyCell->Flags & REG_KEY_NAME_PACKED)
|
if (KeyCell->Flags & KEY_COMP_NAME)
|
||||||
{
|
{
|
||||||
if (KeyName->Length != KeyCell->NameSize * sizeof(WCHAR))
|
if (KeyName->Length != KeyCell->NameLength * sizeof(WCHAR))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
for (i = 0; i < KeyCell->NameSize; i++)
|
for (i = 0; i < KeyCell->NameLength; i++)
|
||||||
{
|
{
|
||||||
if (KeyName->Buffer[i] != (WCHAR)KeyCell->Name[i])
|
if (((PCHAR)KeyName->Buffer)[i] != (WCHAR)KeyCell->Name[i])
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (KeyName->Length != KeyCell->NameSize)
|
if (KeyName->Length != KeyCell->NameLength)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
UnicodeName = (PWCHAR)KeyCell->Name;
|
UnicodeName = (PWCHAR)KeyCell->Name;
|
||||||
for (i = 0; i < KeyCell->NameSize / sizeof(WCHAR); i++)
|
for (i = 0; i < KeyCell->NameLength / sizeof(WCHAR); i++)
|
||||||
{
|
{
|
||||||
if (KeyName->Buffer[i] != UnicodeName[i])
|
if (KeyName->Buffer[i] != UnicodeName[i])
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -480,27 +480,27 @@ CmiCompareKeyNamesI(
|
||||||
|
|
||||||
DPRINT("Flags: %hx\n", KeyCell->Flags);
|
DPRINT("Flags: %hx\n", KeyCell->Flags);
|
||||||
|
|
||||||
if (KeyCell->Flags & REG_KEY_NAME_PACKED)
|
if (KeyCell->Flags & KEY_COMP_NAME)
|
||||||
{
|
{
|
||||||
if (KeyName->Length != KeyCell->NameSize * sizeof(WCHAR))
|
if (KeyName->Length != KeyCell->NameLength * sizeof(WCHAR))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* FIXME: use _strnicmp */
|
/* FIXME: use _strnicmp */
|
||||||
for (i = 0; i < KeyCell->NameSize; i++)
|
for (i = 0; i < KeyCell->NameLength; i++)
|
||||||
{
|
{
|
||||||
if (RtlUpcaseUnicodeChar(KeyName->Buffer[i]) !=
|
if (RtlUpcaseUnicodeChar(((PCHAR)KeyName->Buffer)[i]) !=
|
||||||
RtlUpcaseUnicodeChar((WCHAR)KeyCell->Name[i]))
|
RtlUpcaseUnicodeChar((WCHAR)KeyCell->Name[i]))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (KeyName->Length != KeyCell->NameSize)
|
if (KeyName->Length != KeyCell->NameLength)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
UnicodeName = (PWCHAR)KeyCell->Name;
|
UnicodeName = (PWCHAR)KeyCell->Name;
|
||||||
/* FIXME: use _strnicmp */
|
/* FIXME: use _strnicmp */
|
||||||
for (i = 0; i < KeyCell->NameSize / sizeof(WCHAR); i++)
|
for (i = 0; i < KeyCell->NameLength / sizeof(WCHAR); i++)
|
||||||
{
|
{
|
||||||
if (RtlUpcaseUnicodeChar(KeyName->Buffer[i]) !=
|
if (RtlUpcaseUnicodeChar(KeyName->Buffer[i]) !=
|
||||||
RtlUpcaseUnicodeChar(UnicodeName[i]))
|
RtlUpcaseUnicodeChar(UnicodeName[i]))
|
||||||
|
@ -520,7 +520,7 @@ CmiScanForSubKey(
|
||||||
OUT PCM_KEY_NODE *pSubKeyCell,
|
OUT PCM_KEY_NODE *pSubKeyCell,
|
||||||
OUT HCELL_INDEX *pBlockOffset)
|
OUT HCELL_INDEX *pBlockOffset)
|
||||||
{
|
{
|
||||||
PHASH_TABLE_CELL HashBlock;
|
PCM_KEY_FAST_INDEX HashBlock;
|
||||||
PCM_KEY_NODE CurSubKeyCell;
|
PCM_KEY_NODE CurSubKeyCell;
|
||||||
ULONG Storage;
|
ULONG Storage;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
@ -542,42 +542,42 @@ CmiScanForSubKey(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get hash table */
|
/* Get hash table */
|
||||||
HashBlock = (PHASH_TABLE_CELL)HvGetCell (&RegistryHive->Hive, KeyCell->SubKeyLists[Storage]);
|
HashBlock = (PCM_KEY_FAST_INDEX)HvGetCell (&RegistryHive->Hive, KeyCell->SubKeyLists[Storage]);
|
||||||
if (!HashBlock || HashBlock->Id != REG_HASH_TABLE_CELL_ID)
|
if (!HashBlock || HashBlock->Signature != CM_KEY_FAST_LEAF)
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++)
|
for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++)
|
||||||
{
|
{
|
||||||
if (Attributes & OBJ_CASE_INSENSITIVE)
|
if (Attributes & OBJ_CASE_INSENSITIVE)
|
||||||
{
|
{
|
||||||
if ((HashBlock->Table[i].HashValue == 0
|
if ((HashBlock->List[i].HashKey == 0
|
||||||
|| CmiCompareHashI(SubKeyName, (PCHAR)&HashBlock->Table[i].HashValue)))
|
|| CmiCompareHashI(SubKeyName, (PCHAR)&HashBlock->List[i].HashKey)))
|
||||||
{
|
{
|
||||||
CurSubKeyCell = (PCM_KEY_NODE)HvGetCell (
|
CurSubKeyCell = (PCM_KEY_NODE)HvGetCell (
|
||||||
&RegistryHive->Hive,
|
&RegistryHive->Hive,
|
||||||
HashBlock->Table[i].KeyOffset);
|
HashBlock->List[i].Cell);
|
||||||
|
|
||||||
if (CmiCompareKeyNamesI(SubKeyName, CurSubKeyCell))
|
if (CmiCompareKeyNamesI(SubKeyName, CurSubKeyCell))
|
||||||
{
|
{
|
||||||
*pSubKeyCell = CurSubKeyCell;
|
*pSubKeyCell = CurSubKeyCell;
|
||||||
*pBlockOffset = HashBlock->Table[i].KeyOffset;
|
*pBlockOffset = HashBlock->List[i].Cell;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((HashBlock->Table[i].HashValue == 0
|
if ((HashBlock->List[i].HashKey == 0
|
||||||
|| CmiCompareHash(SubKeyName, (PCHAR)&HashBlock->Table[i].HashValue)))
|
|| CmiCompareHash(SubKeyName, (PCHAR)&HashBlock->List[i].HashKey)))
|
||||||
{
|
{
|
||||||
CurSubKeyCell = (PCM_KEY_NODE)HvGetCell (
|
CurSubKeyCell = (PCM_KEY_NODE)HvGetCell (
|
||||||
&RegistryHive->Hive,
|
&RegistryHive->Hive,
|
||||||
HashBlock->Table[i].KeyOffset);
|
HashBlock->List[i].Cell);
|
||||||
|
|
||||||
if (CmiCompareKeyNames(SubKeyName, CurSubKeyCell))
|
if (CmiCompareKeyNames(SubKeyName, CurSubKeyCell))
|
||||||
{
|
{
|
||||||
*pSubKeyCell = CurSubKeyCell;
|
*pSubKeyCell = CurSubKeyCell;
|
||||||
*pBlockOffset = HashBlock->Table[i].KeyOffset;
|
*pBlockOffset = HashBlock->List[i].Cell;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -619,32 +619,32 @@ CmiAllocateValueCell(
|
||||||
{
|
{
|
||||||
PCM_KEY_VALUE NewValueCell;
|
PCM_KEY_VALUE NewValueCell;
|
||||||
BOOLEAN Packable;
|
BOOLEAN Packable;
|
||||||
USHORT NameSize, i;
|
USHORT NameLength, i;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
NameSize = CmiGetPackedNameLength(ValueName, &Packable);
|
NameLength = CmiGetPackedNameLength(ValueName, &Packable);
|
||||||
|
|
||||||
DPRINT("ValueName->Length %lu NameSize %lu\n", ValueName->Length, NameSize);
|
DPRINT("ValueName->Length %lu NameLength %lu\n", ValueName->Length, NameLength);
|
||||||
|
|
||||||
*VBOffset = HvAllocateCell(&RegistryHive->Hive, sizeof(CM_KEY_VALUE) + NameSize, Storage, HCELL_NIL);
|
*VBOffset = HvAllocateCell(&RegistryHive->Hive, sizeof(CM_KEY_VALUE) + NameLength, Storage, HCELL_NIL);
|
||||||
if (*VBOffset == HCELL_NIL)
|
if (*VBOffset == HCELL_NIL)
|
||||||
{
|
{
|
||||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ASSERT(NameSize <= USHORT_MAX);
|
ASSERT(NameLength <= USHORT_MAX);
|
||||||
NewValueCell = (PCM_KEY_VALUE)HvGetCell (&RegistryHive->Hive, *VBOffset);
|
NewValueCell = (PCM_KEY_VALUE)HvGetCell (&RegistryHive->Hive, *VBOffset);
|
||||||
NewValueCell->Id = REG_VALUE_CELL_ID;
|
NewValueCell->Signature = CM_KEY_VALUE_SIGNATURE;
|
||||||
NewValueCell->NameSize = (USHORT)NameSize;
|
NewValueCell->NameLength = (USHORT)NameLength;
|
||||||
if (Packable)
|
if (Packable)
|
||||||
{
|
{
|
||||||
/* Pack the value name */
|
/* Pack the value name */
|
||||||
for (i = 0; i < NameSize; i++)
|
for (i = 0; i < NameLength; i++)
|
||||||
NewValueCell->Name[i] = (CHAR)ValueName->Buffer[i];
|
((PCHAR)NewValueCell->Name)[i] = (CHAR)ValueName->Buffer[i];
|
||||||
NewValueCell->Flags |= REG_VALUE_NAME_PACKED;
|
NewValueCell->Flags |= VALUE_COMP_NAME;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -652,12 +652,12 @@ CmiAllocateValueCell(
|
||||||
RtlCopyMemory(
|
RtlCopyMemory(
|
||||||
NewValueCell->Name,
|
NewValueCell->Name,
|
||||||
ValueName->Buffer,
|
ValueName->Buffer,
|
||||||
NameSize);
|
NameLength);
|
||||||
NewValueCell->Flags = 0;
|
NewValueCell->Flags = 0;
|
||||||
}
|
}
|
||||||
NewValueCell->DataType = 0;
|
NewValueCell->Type = 0;
|
||||||
NewValueCell->DataSize = 0;
|
NewValueCell->DataLength = 0;
|
||||||
NewValueCell->DataOffset = HCELL_NIL;
|
NewValueCell->Data = HCELL_NIL;
|
||||||
*ValueCell = NewValueCell;
|
*ValueCell = NewValueCell;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -681,7 +681,7 @@ CmiAddValueKey(
|
||||||
HSTORAGE_TYPE Storage;
|
HSTORAGE_TYPE Storage;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
Storage = (KeyCell->Flags & REG_KEY_VOLATILE_CELL) ? Volatile : Stable;
|
Storage = (KeyCell->Flags & KEY_IS_VOLATILE) ? Volatile : Stable;
|
||||||
if (KeyCell->ValueList.List == HCELL_NIL)
|
if (KeyCell->ValueList.List == HCELL_NIL)
|
||||||
{
|
{
|
||||||
/* Allocate some room for the value list */
|
/* Allocate some room for the value list */
|
||||||
|
@ -811,9 +811,9 @@ CmiScanForValueKey(
|
||||||
|
|
||||||
if (CmiComparePackedNames(
|
if (CmiComparePackedNames(
|
||||||
ValueName,
|
ValueName,
|
||||||
CurValueCell->Name,
|
(PUCHAR)CurValueCell->Name,
|
||||||
CurValueCell->NameSize,
|
CurValueCell->NameLength,
|
||||||
(BOOLEAN)((CurValueCell->Flags & REG_VALUE_NAME_PACKED) ? TRUE : FALSE)))
|
(BOOLEAN)((CurValueCell->Flags & VALUE_COMP_NAME) ? TRUE : FALSE)))
|
||||||
{
|
{
|
||||||
*pValueCell = CurValueCell;
|
*pValueCell = CurValueCell;
|
||||||
*pValueCellOffset = ValueListCell->ValueOffset[i];
|
*pValueCellOffset = ValueListCell->ValueOffset[i];
|
||||||
|
|
|
@ -37,6 +37,9 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include "mkhive.h"
|
#include "mkhive.h"
|
||||||
|
|
||||||
|
#define REG_DATA_SIZE_MASK 0x7FFFFFFF
|
||||||
|
#define REG_DATA_IN_OFFSET 0x80000000
|
||||||
|
|
||||||
static EREGISTRY_HIVE RootHive;
|
static EREGISTRY_HIVE RootHive;
|
||||||
static MEMKEY RootKey;
|
static MEMKEY RootKey;
|
||||||
EREGISTRY_HIVE DefaultHive; /* \Registry\User\.DEFAULT */
|
EREGISTRY_HIVE DefaultHive; /* \Registry\User\.DEFAULT */
|
||||||
|
@ -362,10 +365,10 @@ RegSetValueExW(
|
||||||
return ERROR_UNSUCCESSFUL;
|
return ERROR_UNSUCCESSFUL;
|
||||||
|
|
||||||
/* Get size of the allocated cellule (if any) */
|
/* Get size of the allocated cellule (if any) */
|
||||||
if (!(ValueCell->DataSize & REG_DATA_IN_OFFSET) &&
|
if (!(ValueCell->DataLength & REG_DATA_IN_OFFSET) &&
|
||||||
(ValueCell->DataSize & REG_DATA_SIZE_MASK) != 0)
|
(ValueCell->DataLength & REG_DATA_SIZE_MASK) != 0)
|
||||||
{
|
{
|
||||||
DataCell = HvGetCell(&Key->RegistryHive->Hive, ValueCell->DataOffset);
|
DataCell = HvGetCell(&Key->RegistryHive->Hive, ValueCell->Data);
|
||||||
if (!DataCell)
|
if (!DataCell)
|
||||||
return ERROR_UNSUCCESSFUL;
|
return ERROR_UNSUCCESSFUL;
|
||||||
DataCellSize = -HvGetCellSize(&Key->RegistryHive->Hive, DataCell);
|
DataCellSize = -HvGetCellSize(&Key->RegistryHive->Hive, DataCell);
|
||||||
|
@ -379,13 +382,13 @@ RegSetValueExW(
|
||||||
if (cbData <= sizeof(HCELL_INDEX))
|
if (cbData <= sizeof(HCELL_INDEX))
|
||||||
{
|
{
|
||||||
/* If data size <= sizeof(HCELL_INDEX) then store data in the data offset */
|
/* If data size <= sizeof(HCELL_INDEX) then store data in the data offset */
|
||||||
DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize);
|
DPRINT("ValueCell->DataLength %lu\n", ValueCell->DataLength);
|
||||||
if (DataCell)
|
if (DataCell)
|
||||||
HvFreeCell(&Key->RegistryHive->Hive, ValueCell->DataOffset);
|
HvFreeCell(&Key->RegistryHive->Hive, ValueCell->Data);
|
||||||
|
|
||||||
RtlCopyMemory(&ValueCell->DataOffset, lpData, cbData);
|
RtlCopyMemory(&ValueCell->Data, lpData, cbData);
|
||||||
ValueCell->DataSize = (ULONG)(cbData | REG_DATA_IN_OFFSET);
|
ValueCell->DataLength = (ULONG)(cbData | REG_DATA_IN_OFFSET);
|
||||||
ValueCell->DataType = dwType;
|
ValueCell->Type = dwType;
|
||||||
HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCellOffset, FALSE);
|
HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCellOffset, FALSE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -396,7 +399,7 @@ RegSetValueExW(
|
||||||
* data block and allocate a new one. */
|
* data block and allocate a new one. */
|
||||||
HCELL_INDEX NewOffset;
|
HCELL_INDEX NewOffset;
|
||||||
|
|
||||||
DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize);
|
DPRINT("ValueCell->DataLength %lu\n", ValueCell->DataLength);
|
||||||
|
|
||||||
NewOffset = HvAllocateCell(&Key->RegistryHive->Hive, cbData, Stable, HCELL_NIL);
|
NewOffset = HvAllocateCell(&Key->RegistryHive->Hive, cbData, Stable, HCELL_NIL);
|
||||||
if (NewOffset == HCELL_NIL)
|
if (NewOffset == HCELL_NIL)
|
||||||
|
@ -406,17 +409,17 @@ RegSetValueExW(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DataCell)
|
if (DataCell)
|
||||||
HvFreeCell(&Key->RegistryHive->Hive, ValueCell->DataOffset);
|
HvFreeCell(&Key->RegistryHive->Hive, ValueCell->Data);
|
||||||
|
|
||||||
ValueCell->DataOffset = NewOffset;
|
ValueCell->Data = NewOffset;
|
||||||
DataCell = (PVOID)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->DataLength = (ULONG)(cbData & REG_DATA_SIZE_MASK);
|
||||||
ValueCell->DataType = dwType;
|
ValueCell->Type = dwType;
|
||||||
HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCell->DataOffset, FALSE);
|
HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCell->Data, FALSE);
|
||||||
HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCellOffset, FALSE);
|
HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCellOffset, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue