Commit 5a8f7d1f authored by Alexandre Julliard's avatar Alexandre Julliard

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

parent 2f0401c7
......@@ -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 */ );
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 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment