mirror of
https://github.com/reactos/wine.git
synced 2024-11-24 20:30:01 +00:00
Added support for loading .res files for 16-bit resources.
This commit is contained in:
parent
cae289cbe4
commit
cbeb644a94
@ -79,7 +79,7 @@ CLEAN_FILES = *.o *.a *.so *.ln \\\#*\\\# *~ *% .\\\#* *.bak *.orig *.rej \
|
||||
*.flc *.spec.c *.glue.c y.tab.c y.tab.h lex.yy.c core
|
||||
|
||||
OBJS = $(SPEC_SRCS:.spec=.spec.o) $(C_SRCS:.c=.o) $(GEN_C_SRCS:.c=.o) $(GEN_ASM_SRCS:.s=.o) \
|
||||
$(ASM_SRCS:.S=.o) $(RC16_SRCS:.rc16=.o) $(GLUE:.c=.glue.o) $(EXTRA_OBJS)
|
||||
$(ASM_SRCS:.S=.o) $(GLUE:.c=.glue.o) $(EXTRA_OBJS)
|
||||
|
||||
LINTS = $(C_SRCS:.c=.ln)
|
||||
|
||||
@ -154,7 +154,7 @@ DLLS = \
|
||||
|
||||
# Implicit rules
|
||||
|
||||
.SUFFIXES: .mc .rc .rc16 .res .spec .spec.c .spec.o .glue.c
|
||||
.SUFFIXES: .mc .rc .res .spec .spec.c .spec.o .glue.c
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(ALLCFLAGS) -o $*.o $<
|
||||
@ -171,9 +171,6 @@ DLLS = \
|
||||
.mc.rc:
|
||||
LD_LIBRARY_PATH="$(TOPOBJDIR):$$LD_LIBRARY_PATH" $(WMC) -i -H /dev/null -o $@ $<
|
||||
|
||||
.rc16.s:
|
||||
LD_LIBRARY_PATH="$(TOPOBJDIR):$$LD_LIBRARY_PATH" $(WRC) $(WRCFLAGS) $(DIVINCL) -o $@ -w16 -m -c -p `basename $*` -s $<
|
||||
|
||||
.rc.res:
|
||||
LD_LIBRARY_PATH="$(TOPOBJDIR):$$LD_LIBRARY_PATH" $(WRC) $(WRCFLAGS) $(DIVINCL) -o $@ -r $<
|
||||
|
||||
@ -253,8 +250,8 @@ winapi_check::
|
||||
$(SUBDIRS:%=%/__depend__): $(MAKEDEP) dummy
|
||||
cd `dirname $@` && $(MAKE) depend
|
||||
|
||||
depend: $(MAKEDEP) $(C_SRCS) $(RC_SRCS) $(RC16_SRCS) $(EXTRA_SRCS) $(GEN_C_SRCS) $(SUBDIRS:%=%/__depend__)
|
||||
$(MAKEDEP) $(DIVINCL) -C$(SRCDIR) $(C_SRCS) $(RC_SRCS) $(RC16_SRCS) $(EXTRA_SRCS) -C. $(GEN_C_SRCS)
|
||||
depend: $(MAKEDEP) $(C_SRCS) $(RC_SRCS) $(EXTRA_SRCS) $(GEN_C_SRCS) $(SUBDIRS:%=%/__depend__)
|
||||
$(MAKEDEP) $(DIVINCL) -C$(SRCDIR) $(C_SRCS) $(RC_SRCS) $(EXTRA_SRCS) -C. $(GEN_C_SRCS)
|
||||
|
||||
# Rules for cleaning
|
||||
|
||||
@ -265,7 +262,7 @@ $(EXTRASUBDIRS:%=%/__clean__): dummy
|
||||
-cd `dirname $@` && $(RM) $(CLEAN_FILES)
|
||||
|
||||
clean:: $(SUBDIRS:%=%/__clean__) $(EXTRASUBDIRS:%=%/__clean__)
|
||||
$(RM) $(CLEAN_FILES) $(GEN_C_SRCS) $(GEN_ASM_SRCS) $(RC_SRCS:.rc=.res) $(RC16_SRCS:.rc16=.s) $(MC_SRCS:.mc=.rc) $(PROGRAMS)
|
||||
$(RM) $(CLEAN_FILES) $(GEN_C_SRCS) $(GEN_ASM_SRCS) $(RC_SRCS:.rc=.res) $(MC_SRCS:.mc=.rc) $(PROGRAMS)
|
||||
|
||||
# Rules for installing
|
||||
|
||||
@ -281,7 +278,7 @@ $(SPEC_SRCS:.spec=.spec.c): $(WINEBUILD) $(TOPSRCDIR)/include/builtin16.h
|
||||
|
||||
$(GLUE:.c=.glue.c): $(WINEBUILD) $(TOPSRCDIR)/include/builtin16.h
|
||||
|
||||
$(RC_SRCS:.rc=.res) $(RC16_SRCS:.rc16=.s): $(WRC)
|
||||
$(RC_SRCS:.rc=.res): $(WRC)
|
||||
|
||||
$(MC_SRCS:.mc=.rc): $(WMC)
|
||||
|
||||
|
@ -22,11 +22,10 @@ C_SRCS = \
|
||||
thunk.c \
|
||||
user_main.c
|
||||
|
||||
RC16_SRCS = \
|
||||
resources/display.rc16 \
|
||||
resources/mouse.rc16
|
||||
|
||||
RC_SRCS = resources/user32.rc
|
||||
RC_SRCS = \
|
||||
resources/display.rc \
|
||||
resources/mouse.rc \
|
||||
resources/user32.rc
|
||||
|
||||
GLUE = thunk.c
|
||||
|
||||
@ -46,4 +45,12 @@ EXTRASUBDIRS = \
|
||||
$(EXTRA_OBJS): $(TOOLSUBDIRS) dummy
|
||||
@cd `dirname $@` && $(MAKE) `basename $@`
|
||||
|
||||
# Special rules for 16-bit resource files
|
||||
|
||||
resources/display.res: resources/display.rc
|
||||
LD_LIBRARY_PATH="$(TOPOBJDIR):$$LD_LIBRARY_PATH" $(WRC) $(DIVINCL) -o $@ -w16 -m -r resources/display.rc
|
||||
|
||||
resources/mouse.res: resources/mouse.rc
|
||||
LD_LIBRARY_PATH="$(TOPOBJDIR):$$LD_LIBRARY_PATH" $(WRC) $(DIVINCL) -o $@ -w16 -m -r resources/mouse.rc
|
||||
|
||||
### Dependencies:
|
||||
|
@ -1,7 +1,7 @@
|
||||
name display
|
||||
type win16
|
||||
owner user32
|
||||
rsrc display
|
||||
rsrc resources/display.res
|
||||
|
||||
1 stub BitBlt
|
||||
2 stub ColorInfo
|
||||
|
@ -1,7 +1,7 @@
|
||||
name mouse
|
||||
type win16
|
||||
owner user32
|
||||
rsrc mouse
|
||||
rsrc resources/mouse.res
|
||||
|
||||
1 pascal16 Inquire(ptr) MOUSE_Inquire
|
||||
2 pascal16 Enable(segptr) WIN16_MOUSE_Enable
|
||||
|
@ -1,3 +1,3 @@
|
||||
display.s
|
||||
mouse.s
|
||||
display.res
|
||||
mouse.res
|
||||
user32.res
|
||||
|
@ -23,14 +23,6 @@
|
||||
|
||||
DEFAULT_DEBUG_CHANNEL(module);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LPVOID res_start; /* address of resource data */
|
||||
DWORD nr_res;
|
||||
DWORD res_size; /* size of resource data */
|
||||
} BUILTIN16_RESOURCE;
|
||||
|
||||
|
||||
/* Table of all built-in DLLs */
|
||||
|
||||
#define MAX_DLLS 50
|
||||
@ -47,54 +39,20 @@ static int nb_dlls;
|
||||
static HMODULE16 BUILTIN_DoLoadModule16( const BUILTIN16_DESCRIPTOR *descr )
|
||||
{
|
||||
NE_MODULE *pModule;
|
||||
int minsize, res_off;
|
||||
int minsize;
|
||||
SEGTABLEENTRY *pSegTable;
|
||||
HMODULE16 hModule;
|
||||
const BUILTIN16_RESOURCE *rsrc = descr->rsrc;
|
||||
|
||||
if (!rsrc)
|
||||
{
|
||||
hModule = GLOBAL_CreateBlock( GMEM_MOVEABLE, descr->module_start,
|
||||
descr->module_size, 0,
|
||||
FALSE, FALSE, FALSE );
|
||||
if (!hModule) return 0;
|
||||
FarSetOwner16( hModule, hModule );
|
||||
hModule = GLOBAL_CreateBlock( GMEM_MOVEABLE, descr->module_start,
|
||||
descr->module_size, 0,
|
||||
FALSE, FALSE, FALSE );
|
||||
if (!hModule) return 0;
|
||||
FarSetOwner16( hModule, hModule );
|
||||
|
||||
pModule = (NE_MODULE *)GlobalLock16( hModule );
|
||||
}
|
||||
else
|
||||
{
|
||||
ET_BUNDLE *bundle;
|
||||
|
||||
hModule = GLOBAL_Alloc( GMEM_MOVEABLE,
|
||||
descr->module_size + rsrc->res_size,
|
||||
0, FALSE, FALSE, FALSE );
|
||||
if (!hModule) return 0;
|
||||
FarSetOwner16( hModule, hModule );
|
||||
|
||||
pModule = (NE_MODULE *)GlobalLock16( hModule );
|
||||
res_off = ((NE_MODULE *)descr->module_start)->res_table;
|
||||
|
||||
memcpy( (LPBYTE)pModule, descr->module_start, res_off );
|
||||
memcpy( (LPBYTE)pModule + res_off, rsrc->res_start, rsrc->res_size );
|
||||
memcpy( (LPBYTE)pModule + res_off + rsrc->res_size,
|
||||
(LPBYTE)descr->module_start + res_off, descr->module_size - res_off );
|
||||
|
||||
/* Have to fix up various pModule-based near pointers. Ugh! */
|
||||
pModule->name_table += rsrc->res_size;
|
||||
pModule->modref_table += rsrc->res_size;
|
||||
pModule->import_table += rsrc->res_size;
|
||||
pModule->entry_table += rsrc->res_size;
|
||||
|
||||
for ( bundle = (ET_BUNDLE *)((LPBYTE)pModule + pModule->entry_table);
|
||||
bundle->next;
|
||||
bundle = (ET_BUNDLE *)((LPBYTE)pModule + bundle->next) )
|
||||
bundle->next += rsrc->res_size;
|
||||
|
||||
/* NOTE: (Ab)use the hRsrcMap parameter for resource data pointer */
|
||||
pModule->hRsrcMap = rsrc->res_start;
|
||||
}
|
||||
pModule = (NE_MODULE *)GlobalLock16( hModule );
|
||||
pModule->self = hModule;
|
||||
/* NOTE: (Ab)use the hRsrcMap parameter for resource data pointer */
|
||||
pModule->hRsrcMap = (void *)descr->rsrc;
|
||||
|
||||
TRACE( "Built-in %s: hmodule=%04x\n", descr->name, hModule );
|
||||
|
||||
@ -120,8 +78,7 @@ static HMODULE16 BUILTIN_DoLoadModule16( const BUILTIN16_DESCRIPTOR *descr )
|
||||
LocalInit16( GlobalHandleToSel16(pSegTable->hSeg),
|
||||
pSegTable->minsize, minsize );
|
||||
|
||||
if (rsrc)
|
||||
NE_InitResourceHandler(hModule);
|
||||
if (descr->rsrc) NE_InitResourceHandler(hModule);
|
||||
|
||||
NE_RegisterModule( pModule );
|
||||
return hModule;
|
||||
|
@ -13,6 +13,7 @@ C_SRCS = \
|
||||
main.c \
|
||||
parser.c \
|
||||
relay.c \
|
||||
res16.c \
|
||||
res32.c \
|
||||
spec16.c \
|
||||
spec32.c \
|
||||
|
@ -139,12 +139,16 @@ extern char *strupper(char *s);
|
||||
extern void fatal_error( const char *msg, ... );
|
||||
extern void fatal_perror( const char *msg, ... );
|
||||
extern void warning( const char *msg, ... );
|
||||
extern void dump_bytes( FILE *outfile, const unsigned char *data, int len, const char *label );
|
||||
extern void dump_bytes( FILE *outfile, const unsigned char *data, int len,
|
||||
const char *label, int constant );
|
||||
extern void add_import_dll( const char *name );
|
||||
extern void resolve_imports( FILE *outfile );
|
||||
extern int output_imports( FILE *outfile );
|
||||
extern void load_res32_file( const char *name );
|
||||
extern int output_resources( FILE *outfile );
|
||||
extern void load_res16_file( const char *name );
|
||||
extern int output_res16_data( FILE *outfile );
|
||||
extern int output_res16_directory( unsigned char *buffer );
|
||||
|
||||
extern void BuildGlue( FILE *outfile, FILE *infile );
|
||||
extern void BuildRelays( FILE *outfile );
|
||||
@ -169,7 +173,6 @@ extern unsigned short data_selector;
|
||||
extern char DLLName[80];
|
||||
extern char DLLFileName[80];
|
||||
extern char DLLInitFunc[80];
|
||||
extern char rsrc_name[80];
|
||||
extern char owner_name[80];
|
||||
extern const char *input_file_name;
|
||||
extern const char *output_file_name;
|
||||
|
@ -43,7 +43,6 @@ int debugging = 1;
|
||||
char DLLName[80];
|
||||
char DLLFileName[80];
|
||||
char DLLInitFunc[80];
|
||||
char rsrc_name[80];
|
||||
char owner_name[80];
|
||||
|
||||
const char *input_file_name;
|
||||
|
@ -482,11 +482,7 @@ SPEC_TYPE ParseTopLevel( FILE *file )
|
||||
else if (strcmp(token, "rsrc") == 0)
|
||||
{
|
||||
if (SpecType != SPEC_WIN16) load_res32_file( GetToken() );
|
||||
else
|
||||
{
|
||||
strcpy( rsrc_name, GetToken() );
|
||||
strcat( rsrc_name, "_ResourceDescriptor" );
|
||||
}
|
||||
else load_res16_file( GetToken() );
|
||||
}
|
||||
else if (strcmp(token, "owner") == 0)
|
||||
{
|
||||
|
309
tools/winebuild/res16.c
Normal file
309
tools/winebuild/res16.c
Normal file
@ -0,0 +1,309 @@
|
||||
/*
|
||||
* Builtin dlls resource support
|
||||
*
|
||||
* Copyright 2000 Alexandre Julliard
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#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
|
||||
{
|
||||
char *str; /* ptr to string */
|
||||
WORD id; /* integer id if str is NULL */
|
||||
};
|
||||
|
||||
/* descriptor for a resource */
|
||||
struct resource
|
||||
{
|
||||
struct string_id type;
|
||||
struct string_id name;
|
||||
const void *data;
|
||||
unsigned int data_size;
|
||||
WORD memopt;
|
||||
};
|
||||
|
||||
/* type level of the resource tree */
|
||||
struct res_type
|
||||
{
|
||||
const struct string_id *type; /* type name */
|
||||
const struct resource *res; /* first resource of this type */
|
||||
unsigned int nb_names; /* total number of names */
|
||||
};
|
||||
|
||||
static struct resource *resources;
|
||||
static int nb_resources;
|
||||
|
||||
static struct res_type *res_types;
|
||||
static int nb_types; /* total number of types */
|
||||
|
||||
static const unsigned char *file_pos; /* current position in resource file */
|
||||
static const unsigned char *file_end; /* end of resource file */
|
||||
static const char *file_name; /* current resource file name */
|
||||
|
||||
|
||||
inline static struct resource *add_resource(void)
|
||||
{
|
||||
resources = xrealloc( resources, (nb_resources + 1) * sizeof(*resources) );
|
||||
return &resources[nb_resources++];
|
||||
}
|
||||
|
||||
static struct res_type *add_type( const struct resource *res )
|
||||
{
|
||||
struct res_type *type;
|
||||
res_types = xrealloc( res_types, (nb_types + 1) * sizeof(*res_types) );
|
||||
type = &res_types[nb_types++];
|
||||
type->type = &res->type;
|
||||
type->res = res;
|
||||
type->nb_names = 0;
|
||||
return type;
|
||||
}
|
||||
|
||||
/* get the next byte from the current resource file */
|
||||
static WORD get_byte(void)
|
||||
{
|
||||
unsigned char ret = *file_pos++;
|
||||
if (file_pos > file_end) fatal_error( "%s is a truncated/corrupted file\n", file_name );
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* get the next word from the current resource file */
|
||||
static WORD get_word(void)
|
||||
{
|
||||
/* might not be aligned */
|
||||
/* FIXME: should we change this on big-endian machines? */
|
||||
unsigned char low = get_byte();
|
||||
unsigned char high = get_byte();
|
||||
return low | (high << 8);
|
||||
}
|
||||
|
||||
/* get the next dword from the current resource file */
|
||||
static DWORD get_dword(void)
|
||||
{
|
||||
WORD low = get_word();
|
||||
WORD high = get_word();
|
||||
return low | (high << 16);
|
||||
}
|
||||
|
||||
/* get a string from the current resource file */
|
||||
static void get_string( struct string_id *str )
|
||||
{
|
||||
if (*file_pos == 0xff)
|
||||
{
|
||||
get_byte(); /* skip the 0xff */
|
||||
str->str = NULL;
|
||||
str->id = get_word();
|
||||
}
|
||||
else
|
||||
{
|
||||
char *p = xmalloc( (strlen(file_pos) + 1) );
|
||||
str->str = p;
|
||||
str->id = 0;
|
||||
while ((*p++ = get_byte()));
|
||||
}
|
||||
}
|
||||
|
||||
/* load the next resource from the current file */
|
||||
static void load_next_resource(void)
|
||||
{
|
||||
struct resource *res = add_resource();
|
||||
|
||||
get_string( &res->type );
|
||||
get_string( &res->name );
|
||||
res->memopt = get_word();
|
||||
res->data_size = get_dword();
|
||||
res->data = file_pos;
|
||||
file_pos += res->data_size;
|
||||
if (file_pos > file_end) fatal_error( "%s is a truncated/corrupted file\n", file_name );
|
||||
}
|
||||
|
||||
/* load a Win16 .res file */
|
||||
void load_res16_file( const char *name )
|
||||
{
|
||||
int fd;
|
||||
void *base;
|
||||
struct stat st;
|
||||
|
||||
if ((fd = open( name, O_RDONLY )) == -1) fatal_perror( "Cannot open %s", name );
|
||||
if ((fstat( fd, &st ) == -1)) fatal_perror( "Cannot stat %s", name );
|
||||
if (!st.st_size) fatal_error( "%s is an empty file\n" );
|
||||
if ((base = mmap( NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0 )) == (void*)-1)
|
||||
{
|
||||
base = xmalloc( st.st_size );
|
||||
if (read( fd, base, st.st_size ) != st.st_size)
|
||||
fatal_error( "Cannot read %s\n", name );
|
||||
}
|
||||
|
||||
file_name = name;
|
||||
file_pos = base;
|
||||
file_end = file_pos + st.st_size;
|
||||
while (file_pos < file_end) load_next_resource();
|
||||
}
|
||||
|
||||
/* compare two strings/ids */
|
||||
static int cmp_string( const struct string_id *str1, const struct string_id *str2 )
|
||||
{
|
||||
if (!str1->str)
|
||||
{
|
||||
if (!str2->str) return str1->id - str2->id;
|
||||
return 1; /* an id compares larger than a string */
|
||||
}
|
||||
if (!str2->str) return -1;
|
||||
return strcasecmp( str1->str, str2->str );
|
||||
}
|
||||
|
||||
/* compare two resources for sorting the resource directory */
|
||||
/* resources are stored first by type, then by name */
|
||||
static int cmp_res( const void *ptr1, const void *ptr2 )
|
||||
{
|
||||
const struct resource *res1 = ptr1;
|
||||
const struct resource *res2 = ptr2;
|
||||
int ret;
|
||||
|
||||
if ((ret = cmp_string( &res1->type, &res2->type ))) return ret;
|
||||
return cmp_string( &res1->name, &res2->name );
|
||||
}
|
||||
|
||||
/* build the 2-level (type,name) resource tree */
|
||||
static void build_resource_tree(void)
|
||||
{
|
||||
int i;
|
||||
struct res_type *type = NULL;
|
||||
|
||||
qsort( resources, nb_resources, sizeof(*resources), cmp_res );
|
||||
|
||||
for (i = 0; i < nb_resources; i++)
|
||||
{
|
||||
if (!i || cmp_string( &resources[i].type, &resources[i-1].type )) /* new type */
|
||||
type = add_type( &resources[i] );
|
||||
type->nb_names++;
|
||||
}
|
||||
}
|
||||
|
||||
inline static void put_byte( unsigned char **buffer, unsigned char val )
|
||||
{
|
||||
*(*buffer)++ = val;
|
||||
}
|
||||
|
||||
inline static void put_word( unsigned char **buffer, WORD val )
|
||||
{
|
||||
put_byte( buffer, LOBYTE(val) );
|
||||
put_byte( buffer, HIBYTE(val) );
|
||||
}
|
||||
|
||||
/* output a string preceded by its length */
|
||||
static void output_string( unsigned char **buffer, const char *str )
|
||||
{
|
||||
int len = strlen(str);
|
||||
put_byte( buffer, len );
|
||||
while (len--) put_byte( buffer, *str++ );
|
||||
}
|
||||
|
||||
/* output the resource data */
|
||||
int output_res16_data( FILE *outfile )
|
||||
{
|
||||
const struct resource *res;
|
||||
unsigned char *buffer, *p;
|
||||
int i, total;
|
||||
|
||||
if (!nb_resources) return 0;
|
||||
|
||||
for (i = total = 0, res = resources; i < nb_resources; i++, res++)
|
||||
total += (res->data_size + ALIGN_MASK) & ~ALIGN_MASK;
|
||||
|
||||
buffer = p = xmalloc( total );
|
||||
for (i = 0, res = resources; i < 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 );
|
||||
return total;
|
||||
}
|
||||
|
||||
/* output the resource definitions */
|
||||
int output_res16_directory( unsigned char *buffer )
|
||||
{
|
||||
int i, j, offset, res_offset = 0;
|
||||
const struct res_type *type;
|
||||
const struct resource *res;
|
||||
unsigned char *start = buffer;
|
||||
|
||||
build_resource_tree();
|
||||
|
||||
offset = 4; /* alignment + terminator */
|
||||
offset += nb_types * 8; /* typeinfo structures */
|
||||
offset += nb_resources * 12; /* nameinfo structures */
|
||||
|
||||
put_word( &buffer, ALIGNMENT );
|
||||
|
||||
/* type and name structures */
|
||||
|
||||
for (i = 0, type = res_types; i < nb_types; i++, type++)
|
||||
{
|
||||
if (type->type->str)
|
||||
{
|
||||
put_word( &buffer, offset );
|
||||
offset += strlen(type->type->str) + 1;
|
||||
}
|
||||
else
|
||||
put_word( &buffer, type->type->id | 0x8000 );
|
||||
|
||||
put_word( &buffer, type->nb_names );
|
||||
put_word( &buffer, 0 );
|
||||
put_word( &buffer, 0 );
|
||||
|
||||
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->memopt );
|
||||
if (res->name.str)
|
||||
{
|
||||
put_word( &buffer, offset );
|
||||
offset += strlen(res->name.str) + 1;
|
||||
}
|
||||
else
|
||||
put_word( &buffer, res->name.id | 0x8000 );
|
||||
put_word( &buffer, 0 );
|
||||
put_word( &buffer, 0 );
|
||||
res_offset += (res->data_size + ALIGN_MASK) & ~ALIGN_MASK;
|
||||
}
|
||||
}
|
||||
put_word( &buffer, 0 ); /* terminator */
|
||||
|
||||
/* name strings */
|
||||
|
||||
for (i = 0, type = res_types; i < nb_types; i++, type++)
|
||||
{
|
||||
if (type->type->str) output_string( &buffer, type->type->str );
|
||||
for (j = 0, res = type->res; j < type->nb_names; j++, res++)
|
||||
{
|
||||
if (res->name.str) output_string( &buffer, res->name.str );
|
||||
}
|
||||
}
|
||||
put_byte( &buffer, 0 ); /* names terminator */
|
||||
if ((buffer - start) & 1) put_byte( &buffer, 0 ); /* align on word boundary */
|
||||
|
||||
return buffer - start;
|
||||
}
|
@ -63,9 +63,8 @@ static struct res_type *res_types;
|
||||
static int nb_types; /* total number of types */
|
||||
static int nb_id_types; /* number of types that have a numeric id */
|
||||
|
||||
static const char *file_base; /* base of resource file */
|
||||
static const char *file_pos; /* current position in resource file */
|
||||
static const char *file_end; /* end of resource file */
|
||||
static const unsigned char *file_pos; /* current position in resource file */
|
||||
static const unsigned char *file_end; /* end of resource file */
|
||||
static const char *file_name; /* current resource file name */
|
||||
|
||||
|
||||
@ -121,8 +120,7 @@ static DWORD get_dword(void)
|
||||
/* get a string from the current resource file */
|
||||
static void get_string( struct string_id *str )
|
||||
{
|
||||
WCHAR *p = (WCHAR *)file_pos;
|
||||
if (*p == 0xffff)
|
||||
if (*(WCHAR *)file_pos == 0xffff)
|
||||
{
|
||||
get_word(); /* skip the 0xffff */
|
||||
str->str = NULL;
|
||||
@ -130,9 +128,9 @@ static void get_string( struct string_id *str )
|
||||
}
|
||||
else
|
||||
{
|
||||
str->str = xmalloc( (strlenW(p) + 1) * sizeof(WCHAR) );
|
||||
str->id = 0;
|
||||
p = str->str;
|
||||
WCHAR *p = xmalloc( (strlenW((WCHAR*)file_pos) + 1) * sizeof(WCHAR) );
|
||||
str->str = p;
|
||||
str->id = 0;
|
||||
while ((*p++ = get_word()));
|
||||
}
|
||||
}
|
||||
@ -197,9 +195,8 @@ void load_res32_file( const char *name )
|
||||
}
|
||||
|
||||
file_name = name;
|
||||
file_base = base;
|
||||
file_pos = file_base;
|
||||
file_end = file_base + st.st_size;
|
||||
file_pos = base;
|
||||
file_end = file_pos + st.st_size;
|
||||
check_header();
|
||||
while (file_pos < file_end) load_next_resource();
|
||||
}
|
||||
|
@ -62,7 +62,6 @@ static int BuildModule16( FILE *outfile, int max_code_offset,
|
||||
SEGTABLEENTRY *pSegment;
|
||||
OFSTRUCT *pFileInfo;
|
||||
BYTE *pstr;
|
||||
WORD *pword;
|
||||
ET_BUNDLE *bundle = 0;
|
||||
ET_ENTRY *entry = 0;
|
||||
|
||||
@ -143,14 +142,12 @@ static int BuildModule16( FILE *outfile, int max_code_offset,
|
||||
|
||||
/* Resource table */
|
||||
|
||||
pword = (WORD *)pSegment;
|
||||
pModule->res_table = (int)pword - (int)pModule;
|
||||
*pword++ = 0;
|
||||
*pword++ = 0;
|
||||
pstr = (char *)pSegment;
|
||||
pModule->res_table = (int)pstr - (int)pModule;
|
||||
pstr += output_res16_directory( pstr );
|
||||
|
||||
/* Imported names table */
|
||||
|
||||
pstr = (char *)pword;
|
||||
pModule->import_table = (int)pstr - (int)pModule;
|
||||
*pstr++ = 0;
|
||||
*pstr++ = 0;
|
||||
@ -243,7 +240,7 @@ static int BuildModule16( FILE *outfile, int max_code_offset,
|
||||
|
||||
/* Dump the module content */
|
||||
|
||||
dump_bytes( outfile, (char *)pModule, (int)pstr - (int)pModule, "Module" );
|
||||
dump_bytes( outfile, (char *)pModule, (int)pstr - (int)pModule, "Module", 0 );
|
||||
return (int)pstr - (int)pModule;
|
||||
}
|
||||
|
||||
@ -498,7 +495,7 @@ void BuildSpec16File( FILE *outfile )
|
||||
{
|
||||
ORDDEF **type, **typelist;
|
||||
int i, nFuncs, nTypes;
|
||||
int code_offset, data_offset, module_size;
|
||||
int code_offset, data_offset, module_size, res_size;
|
||||
unsigned char *data;
|
||||
|
||||
/* File header */
|
||||
@ -699,16 +696,15 @@ void BuildSpec16File( FILE *outfile )
|
||||
|
||||
/* Output data segment */
|
||||
|
||||
dump_bytes( outfile, data, data_offset, "Data_Segment" );
|
||||
dump_bytes( outfile, data, data_offset, "Data_Segment", 0 );
|
||||
|
||||
/* Build the module */
|
||||
|
||||
module_size = BuildModule16( outfile, code_offset, data_offset );
|
||||
res_size = output_res16_data( outfile );
|
||||
|
||||
/* Output the DLL descriptor */
|
||||
|
||||
if (rsrc_name[0]) fprintf( outfile, "extern const char %s[];\n\n", rsrc_name );
|
||||
|
||||
fprintf( outfile, "\nstatic const BUILTIN16_DESCRIPTOR descriptor = \n{\n" );
|
||||
fprintf( outfile, " \"%s\",\n", DLLName );
|
||||
fprintf( outfile, " Module,\n" );
|
||||
@ -716,9 +712,9 @@ void BuildSpec16File( FILE *outfile )
|
||||
fprintf( outfile, " (BYTE *)&Code_Segment,\n" );
|
||||
fprintf( outfile, " (BYTE *)Data_Segment,\n" );
|
||||
fprintf( outfile, " \"%s\",\n", owner_name );
|
||||
fprintf( outfile, " %s\n", rsrc_name[0] ? rsrc_name : "0" );
|
||||
fprintf( outfile, " %s\n", res_size ? "resource_data" : "0" );
|
||||
fprintf( outfile, "};\n" );
|
||||
|
||||
|
||||
/* Output the DLL constructor */
|
||||
|
||||
fprintf( outfile, "#ifdef __GNUC__\n" );
|
||||
|
@ -101,17 +101,18 @@ void warning( const char *msg, ... )
|
||||
}
|
||||
|
||||
/* dump a byte stream into the assembly code */
|
||||
void dump_bytes( FILE *outfile, const unsigned char *data, int len, const char *label )
|
||||
void dump_bytes( FILE *outfile, const unsigned char *data, int len,
|
||||
const char *label, int constant )
|
||||
{
|
||||
int i;
|
||||
|
||||
fprintf( outfile, "\nstatic unsigned char %s[] = \n{", label );
|
||||
|
||||
fprintf( outfile, "\nstatic %sunsigned char %s[%d] = {",
|
||||
constant ? "const " : "", label, len );
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if (!(i & 0x0f)) fprintf( outfile, "\n " );
|
||||
fprintf( outfile, "%d", *data++ );
|
||||
if (i < len - 1) fprintf( outfile, ", " );
|
||||
if (!(i & 7)) fprintf( outfile, "\n " );
|
||||
fprintf( outfile, "0x%02x", *data++ );
|
||||
if (i < len - 1) fprintf( outfile, "," );
|
||||
}
|
||||
fprintf( outfile, "\n};\n" );
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user