From 346477fb3c98246b03ec3fcb60b50b562aa7ab85 Mon Sep 17 00:00:00 2001 From: Wu Haotian Date: Mon, 9 Jan 2023 22:55:29 +0800 Subject: [PATCH] [NTOS:MM] Use image prefix in MmLoadSystemImage MmLoadSystemImage has a PUNICODE_STRING NamePrefix parameter which is currently unused in ReactOS. When the kernel loads the crash dump storage stack drivers, the drivers will be loaded with MmLoadSystemImage with a "dump_" or "hiber_" (for hibernation, which uses crash dump stack too) prefix. This change adds in the prefix support, and is supposed to push crash dump support forward. CORE-376 --- ntoskrnl/mm/ARM3/sysldr.c | 53 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/ntoskrnl/mm/ARM3/sysldr.c b/ntoskrnl/mm/ARM3/sysldr.c index 35b538259f3..3ea6662cc28 100644 --- a/ntoskrnl/mm/ARM3/sysldr.c +++ b/ntoskrnl/mm/ARM3/sysldr.c @@ -2900,7 +2900,7 @@ MmLoadSystemImage(IN PUNICODE_STRING FileName, ULONG EntrySize, DriverSize; PLOAD_IMPORTS LoadedImports = MM_SYSLDR_NO_IMPORTS; PCHAR MissingApiName, Buffer; - PWCHAR MissingDriverName; + PWCHAR MissingDriverName, PrefixedBuffer = NULL; HANDLE SectionHandle; ACCESS_MASK DesiredAccess; PSECTION Section = NULL; @@ -2964,7 +2964,52 @@ MmLoadSystemImage(IN PUNICODE_STRING FileName, PrefixName = *FileName; /* Check if we have a prefix */ - if (NamePrefix) DPRINT1("Prefixed images are not yet supported!\n"); + if (NamePrefix) + { + /* Check if "directory + prefix" is too long for the string */ + Status = RtlUShortAdd(BaseDirectory.Length, + NamePrefix->Length, + &PrefixName.MaximumLength); + if (!NT_SUCCESS(Status)) + { + Status = STATUS_INVALID_PARAMETER; + goto Quickie; + } + + /* Check if "directory + prefix + basename" is too long for the string */ + Status = RtlUShortAdd(PrefixName.MaximumLength, + BaseName.Length, + &PrefixName.MaximumLength); + if (!NT_SUCCESS(Status)) + { + Status = STATUS_INVALID_PARAMETER; + goto Quickie; + } + + /* Allocate the buffer exclusively used for prefixed name */ + PrefixedBuffer = ExAllocatePoolWithTag(PagedPool, + PrefixName.MaximumLength, + TAG_LDR_WSTR); + if (!PrefixedBuffer) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto Quickie; + } + + /* Clear out the prefixed name string */ + PrefixName.Buffer = PrefixedBuffer; + PrefixName.Length = 0; + + /* Concatenate the strings */ + RtlAppendUnicodeStringToString(&PrefixName, &BaseDirectory); + RtlAppendUnicodeStringToString(&PrefixName, NamePrefix); + RtlAppendUnicodeStringToString(&PrefixName, &BaseName); + + /* Now the base name of the image becomes the prefixed version */ + BaseName.Buffer = &(PrefixName.Buffer[BaseDirectory.Length / sizeof(WCHAR)]); + BaseName.Length += NamePrefix->Length; + BaseName.MaximumLength = (PrefixName.MaximumLength - BaseDirectory.Length); + } /* Check if we already have a name, use it instead */ if (LoadedName) BaseName = *LoadedName; @@ -3406,8 +3451,8 @@ Quickie: /* If we have a file handle, close it */ if (FileHandle) ZwClose(FileHandle); - /* Check if we had a prefix (not supported yet - PrefixName == *FileName now) */ - /* if (NamePrefix) ExFreePool(PrefixName.Buffer); */ + /* If we have allocated a prefixed name buffer, free it */ + if (PrefixedBuffer) ExFreePoolWithTag(PrefixedBuffer, TAG_LDR_WSTR); /* Free the name buffer and return status */ ExFreePoolWithTag(Buffer, TAG_LDR_WSTR);