Added native mode dll support (based on a patch by Marcus Meissner).

diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h
index afb6fd1..c7da34d 100644
--- a/tools/winebuild/build.h
+++ b/tools/winebuild/build.h
@@ -53,6 +53,7 @@
 typedef enum
 {
     SPEC_MODE_DLL,
+    SPEC_MODE_NATIVE,
     SPEC_MODE_GUIEXE,
     SPEC_MODE_CUIEXE,
     SPEC_MODE_GUIEXE_UNICODE,
diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c
index 023f45c..a8f367c 100644
--- a/tools/winebuild/import.c
+++ b/tools/winebuild/import.c
@@ -569,6 +569,7 @@
     switch (spec->mode)
     {
     case SPEC_MODE_DLL:
+    case SPEC_MODE_NATIVE:
         break;
     case SPEC_MODE_GUIEXE:
         kernel_imports += add_extra_symbol( extras, &count, "GetCommandLineA", spec );
diff --git a/tools/winebuild/main.c b/tools/winebuild/main.c
index ce7ff31..615089c 100644
--- a/tools/winebuild/main.c
+++ b/tools/winebuild/main.c
@@ -268,6 +268,7 @@
             else if (!strcmp( optarg, "cui" )) spec->mode = SPEC_MODE_CUIEXE;
             else if (!strcmp( optarg, "guiw" )) spec->mode = SPEC_MODE_GUIEXE_UNICODE;
             else if (!strcmp( optarg, "cuiw" )) spec->mode = SPEC_MODE_CUIEXE_UNICODE;
+            else if (!strcmp( optarg, "native" )) spec->mode = SPEC_MODE_NATIVE;
             else usage(1);
             break;
         case 'o':
diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c
index 8588e72..994a9b2 100644
--- a/tools/winebuild/spec32.c
+++ b/tools/winebuild/spec32.c
@@ -72,6 +72,27 @@
 }
 
 /*******************************************************************
+ *         declare_weak_function
+ *
+ * Output a prototype for a weak function.
+ */
+static void declare_weak_function( FILE *outfile, const char *name, const char *prototype )
+{
+    fprintf( outfile, "#ifdef __GNUC__\n" );
+    fprintf( outfile, "# ifdef __APPLE__\n" );
+    fprintf( outfile, "extern %s __attribute__((weak_import));\n", prototype );
+    fprintf( outfile, "# else\n" );
+    fprintf( outfile, "extern %s __attribute__((weak));\n", prototype );
+    fprintf( outfile, "# endif\n" );
+    fprintf( outfile, "#else\n" );
+    fprintf( outfile, "extern %s;\n", prototype );
+    fprintf( outfile, "static void __asm__dummy_%s(void)", name );
+    fprintf( outfile, " { asm(\".weak " __ASM_NAME("%s") "\"); }\n", name );
+    fprintf( outfile, "#endif\n\n" );
+}
+
+
+/*******************************************************************
  *         output_debug
  *
  * Output the debug channels.
@@ -559,17 +580,8 @@
             fprintf( outfile, "extern int __stdcall %s( void*, unsigned int, void* );\n\n", init_func );
         else
         {
-            fprintf( outfile, "#ifdef __GNUC__\n" );
-            fprintf( outfile, "# ifdef __APPLE__\n" );
-            fprintf( outfile, "extern int __stdcall DllMain( void*, unsigned int, void* ) __attribute__((weak_import));\n" );
-            fprintf( outfile, "# else\n" );
-            fprintf( outfile, "extern int __stdcall DllMain( void*, unsigned int, void* ) __attribute__((weak));\n" );
-            fprintf( outfile, "# endif\n" );
-            fprintf( outfile, "#else\n" );
-            fprintf( outfile, "extern int __stdcall DllMain( void*, unsigned int, void* );\n" );
-            fprintf( outfile, "static void __asm__dummy_dllmain(void)" );
-            fprintf( outfile, " { asm(\".weak " __ASM_NAME("DllMain") "\"); }\n" );
-            fprintf( outfile, "#endif\n\n" );
+            declare_weak_function( outfile, "DllMain",
+                                   "int __stdcall DllMain( void*, unsigned int, void* )" );
             init_func = "DllMain";
         }
         fprintf( outfile,
@@ -586,6 +598,29 @@
         init_func = "__wine_dll_main";
         characteristics = IMAGE_FILE_DLL;
         break;
+    case SPEC_MODE_NATIVE:
+        if (init_func)
+            fprintf( outfile, "extern int __stdcall %s( void*, void* );\n\n", init_func );
+        else
+        {
+            declare_weak_function( outfile, "DriverEntry",
+                                   "int __stdcall DriverEntry( void*, void* )" );
+            init_func = "DriverEntry";
+        }
+        fprintf( outfile,
+                 "static int __stdcall __wine_driver_entry( void *obj, void *path )\n"
+                 "{\n"
+                 "    int ret;\n"
+                 "    if (reason == %d && __wine_spec_init_state == 1)\n"
+                 "        _init( __wine_main_argc, __wine_main_argv, __wine_main_environ );\n"
+                 "    ret = %s ? %s( obj, path ) : 0;\n"
+                 "    if (reason == %d && __wine_spec_init_state == 1) _fini();\n"
+                 "    return ret;\n"
+                 "}\n",
+                 DLL_PROCESS_ATTACH, init_func, init_func, DLL_PROCESS_DETACH );
+        init_func = "__wine_driver_entry";
+        subsystem = IMAGE_SUBSYSTEM_NATIVE;
+        break;
     case SPEC_MODE_GUIEXE:
     case SPEC_MODE_GUIEXE_UNICODE:
         if (!init_func) init_func = "WinMain";
diff --git a/tools/winebuild/winebuild.man.in b/tools/winebuild/winebuild.man.in
index ffd80cd..2e8a203 100644
--- a/tools/winebuild/winebuild.man.in
+++ b/tools/winebuild/winebuild.man.in
@@ -145,7 +145,10 @@
 for a command line Unicode executable,
 .br
 .B guiw
-for a graphical Unicode executable.
+for a graphical Unicode executable,
+.br
+.B native
+for a native-mode dll.
 .br
 A command line executable entry point is a normal C \fBmain\fR
 function. A graphical executable has a \fBWinMain\fR entry point