Generate 16-bit resources in the proper format inside the module data,

and get rid of the special case for builtins in NE_DefResourceHandler.
This commit is contained in:
Alexandre Julliard 2005-05-20 19:19:01 +00:00
parent 806be361d0
commit 1970e467d4
5 changed files with 119 additions and 55 deletions

View File

@ -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 */

View File

@ -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;

View File

@ -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 );

View File

@ -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 */

View File

@ -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 */