Unregister 16-bit dlls on module unload.
This commit is contained in:
parent
da00742aa7
commit
cceab98642
|
@ -998,6 +998,7 @@ init MAIN_KernelInit
|
||||||
|
|
||||||
# 16-bit relays
|
# 16-bit relays
|
||||||
@ cdecl __wine_register_dll_16(ptr) __wine_register_dll_16
|
@ cdecl __wine_register_dll_16(ptr) __wine_register_dll_16
|
||||||
|
@ cdecl __wine_unregister_dll_16(ptr) __wine_unregister_dll_16
|
||||||
@ varargs __wine_call_from_16_word() __wine_call_from_16_word
|
@ varargs __wine_call_from_16_word() __wine_call_from_16_word
|
||||||
@ varargs __wine_call_from_16_long() __wine_call_from_16_long
|
@ varargs __wine_call_from_16_long() __wine_call_from_16_long
|
||||||
@ varargs __wine_call_from_16_regs() __wine_call_from_16_regs
|
@ varargs __wine_call_from_16_regs() __wine_call_from_16_regs
|
||||||
|
|
|
@ -51,7 +51,6 @@ typedef struct
|
||||||
#define MAX_DLLS 50
|
#define MAX_DLLS 50
|
||||||
|
|
||||||
static const BUILTIN16_DESCRIPTOR *builtin_dlls[MAX_DLLS];
|
static const BUILTIN16_DESCRIPTOR *builtin_dlls[MAX_DLLS];
|
||||||
static int nb_dlls;
|
|
||||||
|
|
||||||
|
|
||||||
/* patch all the flat cs references of the code segment if necessary */
|
/* patch all the flat cs references of the code segment if necessary */
|
||||||
|
@ -134,20 +133,22 @@ static HMODULE16 BUILTIN_DoLoadModule16( const BUILTIN16_DESCRIPTOR *descr )
|
||||||
static const BUILTIN16_DESCRIPTOR *find_dll_descr( const char *dllname )
|
static const BUILTIN16_DESCRIPTOR *find_dll_descr( const char *dllname )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < nb_dlls; i++)
|
for (i = 0; i < MAX_DLLS; i++)
|
||||||
{
|
{
|
||||||
const BUILTIN16_DESCRIPTOR *descr = builtin_dlls[i];
|
const BUILTIN16_DESCRIPTOR *descr = builtin_dlls[i];
|
||||||
NE_MODULE *pModule = (NE_MODULE *)descr->module_start;
|
if (descr)
|
||||||
OFSTRUCT *pOfs = (OFSTRUCT *)((LPBYTE)pModule + pModule->fileinfo);
|
{
|
||||||
BYTE *name_table = (BYTE *)pModule + pModule->name_table;
|
NE_MODULE *pModule = (NE_MODULE *)descr->module_start;
|
||||||
|
OFSTRUCT *pOfs = (OFSTRUCT *)((LPBYTE)pModule + pModule->fileinfo);
|
||||||
|
BYTE *name_table = (BYTE *)pModule + pModule->name_table;
|
||||||
|
|
||||||
/* check the dll file name */
|
/* check the dll file name */
|
||||||
if (!FILE_strcasecmp( pOfs->szPathName, dllname ))
|
if (!FILE_strcasecmp( pOfs->szPathName, dllname )) return descr;
|
||||||
return descr;
|
/* check the dll module name (without extension) */
|
||||||
/* check the dll module name (without extension) */
|
if (!FILE_strncasecmp( dllname, name_table+1, *name_table ) &&
|
||||||
if (!FILE_strncasecmp( dllname, name_table+1, *name_table ) &&
|
!strcmp( dllname + *name_table, ".dll" ))
|
||||||
!strcmp( dllname + *name_table, ".dll" ))
|
return descr;
|
||||||
return descr;
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -199,6 +200,31 @@ HMODULE16 BUILTIN_LoadModule( LPCSTR name )
|
||||||
*/
|
*/
|
||||||
void __wine_register_dll_16( const BUILTIN16_DESCRIPTOR *descr )
|
void __wine_register_dll_16( const BUILTIN16_DESCRIPTOR *descr )
|
||||||
{
|
{
|
||||||
assert( nb_dlls < MAX_DLLS );
|
int i;
|
||||||
builtin_dlls[nb_dlls++] = descr;
|
|
||||||
|
for (i = 0; i < MAX_DLLS; i++)
|
||||||
|
{
|
||||||
|
if (builtin_dlls[i]) continue;
|
||||||
|
builtin_dlls[i] = descr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
assert( i < MAX_DLLS );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* __wine_unregister_dll_16 (KERNEL32.@)
|
||||||
|
*
|
||||||
|
* Unregister a built-in DLL descriptor.
|
||||||
|
*/
|
||||||
|
void __wine_unregister_dll_16( const BUILTIN16_DESCRIPTOR *descr )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_DLLS; i++)
|
||||||
|
{
|
||||||
|
if (builtin_dlls[i] != descr) continue;
|
||||||
|
builtin_dlls[i] = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,6 +157,7 @@ extern int output_resources( FILE *outfile );
|
||||||
extern void load_res16_file( const char *name );
|
extern void load_res16_file( const char *name );
|
||||||
extern int output_res16_data( FILE *outfile );
|
extern int output_res16_data( FILE *outfile );
|
||||||
extern int output_res16_directory( unsigned char *buffer );
|
extern int output_res16_directory( unsigned char *buffer );
|
||||||
|
extern void output_dll_init( FILE *outfile, const char *constructor, const char *destructor );
|
||||||
extern void parse_debug_channels( const char *srcdir, const char *filename );
|
extern void parse_debug_channels( const char *srcdir, const char *filename );
|
||||||
|
|
||||||
extern void BuildGlue( FILE *outfile, FILE *infile );
|
extern void BuildGlue( FILE *outfile, FILE *infile );
|
||||||
|
|
|
@ -623,6 +623,7 @@ void BuildSpec16File( FILE *outfile )
|
||||||
int i, nFuncs, nTypes;
|
int i, nFuncs, nTypes;
|
||||||
int code_offset, data_offset, module_size, res_size;
|
int code_offset, data_offset, module_size, res_size;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
char constructor[100], destructor[100];
|
||||||
#ifdef __i386__
|
#ifdef __i386__
|
||||||
unsigned short code_selector = wine_get_cs();
|
unsigned short code_selector = wine_get_cs();
|
||||||
#endif
|
#endif
|
||||||
|
@ -877,40 +878,22 @@ void BuildSpec16File( FILE *outfile )
|
||||||
|
|
||||||
/* Output the DLL constructor */
|
/* Output the DLL constructor */
|
||||||
|
|
||||||
fprintf( outfile, "#ifndef __GNUC__\n" );
|
sprintf( constructor, "__wine_spec_%s_init", make_c_identifier(DLLName) );
|
||||||
fprintf( outfile, "static void __asm__dummy_dll_init(void) {\n" );
|
sprintf( destructor, "__wine_spec_%s_fini", make_c_identifier(DLLName) );
|
||||||
fprintf( outfile, "#endif /* defined(__GNUC__) */\n" );
|
output_dll_init( outfile, constructor, destructor );
|
||||||
|
|
||||||
#if defined(__i386__)
|
|
||||||
fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" );
|
|
||||||
fprintf( outfile, " \"\\tcall " PREFIX "__wine_spec_%s_init\\n\"\n",
|
|
||||||
make_c_identifier(DLLName) );
|
|
||||||
fprintf( outfile, " \"\\t.previous\\n\");\n" );
|
|
||||||
#elif defined(__sparc__)
|
|
||||||
fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" );
|
|
||||||
fprintf( outfile, " \"\\tcall " PREFIX "__wine_spec_%s_init\\n\"\n",
|
|
||||||
make_c_identifier(DLLName) );
|
|
||||||
fprintf( outfile, " \"\\tnop\\n\"\n" );
|
|
||||||
fprintf( outfile, " \"\\t.previous\\n\");\n" );
|
|
||||||
#elif defined(__PPC__)
|
|
||||||
fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" );
|
|
||||||
fprintf( outfile, " \"\\tbl " PREFIX "__wine_spec_%s_init\\n\"\n",
|
|
||||||
make_c_identifier(DLLName) );
|
|
||||||
fprintf( outfile, " \"\\t.previous\\n\");\n" );
|
|
||||||
#else
|
|
||||||
#error You need to define the DLL constructor for your architecture
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fprintf( outfile, "#ifndef __GNUC__\n" );
|
|
||||||
fprintf( outfile, "}\n" );
|
|
||||||
fprintf( outfile, "#endif /* defined(__GNUC__) */\n\n" );
|
|
||||||
|
|
||||||
fprintf( outfile,
|
fprintf( outfile,
|
||||||
"void __wine_spec_%s_init(void)\n"
|
"void %s(void)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" extern void __wine_register_dll_16( const struct dll_descriptor *descr );\n"
|
" extern void __wine_register_dll_16( const struct dll_descriptor *descr );\n"
|
||||||
" __wine_register_dll_16( &descriptor );\n"
|
" __wine_register_dll_16( &descriptor );\n"
|
||||||
"}\n", make_c_identifier(DLLName) );
|
"}\n", constructor );
|
||||||
|
fprintf( outfile,
|
||||||
|
"void %s(void)\n"
|
||||||
|
"{\n"
|
||||||
|
" extern void __wine_unregister_dll_16( const struct dll_descriptor *descr );\n"
|
||||||
|
" __wine_unregister_dll_16( &descriptor );\n"
|
||||||
|
"}\n", destructor );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -425,6 +425,68 @@ static void output_register_funcs( FILE *outfile )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
* output_dll_init
|
||||||
|
*
|
||||||
|
* Output code for calling a dll constructor and destructor.
|
||||||
|
*/
|
||||||
|
void output_dll_init( FILE *outfile, const char *constructor, const char *destructor )
|
||||||
|
{
|
||||||
|
fprintf( outfile, "#ifndef __GNUC__\n" );
|
||||||
|
fprintf( outfile, "static void __asm__dummy_dll_init(void) {\n" );
|
||||||
|
fprintf( outfile, "#endif\n" );
|
||||||
|
|
||||||
|
#if defined(__i386__)
|
||||||
|
if (constructor)
|
||||||
|
{
|
||||||
|
fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" );
|
||||||
|
fprintf( outfile, " \"\\tcall " PREFIX "%s\\n\"\n", constructor );
|
||||||
|
fprintf( outfile, " \"\\t.previous\\n\");\n" );
|
||||||
|
}
|
||||||
|
if (destructor)
|
||||||
|
{
|
||||||
|
fprintf( outfile, "asm(\"\\t.section\t.fini ,\\\"ax\\\"\\n\"\n" );
|
||||||
|
fprintf( outfile, " \"\\tcall " PREFIX "%s\\n\"\n", destructor );
|
||||||
|
fprintf( outfile, " \"\\t.previous\\n\");\n" );
|
||||||
|
}
|
||||||
|
#elif defined(__sparc__)
|
||||||
|
if (constructor)
|
||||||
|
{
|
||||||
|
fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" );
|
||||||
|
fprintf( outfile, " \"\\tcall " PREFIX "%s\\n\"\n", constructor );
|
||||||
|
fprintf( outfile, " \"\\tnop\\n\"\n" );
|
||||||
|
fprintf( outfile, " \"\\t.previous\\n\");\n" );
|
||||||
|
}
|
||||||
|
if (destructor)
|
||||||
|
{
|
||||||
|
fprintf( outfile, "asm(\"\\t.section\t.fini ,\\\"ax\\\"\\n\"\n" );
|
||||||
|
fprintf( outfile, " \"\\tcall " PREFIX "%s\\n\"\n", destructor );
|
||||||
|
fprintf( outfile, " \"\\tnop\\n\"\n" );
|
||||||
|
fprintf( outfile, " \"\\t.previous\\n\");\n" );
|
||||||
|
}
|
||||||
|
#elif defined(__PPC__)
|
||||||
|
if (constructor)
|
||||||
|
{
|
||||||
|
fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" );
|
||||||
|
fprintf( outfile, " \"\\tbl " PREFIX "%s\\n\"\n", constructor );
|
||||||
|
fprintf( outfile, " \"\\t.previous\\n\");\n" );
|
||||||
|
}
|
||||||
|
if (destructor)
|
||||||
|
{
|
||||||
|
fprintf( outfile, "asm(\"\\t.section\t.fini ,\\\"ax\\\"\\n\"\n" );
|
||||||
|
fprintf( outfile, " \"\\tbl " PREFIX "%s\\n\"\n", destructor );
|
||||||
|
DLLName );
|
||||||
|
fprintf( outfile, " \"\\t.previous\\n\");\n" );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#error You need to define the DLL constructor for your architecture
|
||||||
|
#endif
|
||||||
|
fprintf( outfile, "#ifndef __GNUC__\n" );
|
||||||
|
fprintf( outfile, "}\n" );
|
||||||
|
fprintf( outfile, "#endif\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* BuildSpec32File
|
* BuildSpec32File
|
||||||
*
|
*
|
||||||
|
@ -436,6 +498,7 @@ void BuildSpec32File( FILE *outfile )
|
||||||
int nr_exports, nr_imports, nr_resources;
|
int nr_exports, nr_imports, nr_resources;
|
||||||
int characteristics, subsystem;
|
int characteristics, subsystem;
|
||||||
DWORD page_size;
|
DWORD page_size;
|
||||||
|
char constructor[100];
|
||||||
|
|
||||||
#ifdef HAVE_GETPAGESIZE
|
#ifdef HAVE_GETPAGESIZE
|
||||||
page_size = getpagesize();
|
page_size = getpagesize();
|
||||||
|
@ -712,42 +775,17 @@ void BuildSpec32File( FILE *outfile )
|
||||||
|
|
||||||
/* Output the DLL constructor */
|
/* Output the DLL constructor */
|
||||||
|
|
||||||
fprintf( outfile, "#ifndef __GNUC__\n" );
|
sprintf( constructor, "__wine_spec_%s_init", make_c_identifier(DLLName) );
|
||||||
fprintf( outfile, "static void __asm__dummy_dll_init(void) {\n" );
|
output_dll_init( outfile, constructor, NULL );
|
||||||
fprintf( outfile, "#endif /* defined(__GNUC__) */\n" );
|
|
||||||
|
|
||||||
#if defined(__i386__)
|
|
||||||
fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" );
|
|
||||||
fprintf( outfile, " \"\\tcall " PREFIX "__wine_spec_%s_init\\n\"\n",
|
|
||||||
make_c_identifier(DLLName) );
|
|
||||||
fprintf( outfile, " \"\\t.previous\\n\");\n" );
|
|
||||||
#elif defined(__sparc__)
|
|
||||||
fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" );
|
|
||||||
fprintf( outfile, " \"\\tcall " PREFIX "__wine_spec_%s_init\\n\"\n",
|
|
||||||
make_c_identifier(DLLName) );
|
|
||||||
fprintf( outfile, " \"\\tnop\\n\"\n" );
|
|
||||||
fprintf( outfile, " \"\\t.previous\\n\");\n" );
|
|
||||||
#elif defined(__PPC__)
|
|
||||||
fprintf( outfile, "asm(\"\\t.section\t.init ,\\\"ax\\\"\\n\"\n" );
|
|
||||||
fprintf( outfile, " \"\\tbl " PREFIX "__wine_spec_%s_init\\n\"\n",
|
|
||||||
make_c_identifier(DLLName) );
|
|
||||||
fprintf( outfile, " \"\\t.previous\\n\");\n" );
|
|
||||||
#else
|
|
||||||
#error You need to define the DLL constructor for your architecture
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fprintf( outfile, "#ifndef __GNUC__\n" );
|
|
||||||
fprintf( outfile, "}\n" );
|
|
||||||
fprintf( outfile, "#endif /* defined(__GNUC__) */\n\n" );
|
|
||||||
|
|
||||||
fprintf( outfile,
|
fprintf( outfile,
|
||||||
"void __wine_spec_%s_init(void)\n"
|
"void %s(void)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" extern void __wine_dll_register( const struct image_nt_headers *, const char * );\n"
|
" extern void __wine_dll_register( const struct image_nt_headers *, const char * );\n"
|
||||||
" extern void *__wine_dbg_register( char * const *, int );\n"
|
" extern void *__wine_dbg_register( char * const *, int );\n"
|
||||||
" __wine_dll_register( &nt_header, \"%s\" );\n",
|
" __wine_dll_register( &nt_header, \"%s\" );\n"
|
||||||
make_c_identifier(DLLName), DLLFileName );
|
"}\n",
|
||||||
fprintf( outfile, "}\n" );
|
constructor, DLLFileName );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue