[VCDROM] Implement the virtual CD-ROM class driver.
[reactos.git] / ntoskrnl / config / cminit.c
index 0f297c6..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,
@@ -197,13 +183,14 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive,
                           CmpFileRead,
                           CmpFileFlush,
                           Cluster,
-                          (PUNICODE_STRING)FileName);
+                          FileName);
     if (!NT_SUCCESS(Status))
     {
         /* Cleanup allocations and fail */
-        ExFreePoolWithTag(Hive->FlusherLock, TAG_CM);
-        ExFreePoolWithTag(Hive->ViewLock, TAG_CM);
-        ExFreePoolWithTag(Hive, TAG_CM);
+        ExDeleteResourceLite(Hive->FlusherLock);
+        ExFreePoolWithTag(Hive->FlusherLock, TAG_CMHIVE);
+        ExFreePoolWithTag(Hive->ViewLock, TAG_CMHIVE);
+        ExFreePoolWithTag(Hive, TAG_CMHIVE);
         return Status;
     }
 
@@ -214,12 +201,14 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive,
         (OperationType == HINIT_MAPFILE))
     {
         /* Verify integrity */
-        if (CmCheckRegistry((PCMHIVE)Hive, TRUE))
+        ULONG CheckStatus = CmCheckRegistry(Hive, CheckFlags);
+        if (CheckStatus != 0)
         {
             /* Cleanup allocations and fail */
-            ExFreePoolWithTag(Hive->FlusherLock, TAG_CM);
-            ExFreePoolWithTag(Hive->ViewLock, TAG_CM);
-            ExFreePoolWithTag(Hive, TAG_CM);
+            ExDeleteResourceLite(Hive->FlusherLock);
+            ExFreePoolWithTag(Hive->FlusherLock, TAG_CMHIVE);
+            ExFreePoolWithTag(Hive->ViewLock, TAG_CMHIVE);
+            ExFreePoolWithTag(Hive, TAG_CMHIVE);
             return STATUS_REGISTRY_CORRUPT;
         }
     }
@@ -234,7 +223,38 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive,
     ExReleasePushLock(&CmpHiveListHeadLock);
 
     /* Return the hive and success */
-    *RegistryHive = (PCMHIVE)Hive;
+    *CmHive = Hive;
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+CmpDestroyHive(IN PCMHIVE CmHive)
+{
+    /* Remove the hive from the list */
+    ExAcquirePushLockExclusive(&CmpHiveListHeadLock);
+    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_CMHIVE);
+
+    /* Delete the view lock */
+    ExFreePoolWithTag(CmHive->ViewLock, TAG_CMHIVE);
+
+    /* Free the hive storage */
+    HvFree(&CmHive->Hive);
+
+    /* Free the hive */
+    CmpFree(CmHive, TAG_CM);
+
     return STATUS_SUCCESS;
 }
 
@@ -291,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
     {
@@ -358,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 */
@@ -601,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;
+        }
+    }
+}