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) ...@@ -727,8 +727,7 @@ int main(int argc, char **argv)
if (fake_module) if (fake_module)
{ {
if (spec->type == SPEC_WIN16) output_fake_module16( spec ); output_fake_module( spec );
else output_fake_module( spec );
break; break;
} }
if (!is_pe()) if (!is_pe())
......
...@@ -829,7 +829,8 @@ void output_fake_module16( DLLSPEC *spec ) ...@@ -829,7 +829,8 @@ void output_fake_module16( DLLSPEC *spec )
const unsigned int lfanew = (0x40 + sizeof(fakedll_signature) + 15) & ~15; const unsigned int lfanew = (0x40 + sizeof(fakedll_signature) + 15) & ~15;
const unsigned int segtab = lfanew + 0x40; 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(); init_output_buffer();
...@@ -843,6 +844,10 @@ void output_fake_module16( DLLSPEC *spec ) ...@@ -843,6 +844,10 @@ void output_fake_module16( DLLSPEC *spec )
restab += output_buffer_pos; restab += output_buffer_pos;
free( output_buffer ); free( output_buffer );
init_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 ); namelen = strlen( spec->dll_name );
...@@ -874,7 +879,7 @@ void output_fake_module16( DLLSPEC *spec ) ...@@ -874,7 +879,7 @@ void output_fake_module16( DLLSPEC *spec )
put_dword( 0 ); put_dword( 0 );
put_word( 0 ); /* e_oemid */ put_word( 0 ); /* e_oemid */
put_word( 0 ); /* e_oeminfo */ 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 ); put_dword( 0 );
put_dword( 0 ); put_dword( 0 );
...@@ -953,7 +958,5 @@ void output_fake_module16( DLLSPEC *spec ) ...@@ -953,7 +958,5 @@ void output_fake_module16( DLLSPEC *spec )
put_data( data_segment, sizeof(data_segment) ); put_data( data_segment, sizeof(data_segment) );
/* resource data */ /* resource data */
output_bin_res16_data( spec ); put_data( rsrc_ptr, rsrc_size );
flush_output_buffer();
} }
...@@ -790,13 +790,21 @@ struct dir_data ...@@ -790,13 +790,21 @@ struct dir_data
unsigned int size; unsigned int size;
}; };
struct exp_data
{
unsigned int rva;
const char *name;
};
static struct static struct
{ {
unsigned int section_align; unsigned int section_align;
unsigned int file_align; unsigned int file_align;
unsigned int sec_count; unsigned int sec_count;
unsigned int exp_count;
struct dir_data dir[16]; struct dir_data dir[16];
struct sec_data sec[8]; struct sec_data sec[8];
struct exp_data exp[8];
} pe; } pe;
static void set_dir( unsigned int idx, unsigned int rva, unsigned int size ) 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 ) ...@@ -805,6 +813,13 @@ static void set_dir( unsigned int idx, unsigned int rva, unsigned int size )
pe.dir[idx].size = 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) static unsigned int current_rva(void)
{ {
if (!pe.sec_count) return pe.section_align; if (!pe.sec_count) return pe.section_align;
...@@ -864,16 +879,68 @@ void output_fake_module( DLLSPEC *spec ) ...@@ -864,16 +879,68 @@ void output_fake_module( DLLSPEC *spec )
else put_data( exe_code_section, sizeof(exe_code_section) ); else put_data( exe_code_section, sizeof(exe_code_section) );
flush_output_to_section( ".text", -1, 0x60000020 /* CNT_CODE|MEM_EXECUTE|MEM_READ */ ); 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 */ /* .reloc section */
put_dword( 0 ); /* VirtualAddress */ put_dword( 0 ); /* VirtualAddress */
put_dword( 0 ); /* Size */ put_dword( 0 ); /* Size */
flush_output_to_section( ".reloc", 5 /* IMAGE_DIRECTORY_ENTRY_BASERELOC */, flush_output_to_section( ".reloc", 5 /* IMAGE_DIRECTORY_ENTRY_BASERELOC */,
0x42000040 /* CNT_INITIALIZED_DATA|MEM_DISCARDABLE|MEM_READ */ ); 0x42000040 /* CNT_INITIALIZED_DATA|MEM_DISCARDABLE|MEM_READ */ );
/* .rsrc section */ if (spec->type == SPEC_WIN32)
output_bin_resources( spec, current_rva() ); {
flush_output_to_section( ".rsrc", 2 /* IMAGE_DIRECTORY_ENTRY_RESOURCE */, /* .rsrc section */
0x40000040 /* CNT_INITIALIZED_DATA|MEM_READ */ ); 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( 0x5a4d ); /* e_magic */
put_word( 0x40 ); /* e_cblp */ 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