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" );