[NTOS:IO] Reduce stack usage in IopLoadServiceModule. CORE-17215 3089/head
authorThomas Faber <thomas.faber@reactos.org>
Wed, 10 Jun 2020 06:27:27 +0000 (08:27 +0200)
committerThomas Faber <thomas.faber@reactos.org>
Fri, 27 Nov 2020 11:44:35 +0000 (12:44 +0100)
ntoskrnl/io/iomgr/driver.c

index 9fd8c9b..6b3949a 100644 (file)
@@ -299,6 +299,70 @@ IopNormalizeImagePath(
     return STATUS_SUCCESS;
 }
 
+NTSTATUS
+IopQueryServiceSettings(
+    _In_ PUNICODE_STRING ServiceName,
+    _Out_ PUNICODE_STRING ServiceImagePath,
+    _Out_ PULONG ServiceStart)
+{
+    NTSTATUS Status;
+    RTL_QUERY_REGISTRY_TABLE QueryTable[3];
+    UNICODE_STRING CCSName = RTL_CONSTANT_STRING(
+        L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services");
+    HANDLE CCSKey, ServiceKey;
+
+    /* Open CurrentControlSet */
+    Status = IopOpenRegistryKeyEx(&CCSKey, NULL, &CCSName, KEY_READ);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("IopOpenRegistryKeyEx() failed for '%wZ' with status 0x%lx\n",
+                &CCSName, Status);
+        return Status;
+    }
+
+    /* Open service key */
+    Status = IopOpenRegistryKeyEx(&ServiceKey, CCSKey, ServiceName, KEY_READ);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("IopOpenRegistryKeyEx() failed for '%wZ' with status 0x%lx\n",
+                ServiceName, Status);
+        ZwClose(CCSKey);
+        return Status;
+    }
+
+    /*
+     * Get information about the service.
+     */
+    RtlZeroMemory(QueryTable, sizeof(QueryTable));
+
+    RtlInitUnicodeString(ServiceImagePath, NULL);
+
+    QueryTable[0].Name = L"Start";
+    QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
+    QueryTable[0].EntryContext = ServiceStart;
+
+    QueryTable[1].Name = L"ImagePath";
+    QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
+    QueryTable[1].EntryContext = ServiceImagePath;
+
+    Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
+                                    (PWSTR)ServiceKey,
+                                    QueryTable,
+                                    NULL,
+                                    NULL);
+
+    ZwClose(ServiceKey);
+    ZwClose(CCSKey);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("RtlQueryRegistryValues() failed for '%wZ' (Status %lx)\n", ServiceName, Status);
+        return Status;
+    }
+
+    return Status;
+}
+
 /*
  * IopLoadServiceModule
  *
@@ -317,11 +381,9 @@ IopLoadServiceModule(
     IN PUNICODE_STRING ServiceName,
     OUT PLDR_DATA_TABLE_ENTRY *ModuleObject)
 {
-    RTL_QUERY_REGISTRY_TABLE QueryTable[3];
     ULONG ServiceStart;
-    UNICODE_STRING ServiceImagePath, CCSName;
+    UNICODE_STRING ServiceImagePath;
     NTSTATUS Status;
-    HANDLE CCSKey, ServiceKey;
     PVOID BaseAddress;
 
     ASSERT(ExIsResourceAcquiredExclusiveLite(&IopDriverLoadResource));
@@ -341,54 +403,10 @@ IopLoadServiceModule(
     }
     else
     {
-        /* Open CurrentControlSet */
-        RtlInitUnicodeString(&CCSName,
-                             L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services");
-        Status = IopOpenRegistryKeyEx(&CCSKey, NULL, &CCSName, KEY_READ);
-        if (!NT_SUCCESS(Status))
-        {
-            DPRINT1("IopOpenRegistryKeyEx() failed for '%wZ' with status 0x%lx\n",
-                    &CCSName, Status);
-            return Status;
-        }
-
-        /* Open service key */
-        Status = IopOpenRegistryKeyEx(&ServiceKey, CCSKey, ServiceName, KEY_READ);
-        if (!NT_SUCCESS(Status))
-        {
-            DPRINT1("IopOpenRegistryKeyEx() failed for '%wZ' with status 0x%lx\n",
-                    ServiceName, Status);
-            ZwClose(CCSKey);
-            return Status;
-        }
-
-        /*
-         * Get information about the service.
-         */
-        RtlZeroMemory(QueryTable, sizeof(QueryTable));
-
-        RtlInitUnicodeString(&ServiceImagePath, NULL);
-
-        QueryTable[0].Name = L"Start";
-        QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
-        QueryTable[0].EntryContext = &ServiceStart;
-
-        QueryTable[1].Name = L"ImagePath";
-        QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
-        QueryTable[1].EntryContext = &ServiceImagePath;
-
-        Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
-                                        (PWSTR)ServiceKey,
-                                        QueryTable,
-                                        NULL,
-                                        NULL);
-
-        ZwClose(ServiceKey);
-        ZwClose(CCSKey);
-
+        Status = IopQueryServiceSettings(ServiceName, &ServiceImagePath, &ServiceStart);
         if (!NT_SUCCESS(Status))
         {
-            DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
+            DPRINT("IopQueryServiceSettings() failed for '%wZ' (Status %lx)\n", ServiceName, Status);
             return Status;
         }
     }