- Add Filip Navara's cmlib
authorAleksey Bragin <aleksey@reactos.org>
Fri, 28 Jul 2006 20:25:47 +0000 (20:25 +0000)
committerAleksey Bragin <aleksey@reactos.org>
Fri, 28 Jul 2006 20:25:47 +0000 (20:25 +0000)
- Use cmlib in Freeldr and Setupldr (patch by Filip Navara)
- Fix some HIVE definition and checksum calculation in mkhive and ntoskrnl (so they btoh create a compatible registry)

TODO: Apply 2nd half of the patch, which makes ntoskrnl using cmlib.

This commit is dedicated to Filip Navara's constant promises to commit cmlib and to recent small Arty vs. Alex debate on irc :)

svn path=/trunk/; revision=23332

reactos/boot/freeldr/freeldr/freeldr.rbuild
reactos/boot/freeldr/freeldr/freeldr_base.rbuild
reactos/boot/freeldr/freeldr/include/arch/i386/hardware.h
reactos/boot/freeldr/freeldr/reactos/binhive.c
reactos/boot/freeldr/freeldr/setupldr.rbuild
reactos/lib/lib.mak
reactos/lib/lib.rbuild
reactos/ntoskrnl/cm/cm.h
reactos/ntoskrnl/cm/regfile.c
reactos/tools/mkhive/binhive.c

index 277a315..1e7ca01 100644 (file)
@@ -7,5 +7,6 @@
        <library>freeldr_main</library>
        <library>rossym</library>
        <library>string</library>
+       <library>cmlib</library>
        <library>rtl</library>
 </module>
index da916f2..0268e10 100644 (file)
@@ -1,6 +1,7 @@
 <module name="freeldr_base" type="objectlibrary">
        <include base="freeldr_base">include</include>
        <include base="freeldr_base">cache</include>
+       <include base="cmlib">.</include>
        <include base="ntoskrnl">include</include>
        <define name="__USE_W32API" />
 <!--   
index 49a39dd..0bfae9a 100644 (file)
@@ -43,7 +43,7 @@ typedef struct _CM_COMPONENT_INFORMATION
 
 /* CM_COMPONENT_INFORMATION.Flags */
 #define Failed      0x00000001
-#define ReadOnly    0x00000002
+//#define ReadOnly    0x00000002
 #define Removable   0x00000004
 #define ConsoleIn   0x00000008
 #define ConsoleOut  0x00000010
index 0cfcffc..0efd034 100644 (file)
  */
 
 #include <freeldr.h>
+#include <cmlib.h>
 
 #define NDEBUG
 #include <debug.h>
 
-#define  REG_HIVE_ID                   0x66676572 /* "regf" */
-#define  REG_BIN_ID                    0x6e696268 /* "hbin" */
-#define  REG_KEY_CELL_ID               0x6b6e
-#define  REG_HASH_TABLE_BLOCK_ID       0x666c
-#define  REG_VALUE_CELL_ID             0x6b76
-
-#define  REG_BLOCK_SIZE                4096
-#define  REG_HBIN_DATA_OFFSET          32
-#define  REG_INIT_BLOCK_LIST_SIZE      32
-#define  REG_INIT_HASH_TABLE_SIZE      3
-#define  REG_EXTEND_HASH_TABLE_SIZE    4
-#define  REG_VALUE_LIST_CELL_MULTIPLE  4
-
-
-#define ABS_VALUE(V) (((V) < 0) ? -(V) : (V))
-
-
-/* BLOCK_OFFSET = offset in file after header block */
-typedef ULONG BLOCK_OFFSET, *PBLOCK_OFFSET;
-
-/* header for registry hive file : */
-typedef struct _HIVE_HEADER
-{
-  /* Hive identifier "regf" (0x66676572) */
-  ULONG  BlockId;
-
-  /* Update counter */
-  ULONG  UpdateCounter1;
-
-  /* Update counter */
-  ULONG  UpdateCounter2;
-
-  /* When this hive file was last modified */
-  ULONGLONG  DateModified;
-
-  /* Registry format major version (1) */
-  ULONG  MajorVersion;
-
-  /* Registry format minor version (3)
-     Version 3 added fast indexes, version 5 has large value optimizations */
-  ULONG  MinorVersion;
-
-  /* Registry file type (0 - Primary, 1 - Log) */
-  ULONG  Type;
-
-  /* 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 ? */
-  ULONG  BlockSize;
-
-  /* (1?) */
-  ULONG  Unused7;
-
-  /* Name of hive file */
-  WCHAR  FileName[48];
-
-  ULONG  Reserved[99];
-
-  /* Checksum of first 0x200 bytes */
-  ULONG  Checksum;
-} __attribute__((packed)) HIVE_HEADER, *PHIVE_HEADER;
-
-
-typedef struct _BIN_HEADER
-{
-  /* Bin identifier "hbin" (0x6E696268) */
-  ULONG  HeaderId;
-
-  /* Block offset of this bin */
-  BLOCK_OFFSET  BinOffset;
-
-  /* Size in bytes, multiple of the block size (4KB) */
-  ULONG  BinSize;
-
-  ULONG  Reserved[2];
-
-  /* When this bin was last modified */
-  ULONGLONG  DateModified;
-
-  /* ? (In-memory only) */
-  ULONG  MemAlloc;
-} __attribute__((packed)) HBIN, *PHBIN;
-
-
-typedef struct _CELL_HEADER
-{
-  /* <0 if used, >0 if free */
-  LONG  CellSize;
-} __attribute__((packed)) CELL_HEADER, *PCELL_HEADER;
-
-
-typedef struct _KEY_CELL
-{
-  /* Size of this cell */
-  LONG  CellSize;
-
-  /* Key cell identifier "kn" (0x6b6e) */
-  USHORT  Id;
-
-  /* Flags */
-  USHORT  Flags;
-
-  /* Time of last flush */
-  ULONGLONG  LastWriteTime;            /* FILETIME */
-
-  /* ? */
-  ULONG  UnUsed1;
-
-  /* Block offset of parent key cell */
-  BLOCK_OFFSET  ParentKeyOffset;
-
-  /* Count of sub keys for the key in this key cell */
-  ULONG  NumberOfSubKeys;
-
-  /* ? */
-  ULONG  UnUsed2;
-
-  /* Block offset of has table for FIXME: subkeys/values? */
-  BLOCK_OFFSET  HashTableOffset;
-
-  /* ? */
-  ULONG  UnUsed3;
-
-  /* Count of values contained in this key cell */
-  ULONG  NumberOfValues;
-
-  /* Block offset of VALUE_LIST_CELL */
-  BLOCK_OFFSET  ValueListOffset;
-
-  /* Block offset of security cell */
-  BLOCK_OFFSET  SecurityKeyOffset;
-
-  /* Block offset of registry key class */
-  BLOCK_OFFSET  ClassNameOffset;
-
-  /* ? */
-  ULONG  Unused4[5];
-
-  /* Size in bytes of key name */
-  USHORT NameSize;
-
-  /* Size of class name in bytes */
-  USHORT ClassSize;
-
-  /* Name of key (not zero terminated) */
-  CHAR  Name[0];
-} __attribute__((packed)) KEY_CELL, *PKEY_CELL;
-
-
-/* KEY_CELL.Type constants */
-#define  REG_LINK_KEY_CELL_TYPE        0x10
-#define  REG_KEY_NAME_PACKED           0x20
-#define  REG_ROOT_KEY_CELL_TYPE        0x0c
-
-
-// hash record :
-// HashValue=four letters of value's name
-typedef struct _HASH_RECORD
-{
-  BLOCK_OFFSET  KeyOffset;
-  ULONG  HashValue;
-} __attribute__((packed)) HASH_RECORD, *PHASH_RECORD;
-
-
-typedef struct _HASH_TABLE_CELL
-{
-  LONG  CellSize;
-  USHORT  Id;
-  USHORT  HashTableSize;
-  HASH_RECORD  Table[0];
-} __attribute__((packed)) HASH_TABLE_CELL, *PHASH_TABLE_CELL;
-
-
-typedef struct _VALUE_LIST_CELL
-{
-  LONG  CellSize;
-  BLOCK_OFFSET  ValueOffset[0];
-} __attribute__((packed)) VALUE_LIST_CELL, *PVALUE_LIST_CELL;
-
-
-typedef struct _VALUE_CELL
-{
-  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
-  ULONG  DataType;
-  USHORT  Flags;
-  USHORT Unused1;
-  CHAR  Name[0]; /* warning : not zero terminated */
-} __attribute__((packed)) VALUE_CELL, *PVALUE_CELL;
-
-/* VALUE_CELL.Flags constants */
-#define REG_VALUE_NAME_PACKED             0x0001
-
-/* VALUE_CELL.DataSize mask constants */
-#define REG_DATA_SIZE_MASK                 0x7FFFFFFF
-#define REG_DATA_IN_OFFSET                 0x80000000
-
-
-typedef struct _DATA_CELL
-{
-  LONG  CellSize;
-  CHAR  Data[0];
-} __attribute__((packed)) DATA_CELL, *PDATA_CELL;
-
-
-typedef struct _REGISTRY_HIVE
-{
-  ULONG  FileSize;
-  PHIVE_HEADER  HiveHeader;
-  ULONG  BlockListSize;
-  PHBIN  *BlockList;
-  ULONG  FreeListSize;
-  ULONG  FreeListMax;
-  PCELL_HEADER *FreeList;
-  BLOCK_OFFSET *FreeListOffset;
-} REGISTRY_HIVE, *PREGISTRY_HIVE;
-
-
-static PVOID MbBase = NULL;
-static ULONG MbSize = 0;
-
 /* FUNCTIONS ****************************************************************/
 
-static VOID
-InitMbMemory (PVOID ChunkBase)
-{
-  MbBase = ChunkBase;
-  MbSize = 0;
-}
-
-
 static PVOID
-AllocateMbMemory (ULONG MemSize)
+CmpAllocate (ULONG Size, BOOLEAN Paged)
 {
-  PVOID CurBase;
-
-  CurBase = MbBase;
-
-  MbBase = (PVOID)((ULONG)MbBase + MemSize);
-  MbSize += MemSize;
-
-  return CurBase;
-}
-
-static VOID
-FreeMbMemory (VOID)
-{
-  MbSize = 0;
-}
-
-static ULONG
-GetMbAllocatedSize (VOID)
-{
-  return MbSize;
+  return MmAllocateMemory(Size);
 }
 
 
 static VOID
-CmiCreateDefaultHiveHeader (PHIVE_HEADER Header)
-{
-  assert(Header);
-  memset (Header, 0, REG_BLOCK_SIZE);
-  Header->BlockId = REG_HIVE_ID;
-  Header->UpdateCounter1 = 0;
-  Header->UpdateCounter2 = 0;
-  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->Checksum = 0;
-}
-
-
-static VOID
-CmiCreateDefaultBinCell (PHBIN BinCell)
-{
-  assert(BinCell);
-  memset (BinCell, 0, REG_BLOCK_SIZE);
-  BinCell->HeaderId = REG_BIN_ID;
-  BinCell->DateModified = 0ULL;
-  BinCell->BinSize = REG_BLOCK_SIZE;
-}
-
-
-static VOID
-CmiCreateDefaultRootKeyCell (PKEY_CELL RootKeyCell, PCWSTR KeyName)
-{
-  PWCHAR BaseKeyName;
-  ULONG NameSize;
-  ULONG CellSize;
-  ULONG i;
-  BOOLEAN Packable = TRUE;
-
-  assert (RootKeyCell);
-
-  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->Flags = REG_ROOT_KEY_CELL_TYPE;
-  RootKeyCell->LastWriteTime = 0ULL;
-  RootKeyCell->ParentKeyOffset = 0;
-  RootKeyCell->NumberOfSubKeys = 0;
-  RootKeyCell->HashTableOffset = -1;
-  RootKeyCell->NumberOfValues = 0;
-  RootKeyCell->ValueListOffset = -1;
-  RootKeyCell->SecurityKeyOffset = 0;
-  RootKeyCell->ClassNameOffset = -1;
-  RootKeyCell->NameSize = NameSize;
-  RootKeyCell->ClassSize = 0;
-  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 (PCWSTR KeyName)
+CmpFree (PVOID Ptr)
 {
-  PREGISTRY_HIVE Hive;
-  PCELL_HEADER FreeCell;
-  PKEY_CELL RootKeyCell;
-  PHBIN BinCell;
-
-  Hive = (PREGISTRY_HIVE) MmAllocateMemory (sizeof(REGISTRY_HIVE));
-  if (Hive == NULL)
-    {
-      return NULL;
-    }
-  memset (Hive, 0, sizeof(REGISTRY_HIVE));
-
-  DbgPrint((DPRINT_REGISTRY, "Hive %x\n", Hive));
-
-  /* Create hive beader (aka 'base block') */
-  Hive->HiveHeader = (PHIVE_HEADER) AllocateMbMemory (REG_BLOCK_SIZE);
-  if (Hive->HiveHeader == NULL)
-    {
-      MmFreeMemory (Hive);
-      return NULL;
-    }
-  CmiCreateDefaultHiveHeader(Hive->HiveHeader);
-  Hive->FileSize = REG_BLOCK_SIZE;
-
-  /* Allocate block list */
-  Hive->BlockListSize = 1;
-  Hive->BlockList = MmAllocateMemory (sizeof(PHBIN) * Hive->BlockListSize);
-  if (Hive->BlockList == NULL)
-    {
-      MmFreeMemory (Hive);
-      return NULL;
-    }
-
-  /* Allocate free cell list */
-  Hive->FreeListMax = 32;
-  Hive->FreeList = MmAllocateMemory(sizeof(PCELL_HEADER) * Hive->FreeListMax);
-  if (Hive->FreeList == NULL)
-    {
-      MmFreeMemory (Hive->BlockList);
-      MmFreeMemory (Hive);
-      return NULL;
-    }
-  Hive->FreeListOffset = MmAllocateMemory(sizeof(BLOCK_OFFSET) * Hive->FreeListMax);
-  if (Hive->FreeListOffset == NULL)
-    {
-      MmFreeMemory (Hive->FreeList);
-      MmFreeMemory (Hive->BlockList);
-      MmFreeMemory (Hive);
-      return NULL;
-    }
-
-  /* Allocate first bin */
-  Hive->BlockList[0] = (PHBIN) AllocateMbMemory (REG_BLOCK_SIZE);
-  if (Hive->BlockList[0] == NULL)
-    {
-      MmFreeMemory (Hive->FreeListOffset);
-      MmFreeMemory (Hive->FreeList);
-      MmFreeMemory (Hive->BlockList);
-      MmFreeMemory (Hive);
-      return NULL;
-    }
-  Hive->FileSize += REG_BLOCK_SIZE;
-
-  /* Init first bin */
-  BinCell = (PHBIN)Hive->BlockList[0];
-  CmiCreateDefaultBinCell(BinCell);
-  BinCell->BinOffset = 0;
-
-  /* Init root key cell */
-  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)((ULONG)RootKeyCell - RootKeyCell->CellSize);
-  FreeCell->CellSize = REG_BLOCK_SIZE - (REG_HBIN_DATA_OFFSET - RootKeyCell->CellSize);
-
-  Hive->FreeList[0] = FreeCell;
-  Hive->FreeListOffset[0] = REG_HBIN_DATA_OFFSET - RootKeyCell->CellSize;
-  Hive->FreeListSize++;
-
-  return Hive;
-}
-
-
-static VOID
-CmiCleanupHive(PREGISTRY_HIVE Hive, BOOLEAN Release)
-{
-  MmFreeMemory (Hive->FreeListOffset);
-  MmFreeMemory (Hive->FreeList);
-  MmFreeMemory (Hive->BlockList);
-  MmFreeMemory (Hive);
-
-  if (Release)
-    {
-      FreeMbMemory ();
-    }
-}
-
-
-static PHBIN
-CmiGetBin (PREGISTRY_HIVE Hive,
-          BLOCK_OFFSET BlockOffset)
-{
-  ULONG BlockIndex;
-
-  if (BlockOffset == (ULONG) -1)
-    return NULL;
-
-  BlockIndex = BlockOffset / REG_BLOCK_SIZE;
-  if (BlockIndex >= Hive->BlockListSize)
-    return NULL;
-
-  return Hive->BlockList[BlockIndex];
-}
-
-
-static BOOLEAN
-CmiMergeFree(PREGISTRY_HIVE RegistryHive,
-            PCELL_HEADER FreeBlock,
-            BLOCK_OFFSET FreeOffset)
-{
-  BLOCK_OFFSET BlockOffset;
-  BLOCK_OFFSET BinOffset;
-  ULONG BlockSize;
-  ULONG BinSize;
-  PHBIN Bin;
-  ULONG i;
-
-  DbgPrint((DPRINT_REGISTRY, "CmiMergeFree(Block %lx  Offset %lx  Size %lx) called\n",
-          FreeBlock, FreeOffset, FreeBlock->CellSize));
-
-  Bin = CmiGetBin (RegistryHive, FreeOffset);
-  if (Bin == NULL)
-    return FALSE;
-
-  DbgPrint((DPRINT_REGISTRY, "Bin %p\n", Bin));
-
-  BinOffset = Bin->BinOffset;
-  BinSize = Bin->BinSize;
-  DbgPrint((DPRINT_REGISTRY, "Bin %p  Offset %lx  Size %lx\n", Bin, BinOffset, BinSize));
-
-  for (i = 0; i < RegistryHive->FreeListSize; i++)
-    {
-      BlockOffset = RegistryHive->FreeListOffset[i];
-      BlockSize = RegistryHive->FreeList[i]->CellSize;
-      if (BlockOffset > BinOffset &&
-         BlockOffset < BinOffset + BinSize)
-       {
-         DbgPrint((DPRINT_REGISTRY, "Free block: Offset %lx  Size %lx\n",
-                  BlockOffset, BlockSize));
-
-         if ((i < (RegistryHive->FreeListSize - 1)) &&
-             (BlockOffset + BlockSize == FreeOffset) &&
-             (FreeOffset + FreeBlock->CellSize == RegistryHive->FreeListOffset[i + 1]))
-           {
-             DbgPrint((DPRINT_REGISTRY, "Merge current block with previous and next block\n"));
-
-             RegistryHive->FreeList[i]->CellSize +=
-               (FreeBlock->CellSize + RegistryHive->FreeList[i + 1]->CellSize);
-
-             FreeBlock->CellSize = 0;
-             RegistryHive->FreeList[i + 1]->CellSize = 0;
-
-
-             if ((i + 2) < RegistryHive->FreeListSize)
-               {
-                 memmove (&RegistryHive->FreeList[i + 1],
-                          &RegistryHive->FreeList[i + 2],
-                          sizeof(RegistryHive->FreeList[0])
-                            * (RegistryHive->FreeListSize - i - 2));
-                 memmove (&RegistryHive->FreeListOffset[i + 1],
-                          &RegistryHive->FreeListOffset[i + 2],
-                          sizeof(RegistryHive->FreeListOffset[0])
-                            * (RegistryHive->FreeListSize - i - 2));
-               }
-             RegistryHive->FreeListSize--;
-
-             return TRUE;
-           }
-         else if (BlockOffset + BlockSize == FreeOffset)
-           {
-             DbgPrint((DPRINT_REGISTRY, "Merge current block with previous block\n"));
-
-             RegistryHive->FreeList[i]->CellSize += FreeBlock->CellSize;
-             FreeBlock->CellSize = 0;
-
-             return TRUE;
-           }
-         else if (FreeOffset + FreeBlock->CellSize == BlockOffset)
-           {
-             DbgPrint((DPRINT_REGISTRY, "Merge current block with next block\n"));
-
-             FreeBlock->CellSize += RegistryHive->FreeList[i]->CellSize;
-             RegistryHive->FreeList[i]->CellSize = 0;
-             RegistryHive->FreeList[i] = FreeBlock;
-             RegistryHive->FreeListOffset[i] = FreeOffset;
-
-             return TRUE;
-           }
-       }
-    }
-
-  return FALSE;
-}
-
-
-static BOOLEAN
-CmiAddFree(PREGISTRY_HIVE RegistryHive,
-          PCELL_HEADER FreeBlock,
-          BLOCK_OFFSET FreeOffset,
-          BOOLEAN MergeFreeBlocks)
-{
-  PCELL_HEADER *tmpList;
-  BLOCK_OFFSET *tmpListOffset;
-  LONG minInd;
-  LONG maxInd;
-  LONG medInd;
-
-  assert(RegistryHive);
-  assert(FreeBlock);
-
-  DbgPrint((DPRINT_REGISTRY, "FreeBlock %.08lx  FreeOffset %.08lx\n",
-          FreeBlock, FreeOffset));
-
-  /* Merge free blocks */
-  if (MergeFreeBlocks == TRUE)
-    {
-      if (CmiMergeFree(RegistryHive, FreeBlock, FreeOffset))
-       return TRUE;
-    }
-
-  if ((RegistryHive->FreeListSize + 1) > RegistryHive->FreeListMax)
-    {
-      tmpList = MmAllocateMemory (sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax + 32));
-      if (tmpList == NULL)
-       {
-         return FALSE;
-       }
-
-      tmpListOffset = MmAllocateMemory (sizeof(BLOCK_OFFSET) * (RegistryHive->FreeListMax + 32));
-      if (tmpListOffset == NULL)
-       {
-         MmFreeMemory (tmpList);
-         return FALSE;
-       }
-
-      if (RegistryHive->FreeListMax)
-       {
-         memmove (tmpList,
-                  RegistryHive->FreeList,
-                  sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax));
-         memmove (tmpListOffset,
-                  RegistryHive->FreeListOffset,
-                  sizeof(BLOCK_OFFSET) * (RegistryHive->FreeListMax));
-         MmFreeMemory (RegistryHive->FreeList);
-         MmFreeMemory (RegistryHive->FreeListOffset);
-       }
-      RegistryHive->FreeList = tmpList;
-      RegistryHive->FreeListOffset = tmpListOffset;
-      RegistryHive->FreeListMax += 32;
-    }
-
-  /* Add new offset to free list, maintaining list in ascending order */
-  if ((RegistryHive->FreeListSize == 0)
-     || (RegistryHive->FreeListOffset[RegistryHive->FreeListSize-1] < FreeOffset))
-    {
-      /* Add to end of list */
-      RegistryHive->FreeList[RegistryHive->FreeListSize] = FreeBlock;
-      RegistryHive->FreeListOffset[RegistryHive->FreeListSize++] = FreeOffset;
-    }
-  else if (RegistryHive->FreeListOffset[0] > FreeOffset)
-    {
-      /* Add to begin of list */
-      memmove (&RegistryHive->FreeList[1],
-              &RegistryHive->FreeList[0],
-              sizeof(RegistryHive->FreeList[0]) * RegistryHive->FreeListSize);
-      memmove (&RegistryHive->FreeListOffset[1],
-              &RegistryHive->FreeListOffset[0],
-              sizeof(RegistryHive->FreeListOffset[0]) * RegistryHive->FreeListSize);
-      RegistryHive->FreeList[0] = FreeBlock;
-      RegistryHive->FreeListOffset[0] = FreeOffset;
-      RegistryHive->FreeListSize++;
-    }
-  else
-    {
-      /* Search where to insert */
-      minInd = 0;
-      maxInd = RegistryHive->FreeListSize - 1;
-      while ((maxInd - minInd) > 1)
-       {
-         medInd = (minInd + maxInd) / 2;
-         if (RegistryHive->FreeListOffset[medInd] > FreeOffset)
-           maxInd = medInd;
-         else
-           minInd = medInd;
-       }
-
-      /* Insert before maxInd */
-      memmove (&RegistryHive->FreeList[maxInd+1],
-              &RegistryHive->FreeList[maxInd],
-              sizeof(RegistryHive->FreeList[0]) * (RegistryHive->FreeListSize - minInd));
-      memmove (&RegistryHive->FreeListOffset[maxInd + 1],
-              &RegistryHive->FreeListOffset[maxInd],
-              sizeof(RegistryHive->FreeListOffset[0]) * (RegistryHive->FreeListSize-minInd));
-      RegistryHive->FreeList[maxInd] = FreeBlock;
-      RegistryHive->FreeListOffset[maxInd] = FreeOffset;
-      RegistryHive->FreeListSize++;
-    }
-
-  return TRUE;
-}
-
-
-static BOOLEAN
-CmiAddBin(PREGISTRY_HIVE RegistryHive,
-         ULONG BlockCount,
-         PVOID *NewBlock,
-         PBLOCK_OFFSET NewBlockOffset)
-{
-  PCELL_HEADER tmpBlock;
-  PHBIN *BlockList;
-  PHBIN tmpBin;
-  ULONG BinSize;
-  ULONG i;
-
-  BinSize = BlockCount * REG_BLOCK_SIZE;
-  tmpBin = AllocateMbMemory (BinSize);
-  if (tmpBin == NULL)
-    {
-      return FALSE;
-    }
-  memset (tmpBin, 0, BinSize);
-
-  tmpBin->HeaderId = REG_BIN_ID;
-  tmpBin->BinOffset = RegistryHive->FileSize - REG_BLOCK_SIZE;
-  RegistryHive->FileSize += BinSize;
-  tmpBin->BinSize = BinSize;
-  tmpBin->DateModified = 0ULL;
-  tmpBin->MemAlloc = 0;
-
-  /* Increase size of list of blocks */
-  BlockList = MmAllocateMemory (sizeof(PHBIN) * (RegistryHive->BlockListSize + BlockCount));
-  if (BlockList == NULL)
-    {
-      return FALSE;
-    }
-
-  if (RegistryHive->BlockListSize > 0)
-    {
-      memcpy (BlockList,
-             RegistryHive->BlockList,
-             sizeof(PHBIN) * RegistryHive->BlockListSize);
-      MmFreeMemory (RegistryHive->BlockList);
-    }
-
-  RegistryHive->BlockList = BlockList;
-  for (i = 0; i < BlockCount; i++)
-    RegistryHive->BlockList[RegistryHive->BlockListSize + i] = tmpBin;
-  RegistryHive->BlockListSize += BlockCount;
-
-  /* Initialize a free block in this heap : */
-  tmpBlock = (PCELL_HEADER)((ULONG) tmpBin + REG_HBIN_DATA_OFFSET);
-  tmpBlock->CellSize = (REG_BLOCK_SIZE - REG_HBIN_DATA_OFFSET);
-
-  *NewBlock = (PVOID) tmpBlock;
-
-  if (NewBlockOffset)
-    *NewBlockOffset = tmpBin->BinOffset + REG_HBIN_DATA_OFFSET;
-
-  return TRUE;
-}
-
-
-static BOOLEAN
-CmiAllocateCell (PREGISTRY_HIVE RegistryHive,
-                LONG CellSize,
-                PVOID *Block,
-                PBLOCK_OFFSET pBlockOffset)
-{
-  PCELL_HEADER NewBlock;
-  ULONG i;
-
-  *Block = NULL;
-
-  /* Round to 16 bytes multiple */
-  CellSize = ROUND_UP(CellSize, 16);
-
-  /* first search in free blocks */
-  NewBlock = NULL;
-  for (i = 0; i < RegistryHive->FreeListSize; i++)
-    {
-      if (RegistryHive->FreeList[i]->CellSize >= CellSize)
-       {
-         NewBlock = RegistryHive->FreeList[i];
-         if (pBlockOffset)
-           *pBlockOffset = RegistryHive->FreeListOffset[i];
-
-         if ((i + 1) < RegistryHive->FreeListSize)
-           {
-             memmove (&RegistryHive->FreeList[i],
-                      &RegistryHive->FreeList[i + 1],
-                      sizeof(RegistryHive->FreeList[0])
-                        * (RegistryHive->FreeListSize - i - 1));
-             memmove (&RegistryHive->FreeListOffset[i],
-                      &RegistryHive->FreeListOffset[i + 1],
-                      sizeof(RegistryHive->FreeListOffset[0])
-                        * (RegistryHive->FreeListSize - i - 1));
-           }
-         RegistryHive->FreeListSize--;
-         break;
-       }
-    }
-
-  /* Need to extend hive file */
-  if (NewBlock == NULL)
-    {
-      /* Add a new block */
-      if (!CmiAddBin(RegistryHive,
-                    ((sizeof(HBIN) + CellSize - 1) / REG_BLOCK_SIZE) + 1,
-                    (PVOID *)(PVOID)&NewBlock,
-                    pBlockOffset))
-       return FALSE;
-    }
-
-  *Block = NewBlock;
-
-  /* Split the block in two parts */
-  if (NewBlock->CellSize > CellSize)
-    {
-      NewBlock = (PCELL_HEADER) ((ULONG)NewBlock + CellSize);
-      NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - CellSize;
-      CmiAddFree (RegistryHive,
-                 NewBlock,
-                 *pBlockOffset + CellSize,
-                 TRUE);
-    }
-  else if (NewBlock->CellSize < CellSize)
-    {
-      return FALSE;
-    }
-
-  memset(*Block, 0, CellSize);
-  ((PCELL_HEADER)(*Block))->CellSize = -CellSize;
-
-  return TRUE;
-}
-
-
-static PVOID
-CmiGetCell (PREGISTRY_HIVE Hive,
-           BLOCK_OFFSET BlockOffset)
-{
-  PHBIN Bin;
-  ULONG BlockIndex;
-
-  if (BlockOffset == (ULONG) -1)
-    return NULL;
-
-  BlockIndex = BlockOffset / REG_BLOCK_SIZE;
-  if (BlockIndex >= Hive->BlockListSize)
-    return NULL;
-
-  Bin = Hive->BlockList[BlockIndex];
-  if (Bin == NULL)
-    return NULL;
-
-  return (PVOID)((ULONG)Bin + (BlockOffset - Bin->BinOffset));
+  return MmFreeMemory(Ptr);
 }
 
 
 static BOOLEAN
 CmiAllocateHashTableCell (PREGISTRY_HIVE Hive,
-                         PBLOCK_OFFSET HBOffset,
+                         PHCELL_INDEX HBOffset,
                          ULONG SubKeyCount)
 {
   PHASH_TABLE_CELL HashCell;
   ULONG NewHashSize;
-  BOOLEAN Status;
 
   NewHashSize = sizeof(HASH_TABLE_CELL) +
                (SubKeyCount * sizeof(HASH_RECORD));
-  Status = CmiAllocateCell (Hive,
-                           NewHashSize,
-                           (PVOID*)(PVOID)&HashCell,
-                           HBOffset);
-  if ((HashCell == NULL) || (Status == FALSE))
+  *HBOffset = HvAllocateCell (Hive, NewHashSize, HvStable);
+  if (*HBOffset == HCELL_NULL)
     {
       return FALSE;
     }
 
-  HashCell->Id = REG_HASH_TABLE_BLOCK_ID;
+  HashCell = HvGetCell (Hive, *HBOffset);
+  HashCell->Id = REG_HASH_TABLE_CELL_ID;
   HashCell->HashTableSize = SubKeyCount;
 
   return TRUE;
@@ -877,27 +67,16 @@ CmiAllocateHashTableCell (PREGISTRY_HIVE Hive,
 
 static BOOLEAN
 CmiAddKeyToParentHashTable (PREGISTRY_HIVE Hive,
-                           BLOCK_OFFSET ParentKeyOffset,
+                           HCELL_INDEX ParentKeyOffset,
                            PKEY_CELL NewKeyCell,
-                           BLOCK_OFFSET NKBOffset)
+                           HCELL_INDEX NKBOffset)
 {
   PHASH_TABLE_CELL HashBlock;
   PKEY_CELL ParentKeyCell;
   ULONG i;
 
-  ParentKeyCell = CmiGetCell (Hive, ParentKeyOffset);
-  if (ParentKeyCell == NULL)
-    {
-      DbgPrint((DPRINT_REGISTRY, "CmiGetCell() failed\n"));
-      return FALSE;
-    }
-
-  HashBlock =CmiGetCell (Hive, ParentKeyCell->HashTableOffset);
-  if (HashBlock == NULL)
-    {
-      DbgPrint((DPRINT_REGISTRY, "CmiGetCell() failed\n"));
-      return FALSE;
-    }
+  ParentKeyCell = HvGetCell (Hive, ParentKeyOffset);
+  HashBlock = HvGetCell (Hive, ParentKeyCell->HashTableOffset[HvStable]);
 
   for (i = 0; i < HashBlock->HashTableSize; i++)
     {
@@ -907,7 +86,7 @@ CmiAddKeyToParentHashTable (PREGISTRY_HIVE Hive,
          memcpy (&HashBlock->Table[i].HashValue,
                  NewKeyCell->Name,
                  min(NewKeyCell->NameSize, sizeof(ULONG)));
-         ParentKeyCell->NumberOfSubKeys++;
+         ParentKeyCell->NumberOfSubKeys[HvStable]++;
          return TRUE;
        }
     }
@@ -918,22 +97,17 @@ CmiAddKeyToParentHashTable (PREGISTRY_HIVE Hive,
 
 static BOOLEAN
 CmiAllocateValueListCell (PREGISTRY_HIVE Hive,
-                         PBLOCK_OFFSET ValueListOffset,
+                         PHCELL_INDEX ValueListOffset,
                          ULONG ValueCount)
 {
-  PVALUE_LIST_CELL ValueListCell;
   ULONG ValueListSize;
-  BOOLEAN Status;
 
   ValueListSize = sizeof(VALUE_LIST_CELL) +
-                 (ValueCount * sizeof(BLOCK_OFFSET));
-  Status = CmiAllocateCell (Hive,
-                           ValueListSize,
-                           (PVOID)&ValueListCell,
-                           ValueListOffset);
-  if ((ValueListCell == NULL) || (Status == FALSE))
+                 (ValueCount * sizeof(HCELL_INDEX));
+  *ValueListOffset = HvAllocateCell (Hive, ValueListSize, HvStable);
+  if (*ValueListOffset == HCELL_NULL)
     {
-      DbgPrint((DPRINT_REGISTRY, "CmiAllocateCell() failed\n"));
+      DbgPrint((DPRINT_REGISTRY, "HvAllocateCell() failed\n"));
       return FALSE;
     }
 
@@ -944,12 +118,11 @@ CmiAllocateValueListCell (PREGISTRY_HIVE Hive,
 static BOOLEAN
 CmiAllocateValueCell(PREGISTRY_HIVE Hive,
                     PVALUE_CELL *ValueCell,
-                    BLOCK_OFFSET *ValueCellOffset,
+                    HCELL_INDEX *ValueCellOffset,
                     PWCHAR ValueName)
 {
   PVALUE_CELL NewValueCell;
   ULONG NameSize;
-  BOOLEAN Status;
   BOOLEAN Packable = TRUE;
   ULONG i;
 
@@ -963,16 +136,14 @@ CmiAllocateValueCell(PREGISTRY_HIVE Hive,
           break;
         }
     }
-  Status = CmiAllocateCell (Hive,
-                           sizeof(VALUE_CELL) + NameSize,
-                           (PVOID*)(PVOID)&NewValueCell,
-                           ValueCellOffset);
-  if ((NewValueCell == NULL) || (Status == FALSE))
+  *ValueCellOffset = HvAllocateCell (Hive, sizeof(VALUE_CELL) + NameSize, HvStable);
+  if (*ValueCellOffset == HCELL_NULL)
     {
       DbgPrint((DPRINT_REGISTRY, "CmiAllocateCell() failed\n"));
       return FALSE;
     }
 
+  NewValueCell = (PVALUE_CELL) HvGetCell (Hive, *ValueCellOffset);
   NewValueCell->Id = REG_VALUE_CELL_ID;
   NewValueCell->NameSize = NameSize;
   NewValueCell->Flags = 0;
@@ -1005,23 +176,23 @@ CmiAllocateValueCell(PREGISTRY_HIVE Hive,
 
 static BOOLEAN
 CmiAddValueToKeyValueList(PREGISTRY_HIVE Hive,
-                         BLOCK_OFFSET KeyCellOffset,
-                         BLOCK_OFFSET ValueCellOffset)
+                         HCELL_INDEX KeyCellOffset,
+                         HCELL_INDEX ValueCellOffset)
 {
   PVALUE_LIST_CELL ValueListCell;
   PKEY_CELL KeyCell;
 
-  KeyCell = CmiGetCell (Hive, KeyCellOffset);
+  KeyCell = HvGetCell (Hive, KeyCellOffset);
   if (KeyCell == NULL)
     {
-      DbgPrint((DPRINT_REGISTRY, "CmiGetCell() failed\n"));
+      DbgPrint((DPRINT_REGISTRY, "HvGetCell() failed\n"));
       return FALSE;
     }
 
-  ValueListCell = CmiGetCell (Hive, KeyCell->ValueListOffset);
+  ValueListCell = HvGetCell (Hive, KeyCell->ValueListOffset);
   if (ValueListCell == NULL)
     {
-      DbgPrint((DPRINT_REGISTRY, "CmiGetCell() failed\n"));
+      DbgPrint((DPRINT_REGISTRY, "HvGetCell() failed\n"));
       return FALSE;
     }
 
@@ -1033,14 +204,14 @@ CmiAddValueToKeyValueList(PREGISTRY_HIVE Hive,
 
 static BOOLEAN
 CmiExportValue (PREGISTRY_HIVE Hive,
-               BLOCK_OFFSET KeyCellOffset,
+               HCELL_INDEX KeyCellOffset,
                FRLDRHKEY Key,
                PVALUE Value)
 {
-  BLOCK_OFFSET ValueCellOffset;
-  BLOCK_OFFSET DataCellOffset;
+  HCELL_INDEX ValueCellOffset;
+  HCELL_INDEX DataCellOffset;
   PVALUE_CELL ValueCell;
-  PDATA_CELL DataCell;
+  PVOID DataCell;
   ULONG DataSize;
   ULONG DataType;
   PCHAR Data;
@@ -1074,7 +245,7 @@ CmiExportValue (PREGISTRY_HIVE Hive,
       Data = Value->Data;
     }
 
-  if (DataSize <= sizeof(BLOCK_OFFSET))
+  if (DataSize <= sizeof(HCELL_INDEX))
     {
       ValueCell->DataSize = DataSize | REG_DATA_IN_OFFSET;
       ValueCell->DataType = DataType;
@@ -1085,10 +256,8 @@ CmiExportValue (PREGISTRY_HIVE Hive,
   else
     {
       /* Allocate data cell */
-      if (!CmiAllocateCell (Hive,
-                           sizeof(CELL_HEADER) + DataSize,
-                           (PVOID *)(PVOID)&DataCell,
-                           &DataCellOffset))
+      DataCellOffset = HvAllocateCell (Hive, DataSize, HvStable);
+      if (DataCellOffset == HCELL_NULL)
        {
          return FALSE;
        }
@@ -1097,7 +266,8 @@ CmiExportValue (PREGISTRY_HIVE Hive,
       ValueCell->DataSize = DataSize;
       ValueCell->DataType = DataType;
 
-      memcpy (DataCell->Data,
+      DataCell = HvGetCell (Hive, DataCellOffset);
+      memcpy (DataCell,
              Data,
              DataSize);
     }
@@ -1108,11 +278,11 @@ CmiExportValue (PREGISTRY_HIVE Hive,
 
 static BOOLEAN
 CmiExportSubKey (PREGISTRY_HIVE Hive,
-                BLOCK_OFFSET ParentKeyOffset,
+                HCELL_INDEX ParentKeyOffset,
                 FRLDRHKEY ParentKey,
                 FRLDRHKEY Key)
 {
-  BLOCK_OFFSET NKBOffset;
+  HCELL_INDEX NKBOffset;
   PKEY_CELL NewKeyCell;
   ULONG KeyCellSize;
   ULONG SubKeyCount;
@@ -1143,19 +313,21 @@ CmiExportSubKey (PREGISTRY_HIVE Hive,
           
   /* Allocate key cell */
   KeyCellSize = sizeof(KEY_CELL) + NameSize;
-  if (!CmiAllocateCell (Hive, KeyCellSize, (PVOID)&NewKeyCell, &NKBOffset))
+  NKBOffset = HvAllocateCell (Hive, KeyCellSize, HvStable);
+  if (NKBOffset == HCELL_NULL)
     {
-      DbgPrint((DPRINT_REGISTRY, "CmiAllocateCell() failed\n"));
+      DbgPrint((DPRINT_REGISTRY, "HvAllocateCell() failed\n"));
       return FALSE;
     }
 
   /* Initialize key cell */
+  NewKeyCell = (PKEY_CELL) HvGetCell (Hive, NKBOffset);
   NewKeyCell->Id = REG_KEY_CELL_ID;
   NewKeyCell->Flags = 0;
-  NewKeyCell->LastWriteTime = 0ULL;
+  NewKeyCell->LastWriteTime.QuadPart = 0ULL;
   NewKeyCell->ParentKeyOffset = ParentKeyOffset;
-  NewKeyCell->NumberOfSubKeys = 0;
-  NewKeyCell->HashTableOffset = -1;
+  NewKeyCell->NumberOfSubKeys[HvStable] = 0;
+  NewKeyCell->HashTableOffset[HvStable] = -1;
   NewKeyCell->NumberOfValues = 0;
   NewKeyCell->ValueListOffset = -1;
   NewKeyCell->SecurityKeyOffset = -1;
@@ -1228,7 +400,7 @@ CmiExportSubKey (PREGISTRY_HIVE Hive,
     {
       /* Allocate hash table cell */
       if (!CmiAllocateHashTableCell (Hive,
-                                    &NewKeyCell->HashTableOffset,
+                                    &NewKeyCell->HashTableOffset[HvStable],
                                     SubKeyCount))
        {
          DbgPrint((DPRINT_REGISTRY, "CmiAllocateHashTableCell() failed\n"));
@@ -1254,22 +426,6 @@ CmiExportSubKey (PREGISTRY_HIVE Hive,
 }
 
 
-static VOID
-CmiCalcHiveChecksum (PREGISTRY_HIVE Hive)
-{
-  ULONG *Buffer;
-  ULONG Sum;
-  ULONG i;
-
-  Buffer = (ULONG*)Hive->HiveHeader;
-  Sum = 0;
-  for (i = 0; i < 127; i++)
-    Sum += Buffer[i];
-
-  Hive->HiveHeader->Checksum = Sum;
-}
-
-
 static BOOLEAN
 CmiExportHive (PREGISTRY_HIVE Hive,
               PCWSTR KeyName)
@@ -1290,10 +446,10 @@ CmiExportHive (PREGISTRY_HIVE Hive,
       return FALSE;
     }
 
-  KeyCell = CmiGetCell (Hive, Hive->HiveHeader->RootKeyOffset);
+  KeyCell = HvGetCell (Hive, Hive->HiveHeader->RootCell);
   if (KeyCell == NULL)
     {
-      DbgPrint((DPRINT_REGISTRY, "CmiGetBlock() failed\n"));
+      DbgPrint((DPRINT_REGISTRY, "HvGetCell() failed\n"));
       return FALSE;
     }
 
@@ -1312,7 +468,7 @@ CmiExportHive (PREGISTRY_HIVE Hive,
 
       if (Key->DataSize != 0)
        {
-         if (!CmiExportValue (Hive, Hive->HiveHeader->RootKeyOffset, Key, NULL))
+         if (!CmiExportValue (Hive, Hive->HiveHeader->RootCell, Key, NULL))
            return FALSE;
        }
 
@@ -1324,7 +480,7 @@ CmiExportHive (PREGISTRY_HIVE Hive,
                                    VALUE,
                                    ValueList);
 
-         if (!CmiExportValue (Hive, Hive->HiveHeader->RootKeyOffset, Key, Value))
+         if (!CmiExportValue (Hive, Hive->HiveHeader->RootCell, Key, Value))
            return FALSE;
 
          Entry = Entry->Flink;
@@ -1337,7 +493,7 @@ CmiExportHive (PREGISTRY_HIVE Hive,
     {
       /* Allocate hash table cell */
       if (!CmiAllocateHashTableCell (Hive,
-                                    &KeyCell->HashTableOffset,
+                                    &KeyCell->HashTableOffset[HvStable],
                                     SubKeyCount))
        {
          DbgPrint((DPRINT_REGISTRY, "CmiAllocateHashTableCell() failed\n"));
@@ -1352,31 +508,29 @@ CmiExportHive (PREGISTRY_HIVE Hive,
                                     KEY,
                                     KeyList);
 
-         if (!CmiExportSubKey (Hive, Hive->HiveHeader->RootKeyOffset, Key, SubKey))
+         if (!CmiExportSubKey (Hive, Hive->HiveHeader->RootCell, Key, SubKey))
            return FALSE;
 
          Entry = Entry->Flink;
        }
     }
 
-  CmiCalcHiveChecksum (Hive);
-
   return TRUE;
 }
 
 
 static BOOLEAN
-RegImportValue (PHBIN RootBin,
+RegImportValue (PREGISTRY_HIVE Hive,
                PVALUE_CELL ValueCell,
                FRLDRHKEY Key)
 {
-  PDATA_CELL DataCell;
+  PVOID DataCell;
   PWCHAR wName;
   LONG Error;
   ULONG DataSize;
   ULONG i;
 
-  if (ValueCell->CellSize >= 0 || ValueCell->Id != REG_VALUE_CELL_ID)
+  if (ValueCell->Id != REG_VALUE_CELL_ID)
     {
       DbgPrint((DPRINT_REGISTRY, "Invalid key cell!\n"));
       return FALSE;
@@ -1405,7 +559,7 @@ RegImportValue (PHBIN RootBin,
   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))
+  if (DataSize <= sizeof(HCELL_INDEX) && (ValueCell->DataSize & REG_DATA_IN_OFFSET))
     {
       Error = RegSetValue(Key,
                          wName,
@@ -1421,20 +575,13 @@ RegImportValue (PHBIN RootBin,
     }
   else
     {
-      DataCell = (PDATA_CELL)((PUCHAR)RootBin + ValueCell->DataOffset);
+      DataCell = HvGetCell (Hive, ValueCell->DataOffset);
       DbgPrint((DPRINT_REGISTRY, "DataCell: %x\n", DataCell));
 
-      if (DataCell->CellSize >= 0)
-       {
-         DbgPrint((DPRINT_REGISTRY, "Invalid data cell size!\n"));
-         MmFreeMemory (wName);
-         return FALSE;
-       }
-
       Error = RegSetValue (Key,
                           wName,
                           ValueCell->DataType,
-                          DataCell->Data,
+                          DataCell,
                           DataSize);
        
       if (Error != ERROR_SUCCESS)
@@ -1452,7 +599,7 @@ RegImportValue (PHBIN RootBin,
 
 
 static BOOLEAN
-RegImportSubKey(PHBIN RootBin,
+RegImportSubKey(PREGISTRY_HIVE Hive,
                PKEY_CELL KeyCell,
                FRLDRHKEY ParentKey)
 {
@@ -1467,9 +614,8 @@ RegImportSubKey(PHBIN RootBin,
 
 
   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));
-  if (KeyCell->Id != REG_KEY_CELL_ID || KeyCell->CellSize >= 0)
+  if (KeyCell->Id != REG_KEY_CELL_ID)
     {
       DbgPrint((DPRINT_REGISTRY, "Invalid key cell id!\n"));
       return FALSE;
@@ -1511,37 +657,38 @@ RegImportSubKey(PHBIN RootBin,
   /* Enumerate and add values */
   if (KeyCell->NumberOfValues > 0)
     {
-      ValueListCell = (PVALUE_LIST_CELL)((PUCHAR)RootBin + KeyCell->ValueListOffset);
+      ValueListCell = (PVALUE_LIST_CELL) HvGetCell (Hive, KeyCell->ValueListOffset);
       DbgPrint((DPRINT_REGISTRY, "ValueListCell: %x\n", ValueListCell));
 
       for (i = 0; i < KeyCell->NumberOfValues; i++)
        {
          DbgPrint((DPRINT_REGISTRY, "ValueOffset[%d]: %x\n", i, ValueListCell->ValueOffset[i]));
 
-         ValueCell = (PVALUE_CELL)((PUCHAR)RootBin + ValueListCell->ValueOffset[i]);
+         ValueCell = (PVALUE_CELL) HvGetCell (Hive, ValueListCell->ValueOffset[i]);
 
          DbgPrint((DPRINT_REGISTRY, "ValueCell[%d]: %x\n", i, ValueCell));
 
-         if (!RegImportValue(RootBin, ValueCell, SubKey))
+         if (!RegImportValue(Hive, ValueCell, SubKey))
            return FALSE;
        }
     }
 
   /* Enumerate and add subkeys */
-  if (KeyCell->NumberOfSubKeys > 0)
+  if (KeyCell->NumberOfSubKeys[HvStable] > 0)
     {
-      HashCell = (PHASH_TABLE_CELL)((PUCHAR)RootBin + KeyCell->HashTableOffset);
+      HashCell = (PHASH_TABLE_CELL) HvGetCell (Hive, KeyCell->HashTableOffset[HvStable]);
       DbgPrint((DPRINT_REGISTRY, "HashCell: %x\n", HashCell));
+      DbgPrint((DPRINT_REGISTRY, "NumberOfSubKeys: %x\n", KeyCell->NumberOfSubKeys));
 
-      for (i = 0; i < KeyCell->NumberOfSubKeys; i++)
+      for (i = 0; i < KeyCell->NumberOfSubKeys[HvStable]; i++)
        {
          DbgPrint((DPRINT_REGISTRY, "KeyOffset[%d]: %x\n", i, HashCell->Table[i].KeyOffset));
 
-         SubKeyCell = (PKEY_CELL)((PUCHAR)RootBin + HashCell->Table[i].KeyOffset);
+         SubKeyCell = (PKEY_CELL) HvGetCell (Hive, HashCell->Table[i].KeyOffset);
 
          DbgPrint((DPRINT_REGISTRY, "SubKeyCell[%d]: %x\n", i, SubKeyCell));
 
-         if (!RegImportSubKey(RootBin, SubKeyCell, SubKey))
+         if (!RegImportSubKey(Hive, SubKeyCell, SubKey))
            return FALSE;
        }
     }
@@ -1554,38 +701,31 @@ BOOLEAN
 RegImportBinaryHive(PCHAR ChunkBase,
                    ULONG ChunkSize)
 {
-  PHIVE_HEADER HiveHeader;
-  PHBIN RootBin;
   PKEY_CELL KeyCell;
   PHASH_TABLE_CELL HashCell;
   PKEY_CELL SubKeyCell;
   FRLDRHKEY SystemKey;
   ULONG i;
   LONG Error;
+  PREGISTRY_HIVE Hive;
+  NTSTATUS Status;
 
   DbgPrint((DPRINT_REGISTRY, "RegImportBinaryHive(%x, %u) called\n",ChunkBase,ChunkSize));
 
-  HiveHeader = (PHIVE_HEADER)ChunkBase;
-  DbgPrint((DPRINT_REGISTRY, "HiveHeader: %x\n", HiveHeader));
-  if (HiveHeader->BlockId != REG_HIVE_ID)
+  Status = HvInitialize (&Hive, HV_OPERATION_MEMORY_INPLACE,
+                         (ULONG_PTR)ChunkBase, ChunkSize,
+                         CmpAllocate, CmpFree,
+                         NULL, NULL, NULL, NULL, NULL);
+  if (!NT_SUCCESS(Status))
     {
       DbgPrint((DPRINT_REGISTRY, "Invalid hive id!\n"));
       return FALSE;
     }
 
-  RootBin = (PHBIN)((ULONG)HiveHeader + REG_BLOCK_SIZE);
-  DbgPrint((DPRINT_REGISTRY, "RootBin: %x\n", RootBin));
-  if (RootBin->HeaderId != REG_BIN_ID || RootBin->BinSize == 0)
-    {
-      DbgPrint((DPRINT_REGISTRY, "Invalid bin id!\n"));
-      return FALSE;
-    }
-
-  KeyCell = (PKEY_CELL)((ULONG)RootBin + REG_HBIN_DATA_OFFSET);
+  KeyCell = HvGetCell (Hive, Hive->HiveHeader->RootCell);
   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));
-  if (KeyCell->Id != REG_KEY_CELL_ID || KeyCell->CellSize >= 0)
+  if (KeyCell->Id != REG_KEY_CELL_ID)
     {
       DbgPrint((DPRINT_REGISTRY, "Invalid key cell id!\n"));
       return FALSE;
@@ -1605,20 +745,21 @@ RegImportBinaryHive(PCHAR ChunkBase,
     }
 
   /* Enumerate and add subkeys */
-  if (KeyCell->NumberOfSubKeys > 0)
+  if (KeyCell->NumberOfSubKeys[HvStable] > 0)
     {
-      HashCell = (PHASH_TABLE_CELL)((ULONG)RootBin + KeyCell->HashTableOffset);
+      HashCell = HvGetCell (Hive, KeyCell->HashTableOffset[HvStable]);
       DbgPrint((DPRINT_REGISTRY, "HashCell: %x\n", HashCell));
+      DbgPrint((DPRINT_REGISTRY, "NumberOfSubKeys: %x\n", KeyCell->NumberOfSubKeys[HvStable]));
 
-      for (i = 0; i < KeyCell->NumberOfSubKeys; i++)
+      for (i = 0; i < KeyCell->NumberOfSubKeys[HvStable]; i++)
        {
          DbgPrint((DPRINT_REGISTRY, "KeyOffset[%d]: %x\n", i, HashCell->Table[i].KeyOffset));
 
-         SubKeyCell = (PKEY_CELL)((ULONG)RootBin + HashCell->Table[i].KeyOffset);
+         SubKeyCell = HvGetCell (Hive, HashCell->Table[i].KeyOffset);
 
          DbgPrint((DPRINT_REGISTRY, "SubKeyCell[%d]: %x\n", i, SubKeyCell));
 
-         if (!RegImportSubKey(RootBin, SubKeyCell, SystemKey))
+         if (!RegImportSubKey(Hive, SubKeyCell, SystemKey))
            return FALSE;
        }
     }
@@ -1627,31 +768,70 @@ RegImportBinaryHive(PCHAR ChunkBase,
 }
 
 
+static VOID
+CmiWriteHive(PREGISTRY_HIVE Hive,
+             PCHAR ChunkBase,
+             ULONG* ChunkSize)
+{
+  PHBIN Bin;
+  ULONG i, Size;
+
+  /* Write hive header */
+  memcpy (ChunkBase, Hive->HiveHeader, HV_BLOCK_SIZE);
+  Size = HV_BLOCK_SIZE;
+
+  Bin = NULL;
+  for (i = 0; i < Hive->Storage[HvStable].BlockListSize; i++)
+    {
+      if (Hive->Storage[HvStable].BlockList[i].Bin != Bin)
+       {
+         Bin = Hive->Storage[HvStable].BlockList[i].Bin;
+         memcpy (ChunkBase + (i + 1) * HV_BLOCK_SIZE,
+                 Bin, Bin->BinSize);
+         Size += Bin->BinSize;
+       }
+    }
+
+  DbgPrint((DPRINT_REGISTRY, "ChunkSize: %x\n", Size));
+
+  *ChunkSize = Size;
+}
+
+
 BOOLEAN
 RegExportBinaryHive(PCWSTR KeyName,
                    PCHAR ChunkBase,
                    ULONG* ChunkSize)
 {
   PREGISTRY_HIVE Hive;
+  NTSTATUS Status;
 
   DbgPrint((DPRINT_REGISTRY, "Creating binary hardware hive\n"));
 
-  *ChunkSize = 0;
-  InitMbMemory (ChunkBase);
+  Status = HvInitialize (&Hive, HV_OPERATION_CREATE_HIVE, 0, 0,
+                         CmpAllocate, CmpFree,
+                         NULL, NULL, NULL, NULL, NULL);
+  if (!NT_SUCCESS(Status))
+    {
+      return FALSE;
+    }
 
-  Hive = CmiCreateHive (KeyName);
-  if (Hive == NULL)
-    return FALSE;
+  /* Init root key cell */
+  if (!CmCreateRootNode (Hive, KeyName))
+    {
+      HvFree (Hive);
+      return FALSE;
+    }
 
   if (!CmiExportHive (Hive, KeyName))
     {
-      CmiCleanupHive (Hive, TRUE);
+      HvFree (Hive);
       return FALSE;
     }
 
-  CmiCleanupHive (Hive, FALSE);
+  CmiWriteHive (Hive, ChunkBase, ChunkSize);
 
-  *ChunkSize = GetMbAllocatedSize ();
+  HvFree (Hive);
 
   return TRUE;
 }
index ef5fb71..aacbbf6 100644 (file)
@@ -7,5 +7,6 @@
        <library>setupldr_main</library>
        <library>rossym</library>
        <library>string</library>
+       <library>cmlib</library>
        <library>rtl</library>
 </module>
index ddf02e6..e0e7b9e 100644 (file)
@@ -3,3 +3,4 @@ LIB_BASE_ = $(LIB_BASE)$(SEP)
 
 include lib/inflib/inflib.mak
 include lib/3rdparty/zlib/zlib.mak
+include lib/cmlib/cmlib.mak
index 0fd6388..f461de1 100644 (file)
@@ -4,6 +4,9 @@
 <directory name="3rdparty">
        <xi:include href="3rdparty/3rdparty.rbuild" />
 </directory>
+<directory name="cmlib">
+       <xi:include href="cmlib/cmlib.rbuild" />
+</directory>
 <directory name="crt">
        <xi:include href="crt/crt.rbuild" />
 </directory>
index be30972..907d9ab 100644 (file)
@@ -94,7 +94,7 @@ typedef struct _HIVE_HEADER
   ULONG  Unused7;
 
   /* Name of hive file */
-  WCHAR  FileName[48];
+  WCHAR  FileName[32];
 
   ULONG  Reserved[99];
 
index b5ecab8..289007d 100644 (file)
@@ -1360,7 +1360,11 @@ CmiCalcChecksum(PULONG Buffer)
   ULONG i;
 
   for (i = 0; i < 127; i++)
-    Sum += Buffer[i];
+    Sum ^= Buffer[i];
+  if (Sum == (ULONG)-1)
+    Sum = (ULONG)-2;
+  if (Sum == 0)
+    Sum = 1;
 
   return(Sum);
 }
index 9491aff..cc50be3 100644 (file)
@@ -107,7 +107,7 @@ typedef struct _HIVE_HEADER
   ULONG  Unused7;
 
   /* Name of hive file */
-  WCHAR  FileName[48];
+  WCHAR  FileName[32];
 
   ULONG  Reserved[99];
 
@@ -1248,7 +1248,11 @@ CmiCalcHiveChecksum (PREGISTRY_HIVE Hive)
   Buffer = (PULONG)Hive->HiveHeader;
   Sum = 0;
   for (i = 0; i < 127; i++)
-    Sum += Buffer[i];
+    Sum ^= Buffer[i];
+  if (Sum == (ULONG)-1)
+    Sum = (ULONG)-2;
+  if (Sum == 0)
+    Sum = 1;
 
   Hive->HiveHeader->Checksum = Sum;
 }