From cceab986420094724ffb480c869a2061a558990a Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 14 Jun 2002 23:42:53 +0000 Subject: [PATCH] Unregister 16-bit dlls on module unload. --- dlls/kernel/kernel32.spec | 1 + if1632/builtin.c | 54 ++++++++++++++------ tools/winebuild/build.h | 1 + tools/winebuild/spec16.c | 41 +++++----------- tools/winebuild/spec32.c | 100 ++++++++++++++++++++++++++------------ 5 files changed, 123 insertions(+), 74 deletions(-) diff --git a/dlls/kernel/kernel32.spec b/dlls/kernel/kernel32.spec index 5df5a5640f1..130dceb0d0c 100644 --- a/dlls/kernel/kernel32.spec +++ b/dlls/kernel/kernel32.spec @@ -998,6 +998,7 @@ init MAIN_KernelInit # 16-bit relays @ 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_long() __wine_call_from_16_long @ varargs __wine_call_from_16_regs() __wine_call_from_16_regs diff --git a/if1632/builtin.c b/if1632/builtin.c index 0dca8a61e17..f14dd510a58 100644 --- a/if1632/builtin.c +++ b/if1632/builtin.c @@ -51,7 +51,6 @@ typedef struct #define MAX_DLLS 50 static const BUILTIN16_DESCRIPTOR *builtin_dlls[MAX_DLLS]; -static int nb_dlls; /* 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 ) { int i; - for (i = 0; i < nb_dlls; i++) + for (i = 0; i < MAX_DLLS; i++) { const BUILTIN16_DESCRIPTOR *descr = builtin_dlls[i]; - NE_MODULE *pModule = (NE_MODULE *)descr->module_start; - OFSTRUCT *pOfs = (OFSTRUCT *)((LPBYTE)pModule + pModule->fileinfo); - BYTE *name_table = (BYTE *)pModule + pModule->name_table; + if (descr) + { + 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 */ - if (!FILE_strcasecmp( pOfs->szPathName, dllname )) - return descr; - /* check the dll module name (without extension) */ - if (!FILE_strncasecmp( dllname, name_table+1, *name_table ) && - !strcmp( dllname + *name_table, ".dll" )) - return descr; + /* check the dll file name */ + if (!FILE_strcasecmp( pOfs->szPathName, dllname )) return descr; + /* check the dll module name (without extension) */ + if (!FILE_strncasecmp( dllname, name_table+1, *name_table ) && + !strcmp( dllname + *name_table, ".dll" )) + return descr; + } } return NULL; } @@ -199,6 +200,31 @@ HMODULE16 BUILTIN_LoadModule( LPCSTR name ) */ void __wine_register_dll_16( const BUILTIN16_DESCRIPTOR *descr ) { - assert( nb_dlls < MAX_DLLS ); - builtin_dlls[nb_dlls++] = descr; + int i; + + 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; + } } diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index 232157db7c4..a83fdbfac80 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -157,6 +157,7 @@ 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 output_dll_init( FILE *outfile, const char *constructor, const char *destructor ); extern void parse_debug_channels( const char *srcdir, const char *filename ); extern void BuildGlue( FILE *outfile, FILE *infile ); diff --git a/tools/winebuild/spec16.c b/tools/winebuild/spec16.c index 773c2c88326..0facd7cd8ae 100644 --- a/tools/winebuild/spec16.c +++ b/tools/winebuild/spec16.c @@ -623,6 +623,7 @@ void BuildSpec16File( FILE *outfile ) int i, nFuncs, nTypes; int code_offset, data_offset, module_size, res_size; unsigned char *data; + char constructor[100], destructor[100]; #ifdef __i386__ unsigned short code_selector = wine_get_cs(); #endif @@ -877,40 +878,22 @@ void BuildSpec16File( FILE *outfile ) /* Output the DLL constructor */ - fprintf( outfile, "#ifndef __GNUC__\n" ); - fprintf( outfile, "static void __asm__dummy_dll_init(void) {\n" ); - 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" ); + sprintf( constructor, "__wine_spec_%s_init", make_c_identifier(DLLName) ); + sprintf( destructor, "__wine_spec_%s_fini", make_c_identifier(DLLName) ); + output_dll_init( outfile, constructor, destructor ); fprintf( outfile, - "void __wine_spec_%s_init(void)\n" + "void %s(void)\n" "{\n" " extern void __wine_register_dll_16( const struct dll_descriptor *descr );\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 ); } diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index c9760badf86..9fb749d376f 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -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 * @@ -436,6 +498,7 @@ void BuildSpec32File( FILE *outfile ) int nr_exports, nr_imports, nr_resources; int characteristics, subsystem; DWORD page_size; + char constructor[100]; #ifdef HAVE_GETPAGESIZE page_size = getpagesize(); @@ -712,42 +775,17 @@ void BuildSpec32File( FILE *outfile ) /* Output the DLL constructor */ - fprintf( outfile, "#ifndef __GNUC__\n" ); - fprintf( outfile, "static void __asm__dummy_dll_init(void) {\n" ); - 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" ); + sprintf( constructor, "__wine_spec_%s_init", make_c_identifier(DLLName) ); + output_dll_init( outfile, constructor, NULL ); fprintf( outfile, - "void __wine_spec_%s_init(void)\n" + "void %s(void)\n" "{\n" " extern void __wine_dll_register( const struct image_nt_headers *, const char * );\n" " extern void *__wine_dbg_register( char * const *, int );\n" - " __wine_dll_register( &nt_header, \"%s\" );\n", - make_c_identifier(DLLName), DLLFileName ); - fprintf( outfile, "}\n" ); + " __wine_dll_register( &nt_header, \"%s\" );\n" + "}\n", + constructor, DLLFileName ); }