Fix splitting of cells (noticed by Hartmut).
[reactos.git] / reactos / ntoskrnl / cm / regfile.c
index eb34093..85b3409 100644 (file)
@@ -1,5 +1,5 @@
 /* $Id$
- * 
+ *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/cm/regfile.c
@@ -20,8 +20,6 @@
 
 /* LOCAL MACROS *************************************************************/
 
-#define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
-
 #define ABS_VALUE(V) (((V) < 0) ? -(V) : (V))
 
 BOOLEAN CmiDoVerify = FALSE;
@@ -41,14 +39,13 @@ CmiCreateDefaultHiveHeader(PHIVE_HEADER Header)
   Header->UpdateCounter2 = 0;
   Header->DateModified.u.LowPart = 0;
   Header->DateModified.u.HighPart = 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 = (BLOCK_OFFSET)-1;
   Header->BlockSize = REG_BLOCK_SIZE;
-  Header->Unused6 = 1;
   Header->Checksum = 0;
 }
 
@@ -105,7 +102,7 @@ CmiVerifyBinHeader(PHBIN BinHeader)
 
   //BinHeader->DateModified.dwHighDateTime
 
-  
+
   if (BinHeader->BinSize != REG_BLOCK_SIZE)
     {
       DbgPrint("BinSize is %.08x (should be a multiple of %.08x)\n",
@@ -299,32 +296,32 @@ CmiVerifyHiveHeader(PHIVE_HEADER Header)
       ASSERT(Header->BlockId == REG_HIVE_ID);
     }
 
-  if (Header->Unused3 != 1)
+  if (Header->MajorVersion != 1)
     {
-      DbgPrint("Unused3 is %.08x (must be 1)\n",
-        Header->Unused3);
-      ASSERT(Header->Unused3 == 1);
+      DbgPrint("MajorVersion is %.08x (must be 1)\n",
+        Header->MajorVersion);
+      ASSERT(Header->MajorVersion == 1);
     }
 
-  if (Header->Unused4 != 3)
+  if (Header->MinorVersion != 3)
     {
-      DbgPrint("Unused4 is %.08x (must be 3)\n",
-        Header->Unused4);
-      ASSERT(Header->Unused4 == 3);
+      DbgPrint("MinorVersion is %.08x (must be 3)\n",
+        Header->MajorVersion);
+      ASSERT(Header->MajorVersion == 3);
     }
 
-  if (Header->Unused5 != 0)
+  if (Header->Type != 0)
     {
-      DbgPrint("Unused5 is %.08x (must be 0)\n",
-        Header->Unused5);
-      ASSERT(Header->Unused5 == 0);
+      DbgPrint("Type is %.08x (must be 0)\n",
+        Header->Type);
+      ASSERT(Header->Type == 0);
     }
 
-  if (Header->Unused6 != 1)
+  if (Header->Format != 1)
     {
-      DbgPrint("Unused6 is %.08x (must be 1)\n",
-        Header->Unused6);
-      ASSERT(Header->Unused6 == 1);
+      DbgPrint("Format is %.08x (must be 1)\n",
+        Header->Format);
+      ASSERT(Header->Format == 1);
     }
 
   if (Header->Unused7 != 1)
@@ -398,8 +395,6 @@ CmiCreateNewRegFile(HANDLE FileHandle)
 
   ExFreePool(Buffer);
 
-  ASSERTMSG(NT_SUCCESS(Status), ("Status: 0x%X\n", Status));
-
   if (!NT_SUCCESS(Status))
     {
       return(Status);
@@ -688,9 +683,8 @@ CmiImportHiveBins(PREGISTRY_HIVE Hive,
          return STATUS_REGISTRY_CORRUPT;
        }
 
-      ASSERTMSG((Bin->BinSize % REG_BLOCK_SIZE) == 0,
-               ("Bin size (0x%.08x) must be multiple of 4K\n",
-               Bin->BinSize));
+      ASSERTMSG("Bin size must be multiple of 4K\n",
+                (Bin->BinSize % REG_BLOCK_SIZE) == 0);
 
       /* Allocate the hive block */
       Hive->BlockList[BlockIndex].Bin = ExAllocatePool (PagedPool,
@@ -863,19 +857,20 @@ CmiInitNonVolatileRegistryHive (PREGISTRY_HIVE RegistryHive,
         RegistryHive, Filename);
 
   /* Duplicate Filename */
-  Status = RtlpCreateUnicodeString(&RegistryHive->HiveFileName,
-              Filename, NonPagedPool);
+  Status = RtlCreateUnicodeString(&RegistryHive->HiveFileName,
+                                  Filename);
   if (!NT_SUCCESS(Status))
     {
-      DPRINT("RtlpCreateUnicodeString() failed (Status %lx)\n", Status);
+      DPRINT("RtlCreateUnicodeString() failed (Status %lx)\n", Status);
       return(Status);
     }
 
   /* Create log file name */
   RegistryHive->LogFileName.Length = (wcslen(Filename) + 4) * sizeof(WCHAR);
   RegistryHive->LogFileName.MaximumLength = RegistryHive->LogFileName.Length + sizeof(WCHAR);
-  RegistryHive->LogFileName.Buffer = ExAllocatePool(NonPagedPool,
-                                                   RegistryHive->LogFileName.MaximumLength);
+  RegistryHive->LogFileName.Buffer = ExAllocatePoolWithTag(PagedPool,
+                                                          RegistryHive->LogFileName.MaximumLength,
+                                                           TAG('U', 'S', 'T', 'R'));
   if (RegistryHive->LogFileName.Buffer == NULL)
     {
       RtlFreeUnicodeString(&RegistryHive->HiveFileName);
@@ -1073,7 +1068,7 @@ CmiCreateVolatileHive(PREGISTRY_HIVE *RegistryHive)
   RtlZeroMemory (Hive,
                 sizeof(REGISTRY_HIVE));
 
-  DPRINT("Hive %x\n", Hive);
+  DPRINT("Hive 0x%p\n", Hive);
 
   Hive->HiveHeader = (PHIVE_HEADER)ExAllocatePool (NonPagedPool,
                                                   sizeof(HIVE_HEADER));
@@ -1143,7 +1138,7 @@ CmiCreateTempHive(PREGISTRY_HIVE *RegistryHive)
   RtlZeroMemory (Hive,
                 sizeof(REGISTRY_HIVE));
 
-  DPRINT ("Hive %x\n", Hive);
+  DPRINT ("Hive 0x%p\n", Hive);
 
   Hive->HiveHeader = (PHIVE_HEADER)ExAllocatePool (NonPagedPool,
                                                   REG_BLOCK_SIZE);
@@ -1156,7 +1151,7 @@ CmiCreateTempHive(PREGISTRY_HIVE *RegistryHive)
   RtlZeroMemory (Hive->HiveHeader,
                 REG_BLOCK_SIZE);
 
-  DPRINT ("HiveHeader %x\n", Hive->HiveHeader);
+  DPRINT ("HiveHeader 0x%p\n", Hive->HiveHeader);
 
   Hive->Flags = HIVE_NO_FILE;
 
@@ -1265,7 +1260,7 @@ CmiLoadHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
   RtlZeroMemory (Hive,
                 sizeof(REGISTRY_HIVE));
 
-  DPRINT ("Hive %x\n", Hive);
+  DPRINT ("Hive 0x%p\n", Hive);
   Hive->Flags = (Flags & REG_NO_LAZY_FLUSH) ? HIVE_NO_SYNCH : 0;
 
   Hive->HiveHeader = (PHIVE_HEADER)ExAllocatePool(NonPagedPool,
@@ -2873,7 +2868,7 @@ CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
       CmiMarkBlockDirty(RegistryHive, KeyCellOffset);
       CmiMarkBlockDirty(RegistryHive, ValueListCellOffset);
     }
-  else if (KeyCell->NumberOfValues >= 
+  else if (KeyCell->NumberOfValues >=
           (((ULONG)ABS_VALUE(ValueListCell->CellSize) - sizeof(VALUE_LIST_CELL)) / sizeof(BLOCK_OFFSET)))
     {
 #if 0
@@ -3023,7 +3018,7 @@ CmiAllocateHashTableCell (IN PREGISTRY_HIVE RegistryHive,
 
   Status = STATUS_SUCCESS;
   *HashBlock = NULL;
-  NewHashSize = sizeof(HASH_TABLE_CELL) + 
+  NewHashSize = sizeof(HASH_TABLE_CELL) +
                (SubKeyCount * sizeof(HASH_RECORD));
   Status = CmiAllocateCell (RegistryHive,
                            NewHashSize,
@@ -3239,6 +3234,7 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive,
   PHBIN tmpBin;
   ULONG BinSize;
   ULONG i;
+  ULONG BitmapSize;
 
   DPRINT ("CmiAddBin (BlockCount %lu)\n", BlockCount);
 
@@ -3255,9 +3251,8 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive,
   tmpBin->BinOffset = RegistryHive->FileSize - REG_BLOCK_SIZE;
   RegistryHive->FileSize += BinSize;
   tmpBin->BinSize = BinSize;
-  tmpBin->Unused1 = 0;
   KeQuerySystemTime(&tmpBin->DateModified);
-  tmpBin->Unused2 = 0;
+  tmpBin->MemAlloc = 0;
 
   DPRINT ("  BinOffset %lx  BinSize %lx\n", tmpBin->BinOffset,tmpBin->BinSize);
 
@@ -3291,17 +3286,17 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive,
   tmpBlock = (PCELL_HEADER)((ULONG_PTR) tmpBin + REG_HBIN_DATA_OFFSET);
   tmpBlock->CellSize = (BinSize - REG_HBIN_DATA_OFFSET);
 
+  /* Calculate bitmap size in bytes (always a multiple of 32 bits) */
+  BitmapSize = ROUND_UP(RegistryHive->BlockListSize, sizeof(ULONG) * 8) / 8;
+
   /* Grow bitmap if necessary */
-  if (IsNoFileHive(RegistryHive) &&
-      (RegistryHive->BlockListSize % (sizeof(ULONG) * 8) == 0))
+  if (!IsNoFileHive(RegistryHive) &&
+      BitmapSize > RegistryHive->DirtyBitMap.SizeOfBitMap / 8)
     {
       PULONG BitmapBuffer;
-      ULONG BitmapSize;
 
       DPRINT("Grow hive bitmap\n");
 
-      /* Calculate bitmap size in bytes (always a multiple of 32 bits) */
-      BitmapSize = ROUND_UP(RegistryHive->BlockListSize, sizeof(ULONG) * 8) / 8;
       DPRINT("RegistryHive->BlockListSize: %lu\n", RegistryHive->BlockListSize);
       DPRINT("BitmapSize:  %lu Bytes  %lu Bits\n", BitmapSize, BitmapSize * 8);
       BitmapBuffer = (PULONG)ExAllocatePool(PagedPool,
@@ -3309,7 +3304,7 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive,
       RtlZeroMemory(BitmapBuffer, BitmapSize);
       RtlCopyMemory(BitmapBuffer,
                    RegistryHive->DirtyBitMap.Buffer,
-                   RegistryHive->DirtyBitMap.SizeOfBitMap);
+                   RegistryHive->DirtyBitMap.SizeOfBitMap / 8);
       ExFreePool(RegistryHive->BitmapBuffer);
       RegistryHive->BitmapBuffer = BitmapBuffer;
       RtlInitializeBitMap(&RegistryHive->DirtyBitMap,
@@ -3422,6 +3417,7 @@ CmiAllocateCell (PREGISTRY_HIVE RegistryHive,
        {
          NewCell = (PCELL_HEADER) ((ULONG_PTR) NewCell + CellSize);
          NewCell->CellSize = ((PCELL_HEADER) (*Cell))->CellSize - CellSize;
+         ((PCELL_HEADER) (*Cell))->CellSize = CellSize;
          CmiAddFree(RegistryHive,
                     NewCell,
                     *CellOffset + CellSize,
@@ -3436,7 +3432,7 @@ CmiAllocateCell (PREGISTRY_HIVE RegistryHive,
 
       RtlZeroMemory(*Cell,
                    CellSize);
-      ((PCELL_HEADER) (*Cell))->CellSize = -CellSize;
+      ((PCELL_HEADER) (*Cell))->CellSize *= -1;
     }
 
   return STATUS_SUCCESS;
@@ -4069,6 +4065,10 @@ CmiCopyKey (PREGISTRY_HIVE DstHive,
        }
       NewKeyCell->HashTableOffset = NewHashTableOffset;
     }
+  else
+    {
+      NewHashTableCell = NULL;
+    }
 
   /* Allocate and copy value list and values */
   if (SrcKeyCell->NumberOfValues != 0)