Revert Filip's last 4 changes on his request as they break booting
[reactos.git] / reactos / tools / mkhive / binhive.c
index f9e1d3d..6b999f5 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ReactOS kernel
- *  Copyright (C) 2003 ReactOS Team
+ *  Copyright (C) 2003, 2004 ReactOS Team
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: binhive.c,v 1.8 2003/11/14 17:13:36 weiden Exp $
+/* $Id$
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS hive maker
  * FILE:            tools/mkhive/binhive.c
@@ -49,8 +49,8 @@
 #define  REG_EXTEND_HASH_TABLE_SIZE    4
 #define  REG_VALUE_LIST_CELL_MULTIPLE  4
 
-#define ROUND_UP(N, S) ((N) + (S) - ((N) % (S)))
-#define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
+#define ROUND_UP_POW2(N,S)   (((N) + (S) - 1) & ~((S) - 1))
+#define ROUND_DOWN_POW2(N,S) ((N) & ~((S) - 1))
 
 #define ABS_VALUE(V) (((V) < 0) ? -(V) : (V))
 
 // BLOCK_OFFSET = offset in file after header block
 typedef ULONG BLOCK_OFFSET, *PBLOCK_OFFSET;
 
+#ifdef _MSC_VER
+typedef unsigned __int64 FILETIME;
+#else
 typedef unsigned long long FILETIME;
+#endif
+
+#ifdef _MSC_VER
+#pragma pack ( push, hive_header, 1 )
+#endif//_MSC_VER
 
 /* header for registry hive file : */
 typedef struct _HIVE_HEADER
@@ -75,17 +83,18 @@ typedef struct _HIVE_HEADER
   /* When this hive file was last modified */
   FILETIME  DateModified;
 
-  /* Registry format version ? (1?) */
-  ULONG  Unused3;
+  /* Registry format major version (1) */
+  ULONG  MajorVersion;
 
-  /* Registry format version ? (3?) */
-  ULONG  Unused4;
+  /* Registry format minor version (3)
+     Version 3 added fast indexes, version 5 has large value optimizations */
+  ULONG  MinorVersion;
 
-  /* Registry format version ? (0?) */
-  ULONG  Unused5;
+  /* Registry file type (0 - Primary, 1 - Log) */
+  ULONG  Type;
 
-  /* Registry format version ? (1?) */
-  ULONG  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 */
@@ -98,41 +107,39 @@ typedef struct _HIVE_HEADER
   ULONG  Unused7;
 
   /* Name of hive file */
-  WCHAR  FileName[64];
+  WCHAR  FileName[48];
 
-  /* ? */
-  ULONG  Unused8[83];
+  ULONG  Reserved[99];
 
   /* Checksum of first 0x200 bytes */
   ULONG  Checksum;
-} __attribute__((packed)) HIVE_HEADER, *PHIVE_HEADER;
+} GCC_PACKED HIVE_HEADER, *PHIVE_HEADER;
 
 typedef struct _HBIN
 {
   /* Bin identifier "hbin" (0x6E696268) */
-  ULONG  BlockId;
+  ULONG  HeaderId;
 
   /* Block offset of this bin */
-  BLOCK_OFFSET  BlockOffset;
+  BLOCK_OFFSET  BinOffset;
 
   /* Size in bytes, multiple of the block size (4KB) */
-  ULONG  BlockSize;
+  ULONG  BinSize;
 
-  /* ? */
-  ULONG  Unused1;
+  ULONG  Reserved[2];
 
   /* When this bin was last modified */
   FILETIME  DateModified;
 
-  /* ? */
-  ULONG  Unused2;
-} __attribute__((packed)) HBIN, *PHBIN;
+  /* ? (In-memory only) */
+  ULONG  MemAlloc;
+} GCC_PACKED HBIN, *PHBIN;
 
 typedef struct _CELL_HEADER
 {
   /* <0 if used, >0 if free */
   LONG  CellSize;
-} __attribute__((packed)) CELL_HEADER, *PCELL_HEADER;
+} GCC_PACKED CELL_HEADER, *PCELL_HEADER;
 
 typedef struct _KEY_CELL
 {
@@ -188,8 +195,8 @@ typedef struct _KEY_CELL
   USHORT  ClassSize;
 
   /* Name of key (not zero terminated) */
-  UCHAR  Name[0];
-} __attribute__((packed)) KEY_CELL, *PKEY_CELL;
+  CHAR  Name[0];
+} GCC_PACKED KEY_CELL, *PKEY_CELL;
 
 /* KEY_CELL.Type constants */
 #define  REG_LINK_KEY_CELL_TYPE        0x10
@@ -203,7 +210,7 @@ typedef struct _HASH_RECORD
 {
   BLOCK_OFFSET  KeyOffset;
   ULONG  HashValue;
-} __attribute__((packed)) HASH_RECORD, *PHASH_RECORD;
+} GCC_PACKED HASH_RECORD, *PHASH_RECORD;
 
 typedef struct _HASH_TABLE_CELL
 {
@@ -211,13 +218,13 @@ typedef struct _HASH_TABLE_CELL
   USHORT  Id;
   USHORT  HashTableSize;
   HASH_RECORD  Table[0];
-} __attribute__((packed)) HASH_TABLE_CELL, *PHASH_TABLE_CELL;
+} GCC_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;
+} GCC_PACKED VALUE_LIST_CELL, *PVALUE_LIST_CELL;
 
 typedef struct _VALUE_CELL
 {
@@ -229,8 +236,8 @@ typedef struct _VALUE_CELL
   ULONG  DataType;
   USHORT  Flags;
   USHORT  Unused1;
-  UCHAR  Name[0]; /* warning : not zero terminated */
-} __attribute__((packed)) VALUE_CELL, *PVALUE_CELL;
+  CHAR  Name[0]; /* warning : not zero terminated */
+} GCC_PACKED VALUE_CELL, *PVALUE_CELL;
 
 /* VALUE_CELL.Flags constants */
 #define REG_VALUE_NAME_PACKED             0x0001
@@ -242,8 +249,12 @@ typedef struct _VALUE_CELL
 typedef struct _DATA_CELL
 {
   LONG  CellSize;
-  UCHAR  Data[0];
-} __attribute__((packed)) DATA_CELL, *PDATA_CELL;
+  CHAR  Data[0];
+} GCC_PACKED DATA_CELL, *PDATA_CELL;
+
+#ifdef _MSC_VER
+#pragma pack ( pop, hive_header )
+#endif//_MSC_VER
 
 typedef struct _REGISTRY_HIVE
 {
@@ -260,22 +271,33 @@ typedef struct _REGISTRY_HIVE
 /* FUNCTIONS ****************************************************************/
 
 static VOID
-CmiCreateDefaultHiveHeader(PHIVE_HEADER Header)
+memexpand (PWCHAR Dst,
+          PCHAR Src,
+          ULONG Length)
+{
+  ULONG i;
+
+  for (i = 0; i < Length; i++)
+    Dst[i] = (WCHAR)Src[i];
+}
+
+
+static VOID
+CmiCreateDefaultHiveHeader (PHIVE_HEADER Header)
 {
-  assert(Header);
+  assert (Header);
   memset (Header, 0, REG_BLOCK_SIZE);
   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;
 }
 
@@ -283,23 +305,32 @@ CmiCreateDefaultHiveHeader(PHIVE_HEADER Header)
 static VOID
 CmiCreateDefaultBinCell(PHBIN BinCell)
 {
-  assert(BinCell);
+  assert (BinCell);
   memset (BinCell, 0, REG_BLOCK_SIZE);
-  BinCell->BlockId = REG_BIN_ID;
-  BinCell->DateModified = 0ULL;
-  BinCell->BlockSize = REG_BLOCK_SIZE;
+  BinCell->HeaderId = REG_BIN_ID;
+  BinCell->DateModified = 0;
+  BinCell->BinSize = REG_BLOCK_SIZE;
 }
 
 
 static VOID
-CmiCreateDefaultRootKeyCell(PKEY_CELL RootKeyCell)
+CmiCreateDefaultRootKeyCell(PKEY_CELL RootKeyCell, PCHAR KeyName)
 {
-  assert(RootKeyCell);
-  memset (RootKeyCell, 0, sizeof(KEY_CELL));
-  RootKeyCell->CellSize = -sizeof(KEY_CELL);
+  PCHAR BaseKeyName;
+  USHORT NameSize;
+  ULONG CellSize;
+
+  assert (RootKeyCell);
+
+  BaseKeyName = strrchr(KeyName, '\\') + 1;
+  NameSize = strlen(BaseKeyName);
+  CellSize = ROUND_UP_POW2(sizeof(KEY_CELL) + NameSize - 1, 16);
+
+  memset (RootKeyCell, 0, CellSize);
+  RootKeyCell->CellSize = (ULONG)-(LONG)CellSize;
   RootKeyCell->Id = REG_KEY_CELL_ID;
   RootKeyCell->Type = REG_ROOT_KEY_CELL_TYPE;
-  RootKeyCell->LastWriteTime = 0ULL;
+  RootKeyCell->LastWriteTime = 0;
   RootKeyCell->ParentKeyOffset = 0;
   RootKeyCell->NumberOfSubKeys = 0;
   RootKeyCell->HashTableOffset = -1;
@@ -307,13 +338,16 @@ CmiCreateDefaultRootKeyCell(PKEY_CELL RootKeyCell)
   RootKeyCell->ValueListOffset = -1;
   RootKeyCell->SecurityKeyOffset = 0;
   RootKeyCell->ClassNameOffset = -1;
-  RootKeyCell->NameSize = 0;
+  RootKeyCell->NameSize = NameSize;
   RootKeyCell->ClassSize = 0;
+  memcpy (RootKeyCell->Name,
+         BaseKeyName,
+         NameSize);
 }
 
 
 static PREGISTRY_HIVE
-CmiCreateRegistryHive (VOID)
+CmiCreateRegistryHive (PCHAR KeyName)
 {
   PREGISTRY_HIVE Hive;
   PCELL_HEADER FreeCell;
@@ -327,7 +361,7 @@ CmiCreateRegistryHive (VOID)
     }
   memset (Hive, 0, sizeof(REGISTRY_HIVE));
 
-  DPRINT("Hive %x\n", Hive);
+  DPRINT("Hive %p\n", Hive);
 
   /* Create hive beader (aka 'base block') */
   Hive->HiveHeader = (PHIVE_HEADER) malloc (REG_BLOCK_SIZE);
@@ -336,7 +370,7 @@ CmiCreateRegistryHive (VOID)
       free (Hive);
       return NULL;
     }
-  CmiCreateDefaultHiveHeader(Hive->HiveHeader);
+  CmiCreateDefaultHiveHeader (Hive->HiveHeader);
   Hive->FileSize = REG_BLOCK_SIZE;
 
   /* Allocate block list */
@@ -384,20 +418,20 @@ CmiCreateRegistryHive (VOID)
 
   /* Init first bin */
   BinCell = (PHBIN)Hive->BlockList[0];
-  CmiCreateDefaultBinCell(BinCell);
-  BinCell->BlockOffset = 0;
+  CmiCreateDefaultBinCell (BinCell);
+  BinCell->BinOffset = 0;
 
   /* Init root key cell */
   RootKeyCell = (PKEY_CELL)((ULONG_PTR)BinCell + REG_HBIN_DATA_OFFSET);
-  CmiCreateDefaultRootKeyCell(RootKeyCell);
+  CmiCreateDefaultRootKeyCell (RootKeyCell, KeyName);
   Hive->HiveHeader->RootKeyOffset = REG_HBIN_DATA_OFFSET;
 
   /* Init free cell */
-  FreeCell = (PCELL_HEADER)((ULONG_PTR)RootKeyCell + sizeof(KEY_CELL));
-  FreeCell->CellSize = REG_BLOCK_SIZE - (REG_HBIN_DATA_OFFSET + sizeof(KEY_CELL));
+  FreeCell = (PCELL_HEADER)((ULONG_PTR)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 + sizeof(KEY_CELL);
+  Hive->FreeListOffset[0] = REG_HBIN_DATA_OFFSET - RootKeyCell->CellSize;
   Hive->FreeListSize++;
 
   return Hive;
@@ -433,7 +467,7 @@ CmiDestroyRegistryHive (PREGISTRY_HIVE Hive)
              Bin = Hive->BlockList[i];
 
              DPRINT ("Bin[%lu]: Offset 0x%lx  Size 0x%lx\n",
-                     i, Bin->BlockOffset, Bin->BlockSize);
+                     i, Bin->BinOffset, Bin->BinSize);
 
              free (Bin);
            }
@@ -474,7 +508,7 @@ CmiGetCell (PREGISTRY_HIVE Hive,
   if (ppBin)
     *ppBin = pBin;
 
-  return (PVOID)((ULONG_PTR)pBin + (BlockOffset - pBin->BlockOffset));
+  return (PVOID)((ULONG_PTR)pBin + (BlockOffset - pBin->BinOffset));
 }
 
 
@@ -490,7 +524,7 @@ CmiMergeFree(PREGISTRY_HIVE RegistryHive,
   PHBIN Bin;
   ULONG i;
 
-  DPRINT("CmiMergeFree(Block %lx  Offset %lx  Size %lx) called\n",
+  DPRINT("CmiMergeFree(Block %p  Offset %lx  Size %lx) called\n",
         FreeBlock, FreeOffset, FreeBlock->CellSize);
 
   CmiGetCell (RegistryHive,
@@ -500,8 +534,8 @@ CmiMergeFree(PREGISTRY_HIVE RegistryHive,
   if (Bin == NULL)
     return FALSE;
 
-  BinOffset = Bin->BlockOffset;
-  BinSize = Bin->BlockSize;
+  BinOffset = Bin->BinOffset;
+  BinSize = Bin->BinSize;
   DPRINT("Bin %p  Offset %lx  Size %lx\n", Bin, BinOffset, BinSize);
 
   for (i = 0; i < RegistryHive->FreeListSize; i++)
@@ -584,7 +618,7 @@ CmiAddFree(PREGISTRY_HIVE RegistryHive,
   assert(RegistryHive);
   assert(FreeBlock);
 
-  DPRINT("FreeBlock %.08lx  FreeOffset %.08lx\n",
+  DPRINT("FreeBlock %p  FreeOffset %.08lx\n",
         FreeBlock, FreeOffset);
 
   /* Merge free blocks */
@@ -678,30 +712,33 @@ CmiAddFree(PREGISTRY_HIVE RegistryHive,
 
 static BOOL
 CmiAddBin(PREGISTRY_HIVE RegistryHive,
+         ULONG BlockCount,
          PVOID *NewBlock,
          PBLOCK_OFFSET NewBlockOffset)
 {
   PCELL_HEADER tmpBlock;
   PHBIN * tmpBlockList;
   PHBIN tmpBin;
+  ULONG BinSize;
+  ULONG i;
 
-  tmpBin = malloc (REG_BLOCK_SIZE);
+  BinSize = BlockCount *REG_BLOCK_SIZE;
+  tmpBin = malloc (BinSize);
   if (tmpBin == NULL)
     {
       return FALSE;
     }
-  memset (tmpBin, 0, REG_BLOCK_SIZE);
+  memset (tmpBin, 0, BinSize);
 
-  tmpBin->BlockId = REG_BIN_ID;
-  tmpBin->BlockOffset = RegistryHive->FileSize - REG_BLOCK_SIZE;
-  RegistryHive->FileSize += REG_BLOCK_SIZE;
-  tmpBin->BlockSize = REG_BLOCK_SIZE;
-  tmpBin->Unused1 = 0;
-  tmpBin->DateModified = 0ULL;
-  tmpBin->Unused2 = 0;
+  tmpBin->HeaderId = REG_BIN_ID;
+  tmpBin->BinOffset = RegistryHive->FileSize - REG_BLOCK_SIZE;
+  RegistryHive->FileSize += BinSize;
+  tmpBin->BinSize = BinSize;
+  tmpBin->DateModified = 0;
+  tmpBin->MemAlloc = 0;
 
   /* Increase size of list of blocks */
-  tmpBlockList = malloc (sizeof(PHBIN) * (RegistryHive->BlockListSize + 1));
+  tmpBlockList = malloc (sizeof(PHBIN) * (RegistryHive->BlockListSize + BlockCount));
   if (tmpBlockList == NULL)
     {
       free (tmpBin);
@@ -717,7 +754,9 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive,
     }
 
   RegistryHive->BlockList = tmpBlockList;
-  RegistryHive->BlockList[RegistryHive->BlockListSize++] = tmpBin;
+  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_PTR) tmpBin + REG_HBIN_DATA_OFFSET);
@@ -726,7 +765,7 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive,
   *NewBlock = (PVOID) tmpBlock;
 
   if (NewBlockOffset)
-    *NewBlockOffset = tmpBin->BlockOffset + REG_HBIN_DATA_OFFSET;
+    *NewBlockOffset = tmpBin->BinOffset + REG_HBIN_DATA_OFFSET;
 
   return TRUE;
 }
@@ -734,7 +773,7 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive,
 
 static BOOL
 CmiAllocateCell (PREGISTRY_HIVE RegistryHive,
-                LONG BlockSize,
+                LONG CellSize,
                 PVOID *Block,
                 PBLOCK_OFFSET pBlockOffset)
 {
@@ -744,13 +783,13 @@ CmiAllocateCell (PREGISTRY_HIVE RegistryHive,
   *Block = NULL;
 
   /* Round to 16 bytes multiple */
-  BlockSize = ROUND_UP(BlockSize, 16);
+  CellSize = ROUND_UP_POW2(CellSize, 16);
 
   /* first search in free blocks */
   NewBlock = NULL;
   for (i = 0; i < RegistryHive->FreeListSize; i++)
     {
-      if (RegistryHive->FreeList[i]->CellSize >= BlockSize)
+      if (RegistryHive->FreeList[i]->CellSize >= CellSize)
        {
          NewBlock = RegistryHive->FreeList[i];
          if (pBlockOffset)
@@ -776,29 +815,32 @@ CmiAllocateCell (PREGISTRY_HIVE RegistryHive,
   if (NewBlock == NULL)
     {
       /* Add a new block */
-      if (!CmiAddBin(RegistryHive, (PVOID *)&NewBlock , pBlockOffset))
+      if (!CmiAddBin(RegistryHive,
+                    ((sizeof(HBIN) + CellSize - 1) / REG_BLOCK_SIZE) + 1,
+                    (PVOID *)&NewBlock,
+                    pBlockOffset))
        return FALSE;
     }
 
   *Block = NewBlock;
 
   /* Split the block in two parts */
-  if (NewBlock->CellSize > BlockSize)
+  if (NewBlock->CellSize > CellSize)
     {
-      NewBlock = (PCELL_HEADER) ((ULONG_PTR) NewBlock+BlockSize);
-      NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - BlockSize;
+      NewBlock = (PCELL_HEADER) ((ULONG_PTR) NewBlock + CellSize);
+      NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - CellSize;
       CmiAddFree (RegistryHive,
                  NewBlock,
-                 *pBlockOffset + BlockSize,
+                 *pBlockOffset + CellSize,
                  TRUE);
     }
-  else if (NewBlock->CellSize < BlockSize)
+  else if (NewBlock->CellSize < CellSize)
     {
       return FALSE;
     }
 
-  memset(*Block, 0, BlockSize);
-  ((PCELL_HEADER)(*Block))->CellSize = -BlockSize;
+  memset(*Block, 0, CellSize);
+  ((PCELL_HEADER)(*Block))->CellSize = -CellSize;
 
   return TRUE;
 }
@@ -807,7 +849,7 @@ CmiAllocateCell (PREGISTRY_HIVE RegistryHive,
 static BOOL
 CmiAllocateHashTableCell (PREGISTRY_HIVE Hive,
                          PBLOCK_OFFSET HBOffset,
-                         ULONG SubKeyCount)
+                         USHORT SubKeyCount)
 {
   PHASH_TABLE_CELL HashCell;
   ULONG NewHashSize;
@@ -908,7 +950,7 @@ CmiAllocateValueCell(PREGISTRY_HIVE Hive,
                     PCHAR ValueName)
 {
   PVALUE_CELL NewValueCell;
-  ULONG NameSize;
+  USHORT NameSize;
   BOOL Status;
 
   NameSize = (ValueName == NULL) ? 0 : strlen (ValueName);
@@ -970,18 +1012,6 @@ CmiAddValueToKeyValueList(PREGISTRY_HIVE Hive,
 }
 
 
-static VOID
-memexpand (PWCHAR Dst,
-          PCHAR Src,
-          ULONG Length)
-{
-  ULONG i;
-
-  for (i = 0; i < Length; i++)
-    Dst[i] = (WCHAR)Src[i];
-}
-
-
 static BOOL
 CmiExportValue (PREGISTRY_HIVE Hive,
                BLOCK_OFFSET KeyCellOffset,
@@ -995,7 +1025,7 @@ CmiExportValue (PREGISTRY_HIVE Hive,
   ULONG SrcDataSize;
   ULONG DstDataSize;
   ULONG DataType;
-  PUCHAR Data;
+  PCHAR Data;
   BOOL Expand = FALSE;
 
   DPRINT ("CmiExportValue('%s') called\n", (Value == NULL) ? "<default>" : (PCHAR)Value->Name);
@@ -1102,7 +1132,7 @@ CmiExportSubKey (PREGISTRY_HIVE Hive,
   BLOCK_OFFSET NKBOffset;
   PKEY_CELL NewKeyCell;
   ULONG KeyCellSize;
-  ULONG SubKeyCount;
+  USHORT SubKeyCount;
   ULONG ValueCount;
   PLIST_ENTRY Entry;
   HKEY SubKey;
@@ -1125,7 +1155,7 @@ CmiExportSubKey (PREGISTRY_HIVE Hive,
   /* Initialize key cell */
   NewKeyCell->Id = REG_KEY_CELL_ID;
   NewKeyCell->Type = REG_KEY_CELL_TYPE;
-  NewKeyCell->LastWriteTime = 0ULL;
+  NewKeyCell->LastWriteTime = 0;
   NewKeyCell->ParentKeyOffset = ParentKeyOffset;
   NewKeyCell->NumberOfSubKeys = 0;
   NewKeyCell->HashTableOffset = -1;
@@ -1228,7 +1258,7 @@ CmiExportHive (PREGISTRY_HIVE Hive,
 {
   PKEY_CELL KeyCell;
   HKEY Key;
-  ULONG SubKeyCount;
+  USHORT SubKeyCount;
   ULONG ValueCount;
   PLIST_ENTRY Entry;
   HKEY SubKey;
@@ -1249,7 +1279,7 @@ CmiExportHive (PREGISTRY_HIVE Hive,
                        NULL);
   if (KeyCell == NULL)
     {
-      DPRINT1 ("CmiGetBlock() failed\n");
+      DPRINT1 ("CmiGetCell() failed\n");
       return FALSE;
     }
 
@@ -1336,6 +1366,7 @@ CmiWriteHive(PREGISTRY_HIVE Hive,
   File = fopen (FileName, "w+b");
   if (File == NULL)
     {
+      printf("    Error creating/opening file\n");
       return FALSE;
     }
 
@@ -1355,9 +1386,9 @@ CmiWriteHive(PREGISTRY_HIVE Hive,
          Bin = Hive->BlockList[i];
 
          DPRINT ("Bin[%lu]: Offset 0x%lx  Size 0x%lx\n",
-                 i, Bin->BlockOffset, Bin->BlockSize);
+                 i, Bin->BinOffset, Bin->BinSize);
 
-         fwrite (Bin, Bin->BlockSize, 1, File);
+         fwrite (Bin, Bin->BinSize, 1, File);
        }
     }
 
@@ -1375,7 +1406,7 @@ ExportBinaryHive (PCHAR FileName,
 
   printf ("  Creating binary hive: %s\n", FileName);
 
-  Hive = CmiCreateRegistryHive ();
+  Hive = CmiCreateRegistryHive (KeyName);
   if (Hive == NULL)
     return FALSE;