Moved the spec file init function and constructor to winecrt0.
diff --git a/dlls/winecrt0/Makefile.in b/dlls/winecrt0/Makefile.in index 60a9b0c..ada0e66 100644 --- a/dlls/winecrt0/Makefile.in +++ b/dlls/winecrt0/Makefile.in
@@ -12,6 +12,7 @@ exe_main.c \ exe_wentry.c \ exe_wmain.c \ + init.c \ stub.c @MAKE_IMPLIB_RULES@
diff --git a/dlls/winecrt0/crt0_private.h b/dlls/winecrt0/crt0_private.h index 6ecc505..2b83a21 100644 --- a/dlls/winecrt0/crt0_private.h +++ b/dlls/winecrt0/crt0_private.h
@@ -29,6 +29,13 @@ extern void _fini(void); #endif -extern int __wine_spec_init_state; +enum init_state +{ + NO_INIT_DONE, /* no initialization done yet */ + DLL_REGISTERED, /* the dll has been registered */ + CONSTRUCTORS_DONE /* the constructors have been run (implies dll registered too) */ +}; + +extern enum init_state __wine_spec_init_state; #endif /* __WINE_CRT0_PRIVATE_H__ */
diff --git a/dlls/winecrt0/dll_entry.c b/dlls/winecrt0/dll_entry.c index fada80d..2990fb5 100644 --- a/dlls/winecrt0/dll_entry.c +++ b/dlls/winecrt0/dll_entry.c
@@ -28,12 +28,13 @@ BOOL WINAPI __wine_spec_dll_entry( HINSTANCE inst, DWORD reason, LPVOID reserved ) { - BOOL ret; + BOOL ret, needs_init = (__wine_spec_init_state != CONSTRUCTORS_DONE); - if (reason == DLL_PROCESS_ATTACH && __wine_spec_init_state == 1) + if (reason == DLL_PROCESS_ATTACH && needs_init) _init( __wine_main_argc, __wine_main_argv, __wine_main_environ ); + ret = DllMain( inst, reason, reserved ); - if (reason == DLL_PROCESS_DETACH && __wine_spec_init_state == 1) - _fini(); + + if (reason == DLL_PROCESS_DETACH && needs_init) _fini(); return ret; }
diff --git a/dlls/winecrt0/exe_entry.c b/dlls/winecrt0/exe_entry.c index 05c1273..623a17d 100644 --- a/dlls/winecrt0/exe_entry.c +++ b/dlls/winecrt0/exe_entry.c
@@ -29,9 +29,11 @@ DWORD WINAPI __wine_spec_exe_entry( PEB *peb ) { + BOOL needs_init = (__wine_spec_init_state != CONSTRUCTORS_DONE); DWORD ret; - if (__wine_spec_init_state == 1) _init( __wine_main_argc, __wine_main_argv, __wine_main_environ ); + + if (needs_init) _init( __wine_main_argc, __wine_main_argv, __wine_main_environ ); ret = main( __wine_main_argc, __wine_main_argv ); - if (__wine_spec_init_state == 1) _fini(); + if (needs_init) _fini(); ExitProcess( ret ); }
diff --git a/dlls/winecrt0/exe_wentry.c b/dlls/winecrt0/exe_wentry.c index 05359b8..ec69791 100644 --- a/dlls/winecrt0/exe_wentry.c +++ b/dlls/winecrt0/exe_wentry.c
@@ -29,9 +29,11 @@ DWORD WINAPI __wine_spec_exe_wentry( PEB *peb ) { + BOOL needs_init = (__wine_spec_init_state != CONSTRUCTORS_DONE); DWORD ret; - if (__wine_spec_init_state == 1) _init( __wine_main_argc, __wine_main_argv, __wine_main_environ ); + + if (needs_init) _init( __wine_main_argc, __wine_main_argv, __wine_main_environ ); ret = wmain( __wine_main_argc, __wine_main_wargv ); - if (__wine_spec_init_state == 1) _fini(); + if (needs_init) _fini(); ExitProcess( ret ); }
diff --git a/dlls/winecrt0/init.c b/dlls/winecrt0/init.c new file mode 100644 index 0000000..f1b33a8 --- /dev/null +++ b/dlls/winecrt0/init.c
@@ -0,0 +1,42 @@ +/* + * Initialization code for spec files + * + * Copyright 2005 Alexandre Julliard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <stdarg.h> +#include "windef.h" +#include "winbase.h" +#include "wine/library.h" +#include "crt0_private.h" + +enum init_state __wine_spec_init_state = NO_INIT_DONE; + +extern const IMAGE_NT_HEADERS __wine_spec_nt_header; +extern const char __wine_spec_file_name[]; + +void __wine_spec_init(void) +{ + __wine_spec_init_state = DLL_REGISTERED; + __wine_dll_register( &__wine_spec_nt_header, __wine_spec_file_name ); +} + +void __wine_spec_init_ctor(void) +{ + if (__wine_spec_init_state == NO_INIT_DONE) __wine_spec_init(); + __wine_spec_init_state = CONSTRUCTORS_DONE; +}
diff --git a/include/wine/library.h b/include/wine/library.h index adcb1ea..a307c7a 100644 --- a/include/wine/library.h +++ b/include/wine/library.h
@@ -53,6 +53,7 @@ extern char **__wine_main_argv; extern WCHAR **__wine_main_wargv; extern char **__wine_main_environ; +extern void __wine_dll_register( const IMAGE_NT_HEADERS *header, const char *filename ); extern void wine_init( int argc, char *argv[], char *error, int error_size ); /* debugging */
diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index a5e3fd4..8a08448 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c
@@ -474,7 +474,7 @@ else fprintf( outfile, "extern char _end[];\n" ); - fprintf( outfile, "static const char __wine_spec_file_name[] = \"%s\";\n", spec->file_name ); + fprintf( outfile, "const char __wine_spec_file_name[] = \"%s\";\n", spec->file_name ); fprintf( outfile, "extern int __wine_spec_data_start[], __wine_spec_exports[];\n\n" ); output_stub_funcs( outfile, spec ); @@ -489,13 +489,12 @@ /* Output the entry point function */ - fprintf( outfile, "int __wine_spec_init_state = 0;\n" ); fprintf( outfile, "extern void %s();\n\n", spec->init_func ); /* Output the NT header */ /* this is the IMAGE_NT_HEADERS structure, but we cannot include winnt.h here */ - fprintf( outfile, "static const struct image_nt_headers\n{\n" ); + fprintf( outfile, "const struct image_nt_headers\n{\n" ); fprintf( outfile, " int Signature;\n" ); fprintf( outfile, " struct file_header {\n" ); fprintf( outfile, " short Machine;\n" ); @@ -539,7 +538,7 @@ fprintf( outfile, " struct { const void *VirtualAddress; int Size; } DataDirectory[%d];\n", IMAGE_NUMBEROF_DIRECTORY_ENTRIES ); fprintf( outfile, " } OptionalHeader;\n" ); - fprintf( outfile, "} nt_header = {\n" ); + fprintf( outfile, "} __wine_spec_nt_header = {\n" ); fprintf( outfile, " 0x%04x,\n", IMAGE_NT_SIGNATURE ); /* Signature */ switch(target_cpu) { @@ -557,7 +556,7 @@ break; } fprintf( outfile, " 0, 0, 0, 0,\n" ); - fprintf( outfile, " sizeof(nt_header.OptionalHeader),\n" ); /* SizeOfOptionalHeader */ + fprintf( outfile, " sizeof(__wine_spec_nt_header.OptionalHeader),\n" ); /* SizeOfOptionalHeader */ fprintf( outfile, " 0x%04x },\n", spec->characteristics ); /* Characteristics */ fprintf( outfile, " { 0x%04x,\n", IMAGE_NT_OPTIONAL_HDR_MAGIC ); /* Magic */ @@ -594,24 +593,6 @@ spec->nb_resources ? "sizeof(__wine_spec_resources)" : "0" ); fprintf( outfile, " }\n }\n};\n\n" ); - /* Output the DLL constructor */ - - fprintf( outfile, - "void __wine_spec_init(void)\n" - "{\n" - " extern void __wine_dll_register( const struct image_nt_headers *, const char * );\n" - " __wine_spec_init_state = 1;\n" - " __wine_dll_register( &nt_header, __wine_spec_file_name );\n" - "}\n\n" ); - - fprintf( outfile, - "void __wine_spec_init_ctor(void)\n" - "{\n" - " if (__wine_spec_init_state) return;\n" - " __wine_spec_init();\n" - " __wine_spec_init_state = 2;\n" - "}\n" ); - fprintf( outfile, "#ifndef __GNUC__\n" ); fprintf( outfile, "static void __asm__dummy(void) {\n" ); fprintf( outfile, "#endif\n" );