- Rename CmiInitNonVolatileRegistryHive to CmiInitHiveFromFile.
authorAlex Ionescu <aionescu@gmail.com>
Sat, 12 May 2007 08:27:28 +0000 (08:27 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Sat, 12 May 2007 08:27:28 +0000 (08:27 +0000)
- Remove CmiCreateNewRegFile and the way new hives were created, saved, then re-reloded. Instead initialize a new hive only once.
- Add support for calling either HINIT_FILE or HINIT_CREATE with a hive, and support log file hives now.
- Make hacks/oldcm differences smoother, and copy routine to cmsysini.c, since it's now compatible with the rewrite. This is probably the last function that was easily convertible/modifiable.

svn path=/trunk/; revision=26716

reactos/ntoskrnl/cm/cm.h
reactos/ntoskrnl/cm/regfile.c
reactos/ntoskrnl/config/cm.h
reactos/ntoskrnl/config/cminit.c
reactos/ntoskrnl/config/cmsysini.c

index 5454d6b..28bb4c6 100644 (file)
@@ -445,6 +445,14 @@ CmpOpenHiveFiles(IN PUNICODE_STRING BaseName,
                  IN BOOLEAN NoBuffering,
                  OUT PULONG ClusterSize OPTIONAL);
 
+NTSTATUS
+NTAPI
+CmpInitHiveFromFile(IN PUNICODE_STRING HiveName,
+                    IN ULONG HiveFlags,
+                    OUT PEREGISTRY_HIVE *Hive,
+                    IN OUT PBOOLEAN New,
+                    IN ULONG CheckFlags);
+
 #if 0
 static __inline PVOID xHvGetCell(char *file, int line, PHHIVE Hive, HCELL_INDEX Cell)
 {
index ffc2d6c..5b8e3d5 100644 (file)
 /* FUNCTIONS ****************************************************************/
 
 NTSTATUS
-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);
-
-static NTSTATUS
-CmiCreateNewRegFile(HANDLE FileHandle)
+CmiLoadHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
+            IN PUNICODE_STRING FileName,
+            IN ULONG Flags)
 {
-  PEREGISTRY_HIVE CmHive;
-  PHHIVE Hive;
-  NTSTATUS Status;
-
-  CmHive = CmpAllocate(sizeof(EREGISTRY_HIVE), TRUE);
-  CmHive->HiveHandle = FileHandle;
-  Status = HvInitialize(&CmHive->Hive, HV_OPERATION_CREATE_HIVE, 0, 0, 0, 0,
-                        CmpAllocate, CmpFree,
-                        CmpFileRead, CmpFileWrite, CmpFileSetSize,
-                        CmpFileFlush, NULL);
-  if (!NT_SUCCESS(Status))
-    {
-      return FALSE;
-    }
-
-  /* Init root key cell */
-  Hive = &CmHive->Hive;
-  if (!CmCreateRootNode(Hive, L""))
-    {
-      HvFree (Hive);
-      return FALSE;
-    }
-
-  Status = HvWriteHive(Hive) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
-
-  HvFree (Hive);
+    PEREGISTRY_HIVE Hive;
+    NTSTATUS Status;
+    BOOLEAN Allocate = TRUE;
 
-  return(Status);
-}
+    DPRINT ("CmiLoadHive(Filename %wZ)\n", FileName);
 
-static NTSTATUS
-CmiInitNonVolatileRegistryHive (IN ULONG HiveFlags,
-                                IN PUNICODE_STRING HiveName,
-                                OUT PEREGISTRY_HIVE *Hive)
-{
-    ULONG CreateDisposition, LogDisposition;
-    HANDLE FileHandle, LogHandle;
-    NTSTATUS Status;
-    //ULONG Operation;
-    PEREGISTRY_HIVE NewHive;
-
-    *Hive = NULL;
-
-    Status = CmpOpenHiveFiles(HiveName,
-                              NULL, //L".LOG",
-                              &FileHandle,
-                              &LogHandle,
-                              &CreateDisposition,
-                              &LogDisposition,
-                              TRUE,
-                              FALSE,
-                              TRUE,
-                              NULL);
-    if (CreateDisposition == FILE_CREATED)
-    {
-        Status = CmiCreateNewRegFile(FileHandle);
-        if (!NT_SUCCESS(Status))
-        {
-            DPRINT("CmiCreateNewRegFile() failed (Status %lx)\n", Status);
-            ZwClose(FileHandle);
-            return(Status);
-        }
-    }
+    if (Flags & ~REG_NO_LAZY_FLUSH) return STATUS_INVALID_PARAMETER;
 
-    Status = CmpInitializeHive(&NewHive,
-                               HINIT_FILE,
-                               HiveFlags,
-                               HFILE_TYPE_PRIMARY,
-                               NULL,
-                               FileHandle,
-                               NULL,
-                               NULL,
-                               HiveName,
-                               0);
+    Status = CmpInitHiveFromFile(FileName,
+                                 (Flags & REG_NO_LAZY_FLUSH) ? HIVE_NO_SYNCH : 0,
+                                 &Hive,
+                                 &Allocate,
+                                 0);
     if (!NT_SUCCESS(Status))
     {
-        DPRINT1("Failed to open hive\n");
-        ZwClose(FileHandle);
+        DPRINT1("CmpInitHiveFromFile() failed (Status %lx)\n", Status);
+        ExFreePool(Hive);
         return Status;
     }
 
-    CmPrepareHive(&NewHive->Hive);
-    NewHive->Flags = HiveFlags;
-
-    RtlCreateUnicodeString(&NewHive->HiveFileName, HiveName->Buffer);
-
-    /* Close the hive file */
-    ZwClose(FileHandle);
-
-    *Hive = NewHive;
-    return Status;
-}
-
-NTSTATUS
-CmiLoadHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
-           IN PUNICODE_STRING FileName,
-           IN ULONG Flags)
-{
-  PEREGISTRY_HIVE Hive;
-  NTSTATUS Status;
-
-  DPRINT ("CmiLoadHive(Filename %wZ)\n", FileName);
-
-  if (Flags & ~REG_NO_LAZY_FLUSH)
-    return STATUS_INVALID_PARAMETER;
-
-  Status = CmiInitNonVolatileRegistryHive ((Flags & REG_NO_LAZY_FLUSH) ? HIVE_NO_SYNCH : 0,
-                                          FileName,
-                       &Hive);
-  if (!NT_SUCCESS (Status))
-    {
-      DPRINT1 ("CmiInitNonVolatileRegistryHive() failed (Status %lx)\n", Status);
-      ExFreePool (Hive);
-      return Status;
-    }
-
-  Status = CmiConnectHive (KeyObjectAttributes,
-                          Hive);
-  if (!NT_SUCCESS(Status))
+    Status = CmiConnectHive(KeyObjectAttributes, Hive);
+    if (!NT_SUCCESS(Status))
     {
-      DPRINT1 ("CmiConnectHive() failed (Status %lx)\n", Status);
-//      CmiRemoveRegistryHive (Hive);
+        DPRINT1 ("CmiConnectHive() failed (Status %lx)\n", Status);
+        //      CmiRemoveRegistryHive (Hive);
     }
 
-  DPRINT ("CmiLoadHive() done\n");
-
-  return Status;
+    DPRINT ("CmiLoadHive() done\n");
+    return Status;
 }
 
 
 NTSTATUS
-CmiRemoveRegistryHive(PEREGISTRY_HIVE RegistryHive)
+CmiRemoveRegistaryHive(PEREGISTRY_HIVE RegistryHive)
 {
   /* Remove hive from hive list */
   RemoveEntryList (&RegistryHive->HiveList);
index d0d2786..6b0c7a3 100644 (file)
@@ -846,6 +846,21 @@ CmpLinkHiveToMaster(
     IN PSECURITY_DESCRIPTOR SecurityDescriptor\r
 );\r
 \r
+NTSTATUS\r
+NTAPI\r
+CmpOpenHiveFiles(\r
+    IN PUNICODE_STRING BaseName,\r
+    IN PWCHAR Extension OPTIONAL,\r
+    IN PHANDLE Primary,\r
+    IN PHANDLE Log,\r
+    IN PULONG PrimaryDisposition,\r
+    IN PULONG LogDisposition,\r
+    IN BOOLEAN CreateAllowed,\r
+    IN BOOLEAN MarkAsSystemHive,\r
+    IN BOOLEAN NoBuffering,\r
+    OUT PULONG ClusterSize OPTIONAL\r
+);\r
+\r
 //\r
 // Registry Utility Functions\r
 //\r
index bcf41ad..cb41436 100644 (file)
@@ -169,6 +169,7 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive,
     /* Set flags */\r
     Hive->Flags = HiveFlags;\r
     Hive->HiveHandle = Primary;\r
+    Hive->LogHandle = Log;\r
 \r
     /* Check how large the file is */\r
     ZwQueryInformationFile(Primary,\r
index e3ce128..d2c6a7d 100644 (file)
 KGUARDED_MUTEX CmpSelfHealQueueLock;\r
 LIST_ENTRY CmpSelfHealQueueListHead;\r
 PEPROCESS CmpSystemProcess;\r
+BOOLEAN HvShutdownComplete;\r
 \r
 /* FUNCTIONS *****************************************************************/\r
 \r
+NTSTATUS\r
+NTAPI\r
+CmpInitHiveFromFile(IN PUNICODE_STRING HiveName,\r
+                    IN ULONG HiveFlags,\r
+                    OUT PCMHIVE *Hive,\r
+                    IN OUT PBOOLEAN New,\r
+                    IN ULONG CheckFlags)\r
+{\r
+    ULONG HiveDisposition, LogDisposition;\r
+    HANDLE FileHandle = NULL, LogHandle = NULL;\r
+    NTSTATUS Status;\r
+    ULONG Operation, FileType;\r
+    PEREGISTRY_HIVE NewHive;\r
+    PAGED_CODE();\r
+\r
+    /* Assume failure */\r
+    *Hive = NULL;\r
+\r
+    /* Open or create the hive files */\r
+    Status = CmpOpenHiveFiles(HiveName,\r
+                              L".LOG",\r
+                              &FileHandle,\r
+                              &LogHandle,\r
+                              &HiveDisposition,\r
+                              &LogDisposition,\r
+                              *New,\r
+                              FALSE,\r
+                              TRUE,\r
+                              NULL);\r
+    if (!NT_SUCCESS(Status)) return Status;\r
+\r
+    /* Check if we have a log handle */\r
+    FileType = (LogHandle) ? HFILE_TYPE_LOG : HFILE_TYPE_PRIMARY;\r
+\r
+    /* Check if we created or opened the hive */\r
+    if (HiveDisposition == FILE_CREATED)\r
+    {\r
+        /* Do a create operation */\r
+        Operation = HINIT_CREATE;\r
+        *New = TRUE;\r
+    }\r
+    else\r
+    {\r
+        /* Open it as a file */\r
+        Operation = HINIT_FILE;\r
+        *New = FALSE;\r
+    }\r
+\r
+    /* Check if we're sharing hives */\r
+    if (CmpShareSystemHives)\r
+    {\r
+        /* Then force using the primary hive */\r
+        FileType = HFILE_TYPE_PRIMARY;\r
+        if (LogHandle)\r
+        {\r
+            /* Get rid of the log handle */\r
+            ZwClose(LogHandle);\r
+            LogHandle = NULL;\r
+        }\r
+    }\r
+\r
+    /* Check if we're too late */\r
+    if (HvShutdownComplete)\r
+    {\r
+        /* Fail */\r
+        ZwClose(FileHandle);\r
+        if (LogHandle) ZwClose(LogHandle);\r
+        return STATUS_TOO_LATE;\r
+    }\r
+\r
+    /* Initialize the hive */\r
+    Status = CmpInitializeHive((PCMHIVE*)&NewHive,\r
+                               Operation,\r
+                               HiveFlags,\r
+                               FileType,\r
+                               NULL,\r
+                               FileHandle,\r
+                               LogHandle,\r
+                               NULL,\r
+                               HiveName,\r
+                               0);\r
+    if (!NT_SUCCESS(Status))\r
+    {\r
+        /* Fail */\r
+        ZwClose(FileHandle);\r
+        if (LogHandle) ZwClose(LogHandle);\r
+        return Status;\r
+    }\r
+\r
+    /* Success, return hive */\r
+    *Hive = (PCMHIVE)NewHive;\r
+\r
+    /* ROS: Init root key cell and prepare the hive */\r
+    if (Operation == HINIT_CREATE) CmCreateRootNode(&NewHive->Hive, L"");\r
+    CmPrepareHive(&NewHive->Hive);\r
+\r
+    /* Duplicate the hive name */\r
+    NewHive->HiveFileName.Buffer = ExAllocatePoolWithTag(PagedPool,\r
+                                                         HiveName->Length,\r
+                                                         TAG_CM);\r
+    if (NewHive->HiveFileName.Buffer)\r
+    {\r
+        /* Copy the string */\r
+        RtlCopyMemory(NewHive->HiveFileName.Buffer,\r
+                      HiveName->Buffer,\r
+                      HiveName->Length);\r
+        NewHive->HiveFileName.Length = HiveName->Length;\r
+        NewHive->HiveFileName.MaximumLength = HiveName->MaximumLength;\r
+    }\r
+\r
+    /* ROS: Close the hive files */\r
+    ZwClose(FileHandle);\r
+    if (LogHandle) ZwClose(LogHandle);\r
+\r
+    /* Return success */\r
+    return STATUS_SUCCESS;\r
+}\r
+\r
 NTSTATUS\r
 NTAPI\r
 CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock)\r