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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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