*/
#include <freeldr.h>
-#include <rtl.h>
-#include <mm.h>
-#include <debug.h>
-
-#include "registry.h"
+#define NDEBUG
+#include <debug.h>
#define REG_HIVE_ID 0x66676572 /* "regf" */
#define REG_BIN_ID 0x6e696268 /* "hbin" */
/* BLOCK_OFFSET = offset in file after header block */
-typedef U32 BLOCK_OFFSET, *PBLOCK_OFFSET;
+typedef ULONG BLOCK_OFFSET, *PBLOCK_OFFSET;
/* header for registry hive file : */
typedef struct _HIVE_HEADER
{
/* Hive identifier "regf" (0x66676572) */
- U32 BlockId;
+ ULONG BlockId;
/* Update counter */
- U32 UpdateCounter1;
+ ULONG UpdateCounter1;
/* Update counter */
- U32 UpdateCounter2;
+ ULONG UpdateCounter2;
/* When this hive file was last modified */
- U64 DateModified; /* FILETIME */
+ ULONGLONG DateModified;
- /* Registry format version ? (1?) */
- U32 Unused3;
+ /* Registry format major version (1) */
+ ULONG MajorVersion;
- /* Registry format version ? (3?) */
- U32 Unused4;
+ /* Registry format minor version (3)
+ Version 3 added fast indexes, version 5 has large value optimizations */
+ ULONG MinorVersion;
- /* Registry format version ? (0?) */
- U32 Unused5;
+ /* Registry file type (0 - Primary, 1 - Log) */
+ ULONG Type;
- /* Registry format version ? (1?) */
- U32 Unused6;
+ /* Registry format (1 is the only defined value so far) */
+ ULONG Format;
/* Offset into file from the byte after the end of the base block.
If the hive is volatile, this is the actual pointer to the KEY_CELL */
BLOCK_OFFSET RootKeyOffset;
/* Size of each hive block ? */
- U32 BlockSize;
+ ULONG BlockSize;
/* (1?) */
- U32 Unused7;
+ ULONG Unused7;
/* Name of hive file */
- WCHAR FileName[64];
+ WCHAR FileName[48];
- /* ? */
- U32 Unused8[83];
+ ULONG Reserved[99];
/* Checksum of first 0x200 bytes */
- U32 Checksum;
+ ULONG Checksum;
} __attribute__((packed)) HIVE_HEADER, *PHIVE_HEADER;
typedef struct _BIN_HEADER
{
/* Bin identifier "hbin" (0x6E696268) */
- U32 HeaderId;
+ ULONG HeaderId;
- /* Bin offset */
+ /* Block offset of this bin */
BLOCK_OFFSET BinOffset;
/* Size in bytes, multiple of the block size (4KB) */
- U32 BinSize;
+ ULONG BinSize;
- /* ? */
- U32 Unused1;
+ ULONG Reserved[2];
/* When this bin was last modified */
- U64 DateModified; /* FILETIME */
+ ULONGLONG DateModified;
- /* ? */
- U32 Unused2;
+ /* ? (In-memory only) */
+ ULONG MemAlloc;
} __attribute__((packed)) HBIN, *PHBIN;
typedef struct _CELL_HEADER
{
/* <0 if used, >0 if free */
- S32 CellSize;
+ LONG CellSize;
} __attribute__((packed)) CELL_HEADER, *PCELL_HEADER;
typedef struct _KEY_CELL
{
/* Size of this cell */
- S32 CellSize;
+ LONG CellSize;
/* Key cell identifier "kn" (0x6b6e) */
- U16 Id;
+ USHORT Id;
- /* ? */
- U16 Type;
+ /* Flags */
+ USHORT Flags;
/* Time of last flush */
- U64 LastWriteTime; /* FILETIME */
+ ULONGLONG LastWriteTime; /* FILETIME */
/* ? */
- U32 UnUsed1;
+ ULONG UnUsed1;
/* Block offset of parent key cell */
BLOCK_OFFSET ParentKeyOffset;
/* Count of sub keys for the key in this key cell */
- U32 NumberOfSubKeys;
+ ULONG NumberOfSubKeys;
/* ? */
- U32 UnUsed2;
+ ULONG UnUsed2;
/* Block offset of has table for FIXME: subkeys/values? */
BLOCK_OFFSET HashTableOffset;
/* ? */
- U32 UnUsed3;
+ ULONG UnUsed3;
/* Count of values contained in this key cell */
- U32 NumberOfValues;
+ ULONG NumberOfValues;
/* Block offset of VALUE_LIST_CELL */
BLOCK_OFFSET ValueListOffset;
BLOCK_OFFSET ClassNameOffset;
/* ? */
- U32 Unused4[5];
+ ULONG Unused4[5];
/* Size in bytes of key name */
- U16 NameSize;
+ USHORT NameSize;
/* Size of class name in bytes */
- U16 ClassSize;
+ USHORT ClassSize;
/* Name of key (not zero terminated) */
- U8 Name[0];
+ CHAR Name[0];
} __attribute__((packed)) KEY_CELL, *PKEY_CELL;
/* KEY_CELL.Type constants */
#define REG_LINK_KEY_CELL_TYPE 0x10
-#define REG_KEY_CELL_TYPE 0x20
-#define REG_ROOT_KEY_CELL_TYPE 0x2c
+#define REG_KEY_NAME_PACKED 0x20
+#define REG_ROOT_KEY_CELL_TYPE 0x0c
// hash record :
typedef struct _HASH_RECORD
{
BLOCK_OFFSET KeyOffset;
- U32 HashValue;
+ ULONG HashValue;
} __attribute__((packed)) HASH_RECORD, *PHASH_RECORD;
typedef struct _HASH_TABLE_CELL
{
- S32 CellSize;
- U16 Id;
- U16 HashTableSize;
+ LONG CellSize;
+ USHORT Id;
+ USHORT HashTableSize;
HASH_RECORD Table[0];
} __attribute__((packed)) HASH_TABLE_CELL, *PHASH_TABLE_CELL;
typedef struct _VALUE_LIST_CELL
{
- S32 CellSize;
+ LONG CellSize;
BLOCK_OFFSET ValueOffset[0];
} __attribute__((packed)) VALUE_LIST_CELL, *PVALUE_LIST_CELL;
typedef struct _VALUE_CELL
{
- S32 CellSize;
- U16 Id; // "kv"
- U16 NameSize; // length of Name
- U32 DataSize; // length of datas in the cell pointed by DataOffset
+ LONG CellSize;
+ USHORT Id; // "kv"
+ USHORT NameSize; // length of Name
+ ULONG DataSize; // length of datas in the cell pointed by DataOffset
BLOCK_OFFSET DataOffset;// datas are here if high bit of DataSize is set
- U32 DataType;
- U16 Flags;
- U16 Unused1;
- UCHAR Name[0]; /* warning : not zero terminated */
+ ULONG DataType;
+ USHORT Flags;
+ USHORT Unused1;
+ CHAR Name[0]; /* warning : not zero terminated */
} __attribute__((packed)) VALUE_CELL, *PVALUE_CELL;
/* VALUE_CELL.Flags constants */
typedef struct _DATA_CELL
{
- S32 CellSize;
- UCHAR Data[0];
+ LONG CellSize;
+ CHAR Data[0];
} __attribute__((packed)) DATA_CELL, *PDATA_CELL;
typedef struct _REGISTRY_HIVE
{
- U32 FileSize;
+ ULONG FileSize;
PHIVE_HEADER HiveHeader;
- U32 BlockListSize;
+ ULONG BlockListSize;
PHBIN *BlockList;
- U32 FreeListSize;
- U32 FreeListMax;
+ ULONG FreeListSize;
+ ULONG FreeListMax;
PCELL_HEADER *FreeList;
BLOCK_OFFSET *FreeListOffset;
} REGISTRY_HIVE, *PREGISTRY_HIVE;
static PVOID MbBase = NULL;
-static U32 MbSize = 0;
+static ULONG MbSize = 0;
/* FUNCTIONS ****************************************************************/
static PVOID
-AllocateMbMemory (U32 MemSize)
+AllocateMbMemory (ULONG MemSize)
{
PVOID CurBase;
CurBase = MbBase;
- MbBase = (PVOID)((U32)MbBase + MemSize);
+ MbBase = (PVOID)((ULONG)MbBase + MemSize);
MbSize += MemSize;
return CurBase;
MbSize = 0;
}
-static U32
+static ULONG
GetMbAllocatedSize (VOID)
{
return MbSize;
Header->BlockId = REG_HIVE_ID;
Header->UpdateCounter1 = 0;
Header->UpdateCounter2 = 0;
- Header->DateModified = 0ULL;
- Header->Unused3 = 1;
- Header->Unused4 = 3;
- Header->Unused5 = 0;
- Header->Unused6 = 1;
+ Header->DateModified = 0;
+ Header->MajorVersion = 1;
+ Header->MinorVersion = 3;
+ Header->Type = 0;
+ Header->Format = 1;
Header->Unused7 = 1;
Header->RootKeyOffset = -1;
Header->BlockSize = REG_BLOCK_SIZE;
- Header->Unused6 = 1;
Header->Checksum = 0;
}
static VOID
-CmiCreateDefaultRootKeyCell (PKEY_CELL RootKeyCell, PCHAR KeyName)
+CmiCreateDefaultRootKeyCell (PKEY_CELL RootKeyCell, PCWSTR KeyName)
{
- PCHAR BaseKeyName;
- U32 NameSize;
- U32 CellSize;
+ PWCHAR BaseKeyName;
+ ULONG NameSize;
+ ULONG CellSize;
+ ULONG i;
+ BOOL Packable = TRUE;
assert (RootKeyCell);
- BaseKeyName = strrchr(KeyName, '\\') + 1;
- NameSize = strlen(BaseKeyName);
- CellSize = ROUND_UP(sizeof(KEY_CELL) + NameSize - 1, 16);
+ BaseKeyName = wcsrchr(KeyName, L'\\') + 1;
+ NameSize = wcslen(BaseKeyName);
+ for (i = 0; i < NameSize; i++)
+ {
+ if (KeyName[i] & 0xFF00)
+ {
+ Packable = FALSE;
+ NameSize *= sizeof(WCHAR);
+ break;
+ }
+ }
+
+ CellSize = ROUND_UP(sizeof(KEY_CELL) + NameSize, 16);
memset (RootKeyCell, 0, CellSize);
RootKeyCell->CellSize = -CellSize;
RootKeyCell->Id = REG_KEY_CELL_ID;
- RootKeyCell->Type = REG_ROOT_KEY_CELL_TYPE;
+ RootKeyCell->Flags = REG_ROOT_KEY_CELL_TYPE;
RootKeyCell->LastWriteTime = 0ULL;
RootKeyCell->ParentKeyOffset = 0;
RootKeyCell->NumberOfSubKeys = 0;
RootKeyCell->ClassNameOffset = -1;
RootKeyCell->NameSize = NameSize;
RootKeyCell->ClassSize = 0;
- memcpy (RootKeyCell->Name, BaseKeyName, NameSize);
+ if (Packable)
+ {
+ for(i = 0; i < NameSize; i++)
+ {
+ ((PCHAR)RootKeyCell->Name)[i] = BaseKeyName[i];
+ }
+ RootKeyCell->Flags |= REG_KEY_NAME_PACKED;
+ }
+ else
+ {
+ memcpy (RootKeyCell->Name, BaseKeyName, NameSize);
+ }
}
static PREGISTRY_HIVE
-CmiCreateHive (PCHAR KeyName)
+CmiCreateHive (PCWSTR KeyName)
{
PREGISTRY_HIVE Hive;
PCELL_HEADER FreeCell;
BinCell->BinOffset = 0;
/* Init root key cell */
- RootKeyCell = (PKEY_CELL)((U32)BinCell + REG_HBIN_DATA_OFFSET);
+ RootKeyCell = (PKEY_CELL)((ULONG)BinCell + REG_HBIN_DATA_OFFSET);
CmiCreateDefaultRootKeyCell(RootKeyCell, KeyName);
Hive->HiveHeader->RootKeyOffset = REG_HBIN_DATA_OFFSET;
/* Init free cell */
- FreeCell = (PCELL_HEADER)((U32)RootKeyCell - RootKeyCell->CellSize);
+ FreeCell = (PCELL_HEADER)((ULONG)RootKeyCell - RootKeyCell->CellSize);
FreeCell->CellSize = REG_BLOCK_SIZE - (REG_HBIN_DATA_OFFSET - RootKeyCell->CellSize);
Hive->FreeList[0] = FreeCell;
CmiGetBin (PREGISTRY_HIVE Hive,
BLOCK_OFFSET BlockOffset)
{
- U32 BlockIndex;
+ ULONG BlockIndex;
- if (BlockOffset == (U32) -1)
+ if (BlockOffset == (ULONG) -1)
return NULL;
BlockIndex = BlockOffset / REG_BLOCK_SIZE;
{
BLOCK_OFFSET BlockOffset;
BLOCK_OFFSET BinOffset;
- U32 BlockSize;
- U32 BinSize;
+ ULONG BlockSize;
+ ULONG BinSize;
PHBIN Bin;
- U32 i;
+ ULONG i;
DbgPrint((DPRINT_REGISTRY, "CmiMergeFree(Block %lx Offset %lx Size %lx) called\n",
FreeBlock, FreeOffset, FreeBlock->CellSize));
{
PCELL_HEADER *tmpList;
BLOCK_OFFSET *tmpListOffset;
- S32 minInd;
- S32 maxInd;
- S32 medInd;
+ LONG minInd;
+ LONG maxInd;
+ LONG medInd;
assert(RegistryHive);
assert(FreeBlock);
static BOOL
CmiAddBin(PREGISTRY_HIVE RegistryHive,
- U32 BlockCount,
+ ULONG BlockCount,
PVOID *NewBlock,
PBLOCK_OFFSET NewBlockOffset)
{
PCELL_HEADER tmpBlock;
PHBIN *BlockList;
PHBIN tmpBin;
- U32 BinSize;
- U32 i;
+ ULONG BinSize;
+ ULONG i;
BinSize = BlockCount * REG_BLOCK_SIZE;
tmpBin = AllocateMbMemory (BinSize);
tmpBin->BinOffset = RegistryHive->FileSize - REG_BLOCK_SIZE;
RegistryHive->FileSize += BinSize;
tmpBin->BinSize = BinSize;
- tmpBin->Unused1 = 0;
tmpBin->DateModified = 0ULL;
- tmpBin->Unused2 = 0;
+ tmpBin->MemAlloc = 0;
/* Increase size of list of blocks */
BlockList = MmAllocateMemory (sizeof(PHBIN) * (RegistryHive->BlockListSize + BlockCount));
RegistryHive->BlockListSize += BlockCount;
/* Initialize a free block in this heap : */
- tmpBlock = (PCELL_HEADER)((U32) tmpBin + REG_HBIN_DATA_OFFSET);
+ tmpBlock = (PCELL_HEADER)((ULONG) tmpBin + REG_HBIN_DATA_OFFSET);
tmpBlock->CellSize = (REG_BLOCK_SIZE - REG_HBIN_DATA_OFFSET);
*NewBlock = (PVOID) tmpBlock;
static BOOL
CmiAllocateCell (PREGISTRY_HIVE RegistryHive,
- S32 CellSize,
+ LONG CellSize,
PVOID *Block,
PBLOCK_OFFSET pBlockOffset)
{
PCELL_HEADER NewBlock;
- U32 i;
+ ULONG i;
*Block = NULL;
/* Split the block in two parts */
if (NewBlock->CellSize > CellSize)
{
- NewBlock = (PCELL_HEADER) ((U32)NewBlock + CellSize);
+ NewBlock = (PCELL_HEADER) ((ULONG)NewBlock + CellSize);
NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - CellSize;
+ ((PCELL_HEADER) (*Block))->CellSize = CellSize;
CmiAddFree (RegistryHive,
NewBlock,
*pBlockOffset + CellSize,
}
memset(*Block, 0, CellSize);
- ((PCELL_HEADER)(*Block))->CellSize = -CellSize;
+ ((PCELL_HEADER)(*Block))->CellSize *= -1;
return TRUE;
}
BLOCK_OFFSET BlockOffset)
{
PHBIN Bin;
- U32 BlockIndex;
+ ULONG BlockIndex;
- if (BlockOffset == (U32) -1)
+ if (BlockOffset == (ULONG) -1)
return NULL;
BlockIndex = BlockOffset / REG_BLOCK_SIZE;
if (Bin == NULL)
return NULL;
- return (PVOID)((U32)Bin + (BlockOffset - Bin->BinOffset));
+ return (PVOID)((ULONG)Bin + (BlockOffset - Bin->BinOffset));
}
static BOOL
CmiAllocateHashTableCell (PREGISTRY_HIVE Hive,
PBLOCK_OFFSET HBOffset,
- U32 SubKeyCount)
+ ULONG SubKeyCount)
{
PHASH_TABLE_CELL HashCell;
- U32 NewHashSize;
+ ULONG NewHashSize;
BOOL Status;
- NewHashSize = sizeof(HASH_TABLE_CELL) +
+ NewHashSize = sizeof(HASH_TABLE_CELL) +
(SubKeyCount * sizeof(HASH_RECORD));
Status = CmiAllocateCell (Hive,
NewHashSize,
{
PHASH_TABLE_CELL HashBlock;
PKEY_CELL ParentKeyCell;
- U32 i;
+ ULONG i;
ParentKeyCell = CmiGetCell (Hive, ParentKeyOffset);
if (ParentKeyCell == NULL)
HashBlock->Table[i].KeyOffset = NKBOffset;
memcpy (&HashBlock->Table[i].HashValue,
NewKeyCell->Name,
- 4);
+ min(NewKeyCell->NameSize, sizeof(ULONG)));
ParentKeyCell->NumberOfSubKeys++;
return TRUE;
}
static BOOL
CmiAllocateValueListCell (PREGISTRY_HIVE Hive,
PBLOCK_OFFSET ValueListOffset,
- U32 ValueCount)
+ ULONG ValueCount)
{
PVALUE_LIST_CELL ValueListCell;
- U32 ValueListSize;
+ ULONG ValueListSize;
BOOL Status;
ValueListSize = sizeof(VALUE_LIST_CELL) +
CmiAllocateValueCell(PREGISTRY_HIVE Hive,
PVALUE_CELL *ValueCell,
BLOCK_OFFSET *ValueCellOffset,
- PCHAR ValueName)
+ PWCHAR ValueName)
{
PVALUE_CELL NewValueCell;
- U32 NameSize;
+ ULONG NameSize;
BOOL Status;
+ BOOLEAN Packable = TRUE;
+ ULONG i;
- NameSize = (ValueName == NULL) ? 0 : strlen (ValueName);
+ NameSize = (ValueName == NULL) ? 0 : wcslen (ValueName);
+ for (i = 0; i < NameSize; i++)
+ {
+ if (ValueName[i] & 0xFF00)
+ {
+ NameSize *= sizeof(WCHAR);
+ Packable = FALSE;
+ break;
+ }
+ }
Status = CmiAllocateCell (Hive,
sizeof(VALUE_CELL) + NameSize,
(PVOID*)(PVOID)&NewValueCell,
NewValueCell->Id = REG_VALUE_CELL_ID;
NewValueCell->NameSize = NameSize;
+ NewValueCell->Flags = 0;
if (NameSize > 0)
{
- memcpy (NewValueCell->Name,
- ValueName,
- NameSize);
- NewValueCell->Flags = REG_VALUE_NAME_PACKED;
+ if (Packable)
+ {
+ for (i = 0; i < NameSize; i++)
+ {
+ ((PCHAR)NewValueCell->Name)[i] = (CHAR)ValueName[i];
+ }
+ NewValueCell->Flags |= REG_VALUE_NAME_PACKED;
+ }
+ else
+ {
+ memcpy (NewValueCell->Name,
+ ValueName,
+ NameSize);
+ }
}
NewValueCell->DataType = 0;
NewValueCell->DataSize = 0;
return TRUE;
}
-
-static VOID
-memexpand (PWCHAR Dst,
- PCHAR Src,
- U32 Length)
-{
- U32 i;
-
- for (i = 0; i < Length; i++)
- Dst[i] = (WCHAR)Src[i];
-}
-
-
static BOOL
CmiExportValue (PREGISTRY_HIVE Hive,
BLOCK_OFFSET KeyCellOffset,
- HKEY Key,
+ FRLDRHKEY Key,
PVALUE Value)
{
BLOCK_OFFSET ValueCellOffset;
BLOCK_OFFSET DataCellOffset;
PVALUE_CELL ValueCell;
PDATA_CELL DataCell;
- U32 SrcDataSize;
- U32 DstDataSize;
- U32 DataType;
- PUCHAR Data;
- BOOL Expand = FALSE;
+ ULONG DataSize;
+ ULONG DataType;
+ PCHAR Data;
- DbgPrint((DPRINT_REGISTRY, "CmiExportValue('%s') called\n",
+ DbgPrint((DPRINT_REGISTRY, "CmiExportValue('%S') called\n",
(Value == NULL) ? "<default>" : (PCHAR)Value->Name));
DbgPrint((DPRINT_REGISTRY, "DataSize %lu\n",
(Value == NULL) ? Key->DataSize : Value->DataSize));
if (Value == NULL)
{
DataType = Key->DataType;
- SrcDataSize = Key->DataSize;
+ DataSize = Key->DataSize;
Data = Key->Data;
}
else
{
DataType = Value->DataType;
- SrcDataSize = Value->DataSize;
+ DataSize = Value->DataSize;
Data = Value->Data;
}
- DstDataSize = SrcDataSize;
- if (DataType == REG_SZ ||
- DataType == REG_EXPAND_SZ ||
- DataType == REG_MULTI_SZ)
+ if (DataSize <= sizeof(BLOCK_OFFSET))
{
- DstDataSize *= sizeof(WCHAR);
- Expand = TRUE;
- }
-
- if (DstDataSize <= sizeof(BLOCK_OFFSET))
- {
- ValueCell->DataSize = DstDataSize | REG_DATA_IN_OFFSET;
+ ValueCell->DataSize = DataSize | REG_DATA_IN_OFFSET;
ValueCell->DataType = DataType;
- if (Expand)
- {
- memexpand ((PWCHAR)&ValueCell->DataOffset,
- (PCHAR)&Data,
- SrcDataSize);
- }
- else
- {
- memcpy (&ValueCell->DataOffset,
- &Data,
- SrcDataSize);
- }
+ memcpy (&ValueCell->DataOffset,
+ Data,
+ DataSize);
}
else
{
/* Allocate data cell */
if (!CmiAllocateCell (Hive,
- sizeof(CELL_HEADER) + DstDataSize,
+ sizeof(CELL_HEADER) + DataSize,
(PVOID *)(PVOID)&DataCell,
&DataCellOffset))
{
}
ValueCell->DataOffset = DataCellOffset;
- ValueCell->DataSize = DstDataSize;
+ ValueCell->DataSize = DataSize;
ValueCell->DataType = DataType;
- if (Expand)
- {
- if (SrcDataSize <= sizeof(BLOCK_OFFSET))
- {
- memexpand ((PWCHAR)DataCell->Data,
- (PCHAR)&Data,
- SrcDataSize);
- }
- else
- {
- memexpand ((PWCHAR)DataCell->Data,
- Data,
- SrcDataSize);
- }
- }
- else
- {
- memcpy (DataCell->Data,
- Data,
- SrcDataSize);
- }
+ memcpy (DataCell->Data,
+ Data,
+ DataSize);
}
return TRUE;
static BOOL
CmiExportSubKey (PREGISTRY_HIVE Hive,
BLOCK_OFFSET ParentKeyOffset,
- HKEY ParentKey,
- HKEY Key)
+ FRLDRHKEY ParentKey,
+ FRLDRHKEY Key)
{
BLOCK_OFFSET NKBOffset;
PKEY_CELL NewKeyCell;
- U32 KeyCellSize;
- U32 SubKeyCount;
- U32 ValueCount;
+ ULONG KeyCellSize;
+ ULONG SubKeyCount;
+ ULONG ValueCount;
PLIST_ENTRY Entry;
- HKEY SubKey;
+ FRLDRHKEY SubKey;
PVALUE Value;
+ BOOLEAN Packable = TRUE;
+ ULONG i;
+ ULONG NameSize;
- DbgPrint((DPRINT_REGISTRY, "CmiExportSubKey('%s') called\n", Key->Name));
+ DbgPrint((DPRINT_REGISTRY, "CmiExportSubKey('%S') called\n", Key->Name));
/* Don't export links */
if (Key->DataType == REG_LINK)
return TRUE;
+ NameSize = (Key->NameSize - sizeof(WCHAR)) / sizeof(WCHAR);
+ for (i = 0; i < NameSize; i++)
+ {
+ if (Key->Name[i] & 0xFF00)
+ {
+ Packable = FALSE;
+ NameSize *= sizeof(WCHAR);
+ break;
+ }
+ }
+
/* Allocate key cell */
- KeyCellSize = sizeof(KEY_CELL) + Key->NameSize - 1;
+ KeyCellSize = sizeof(KEY_CELL) + NameSize;
if (!CmiAllocateCell (Hive, KeyCellSize, (PVOID)&NewKeyCell, &NKBOffset))
{
DbgPrint((DPRINT_REGISTRY, "CmiAllocateCell() failed\n"));
/* Initialize key cell */
NewKeyCell->Id = REG_KEY_CELL_ID;
- NewKeyCell->Type = REG_KEY_CELL_TYPE;
+ NewKeyCell->Flags = 0;
NewKeyCell->LastWriteTime = 0ULL;
NewKeyCell->ParentKeyOffset = ParentKeyOffset;
NewKeyCell->NumberOfSubKeys = 0;
NewKeyCell->ValueListOffset = -1;
NewKeyCell->SecurityKeyOffset = -1;
NewKeyCell->ClassNameOffset = -1;
- NewKeyCell->NameSize = Key->NameSize - 1;
+ NewKeyCell->NameSize = NameSize;
NewKeyCell->ClassSize = 0;
- memcpy (NewKeyCell->Name,
- Key->Name,
- Key->NameSize - 1);
+ if (Packable)
+ {
+ for (i = 0; i < NameSize; i++)
+ {
+ ((PCHAR)NewKeyCell->Name)[i] = (CHAR)Key->Name[i];
+ }
+ NewKeyCell->Flags |= REG_KEY_NAME_PACKED;
+
+ }
+ else
+ {
+ memcpy (NewKeyCell->Name,
+ Key->Name,
+ NameSize);
+ }
/* Add key cell to the parent key's hash table */
if (!CmiAddKeyToParentHashTable (Hive,
static VOID
CmiCalcHiveChecksum (PREGISTRY_HIVE Hive)
{
- U32 *Buffer;
- U32 Sum;
- U32 i;
+ ULONG *Buffer;
+ ULONG Sum;
+ ULONG i;
- Buffer = (U32*)Hive->HiveHeader;
+ Buffer = (ULONG*)Hive->HiveHeader;
Sum = 0;
for (i = 0; i < 127; i++)
Sum += Buffer[i];
}
-BOOL
+static BOOL
CmiExportHive (PREGISTRY_HIVE Hive,
- PCHAR KeyName)
+ PCWSTR KeyName)
{
PKEY_CELL KeyCell;
- HKEY Key;
- U32 SubKeyCount;
- U32 ValueCount;
+ FRLDRHKEY Key;
+ ULONG SubKeyCount;
+ ULONG ValueCount;
PLIST_ENTRY Entry;
- HKEY SubKey;
+ FRLDRHKEY SubKey;
PVALUE Value;
- DbgPrint((DPRINT_REGISTRY, "CmiExportHive(%x, '%s') called\n", Hive, KeyName));
+ DbgPrint((DPRINT_REGISTRY, "CmiExportHive(%x, '%S') called\n", Hive, KeyName));
if (RegOpenKey (NULL, KeyName, &Key) != ERROR_SUCCESS)
{
static BOOL
RegImportValue (PHBIN RootBin,
PVALUE_CELL ValueCell,
- HKEY Key)
+ FRLDRHKEY Key)
{
PDATA_CELL DataCell;
PWCHAR wName;
- PCHAR cName;
- S32 Error;
- S32 DataSize;
- PCHAR cBuffer;
- PWCHAR wBuffer;
- S32 i;
+ LONG Error;
+ ULONG DataSize;
+ ULONG i;
if (ValueCell->CellSize >= 0 || ValueCell->Id != REG_VALUE_CELL_ID)
{
if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
{
- cName = MmAllocateMemory (ValueCell->NameSize + 1);
- memcpy (cName,
- ValueCell->Name,
- ValueCell->NameSize);
- cName[ValueCell->NameSize] = 0;
+ wName = MmAllocateMemory ((ValueCell->NameSize + 1)*sizeof(WCHAR));
+ for (i = 0; i < ValueCell->NameSize; i++)
+ {
+ wName[i] = ((PCHAR)ValueCell->Name)[i];
+ }
+ wName[ValueCell->NameSize] = 0;
}
else
{
- wName = (PWCHAR)ValueCell->Name;
- cName = MmAllocateMemory (ValueCell->NameSize / 2 + 1);
- for (i = 0; i < ValueCell->NameSize / 2; i++)
- cName[i] = (CHAR)wName[i];
- cName[ValueCell->NameSize / 2] = 0;
+ wName = MmAllocateMemory (ValueCell->NameSize + sizeof(WCHAR));
+ memcpy (wName,
+ ValueCell->Name,
+ ValueCell->NameSize);
+ wName[ValueCell->NameSize / sizeof(WCHAR)] = 0;
}
DataSize = ValueCell->DataSize & REG_DATA_SIZE_MASK;
- DbgPrint((DPRINT_REGISTRY, "ValueName: '%s'\n", cName));
+ DbgPrint((DPRINT_REGISTRY, "ValueName: '%S'\n", wName));
DbgPrint((DPRINT_REGISTRY, "DataSize: %u\n", DataSize));
if (DataSize <= sizeof(BLOCK_OFFSET) && (ValueCell->DataSize & REG_DATA_IN_OFFSET))
{
Error = RegSetValue(Key,
- cName,
+ wName,
ValueCell->DataType,
- (PUCHAR)&ValueCell->DataOffset,
+ (PCHAR)&ValueCell->DataOffset,
DataSize);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_REGISTRY, "RegSetValue() failed!\n"));
- MmFreeMemory (cName);
+ MmFreeMemory (wName);
return FALSE;
}
}
if (DataCell->CellSize >= 0)
{
DbgPrint((DPRINT_REGISTRY, "Invalid data cell size!\n"));
- MmFreeMemory (cName);
+ MmFreeMemory (wName);
return FALSE;
}
- if (ValueCell->DataType == REG_SZ ||
- ValueCell->DataType == REG_EXPAND_SZ ||
- ValueCell->DataType == REG_MULTI_SZ)
- {
- wBuffer = (PWCHAR)DataCell->Data;
- cBuffer = MmAllocateMemory(DataSize/2);
- for (i = 0; i < DataSize / 2; i++)
- cBuffer[i] = (CHAR)wBuffer[i];
-
- Error = RegSetValue (Key,
- cName,
- ValueCell->DataType,
- cBuffer,
- DataSize/2);
-
- MmFreeMemory(cBuffer);
- }
- else
- {
- Error = RegSetValue (Key,
- cName,
- ValueCell->DataType,
- (PUCHAR)DataCell->Data,
- DataSize);
- }
+ Error = RegSetValue (Key,
+ wName,
+ ValueCell->DataType,
+ DataCell->Data,
+ DataSize);
+
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_REGISTRY, "RegSetValue() failed!\n"));
- MmFreeMemory (cName);
+ MmFreeMemory (wName);
return FALSE;
}
}
- MmFreeMemory (cName);
+ MmFreeMemory (wName);
return TRUE;
}
static BOOL
RegImportSubKey(PHBIN RootBin,
PKEY_CELL KeyCell,
- HKEY ParentKey)
+ FRLDRHKEY ParentKey)
{
PHASH_TABLE_CELL HashCell;
PKEY_CELL SubKeyCell;
PVALUE_LIST_CELL ValueListCell;
PVALUE_CELL ValueCell = NULL;
- PCHAR cName;
- HKEY SubKey;
- S32 Error;
- U32 i;
+ PWCHAR wName;
+ FRLDRHKEY SubKey;
+ LONG Error;
+ ULONG i;
DbgPrint((DPRINT_REGISTRY, "KeyCell: %x\n", KeyCell));
return FALSE;
}
- /* FIXME: implement packed key names */
- cName = MmAllocateMemory (KeyCell->NameSize + 1);
- memcpy (cName,
- KeyCell->Name,
- KeyCell->NameSize);
- cName[KeyCell->NameSize] = 0;
+ if (KeyCell->Flags & REG_KEY_NAME_PACKED)
+ {
+ wName = MmAllocateMemory ((KeyCell->NameSize + 1) * sizeof(WCHAR));
+ for (i = 0; i < KeyCell->NameSize; i++)
+ {
+ wName[i] = ((PCHAR)KeyCell->Name)[i];
+ }
+ wName[KeyCell->NameSize] = 0;
+ }
+ else
+ {
+ wName = MmAllocateMemory (KeyCell->NameSize + sizeof(WCHAR));
+ memcpy (wName,
+ KeyCell->Name,
+ KeyCell->NameSize);
+ wName[KeyCell->NameSize/sizeof(WCHAR)] = 0;
+ }
- DbgPrint((DPRINT_REGISTRY, "KeyName: '%s'\n", cName));
+ DbgPrint((DPRINT_REGISTRY, "KeyName: '%S'\n", wName));
/* Create new sub key */
Error = RegCreateKey (ParentKey,
- cName,
+ wName,
&SubKey);
- MmFreeMemory (cName);
+ MmFreeMemory (wName);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_REGISTRY, "RegCreateKey() failed!\n"));
BOOL
RegImportBinaryHive(PCHAR ChunkBase,
- U32 ChunkSize)
+ ULONG ChunkSize)
{
PHIVE_HEADER HiveHeader;
PHBIN RootBin;
PKEY_CELL KeyCell;
PHASH_TABLE_CELL HashCell;
PKEY_CELL SubKeyCell;
- HKEY SystemKey;
- U32 i;
- S32 Error;
+ FRLDRHKEY SystemKey;
+ ULONG i;
+ LONG Error;
DbgPrint((DPRINT_REGISTRY, "RegImportBinaryHive(%x, %u) called\n",ChunkBase,ChunkSize));
return FALSE;
}
- RootBin = (PHBIN)((U32)HiveHeader + REG_BLOCK_SIZE);
+ RootBin = (PHBIN)((ULONG)HiveHeader + REG_BLOCK_SIZE);
DbgPrint((DPRINT_REGISTRY, "RootBin: %x\n", RootBin));
if (RootBin->HeaderId != REG_BIN_ID || RootBin->BinSize == 0)
{
return FALSE;
}
- KeyCell = (PKEY_CELL)((U32)RootBin + REG_HBIN_DATA_OFFSET);
+ KeyCell = (PKEY_CELL)((ULONG)RootBin + REG_HBIN_DATA_OFFSET);
DbgPrint((DPRINT_REGISTRY, "KeyCell: %x\n", KeyCell));
DbgPrint((DPRINT_REGISTRY, "KeyCell->CellSize: %x\n", KeyCell->CellSize));
DbgPrint((DPRINT_REGISTRY, "KeyCell->Id: %x\n", KeyCell->Id));
/* Open 'System' key */
Error = RegOpenKey(NULL,
- "\\Registry\\Machine\\SYSTEM",
+ L"\\Registry\\Machine\\SYSTEM",
&SystemKey);
if (Error != ERROR_SUCCESS)
{
/* Enumerate and add subkeys */
if (KeyCell->NumberOfSubKeys > 0)
{
- HashCell = (PHASH_TABLE_CELL)((U32)RootBin + KeyCell->HashTableOffset);
+ HashCell = (PHASH_TABLE_CELL)((ULONG)RootBin + KeyCell->HashTableOffset);
DbgPrint((DPRINT_REGISTRY, "HashCell: %x\n", HashCell));
for (i = 0; i < KeyCell->NumberOfSubKeys; i++)
{
DbgPrint((DPRINT_REGISTRY, "KeyOffset[%d]: %x\n", i, HashCell->Table[i].KeyOffset));
- SubKeyCell = (PKEY_CELL)((U32)RootBin + HashCell->Table[i].KeyOffset);
+ SubKeyCell = (PKEY_CELL)((ULONG)RootBin + HashCell->Table[i].KeyOffset);
DbgPrint((DPRINT_REGISTRY, "SubKeyCell[%d]: %x\n", i, SubKeyCell));
BOOL
-RegExportBinaryHive(PCHAR KeyName,
+RegExportBinaryHive(PCWSTR KeyName,
PCHAR ChunkBase,
- U32* ChunkSize)
+ ULONG* ChunkSize)
{
PREGISTRY_HIVE Hive;