[VCDROM] Implement the virtual CD-ROM class driver.
[reactos.git] / ntoskrnl / config / cminit.c
index 84749d3..bf055fd 100644 (file)
@@ -16,7 +16,7 @@
 
 NTSTATUS
 NTAPI
-CmpInitializeHive(OUT PCMHIVE *RegistryHive,
+CmpInitializeHive(OUT PCMHIVE *CmHive,
                   IN ULONG OperationType,
                   IN ULONG HiveFlags,
                   IN ULONG FileType,
@@ -28,26 +28,27 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive,
                   IN ULONG CheckFlags)
 {
     PCMHIVE Hive;
-    FILE_STANDARD_INFORMATION FileInformation;
     IO_STATUS_BLOCK IoStatusBlock;
     FILE_FS_SIZE_INFORMATION FileSizeInformation;
     NTSTATUS Status;
     ULONG Cluster;
 
     /* Assume failure */
-    *RegistryHive = NULL;
+    *CmHive = 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.
+     * - An external hive that is also internal.
+     * - A log hive that is not a primary hive too.
+     * - A volatile hive that is linked to permanent storage,
+     *   unless this hive is a shared system hive.
+     * - An in-memory initialization without hive data.
+     * - A log hive that is not linked to a correct file type.
      */
     if (((External) && ((Primary) || (Log))) ||
         ((Log) && !(Primary)) ||
-        ((HiveFlags & HIVE_VOLATILE) && ((Primary) || (External) || (Log))) ||
+        (!(CmpShareSystemHives) && (HiveFlags & HIVE_VOLATILE) &&
+            ((Primary) || (External) || (Log))) ||
         ((OperationType == HINIT_MEMORY) && (!HiveData)) ||
         ((Log) && (FileType != HFILE_TYPE_LOG)))
     {
@@ -84,7 +85,7 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive,
     }
 
     /* Allocate the hive */
-    Hive = ExAllocatePoolWithTag(NonPagedPool, sizeof(CMHIVE), TAG_CM);
+    Hive = ExAllocatePoolWithTag(NonPagedPool, sizeof(CMHIVE), TAG_CMHIVE);
     if (!Hive) return STATUS_INSUFFICIENT_RESOURCES;
 
     /* Setup null fields */
@@ -115,23 +116,23 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive,
     /* Allocate the view log */
     Hive->ViewLock = ExAllocatePoolWithTag(NonPagedPool,
                                            sizeof(KGUARDED_MUTEX),
-                                           TAG_CM);
+                                           TAG_CMHIVE);
     if (!Hive->ViewLock)
     {
         /* Cleanup allocation and fail */
-        ExFreePoolWithTag(Hive, TAG_CM);
+        ExFreePoolWithTag(Hive, TAG_CMHIVE);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
     /* Allocate the flush lock */
     Hive->FlusherLock = ExAllocatePoolWithTag(NonPagedPool,
                                               sizeof(ERESOURCE),
-                                              TAG_CM);
+                                              TAG_CMHIVE);
     if (!Hive->FlusherLock)
     {
         /* Cleanup allocations and fail */
-        ExFreePoolWithTag(Hive->ViewLock, TAG_CM);
-        ExFreePoolWithTag(Hive, TAG_CM);
+        ExFreePoolWithTag(Hive->ViewLock, TAG_CMHIVE);
+        ExFreePoolWithTag(Hive, TAG_CMHIVE);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
@@ -169,26 +170,11 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive,
     Hive->Flags = 0;
     Hive->FlushCount = 0;
 
-    /* Set flags */
-    Hive->Flags = HiveFlags;
-
-    /* Check if this is a primary */
-    if (Primary)
-    {
-        /* Check how large the file is */
-        ZwQueryInformationFile(Primary,
-                               &IoStatusBlock,
-                               &FileInformation,
-                               sizeof(FileInformation),
-                               FileStandardInformation);
-        Cluster = FileInformation.EndOfFile.LowPart;
-    }
-
     /* Initialize it */
     Status = HvInitialize(&Hive->Hive,
                           OperationType,
-                          FileType,
                           HiveFlags,
+                          FileType,
                           HiveData,
                           CmpAllocate,
                           CmpFree,
@@ -202,9 +188,9 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive,
     {
         /* Cleanup allocations and fail */
         ExDeleteResourceLite(Hive->FlusherLock);
-        ExFreePoolWithTag(Hive->FlusherLock, TAG_CM);
-        ExFreePoolWithTag(Hive->ViewLock, TAG_CM);
-        ExFreePoolWithTag(Hive, TAG_CM);
+        ExFreePoolWithTag(Hive->FlusherLock, TAG_CMHIVE);
+        ExFreePoolWithTag(Hive->ViewLock, TAG_CMHIVE);
+        ExFreePoolWithTag(Hive, TAG_CMHIVE);
         return Status;
     }
 
@@ -220,9 +206,9 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive,
         {
             /* Cleanup allocations and fail */
             ExDeleteResourceLite(Hive->FlusherLock);
-            ExFreePoolWithTag(Hive->FlusherLock, TAG_CM);
-            ExFreePoolWithTag(Hive->ViewLock, TAG_CM);
-            ExFreePoolWithTag(Hive, TAG_CM);
+            ExFreePoolWithTag(Hive->FlusherLock, TAG_CMHIVE);
+            ExFreePoolWithTag(Hive->ViewLock, TAG_CMHIVE);
+            ExFreePoolWithTag(Hive, TAG_CMHIVE);
             return STATUS_REGISTRY_CORRUPT;
         }
     }
@@ -237,7 +223,7 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive,
     ExReleasePushLock(&CmpHiveListHeadLock);
 
     /* Return the hive and success */
-    *RegistryHive = (PCMHIVE)Hive;
+    *CmHive = Hive;
     return STATUS_SUCCESS;
 }
 
@@ -250,16 +236,25 @@ CmpDestroyHive(IN PCMHIVE CmHive)
     RemoveEntryList(&CmHive->HiveList);
     ExReleasePushLock(&CmpHiveListHeadLock);
 
+    /* Destroy the security descriptor cache */
+    CmpDestroySecurityCache(CmHive);
+
+    /* Destroy the view list */
+    CmpDestroyHiveViewList(CmHive);
+
     /* Delete the flusher lock */
     ExDeleteResourceLite(CmHive->FlusherLock);
-    ExFreePoolWithTag(CmHive->FlusherLock, TAG_CM);
+    ExFreePoolWithTag(CmHive->FlusherLock, TAG_CMHIVE);
 
     /* Delete the view lock */
-    ExFreePoolWithTag(CmHive->ViewLock, TAG_CM);
+    ExFreePoolWithTag(CmHive->ViewLock, TAG_CMHIVE);
 
-    /* Free the hive */
+    /* Free the hive storage */
     HvFree(&CmHive->Hive);
 
+    /* Free the hive */
+    CmpFree(CmHive, TAG_CM);
+
     return STATUS_SUCCESS;
 }
 
@@ -316,7 +311,7 @@ CmpOpenHiveFiles(IN PCUNICODE_STRING BaseName,
         /* Build the full name */
         FullName.Buffer = NameBuffer;
         FullName.MaximumLength = Length;
-        RtlAppendUnicodeStringToString(&FullName, BaseName);
+        RtlCopyUnicodeString(&FullName, BaseName);
     }
     else
     {
@@ -383,15 +378,16 @@ CmpOpenHiveFiles(IN PCUNICODE_STRING BaseName,
     /* Check if anything failed until now */
     if (!NT_SUCCESS(Status))
     {
+        DPRINT1("ZwCreateFile(%wZ) failed, Status 0x%08lx.\n", ObjectAttributes.ObjectName, Status);
+
         /* Close handles and free buffers */
         if (NameBuffer) ExFreePoolWithTag(NameBuffer, TAG_CM);
         ObDereferenceObject(Event);
         ZwClose(EventHandle);
-        DPRINT1("ZwCreateFile failed : %lx.\n", Status);
         *Primary = NULL;
         return Status;
     }
-                          
+
     if (MarkAsSystemHive)
     {
         /* We opened it, mark it as a system hive */
@@ -626,3 +622,19 @@ CmpOpenHiveFiles(IN PCUNICODE_STRING BaseName,
     ZwClose(EventHandle);
     return STATUS_SUCCESS;
 }
+
+VOID
+NTAPI
+CmpCloseHiveFiles(IN PCMHIVE Hive)
+{
+    ULONG i;
+
+    for (i = 0; i < HFILE_TYPE_MAX; i++)
+    {
+        if (Hive->FileHandles[i] != NULL)
+        {
+            ZwClose(Hive->FileHandles[i]);
+            Hive->FileHandles[i] = NULL;
+        }
+    }
+}