- Remove unusued, complex hive checking code from regfile.c.
authorAlex Ionescu <aionescu@gmail.com>
Fri, 11 May 2007 04:59:38 +0000 (04:59 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Fri, 11 May 2007 04:59:38 +0000 (04:59 +0000)
- Implement CmpInitializeHive based on Cm Rewrite but keep code compatible with the current EREGISTRY_HIVE structure in the current Cm.
- Remove CmiCreateVolatileHive and CmiCreateTemp since they're unused.
- Implement CmpCreateRootNode based on CmRewrite and CmCreateRootNode in cmlib, CmpCopyName and CmpNameSize from Cm Rewrite and use them.
- Use CmpInitializeHive + CmpCreateRootNode for the master volatile hive.

svn path=/trunk/; revision=26692

reactos/ntoskrnl/cm/regfile.c
reactos/ntoskrnl/cm/registry.c
reactos/ntoskrnl/config/cm.h
reactos/ntoskrnl/config/cmname.c

index 6ec8914..3b63ce5 100644 (file)
@@ -15,9 +15,7 @@
 #include <internal/debug.h>
 
 #include "cm.h"
-
-/* uncomment to enable hive checks (incomplete and probably buggy) */
-//#define HIVE_CHECK
+#include "..\config\cm.h"
 
 /* LOCAL MACROS *************************************************************/
 
@@ -165,276 +163,6 @@ CmiCreateNewRegFile(HANDLE FileHandle)
   return(Status);
 }
 
-
-#ifdef HIVE_CHECK
-
-static ULONG
-CmiCalcChecksum(PULONG Buffer)
-{
-  ULONG Sum = 0;
-  ULONG i;
-
-  for (i = 0; i < 127; i++)
-    Sum ^= Buffer[i];
-  if (Sum == (ULONG)-1)
-    Sum = (ULONG)-2;
-  if (Sum == 0)
-    Sum = 1;
-
-  return(Sum);
-}
-
-static NTSTATUS
-CmiCheckAndFixHive(PEREGISTRY_HIVE RegistryHive)
-{
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  FILE_STANDARD_INFORMATION fsi;
-  IO_STATUS_BLOCK IoStatusBlock;
-  HANDLE HiveHandle = INVALID_HANDLE_VALUE;
-  HANDLE LogHandle = INVALID_HANDLE_VALUE;
-  PHBASE_BLOCK HiveHeader = NULL;
-  PHBASE_BLOCK LogHeader = NULL;
-  LARGE_INTEGER FileOffset;
-  ULONG FileSize;
-  ULONG BufferSize;
-  ULONG BitmapSize;
-  RTL_BITMAP BlockBitMap;
-  NTSTATUS Status;
-
-  DPRINT("CmiCheckAndFixHive() called\n");
-
-  /* Try to open the hive file */
-  InitializeObjectAttributes(&ObjectAttributes,
-                            &RegistryHive->HiveFileName,
-                            OBJ_CASE_INSENSITIVE,
-                            NULL,
-                            NULL);
-
-  Status = ZwCreateFile(&HiveHandle,
-                       FILE_READ_DATA | FILE_READ_ATTRIBUTES,
-                       &ObjectAttributes,
-                       &IoStatusBlock,
-                       NULL,
-                       FILE_ATTRIBUTE_NORMAL,
-                       0,
-                       FILE_OPEN,
-                       FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
-                       NULL,
-                       0);
-  if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
-    {
-      return(STATUS_SUCCESS);
-    }
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT("ZwCreateFile() failed (Status %lx)\n", Status);
-      return(Status);
-    }
-
-  /* Try to open the log file */
-  InitializeObjectAttributes(&ObjectAttributes,
-                            &RegistryHive->LogFileName,
-                            OBJ_CASE_INSENSITIVE,
-                            NULL,
-                            NULL);
-
-  Status = ZwCreateFile(&LogHandle,
-                       FILE_READ_DATA | FILE_READ_ATTRIBUTES,
-                       &ObjectAttributes,
-                       &IoStatusBlock,
-                       NULL,
-                       FILE_ATTRIBUTE_NORMAL,
-                       0,
-                       FILE_OPEN,
-                       FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
-                       NULL,
-                       0);
-  if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
-    {
-      LogHandle = INVALID_HANDLE_VALUE;
-    }
-  else if (!NT_SUCCESS(Status))
-    {
-      DPRINT("ZwCreateFile() failed (Status %lx)\n", Status);
-      ZwClose(HiveHandle);
-      return(Status);
-    }
-
-  /* Allocate hive header */
-  HiveHeader = ExAllocatePool(PagedPool,
-                             sizeof(HBASE_BLOCK));
-  if (HiveHeader == NULL)
-    {
-      DPRINT("ExAllocatePool() failed\n");
-      Status = STATUS_INSUFFICIENT_RESOURCES;
-      goto ByeBye;
-    }
-
-  /* Read hive base block */
-  FileOffset.QuadPart = 0ULL;
-  Status = ZwReadFile(HiveHandle,
-                     0,
-                     0,
-                     0,
-                     &IoStatusBlock,
-                     HiveHeader,
-                     sizeof(HBASE_BLOCK),
-                     &FileOffset,
-                     0);
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT("ZwReadFile() failed (Status %lx)\n", Status);
-      goto ByeBye;
-    }
-
-  if (LogHandle == INVALID_HANDLE_VALUE)
-    {
-      if (HiveHeader->Checksum != CmiCalcChecksum((PULONG)HiveHeader) ||
-         HiveHeader->Sequence1 != HiveHeader->Sequence2)
-       {
-         /* There is no way to fix the hive without log file - BSOD! */
-         DPRINT("Hive header inconsistent and no log file available!\n");
-         KEBUGCHECK(CONFIG_LIST_FAILED);
-       }
-
-      Status = STATUS_SUCCESS;
-      goto ByeBye;
-    }
-  else
-    {
-      /* Allocate hive header */
-      LogHeader = ExAllocatePool(PagedPool,
-                                HV_LOG_HEADER_SIZE);
-      if (LogHeader == NULL)
-       {
-         DPRINT("ExAllocatePool() failed\n");
-         Status = STATUS_INSUFFICIENT_RESOURCES;
-         goto ByeBye;
-       }
-
-      /* Read log file header */
-      FileOffset.QuadPart = 0ULL;
-      Status = ZwReadFile(LogHandle,
-                         0,
-                         0,
-                         0,
-                         &IoStatusBlock,
-                         LogHeader,
-                         HV_LOG_HEADER_SIZE,
-                         &FileOffset,
-                         0);
-      if (!NT_SUCCESS(Status))
-       {
-         DPRINT("ZwReadFile() failed (Status %lx)\n", Status);
-         goto ByeBye;
-       }
-
-      /* Check log file header integrity */
-      if (LogHeader->Checksum != CmiCalcChecksum((PULONG)LogHeader) ||
-          LogHeader->Sequence1 != LogHeader->Sequence2)
-       {
-         if (HiveHeader->Checksum != CmiCalcChecksum((PULONG)HiveHeader) ||
-             HiveHeader->Sequence1 != HiveHeader->Sequence2)
-           {
-             DPRINT("Hive file and log file are inconsistent!\n");
-             KEBUGCHECK(CONFIG_LIST_FAILED);
-           }
-
-         /* Log file damaged but hive is okay */
-         Status = STATUS_SUCCESS;
-         goto ByeBye;
-       }
-
-      if (HiveHeader->Sequence1 == HiveHeader->Sequence2 &&
-         HiveHeader->Sequence1 == LogHeader->Sequence1)
-       {
-         /* Hive and log file are up-to-date */
-         Status = STATUS_SUCCESS;
-         goto ByeBye;
-       }
-
-      /*
-       * Hive needs an update!
-       */
-
-      /* Get file size */
-      Status = ZwQueryInformationFile(LogHandle,
-                                     &IoStatusBlock,
-                                     &fsi,
-                                     sizeof(fsi),
-                                     FileStandardInformation);
-      if (!NT_SUCCESS(Status))
-       {
-         DPRINT("ZwQueryInformationFile() failed (Status %lx)\n", Status);
-         goto ByeBye;
-       }
-      FileSize = fsi.EndOfFile.u.LowPart;
-
-      /* Calculate bitmap and block size */
-      BitmapSize = ROUND_UP((FileSize / HV_BLOCK_SIZE) - 1, sizeof(ULONG) * 8) / 8;
-      BufferSize = HV_LOG_HEADER_SIZE + sizeof(ULONG) + BitmapSize;
-      BufferSize = ROUND_UP(BufferSize, HV_BLOCK_SIZE);
-
-      /* Reallocate log header block */
-      ExFreePool(LogHeader);
-      LogHeader = ExAllocatePool(PagedPool,
-                                BufferSize);
-      if (LogHeader == NULL)
-       {
-         DPRINT("ExAllocatePool() failed\n");
-         Status = STATUS_INSUFFICIENT_RESOURCES;
-         goto ByeBye;
-       }
-
-      /* Read log file header */
-      FileOffset.QuadPart = 0ULL;
-      Status = ZwReadFile(LogHandle,
-                         0,
-                         0,
-                         0,
-                         &IoStatusBlock,
-                         LogHeader,
-                         BufferSize,
-                         &FileOffset,
-                         0);
-      if (!NT_SUCCESS(Status))
-       {
-         DPRINT("ZwReadFile() failed (Status %lx)\n", Status);
-         goto ByeBye;
-       }
-
-      /* Initialize bitmap */
-      RtlInitializeBitMap(&BlockBitMap,
-                         (PVOID)((ULONG_PTR)LogHeader + HV_BLOCK_SIZE + sizeof(ULONG)),
-                         BitmapSize * 8);
-
-      /* FIXME: Update dirty blocks */
-
-
-      /* FIXME: Update hive header */
-
-
-      Status = STATUS_SUCCESS;
-    }
-
-
-  /* Clean up the mess */
-ByeBye:
-  if (HiveHeader != NULL)
-    ExFreePool(HiveHeader);
-
-  if (LogHeader != NULL)
-    ExFreePool(LogHeader);
-
-  if (LogHandle != INVALID_HANDLE_VALUE)
-    ZwClose(LogHandle);
-
-  ZwClose(HiveHandle);
-
-  return(Status);
-}
-#endif
-
 static NTSTATUS
 CmiInitNonVolatileRegistryHive (PEREGISTRY_HIVE RegistryHive,
                                PWSTR Filename)
@@ -477,18 +205,6 @@ CmiInitNonVolatileRegistryHive (PEREGISTRY_HIVE RegistryHive,
   wcscat(RegistryHive->LogFileName.Buffer,
         L".log");
 
-#ifdef HIVE_CHECK
-  /* Check and eventually fix a hive */
-  Status = CmiCheckAndFixHive(RegistryHive);
-  if (!NT_SUCCESS(Status))
-    {
-      RtlFreeUnicodeString(&RegistryHive->HiveFileName);
-      RtlFreeUnicodeString(&RegistryHive->LogFileName);
-      DPRINT1("CmiCheckAndFixHive() failed (Status %lx)\n", Status);
-      return(Status);
-    }
-#endif
-
   InitializeObjectAttributes(&ObjectAttributes,
                             &RegistryHive->HiveFileName,
                             OBJ_CASE_INSENSITIVE,
@@ -603,72 +319,144 @@ CmiInitNonVolatileRegistryHive (PEREGISTRY_HIVE RegistryHive,
   return STATUS_SUCCESS;
 }
 
+ULONG
+NTAPI
+CmCheckRegistry(IN PEREGISTRY_HIVE RegistryHive,
+                IN ULONG Flags)
+{
+    /* FIXME: HACK! */
+    return 0;
+}
 
 NTSTATUS
-CmiCreateTempHive(PEREGISTRY_HIVE *RegistryHive)
+NTAPI
+CmpInitializeHive(OUT PEREGISTRY_HIVE *RegistryHive,
+                  IN ULONG OperationType,
+                  IN ULONG HiveFlags,
+                  IN ULONG FileType,
+                  IN PVOID HiveData OPTIONAL,
+                  IN HANDLE Primary,
+                  IN HANDLE Log,
+                  IN HANDLE External,
+                  IN PUNICODE_STRING FileName OPTIONAL,
+                  IN ULONG CheckFlags)
 {
-  PEREGISTRY_HIVE Hive;
-  NTSTATUS Status;
-
-  *RegistryHive = NULL;
-
-  Hive = ExAllocatePool (NonPagedPool,
-                        sizeof(EREGISTRY_HIVE));
-  if (Hive == NULL)
-    return STATUS_INSUFFICIENT_RESOURCES;
-
-  RtlZeroMemory (Hive,
-                sizeof(EREGISTRY_HIVE));
-
-  DPRINT("Hive 0x%p\n", Hive);
-
-  Status = HvInitialize(&Hive->Hive, HV_OPERATION_CREATE_HIVE, 0, 0, 0, 0,
-                        CmpAllocate, CmpFree,
-                        CmpFileRead, CmpFileWrite, CmpFileSetSize,
-                        CmpFileFlush, NULL);
-  if (!NT_SUCCESS(Status))
-    {
-      ExFreePool (Hive);
-      return Status;
-    }
+    PEREGISTRY_HIVE Hive;
+    IO_STATUS_BLOCK IoStatusBlock;
+    FILE_FS_SIZE_INFORMATION FileSizeInformation;
+    NTSTATUS Status;
+    ULONG Cluster;
+
+    /* Assume failure */
+    *RegistryHive = NULL;
+
+    /*
+     * The following are invalid:
+     * An external hive that is also internal.
+     * A log hive that's not a primary hive too.
+     * A volatile hive that's linked to permanent storage.
+     * An in-memory initialization without hive data.
+     * A log hive that's not linked to a correct file type.
+     */
+    if (((External) && ((Primary) || (Log))) ||
+        ((Log) && !(Primary)) ||
+        ((HiveFlags & HIVE_VOLATILE) && ((Primary) || (External) || (Log))) ||
+        ((OperationType == HINIT_MEMORY) && (!HiveData)) ||
+        ((Log) && (FileType != HFILE_TYPE_LOG)))
+    {
+        /* Fail the request */
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Check if this is a primary hive */
+    if (Primary)
+    {
+        /* Get the cluster size */
+        Status = ZwQueryVolumeInformationFile(Primary,
+                                              &IoStatusBlock,
+                                              &FileSizeInformation,
+                                              sizeof(FILE_FS_SIZE_INFORMATION),
+                                              FileFsSizeInformation);
+        if (!NT_SUCCESS(Status)) return Status;
+
+        /* Make sure it's not larger then the block size */
+        if (FileSizeInformation.BytesPerSector > HBLOCK_SIZE)
+        {
+            /* Fail */
+            return STATUS_REGISTRY_IO_FAILED;
+        }
 
-  if (!CmCreateRootNode (&Hive->Hive, L""))
-    {
-      HvFree (&Hive->Hive);
-      ExFreePool (Hive);
-      return STATUS_INSUFFICIENT_RESOURCES;
+        /* Otherwise, calculate the cluster */
+        Cluster = FileSizeInformation.BytesPerSector / HSECTOR_SIZE;
+        Cluster = max(1, Cluster);
+    }
+    else
+    {
+        /* Otherwise use cluster 1 */
+        Cluster = 1;
+    }
+
+    /* Allocate and clear the hive */
+    Hive = ExAllocatePoolWithTag(NonPagedPool, sizeof(EREGISTRY_HIVE), TAG_CM);
+    if (!Hive) return STATUS_INSUFFICIENT_RESOURCES;
+    RtlZeroMemory(Hive, sizeof(EREGISTRY_HIVE));
+
+    /* Initialize it */
+    Status = HvInitialize(&Hive->Hive,
+                          OperationType,
+                          HiveFlags,
+                          FileType,
+                          (ULONG_PTR)HiveData,
+                          Cluster,
+                          CmpAllocate,
+                          CmpFree,
+                          CmpFileRead,
+                          CmpFileWrite,
+                          CmpFileSetSize,
+                          CmpFileFlush,
+                          FileName);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Clear allocations and fail */
+        ExFreePool(Hive);
+        return Status;
+    }
+
+    /* Set flag */
+    Hive->Flags = HIVE_NO_FILE;
+
+    /* Check if we should verify the registry */
+    if ((OperationType == HINIT_FILE) ||
+        (OperationType == HINIT_MEMORY) ||
+        (OperationType == HINIT_MEMORY_INPLACE) ||
+        (OperationType == HINIT_MAPFILE))
+    {
+        /* Verify integrity */
+        if (CmCheckRegistry(Hive, TRUE))
+        {
+            /* Free all alocations */
+            ExFreePool(Hive);
+            return STATUS_REGISTRY_CORRUPT;
+        }
     }
 
-  Hive->Flags = HIVE_NO_FILE;
+    /* Acquire hive list lock exclusively */
+    KeEnterCriticalRegion();
+    ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
 
-  /* Acquire hive list lock exclusively */
-  KeEnterCriticalRegion();
-  ExAcquireResourceExclusiveLite (&CmiRegistryLock, TRUE);
+    /* Add the new hive to the hive list */
+    InsertTailList(&CmiHiveListHead, &Hive->HiveList);
 
-  /* Add the new hive to the hive list */
-  InsertTailList (&CmiHiveListHead,
-                 &Hive->HiveList);
+    /* Release hive list lock */
+    ExReleaseResourceLite(&CmiRegistryLock);
+    KeLeaveCriticalRegion();
 
-  /* Release hive list lock */
-  ExReleaseResourceLite (&CmiRegistryLock);
-  KeLeaveCriticalRegion();
-
-  VERIFY_REGISTRY_HIVE (Hive);
-
-  *RegistryHive = Hive;
-
-  return STATUS_SUCCESS;
-}
-
-
-NTSTATUS
-CmiCreateVolatileHive(PEREGISTRY_HIVE *RegistryHive)
-{
-  DPRINT ("CmiCreateVolatileHive() called\n");
-  return CmiCreateTempHive(RegistryHive);
+    /* Return the hive and success */
+    VERIFY_REGISTRY_HIVE(Hive);
+    *RegistryHive = Hive;
+    return STATUS_SUCCESS;
 }
 
-
 NTSTATUS
 CmiLoadHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
            IN PUNICODE_STRING FileName,
index 31fa65c..d47a1f6 100644 (file)
@@ -19,6 +19,7 @@
 #include <internal/debug.h>
 
 #include "cm.h"
+#include "..\config\cm.h"
 
 #if defined (ALLOC_PRAGMA)
 #pragma alloc_text(INIT, CmInitSystem1)
@@ -78,6 +79,30 @@ NTSTATUS
 NTAPI
 CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock);
 
+NTSTATUS
+NTAPI
+CmpInitializeHive(PEREGISTRY_HIVE *RegistryHive,
+                  ULONG OperationType,
+                  ULONG HiveFlags,
+                  ULONG FileType,
+                  PVOID HiveData OPTIONAL,
+                  HANDLE Primary,
+                  HANDLE Log,
+                  HANDLE External,
+                  PUNICODE_STRING FileName OPTIONAL,
+                  ULONG CheckFlags);
+
+USHORT
+NTAPI
+CmpCopyName(IN PHHIVE Hive,
+            IN PWCHAR Destination,
+            IN PUNICODE_STRING Source);
+
+USHORT
+NTAPI
+CmpNameSize(IN PHHIVE Hive,
+            IN PUNICODE_STRING Name);
+
 static VOID STDCALL
 CmiHiveSyncDpcRoutine(PKDPC Dpc,
                      PVOID DeferredContext,
@@ -303,6 +328,61 @@ CmpCreateObjectTypes(VOID)
     return ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &CmiKeyType);
 }
 
+BOOLEAN
+NTAPI
+CmpCreateRootNode(IN PHHIVE Hive,
+                  IN PCWSTR Name,
+                  OUT PHCELL_INDEX Index)
+{
+    UNICODE_STRING KeyName;
+    PCM_KEY_NODE KeyCell;
+    LARGE_INTEGER SystemTime;
+    PAGED_CODE();
+
+    /* Initialize the node name and allocate it */
+    RtlInitUnicodeString(&KeyName, Name);
+    *Index = HvAllocateCell(Hive,
+                            FIELD_OFFSET(CM_KEY_NODE, Name) +
+                            CmpNameSize(Hive, &KeyName),
+                            HvStable); // FIXME: , HCELL_NIL);
+    if (*Index == HCELL_NIL) return FALSE;
+
+    /* Set the cell index and get the data */
+    Hive->HiveHeader->RootCell = *Index;
+    KeyCell = (PCM_KEY_NODE)HvGetCell(Hive, *Index);
+    if (!KeyCell) return FALSE;
+
+    /* Setup the cell */
+    KeyCell->Id = (USHORT)CM_KEY_NODE_SIGNATURE;;
+    KeyCell->Flags = KEY_HIVE_ENTRY | KEY_NO_DELETE;
+    KeQuerySystemTime(&SystemTime);
+    KeyCell->LastWriteTime = SystemTime;
+    KeyCell->Parent = HCELL_NIL;
+    KeyCell->SubKeyCounts[HvStable] = 0;
+    KeyCell->SubKeyCounts[HvVolatile] = 0;
+    KeyCell->SubKeyLists[HvStable] = HCELL_NIL;
+    KeyCell->SubKeyLists[HvVolatile] = HCELL_NIL;
+    KeyCell->ValueList.Count = 0;
+    KeyCell->ValueList.List = HCELL_NIL;
+    KeyCell->SecurityKeyOffset = HCELL_NIL;
+    KeyCell->ClassNameOffset = HCELL_NIL;
+    KeyCell->ClassSize = 0;
+
+    /* Copy the name (this will also set the length) */
+    KeyCell->NameSize = CmpCopyName(Hive, (PWCHAR)KeyCell->Name, &KeyName);
+
+    /* Check if the name was compressed */
+    if (KeyCell->NameSize < KeyName.Length)
+    {
+        /* Set the flag */
+        KeyCell->Flags |= KEY_COMP_NAME;
+    }
+
+    /* Return success */
+    HvReleaseCell(Hive, *Index);
+    return TRUE;
+}
+
 BOOLEAN
 NTAPI
 CmpCreateRegistryRoot(VOID)
@@ -311,7 +391,16 @@ CmpCreateRegistryRoot(VOID)
     OBJECT_ATTRIBUTES ObjectAttributes;
     PKEY_OBJECT RootKey;
     HANDLE RootKeyHandle;
+    HCELL_INDEX RootIndex;
     NTSTATUS Status;
+    PAGED_CODE();
+
+    /* Setup the root node */
+    if (!CmpCreateRootNode(&CmiVolatileHive->Hive, L"REGISTRY", &RootIndex))
+    {
+        /* We failed */
+        return FALSE;
+    }
 
     /* Create '\Registry' key. */
     RtlInitUnicodeString(&KeyName, REG_ROOT_KEY_NAME);
@@ -333,8 +422,8 @@ CmpCreateRegistryRoot(VOID)
 
     /* Setup the root key */
     RootKey->RegistryHive = CmiVolatileHive;
-    RootKey->KeyCellOffset = CmiVolatileHive->Hive.HiveHeader->RootCell;
-    RootKey->KeyCell = HvGetCell(&CmiVolatileHive->Hive, RootKey->KeyCellOffset);
+    RootKey->KeyCellOffset = RootIndex;
+    RootKey->KeyCell = HvGetCell(&CmiVolatileHive->Hive, RootIndex);
     RootKey->ParentKey = RootKey;
     RootKey->Flags = 0;
     RootKey->SubKeyCounts = 0;
@@ -421,8 +510,17 @@ CmInitSystem1(VOID)
         KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 1, Status, 0);
     }
 
-    /* Build volatile registry store */
-    Status = CmiCreateVolatileHive(&CmiVolatileHive);
+    /* Build the master hive */
+    Status = CmpInitializeHive(&CmiVolatileHive,
+                               HINIT_CREATE,
+                               HIVE_VOLATILE,
+                               HFILE_TYPE_PRIMARY,
+                               NULL,
+                               NULL,
+                               NULL,
+                               NULL,
+                               NULL,
+                               0);
     if (!NT_SUCCESS(Status))
     {
         /* Bugcheck */
@@ -433,7 +531,7 @@ CmInitSystem1(VOID)
     if (!CmpCreateRegistryRoot())
     {
         /* Bugcheck */
-        KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 4, 0, 0);
+        KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 3, 0, 0);
     }
 
     /* Create '\Registry\Machine' key. */
index f01d55a..5be366c 100644 (file)
@@ -84,7 +84,7 @@
 //\r
 // Cell Masks\r
 //\r
-#define HCELL_NIL                                       0\r
+#define HCELL_NIL                                       -1\r
 #define HCELL_CACHED                                    1\r
 \r
 //\r
 #define CM_DELAYS_PER_PAGE                       \\r
     PAGE_SIZE / sizeof(CM_DELAYED_CLOSE_ENTRY)\r
 \r
+#ifndef __INCLUDE_CM_H\r
+\r
 //\r
 // Key Hash\r
 //\r
@@ -984,3 +986,5 @@ extern BOOLEAN ExpInTextModeSetup;
 // Inlined functions\r
 //\r
 #include "cm_x.h"\r
+\r
+#endif\r
index 7affc6f..81801c2 100644 (file)
 \r
 /* FUNCTIONS *****************************************************************/\r
 \r
+USHORT\r
+NTAPI\r
+CmpCopyName(IN PHHIVE Hive,\r
+            IN PWCHAR Destination,\r
+            IN PUNICODE_STRING Source)\r
+{\r
+    ULONG i;\r
+\r
+    /* Check for old hives */\r
+    if (Hive->Version == 1)\r
+    {\r
+        /* Just copy the source directly */\r
+        RtlCopyMemory(Destination, Source->Buffer, Source->Length);\r
+        return Source->Length;\r
+    }\r
+\r
+    /* For new versions, check for compressed name */\r
+    for (i = 0; i < (Source->Length / sizeof(WCHAR)); i++)\r
+    {\r
+        /* Check if the name is non compressed */\r
+        if (Source->Buffer[i] > (UCHAR)-1)\r
+        {\r
+            /* Do the copy */\r
+            RtlCopyMemory(Destination, Source->Buffer, Source->Length);\r
+            return Source->Length;\r
+        }\r
+\r
+        /* Copy this character */\r
+        Destination[i] = Source->Buffer[i];\r
+    }\r
+\r
+    /* Compressed name, return length */\r
+    return Source->Length / sizeof(WCHAR);\r
+}\r
+\r
+USHORT\r
+NTAPI\r
+CmpNameSize(IN PHHIVE Hive,\r
+            IN PUNICODE_STRING Name)\r
+{\r
+    ULONG i;\r
+\r
+    /* For old hives, just retun the length */\r
+    if (Hive->Version == 1) return Name->Length;\r
+\r
+    /* For new versions, check for compressed name */\r
+    for (i = 0; i < (Name->Length / sizeof(WCHAR)); i++)\r
+    {\r
+        /* Check if the name is non compressed */\r
+        if (Name->Buffer[i] > (UCHAR)-1) return Name->Length;\r
+    }\r
+\r
+    /* Compressed name, return length */\r
+    return Name->Length / sizeof(WCHAR);\r
+}\r
+\r
 LONG\r
 NTAPI\r
 CmpCompareCompressedName(IN PUNICODE_STRING SearchName,\r