mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 17:25:55 +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 <debug.h>
|
||||
|
||||
#define REG_DATA_SIZE_MASK 0x7FFFFFFF
|
||||
#define REG_DATA_IN_OFFSET 0x80000000
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
static PVOID
|
||||
|
@ -46,20 +49,20 @@ CmiAllocateHashTableCell (PHHIVE Hive,
|
|||
PHCELL_INDEX HBOffset,
|
||||
ULONG SubKeyCount)
|
||||
{
|
||||
PHASH_TABLE_CELL HashCell;
|
||||
PCM_KEY_FAST_INDEX HashCell;
|
||||
ULONG NewHashSize;
|
||||
|
||||
NewHashSize = sizeof(HASH_TABLE_CELL) +
|
||||
(SubKeyCount * sizeof(HASH_RECORD));
|
||||
NewHashSize = sizeof(CM_KEY_FAST_INDEX) +
|
||||
(SubKeyCount * sizeof(CM_INDEX));
|
||||
*HBOffset = HvAllocateCell (Hive, NewHashSize, Stable, HCELL_NIL);
|
||||
if (*HBOffset == HCELL_NIL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HashCell = (PHASH_TABLE_CELL)HvGetCell (Hive, *HBOffset);
|
||||
HashCell->Id = REG_HASH_TABLE_CELL_ID;
|
||||
HashCell->HashTableSize = SubKeyCount;
|
||||
HashCell = (PCM_KEY_FAST_INDEX)HvGetCell (Hive, *HBOffset);
|
||||
HashCell->Signature = CM_KEY_FAST_LEAF;
|
||||
HashCell->Count = SubKeyCount;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -71,21 +74,21 @@ CmiAddKeyToParentHashTable (PHHIVE Hive,
|
|||
PCM_KEY_NODE NewKeyCell,
|
||||
HCELL_INDEX NKBOffset)
|
||||
{
|
||||
PHASH_TABLE_CELL HashBlock;
|
||||
PCM_KEY_FAST_INDEX HashBlock;
|
||||
PCM_KEY_NODE ParentKeyCell;
|
||||
ULONG i;
|
||||
|
||||
ParentKeyCell = (PVOID)HvGetCell (Hive, Parent);
|
||||
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;
|
||||
memcpy (&HashBlock->Table[i].HashValue,
|
||||
HashBlock->List[i].Cell = NKBOffset;
|
||||
memcpy (&HashBlock->List[i].HashKey,
|
||||
NewKeyCell->Name,
|
||||
min(NewKeyCell->NameSize, sizeof(ULONG)));
|
||||
min(NewKeyCell->NameLength, sizeof(ULONG)));
|
||||
ParentKeyCell->SubKeyCounts[Stable]++;
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -122,21 +125,21 @@ CmiAllocateValueCell(PHHIVE Hive,
|
|||
PWCHAR ValueName)
|
||||
{
|
||||
PCM_KEY_VALUE NewValueCell;
|
||||
ULONG NameSize;
|
||||
ULONG NameLength;
|
||||
BOOLEAN Packable = TRUE;
|
||||
ULONG i;
|
||||
|
||||
NameSize = (ValueName == NULL) ? 0 : wcslen (ValueName);
|
||||
for (i = 0; i < NameSize; i++)
|
||||
NameLength = (ValueName == NULL) ? 0 : wcslen (ValueName);
|
||||
for (i = 0; i < NameLength; i++)
|
||||
{
|
||||
if (ValueName[i] & 0xFF00)
|
||||
{
|
||||
NameSize *= sizeof(WCHAR);
|
||||
NameLength *= sizeof(WCHAR);
|
||||
Packable = FALSE;
|
||||
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)
|
||||
{
|
||||
DbgPrint((DPRINT_REGISTRY, "CmiAllocateCell() failed\n"));
|
||||
|
@ -144,29 +147,29 @@ CmiAllocateValueCell(PHHIVE Hive,
|
|||
}
|
||||
|
||||
NewValueCell = (PCM_KEY_VALUE) HvGetCell (Hive, *ValueCellOffset);
|
||||
NewValueCell->Id = REG_VALUE_CELL_ID;
|
||||
NewValueCell->NameSize = NameSize;
|
||||
NewValueCell->Signature = CM_KEY_VALUE_SIGNATURE;
|
||||
NewValueCell->NameLength = NameLength;
|
||||
NewValueCell->Flags = 0;
|
||||
if (NameSize > 0)
|
||||
if (NameLength > 0)
|
||||
{
|
||||
if (Packable)
|
||||
{
|
||||
for (i = 0; i < NameSize; i++)
|
||||
for (i = 0; i < NameLength; i++)
|
||||
{
|
||||
((PCHAR)NewValueCell->Name)[i] = (CHAR)ValueName[i];
|
||||
}
|
||||
NewValueCell->Flags |= REG_VALUE_NAME_PACKED;
|
||||
NewValueCell->Flags |= VALUE_COMP_NAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (NewValueCell->Name,
|
||||
ValueName,
|
||||
NameSize);
|
||||
NameLength);
|
||||
}
|
||||
}
|
||||
NewValueCell->DataType = 0;
|
||||
NewValueCell->DataSize = 0;
|
||||
NewValueCell->DataOffset = -1;
|
||||
NewValueCell->Type = 0;
|
||||
NewValueCell->DataLength = 0;
|
||||
NewValueCell->Data = -1;
|
||||
|
||||
*ValueCell = NewValueCell;
|
||||
|
||||
|
@ -212,13 +215,13 @@ CmiExportValue (PHHIVE Hive,
|
|||
HCELL_INDEX DataCellOffset;
|
||||
PCM_KEY_VALUE ValueCell;
|
||||
PVOID DataCell;
|
||||
ULONG DataSize;
|
||||
ULONG DataType;
|
||||
ULONG DataLength;
|
||||
ULONG Type;
|
||||
PCHAR Data;
|
||||
|
||||
DbgPrint((DPRINT_REGISTRY, "CmiExportValue('%S') called\n",
|
||||
(Value == NULL) ? "<default>" : (PCHAR)Value->Name));
|
||||
DbgPrint((DPRINT_REGISTRY, "DataSize %lu\n",
|
||||
DbgPrint((DPRINT_REGISTRY, "DataLength %lu\n",
|
||||
(Value == NULL) ? Key->DataSize : Value->DataSize));
|
||||
|
||||
/* Allocate value cell */
|
||||
|
@ -234,42 +237,42 @@ CmiExportValue (PHHIVE Hive,
|
|||
|
||||
if (Value == NULL)
|
||||
{
|
||||
DataType = Key->DataType;
|
||||
DataSize = Key->DataSize;
|
||||
Type = Key->DataType;
|
||||
DataLength = Key->DataSize;
|
||||
Data = Key->Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
DataType = Value->DataType;
|
||||
DataSize = Value->DataSize;
|
||||
Type = Value->DataType;
|
||||
DataLength = Value->DataSize;
|
||||
Data = Value->Data;
|
||||
}
|
||||
|
||||
if (DataSize <= sizeof(HCELL_INDEX))
|
||||
if (DataLength <= sizeof(HCELL_INDEX))
|
||||
{
|
||||
ValueCell->DataSize = DataSize | REG_DATA_IN_OFFSET;
|
||||
ValueCell->DataType = DataType;
|
||||
memcpy (&ValueCell->DataOffset,
|
||||
ValueCell->DataLength = DataLength | REG_DATA_IN_OFFSET;
|
||||
ValueCell->Type = Type;
|
||||
memcpy (&ValueCell->Data,
|
||||
&Data,
|
||||
DataSize);
|
||||
DataLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Allocate data cell */
|
||||
DataCellOffset = HvAllocateCell (Hive, DataSize, Stable, HCELL_NIL);
|
||||
DataCellOffset = HvAllocateCell (Hive, DataLength, Stable, HCELL_NIL);
|
||||
if (DataCellOffset == HCELL_NIL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ValueCell->DataOffset = DataCellOffset;
|
||||
ValueCell->DataSize = DataSize;
|
||||
ValueCell->DataType = DataType;
|
||||
ValueCell->Data = DataCellOffset;
|
||||
ValueCell->DataLength = DataLength;
|
||||
ValueCell->Type = Type;
|
||||
|
||||
DataCell = (PVOID)HvGetCell (Hive, DataCellOffset);
|
||||
memcpy (DataCell,
|
||||
Data,
|
||||
DataSize);
|
||||
DataLength);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -292,7 +295,7 @@ CmiExportSubKey (PHHIVE Hive,
|
|||
PVALUE Value;
|
||||
BOOLEAN Packable = TRUE;
|
||||
ULONG i;
|
||||
ULONG NameSize;
|
||||
ULONG NameLength;
|
||||
|
||||
DbgPrint((DPRINT_REGISTRY, "CmiExportSubKey('%S') called\n", Key->Name));
|
||||
|
||||
|
@ -300,19 +303,19 @@ CmiExportSubKey (PHHIVE Hive,
|
|||
if (Key->DataType == REG_LINK)
|
||||
return TRUE;
|
||||
|
||||
NameSize = (Key->NameSize - sizeof(WCHAR)) / sizeof(WCHAR);
|
||||
for (i = 0; i < NameSize; i++)
|
||||
NameLength = (Key->NameSize - sizeof(WCHAR)) / sizeof(WCHAR);
|
||||
for (i = 0; i < NameLength; i++)
|
||||
{
|
||||
if (Key->Name[i] & 0xFF00)
|
||||
{
|
||||
Packable = FALSE;
|
||||
NameSize *= sizeof(WCHAR);
|
||||
NameLength *= sizeof(WCHAR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate key cell */
|
||||
KeyCellSize = sizeof(CM_KEY_NODE) + NameSize;
|
||||
KeyCellSize = sizeof(CM_KEY_NODE) + NameLength;
|
||||
NKBOffset = HvAllocateCell (Hive, KeyCellSize, Stable, HCELL_NIL);
|
||||
if (NKBOffset == HCELL_NIL)
|
||||
{
|
||||
|
@ -322,7 +325,7 @@ CmiExportSubKey (PHHIVE Hive,
|
|||
|
||||
/* Initialize key cell */
|
||||
NewKeyCell = (PCM_KEY_NODE) HvGetCell (Hive, NKBOffset);
|
||||
NewKeyCell->Id = REG_KEY_CELL_ID;
|
||||
NewKeyCell->Signature = CM_KEY_NODE_SIGNATURE;
|
||||
NewKeyCell->Flags = 0;
|
||||
NewKeyCell->LastWriteTime.QuadPart = 0ULL;
|
||||
NewKeyCell->Parent = Parent;
|
||||
|
@ -330,24 +333,24 @@ CmiExportSubKey (PHHIVE Hive,
|
|||
NewKeyCell->SubKeyLists[Stable] = -1;
|
||||
NewKeyCell->ValueList.Count = 0;
|
||||
NewKeyCell->ValueList.List = -1;
|
||||
NewKeyCell->SecurityKeyOffset = -1;
|
||||
NewKeyCell->ClassNameOffset = -1;
|
||||
NewKeyCell->NameSize = NameSize;
|
||||
NewKeyCell->ClassSize = 0;
|
||||
NewKeyCell->Security = -1;
|
||||
NewKeyCell->Class = -1;
|
||||
NewKeyCell->NameLength = NameLength;
|
||||
NewKeyCell->ClassLength = 0;
|
||||
if (Packable)
|
||||
{
|
||||
for (i = 0; i < NameSize; i++)
|
||||
for (i = 0; i < NameLength; i++)
|
||||
{
|
||||
((PCHAR)NewKeyCell->Name)[i] = (CHAR)Key->Name[i];
|
||||
}
|
||||
NewKeyCell->Flags |= REG_KEY_NAME_PACKED;
|
||||
NewKeyCell->Flags |= KEY_COMP_NAME;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (NewKeyCell->Name,
|
||||
Key->Name,
|
||||
NameSize);
|
||||
NameLength);
|
||||
}
|
||||
|
||||
/* Add key cell to the parent key's hash table */
|
||||
|
@ -527,45 +530,45 @@ RegImportValue (PHHIVE Hive,
|
|||
PVOID DataCell;
|
||||
PWCHAR wName;
|
||||
LONG Error;
|
||||
ULONG DataSize;
|
||||
ULONG DataLength;
|
||||
ULONG i;
|
||||
|
||||
if (ValueCell->Id != REG_VALUE_CELL_ID)
|
||||
if (ValueCell->Signature != CM_KEY_VALUE_SIGNATURE)
|
||||
{
|
||||
DbgPrint((DPRINT_REGISTRY, "Invalid key cell!\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
|
||||
if (ValueCell->Flags & VALUE_COMP_NAME)
|
||||
{
|
||||
wName = MmAllocateMemory ((ValueCell->NameSize + 1)*sizeof(WCHAR));
|
||||
for (i = 0; i < ValueCell->NameSize; i++)
|
||||
wName = MmAllocateMemory ((ValueCell->NameLength + 1)*sizeof(WCHAR));
|
||||
for (i = 0; i < ValueCell->NameLength; i++)
|
||||
{
|
||||
wName[i] = ((PCHAR)ValueCell->Name)[i];
|
||||
}
|
||||
wName[ValueCell->NameSize] = 0;
|
||||
wName[ValueCell->NameLength] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
wName = MmAllocateMemory (ValueCell->NameSize + sizeof(WCHAR));
|
||||
wName = MmAllocateMemory (ValueCell->NameLength + sizeof(WCHAR));
|
||||
memcpy (wName,
|
||||
ValueCell->Name,
|
||||
ValueCell->NameSize);
|
||||
wName[ValueCell->NameSize / sizeof(WCHAR)] = 0;
|
||||
ValueCell->NameLength);
|
||||
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, "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,
|
||||
wName,
|
||||
ValueCell->DataType,
|
||||
(PCHAR)&ValueCell->DataOffset,
|
||||
DataSize);
|
||||
ValueCell->Type,
|
||||
(PCHAR)&ValueCell->Data,
|
||||
DataLength);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DbgPrint((DPRINT_REGISTRY, "RegSetValue() failed!\n"));
|
||||
|
@ -575,14 +578,14 @@ RegImportValue (PHHIVE Hive,
|
|||
}
|
||||
else
|
||||
{
|
||||
DataCell = (PVOID)HvGetCell (Hive, ValueCell->DataOffset);
|
||||
DataCell = (PVOID)HvGetCell (Hive, ValueCell->Data);
|
||||
DbgPrint((DPRINT_REGISTRY, "DataCell: %x\n", DataCell));
|
||||
|
||||
Error = RegSetValue (Key,
|
||||
wName,
|
||||
ValueCell->DataType,
|
||||
ValueCell->Type,
|
||||
DataCell,
|
||||
DataSize);
|
||||
DataLength);
|
||||
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
|
@ -603,7 +606,7 @@ RegImportSubKey(PHHIVE Hive,
|
|||
PCM_KEY_NODE KeyCell,
|
||||
FRLDRHKEY ParentKey)
|
||||
{
|
||||
PHASH_TABLE_CELL HashCell;
|
||||
PCM_KEY_FAST_INDEX HashCell;
|
||||
PCM_KEY_NODE SubKeyCell;
|
||||
PVALUE_LIST_CELL ValueListCell;
|
||||
PCM_KEY_VALUE ValueCell = NULL;
|
||||
|
@ -614,29 +617,29 @@ RegImportSubKey(PHHIVE Hive,
|
|||
|
||||
|
||||
DbgPrint((DPRINT_REGISTRY, "KeyCell: %x\n", KeyCell));
|
||||
DbgPrint((DPRINT_REGISTRY, "KeyCell->Id: %x\n", KeyCell->Id));
|
||||
if (KeyCell->Id != REG_KEY_CELL_ID)
|
||||
DbgPrint((DPRINT_REGISTRY, "KeyCell->Signature: %x\n", KeyCell->Signature));
|
||||
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;
|
||||
}
|
||||
|
||||
if (KeyCell->Flags & REG_KEY_NAME_PACKED)
|
||||
if (KeyCell->Flags & KEY_COMP_NAME)
|
||||
{
|
||||
wName = MmAllocateMemory ((KeyCell->NameSize + 1) * sizeof(WCHAR));
|
||||
for (i = 0; i < KeyCell->NameSize; i++)
|
||||
wName = MmAllocateMemory ((KeyCell->NameLength + 1) * sizeof(WCHAR));
|
||||
for (i = 0; i < KeyCell->NameLength; i++)
|
||||
{
|
||||
wName[i] = ((PCHAR)KeyCell->Name)[i];
|
||||
}
|
||||
wName[KeyCell->NameSize] = 0;
|
||||
wName[KeyCell->NameLength] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
wName = MmAllocateMemory (KeyCell->NameSize + sizeof(WCHAR));
|
||||
wName = MmAllocateMemory (KeyCell->NameLength + sizeof(WCHAR));
|
||||
memcpy (wName,
|
||||
KeyCell->Name,
|
||||
KeyCell->NameSize);
|
||||
wName[KeyCell->NameSize/sizeof(WCHAR)] = 0;
|
||||
KeyCell->NameLength);
|
||||
wName[KeyCell->NameLength/sizeof(WCHAR)] = 0;
|
||||
}
|
||||
|
||||
DbgPrint((DPRINT_REGISTRY, "KeyName: '%S'\n", wName));
|
||||
|
@ -676,15 +679,15 @@ RegImportSubKey(PHHIVE Hive,
|
|||
/* Enumerate and add subkeys */
|
||||
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, "SubKeyCounts: %x\n", KeyCell->SubKeyCounts));
|
||||
|
||||
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));
|
||||
|
||||
|
@ -702,7 +705,7 @@ RegImportBinaryHive(PCHAR ChunkBase,
|
|||
ULONG ChunkSize)
|
||||
{
|
||||
PCM_KEY_NODE KeyCell;
|
||||
PHASH_TABLE_CELL HashCell;
|
||||
PCM_KEY_FAST_INDEX HashCell;
|
||||
PCM_KEY_NODE SubKeyCell;
|
||||
FRLDRHKEY SystemKey;
|
||||
ULONG i;
|
||||
|
@ -729,17 +732,17 @@ RegImportBinaryHive(PCHAR ChunkBase,
|
|||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DbgPrint((DPRINT_REGISTRY, "Invalid hive id!\n"));
|
||||
DbgPrint((DPRINT_REGISTRY, "Invalid hive Signature!\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Hive = &CmHive->Hive;
|
||||
KeyCell = (PCM_KEY_NODE)HvGetCell (Hive, Hive->BaseBlock->RootCell);
|
||||
DbgPrint((DPRINT_REGISTRY, "KeyCell: %x\n", KeyCell));
|
||||
DbgPrint((DPRINT_REGISTRY, "KeyCell->Id: %x\n", KeyCell->Id));
|
||||
if (KeyCell->Id != REG_KEY_CELL_ID)
|
||||
DbgPrint((DPRINT_REGISTRY, "KeyCell->Signature: %x\n", KeyCell->Signature));
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -759,15 +762,15 @@ RegImportBinaryHive(PCHAR ChunkBase,
|
|||
/* Enumerate and add subkeys */
|
||||
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, "SubKeyCounts: %x\n", KeyCell->SubKeyCounts[Stable]));
|
||||
|
||||
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));
|
||||
|
||||
|
|
|
@ -51,6 +51,8 @@
|
|||
* and this line has to be removed */
|
||||
#define PAGE_SIZE 4096
|
||||
|
||||
#define ANYSIZE_ARRAY 1
|
||||
|
||||
typedef void VOID, *PVOID, *HANDLE;
|
||||
typedef HANDLE HKEY, *PHKEY;
|
||||
typedef unsigned char UCHAR, *PUCHAR, BYTE, *LPBYTE;
|
||||
|
|
|
@ -13,12 +13,39 @@
|
|||
#define REG_EXTEND_HASH_TABLE_SIZE 4
|
||||
#define REG_VALUE_LIST_CELL_MULTIPLE 4
|
||||
|
||||
#define REG_KEY_CELL_ID 0x6b6e
|
||||
#define REG_HASH_TABLE_CELL_ID 0x666c
|
||||
#define REG_VALUE_CELL_ID 0x6b76
|
||||
#define REG_SECURITY_CELL_ID 0x6b73
|
||||
//
|
||||
// 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
|
||||
|
||||
#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
|
||||
#include <host/pshpack1.h>
|
||||
|
@ -26,6 +53,9 @@
|
|||
#include <pshpack1.h>
|
||||
#endif
|
||||
|
||||
//
|
||||
// For memory-mapped Hives
|
||||
//
|
||||
typedef struct _CM_VIEW_OF_FILE
|
||||
{
|
||||
LIST_ENTRY LRUViewList;
|
||||
|
@ -37,111 +67,69 @@ typedef struct _CM_VIEW_OF_FILE
|
|||
ULONG UseCount;
|
||||
} CM_VIEW_OF_FILE, *PCM_VIEW_OF_FILE;
|
||||
|
||||
//
|
||||
// Children of Key Notes
|
||||
//
|
||||
typedef struct _CHILD_LIST
|
||||
{
|
||||
ULONG Count;
|
||||
HCELL_INDEX List;
|
||||
} CHILD_LIST, *PCHILD_LIST;
|
||||
|
||||
//
|
||||
// Node Key
|
||||
//
|
||||
typedef struct _CM_KEY_NODE
|
||||
{
|
||||
/* Key cell identifier "kn" (0x6b6e) */
|
||||
USHORT Id;
|
||||
|
||||
/* Flags */
|
||||
USHORT Flags;
|
||||
|
||||
/* Time of last flush */
|
||||
LARGE_INTEGER LastWriteTime;
|
||||
|
||||
ULONG Spare;
|
||||
|
||||
/* BlockAddress offset of parent key cell */
|
||||
HCELL_INDEX Parent;
|
||||
|
||||
/* Count of sub keys for the key in this key cell (stable & volatile) */
|
||||
ULONG SubKeyCounts[HTYPE_COUNT];
|
||||
|
||||
/* BlockAddress offset of has table for FIXME: subkeys/values? (stable & volatile) */
|
||||
HCELL_INDEX SubKeyLists[HTYPE_COUNT];
|
||||
|
||||
CHILD_LIST ValueList;
|
||||
|
||||
/* BlockAddress offset of security cell */
|
||||
HCELL_INDEX SecurityKeyOffset;
|
||||
|
||||
/* BlockAddress offset of registry key class */
|
||||
HCELL_INDEX ClassNameOffset;
|
||||
|
||||
ULONG MaxNameLen;
|
||||
ULONG MaxClassLen;
|
||||
ULONG MaxValueNameLen;
|
||||
ULONG MaxValueDataLen;
|
||||
ULONG WorkVar;
|
||||
|
||||
/* Size in bytes of key name */
|
||||
USHORT NameSize;
|
||||
|
||||
/* Size of class name in bytes */
|
||||
USHORT ClassSize;
|
||||
|
||||
/* Name of key (not zero terminated) */
|
||||
UCHAR Name[0];
|
||||
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;
|
||||
|
||||
/* CM_KEY_NODE.Flags constants */
|
||||
#define REG_KEY_VOLATILE_CELL 0x01
|
||||
#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;
|
||||
|
||||
//
|
||||
// Value List
|
||||
//
|
||||
typedef struct _VALUE_LIST_CELL
|
||||
{
|
||||
HCELL_INDEX ValueOffset[0];
|
||||
HCELL_INDEX ValueOffset[0];
|
||||
} VALUE_LIST_CELL, *PVALUE_LIST_CELL;
|
||||
|
||||
//
|
||||
// Value Key
|
||||
//
|
||||
typedef struct _CM_KEY_VALUE
|
||||
{
|
||||
USHORT Id; // "kv"
|
||||
USHORT NameSize; // length of Name
|
||||
ULONG DataSize; // length of datas in the cell pointed by DataOffset
|
||||
HCELL_INDEX DataOffset;// datas are here if high bit of DataSize is set
|
||||
ULONG DataType;
|
||||
USHORT Flags;
|
||||
USHORT Unused1;
|
||||
UCHAR Name[0]; /* warning : not zero terminated */
|
||||
USHORT Signature;
|
||||
USHORT NameLength;
|
||||
ULONG DataLength;
|
||||
HCELL_INDEX Data;
|
||||
ULONG Type;
|
||||
USHORT Flags;
|
||||
USHORT Unused1;
|
||||
WCHAR Name[0];
|
||||
} CM_KEY_VALUE, *PCM_KEY_VALUE;
|
||||
|
||||
/* CM_KEY_VALUE.Flags constants */
|
||||
#define REG_VALUE_NAME_PACKED 0x0001
|
||||
|
||||
/* CM_KEY_VALUE.DataSize mask constants */
|
||||
#define REG_DATA_SIZE_MASK 0x7FFFFFFF
|
||||
#define REG_DATA_IN_OFFSET 0x80000000
|
||||
|
||||
//
|
||||
// Security Key
|
||||
//
|
||||
typedef struct _CM_KEY_SECURITY
|
||||
{
|
||||
USHORT Signature; // "sk"
|
||||
USHORT Signature;
|
||||
USHORT Reserved;
|
||||
HCELL_INDEX Flink;
|
||||
HCELL_INDEX Blink;
|
||||
|
@ -157,6 +145,53 @@ typedef struct _CM_KEY_SECURITY
|
|||
#include <poppack.h>
|
||||
#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 */
|
||||
|
|
|
@ -16,34 +16,47 @@ CmCreateRootNode(
|
|||
HCELL_INDEX RootCellIndex;
|
||||
SIZE_T NameSize;
|
||||
|
||||
/* Allocate the cell */
|
||||
NameSize = wcslen(Name) * sizeof(WCHAR);
|
||||
RootCellIndex = HvAllocateCell(Hive,
|
||||
sizeof(CM_KEY_NODE) + NameSize,
|
||||
FIELD_OFFSET(CM_KEY_NODE, Name) + NameSize,
|
||||
Stable,
|
||||
HCELL_NIL);
|
||||
if (RootCellIndex == HCELL_NIL)
|
||||
return FALSE;
|
||||
if (RootCellIndex == HCELL_NIL) return FALSE;
|
||||
|
||||
/* Seutp the base block */
|
||||
Hive->BaseBlock->RootCell = RootCellIndex;
|
||||
Hive->BaseBlock->CheckSum = HvpHiveHeaderChecksum(Hive->BaseBlock);
|
||||
|
||||
/* Get the key cell */
|
||||
KeyCell = (PCM_KEY_NODE)HvGetCell(Hive, RootCellIndex);
|
||||
KeyCell->Id = REG_KEY_CELL_ID;
|
||||
KeyCell->Flags = REG_KEY_ROOT_CELL;
|
||||
if (!KeyCell) return FALSE;
|
||||
|
||||
/* Setup the cell */
|
||||
KeyCell->Signature = (USHORT)CM_KEY_NODE_SIGNATURE;
|
||||
KeyCell->Flags = KEY_HIVE_ENTRY | KEY_NO_DELETE;
|
||||
KeyCell->LastWriteTime.QuadPart = 0;
|
||||
KeyCell->Parent = HCELL_NIL;
|
||||
KeyCell->SubKeyCounts[0] = 0;
|
||||
KeyCell->SubKeyCounts[1] = 0;
|
||||
KeyCell->SubKeyLists[0] = HCELL_NIL;
|
||||
KeyCell->SubKeyLists[1] = HCELL_NIL;
|
||||
KeyCell->SubKeyCounts[Stable] = 0;
|
||||
KeyCell->SubKeyCounts[Volatile] = 0;
|
||||
KeyCell->SubKeyLists[Stable] = HCELL_NIL;
|
||||
KeyCell->SubKeyLists[Volatile] = HCELL_NIL;
|
||||
KeyCell->ValueList.Count = 0;
|
||||
KeyCell->ValueList.List = HCELL_NIL;
|
||||
KeyCell->SecurityKeyOffset = HCELL_NIL;
|
||||
KeyCell->ClassNameOffset = HCELL_NIL;
|
||||
KeyCell->NameSize = (USHORT)NameSize;
|
||||
KeyCell->ClassSize = 0;
|
||||
KeyCell->Security = HCELL_NIL;
|
||||
KeyCell->Class = HCELL_NIL;
|
||||
KeyCell->ClassLength = 0;
|
||||
KeyCell->MaxNameLen = 0;
|
||||
KeyCell->MaxClassLen = 0;
|
||||
KeyCell->MaxValueNameLen = 0;
|
||||
KeyCell->MaxValueDataLen = 0;
|
||||
|
||||
/* Write the name */
|
||||
KeyCell->NameLength = (USHORT)NameSize;
|
||||
memcpy(KeyCell->Name, Name, NameSize);
|
||||
|
||||
/* Return success */
|
||||
HvReleaseCell(Hive, RootCellIndex);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -53,10 +66,10 @@ CmpPrepareKey(
|
|||
PCM_KEY_NODE KeyCell)
|
||||
{
|
||||
PCM_KEY_NODE SubKeyCell;
|
||||
PHASH_TABLE_CELL HashCell;
|
||||
PCM_KEY_FAST_INDEX HashCell;
|
||||
ULONG i;
|
||||
|
||||
ASSERT(KeyCell->Id == REG_KEY_CELL_ID);
|
||||
ASSERT(KeyCell->Signature == CM_KEY_NODE_SIGNATURE);
|
||||
|
||||
KeyCell->SubKeyLists[Volatile] = HCELL_NIL;
|
||||
KeyCell->SubKeyCounts[Volatile] = 0;
|
||||
|
@ -68,7 +81,7 @@ CmpPrepareKey(
|
|||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,10 +62,6 @@ RtlClearAllBits(
|
|||
|
||||
#endif
|
||||
|
||||
#include <wchar.h>
|
||||
#include "hivedata.h"
|
||||
#include "cmdata.h"
|
||||
|
||||
#ifndef ROUND_UP
|
||||
#define ROUND_UP(a,b) ((((a)+(b)-1)/(b))*(b))
|
||||
#define ROUND_DOWN(a,b) (((a)/(b))*(b))
|
||||
|
@ -75,112 +71,9 @@ RtlClearAllBits(
|
|||
|
||||
#define CMAPI NTAPI
|
||||
|
||||
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;
|
||||
#include <wchar.h>
|
||||
#include "hivedata.h"
|
||||
#include "cmdata.h"
|
||||
|
||||
#ifndef _CM_
|
||||
typedef struct _EREGISTRY_HIVE
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
#define HIVE_VOLATILE 1
|
||||
#define HIVE_NOLAZYFLUSH 2
|
||||
#define HIVE_HAS_BEEN_REPLACED 4
|
||||
#define HIVE_HAS_BEEN_FREED 8
|
||||
#define HIVE_UNKNOWN 0x10
|
||||
#define HIVE_IS_UNLOADING 0x20
|
||||
|
||||
//
|
||||
// Hive types
|
||||
|
@ -190,6 +193,114 @@ typedef struct _HCELL
|
|||
#include <poppack.h>
|
||||
#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 IsUsedCell(Cell)(Cell->Size < 0)
|
||||
|
||||
|
|
|
@ -192,9 +192,9 @@ CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1,
|
|||
IN PVOID Argument2);
|
||||
|
||||
#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_ROOT_KEY_CELL(x) ASSERT(x->Id == REG_KEY_CELL_ID)
|
||||
#define VERIFY_VALUE_CELL(x) ASSERT(x->Id == REG_VALUE_CELL_ID)
|
||||
#define VERIFY_KEY_CELL(x) ASSERT(x->Signature == CM_KEY_NODE_SIGNATURE)
|
||||
#define VERIFY_ROOT_KEY_CELL(x) ASSERT(x->Signature == CM_KEY_NODE_SIGNATURE)
|
||||
#define VERIFY_VALUE_CELL(x) ASSERT(x->Signature == CM_KEY_VALUE_SIGNATURE)
|
||||
#define VERIFY_VALUE_LIST_CELL(x)
|
||||
#define VERIFY_KEY_OBJECT(x)
|
||||
#define VERIFY_REGISTRY_HIVE(x)
|
||||
|
@ -317,21 +317,6 @@ NTSTATUS
|
|||
NTAPI
|
||||
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
|
||||
CmiConnectHive(POBJECT_ATTRIBUTES KeyObjectAttributes,
|
||||
PEREGISTRY_HIVE RegistryHive);
|
||||
|
|
|
@ -333,7 +333,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
|||
RtlCreateUnicodeString(&KeyObject->Name, Start);
|
||||
|
||||
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.Count = KeyObject->KeyCell->ValueList.Count;
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
/* LOCAL MACROS *************************************************************/
|
||||
|
||||
#define ABS_VALUE(V) (((V) < 0) ? -(V) : (V))
|
||||
#define REG_DATA_SIZE_MASK 0x7FFFFFFF
|
||||
#define REG_DATA_IN_OFFSET 0x80000000
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
|
@ -105,10 +107,10 @@ ULONG
|
|||
CmiGetMaxNameLength(PHHIVE Hive,
|
||||
PCM_KEY_NODE KeyCell)
|
||||
{
|
||||
PHASH_TABLE_CELL HashBlock;
|
||||
PCM_KEY_FAST_INDEX HashBlock;
|
||||
PCM_KEY_NODE CurSubKeyCell;
|
||||
ULONG MaxName;
|
||||
ULONG NameSize;
|
||||
ULONG NameLength;
|
||||
ULONG i;
|
||||
ULONG Storage;
|
||||
|
||||
|
@ -117,18 +119,18 @@ CmiGetMaxNameLength(PHHIVE Hive,
|
|||
{
|
||||
if (KeyCell->SubKeyLists[Storage] != HCELL_NIL)
|
||||
{
|
||||
HashBlock = (PHASH_TABLE_CELL)HvGetCell (Hive, KeyCell->SubKeyLists[Storage]);
|
||||
ASSERT(HashBlock->Id == REG_HASH_TABLE_CELL_ID);
|
||||
HashBlock = (PCM_KEY_FAST_INDEX)HvGetCell (Hive, KeyCell->SubKeyLists[Storage]);
|
||||
ASSERT(HashBlock->Signature == CM_KEY_FAST_LEAF);
|
||||
|
||||
for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++)
|
||||
{
|
||||
CurSubKeyCell = (PCM_KEY_NODE)HvGetCell (Hive,
|
||||
HashBlock->Table[i].KeyOffset);
|
||||
NameSize = CurSubKeyCell->NameSize;
|
||||
if (CurSubKeyCell->Flags & REG_KEY_NAME_PACKED)
|
||||
NameSize *= sizeof(WCHAR);
|
||||
if (NameSize > MaxName)
|
||||
MaxName = NameSize;
|
||||
HashBlock->List[i].Cell);
|
||||
NameLength = CurSubKeyCell->NameLength;
|
||||
if (CurSubKeyCell->Flags & KEY_COMP_NAME)
|
||||
NameLength *= sizeof(WCHAR);
|
||||
if (NameLength > MaxName)
|
||||
MaxName = NameLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -142,7 +144,7 @@ ULONG
|
|||
CmiGetMaxClassLength(PHHIVE Hive,
|
||||
PCM_KEY_NODE KeyCell)
|
||||
{
|
||||
PHASH_TABLE_CELL HashBlock;
|
||||
PCM_KEY_FAST_INDEX HashBlock;
|
||||
PCM_KEY_NODE CurSubKeyCell;
|
||||
ULONG MaxClass;
|
||||
ULONG i;
|
||||
|
@ -153,18 +155,18 @@ CmiGetMaxClassLength(PHHIVE Hive,
|
|||
{
|
||||
if (KeyCell->SubKeyLists[Storage] != HCELL_NIL)
|
||||
{
|
||||
HashBlock = (PHASH_TABLE_CELL)HvGetCell (Hive,
|
||||
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++)
|
||||
{
|
||||
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)
|
||||
{
|
||||
Size = CurValueCell->NameSize;
|
||||
if (CurValueCell->Flags & REG_VALUE_NAME_PACKED)
|
||||
Size = CurValueCell->NameLength;
|
||||
if (CurValueCell->Flags & VALUE_COMP_NAME)
|
||||
{
|
||||
Size *= sizeof(WCHAR);
|
||||
}
|
||||
|
@ -243,9 +245,9 @@ CmiGetMaxValueDataLength(PHHIVE Hive,
|
|||
{
|
||||
CurValueCell = (PCM_KEY_VALUE)HvGetCell (Hive,
|
||||
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;
|
||||
}
|
||||
|
||||
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 */
|
||||
|
|
|
@ -432,7 +432,7 @@ CmpParseKey(IN PVOID ParsedObject,
|
|||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
if ((SubKeyCell->Flags & REG_KEY_LINK_CELL) &&
|
||||
if ((SubKeyCell->Flags & KEY_SYM_LINK) &&
|
||||
!((Attributes & OBJ_OPENLINK) && (EndPtr == NULL)))
|
||||
{
|
||||
RtlInitUnicodeString(&LinkPath, NULL);
|
||||
|
@ -526,7 +526,7 @@ CmpParseKey(IN PVOID ParsedObject,
|
|||
}
|
||||
else
|
||||
{
|
||||
if ((FoundObject->KeyCell->Flags & REG_KEY_LINK_CELL) &&
|
||||
if ((FoundObject->KeyCell->Flags & KEY_SYM_LINK) &&
|
||||
!((Attributes & OBJ_OPENLINK) && (EndPtr == NULL)))
|
||||
{
|
||||
DPRINT("Found link\n");
|
||||
|
@ -832,7 +832,7 @@ CmiGetLinkTarget(PEREGISTRY_HIVE RegistryHive,
|
|||
return(Status);
|
||||
}
|
||||
|
||||
if (ValueCell->DataType != REG_LINK)
|
||||
if (ValueCell->Type != REG_LINK)
|
||||
{
|
||||
DPRINT1("Type != REG_LINK\n!");
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
|
@ -841,17 +841,17 @@ CmiGetLinkTarget(PEREGISTRY_HIVE RegistryHive,
|
|||
if (TargetPath->Buffer == NULL && TargetPath->MaximumLength == 0)
|
||||
{
|
||||
TargetPath->Length = 0;
|
||||
TargetPath->MaximumLength = (USHORT)ValueCell->DataSize + sizeof(WCHAR);
|
||||
TargetPath->MaximumLength = (USHORT)ValueCell->DataLength + sizeof(WCHAR);
|
||||
TargetPath->Buffer = ExAllocatePool(NonPagedPool,
|
||||
TargetPath->MaximumLength);
|
||||
}
|
||||
|
||||
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,
|
||||
DataCell,
|
||||
TargetPath->Length);
|
||||
|
@ -860,7 +860,7 @@ CmiGetLinkTarget(PEREGISTRY_HIVE RegistryHive,
|
|||
else
|
||||
{
|
||||
RtlCopyMemory(TargetPath->Buffer,
|
||||
&ValueCell->DataOffset,
|
||||
&ValueCell->Data,
|
||||
TargetPath->Length);
|
||||
TargetPath->Buffer[TargetPath->Length / sizeof(WCHAR)] = 0;
|
||||
}
|
||||
|
|
|
@ -43,14 +43,6 @@
|
|||
#define ASSERT_VALUE_BIG(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
|
||||
//
|
||||
|
@ -64,29 +56,11 @@
|
|||
#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_BIG 0x3FD8
|
||||
#define CM_KEY_VALUE_SPECIAL_SIZE 0x80000000
|
||||
#define VALUE_COMP_NAME 0x0001
|
||||
|
||||
//
|
||||
// Number of various lists and hashes
|
||||
|
@ -419,127 +393,6 @@ typedef struct _CMHIVE
|
|||
PKTHREAD CreatorOwner;
|
||||
} 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
|
||||
//
|
||||
|
|
|
@ -607,7 +607,7 @@ CmpCreateRootNode(IN PHHIVE Hive,
|
|||
if (!KeyCell) return FALSE;
|
||||
|
||||
/* 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;
|
||||
KeQuerySystemTime(&SystemTime);
|
||||
KeyCell->LastWriteTime = SystemTime;
|
||||
|
|
|
@ -150,39 +150,39 @@ CmiInitializeTempHive(
|
|||
static NTSTATUS
|
||||
CmiAddKeyToHashTable(
|
||||
IN PEREGISTRY_HIVE RegistryHive,
|
||||
IN OUT PHASH_TABLE_CELL HashCell,
|
||||
IN OUT PCM_KEY_FAST_INDEX HashCell,
|
||||
IN PCM_KEY_NODE KeyCell,
|
||||
IN HSTORAGE_TYPE StorageType,
|
||||
IN PCM_KEY_NODE NewKeyCell,
|
||||
IN HCELL_INDEX NKBOffset)
|
||||
{
|
||||
ULONG i = KeyCell->SubKeyCounts[StorageType];
|
||||
ULONG HashValue;
|
||||
ULONG HashKey;
|
||||
|
||||
if (NewKeyCell->Flags & REG_KEY_NAME_PACKED)
|
||||
if (NewKeyCell->Flags & KEY_COMP_NAME)
|
||||
{
|
||||
RtlCopyMemory(
|
||||
&HashValue,
|
||||
&HashKey,
|
||||
NewKeyCell->Name,
|
||||
min(NewKeyCell->NameSize, sizeof(ULONG)));
|
||||
min(NewKeyCell->NameLength, sizeof(ULONG)));
|
||||
}
|
||||
|
||||
for (i = 0; i < KeyCell->SubKeyCounts[StorageType]; i++)
|
||||
{
|
||||
if (HashCell->Table[i].HashValue > HashValue)
|
||||
if (HashCell->List[i].HashKey > HashKey)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < KeyCell->SubKeyCounts[StorageType])
|
||||
{
|
||||
RtlMoveMemory(HashCell->Table + i + 1,
|
||||
HashCell->Table + i,
|
||||
(HashCell->HashTableSize - 1 - i) *
|
||||
sizeof(HashCell->Table[0]));
|
||||
RtlMoveMemory(HashCell->List + i + 1,
|
||||
HashCell->List + i,
|
||||
(HashCell->Count - 1 - i) *
|
||||
sizeof(HashCell->List[0]));
|
||||
}
|
||||
|
||||
HashCell->Table[i].KeyOffset = NKBOffset;
|
||||
HashCell->Table[i].HashValue = HashValue;
|
||||
HashCell->List[i].Cell = NKBOffset;
|
||||
HashCell->List[i].HashKey = HashKey;
|
||||
HvMarkCellDirty(&RegistryHive->Hive, KeyCell->SubKeyLists[StorageType], FALSE);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -190,19 +190,19 @@ CmiAddKeyToHashTable(
|
|||
static NTSTATUS
|
||||
CmiAllocateHashTableCell (
|
||||
IN PEREGISTRY_HIVE RegistryHive,
|
||||
OUT PHASH_TABLE_CELL *HashBlock,
|
||||
OUT PCM_KEY_FAST_INDEX *HashBlock,
|
||||
OUT HCELL_INDEX *HBOffset,
|
||||
IN USHORT SubKeyCount,
|
||||
IN HSTORAGE_TYPE Storage)
|
||||
{
|
||||
PHASH_TABLE_CELL NewHashBlock;
|
||||
PCM_KEY_FAST_INDEX NewHashBlock;
|
||||
ULONG NewHashSize;
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
*HashBlock = NULL;
|
||||
NewHashSize = sizeof(HASH_TABLE_CELL) +
|
||||
(SubKeyCount * sizeof(HASH_RECORD));
|
||||
NewHashSize = sizeof(CM_KEY_FAST_INDEX) +
|
||||
(SubKeyCount * sizeof(CM_INDEX));
|
||||
*HBOffset = HvAllocateCell(&RegistryHive->Hive, NewHashSize, Storage, HCELL_NIL);
|
||||
|
||||
if (*HBOffset == HCELL_NIL)
|
||||
|
@ -212,9 +212,9 @@ CmiAllocateHashTableCell (
|
|||
else
|
||||
{
|
||||
ASSERT(SubKeyCount <= USHORT_MAX);
|
||||
NewHashBlock = (PHASH_TABLE_CELL)HvGetCell (&RegistryHive->Hive, *HBOffset);
|
||||
NewHashBlock->Id = REG_HASH_TABLE_CELL_ID;
|
||||
NewHashBlock->HashTableSize = SubKeyCount;
|
||||
NewHashBlock = (PCM_KEY_FAST_INDEX)HvGetCell (&RegistryHive->Hive, *HBOffset);
|
||||
NewHashBlock->Signature = CM_KEY_FAST_LEAF;
|
||||
NewHashBlock->Count = SubKeyCount;
|
||||
*HashBlock = NewHashBlock;
|
||||
}
|
||||
|
||||
|
@ -231,12 +231,12 @@ CmiAddSubKey(
|
|||
OUT PCM_KEY_NODE *pSubKeyCell,
|
||||
OUT HCELL_INDEX *pBlockOffset)
|
||||
{
|
||||
PHASH_TABLE_CELL HashBlock;
|
||||
PCM_KEY_FAST_INDEX HashBlock;
|
||||
HCELL_INDEX NKBOffset;
|
||||
PCM_KEY_NODE NewKeyCell;
|
||||
ULONG NewBlockSize;
|
||||
NTSTATUS Status;
|
||||
USHORT NameSize;
|
||||
USHORT NameLength;
|
||||
PWSTR NamePtr;
|
||||
BOOLEAN Packable;
|
||||
HSTORAGE_TYPE Storage;
|
||||
|
@ -250,17 +250,17 @@ CmiAddSubKey(
|
|||
if (SubKeyName->Buffer[0] == L'\\')
|
||||
{
|
||||
NamePtr = &SubKeyName->Buffer[1];
|
||||
NameSize = SubKeyName->Length - sizeof(WCHAR);
|
||||
NameLength = SubKeyName->Length - sizeof(WCHAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
NamePtr = SubKeyName->Buffer;
|
||||
NameSize = SubKeyName->Length;
|
||||
NameLength = SubKeyName->Length;
|
||||
}
|
||||
|
||||
/* Check whether key name can be packed */
|
||||
Packable = TRUE;
|
||||
for (i = 0; i < NameSize / sizeof(WCHAR); i++)
|
||||
for (i = 0; i < NameLength / sizeof(WCHAR); i++)
|
||||
{
|
||||
if (NamePtr[i] & 0xFF00)
|
||||
{
|
||||
|
@ -272,13 +272,13 @@ CmiAddSubKey(
|
|||
/* Adjust name size */
|
||||
if (Packable)
|
||||
{
|
||||
NameSize = NameSize / sizeof(WCHAR);
|
||||
NameLength = NameLength / sizeof(WCHAR);
|
||||
}
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
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);
|
||||
if (NKBOffset == HCELL_NIL)
|
||||
{
|
||||
|
@ -287,10 +287,10 @@ CmiAddSubKey(
|
|||
else
|
||||
{
|
||||
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)
|
||||
{
|
||||
NewKeyCell->Flags = REG_KEY_VOLATILE_CELL;
|
||||
NewKeyCell->Flags = KEY_IS_VOLATILE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -304,17 +304,17 @@ CmiAddSubKey(
|
|||
NewKeyCell->SubKeyLists[Volatile] = HCELL_NIL;
|
||||
NewKeyCell->ValueList.Count = 0;
|
||||
NewKeyCell->ValueList.List = HCELL_NIL;
|
||||
NewKeyCell->SecurityKeyOffset = HCELL_NIL;
|
||||
NewKeyCell->ClassNameOffset = HCELL_NIL;
|
||||
NewKeyCell->Security = HCELL_NIL;
|
||||
NewKeyCell->Class = HCELL_NIL;
|
||||
|
||||
/* Pack the key name */
|
||||
NewKeyCell->NameSize = NameSize;
|
||||
NewKeyCell->NameLength = NameLength;
|
||||
if (Packable)
|
||||
{
|
||||
NewKeyCell->Flags |= REG_KEY_NAME_PACKED;
|
||||
for (i = 0; i < NameSize; i++)
|
||||
NewKeyCell->Flags |= KEY_COMP_NAME;
|
||||
for (i = 0; i < NameLength; i++)
|
||||
{
|
||||
NewKeyCell->Name[i] = (CHAR)(NamePtr[i] & 0x00FF);
|
||||
((PCHAR)NewKeyCell->Name)[i] = (CHAR)(NamePtr[i] & 0x00FF);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -322,7 +322,7 @@ CmiAddSubKey(
|
|||
RtlCopyMemory(
|
||||
NewKeyCell->Name,
|
||||
NamePtr,
|
||||
NameSize);
|
||||
NameLength);
|
||||
}
|
||||
|
||||
VERIFY_KEY_CELL(NewKeyCell);
|
||||
|
@ -348,14 +348,14 @@ CmiAddSubKey(
|
|||
}
|
||||
else
|
||||
{
|
||||
HashBlock = (PHASH_TABLE_CELL)HvGetCell (
|
||||
HashBlock = (PCM_KEY_FAST_INDEX)HvGetCell (
|
||||
&RegistryHive->Hive,
|
||||
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;
|
||||
|
||||
/* Reallocate the hash table cell */
|
||||
|
@ -363,7 +363,7 @@ CmiAddSubKey(
|
|||
RegistryHive,
|
||||
&NewHashBlock,
|
||||
&HTOffset,
|
||||
HashBlock->HashTableSize +
|
||||
HashBlock->Count +
|
||||
REG_EXTEND_HASH_TABLE_SIZE,
|
||||
Storage);
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -372,12 +372,12 @@ CmiAddSubKey(
|
|||
}
|
||||
|
||||
RtlZeroMemory(
|
||||
&NewHashBlock->Table[0],
|
||||
sizeof(NewHashBlock->Table[0]) * NewHashBlock->HashTableSize);
|
||||
&NewHashBlock->List[0],
|
||||
sizeof(NewHashBlock->List[0]) * NewHashBlock->Count);
|
||||
RtlCopyMemory(
|
||||
&NewHashBlock->Table[0],
|
||||
&HashBlock->Table[0],
|
||||
sizeof(NewHashBlock->Table[0]) * HashBlock->HashTableSize);
|
||||
&NewHashBlock->List[0],
|
||||
&HashBlock->List[0],
|
||||
sizeof(NewHashBlock->List[0]) * HashBlock->Count);
|
||||
HvFreeCell (&RegistryHive->Hive, ParentKeyCell->SubKeyLists[Storage]);
|
||||
ParentKeyCell->SubKeyLists[Storage] = HTOffset;
|
||||
HashBlock = NewHashBlock;
|
||||
|
@ -443,24 +443,24 @@ CmiCompareKeyNames(
|
|||
PWCHAR UnicodeName;
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (KeyName->Length != KeyCell->NameSize)
|
||||
if (KeyName->Length != KeyCell->NameLength)
|
||||
return FALSE;
|
||||
|
||||
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])
|
||||
return FALSE;
|
||||
|
@ -480,27 +480,27 @@ CmiCompareKeyNamesI(
|
|||
|
||||
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;
|
||||
|
||||
/* 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]))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (KeyName->Length != KeyCell->NameSize)
|
||||
if (KeyName->Length != KeyCell->NameLength)
|
||||
return FALSE;
|
||||
|
||||
UnicodeName = (PWCHAR)KeyCell->Name;
|
||||
/* 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]) !=
|
||||
RtlUpcaseUnicodeChar(UnicodeName[i]))
|
||||
|
@ -520,7 +520,7 @@ CmiScanForSubKey(
|
|||
OUT PCM_KEY_NODE *pSubKeyCell,
|
||||
OUT HCELL_INDEX *pBlockOffset)
|
||||
{
|
||||
PHASH_TABLE_CELL HashBlock;
|
||||
PCM_KEY_FAST_INDEX HashBlock;
|
||||
PCM_KEY_NODE CurSubKeyCell;
|
||||
ULONG Storage;
|
||||
ULONG i;
|
||||
|
@ -542,42 +542,42 @@ CmiScanForSubKey(
|
|||
}
|
||||
|
||||
/* Get hash table */
|
||||
HashBlock = (PHASH_TABLE_CELL)HvGetCell (&RegistryHive->Hive, KeyCell->SubKeyLists[Storage]);
|
||||
if (!HashBlock || HashBlock->Id != REG_HASH_TABLE_CELL_ID)
|
||||
HashBlock = (PCM_KEY_FAST_INDEX)HvGetCell (&RegistryHive->Hive, KeyCell->SubKeyLists[Storage]);
|
||||
if (!HashBlock || HashBlock->Signature != CM_KEY_FAST_LEAF)
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
|
||||
for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++)
|
||||
{
|
||||
if (Attributes & OBJ_CASE_INSENSITIVE)
|
||||
{
|
||||
if ((HashBlock->Table[i].HashValue == 0
|
||||
|| CmiCompareHashI(SubKeyName, (PCHAR)&HashBlock->Table[i].HashValue)))
|
||||
if ((HashBlock->List[i].HashKey == 0
|
||||
|| CmiCompareHashI(SubKeyName, (PCHAR)&HashBlock->List[i].HashKey)))
|
||||
{
|
||||
CurSubKeyCell = (PCM_KEY_NODE)HvGetCell (
|
||||
&RegistryHive->Hive,
|
||||
HashBlock->Table[i].KeyOffset);
|
||||
HashBlock->List[i].Cell);
|
||||
|
||||
if (CmiCompareKeyNamesI(SubKeyName, CurSubKeyCell))
|
||||
{
|
||||
*pSubKeyCell = CurSubKeyCell;
|
||||
*pBlockOffset = HashBlock->Table[i].KeyOffset;
|
||||
*pBlockOffset = HashBlock->List[i].Cell;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((HashBlock->Table[i].HashValue == 0
|
||||
|| CmiCompareHash(SubKeyName, (PCHAR)&HashBlock->Table[i].HashValue)))
|
||||
if ((HashBlock->List[i].HashKey == 0
|
||||
|| CmiCompareHash(SubKeyName, (PCHAR)&HashBlock->List[i].HashKey)))
|
||||
{
|
||||
CurSubKeyCell = (PCM_KEY_NODE)HvGetCell (
|
||||
&RegistryHive->Hive,
|
||||
HashBlock->Table[i].KeyOffset);
|
||||
HashBlock->List[i].Cell);
|
||||
|
||||
if (CmiCompareKeyNames(SubKeyName, CurSubKeyCell))
|
||||
{
|
||||
*pSubKeyCell = CurSubKeyCell;
|
||||
*pBlockOffset = HashBlock->Table[i].KeyOffset;
|
||||
*pBlockOffset = HashBlock->List[i].Cell;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
@ -619,32 +619,32 @@ CmiAllocateValueCell(
|
|||
{
|
||||
PCM_KEY_VALUE NewValueCell;
|
||||
BOOLEAN Packable;
|
||||
USHORT NameSize, i;
|
||||
USHORT NameLength, i;
|
||||
NTSTATUS Status;
|
||||
|
||||
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)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(NameSize <= USHORT_MAX);
|
||||
ASSERT(NameLength <= USHORT_MAX);
|
||||
NewValueCell = (PCM_KEY_VALUE)HvGetCell (&RegistryHive->Hive, *VBOffset);
|
||||
NewValueCell->Id = REG_VALUE_CELL_ID;
|
||||
NewValueCell->NameSize = (USHORT)NameSize;
|
||||
NewValueCell->Signature = CM_KEY_VALUE_SIGNATURE;
|
||||
NewValueCell->NameLength = (USHORT)NameLength;
|
||||
if (Packable)
|
||||
{
|
||||
/* Pack the value name */
|
||||
for (i = 0; i < NameSize; i++)
|
||||
NewValueCell->Name[i] = (CHAR)ValueName->Buffer[i];
|
||||
NewValueCell->Flags |= REG_VALUE_NAME_PACKED;
|
||||
for (i = 0; i < NameLength; i++)
|
||||
((PCHAR)NewValueCell->Name)[i] = (CHAR)ValueName->Buffer[i];
|
||||
NewValueCell->Flags |= VALUE_COMP_NAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -652,12 +652,12 @@ CmiAllocateValueCell(
|
|||
RtlCopyMemory(
|
||||
NewValueCell->Name,
|
||||
ValueName->Buffer,
|
||||
NameSize);
|
||||
NameLength);
|
||||
NewValueCell->Flags = 0;
|
||||
}
|
||||
NewValueCell->DataType = 0;
|
||||
NewValueCell->DataSize = 0;
|
||||
NewValueCell->DataOffset = HCELL_NIL;
|
||||
NewValueCell->Type = 0;
|
||||
NewValueCell->DataLength = 0;
|
||||
NewValueCell->Data = HCELL_NIL;
|
||||
*ValueCell = NewValueCell;
|
||||
}
|
||||
|
||||
|
@ -681,7 +681,7 @@ CmiAddValueKey(
|
|||
HSTORAGE_TYPE Storage;
|
||||
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)
|
||||
{
|
||||
/* Allocate some room for the value list */
|
||||
|
@ -811,9 +811,9 @@ CmiScanForValueKey(
|
|||
|
||||
if (CmiComparePackedNames(
|
||||
ValueName,
|
||||
CurValueCell->Name,
|
||||
CurValueCell->NameSize,
|
||||
(BOOLEAN)((CurValueCell->Flags & REG_VALUE_NAME_PACKED) ? TRUE : FALSE)))
|
||||
(PUCHAR)CurValueCell->Name,
|
||||
CurValueCell->NameLength,
|
||||
(BOOLEAN)((CurValueCell->Flags & VALUE_COMP_NAME) ? TRUE : FALSE)))
|
||||
{
|
||||
*pValueCell = CurValueCell;
|
||||
*pValueCellOffset = ValueListCell->ValueOffset[i];
|
||||
|
|
|
@ -37,6 +37,9 @@
|
|||
#define NDEBUG
|
||||
#include "mkhive.h"
|
||||
|
||||
#define REG_DATA_SIZE_MASK 0x7FFFFFFF
|
||||
#define REG_DATA_IN_OFFSET 0x80000000
|
||||
|
||||
static EREGISTRY_HIVE RootHive;
|
||||
static MEMKEY RootKey;
|
||||
EREGISTRY_HIVE DefaultHive; /* \Registry\User\.DEFAULT */
|
||||
|
@ -362,10 +365,10 @@ RegSetValueExW(
|
|||
return ERROR_UNSUCCESSFUL;
|
||||
|
||||
/* Get size of the allocated cellule (if any) */
|
||||
if (!(ValueCell->DataSize & REG_DATA_IN_OFFSET) &&
|
||||
(ValueCell->DataSize & REG_DATA_SIZE_MASK) != 0)
|
||||
if (!(ValueCell->DataLength & REG_DATA_IN_OFFSET) &&
|
||||
(ValueCell->DataLength & REG_DATA_SIZE_MASK) != 0)
|
||||
{
|
||||
DataCell = HvGetCell(&Key->RegistryHive->Hive, ValueCell->DataOffset);
|
||||
DataCell = HvGetCell(&Key->RegistryHive->Hive, ValueCell->Data);
|
||||
if (!DataCell)
|
||||
return ERROR_UNSUCCESSFUL;
|
||||
DataCellSize = -HvGetCellSize(&Key->RegistryHive->Hive, DataCell);
|
||||
|
@ -379,13 +382,13 @@ RegSetValueExW(
|
|||
if (cbData <= sizeof(HCELL_INDEX))
|
||||
{
|
||||
/* 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)
|
||||
HvFreeCell(&Key->RegistryHive->Hive, ValueCell->DataOffset);
|
||||
HvFreeCell(&Key->RegistryHive->Hive, ValueCell->Data);
|
||||
|
||||
RtlCopyMemory(&ValueCell->DataOffset, lpData, cbData);
|
||||
ValueCell->DataSize = (ULONG)(cbData | REG_DATA_IN_OFFSET);
|
||||
ValueCell->DataType = dwType;
|
||||
RtlCopyMemory(&ValueCell->Data, lpData, cbData);
|
||||
ValueCell->DataLength = (ULONG)(cbData | REG_DATA_IN_OFFSET);
|
||||
ValueCell->Type = dwType;
|
||||
HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCellOffset, FALSE);
|
||||
}
|
||||
else
|
||||
|
@ -396,7 +399,7 @@ RegSetValueExW(
|
|||
* data block and allocate a new one. */
|
||||
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);
|
||||
if (NewOffset == HCELL_NIL)
|
||||
|
@ -406,17 +409,17 @@ RegSetValueExW(
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* Copy new contents to cellule */
|
||||
RtlCopyMemory(DataCell, lpData, cbData);
|
||||
ValueCell->DataSize = (ULONG)(cbData & REG_DATA_SIZE_MASK);
|
||||
ValueCell->DataType = dwType;
|
||||
HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCell->DataOffset, FALSE);
|
||||
ValueCell->DataLength = (ULONG)(cbData & REG_DATA_SIZE_MASK);
|
||||
ValueCell->Type = dwType;
|
||||
HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCell->Data, FALSE);
|
||||
HvMarkCellDirty(&Key->RegistryHive->Hive, ValueCellOffset, FALSE);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue