https://git.reactos.org/?p=reactos.git;a=commitdiff;h=346477fb3c98246b03ec3fcb60b50b562aa7ab85

commit 346477fb3c98246b03ec3fcb60b50b562aa7ab85
Author:     Wu Haotian <[email protected]>
AuthorDate: Mon Jan 9 22:55:29 2023 +0800
Commit:     Victor Perevertkin <[email protected]>
CommitDate: Wed Jan 18 02:35:19 2023 +0300

    [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);

Reply via email to