winebuild: Add support for creating 16-bit fake dlls.
This commit is contained in:
parent
8024718c78
commit
5d3e134b17
|
@ -251,7 +251,9 @@ extern void output_bin_resources( DLLSPEC *spec, unsigned int start_rva );
|
|||
extern void output_fake_module( DLLSPEC *spec );
|
||||
extern void load_res16_file( const char *name, DLLSPEC *spec );
|
||||
extern void output_res16_data( DLLSPEC *spec );
|
||||
extern void output_bin_res16_data( DLLSPEC *spec );
|
||||
extern void output_res16_directory( DLLSPEC *spec );
|
||||
extern void output_bin_res16_directory( DLLSPEC *spec, unsigned int data_offset );
|
||||
extern void output_spec16_file( DLLSPEC *spec );
|
||||
extern void output_fake_module16( DLLSPEC *spec16 );
|
||||
extern void output_res_o_file( DLLSPEC *spec );
|
||||
|
|
|
@ -215,6 +215,13 @@ static void output_string( const char *str )
|
|||
output( " /* %s */\n", str );
|
||||
}
|
||||
|
||||
/* output a string preceded by its length in binary format*/
|
||||
static void output_bin_string( const char *str )
|
||||
{
|
||||
put_byte( strlen(str) );
|
||||
while (*str) put_byte( *str++ );
|
||||
}
|
||||
|
||||
/* output the resource data */
|
||||
void output_res16_data( DLLSPEC *spec )
|
||||
{
|
||||
|
@ -268,3 +275,60 @@ void output_res16_directory( DLLSPEC *spec )
|
|||
|
||||
free_resource_tree( tree );
|
||||
}
|
||||
|
||||
/* output the resource data in binary format */
|
||||
void output_bin_res16_data( DLLSPEC *spec )
|
||||
{
|
||||
const struct resource *res;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
|
||||
put_data( res->data, res->data_size );
|
||||
}
|
||||
|
||||
/* output the resource definitions in binary format */
|
||||
void output_bin_res16_directory( DLLSPEC *spec, unsigned int data_offset )
|
||||
{
|
||||
unsigned int i, j;
|
||||
struct res_tree *tree;
|
||||
const struct res_type *type;
|
||||
const struct resource *res;
|
||||
|
||||
tree = build_resource_tree( spec );
|
||||
|
||||
put_word( 0 ); /* alignment */
|
||||
|
||||
/* type and name structures */
|
||||
|
||||
for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
|
||||
{
|
||||
put_word( type->name_offset );
|
||||
put_word( type->nb_names );
|
||||
put_word( 0 );
|
||||
put_word( 0 );
|
||||
|
||||
for (j = 0, res = type->res; j < type->nb_names; j++, res++)
|
||||
{
|
||||
put_word( data_offset );
|
||||
put_word( res->data_size );
|
||||
put_word( res->memopt );
|
||||
put_word( res->name_offset );
|
||||
put_word( 0 );
|
||||
put_word( 0 );
|
||||
data_offset += res->data_size;
|
||||
}
|
||||
}
|
||||
put_word( 0 ); /* terminator */
|
||||
|
||||
/* name strings */
|
||||
|
||||
for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
|
||||
{
|
||||
if (type->type->str) output_bin_string( type->type->str );
|
||||
for (j = 0, res = type->res; j < type->nb_names; j++, res++)
|
||||
if (res->name.str) output_bin_string( res->name.str );
|
||||
}
|
||||
put_byte( 0 ); /* names terminator */
|
||||
|
||||
free_resource_tree( tree );
|
||||
}
|
||||
|
|
|
@ -63,6 +63,22 @@ static inline int is_function( const ORDDEF *odp )
|
|||
odp->type == TYPE_STUB);
|
||||
}
|
||||
|
||||
static void init_dll_name( DLLSPEC *spec )
|
||||
{
|
||||
if (!spec->file_name)
|
||||
{
|
||||
char *p;
|
||||
spec->file_name = xstrdup( output_file_name );
|
||||
if ((p = strrchr( spec->file_name, '.' ))) *p = 0;
|
||||
}
|
||||
if (!spec->dll_name) /* set default name from file name */
|
||||
{
|
||||
char *p;
|
||||
spec->dll_name = xstrdup( spec->file_name );
|
||||
if ((p = strrchr( spec->dll_name, '.' ))) *p = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* output_entries
|
||||
*
|
||||
|
@ -546,19 +562,6 @@ static void output_module16( DLLSPEC *spec )
|
|||
ORDDEF *entry_point = NULL;
|
||||
int i, j, nb_funcs;
|
||||
|
||||
if (!spec->file_name)
|
||||
{
|
||||
char *p;
|
||||
spec->file_name = xstrdup( output_file_name );
|
||||
if ((p = strrchr( spec->file_name, '.' ))) *p = 0;
|
||||
}
|
||||
if (!spec->dll_name) /* set default name from file name */
|
||||
{
|
||||
char *p;
|
||||
spec->dll_name = xstrdup( spec->file_name );
|
||||
if ((p = strrchr( spec->dll_name, '.' ))) *p = 0;
|
||||
}
|
||||
|
||||
/* store the main entry point as ordinal 0 */
|
||||
|
||||
if (!spec->ordinals)
|
||||
|
@ -657,7 +660,7 @@ static void output_module16( DLLSPEC *spec )
|
|||
output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_cmovent */
|
||||
output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_align */
|
||||
output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_cres */
|
||||
output( "\t.byte 0x04\n" ); /* ne_exetyp = NE_OSFLAGS_WINDOWS */
|
||||
output( "\t.byte 0x02\n" ); /* ne_exetyp = NE_OSFLAGS_WINDOWS */
|
||||
output( "\t.byte 0x08\n" ); /* ne_flagsothers = NE_AFLAGS_FASTLOAD */
|
||||
output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_pretthunks */
|
||||
output( "\t%s 0\n", get_asm_short_keyword() ); /* ne_psegrefbytes */
|
||||
|
@ -847,6 +850,7 @@ static void output_module16( DLLSPEC *spec )
|
|||
*/
|
||||
void BuildSpec16File( DLLSPEC *spec )
|
||||
{
|
||||
init_dll_name( spec );
|
||||
output_standard_file_header();
|
||||
output_module16( spec );
|
||||
output_init_code( spec );
|
||||
|
@ -870,6 +874,7 @@ void output_spec16_file( DLLSPEC *spec16 )
|
|||
{
|
||||
DLLSPEC *spec32 = alloc_dll_spec();
|
||||
|
||||
init_dll_name( spec16 );
|
||||
spec32->file_name = xstrdup( spec16->file_name );
|
||||
|
||||
if (spec16->characteristics & IMAGE_FILE_DLL)
|
||||
|
@ -902,7 +907,141 @@ void output_spec16_file( DLLSPEC *spec16 )
|
|||
*
|
||||
* Create a fake 16-bit binary module.
|
||||
*/
|
||||
void output_fake_module16( DLLSPEC *spec16 )
|
||||
void output_fake_module16( DLLSPEC *spec )
|
||||
{
|
||||
warning( "not implemented yet\n" );
|
||||
static const unsigned char code_segment[] = { 0x90, 0xc3 };
|
||||
static const unsigned char data_segment[16] = { 0 };
|
||||
static const char fakedll_signature[] = "Wine placeholder DLL";
|
||||
const unsigned int cseg = 2;
|
||||
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;
|
||||
|
||||
init_dll_name( spec );
|
||||
init_output_buffer();
|
||||
|
||||
rsrctab = lfanew;
|
||||
restab = segtab + 8 * cseg;
|
||||
if (spec->nb_resources)
|
||||
{
|
||||
output_bin_res16_directory( spec, 0 );
|
||||
align_output( 2 );
|
||||
rsrctab = restab;
|
||||
restab += output_buffer_pos;
|
||||
free( output_buffer );
|
||||
init_output_buffer();
|
||||
}
|
||||
|
||||
namelen = strlen( spec->dll_name );
|
||||
modtab = restab + ((namelen + 3) & ~1);
|
||||
imptab = modtab;
|
||||
enttab = modtab + 2;
|
||||
cbenttab = 1;
|
||||
codeseg = (enttab + cbenttab + 1) & ~1;
|
||||
dataseg = codeseg + sizeof(code_segment);
|
||||
rsrcdata = dataseg + sizeof(data_segment);
|
||||
|
||||
init_output_buffer();
|
||||
|
||||
put_word( 0x5a4d ); /* e_magic */
|
||||
put_word( 0x40 ); /* e_cblp */
|
||||
put_word( 0x01 ); /* e_cp */
|
||||
put_word( 0 ); /* e_crlc */
|
||||
put_word( lfanew / 16 ); /* e_cparhdr */
|
||||
put_word( 0x0000 ); /* e_minalloc */
|
||||
put_word( 0xffff ); /* e_maxalloc */
|
||||
put_word( 0x0000 ); /* e_ss */
|
||||
put_word( 0x00b8 ); /* e_sp */
|
||||
put_word( 0 ); /* e_csum */
|
||||
put_word( 0 ); /* e_ip */
|
||||
put_word( 0 ); /* e_cs */
|
||||
put_word( lfanew ); /* e_lfarlc */
|
||||
put_word( 0 ); /* e_ovno */
|
||||
put_dword( 0 ); /* e_res */
|
||||
put_dword( 0 );
|
||||
put_word( 0 ); /* e_oemid */
|
||||
put_word( 0 ); /* e_oeminfo */
|
||||
put_dword( 0 ); /* e_res2 */
|
||||
put_dword( 0 );
|
||||
put_dword( 0 );
|
||||
put_dword( 0 );
|
||||
put_dword( 0 );
|
||||
put_dword( lfanew );
|
||||
|
||||
put_data( fakedll_signature, sizeof(fakedll_signature) );
|
||||
align_output( 16 );
|
||||
|
||||
put_word( 0x454e ); /* ne_magic */
|
||||
put_byte( 0 ); /* ne_ver */
|
||||
put_byte( 0 ); /* ne_rev */
|
||||
put_word( enttab - lfanew ); /* ne_enttab */
|
||||
put_word( cbenttab ); /* ne_cbenttab */
|
||||
put_dword( 0 ); /* ne_crc */
|
||||
put_word( NE_FFLAGS_SINGLEDATA | /* ne_flags */
|
||||
((spec->characteristics & IMAGE_FILE_DLL) ? NE_FFLAGS_LIBMODULE : 0) );
|
||||
put_word( 2 ); /* ne_autodata */
|
||||
put_word( spec->heap_size ); /* ne_heap */
|
||||
put_word( 0 ); /* ne_stack */
|
||||
put_word( 0 ); put_word( 0 ); /* ne_csip */
|
||||
put_word( 0 ); put_word( 2 ); /* ne_sssp */
|
||||
put_word( cseg ); /* ne_cseg */
|
||||
put_word( 0 ); /* ne_cmod */
|
||||
put_word( 0 ); /* ne_cbnrestab */
|
||||
put_word( segtab - lfanew ); /* ne_segtab */
|
||||
put_word( rsrctab - lfanew ); /* ne_rsrctab */
|
||||
put_word( restab - lfanew ); /* ne_restab */
|
||||
put_word( modtab - lfanew ); /* ne_modtab */
|
||||
put_word( imptab - lfanew ); /* ne_imptab */
|
||||
put_dword( 0 ); /* ne_nrestab */
|
||||
put_word( 0 ); /* ne_cmovent */
|
||||
put_word( 0 ); /* ne_align */
|
||||
put_word( 0 ); /* ne_cres */
|
||||
put_byte( 2 /*NE_OSFLAGS_WINDOWS*/ ); /* ne_exetyp */
|
||||
put_byte( 8 /*NE_AFLAGS_FASTLOAD*/ ); /* ne_flagsothers */
|
||||
put_word( 0 ); /* ne_pretthunks */
|
||||
put_word( 0 ); /* ne_psegrefbytes */
|
||||
put_word( 0 ); /* ne_swaparea */
|
||||
put_word( 0 ); /* ne_expver */
|
||||
|
||||
/* segment table */
|
||||
put_word( codeseg );
|
||||
put_word( sizeof(code_segment) );
|
||||
put_word( 0x2000 /* NE_SEGFLAGS_32BIT */ );
|
||||
put_word( sizeof(code_segment) );
|
||||
put_word( dataseg );
|
||||
put_word( sizeof(data_segment) );
|
||||
put_word( 0x0001 /* NE_SEGFLAGS_DATA */ );
|
||||
put_word( sizeof(data_segment) );
|
||||
|
||||
/* resource directory */
|
||||
if (spec->nb_resources)
|
||||
{
|
||||
output_bin_res16_directory( spec, rsrcdata );
|
||||
align_output( 2 );
|
||||
}
|
||||
|
||||
/* resident names table */
|
||||
put_byte( namelen );
|
||||
for (i = 0; i < namelen; i++) put_byte( toupper(spec->dll_name[i]) );
|
||||
put_byte( 0 );
|
||||
align_output( 2 );
|
||||
|
||||
/* imported names table */
|
||||
put_word( 0 );
|
||||
|
||||
/* entry table */
|
||||
put_byte( 0 );
|
||||
align_output( 2 );
|
||||
|
||||
/* code segment */
|
||||
put_data( code_segment, sizeof(code_segment) );
|
||||
|
||||
/* data segment */
|
||||
put_data( data_segment, sizeof(data_segment) );
|
||||
|
||||
/* resource data */
|
||||
output_bin_res16_data( spec );
|
||||
|
||||
flush_output_buffer();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue