[NTOS:IO] Reduce stack usage in IopLoadServiceModule. CORE-17215

This commit is contained in:
Thomas Faber 2020-06-10 08:27:27 +02:00
parent 2858ff53ce
commit 828d5fa93e
No known key found for this signature in database
GPG key ID: 076E7C3D44720826

View file

@ -299,51 +299,19 @@ IopNormalizeImagePath(
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
/*
* IopLoadServiceModule
*
* Load a module specified by registry settings for service.
*
* Parameters
* ServiceName
* Name of the service to load.
*
* Return Value
* Status
*/
NTSTATUS NTSTATUS
FASTCALL IopQueryServiceSettings(
IopLoadServiceModule( _In_ PUNICODE_STRING ServiceName,
IN PUNICODE_STRING ServiceName, _Out_ PUNICODE_STRING ServiceImagePath,
OUT PLDR_DATA_TABLE_ENTRY *ModuleObject) _Out_ PULONG ServiceStart)
{ {
RTL_QUERY_REGISTRY_TABLE QueryTable[3];
ULONG ServiceStart;
UNICODE_STRING ServiceImagePath, CCSName;
NTSTATUS Status; NTSTATUS Status;
HANDLE CCSKey, ServiceKey; RTL_QUERY_REGISTRY_TABLE QueryTable[3];
PVOID BaseAddress; UNICODE_STRING CCSName = RTL_CONSTANT_STRING(
ASSERT(ExIsResourceAcquiredExclusiveLite(&IopDriverLoadResource));
ASSERT(ServiceName->Length);
DPRINT("IopLoadServiceModule(%wZ, 0x%p)\n", ServiceName, ModuleObject);
if (ExpInTextModeSetup)
{
/* We have no registry, but luckily we know where all the drivers are */
DPRINT1("IopLoadServiceModule(%wZ, 0x%p) called in ExpInTextModeSetup mode...\n", ServiceName, ModuleObject);
/* ServiceStart < 4 is all that matters */
ServiceStart = 0;
/* IopNormalizeImagePath will do all of the work for us if we give it an empty string */
RtlInitEmptyUnicodeString(&ServiceImagePath, NULL, 0);
}
else
{
/* Open CurrentControlSet */
RtlInitUnicodeString(&CCSName,
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services"); L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services");
HANDLE CCSKey, ServiceKey;
/* Open CurrentControlSet */
Status = IopOpenRegistryKeyEx(&CCSKey, NULL, &CCSName, KEY_READ); Status = IopOpenRegistryKeyEx(&CCSKey, NULL, &CCSName, KEY_READ);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -367,15 +335,15 @@ IopLoadServiceModule(
*/ */
RtlZeroMemory(QueryTable, sizeof(QueryTable)); RtlZeroMemory(QueryTable, sizeof(QueryTable));
RtlInitUnicodeString(&ServiceImagePath, NULL); RtlInitUnicodeString(ServiceImagePath, NULL);
QueryTable[0].Name = L"Start"; QueryTable[0].Name = L"Start";
QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
QueryTable[0].EntryContext = &ServiceStart; QueryTable[0].EntryContext = ServiceStart;
QueryTable[1].Name = L"ImagePath"; QueryTable[1].Name = L"ImagePath";
QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT; QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
QueryTable[1].EntryContext = &ServiceImagePath; QueryTable[1].EntryContext = ServiceImagePath;
Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE, Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
(PWSTR)ServiceKey, (PWSTR)ServiceKey,
@ -388,7 +356,57 @@ IopLoadServiceModule(
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status); DPRINT1("RtlQueryRegistryValues() failed for '%wZ' (Status %lx)\n", ServiceName, Status);
return Status;
}
return Status;
}
/*
* IopLoadServiceModule
*
* Load a module specified by registry settings for service.
*
* Parameters
* ServiceName
* Name of the service to load.
*
* Return Value
* Status
*/
NTSTATUS
FASTCALL
IopLoadServiceModule(
IN PUNICODE_STRING ServiceName,
OUT PLDR_DATA_TABLE_ENTRY *ModuleObject)
{
ULONG ServiceStart;
UNICODE_STRING ServiceImagePath;
NTSTATUS Status;
PVOID BaseAddress;
ASSERT(ExIsResourceAcquiredExclusiveLite(&IopDriverLoadResource));
ASSERT(ServiceName->Length);
DPRINT("IopLoadServiceModule(%wZ, 0x%p)\n", ServiceName, ModuleObject);
if (ExpInTextModeSetup)
{
/* We have no registry, but luckily we know where all the drivers are */
DPRINT1("IopLoadServiceModule(%wZ, 0x%p) called in ExpInTextModeSetup mode...\n", ServiceName, ModuleObject);
/* ServiceStart < 4 is all that matters */
ServiceStart = 0;
/* IopNormalizeImagePath will do all of the work for us if we give it an empty string */
RtlInitEmptyUnicodeString(&ServiceImagePath, NULL, 0);
}
else
{
Status = IopQueryServiceSettings(ServiceName, &ServiceImagePath, &ServiceStart);
if (!NT_SUCCESS(Status))
{
DPRINT("IopQueryServiceSettings() failed for '%wZ' (Status %lx)\n", ServiceName, Status);
return Status; return Status;
} }
} }