- 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:
Aleksey Bragin 2007-10-28 21:31:46 +00:00
parent 45199dd0b1
commit 6b7c404e0b
14 changed files with 509 additions and 857 deletions

View file

@ -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));

View file

@ -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;

View file

@ -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; USHORT Flags;
LARGE_INTEGER LastWriteTime;
/* Flags */ ULONG Spare;
USHORT Flags; HCELL_INDEX Parent;
ULONG SubKeyCounts[HTYPE_COUNT];
/* Time of last flush */ HCELL_INDEX SubKeyLists[HTYPE_COUNT];
LARGE_INTEGER LastWriteTime; CHILD_LIST ValueList;
HCELL_INDEX Security;
ULONG Spare; HCELL_INDEX Class;
ULONG MaxNameLen;
/* BlockAddress offset of parent key cell */ ULONG MaxClassLen;
HCELL_INDEX Parent; ULONG MaxValueNameLen;
ULONG MaxValueDataLen;
/* Count of sub keys for the key in this key cell (stable & volatile) */ ULONG WorkVar;
ULONG SubKeyCounts[HTYPE_COUNT]; USHORT NameLength;
USHORT ClassLength;
/* BlockAddress offset of has table for FIXME: subkeys/values? (stable & volatile) */ WCHAR Name[0];
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];
} 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 */

View file

@ -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);
} }
} }

View file

@ -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

View file

@ -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)

View file

@ -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);

View file

@ -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;

View file

@ -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 */

View file

@ -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;
} }

View file

@ -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
// //

View file

@ -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;

View file

@ -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];

View file

@ -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);
} }