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@winehq.org>
This commit is contained in:
parent
2f0401c783
commit
5a8f7d1f74
|
@ -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())
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue