Fix splitting of cells (noticed by Hartmut).
[reactos.git] / reactos / tools / mkhive / binhive.c
index 2ee32ad..6b3dfb8 100644 (file)
@@ -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))
 
@@ -83,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 */
@@ -106,10 +107,9 @@ 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;
@@ -126,14 +126,13 @@ typedef struct _HBIN
   /* Size in bytes, multiple of the block size (4KB) */
   ULONG  BinSize;
 
-  /* ? */
-  ULONG  Unused1;
+  ULONG  Reserved[2];
 
   /* When this bin was last modified */
   FILETIME  DateModified;
 
-  /* ? */
-  ULONG  Unused2;
+  /* ? (In-memory only) */
+  ULONG  MemAlloc;
 } GCC_PACKED HBIN, *PHBIN;
 
 typedef struct _CELL_HEADER
@@ -196,7 +195,7 @@ typedef struct _KEY_CELL
   USHORT  ClassSize;
 
   /* Name of key (not zero terminated) */
-  UCHAR  Name[0];
+  CHAR  Name[0];
 } GCC_PACKED KEY_CELL, *PKEY_CELL;
 
 /* KEY_CELL.Type constants */
@@ -237,7 +236,7 @@ typedef struct _VALUE_CELL
   ULONG  DataType;
   USHORT  Flags;
   USHORT  Unused1;
-  UCHAR  Name[0]; /* warning : not zero terminated */
+  CHAR  Name[0]; /* warning : not zero terminated */
 } GCC_PACKED VALUE_CELL, *PVALUE_CELL;
 
 /* VALUE_CELL.Flags constants */
@@ -250,7 +249,7 @@ typedef struct _VALUE_CELL
 typedef struct _DATA_CELL
 {
   LONG  CellSize;
-  UCHAR  Data[0];
+  CHAR  Data[0];
 } GCC_PACKED DATA_CELL, *PDATA_CELL;
 
 #ifdef _MSC_VER
@@ -292,14 +291,13 @@ CmiCreateDefaultHiveHeader (PHIVE_HEADER Header)
   Header->UpdateCounter1 = 0;
   Header->UpdateCounter2 = 0;
   Header->DateModified = 0;
-  Header->Unused3 = 1;
-  Header->Unused4 = 3;
-  Header->Unused5 = 0;
-  Header->Unused6 = 1;
+  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;
 }
 
@@ -326,7 +324,7 @@ CmiCreateDefaultRootKeyCell(PKEY_CELL RootKeyCell, PCHAR KeyName)
 
   BaseKeyName = strrchr(KeyName, '\\') + 1;
   NameSize = strlen(BaseKeyName);
-  CellSize = ROUND_UP(sizeof(KEY_CELL) + NameSize - 1, 16);
+  CellSize = ROUND_UP_POW2(sizeof(KEY_CELL) + NameSize - 1, 16);
 
   memset (RootKeyCell, 0, CellSize);
   RootKeyCell->CellSize = (ULONG)-(LONG)CellSize;
@@ -736,9 +734,8 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive,
   tmpBin->BinOffset = RegistryHive->FileSize - REG_BLOCK_SIZE;
   RegistryHive->FileSize += BinSize;
   tmpBin->BinSize = BinSize;
-  tmpBin->Unused1 = 0;
   tmpBin->DateModified = 0;
-  tmpBin->Unused2 = 0;
+  tmpBin->MemAlloc = 0;
 
   /* Increase size of list of blocks */
   tmpBlockList = malloc (sizeof(PHBIN) * (RegistryHive->BlockListSize + BlockCount));
@@ -786,7 +783,7 @@ CmiAllocateCell (PREGISTRY_HIVE RegistryHive,
   *Block = NULL;
 
   /* Round to 16 bytes multiple */
-  CellSize = ROUND_UP(CellSize, 16);
+  CellSize = ROUND_UP_POW2(CellSize, 16);
 
   /* first search in free blocks */
   NewBlock = NULL;
@@ -832,6 +829,7 @@ CmiAllocateCell (PREGISTRY_HIVE RegistryHive,
     {
       NewBlock = (PCELL_HEADER) ((ULONG_PTR) NewBlock + CellSize);
       NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - CellSize;
+      ((PCELL_HEADER) (*Block))->CellSize = CellSize;
       CmiAddFree (RegistryHive,
                  NewBlock,
                  *pBlockOffset + CellSize,
@@ -843,7 +841,7 @@ CmiAllocateCell (PREGISTRY_HIVE RegistryHive,
     }
 
   memset(*Block, 0, CellSize);
-  ((PCELL_HEADER)(*Block))->CellSize = -CellSize;
+  ((PCELL_HEADER)(*Block))->CellSize *= -1;
 
   return TRUE;
 }
@@ -1028,7 +1026,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);