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:
parent
806be361d0
commit
1970e467d4
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 );
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user