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