[PATCH 09/10] ntdll: Handle MUI redirection in LdrAccessResource.

Mark Harmstone mark at harmstone.com
Sat Mar 27 14:47:36 CDT 2021


Signed-off-by: Mark Harmstone <mark at harmstone.com>
---
 dlls/ntdll/mui.c        | 69 +++++++++++++++++++++++++++++++++++++++++
 dlls/ntdll/ntdll_misc.h |  1 +
 dlls/ntdll/resource.c   |  2 ++
 3 files changed, 72 insertions(+)

diff --git a/dlls/ntdll/mui.c b/dlls/ntdll/mui.c
index dcdfefcbeb8..a9758c71f82 100644
--- a/dlls/ntdll/mui.c
+++ b/dlls/ntdll/mui.c
@@ -1263,3 +1263,72 @@ NTSTATUS NTAPI LdrRemoveLoadAsDataTable( PVOID init_module, PVOID *base_module,
 
     return STATUS_SUCCESS;
 }
+
+/***********************************************************************
+ *           try_mui_redirect_module
+ *
+ * Called by LdrAccessResource - see if we should be redirecting this to
+ * a MUI file.
+ */
+void try_mui_redirect_module( HMODULE *mod, const IMAGE_RESOURCE_DATA_ENTRY *entry )
+{
+    mui_module *mm = NULL, *mm2;
+    mui_lang_module *mm_lang;
+
+    /* no need to get size if entry is before start of image */
+    if ((void*)entry > (void*)*mod)
+    {
+        void *base = (void*)((uintptr_t)*mod & ~3);
+        size_t size = 0;
+        PIMAGE_NT_HEADERS nth;
+
+        nth = RtlImageNtHeader(base);
+        if (!nth)
+            return;
+
+        if (nth->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
+            size = ((IMAGE_OPTIONAL_HEADER32*)&nth->OptionalHeader)->SizeOfImage;
+        else if (nth->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
+            size = ((IMAGE_OPTIONAL_HEADER64*)&nth->OptionalHeader)->SizeOfImage;
+        else
+            return;
+
+        /* return if entry is within bounds of original image */
+
+        if ((char*)entry < (char*)base + size)
+            return;
+    }
+
+    /* find mui_module entry, and return if not found */
+
+    RtlEnterCriticalSection( &mui_section );
+
+    LIST_FOR_EACH_ENTRY( mm2, &mui_modules, mui_module, entry )
+    {
+        if (mm2->module == *mod)
+        {
+            mm = mm2;
+            break;
+        }
+    }
+
+    RtlLeaveCriticalSection( &mui_section );
+
+    if (!mm)
+        return;
+
+    /* loop through loaded languages */
+
+    RtlEnterCriticalSection( &mm->list_section );
+
+    LIST_FOR_EACH_ENTRY( mm_lang, &mm->langs, mui_lang_module, entry )
+    {
+        if ((void*)entry >= (void*)mm_lang->addr && (char*)entry < (char*)mm_lang->addr + mm_lang->size)
+        {
+            *mod = mm_lang->addr;
+            break;
+        }
+    }
+
+    RtlLeaveCriticalSection( &mm->list_section );
+}
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 8583c28dff6..563d599d426 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -117,5 +117,6 @@ extern NTSTATUS find_resource_entry( HMODULE hmod, const LDR_RESOURCE_INFO *info
 /* MUI */
 extern BOOLEAN try_mui_find_entry( HMODULE mod, const LDR_RESOURCE_INFO *info, ULONG level,
                                    const void **ret, NTSTATUS *status) DECLSPEC_HIDDEN;
+extern void try_mui_redirect_module( HMODULE *mod, const IMAGE_RESOURCE_DATA_ENTRY *entry ) DECLSPEC_HIDDEN;
 
 #endif
diff --git a/dlls/ntdll/resource.c b/dlls/ntdll/resource.c
index a8cff12652a..6ed93f5d6d8 100644
--- a/dlls/ntdll/resource.c
+++ b/dlls/ntdll/resource.c
@@ -328,6 +328,8 @@ static inline NTSTATUS access_resource( HMODULE hmod, const IMAGE_RESOURCE_DATA_
     {
         ULONG dirsize;
 
+        try_mui_redirect_module( &hmod, entry );
+
         if (!RtlImageDirectoryEntryToData( hmod, TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &dirsize ))
             status = STATUS_RESOURCE_DATA_NOT_FOUND;
         else
-- 
2.26.3




More information about the wine-devel mailing list