[PATCH 1/2] server: Return a fake mapping with WineFakeDll flag set for a fake 16 bit dll.

Oleh Nykyforchyn oleh.nyk at gmail.com
Thu Oct 14 06:28:44 CDT 2021


If fake 16 bit dll is found by create_mapping and status is set to
STATUS_IMAGE_INVALID_WIN_16, do not release the mapping, but return it with
WineFakeDll flag set to allow ntdll properly discover this dll by NtCreateSection
and handle by find_dll_file.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51564
Signed-off-by: Oleh Nykyforchyn <oleh.nyk at gmail.com>
---
 server/mapping.c | 31 +++++++++++++++++++++++--------
 1 file changed, 23 insertions(+), 8 deletions(-)

diff --git a/server/mapping.c b/server/mapping.c
index 93dae94b7c4..8016feaf432 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -697,6 +697,13 @@ static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_s
     mz_size = size;
     pos = mz.dos.e_lfanew;
 
+    mapping->image.image_flags  = 0;
+    mapping->image.loader_flags = 0;
+    if (mz_size == sizeof(mz) && !memcmp( mz.buffer, builtin_signature, sizeof(builtin_signature) ))
+        mapping->image.image_flags |= IMAGE_FLAGS_WineBuiltin;
+    else if (mz_size == sizeof(mz) && !memcmp( mz.buffer, fakedll_signature, sizeof(fakedll_signature) ))
+        mapping->image.image_flags |= IMAGE_FLAGS_WineFakeDll;
+
     size = pread( unix_fd, &nt, sizeof(nt), pos );
     if (size < sizeof(nt.Signature) + sizeof(nt.FileHeader)) return STATUS_INVALID_IMAGE_PROTECT;
     /* zero out Optional header in the case it's not present or partial */
@@ -707,7 +714,11 @@ static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_s
     {
         IMAGE_OS2_HEADER *os2 = (IMAGE_OS2_HEADER *)&nt;
         if (os2->ne_magic != IMAGE_OS2_SIGNATURE) return STATUS_INVALID_IMAGE_PROTECT;
-        if (os2->ne_exetyp == 2) return STATUS_INVALID_IMAGE_WIN_16;
+        if (os2->ne_exetyp == 2)
+        {
+            mapping->image.machine = IMAGE_FILE_MACHINE_I386;
+            return STATUS_INVALID_IMAGE_WIN_16;
+        }
         if (os2->ne_exetyp == 5) return STATUS_INVALID_IMAGE_PROTECT;
         return STATUS_INVALID_IMAGE_NE_FORMAT;
     }
@@ -737,7 +748,6 @@ static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_s
                                           nt.opt.hdr32.SectionAlignment & page_mask);
         mapping->image.header_size     = nt.opt.hdr32.SizeOfHeaders;
         mapping->image.checksum        = nt.opt.hdr32.CheckSum;
-        mapping->image.image_flags     = 0;
         if (nt.opt.hdr32.SectionAlignment & page_mask)
             mapping->image.image_flags |= IMAGE_FLAGS_ImageMappedFlat;
         if ((nt.opt.hdr32.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) &&
@@ -769,7 +779,6 @@ static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_s
                                           nt.opt.hdr64.SectionAlignment & page_mask);
         mapping->image.header_size     = nt.opt.hdr64.SizeOfHeaders;
         mapping->image.checksum        = nt.opt.hdr64.CheckSum;
-        mapping->image.image_flags     = 0;
         if (nt.opt.hdr64.SectionAlignment & page_mask)
             mapping->image.image_flags |= IMAGE_FLAGS_ImageMappedFlat;
         if ((nt.opt.hdr64.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) &&
@@ -788,10 +797,6 @@ static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_s
     mapping->image.zerobits      = 0; /* FIXME */
     mapping->image.file_size     = file_size;
     mapping->image.loader_flags  = clr_va && clr_size;
-    if (mz_size == sizeof(mz) && !memcmp( mz.buffer, builtin_signature, sizeof(builtin_signature) ))
-        mapping->image.image_flags |= IMAGE_FLAGS_WineBuiltin;
-    else if (mz_size == sizeof(mz) && !memcmp( mz.buffer, fakedll_signature, sizeof(fakedll_signature) ))
-        mapping->image.image_flags |= IMAGE_FLAGS_WineFakeDll;
 
     /* load the section headers */
 
@@ -920,7 +925,11 @@ static struct mapping *create_mapping( struct object *root, const struct unicode
             unsigned int err = get_image_params( mapping, st.st_size, unix_fd );
             if (!err) return mapping;
             set_error( err );
-            goto error;
+            /* return fake mapping to discover fake 16 bit dll */
+            if ((err == STATUS_INVALID_IMAGE_WIN_16) && (mapping->image.image_flags & IMAGE_FLAGS_WineFakeDll))
+                return mapping;
+            else
+                goto error;
         }
         if (!mapping->size)
         {
@@ -1106,6 +1115,12 @@ struct object *create_user_data_mapping( struct object *root, const struct unico
 
     if (!(mapping = create_mapping( root, name, attr, sizeof(KSHARED_USER_DATA),
                                     SEC_COMMIT, 0, FILE_READ_DATA | FILE_WRITE_DATA, sd ))) return NULL;
+    /* FIXME: is this necessary? */
+    if ((get_error() == STATUS_INVALID_IMAGE_WIN_16) && (mapping->image.image_flags & IMAGE_FLAGS_WineFakeDll))
+    {
+        release_object( mapping );
+        return NULL;
+    }
     ptr = mmap( NULL, mapping->size, PROT_WRITE, MAP_SHARED, get_unix_fd( mapping->fd ), 0 );
     if (ptr != MAP_FAILED)
     {
-- 
2.33.0




More information about the wine-devel mailing list