Alexandre Julliard : winebuild: Wrap 16-bit fake dlls in a PE module.

Alexandre Julliard julliard at winehq.org
Thu Oct 21 16:04:17 CDT 2021


Module: wine
Branch: master
Commit: 5a8f7d1f745d3fb8fd48d577103ac5068d3c1746
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=5a8f7d1f745d3fb8fd48d577103ac5068d3c1746

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Oct 21 12:50:13 2021 +0200

winebuild: Wrap 16-bit fake dlls in a PE module.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51564
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 tools/winebuild/main.c   |  3 +-
 tools/winebuild/spec16.c | 13 +++++----
 tools/winebuild/spec32.c | 75 +++++++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 80 insertions(+), 11 deletions(-)

diff --git a/tools/winebuild/main.c b/tools/winebuild/main.c
index 45e21f8c462..1a9be3c7ae7 100644
--- a/tools/winebuild/main.c
+++ b/tools/winebuild/main.c
@@ -727,8 +727,7 @@ int main(int argc, char **argv)
 
         if (fake_module)
         {
-            if (spec->type == SPEC_WIN16) output_fake_module16( spec );
-            else output_fake_module( spec );
+            output_fake_module( spec );
             break;
         }
         if (!is_pe())
diff --git a/tools/winebuild/spec16.c b/tools/winebuild/spec16.c
index e82f5f81d9a..8d4f96ea323 100644
--- a/tools/winebuild/spec16.c
+++ b/tools/winebuild/spec16.c
@@ -829,7 +829,8 @@ void output_fake_module16( DLLSPEC *spec )
     const unsigned int lfanew = (0x40 + sizeof(fakedll_signature) + 15) & ~15;
     const unsigned int segtab = lfanew + 0x40;
 
-    unsigned int i, rsrctab, restab, namelen, modtab, imptab, enttab, cbenttab, codeseg, dataseg, rsrcdata;
+    unsigned int i, rsrctab, restab, namelen, modtab, imptab, enttab, cbenttab, codeseg, dataseg, rsrcdata, rsrc_size = 0;
+    void *rsrc_ptr = NULL;
 
     init_output_buffer();
 
@@ -843,6 +844,10 @@ void output_fake_module16( DLLSPEC *spec )
         restab += output_buffer_pos;
         free( output_buffer );
         init_output_buffer();
+        output_bin_res16_data( spec );
+        rsrc_ptr = output_buffer;
+        rsrc_size = output_buffer_pos;
+        init_output_buffer();
     }
 
     namelen  = strlen( spec->dll_name );
@@ -874,7 +879,7 @@ void output_fake_module16( DLLSPEC *spec )
     put_dword( 0 );
     put_word( 0 );            /* e_oemid */
     put_word( 0 );            /* e_oeminfo */
-    put_dword( 0 );           /* e_res2 */
+    put_dword( rsrcdata + rsrc_size ); /* e_res2 */
     put_dword( 0 );
     put_dword( 0 );
     put_dword( 0 );
@@ -953,7 +958,5 @@ void output_fake_module16( DLLSPEC *spec )
     put_data( data_segment, sizeof(data_segment) );
 
     /* resource data */
-    output_bin_res16_data( spec );
-
-    flush_output_buffer();
+    put_data( rsrc_ptr, rsrc_size );
 }
diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c
index 7a28777fb77..513778ad10c 100644
--- a/tools/winebuild/spec32.c
+++ b/tools/winebuild/spec32.c
@@ -790,13 +790,21 @@ struct dir_data
     unsigned int size;
 };
 
+struct exp_data
+{
+    unsigned int rva;
+    const char  *name;
+};
+
 static struct
 {
     unsigned int    section_align;
     unsigned int    file_align;
     unsigned int    sec_count;
+    unsigned int    exp_count;
     struct dir_data dir[16];
     struct sec_data sec[8];
+    struct exp_data exp[8];
 } pe;
 
 static void set_dir( unsigned int idx, unsigned int rva, unsigned int size )
@@ -805,6 +813,13 @@ static void set_dir( unsigned int idx, unsigned int rva, unsigned int size )
     pe.dir[idx].size = size;
 }
 
+static void add_export( unsigned int rva, const char *name )
+{
+    pe.exp[pe.exp_count].rva  = rva;
+    pe.exp[pe.exp_count].name = name;
+    pe.exp_count++;
+}
+
 static unsigned int current_rva(void)
 {
     if (!pe.sec_count) return pe.section_align;
@@ -864,16 +879,68 @@ void output_fake_module( DLLSPEC *spec )
     else put_data( exe_code_section, sizeof(exe_code_section) );
     flush_output_to_section( ".text", -1, 0x60000020 /* CNT_CODE|MEM_EXECUTE|MEM_READ */ );
 
+    if (spec->type == SPEC_WIN16)
+    {
+        add_export( current_rva(), "__wine_spec_dos_header" );
+
+        /* .rodata section */
+        output_fake_module16( spec );
+        if (spec->main_module)
+        {
+            add_export( current_rva() + output_buffer_pos, "__wine_spec_main_module" );
+            put_data( spec->main_module, strlen(spec->main_module) + 1 );
+        }
+        flush_output_to_section( ".rodata", -1, 0x40000040 /* CNT_INITIALIZED_DATA|MEM_READ */ );
+    }
+
+    if (pe.exp_count)
+    {
+        /* .edata section */
+        unsigned int exp_rva = current_rva() + 40; /* sizeof(IMAGE_EXPORT_DIRECTORY) */
+        unsigned int pos, str_rva = exp_rva + 10 * pe.exp_count;
+
+	put_dword( 0 );               /* Characteristics */
+        put_dword( hash_filename(spec->file_name) );     /* TimeDateStamp */
+        put_word( 0 );                /* MajorVersion */
+        put_word( 0 );                /* MinorVersion */
+        put_dword( str_rva );         /* Name */
+        put_dword( 1 );               /* Base */
+        put_dword( pe.exp_count );    /* NumberOfFunctions */
+        put_dword( pe.exp_count );    /* NumberOfNames */
+        put_dword( exp_rva );         /* AddressOfFunctions */
+        put_dword( exp_rva + 4 * pe.exp_count );     /* AddressOfNames */
+        put_dword( exp_rva + 8 * pe.exp_count );     /* AddressOfNameOrdinals */
+
+        /* functions */
+        for (i = 0; i < pe.exp_count; i++) put_dword( pe.exp[i].rva );
+        /* names */
+        for (i = 0, pos = str_rva + strlen(spec->file_name) + 1; i < pe.exp_count; i++)
+        {
+            put_dword( pos );
+            pos += strlen( pe.exp[i].name ) + 1;
+        }
+        /* ordinals */
+        for (i = 0; i < pe.exp_count; i++) put_word( i );
+        /* strings */
+        put_data( spec->file_name, strlen(spec->file_name) + 1 );
+        for (i = 0; i < pe.exp_count; i++) put_data( pe.exp[i].name, strlen(pe.exp[i].name) + 1 );
+        flush_output_to_section( ".edata", 0 /* IMAGE_DIRECTORY_ENTRY_EXPORT */,
+                                 0x40000040 /* CNT_INITIALIZED_DATA|MEM_READ */ );
+    }
+
     /* .reloc section */
     put_dword( 0 );  /* VirtualAddress */
     put_dword( 0 );  /* Size */
     flush_output_to_section( ".reloc", 5 /* IMAGE_DIRECTORY_ENTRY_BASERELOC */,
                              0x42000040 /* CNT_INITIALIZED_DATA|MEM_DISCARDABLE|MEM_READ */ );
 
-    /* .rsrc section */
-    output_bin_resources( spec, current_rva() );
-    flush_output_to_section( ".rsrc", 2 /* IMAGE_DIRECTORY_ENTRY_RESOURCE */,
-                             0x40000040 /* CNT_INITIALIZED_DATA|MEM_READ */ );
+    if (spec->type == SPEC_WIN32)
+    {
+        /* .rsrc section */
+        output_bin_resources( spec, current_rva() );
+        flush_output_to_section( ".rsrc", 2 /* IMAGE_DIRECTORY_ENTRY_RESOURCE */,
+                                 0x40000040 /* CNT_INITIALIZED_DATA|MEM_READ */ );
+    }
 
     put_word( 0x5a4d );       /* e_magic */
     put_word( 0x40 );         /* e_cblp */




More information about the wine-cvs mailing list