diff --git a/dlls/kernel/ne_module.c b/dlls/kernel/ne_module.c index e2e4866f3c2..4dc2a652c6f 100644 --- a/dlls/kernel/ne_module.c +++ b/dlls/kernel/ne_module.c @@ -72,7 +72,6 @@ typedef struct { const void *module; /* module header */ void *code_start; /* 32-bit address of DLL code */ - const void *rsrc; /* resources data */ } BUILTIN16_DESCRIPTOR; struct builtin_dll @@ -1010,8 +1009,6 @@ static HMODULE16 NE_DoLoadBuiltinModule( const BUILTIN16_DESCRIPTOR *descr, cons pModule = GlobalLock16( hModule ); pModule->ne_flags |= NE_FFLAGS_BUILTIN; pModule->count = 1; - /* NOTE: (Ab)use the rsrc32_map parameter for resource data pointer */ - pModule->rsrc32_map = (void *)descr->rsrc; /* Allocate the code segment */ diff --git a/dlls/kernel/resource16.c b/dlls/kernel/resource16.c index 2ca2b7c2fc0..2cd203662b6 100644 --- a/dlls/kernel/resource16.c +++ b/dlls/kernel/resource16.c @@ -347,22 +347,12 @@ HGLOBAL16 WINAPI NE_DefResourceHandler( HGLOBAL16 hMemObj, HMODULE16 hModule, if (handle) { - if (pModule->ne_flags & NE_FFLAGS_BUILTIN) + if (!NE_READ_DATA( pModule, GlobalLock16( handle ), + (int)pNameInfo->offset << sizeShift, + (int)pNameInfo->length << sizeShift )) { - /* NOTE: hRsrcMap points to start of built-in resource data */ - memcpy( GlobalLock16( handle ), - (char *)pModule->rsrc32_map + (pNameInfo->offset << sizeShift), - pNameInfo->length << sizeShift ); - } - else - { - if (!NE_READ_DATA( pModule, GlobalLock16( handle ), - (int)pNameInfo->offset << sizeShift, - (int)pNameInfo->length << sizeShift )) - { - GlobalFree16( handle ); - handle = 0; - } + GlobalFree16( handle ); + handle = 0; } } return handle; diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index 7dee65e9319..675624ad52e 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -177,8 +177,13 @@ extern int output_imports( FILE *outfile, DLLSPEC *spec ); extern int load_res32_file( const char *name, DLLSPEC *spec ); extern void output_resources( FILE *outfile, DLLSPEC *spec ); extern void load_res16_file( const char *name, DLLSPEC *spec ); -extern int output_res16_data( FILE *outfile, DLLSPEC *spec ); -extern unsigned int output_res16_directory( unsigned char **ret_buf, DLLSPEC *spec ); +extern unsigned int get_res16_data_size( DLLSPEC *spec, unsigned int res_offset, + unsigned int alignment ); +extern unsigned int output_res16_data( unsigned char **ret_buf, DLLSPEC *spec, + unsigned int res_offset, unsigned int alignment ); +extern unsigned int get_res16_directory_size( DLLSPEC *spec ); +extern unsigned int output_res16_directory( unsigned char **ret_buf, DLLSPEC *spec, + unsigned int res_offset, unsigned int alignment ); extern void output_dll_init( FILE *outfile, const char *constructor, const char *destructor ); extern void BuildRelays16( FILE *outfile ); diff --git a/tools/winebuild/res16.c b/tools/winebuild/res16.c index b5540defdbf..9aad666bdfb 100644 --- a/tools/winebuild/res16.c +++ b/tools/winebuild/res16.c @@ -42,9 +42,6 @@ #include "winbase.h" #include "build.h" -#define ALIGNMENT 2 /* alignment for resource data */ -#define ALIGN_MASK ((1 << ALIGNMENT) - 1) - /* Unicode string or integer id */ struct string_id { @@ -268,43 +265,96 @@ static void output_string( unsigned char **buffer, const char *str ) while (len--) put_byte( buffer, *str++ ); } -/* output the resource data */ -int output_res16_data( FILE *outfile, DLLSPEC *spec ) +/* get the resource data total size */ +unsigned int get_res16_data_size( DLLSPEC *spec, unsigned int res_offset, unsigned int alignment ) { const struct resource *res; - unsigned char *buffer, *p; - unsigned int i; - int total; + unsigned int i, total; + unsigned int align_mask = (1 << alignment) - 1; if (!spec->nb_resources) return 0; - for (i = total = 0, res = spec->resources; i < spec->nb_resources; i++, res++) - total += (res->data_size + ALIGN_MASK) & ~ALIGN_MASK; + /* add padding at the beginning if needed so that resources are properly aligned */ + total = ((res_offset + align_mask) & ~align_mask) - res_offset; - buffer = p = xmalloc( total ); for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++) - { - memcpy( p, res->data, res->data_size ); - p += res->data_size; - while ((int)p & ALIGN_MASK) *p++ = 0; - } - dump_bytes( outfile, buffer, total, "resource_data", 1 ); - free( buffer ); + total += (res->data_size + align_mask) & ~align_mask; + return total; } -/* output the resource definitions */ -unsigned int output_res16_directory( unsigned char **ret_buf, DLLSPEC *spec ) +/* output the resource data */ +unsigned int output_res16_data( unsigned char **ret_buf, DLLSPEC *spec, + unsigned int res_offset, unsigned int alignment ) +{ + const struct resource *res; + unsigned char *p; + unsigned int i, total, padding; + unsigned int align_mask = (1 << alignment) - 1; + + if (!spec->nb_resources) return 0; + + /* add padding at the beginning if needed so that resources are properly aligned */ + padding = ((res_offset + align_mask) & ~align_mask) - res_offset; + + for (i = total = 0, res = spec->resources; i < spec->nb_resources; i++, res++) + total += (res->data_size + align_mask) & ~align_mask; + + *ret_buf = p = xmalloc( total + padding ); + memset( p, 0, padding ); + p += padding; + for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++) + { + unsigned int size = (res->data_size + align_mask) & ~align_mask; + memcpy( p, res->data, res->data_size ); + memset( p + res->data_size, 0, size - res->data_size ); + p += size; + } + return total; +} + +/* get the resource definitions total size */ +unsigned int get_res16_directory_size( DLLSPEC *spec ) { - int offset, res_offset = 0; unsigned int i, j, total_size; struct res_tree *tree; const struct res_type *type; const struct resource *res; + + tree = build_resource_tree( spec ); + + total_size = 4; /* alignment + terminator */ + total_size += tree->nb_types * 8; /* typeinfo structures */ + total_size += spec->nb_resources * 12; /* nameinfo structures */ + + for (i = 0, type = tree->types; i < tree->nb_types; i++, type++) + { + if (type->type->str) total_size += strlen(type->type->str) + 1; + for (j = 0, res = type->res; j < type->nb_names; j++, res++) + if (res->name.str) total_size += strlen(res->name.str) + 1; + } + total_size++; /* final terminator */ + if (total_size & 1) total_size++; + return total_size; +} + +/* output the resource definitions */ +unsigned int output_res16_directory( unsigned char **ret_buf, DLLSPEC *spec, + unsigned int res_offset, unsigned int alignment ) +{ + int offset; + unsigned int i, j, total_size; + unsigned int align_mask = (1 << alignment) - 1; + struct res_tree *tree; + const struct res_type *type; + const struct resource *res; unsigned char *buffer; tree = build_resource_tree( spec ); + /* make sure data offset is properly aligned */ + res_offset = (res_offset + align_mask) & ~align_mask; + /* first compute total size */ offset = 4; /* alignment + terminator */ @@ -323,7 +373,7 @@ unsigned int output_res16_directory( unsigned char **ret_buf, DLLSPEC *spec ) if (total_size & 1) total_size++; *ret_buf = buffer = xmalloc( total_size ); - put_word( &buffer, ALIGNMENT ); + put_word( &buffer, alignment ); /* type and name structures */ @@ -343,8 +393,8 @@ unsigned int output_res16_directory( unsigned char **ret_buf, DLLSPEC *spec ) for (j = 0, res = type->res; j < type->nb_names; j++, res++) { - put_word( &buffer, res_offset >> ALIGNMENT ); - put_word( &buffer, (res->data_size + ALIGN_MASK) >> ALIGNMENT ); + put_word( &buffer, res_offset >> alignment ); + put_word( &buffer, (res->data_size + align_mask) >> alignment ); put_word( &buffer, res->memopt ); if (res->name.str) { @@ -355,7 +405,7 @@ unsigned int output_res16_directory( unsigned char **ret_buf, DLLSPEC *spec ) put_word( &buffer, res->name.id | 0x8000 ); put_word( &buffer, 0 ); put_word( &buffer, 0 ); - res_offset += (res->data_size + ALIGN_MASK) & ~ALIGN_MASK; + res_offset += (res->data_size + align_mask) & ~align_mask; } } put_word( &buffer, 0 ); /* terminator */ diff --git a/tools/winebuild/spec16.c b/tools/winebuild/spec16.c index a4261b4aabf..6266327452f 100644 --- a/tools/winebuild/spec16.c +++ b/tools/winebuild/spec16.c @@ -203,11 +203,14 @@ static void output_bytes( FILE *outfile, const void *buffer, unsigned int size ) static void output_module_data( FILE *outfile, int max_code_offset, const void *data_segment, unsigned int data_size, DLLSPEC *spec ) { - unsigned char *res_buffer, *et_buffer; + unsigned char *resdir_buffer, *resdata_buffer, *et_buffer; unsigned char string[256]; int i; - unsigned int segtable_offset, resdir_offset, impnames_offset, resnames_offset, et_offset, data_offset; - unsigned int resnames_size, resdir_size, et_size; + unsigned int ne_offset, segtable_offset, impnames_offset, data_offset; + unsigned int resnames_offset, resnames_size; + unsigned int resdir_size, resdir_offset; + unsigned int resdata_size, resdata_offset, resdata_align; + unsigned int et_size, et_offset; /* DOS header */ @@ -236,6 +239,7 @@ static void output_module_data( FILE *outfile, int max_code_offset, const void * /* NE header */ + ne_offset = 64; fprintf( outfile, " struct\n {\n" ); fprintf( outfile, " unsigned short ne_magic;\n" ); fprintf( outfile, " unsigned char ne_ver;\n" ); @@ -282,7 +286,7 @@ static void output_module_data( FILE *outfile, int max_code_offset, const void * /* resource directory */ resdir_offset = segtable_offset + 2 * 8; - resdir_size = output_res16_directory( &res_buffer, spec ); + resdir_size = get_res16_directory_size( spec ); fprintf( outfile, " unsigned char resdir[%d];\n", resdir_size ); /* resident names table */ @@ -322,6 +326,18 @@ static void output_module_data( FILE *outfile, int max_code_offset, const void * if (data_offset + data_size >= 0x10000) fatal_error( "Not supported yet: 16-bit module data larger than 64K\n" ); + /* resource data */ + + resdata_offset = ne_offset + data_offset + data_size; + for (resdata_align = 0; resdata_align < 16; resdata_align++) + { + unsigned int size = get_res16_data_size( spec, resdata_offset, resdata_align ); + if ((resdata_offset + size) >> resdata_align <= 0xffff) break; + } + output_res16_directory( &resdir_buffer, spec, resdata_offset, resdata_align ); + resdata_size = output_res16_data( &resdata_buffer, spec, resdata_offset, resdata_align ); + if (resdata_size) fprintf( outfile, " unsigned char resources[%d];\n", resdata_size ); + /* DOS header */ fprintf( outfile, "} module =\n{\n {\n" ); @@ -375,8 +391,8 @@ static void output_module_data( FILE *outfile, int max_code_offset, const void * /* resource directory */ - output_bytes( outfile, res_buffer, resdir_size ); - free( res_buffer ); + output_bytes( outfile, resdir_buffer, resdir_size ); + free( resdir_buffer ); /* resident names table */ @@ -405,6 +421,14 @@ static void output_module_data( FILE *outfile, int max_code_offset, const void * output_bytes( outfile, data_segment, data_size ); + /* resource data */ + + if (resdata_size) + { + output_bytes( outfile, resdata_buffer, resdata_size ); + free( resdata_buffer ); + } + fprintf( outfile, "};\n" ); } @@ -647,7 +671,7 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec ) { ORDDEF **type, **typelist; int i, nFuncs, nTypes; - int code_offset, data_offset, res_size; + int code_offset, data_offset; unsigned char *data; char constructor[100], destructor[100]; #ifdef __i386__ @@ -878,7 +902,6 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec ) /* Build the module */ output_module_data( outfile, code_offset, data, data_offset, spec ); - res_size = output_res16_data( outfile, spec ); /* Output the DLL descriptor */ @@ -890,8 +913,7 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec ) fprintf( outfile, " const unsigned char *rsrc;\n" ); fprintf( outfile, "} descriptor =\n{\n" ); fprintf( outfile, " &module,\n" ); - fprintf( outfile, " &code_segment,\n" ); - fprintf( outfile, " %s\n", res_size ? "resource_data" : "0" ); + fprintf( outfile, " &code_segment\n" ); fprintf( outfile, "};\n" ); /* Output the DLL constructor */