https://git.reactos.org/?p=reactos.git;a=commitdiff;h=828d5fa93e2cc98731626…
commit 828d5fa93e2cc987316264c043b19b50e02d8f4d
Author: Thomas Faber <thomas.faber(a)reactos.org>
AuthorDate: Wed Jun 10 08:27:27 2020 +0200
Commit: Thomas Faber <thomas.faber(a)reactos.org>
CommitDate: Fri Nov 27 12:44:35 2020 +0100
[NTOS:IO] Reduce stack usage in IopLoadServiceModule. CORE-17215
---
ntoskrnl/io/iomgr/driver.c | 116 ++++++++++++++++++++++++++-------------------
1 file changed, 67 insertions(+), 49 deletions(-)
diff --git a/ntoskrnl/io/iomgr/driver.c b/ntoskrnl/io/iomgr/driver.c
index 9fd8c9b87c5..6b3949a5189 100644
--- a/ntoskrnl/io/iomgr/driver.c
+++ b/ntoskrnl/io/iomgr/driver.c
@@ -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;
}
}