[NTOSKRNL]
[reactos.git] / reactos / ntoskrnl / config / cminit.c
index 6d85ef7..8689e8e 100644 (file)
@@ -116,13 +116,24 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive,
     Hive->ViewLock = ExAllocatePoolWithTag(NonPagedPool,
                                            sizeof(KGUARDED_MUTEX),
                                            TAG_CM);
-    if (!Hive->ViewLock) return STATUS_INSUFFICIENT_RESOURCES;
+    if (!Hive->ViewLock)
+    {
+        /* Cleanup allocation and fail */
+        ExFreePoolWithTag(Hive, TAG_CM);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
 
     /* Allocate the flush lock */
     Hive->FlusherLock = ExAllocatePoolWithTag(NonPagedPool,
                                               sizeof(ERESOURCE),
                                               TAG_CM);
-    if (!Hive->FlusherLock) return STATUS_INSUFFICIENT_RESOURCES;
+    if (!Hive->FlusherLock)
+    {
+        /* Cleanup allocations and fail */
+        ExFreePoolWithTag(Hive->ViewLock, TAG_CM);
+        ExFreePoolWithTag(Hive, TAG_CM);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
 
     /* Setup the handles */
     Hive->FileHandles[HFILE_TYPE_PRIMARY] = Primary;
@@ -186,13 +197,13 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive,
                           CmpFileRead,
                           CmpFileFlush,
                           Cluster,
-                          (PUNICODE_STRING)FileName);
+                          FileName);
     if (!NT_SUCCESS(Status))
     {
-        /* Clear allocations and fail */
-        ExFreePool(Hive->ViewLock);
-        ExFreePool(Hive->FlusherLock);
-        ExFreePool(Hive);
+        /* Cleanup allocations and fail */
+        ExFreePoolWithTag(Hive->FlusherLock, TAG_CM);
+        ExFreePoolWithTag(Hive->ViewLock, TAG_CM);
+        ExFreePoolWithTag(Hive, TAG_CM);
         return Status;
     }
 
@@ -205,10 +216,10 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive,
         /* Verify integrity */
         if (CmCheckRegistry((PCMHIVE)Hive, TRUE))
         {
-            /* Free all alocations */
-            ExFreePool(Hive->ViewLock);
-            ExFreePool(Hive->FlusherLock);
-            ExFreePool(Hive);
+            /* Cleanup allocations and fail */
+            ExFreePoolWithTag(Hive->FlusherLock, TAG_CM);
+            ExFreePoolWithTag(Hive->ViewLock, TAG_CM);
+            ExFreePoolWithTag(Hive, TAG_CM);
             return STATUS_REGISTRY_CORRUPT;
         }
     }
@@ -227,14 +238,36 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive,
     return STATUS_SUCCESS;
 }
 
+NTSTATUS
+NTAPI
+CmpDestroyHive(IN PCMHIVE CmHive)
+{
+    /* Remove the hive from the list */
+    ExAcquirePushLockExclusive(&CmpHiveListHeadLock);
+    RemoveEntryList(&CmHive->HiveList);
+    ExReleasePushLock(&CmpHiveListHeadLock);
+
+    /* Delete the flusher lock */
+    ExDeleteResourceLite(CmHive->FlusherLock);
+    ExFreePoolWithTag(CmHive->FlusherLock, TAG_CM);
+
+    /* Delete the view lock */
+    ExFreePoolWithTag(CmHive->ViewLock, TAG_CM);
+
+    /* Free the hive */
+    HvFree(&CmHive->Hive);
+
+    return STATUS_SUCCESS;
+}
+
 NTSTATUS
 NTAPI
 CmpOpenHiveFiles(IN PCUNICODE_STRING BaseName,
                  IN PCWSTR Extension OPTIONAL,
-                 IN PHANDLE Primary,
-                 IN PHANDLE Log,
-                 IN PULONG PrimaryDisposition,
-                 IN PULONG LogDisposition,
+                 OUT PHANDLE Primary,
+                 OUT PHANDLE Log,
+                 OUT PULONG PrimaryDisposition,
+                 OUT PULONG LogDisposition,
                  IN BOOLEAN CreateAllowed,
                  IN BOOLEAN MarkAsSystemHive,
                  IN BOOLEAN NoBuffering,
@@ -265,7 +298,7 @@ CmpOpenHiveFiles(IN PCUNICODE_STRING BaseName,
     if (Extension)
     {
         /* Update the name length */
-        Length += wcslen(Extension) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
+        Length += (USHORT)wcslen(Extension) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
 
         /* Allocate the buffer for the full name */
         NameBuffer = ExAllocatePoolWithTag(PagedPool, Length, TAG_CM);
@@ -309,10 +342,11 @@ CmpOpenHiveFiles(IN PCUNICODE_STRING BaseName,
     }
 
     /* Setup the flags */
-    IoFlags = FILE_OPEN_FOR_BACKUP_INTENT |
+    // FIXME : FILE_OPEN_FOR_BACKUP_INTENT is unimplemented and breaks 3rd stage boot
+    IoFlags = //FILE_OPEN_FOR_BACKUP_INTENT |
               FILE_NO_COMPRESSION |
               FILE_RANDOM_ACCESS |
-              (NoBuffering) ? FILE_NO_INTERMEDIATE_BUFFERING : 0;
+              (NoBuffering ? FILE_NO_INTERMEDIATE_BUFFERING : 0);
 
     /* Set share and access modes */
     if ((CmpMiniNTBoot) && (CmpShareSystemHives))
@@ -333,7 +367,7 @@ CmpOpenHiveFiles(IN PCUNICODE_STRING BaseName,
 
     /* Now create the file */
     Status = ZwCreateFile(Primary,
-                          DesiredAccess,
+                          DesiredAccess | SYNCHRONIZE,
                           &ObjectAttributes,
                           &IoStatusBlock,
                           NULL,
@@ -343,7 +377,19 @@ CmpOpenHiveFiles(IN PCUNICODE_STRING BaseName,
                           FILE_SYNCHRONOUS_IO_NONALERT | IoFlags,
                           NULL,
                           0);
-    if ((NT_SUCCESS(Status)) && (MarkAsSystemHive))
+    /* Check if anything failed until now */
+    if (!NT_SUCCESS(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 */
         Status = ZwFsControlFile(*Primary,
@@ -370,18 +416,16 @@ CmpOpenHiveFiles(IN PCUNICODE_STRING BaseName,
         /* If we don't support it, ignore the failure */
         if (Status == STATUS_INVALID_DEVICE_REQUEST) Status = STATUS_SUCCESS;
 
-        /* If we failed, close the handle */
-        if (!NT_SUCCESS(Status)) ZwClose(*Primary);
-    }
-
-    /* Check if anything failed until now */
-    if (!NT_SUCCESS(Status))
-    {
-        /* Close handles and free buffers */
-        if (NameBuffer) ExFreePool(NameBuffer);
-        ObDereferenceObject(Event);
-        ZwClose(EventHandle);
-        return Status;
+        if (!NT_SUCCESS(Status))
+        {
+            /* Close handles and free buffers */
+            if (NameBuffer) ExFreePoolWithTag(NameBuffer, TAG_CM);
+            ObDereferenceObject(Event);
+            ZwClose(EventHandle);
+            ZwClose(*Primary);
+            *Primary = NULL;
+            return Status;
+        }
     }
 
     /* Disable compression */
@@ -407,7 +451,7 @@ CmpOpenHiveFiles(IN PCUNICODE_STRING BaseName,
     }
 
     /* Get the disposition */
-    *PrimaryDisposition = IoStatusBlock.Information;
+    *PrimaryDisposition = (ULONG)IoStatusBlock.Information;
     if (IoStatusBlock.Information != FILE_CREATED)
     {
         /* Check how large the file is */
@@ -439,7 +483,7 @@ CmpOpenHiveFiles(IN PCUNICODE_STRING BaseName,
         if (!NT_SUCCESS(Status))
         {
             /* Close handles and free buffers */
-            if (NameBuffer) ExFreePool(NameBuffer);
+            if (NameBuffer) ExFreePoolWithTag(NameBuffer, TAG_CM);
             ObDereferenceObject(Event);
             ZwClose(EventHandle);
             return Status;
@@ -449,7 +493,7 @@ CmpOpenHiveFiles(IN PCUNICODE_STRING BaseName,
         if (FsSizeInformation.BytesPerSector > HBLOCK_SIZE)
         {
             /* Close handles and free buffers */
-            if (NameBuffer) ExFreePool(NameBuffer);
+            if (NameBuffer) ExFreePoolWithTag(NameBuffer, TAG_CM);
             ObDereferenceObject(Event);
             ZwClose(EventHandle);
             return STATUS_CANNOT_LOAD_REGISTRY_FILE;
@@ -570,11 +614,11 @@ CmpOpenHiveFiles(IN PCUNICODE_STRING BaseName,
         }
 
         /* Return the disposition */
-        *LogDisposition = IoStatusBlock.Information;
+        *LogDisposition = (ULONG)IoStatusBlock.Information;
     }
 
     /* We're done, close handles and free buffers */
-    if (NameBuffer) ExFreePool(NameBuffer);
+    if (NameBuffer) ExFreePoolWithTag(NameBuffer, TAG_CM);
     ObDereferenceObject(Event);
     ZwClose(EventHandle);
     return STATUS_SUCCESS;