New loading scheme for Winelib apps, makes them behave like builtin
dlls and takes load order into account. Install them in dlldir.
Improved MODULE_GetBinaryType to recognize ELF binaries.
Added a wrapper script to setup the environment when running directly
from inside the source tree.

diff --git a/.cvsignore b/.cvsignore
index 38068e2..bae1588 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -4,4 +4,3 @@
 config.cache
 config.log
 config.status
-wine
diff --git a/Make.rules.in b/Make.rules.in
index a871b18..676cc27 100644
--- a/Make.rules.in
+++ b/Make.rules.in
@@ -68,6 +68,7 @@
 ALLLINTFLAGS = $(LINTFLAGS) $(DEFS) $(OPTIONS) $(DIVINCL)
 MKINSTALLDIRS= $(TOPSRCDIR)/tools/mkinstalldirs
 WINAPI_CHECK = $(TOPSRCDIR)/tools/winapi_check/winapi_check
+WINEWRAPPER  = $(TOPSRCDIR)/tools/winewrapper
 WINEBUILD    = $(TOOLSDIR)/tools/winebuild/winebuild
 MAKEDEP      = $(TOOLSDIR)/tools/makedep
 WRC          = $(TOOLSDIR)/tools/wrc/wrc
@@ -79,11 +80,11 @@
 LIBUNICODE= -L$(TOPOBJDIR)/unicode -lwine_unicode
 LIBUUID   = -L$(TOPOBJDIR)/ole -lwine_uuid
 
-WINETEST     = $(TOPOBJDIR)/programs/winetest/winetest
+WINETEST     = $(TOPOBJDIR)/programs/winetest/winetest.exe$(DLLEXT)
 RUNTEST      = $(TOPSRCDIR)/programs/winetest/runtest
 RUNTESTFLAGS = -q -P wine -M $(MODULE) -T $(TOPOBJDIR)
 TESTRESULTS  = $(PLTESTS:.pl=.ok) $(CTESTS:.c=.ok)
-TESTPROGRAM  = tests/$(MODULE:%.dll=%)_test
+TESTPROGRAM  = tests/$(MODULE:%.dll=%)_test.exe
 TESTLIST     = tests/testlist.c
 TESTOBJS     = $(TESTMAIN) $(TESTLIST:.c=.o) $(CTESTS:.c=.o)
 TESTMAIN     = $(TOPOBJDIR)/programs/winetest/wtmain.o
@@ -150,7 +151,7 @@
 	$(LINT) -c $(ALLLINTFLAGS) $< || ( $(RM) $@ && exit 1 )
 
 .c.ok:
-	$(RUNTEST) $(RUNTESTFLAGS) -p $(TESTPROGRAM) $< && touch $@
+	$(RUNTEST) $(RUNTESTFLAGS) -p $(TESTPROGRAM)$(DLLEXT) $< && touch $@
 
 .pl.ok:
 	$(RUNTEST) $(RUNTESTFLAGS) $< && touch $@
@@ -256,7 +257,7 @@
 	$(RM) $(TESTRESULTS)
 
 clean:: $(SUBDIRS:%=%/__clean__) $(EXTRASUBDIRS:%=%/__clean__)
-	$(RM) $(CLEAN_FILES) $(GEN_C_SRCS) $(GEN_ASM_SRCS) $(RC_SRCS:.rc=.res) $(RC_SRCS16:.rc=.res) $(MC_SRCS:.mc=.mc.rc) $(TESTRESULTS) $(TESTLIST) $(TESTPROGRAM)$(EXEEXT) $(PROGRAMS)
+	$(RM) $(CLEAN_FILES) $(GEN_C_SRCS) $(GEN_ASM_SRCS) $(RC_SRCS:.rc=.res) $(RC_SRCS16:.rc=.res) $(MC_SRCS:.mc=.mc.rc) $(TESTRESULTS) $(TESTLIST) $(TESTPROGRAM) $(PROGRAMS)
 
 # Rules for installing
 
@@ -274,10 +275,10 @@
 	@cd `dirname $@` && $(MAKE) test
 
 $(PLTESTS:.c=.ok): $(WINETEST)
-$(CTESTS:.c=.ok): $(TESTPROGRAM)$(EXEEXT)
+$(CTESTS:.c=.ok): $(TESTPROGRAM)$(DLLEXT)
 
 $(WINETEST):
-	cd $(TOPOBJDIR)/programs/winetest && $(MAKE) winetest
+	cd $(TOPOBJDIR)/programs/winetest && $(MAKE) winetest.exe$(DLLEXT)
 
 $(TESTMAIN):
 	cd $(TOPOBJDIR)/programs/winetest && $(MAKE) wtmain.o
@@ -285,20 +286,17 @@
 $(TESTLIST): Makefile.in
 	$(TOPSRCDIR)/programs/winetest/make_ctests $(CTESTS) >$(TESTLIST) || $(RM) $(TESTLIST)
 
-$(TESTPROGRAM): $(TESTPROGRAM).exe.so
-	$(RM) $(TESTPROGRAM) && cd tests && $(LN_S) $(TOPOBJDIR)/../wine `basename $(TESTPROGRAM)`
+$(TESTPROGRAM).so: $(TESTPROGRAM).spec.o $(TESTOBJS)
+	$(LDSHARED) $(LDDLLFLAGS) $(TESTPROGRAM).spec.o $(TESTOBJS) -o $@ $(LIBWINE) $(LIBS)
 
-$(TESTPROGRAM).exe.so: $(TESTPROGRAM).exe.spec.o $(TESTOBJS)
-	$(LDSHARED) $(LDDLLFLAGS) $(TESTPROGRAM).exe.spec.o $(TESTOBJS) -o $@ $(LIBWINE) $(LIBS)
-
-$(TESTPROGRAM).exe.tmp.o: $(TESTOBJS)
+$(TESTPROGRAM).tmp.o: $(TESTOBJS)
 	$(LDCOMBINE) $(TESTOBJS) -o $@
 	-$(STRIP) --strip-unneeded $@
 
-$(TESTPROGRAM).exe.spec.c: $(TESTPROGRAM).exe.tmp.o $(WINEBUILD)
-	$(LDPATH) $(WINEBUILD) $(DEFS) -sym $(TESTPROGRAM).exe.tmp.o -o $@ -exe $(TESTPROGRAM).exe -mcui -L$(DLLDIR) $(TESTIMPORTS:%=-l%)
+$(TESTPROGRAM).spec.c: $(TESTPROGRAM).tmp.o $(WINEBUILD)
+	$(LDPATH) $(WINEBUILD) $(DEFS) -sym $(TESTPROGRAM).tmp.o -o $@ -exe $(TESTPROGRAM) -mcui -L$(DLLDIR) $(TESTIMPORTS:%=-l%)
 
-$(TESTPROGRAM).exe: $(TESTOBJS)
+$(TESTPROGRAM): $(TESTOBJS)
 	$(CC) $(TESTOBJS) -o $@ $(TESTIMPORTS:%=-l%) $(LIBWINE) $(LIBS)
 
 # Misc. rules
diff --git a/Makefile.in b/Makefile.in
index f5a89ad..7cf7ebf 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -20,50 +20,33 @@
 VPATH     = @srcdir@
 LIBEXT    = @LIBEXT@
 LDCONFIG  = @LDCONFIG@
-MODULE    = wine
-LDIMPORTS = ntdll.dll
+MODULE    = none
 
-# Stand-alone programs
-PROGRAMS = \
-	server/wineserver
+# Sub-directories containing stand-alone programs
+PROGSUBDIRS = \
+	server
 
-# Programs that link with libwine
-LIBPROGRAMS = \
-	debugger \
+# Sub-directories containing programs that use some Wine dlls
+LIBPROGSUBDIRS = \
+	miscemu \
 	programs
 
-# Libraries (not dlls) to build
-LIBRARIES = \
-	library/libwine.$(LIBEXT) \
-	ole/libwine_uuid.a \
-	tsx11/libwine_tsx11.$(LIBEXT) \
-	unicode/libwine_unicode.$(LIBEXT)
-
-# Dlls that we need to link against (should go away)
-LINKABLE_DLLS = user32.dll gdi32.dll kernel32.dll ntdll.dll
-
-# Libraries symlinks to create at the top level
-LIBSYMLINKS = \
-	$(LINKABLE_DLLS:%=lib%.$(LIBEXT)) \
-	libwine.$(LIBEXT) \
-	libwine_tsx11.$(LIBEXT) \
-	libwine_unicode.$(LIBEXT) \
-	libwine_uuid.a
+# Sub-directories containing libraries (not dlls) to build
+LIBSUBDIRS = \
+	library \
+	ole \
+	tsx11 \
+	unicode
 
 # Sub-directories to run make depend/clean/install into
 SUBDIRS = \
-	debugger \
+	$(LIBPROGSUBDIRS) \
+	$(LIBSUBDIRS) \
+	$(PROGSUBDIRS) \
 	dlls \
 	documentation \
 	include \
-	library \
-	miscemu \
-	ole \
-	programs \
-	server \
-	tools \
-	tsx11 \
-	unicode
+	tools
 
 # Sub-directories to run make test into
 TESTSUBDIRS = \
@@ -73,7 +56,7 @@
 EMUOBJS = \
 	miscemu/miscemu.o
 
-all: Make.rules $(PROGRAMS) $(LIBPROGRAMS) $(LIBSYMLINKS) wine
+all: Make.rules $(PROGSUBDIRS) $(LIBPROGSUBDIRS) wine
 	@echo "Wine build complete."
 
 WINAPI_CHECK_EXTRA_FLAGS = --global
@@ -84,68 +67,30 @@
 	@echo $? is newer than 'Make.rules', please rerun ./configure!
 	@exit 1
 
-wine: $(EMUOBJS) $(LDIMPORTS:%=lib%.$(LIBEXT)) library/libwine.$(LIBEXT) unicode/libwine_unicode.$(LIBEXT)
-	$(CC) -o wine $(EMUOBJS) -L. $(LDIMPORTS:%=-l%) $(LIBWINE) $(LIBUNICODE) $(LIBS) $(LDFLAGS)
+wine: $(WINEWRAPPER)
+	$(RM) $@ && $(LN_S) $(WINEWRAPPER) $@
 
-install_wine: dummy
-	$(MKINSTALLDIRS) $(bindir)
-	$(INSTALL_PROGRAM) wine $(bindir)/wine
-
-install:: all install_wine $(SUBDIRS:%=%/__install__)
+install:: all $(SUBDIRS:%=%/__install__)
 	-$(LDCONFIG)
 
 uninstall:: $(SUBDIRS:%=%/__uninstall__)
-	$(RM) $(bindir)/wine
-
-$(EMUOBJS) $(PROGRAMS) $(LIBRARIES): dummy
-	@cd `dirname $@` && $(MAKE) `basename $@`
-
-# Symlinks to libraries that we need to link against
-
-libwine.$(LIBEXT): library/libwine.$(LIBEXT)
-	$(RM) $@ && $(LN_S) library/libwine.$(LIBEXT) $@
-
-libwine_tsx11.$(LIBEXT): tsx11/libwine_tsx11.$(LIBEXT)
-	$(RM) $@ && $(LN_S) tsx11/libwine_tsx11.$(LIBEXT) $@
-
-libwine_unicode.$(LIBEXT): unicode/libwine_unicode.$(LIBEXT)
-	$(RM) $@ && $(LN_S) unicode/libwine_unicode.$(LIBEXT) $@
-
-libwine_uuid.a: ole/libwine_uuid.a
-	$(RM) $@ && $(LN_S) ole/libwine_uuid.a $@
-
-libuser32.dll.$(LIBEXT): dlls/user32.dll$(DLLEXT)
-	$(RM) $@ && $(LN_S) dlls/user32.dll$(DLLEXT) $@
-
-libgdi32.dll.$(LIBEXT): dlls/gdi32.dll$(DLLEXT)
-	$(RM) $@ && $(LN_S) dlls/gdi32.dll$(DLLEXT) $@
-
-libkernel32.dll.$(LIBEXT): dlls/kernel32.dll$(DLLEXT)
-	$(RM) $@ && $(LN_S) dlls/kernel32.dll$(DLLEXT) $@
-
-libntdll.dll.$(LIBEXT): dlls/ntdll.dll$(DLLEXT)
-	$(RM) $@ && $(LN_S) dlls/ntdll.dll$(DLLEXT) $@
-
-$(LINKABLE_DLLS:%=dlls/%$(DLLEXT)): dlls
 
 # Dependencies between directories
 
-$(PROGRAMS): tools
+$(LIBPROGSUBDIRS): tools dlls $(LIBSUBDIRS)
 
-$(EMUOBJS): tools dlls
+$(PROGSUBDIRS): tools $(LIBSUBDIRS)
 
-$(LIBPROGRAMS): tools dlls wine
+dlls: tools $(LIBSUBDIRS)
 
-server tools: $(LIBRARIES)
-
-dlls: tools $(LIBRARIES)
+tools: $(LIBSUBDIRS)
 
 checklink::
 	$(CC) -o checklink $(TOPSRCDIR)/library/checklink.c && $(RM) checklink
 
 checklink::
 	@cd dlls && $(MAKE) checklink
-	@cd debugger && $(MAKE) checklink
+	@cd programs && $(MAKE) checklink
 
 test_environment: dummy
 	@cd programs/winetest && $(MAKE) all
diff --git a/dlls/Makedll.rules.in b/dlls/Makedll.rules.in
index f1df256..9829173 100644
--- a/dlls/Makedll.rules.in
+++ b/dlls/Makedll.rules.in
@@ -35,14 +35,16 @@
 # Rules for .dll files
 
 $(MODULE): $(OBJS) $(MODULE).dbg.o $(SPEC_DEF) Makefile.in
-	$(DLLWRAP) $(DLLWRAPFLAGS) --def $(SPEC_DEF) --implib $(MODULE:.dll=.a) -o $(MODULE) $(OBJS) $(MODULE).dbg.o -L$(DLLDIR) $(IMPORTS:%=-l%) $(ALL_LIBS)
+	$(DLLWRAP) $(DLLWRAPFLAGS) --def $(SPEC_DEF) --implib $(MODULE:.dll=.a) -o $@ $(OBJS) $(MODULE).dbg.o -L$(DLLDIR) $(DELAYIMPORTS:%=-l%) $(IMPORTS:%=-l%) $(ALL_LIBS)
 
 $(SPEC_DEF): $(WINEBUILD)
 
 # Rules for checking that no imports are missing
 
+CHECKLINK_RPATH = dlls library tsx11 unicode
+
 checklink:: $(MODULE)$(DLLEXT)
-	$(CC) -o checklink $(TOPSRCDIR)/library/checklink.c $(MODULE)$(DLLEXT) && $(RM) checklink
+	$(CC) -o checklink $(CHECKLINK_RPATH:%=-Wl,-rpath,$(TOPOBJDIR)/%) $(TOPSRCDIR)/library/checklink.c $(MODULE)$(DLLEXT) && $(RM) checklink
 
 # Rules for testing
 
diff --git a/dlls/x11drv/clipboard.c b/dlls/x11drv/clipboard.c
index f53a9ea..4a276fb 100644
--- a/dlls/x11drv/clipboard.c
+++ b/dlls/x11drv/clipboard.c
@@ -288,8 +288,6 @@
         execl( BINDIR "/wineclipsrv", "wineclipsrv",
                selMask, dbgClassMask, clearSelection, NULL );
         execlp( "wineclipsrv", "wineclipsrv", selMask, dbgClassMask, clearSelection, NULL );
-        execl( "./windows/x11drv/wineclipsrv", "wineclipsrv",
-               selMask, dbgClassMask, clearSelection, NULL );
 
         /* Exec Failed! */
         perror("Could not start Wine clipboard server");
diff --git a/documentation/Makefile.in b/documentation/Makefile.in
index b62d649..ca851d8 100644
--- a/documentation/Makefile.in
+++ b/documentation/Makefile.in
@@ -65,7 +65,7 @@
 	db2ps $(BOOKNAME).sgml > /dev/null
 
 wine.man: wine.man.in
-	sed -e 's,@bindir\@,$(bindir),g' -e 's,@libdir\@,$(libdir),g' $(SRCDIR)/wine.man.in >$@ || $(RM) $@
+	sed -e 's,@bindir\@,$(bindir),g' -e 's,@dlldir\@,$(dlldir),g' $(SRCDIR)/wine.man.in >$@ || $(RM) $@
 
 install:: $(MAN_TARGETS)
 	$(INSTALL) -d $(mandir)/man$(prog_manext)
diff --git a/documentation/samples/config b/documentation/samples/config
index 4baa1d5..5966829 100644
--- a/documentation/samples/config
+++ b/documentation/samples/config
@@ -107,6 +107,8 @@
 "msacm"        = "builtin, native"
 "msacm32"      = "builtin, native"
 "midimap.drv"  = "builtin, native"
+; you can specify applications too
+"notepad.exe"  = "native, builtin"
 ; default for all other dlls
 "*" = "native, builtin, so"
 
diff --git a/documentation/wine.man.in b/documentation/wine.man.in
index 1d1b227..4d31b04 100644
--- a/documentation/wine.man.in
+++ b/documentation/wine.man.in
@@ -254,31 +254,30 @@
 .B wine
 processes. 
 .TP
-.I WINEPRELOAD
-If set, specifies the full name of a shared library that
-.B wine
-loads and runs as a Winelib application.
-.TP
 .I WINESERVER
 Specifies the path and name of the
 .B wineserver
-binary. If not set, a file named "wineserver" is searched in the
-path and in a few other likely locations.
+binary. If not set, Wine will try to load
+.B @bindir@/wineserver,
+and if this doesn't exist will then look for a file named "wineserver"
+in the path and in a few other likely locations.
 .TP
 .I WINELOADER
 Specifies the path and name of the
 .B wine
-binary to use to launch new Windows processes. If not set, a binary
-named "wine" is searched in the path and in a few other likely
-locations.
+binary to use to launch new Windows processes. If not set, Wine will
+try to load
+.B @bindir@/wine,
+and if this doesn't exist will then look for a file named "wine" in
+the path and in a few other likely locations.
 .TP
 .I WINEDLLPATH
-Specifies the path(s) in which to search for builtin dll files. This
-is a list of directories separated by ":". Builtin dlls are also
-searched in the directories specified by the standard
-.I LD_LIBRARY_PATH
-if they are not found in the directories listed in
-.I WINEDLLPATH.
+Specifies the path(s) in which to search for builtin dlls and Winelib
+applications. This is a list of directories separated by ":". In
+addition to any directory specified in
+.I WINEDLLPATH,
+Wine will also look in
+.B @dlldir@.
 .TP
 .I DISPLAY
 Specifies the X11 display to use.
@@ -378,12 +377,12 @@
 .B wine 
 debugger
 .TP 
-.I @bindir@/wineclpsrv
+.I @bindir@/wineclipsrv
 The 
 .B wine 
 clipboard server
 .TP 
-.I @libdir@
+.I @dlldir@
 Directory containing 
 .B wine's
 shared libraries 
diff --git a/include/module.h b/include/module.h
index 8c5b360..1e0146a 100644
--- a/include/module.h
+++ b/include/module.h
@@ -186,6 +186,19 @@
     LOADORDER_NTYPES
 };
 
+/* return values for MODULE_GetBinaryType */
+enum binary_type
+{
+    BINARY_UNKNOWN,
+    BINARY_PE_EXE,
+    BINARY_PE_DLL,
+    BINARY_WIN16,
+    BINARY_OS216,
+    BINARY_DOS,
+    BINARY_UNIX_EXE,
+    BINARY_UNIX_LIB
+};
+
 /* module.c */
 extern WINE_MODREF *MODULE_AllocModRef( HMODULE hModule, LPCSTR filename );
 extern FARPROC MODULE_GetProcAddress( HMODULE hModule, LPCSTR function, BOOL snoop );
@@ -197,6 +210,7 @@
 extern BOOL MODULE_FreeLibrary( WINE_MODREF *wm );
 extern WINE_MODREF *MODULE_FindModule( LPCSTR path );
 extern HMODULE16 MODULE_CreateDummyModule( LPCSTR filename, HMODULE module32 );
+extern enum binary_type MODULE_GetBinaryType( HANDLE hfile );
 extern FARPROC16 WINAPI WIN32_GetProcAddress16( HMODULE hmodule, LPCSTR name );
 extern SEGPTR WINAPI HasGPHandler16( SEGPTR address );
 extern void MODULE_WalkModref( DWORD id );
@@ -287,10 +301,5 @@
 
 /* scheduler/process.c */
 extern void PROCESS_CallUserSignalProc( UINT uCode, HMODULE16 hModule );
-extern BOOL PROCESS_Create( HANDLE hFile, LPCSTR filename, LPSTR cmd_line, LPCSTR env,
-                            LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
-                            BOOL inherit, DWORD flags,
-                            STARTUPINFOA *startup, PROCESS_INFORMATION *info,
-                            LPCSTR lpCurrentDirectory );
 
 #endif  /* __WINE_MODULE_H */
diff --git a/include/wine/library.h b/include/wine/library.h
index 8b35612..515c4bb 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -33,8 +33,7 @@
 extern int wine_dlclose( void *handle, char *error, int errorsize );
 extern void wine_dll_set_callback( load_dll_callback_t load );
 extern void *wine_dll_load( const char *filename, char *error, int errorsize );
-extern void *wine_dll_load_main_exe( const char *name, int search_path,
-                                     char *error, int errorsize );
+extern void *wine_dll_load_main_exe( const char *name, char *error, int errorsize, int test_only );
 extern void wine_dll_unload( void *handle );
 
 extern int __wine_main_argc;
diff --git a/library/loader.c b/library/loader.c
index 10352c4..60aefe4 100644
--- a/library/loader.c
+++ b/library/loader.c
@@ -118,7 +118,7 @@
 
 /* open a library for a given dll, searching in the dll path
  * 'name' must be the Windows dll name (e.g. "kernel32.dll") */
-static void *dlopen_dll( const char *name, char *error, int errorsize )
+static void *dlopen_dll( const char *name, char *error, int errorsize, int test_only )
 {
     int i, namelen = strlen(name);
     char *buffer, *p;
@@ -139,17 +139,16 @@
         int len = strlen(dll_paths[i]);
         p = buffer + dll_path_maxlen - len;
         memcpy( p, dll_paths[i], len );
-        if ((ret = wine_dlopen( p, RTLD_NOW, error, errorsize ))) break;
-        if (file_exists( p ))  /* exists but cannot be loaded, return the error */
+        if (test_only)  /* just test for file existence */
         {
-            free( buffer );
-            return NULL;
+            if ((ret = (void *)file_exists( p ))) break;
+        }
+        else
+        {
+            if ((ret = wine_dlopen( p, RTLD_NOW, error, errorsize ))) break;
+            if (file_exists( p )) break; /* exists but cannot be loaded, return the error */
         }
     }
-
-    /* now try the default dlopen search path */
-    if (!ret)
-        ret = wine_dlopen( buffer + dll_path_maxlen + 1, RTLD_NOW, error, errorsize );
     free( buffer );
     return ret;
 }
@@ -374,7 +373,7 @@
             return (void *)1;
         }
     }
-    return dlopen_dll( filename, error, errorsize );
+    return dlopen_dll( filename, error, errorsize, 0 );
 }
 
 
@@ -393,46 +392,9 @@
 /***********************************************************************
  *           wine_dll_load_main_exe
  *
- * Try to load the .so for the main exe, optionally searching for it in PATH.
+ * Try to load the .so for the main exe.
  */
-void *wine_dll_load_main_exe( const char *name, int search_path, char *error, int errorsize )
+void *wine_dll_load_main_exe( const char *name, char *error, int errorsize, int test_only )
 {
-    void *ret = NULL;
-    const char *path = NULL;
-    if (search_path) path = getenv( "PATH" );
-
-    if (!path)
-    {
-        /* no path, try only the specified name */
-        ret = wine_dlopen( name, RTLD_NOW, error, errorsize );
-    }
-    else
-    {
-        char buffer[128], *tmp = buffer;
-        size_t namelen = strlen(name);
-        size_t pathlen = strlen(path);
-
-        if (namelen + pathlen + 2 > sizeof(buffer)) tmp = malloc( namelen + pathlen + 2 );
-        if (tmp)
-        {
-            char *basename = tmp + pathlen;
-            *basename = '/';
-            strcpy( basename + 1, name );
-            for (;;)
-            {
-                int len;
-                const char *p = strchr( path, ':' );
-                if (!p) p = path + strlen(path);
-                if ((len = p - path) > 0)
-                {
-                    memcpy( basename - len, path, len );
-                    if ((ret = wine_dlopen( basename - len, RTLD_NOW, error, errorsize ))) break;
-                }
-                if (!*p) break;
-                path = p + 1;
-            }
-            if (tmp != buffer) free( tmp );
-        }
-    }
-    return ret;
+    return dlopen_dll( name, error, errorsize, test_only );
 }
diff --git a/loader/module.c b/loader/module.c
index 5d7c306..ad09e2a 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -518,10 +518,11 @@
  * FIXME: is reading the module imports the only way of discerning
  *        old Windows binaries from OS/2 ones ? At least it seems so...
  */
-static DWORD MODULE_Decide_OS2_OldWin(HANDLE hfile, IMAGE_DOS_HEADER *mz, IMAGE_OS2_HEADER *ne)
+static enum binary_type MODULE_Decide_OS2_OldWin(HANDLE hfile, const IMAGE_DOS_HEADER *mz,
+                                                 const IMAGE_OS2_HEADER *ne)
 {
     DWORD currpos = SetFilePointer( hfile, 0, NULL, SEEK_CUR);
-    DWORD type = SCS_OS216_BINARY;
+    enum binary_type ret = BINARY_OS216;
     LPWORD modtab = NULL;
     LPSTR nametab = NULL;
     DWORD len;
@@ -548,7 +549,7 @@
 	if (!(strncmp(&module[1], "KERNEL", module[0])))
 	{ /* very old Windows file */
 	    MESSAGE("This seems to be a very old (pre-3.0) Windows executable. Expect crashes, especially if this is a real-mode binary !\n");
-	    type = SCS_WOW_BINARY;
+            ret = BINARY_WIN16;
 	    goto good;
 	}
     }
@@ -560,11 +561,120 @@
     HeapFree( GetProcessHeap(), 0, modtab);
     HeapFree( GetProcessHeap(), 0, nametab);
     SetFilePointer( hfile, currpos, NULL, SEEK_SET); /* restore filepos */
-    return type;
+    return ret;
 }
 
 /***********************************************************************
  *           MODULE_GetBinaryType
+ */
+enum binary_type MODULE_GetBinaryType( HANDLE hfile )
+{
+    union
+    {
+        struct
+        {
+            unsigned char magic[4];
+            unsigned char ignored[12];
+            unsigned short type;
+        } elf;
+        IMAGE_DOS_HEADER mz;
+    } header;
+
+    char magic[4];
+    DWORD len;
+
+    /* Seek to the start of the file and read the header information. */
+    if (SetFilePointer( hfile, 0, NULL, SEEK_SET ) == -1)
+        return BINARY_UNKNOWN;
+    if (!ReadFile( hfile, &header, sizeof(header), &len, NULL ) || len != sizeof(header))
+        return BINARY_UNKNOWN;
+
+    if (!memcmp( header.elf.magic, "\177ELF", 4 ))
+    {
+        /* FIXME: we don't bother to check byte order, architecture, etc. */
+        switch(header.elf.type)
+        {
+        case 2: return BINARY_UNIX_EXE;
+        case 3: return BINARY_UNIX_LIB;
+        }
+        return BINARY_UNKNOWN;
+    }
+
+    /* Not ELF, try DOS */
+
+    if (header.mz.e_magic == IMAGE_DOS_SIGNATURE)
+    {
+        /* We do have a DOS image so we will now try to seek into
+         * the file by the amount indicated by the field
+         * "Offset to extended header" and read in the
+         * "magic" field information at that location.
+         * This will tell us if there is more header information
+         * to read or not.
+         */
+        /* But before we do we will make sure that header
+         * structure encompasses the "Offset to extended header"
+         * field.
+         */
+        if ((header.mz.e_cparhdr << 4) < sizeof(IMAGE_DOS_HEADER))
+            return BINARY_DOS;
+        if (header.mz.e_crlc && (header.mz.e_lfarlc < sizeof(IMAGE_DOS_HEADER)))
+            return BINARY_DOS;
+        if (header.mz.e_lfanew < sizeof(IMAGE_DOS_HEADER))
+            return BINARY_DOS;
+        if (SetFilePointer( hfile, header.mz.e_lfanew, NULL, SEEK_SET ) == -1)
+            return BINARY_DOS;
+        if (!ReadFile( hfile, magic, sizeof(magic), &len, NULL ) || len != sizeof(magic))
+            return BINARY_DOS;
+
+        /* Reading the magic field succeeded so
+         * we will try to determine what type it is.
+         */
+        if (!memcmp( magic, "PE\0\0", 4 ))
+        {
+            IMAGE_NT_HEADERS nt;
+
+            if (SetFilePointer( hfile, header.mz.e_lfanew, NULL, SEEK_SET ) != -1 &&
+                ReadFile( hfile, &nt, sizeof(nt), &len, NULL ) && len == sizeof(nt))
+            {
+                if (nt.FileHeader.Characteristics & IMAGE_FILE_DLL) return BINARY_PE_DLL;
+                return BINARY_PE_EXE;
+            }
+            return BINARY_UNKNOWN;
+        }
+
+        if (!memcmp( magic, "NE", 2 ))
+        {
+            /* This is a Windows executable (NE) header.  This can
+             * mean either a 16-bit OS/2 or a 16-bit Windows or even a
+             * DOS program (running under a DOS extender).  To decide
+             * which, we'll have to read the NE header.
+             */
+            IMAGE_OS2_HEADER ne;
+            if (    SetFilePointer( hfile, header.mz.e_lfanew, NULL, SEEK_SET ) != -1
+                    && ReadFile( hfile, &ne, sizeof(ne), &len, NULL )
+                    && len == sizeof(ne) )
+            {
+                switch ( ne.ne_exetyp )
+                {
+                case 2:  return BINARY_WIN16;
+                case 5:  return BINARY_DOS;
+                default: return MODULE_Decide_OS2_OldWin(hfile, &header.mz, &ne);
+                }
+            }
+            /* Couldn't read header, so abort. */
+            return BINARY_UNKNOWN;
+        }
+
+        /* Unknown extended header, but this file is nonetheless DOS-executable. */
+        return BINARY_DOS;
+    }
+
+    return BINARY_UNKNOWN;
+}
+
+/***********************************************************************
+ *             GetBinaryTypeA                     [KERNEL32.@]
+ *             GetBinaryType                      [KERNEL32.@]
  *
  * The GetBinaryType function determines whether a file is executable
  * or not and if it is it returns what type of executable it is.
@@ -593,133 +703,11 @@
  * Note that .COM and .PIF files are only recognized by their
  * file name extension; but Windows does it the same way ...
  */
-static BOOL MODULE_GetBinaryType( HANDLE hfile, LPCSTR filename, LPDWORD lpBinaryType )
-{
-    IMAGE_DOS_HEADER mz_header;
-    char magic[4], *ptr;
-    DWORD len;
-
-    /* Seek to the start of the file and read the DOS header information.
-     */
-    if (    SetFilePointer( hfile, 0, NULL, SEEK_SET ) != -1  
-         && ReadFile( hfile, &mz_header, sizeof(mz_header), &len, NULL )
-         && len == sizeof(mz_header) )
-    {
-        /* Now that we have the header check the e_magic field
-         * to see if this is a dos image.
-         */
-        if ( mz_header.e_magic == IMAGE_DOS_SIGNATURE )
-        {
-            BOOL lfanewValid = FALSE;
-            /* We do have a DOS image so we will now try to seek into
-             * the file by the amount indicated by the field
-             * "Offset to extended header" and read in the
-             * "magic" field information at that location.
-             * This will tell us if there is more header information
-             * to read or not.
-             */
-            /* But before we do we will make sure that header
-             * structure encompasses the "Offset to extended header"
-             * field.
-             */
-            if ( (mz_header.e_cparhdr<<4) >= sizeof(IMAGE_DOS_HEADER) )
-                if ( ( mz_header.e_crlc == 0 ) ||
-                     ( mz_header.e_lfarlc >= sizeof(IMAGE_DOS_HEADER) ) )
-                    if (    mz_header.e_lfanew >= sizeof(IMAGE_DOS_HEADER)
-                         && SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET ) != -1  
-                         && ReadFile( hfile, magic, sizeof(magic), &len, NULL )
-                         && len == sizeof(magic) )
-                        lfanewValid = TRUE;
-
-            if ( !lfanewValid )
-            {
-                /* If we cannot read this "extended header" we will
-                 * assume that we have a simple DOS executable.
-                 */
-                *lpBinaryType = SCS_DOS_BINARY;
-                return TRUE;
-            }
-            else
-            {
-                /* Reading the magic field succeeded so
-                 * we will try to determine what type it is.
-                 */
-                if ( *(DWORD*)magic      == IMAGE_NT_SIGNATURE )
-                {
-                    /* This is an NT signature.
-                     */
-                    *lpBinaryType = SCS_32BIT_BINARY;
-                    return TRUE;
-                }
-                else if ( *(WORD*)magic == IMAGE_OS2_SIGNATURE )
-                {
-                    /* The IMAGE_OS2_SIGNATURE indicates that the
-                     * "extended header is a Windows executable (NE)
-                     * header."  This can mean either a 16-bit OS/2
-                     * or a 16-bit Windows or even a DOS program 
-                     * (running under a DOS extender).  To decide
-                     * which, we'll have to read the NE header.
-                     */
-
-                     IMAGE_OS2_HEADER ne;
-                     if (    SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET ) != -1  
-                          && ReadFile( hfile, &ne, sizeof(ne), &len, NULL )
-                          && len == sizeof(ne) )
-                     {
-                         switch ( ne.ne_exetyp )
-                         {
-                         case 2:  *lpBinaryType = SCS_WOW_BINARY;   return TRUE;
-                         case 5:  *lpBinaryType = SCS_DOS_BINARY;   return TRUE;
-                         default: *lpBinaryType =
-				  MODULE_Decide_OS2_OldWin(hfile, &mz_header, &ne);
-				  return TRUE;
-                         }
-                     }
-                     /* Couldn't read header, so abort. */
-                     return FALSE;
-                }
-                else
-                {
-                    /* Unknown extended header, but this file is nonetheless
-		       DOS-executable.
-                     */
-                    *lpBinaryType = SCS_DOS_BINARY;
-	            return TRUE;
-                }
-            }
-        }
-    }
-
-    /* If we get here, we don't even have a correct MZ header.
-     * Try to check the file extension for known types ...
-     */
-    ptr = strrchr( filename, '.' );
-    if ( ptr && !strchr( ptr, '\\' ) && !strchr( ptr, '/' ) )
-    {
-        if ( !FILE_strcasecmp( ptr, ".COM" ) )
-        {
-            *lpBinaryType = SCS_DOS_BINARY;
-            return TRUE;
-        }
-
-        if ( !FILE_strcasecmp( ptr, ".PIF" ) )
-        {
-            *lpBinaryType = SCS_PIF_BINARY;
-            return TRUE;
-        }
-    }
-
-    return FALSE;
-}
-
-/***********************************************************************
- *             GetBinaryTypeA                     [KERNEL32.@]
- *             GetBinaryType                      [KERNEL32.@]
- */
 BOOL WINAPI GetBinaryTypeA( LPCSTR lpApplicationName, LPDWORD lpBinaryType )
 {
     BOOL ret = FALSE;
     HANDLE hfile;
+    char *ptr;
 
     TRACE_(win32)("%s\n", lpApplicationName );
 
@@ -737,12 +725,47 @@
 
     /* Check binary type
      */
-    ret = MODULE_GetBinaryType( hfile, lpApplicationName, lpBinaryType );
+    switch(MODULE_GetBinaryType( hfile ))
+    {
+    case BINARY_UNKNOWN:
+        /* try to determine from file name */
+        ptr = strrchr( lpApplicationName, '.' );
+        if (!ptr) break;
+        if (!FILE_strcasecmp( ptr, ".COM" ))
+        {
+            *lpBinaryType = SCS_DOS_BINARY;
+            ret = TRUE;
+        }
+        else if (!FILE_strcasecmp( ptr, ".PIF" ))
+        {
+            *lpBinaryType = SCS_PIF_BINARY;
+            ret = TRUE;
+        }
+        break;
+    case BINARY_PE_EXE:
+    case BINARY_PE_DLL:
+        *lpBinaryType = SCS_32BIT_BINARY;
+        ret = TRUE;
+        break;
+    case BINARY_WIN16:
+        *lpBinaryType = SCS_WOW_BINARY;
+        ret = TRUE;
+        break;
+    case BINARY_OS216:
+        *lpBinaryType = SCS_OS216_BINARY;
+        ret = TRUE;
+        break;
+    case BINARY_DOS:
+        *lpBinaryType = SCS_DOS_BINARY;
+        ret = TRUE;
+        break;
+    case BINARY_UNIX_EXE:
+    case BINARY_UNIX_LIB:
+        ret = FALSE;
+        break;
+    }
 
-    /* Close the file.
-     */
     CloseHandle( hfile );
-
     return ret;
 }
 
@@ -967,238 +990,6 @@
 }
 
 
-/*************************************************************************
- *               get_file_name
- *
- * Helper for CreateProcess: retrieve the file name to load from the
- * app name and command line. Store the file name in buffer, and
- * return a possibly modified command line.
- */
-static LPSTR get_file_name( LPCSTR appname, LPSTR cmdline, LPSTR buffer, int buflen )
-{
-    char *name, *pos, *ret = NULL;
-    const char *p;
-
-    /* if we have an app name, everything is easy */
-
-    if (appname)
-    {
-        /* use the unmodified app name as file name */
-        lstrcpynA( buffer, appname, buflen );
-        if (!(ret = cmdline))
-        {
-            /* no command-line, create one */
-            if ((ret = HeapAlloc( GetProcessHeap(), 0, strlen(appname) + 3 )))
-                sprintf( ret, "\"%s\"", appname );
-        }
-        return ret;
-    }
-
-    if (!cmdline)
-    {
-        SetLastError( ERROR_INVALID_PARAMETER );
-        return NULL;
-    }
-
-    /* first check for a quoted file name */
-
-    if ((cmdline[0] == '"') && ((p = strchr( cmdline + 1, '"' ))))
-    {
-        int len = p - cmdline - 1;
-        /* extract the quoted portion as file name */
-        if (!(name = HeapAlloc( GetProcessHeap(), 0, len + 1 ))) return NULL;
-        memcpy( name, cmdline + 1, len );
-        name[len] = 0;
-
-        if (SearchPathA( NULL, name, ".exe", buflen, buffer, NULL ) ||
-            SearchPathA( NULL, name, NULL, buflen, buffer, NULL ))
-            ret = cmdline;  /* no change necessary */
-        goto done;
-    }
-
-    /* now try the command-line word by word */
-
-    if (!(name = HeapAlloc( GetProcessHeap(), 0, strlen(cmdline) + 1 ))) return NULL;
-    pos = name;
-    p = cmdline;
-
-    while (*p)
-    {
-        do *pos++ = *p++; while (*p && *p != ' ');
-        *pos = 0;
-        TRACE("trying '%s'\n", name );
-        if (SearchPathA( NULL, name, ".exe", buflen, buffer, NULL ) ||
-            SearchPathA( NULL, name, NULL, buflen, buffer, NULL ))
-        {
-            ret = cmdline;
-            break;
-        }
-    }
-
-    if (!ret || !strchr( name, ' ' )) goto done;  /* no change necessary */
-
-    /* now build a new command-line with quotes */
-
-    if (!(ret = HeapAlloc( GetProcessHeap(), 0, strlen(cmdline) + 3 ))) goto done;
-    sprintf( ret, "\"%s\"%s", name, p );
-
- done:
-    HeapFree( GetProcessHeap(), 0, name );
-    return ret;
-}
-
-
-/**********************************************************************
- *       CreateProcessA          (KERNEL32.@)
- */
-BOOL WINAPI CreateProcessA( LPCSTR lpApplicationName, LPSTR lpCommandLine, 
-                            LPSECURITY_ATTRIBUTES lpProcessAttributes,
-                            LPSECURITY_ATTRIBUTES lpThreadAttributes,
-                            BOOL bInheritHandles, DWORD dwCreationFlags,
-                            LPVOID lpEnvironment, LPCSTR lpCurrentDirectory,
-                            LPSTARTUPINFOA lpStartupInfo,
-                            LPPROCESS_INFORMATION lpProcessInfo )
-{
-    BOOL retv = FALSE;
-    HANDLE hFile;
-    DWORD type;
-    char name[MAX_PATH];
-    LPSTR tidy_cmdline;
-
-    /* Process the AppName and/or CmdLine to get module name and path */
-
-    TRACE("app %s cmdline %s\n", debugstr_a(lpApplicationName), debugstr_a(lpCommandLine) );
-
-    if (!(tidy_cmdline = get_file_name( lpApplicationName, lpCommandLine, name, sizeof(name) )))
-        return FALSE;
-
-    /* Warn if unsupported features are used */
-
-    if (dwCreationFlags & NORMAL_PRIORITY_CLASS)
-        FIXME("(%s,...): NORMAL_PRIORITY_CLASS ignored\n", name);
-    if (dwCreationFlags & IDLE_PRIORITY_CLASS)
-        FIXME("(%s,...): IDLE_PRIORITY_CLASS ignored\n", name);
-    if (dwCreationFlags & HIGH_PRIORITY_CLASS)
-        FIXME("(%s,...): HIGH_PRIORITY_CLASS ignored\n", name);
-    if (dwCreationFlags & REALTIME_PRIORITY_CLASS)
-        FIXME("(%s,...): REALTIME_PRIORITY_CLASS ignored\n", name);
-    if (dwCreationFlags & CREATE_NEW_PROCESS_GROUP)
-        FIXME("(%s,...): CREATE_NEW_PROCESS_GROUP ignored\n", name);
-    if (dwCreationFlags & CREATE_UNICODE_ENVIRONMENT)
-        FIXME("(%s,...): CREATE_UNICODE_ENVIRONMENT ignored\n", name);
-    if (dwCreationFlags & CREATE_SEPARATE_WOW_VDM)
-        FIXME("(%s,...): CREATE_SEPARATE_WOW_VDM ignored\n", name);
-    if (dwCreationFlags & CREATE_SHARED_WOW_VDM)
-        FIXME("(%s,...): CREATE_SHARED_WOW_VDM ignored\n", name);
-    if (dwCreationFlags & CREATE_DEFAULT_ERROR_MODE)
-        FIXME("(%s,...): CREATE_DEFAULT_ERROR_MODE ignored\n", name);
-    if (dwCreationFlags & CREATE_NO_WINDOW)
-        FIXME("(%s,...): CREATE_NO_WINDOW ignored\n", name);
-    if (dwCreationFlags & PROFILE_USER)
-        FIXME("(%s,...): PROFILE_USER ignored\n", name);
-    if (dwCreationFlags & PROFILE_KERNEL)
-        FIXME("(%s,...): PROFILE_KERNEL ignored\n", name);
-    if (dwCreationFlags & PROFILE_SERVER)
-        FIXME("(%s,...): PROFILE_SERVER ignored\n", name);
-    if (lpStartupInfo->lpDesktop)
-        FIXME("(%s,...): lpStartupInfo->lpDesktop %s ignored\n", 
-                      name, debugstr_a(lpStartupInfo->lpDesktop));
-    if (lpStartupInfo->dwFlags & STARTF_RUNFULLSCREEN)
-        FIXME("(%s,...): STARTF_RUNFULLSCREEN ignored\n", name);
-    if (lpStartupInfo->dwFlags & STARTF_FORCEONFEEDBACK)
-        FIXME("(%s,...): STARTF_FORCEONFEEDBACK ignored\n", name);
-    if (lpStartupInfo->dwFlags & STARTF_FORCEOFFFEEDBACK)
-        FIXME("(%s,...): STARTF_FORCEOFFFEEDBACK ignored\n", name);
-    if (lpStartupInfo->dwFlags & STARTF_USEHOTKEY)
-        FIXME("(%s,...): STARTF_USEHOTKEY ignored\n", name);
-
-    /* Open file and determine executable type */
-
-    hFile = CreateFileA( name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
-    if (hFile == INVALID_HANDLE_VALUE) goto done;
-
-    if ( !MODULE_GetBinaryType( hFile, name, &type ) )
-    { /* unknown file, try as unix executable */
-        CloseHandle( hFile );
-        retv = PROCESS_Create( 0, name, tidy_cmdline, lpEnvironment, 
-                               lpProcessAttributes, lpThreadAttributes,
-                               bInheritHandles, dwCreationFlags,
-                               lpStartupInfo, lpProcessInfo, lpCurrentDirectory );
-        goto done;
-    }
-
-    /* Create process */
-
-    switch ( type )
-    {
-    case SCS_32BIT_BINARY:
-    case SCS_WOW_BINARY:
-    case SCS_DOS_BINARY:
-        retv = PROCESS_Create( hFile, name, tidy_cmdline, lpEnvironment, 
-                               lpProcessAttributes, lpThreadAttributes,
-                               bInheritHandles, dwCreationFlags,
-                               lpStartupInfo, lpProcessInfo, lpCurrentDirectory);
-        break;
-
-    case SCS_PIF_BINARY:
-    case SCS_POSIX_BINARY:
-    case SCS_OS216_BINARY:
-        FIXME("Unsupported executable type: %ld\n", type );
-        /* fall through */
-
-    default:
-        SetLastError( ERROR_BAD_FORMAT );
-        break;
-    }
-    CloseHandle( hFile );
-
- done:
-    if (tidy_cmdline != lpCommandLine) HeapFree( GetProcessHeap(), 0, tidy_cmdline );
-    return retv;
-}
-
-/**********************************************************************
- *       CreateProcessW          (KERNEL32.@)
- * NOTES
- *  lpReserved is not converted
- */
-BOOL WINAPI CreateProcessW( LPCWSTR lpApplicationName, LPWSTR lpCommandLine, 
-                                LPSECURITY_ATTRIBUTES lpProcessAttributes,
-                                LPSECURITY_ATTRIBUTES lpThreadAttributes,
-                                BOOL bInheritHandles, DWORD dwCreationFlags,
-                                LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory,
-                                LPSTARTUPINFOW lpStartupInfo,
-                                LPPROCESS_INFORMATION lpProcessInfo )
-{   BOOL ret;
-    STARTUPINFOA StartupInfoA;
-    
-    LPSTR lpApplicationNameA = HEAP_strdupWtoA (GetProcessHeap(),0,lpApplicationName);
-    LPSTR lpCommandLineA = HEAP_strdupWtoA (GetProcessHeap(),0,lpCommandLine);
-    LPSTR lpCurrentDirectoryA = HEAP_strdupWtoA (GetProcessHeap(),0,lpCurrentDirectory);
-
-    memcpy (&StartupInfoA, lpStartupInfo, sizeof(STARTUPINFOA));
-    StartupInfoA.lpDesktop = HEAP_strdupWtoA (GetProcessHeap(),0,lpStartupInfo->lpDesktop);
-    StartupInfoA.lpTitle = HEAP_strdupWtoA (GetProcessHeap(),0,lpStartupInfo->lpTitle);
-
-    TRACE_(win32)("(%s,%s,...)\n", debugstr_w(lpApplicationName), debugstr_w(lpCommandLine));
-
-    if (lpStartupInfo->lpReserved)
-      FIXME_(win32)("StartupInfo.lpReserved is used, please report (%s)\n", debugstr_w(lpStartupInfo->lpReserved));
-      
-    ret = CreateProcessA(  lpApplicationNameA,  lpCommandLineA, 
-                             lpProcessAttributes, lpThreadAttributes,
-                             bInheritHandles, dwCreationFlags,
-                             lpEnvironment, lpCurrentDirectoryA,
-                             &StartupInfoA, lpProcessInfo );
-
-    HeapFree( GetProcessHeap(), 0, lpCurrentDirectoryA );
-    HeapFree( GetProcessHeap(), 0, lpCommandLineA );
-    HeapFree( GetProcessHeap(), 0, StartupInfoA.lpDesktop );
-    HeapFree( GetProcessHeap(), 0, StartupInfoA.lpTitle );
-
-    return ret;
-}
-
 /***********************************************************************
  *              GetModuleHandleA         (KERNEL32.@)
  *              GetModuleHandle32        (KERNEL.488)
@@ -1297,17 +1088,20 @@
                                             NULL, OPEN_EXISTING, 0, 0 );
                 if (hFile != INVALID_HANDLE_VALUE)
                 {
-                    DWORD type;
-                    MODULE_GetBinaryType( hFile, filename, &type );
-                    if (type == SCS_32BIT_BINARY)
+                    HANDLE mapping;
+                    switch (MODULE_GetBinaryType( hFile ))
                     {
-                        HANDLE mapping = CreateFileMappingA( hFile, NULL, PAGE_READONLY,
-                                                             0, 0, NULL );
+                    case BINARY_PE_EXE:
+                    case BINARY_PE_DLL:
+                        mapping = CreateFileMappingA( hFile, NULL, PAGE_READONLY, 0, 0, NULL );
                         if (mapping)
                         {
                             hmod = (HMODULE)MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
                             CloseHandle( mapping );
                         }
+                        break;
+                    default:
+                        break;
                     }
                     CloseHandle( hFile );
                 }
diff --git a/miscemu/.cvsignore b/miscemu/.cvsignore
index 25613a4..1bf52a4 100644
--- a/miscemu/.cvsignore
+++ b/miscemu/.cvsignore
@@ -1,2 +1,3 @@
 Makefile
+wine
 wine.spec.c
diff --git a/miscemu/Makefile.in b/miscemu/Makefile.in
index ca523c4..7a96f37 100644
--- a/miscemu/Makefile.in
+++ b/miscemu/Makefile.in
@@ -3,19 +3,32 @@
 TOPOBJDIR = ..
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
-MODULE    = miscemu
+MODULE    = wine
 IMPORTS   = ntdll
+LDIMPORTS = ntdll.dll
 
 SPEC_SRCS = wine.spec
 
 C_SRCS = \
 	main.c
 
-all: $(MODULE).o
+all: $(MODULE)
 
 @MAKE_RULES@
 
-$(MODULE).o: $(SPEC_SRCS:.spec=.spec.o) $(OBJS) Makefile.in $(TOPSRCDIR)/Make.rules.in
-	$(LDCOMBINE) $(SPEC_SRCS:.spec=.spec.o) $(OBJS) -o $@
+ALL_OBJS = $(SPEC_SRCS:.spec=.spec.o) $(OBJS)
+
+$(MODULE): $(ALL_OBJS)
+	$(CC) -o $@ $(ALL_OBJS) -L$(DLLDIR) $(LDIMPORTS:%=-l%) $(LIBWINE) $(LIBUNICODE) $(LIBS) $(LDFLAGS)
+
+install:: $(MODULE)
+	$(MKINSTALLDIRS) $(bindir)
+	$(INSTALL_PROGRAM) wine $(bindir)/wine
+
+uninstall::
+	$(RM) $(bindir)/wine
+
+clean::
+	$(RM) $(MODULE)
 
 ### Dependencies:
diff --git a/programs/.cvsignore b/programs/.cvsignore
index 968fe91..a2bb395 100644
--- a/programs/.cvsignore
+++ b/programs/.cvsignore
@@ -1,2 +1,3 @@
 Makefile
 Makeprog.rules
+wineapploader
diff --git a/programs/Makefile.in b/programs/Makefile.in
index 76fe18e..acaccfe 100644
--- a/programs/Makefile.in
+++ b/programs/Makefile.in
@@ -4,54 +4,106 @@
 VPATH     = @srcdir@
 MODULE    = none
 
-INSTALLSUBDIRS = \
+SUBDIRS = \
+	$(TOPOBJDIR)/debugger \
+	avitools \
+	clock \
+	cmdlgtst \
 	control \
 	expand \
 	notepad \
+	osversioncheck \
+	progman \
+	regapi \
+	regedit \
+	regsvr32 \
+	regtest \
+	uninstaller \
+	view \
+	wcmd \
+	wineconsole \
+	winemine \
+	winepath \
+	winetest \
+	winhelp \
+	winver
+
+# Programs to install in bin directory
+# We don't install everything to avoid polluting /usr/bin too much
+INSTALLPROGS = \
+	expand \
+	notepad \
 	progman \
 	regedit \
 	regsvr32 \
 	uninstaller \
 	wcmd \
 	wineconsole \
+	winedbg \
 	winemine \
 	winepath \
-	winhelp \
-	winver
+	winhelp
 
-# Programs that are not generally useful and don't get installed
-# Use 'make everything' to build them
-OTHERSUBDIRS = \
-	avitools \
-	clock \
-	cmdlgtst \
-	osversioncheck \
-	regapi \
-	regtest \
-	view \
-	winetest
-
-SUBDIRS = $(INSTALLSUBDIRS) $(OTHERSUBDIRS)
-
-all: $(INSTALLSUBDIRS)
+# Symlinks to apps that we want to run from inside the source tree
+SYMLINKS = \
+	wineconsole.exe \
+	winedbg.exe \
+	winetest.exe
 
 @MAKE_RULES@
 
-everything: $(SUBDIRS)
+all: wineapploader $(SUBDIRS) $(SYMLINKS:%=%$(DLLEXT))
 
-install-everything: $(SUBDIRS:%=%/__install__)
+wineapploader: wineapploader.in
+	sed -e 's,@bindir\@,$(bindir),g' $(SRCDIR)/wineapploader.in >$@ || $(RM) $@
 
-uninstall-everything: $(SUBDIRS:%=%/__uninstall__)
+# Rules for installation
 
-install:: $(INSTALLSUBDIRS:%=%/__install__)
+.PHONY: install-apploader install-progs install-progs.so $(INSTALLPROGS:%=%/__installprog__)
 
-uninstall:: $(INSTALLSUBDIRS:%=%/__uninstall__)
+install-apploader: wineapploader dummy
+	$(MKINSTALLDIRS) $(bindir)
+	$(INSTALL_SCRIPT) wineapploader $(bindir)/wineapploader
+
+$(INSTALLPROGS:%=%/__installprog__): install-apploader
+	$(RM) $(bindir)/`dirname $@` && $(LN) $(bindir)/wineapploader $(bindir)/`dirname $@`
+
+install-progs.so: $(INSTALLPROGS:%=%/__installprog__)
+	$(RM) $(bindir)/wineapploader
+
+install-progs: # nothing to do here
+
+install:: $(SUBDIRS:%=%/__install__) install-progs$(DLLEXT)
+
+uninstall:: $(SUBDIRS:%=%/__uninstall__)
+	$(RM) $(bindir)/wineapploader $(INSTALLPROGS:%=$(bindir)/%)
+	-rmdir $(dlldir)
+
+clean::
+	$(RM) wineapploader $(SYMLINKS)
+
+# Rules for testing
 
 $(SUBDIRS:%=%/__checklink__): dummy
 	@cd `dirname $@` && $(MAKE) checklink
 
+checklink:: $(SUBDIRS:%=%/__checklink__)
+
 check test:: $(SUBDIRS:%=%/__test__)
 
-checklink:: $(SUBDIRS:%=%/__checklink__)
+# Rules for symlinks
+
+wineconsole.exe$(DLLEXT): wineconsole/wineconsole.exe$(DLLEXT)
+	$(RM) $@ && $(LN_S) wineconsole/wineconsole.exe$(DLLEXT) $@
+
+winedbg.exe$(DLLEXT): $(TOPOBJDIR)/debugger/winedbg.exe$(DLLEXT)
+	$(RM) $@ && $(LN_S) $(TOPOBJDIR)/debugger/winedbg.exe$(DLLEXT) $@
+
+winetest.exe$(DLLEXT): winetest/winetest.exe$(DLLEXT)
+	$(RM) $@ && $(LN_S) winetest/winetest.exe$(DLLEXT) $@
+
+wineconsole/wineconsole.exe$(DLLEXT): wineconsole
+$(TOPOBJDIR)/debugger/winedbg.exe$(DLLEXT): $(TOPOBJDIR)/debugger
+winetest/winetest.exe$(DLLEXT): winetest
 
 ### Dependencies:
diff --git a/programs/Makeprog.rules.in b/programs/Makeprog.rules.in
index 1abc1ac..9d9615e 100644
--- a/programs/Makeprog.rules.in
+++ b/programs/Makeprog.rules.in
@@ -32,8 +32,8 @@
 $(MODULE).so: $(MODULE).spec.o $(ALL_OBJS) Makefile.in
 	$(LDSHARED) $(LDDLLFLAGS) $(MODULE).spec.o $(ALL_OBJS) -o $@ $(ALL_LIBS)
 
-$(BASEMODULE): $(MODULE).so
-	$(RM) $(BASEMODULE) && $(LN_S) $(TOPOBJDIR)/wine $(BASEMODULE)
+$(BASEMODULE): $(WINEWRAPPER)
+	$(RM) $@ && $(LN_S) $(WINEWRAPPER) $@
 
 # Rules for .exe main module
 
@@ -42,8 +42,10 @@
 
 # Rules for checking that no imports are missing
 
+CHECKLINK_RPATH = library tsx11 unicode
+
 checklink:: $(MODULE).so
-	$(CC) -o checklink $(TOPSRCDIR)/library/checklink.c $(MODULE).so && $(RM) checklink
+	$(CC) -o checklink $(CHECKLINK_RPATH:%=-Wl,-rpath,$(TOPOBJDIR)/%) $(TOPSRCDIR)/library/checklink.c $(MODULE).so && $(RM) checklink
 
 # Rules for testing
 
@@ -51,21 +53,25 @@
 
 # Rules for installation
 
-.PHONY: install_prog install_prog.so
+.PHONY: install_prog install_prog.so uninstall_prog uninstall_prog.so
 
-install_prog.so:: $(MODULE).so
-	$(MKINSTALLDIRS) $(bindir)
-	$(INSTALL_PROGRAM) $(MODULE).so $(bindir)/$(MODULE).so
-	cd $(bindir) && $(RM) $(BASEMODULE) && $(LN_S) wine $(BASEMODULE)
+install_prog.so: $(MODULE).so
+	$(MKINSTALLDIRS) $(dlldir)
+	$(INSTALL_PROGRAM) $(MODULE).so $(dlldir)/$(MODULE).so
 
-install_prog.exe:: $(MODULE)
+install_prog: $(MODULE)
 	$(MKINSTALLDIRS) $(bindir)
 	$(INSTALL_PROGRAM) $(MODULE) $(bindir)/$(MODULE)
 
+uninstall_prog.so: dummy
+	$(RM) $(dlldir)/$(MODULE).so
+
+uninstall_prog: dummy
+	$(RM) $(bindir)/$(MODULE)
+
 install:: install_prog$(DLLEXT)
 
-uninstall::
-	$(RM) $(bindir)/$(BASEMODULE) $(bindir)/$(MODULE) $(bindir)/$(MODULE).so
+uninstall:: uninstall_prog$(DLLEXT)
 
 clean::
 	$(RM) $(BASEMODULE) $(MODULE)
diff --git a/programs/avitools/Makefile.in b/programs/avitools/Makefile.in
index 4ff4f6f..2e8cf45 100644
--- a/programs/avitools/Makefile.in
+++ b/programs/avitools/Makefile.in
@@ -15,25 +15,25 @@
 
 @MAKE_RULES@
 
-all: $(PROGRAMS:%=%$(DLLEXT)) $(PROGRAMS:%.exe=%$(EXEEXT))
+all: $(PROGRAMS:%=%$(DLLEXT)) $(PROGRAMS:.exe=$(EXEEXT))
 
 aviinfo.exe.spec.c: aviinfo.o $(WINEBUILD)
-	$(LDPATH) $(WINEBUILD) $(DEFS) -sym aviinfo.o -o aviinfo.exe.spec.c -exe aviinfo.exe -mgui -L$(DLLDIR) -lkernel32
+	$(LDPATH) $(WINEBUILD) $(DEFS) -sym aviinfo.o -o $@ -exe aviinfo.exe -mgui -L$(DLLDIR) -lkernel32
 
 aviplay.exe.spec.c: aviplay.o $(WINEBUILD)
-	$(LDPATH) $(WINEBUILD) $(DEFS) -sym aviplay.o -o aviplay.exe.spec.c -exe aviplay.exe -mgui -L$(DLLDIR) -lddraw -lkernel32
+	$(LDPATH) $(WINEBUILD) $(DEFS) -sym aviplay.o -o $@ -exe aviplay.exe -mgui -L$(DLLDIR) -lddraw -lkernel32
 
 icinfo.exe.spec.c: icinfo.o $(WINEBUILD)
-	$(LDPATH) $(WINEBUILD) $(DEFS) -sym icinfo.o -o icinfo.exe.spec.c -exe icinfo.exe -mgui -L$(DLLDIR) -lmsvfw32 -lkernel32
+	$(LDPATH) $(WINEBUILD) $(DEFS) -sym icinfo.o -o $@ -exe icinfo.exe -mgui -L$(DLLDIR) -lmsvfw32 -lkernel32
 
 aviinfo.exe.so: aviinfo.o aviinfo.exe.spec.o
-	$(LDSHARED) $(LDDLLFLAGS) -o aviinfo.exe.so aviinfo.o aviinfo.exe.spec.o $(ALL_LIBS)
+	$(LDSHARED) $(LDDLLFLAGS) -o $@ aviinfo.o aviinfo.exe.spec.o $(ALL_LIBS)
 
 aviplay.exe.so: aviplay.o aviplay.exe.spec.o
-	$(LDSHARED) $(LDDLLFLAGS) -o aviplay.exe.so aviplay.o aviplay.exe.spec.o $(ALL_LIBS)
+	$(LDSHARED) $(LDDLLFLAGS) -o $@ aviplay.o aviplay.exe.spec.o $(ALL_LIBS)
 
 icinfo.exe.so: icinfo.o icinfo.exe.spec.o
-	$(LDSHARED) $(LDDLLFLAGS) -o icinfo.exe.so icinfo.o icinfo.exe.spec.o $(ALL_LIBS)
+	$(LDSHARED) $(LDDLLFLAGS) -o $@ icinfo.o icinfo.exe.spec.o $(ALL_LIBS)
 
 aviinfo.exe: aviinfo.o
 	$(CC) -o $@ aviinfo.o -lkernel32 $(ALL_LIBS)
@@ -44,38 +44,45 @@
 icinfo.exe: icinfo.o
 	$(CC) -o $@ icinfo.o -lmsvfw32 -lkernel32 $(ALL_LIBS)
 
-aviinfo: aviinfo.exe.so
-	$(RM) aviinfo && $(LN_S) $(TOPOBJDIR)/wine aviinfo
+$(PROGRAMS:.exe=): $(WINEWRAPPER)
+	$(RM) $@ && $(LN_S) $(WINEWRAPPER) $@
 
-aviplay: aviplay.exe.so
-	$(RM) aviplay && $(LN_S) $(TOPOBJDIR)/wine aviplay
+# Rules for installation
 
-icinfo: icinfo.exe.so
-	$(RM) icinfo && $(LN_S) $(TOPOBJDIR)/wine icinfo
+.PHONY: install_prog install_prog.so uninstall_prog uninstall_prog.so
 
-.PHONY: install_prog install_prog.so
+install_prog.so: $(PROGRAMS:%=%.so)
+	$(MKINSTALLDIRS) $(dlldir)
+	$(INSTALL_PROGRAM) aviinfo.exe.so $(dlldir)/aviinfo.exe.so
+	$(INSTALL_PROGRAM) aviplay.exe.so $(dlldir)/aviplay.exe.so
+	$(INSTALL_PROGRAM) icinfo.exe.so $(dlldir)/icinfo.exe.so
 
-install_prog.so:: $(PROGRAMS:%=%.so)
-	$(MKINSTALLDIRS) $(bindir)
-	$(INSTALL_PROGRAM) aviinfo.exe.so $(bindir)/aviinfo.exe.so
-	$(INSTALL_PROGRAM) aviplay.exe.so $(bindir)/aviplay.exe.so
-	$(INSTALL_PROGRAM) icinfo.exe.so $(bindir)/icinfo.exe.so
-	cd $(bindir) && $(LN_S) wine aviinfo && $(LN_S) wine aviplay && $(LN_S) wine icinfo
-
-install_prog:: $(PROGRAMS)
+install_prog: $(PROGRAMS)
 	$(MKINSTALLDIRS) $(bindir)
 	$(INSTALL_PROGRAM) aviinfo.exe $(bindir)/aviinfo.exe
 	$(INSTALL_PROGRAM) aviplay.exe $(bindir)/aviplay.exe
 	$(INSTALL_PROGRAM) icinfo.exe $(bindir)/icinfo.exe
 
+uninstall_prog.so:
+	$(RM) $(PROGRAMS:%=$(dlldir)/%.so)
+
+uninstall_prog:
+	$(RM) $(PROGRAMS:%=$(bindir)/%)
+
 install:: install_prog$(DLLEXT)
 
-uninstall::
-	$(RM) $(PROGRAMS:%=$(bindir)/%$(DLLEXT)) $(PROGRAMS:%.exe=$(bindir)/%)
+uninstall:: uninstall_prog$(DLLEXT)
+
+clean::
+	$(RM) $(PROGRAMS:.exe=)
+
+# Rules for checking that no imports are missing
+
+CHECKLINK_RPATH = library tsx11 unicode
 
 checklink:: $(PROGRAMS:%=%.so)
-	$(CC) -o checklink $(TOPSRCDIR)/library/checklink.c aviinfo.exe.so && $(RM) checklink
-	$(CC) -o checklink $(TOPSRCDIR)/library/checklink.c aviplay.exe.so && $(RM) checklink
-	$(CC) -o checklink $(TOPSRCDIR)/library/checklink.c icinfo.exe.so && $(RM) checklink
+	$(CC) -o checklink $(CHECKLINK_RPATH:%=-Wl,-rpath,$(TOPOBJDIR)/%) $(TOPSRCDIR)/library/checklink.c aviinfo.exe.so && $(RM) checklink
+	$(CC) -o checklink $(CHECKLINK_RPATH:%=-Wl,-rpath,$(TOPOBJDIR)/%) $(TOPSRCDIR)/library/checklink.c aviplay.exe.so && $(RM) checklink
+	$(CC) -o checklink $(CHECKLINK_RPATH:%=-Wl,-rpath,$(TOPOBJDIR)/%) $(TOPSRCDIR)/library/checklink.c icinfo.exe.so && $(RM) checklink
 
 ### Dependencies:
diff --git a/programs/wineapploader.in b/programs/wineapploader.in
new file mode 100755
index 0000000..2c746f4
--- /dev/null
+++ b/programs/wineapploader.in
@@ -0,0 +1,52 @@
+#!/bin/sh
+#
+# Wrapper script to start a Winelib application once it is installed
+#
+# Copyright (C) 2002 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
+#
+
+# determine the app Winelib library name
+appname=`basename "$0" .exe`.exe
+
+# first try explicit WINELOADER
+if [ -x "$WINELOADER" ]; then exec "$WINELOADER" "$appname" "$@"; fi
+
+# then default bin directory
+if [ -x "@bindir@/wine" ]; then exec "@bindir@/wine" "$appname" "$@"; fi
+
+# now try the directory containing $0
+appdir=""
+case "$0" in
+  */*)
+    # $0 contains a path, use it
+    appdir=`dirname "$0"`
+    ;;
+  *)
+    # no directory in $0, search in PATH
+    saved_ifs=$IFS
+    IFS=:
+    for d in $PATH
+    do
+      IFS=$saved_ifs
+      if [ -x "$d/$0" ]; then appdir="$d"; break; fi
+    done
+    ;;
+esac
+if [ -x "$appdir/wine" ]; then exec "$appdir/wine" "$appname" "$@"; fi
+
+# finally look in PATH
+exec wine "$appname" "$@"
diff --git a/programs/winetest/Makefile.in b/programs/winetest/Makefile.in
index 6ac52dd..04f52f6 100644
--- a/programs/winetest/Makefile.in
+++ b/programs/winetest/Makefile.in
@@ -28,13 +28,6 @@
 wine.c: wine.xs
 	perl $(XSUBPPDIR)/xsubpp -typemap $(XSUBPPDIR)/typemap $(SRCDIR)/wine.xs >wine.c || $(RM) wine.c
 
-install::
-	$(MKINSTALLDIRS) $(libdir)
-	$(INSTALL_DATA) wine.pm $(libdir)/wine.pm
-
-uninstall::
-	$(RM) $(libdir)/wine.pm
-
 clean::
 	$(RM) wine.c
 
diff --git a/programs/winetest/runtest b/programs/winetest/runtest
index 5b3974b..9c6afc4 100755
--- a/programs/winetest/runtest
+++ b/programs/winetest/runtest
@@ -119,11 +119,12 @@
 {
     chop($topobjdir = `cd $topobjdir && pwd`);
     $ENV{LD_LIBRARY_PATH} = $topobjdir . ":" . $ENV{LD_LIBRARY_PATH};
-    $ENV{WINEDLLPATH} = $topobjdir . "/dlls";
+    $ENV{WINEDLLPATH} = $topobjdir . "/dlls:" . $topobjdir . "/programs";
     $ENV{WINESERVER} = $topobjdir . "/server/wineserver";
     $ENV{WINELOADER} = $topobjdir . "/wine";
     $ENV{WINETEST_PLATFORM} = $platform || "wine";
-    $program ||= $topobjdir . "/programs/winetest/winetest";
+    $program ||= "winetest.exe";
+    exec $ENV{WINELOADER}, $program, $infile, @ARGV;
 }
 else
 {
@@ -131,7 +132,7 @@
 }
 
 # and now exec the program
-$program ||= "winetest";
+$program ||= "winetest.exe";
 exec $program, $infile, @ARGV;
 print STDERR "Could not exec $program\n";
 exit 1;
diff --git a/scheduler/client.c b/scheduler/client.c
index c8523ee..aabae96 100644
--- a/scheduler/client.c
+++ b/scheduler/client.c
@@ -488,24 +488,12 @@
                 {
                     strcpy( p, "/wineserver" );
                     execl( path, "wineserver", NULL );
-                    strcpy( p, "/server/wineserver" );
-                    execl( path, "wineserver", NULL );
                 }
-		free(path);
+                free(path);
             }
 
-            /* now try the path */
+            /* finally try the path */
             execlp( "wineserver", "wineserver", NULL );
-
-            /* and finally the current dir */
-            if (!(path = malloc( strlen(oldcwd) + 20 )))
-                fatal_error( "out of memory\n" );
-            p = strcpy( path, oldcwd ) + strlen( oldcwd );
-            strcpy( p, "/wineserver" );
-            execl( path, "wineserver", NULL );
-            strcpy( p, "/server/wineserver" );
-            execl( path, "wineserver", NULL );
-            free(path);
             fatal_error( "could not exec wineserver\n" );
         }
         started = 1;
diff --git a/scheduler/process.c b/scheduler/process.c
index f192f3b..b6e885c 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -36,6 +36,7 @@
 #include "drive.h"
 #include "module.h"
 #include "file.h"
+#include "heap.h"
 #include "thread.h"
 #include "winerror.h"
 #include "wincon.h"
@@ -236,6 +237,118 @@
         proc( uCode, GetCurrentProcessId(), dwFlags, hModule );
 }
 
+
+/***********************************************************************
+ *           get_basename
+ */
+inline static const char *get_basename( const char *name )
+{
+    char *p;
+
+    if ((p = strrchr( name, '/' ))) name = p + 1;
+    if ((p = strrchr( name, '\\' ))) name = p + 1;
+    return name;
+}
+
+
+/***********************************************************************
+ *           open_exe_file
+ *
+ * Open an exe file, taking load order into account.
+ * Returns the file handle or 0 for a builtin exe.
+ */
+static HANDLE open_exe_file( const char *name )
+{
+    enum loadorder_type loadorder[LOADORDER_NTYPES];
+    HANDLE handle;
+    int i;
+
+    SetLastError( ERROR_FILE_NOT_FOUND );
+    MODULE_GetLoadOrder( loadorder, name, TRUE );
+
+    for(i = 0; i < LOADORDER_NTYPES; i++)
+    {
+        if (loadorder[i] == LOADORDER_INVALID) break;
+        switch(loadorder[i])
+        {
+        case LOADORDER_DLL:
+            TRACE( "Trying native exe %s\n", debugstr_a(name) );
+            if ((handle = CreateFileA( name, GENERIC_READ, FILE_SHARE_READ,
+                                       NULL, OPEN_EXISTING, 0, 0 )) != INVALID_HANDLE_VALUE)
+                return handle;
+            if (GetLastError() != ERROR_FILE_NOT_FOUND) return INVALID_HANDLE_VALUE;
+            break;
+        case LOADORDER_BI:
+            TRACE( "Trying built-in exe %s\n", debugstr_a(name) );
+            if (wine_dll_load_main_exe( get_basename(name), NULL, 0, 1 )) return 0;
+            break;
+        default:
+            break;
+        }
+    }
+    return INVALID_HANDLE_VALUE;
+}
+
+
+/***********************************************************************
+ *           find_exe_file
+ *
+ * Open an exe file, and return the full name and file handle.
+ * Returns FALSE if file could not be found.
+ * If file exists but cannot be opened, returns TRUE and set handle to INVALID_HANDLE_VALUE.
+ * If file is a builtin exe, returns TRUE and sets handle to 0.
+ */
+static BOOL find_exe_file( const char *name, char *buffer, int buflen, HANDLE *handle )
+{
+    enum loadorder_type loadorder[LOADORDER_NTYPES];
+    int i;
+
+    TRACE("looking for %s\n", debugstr_a(name) );
+
+    if (SearchPathA( NULL, name, ".exe", buflen, buffer, NULL ))
+    {
+        *handle = open_exe_file( buffer );
+        return TRUE;
+    }
+
+    /* no such file in path, try builtin with .exe extension */
+
+    lstrcpynA( buffer, get_basename(name), buflen );
+    if (!strchr( buffer, '.' ))
+    {
+        char *p = buffer + strlen(buffer);
+        lstrcpynA( p, ".exe", buflen - (p - buffer) );
+    }
+
+    MODULE_GetLoadOrder( loadorder, buffer, TRUE );
+    for (i = 0; i < LOADORDER_NTYPES; i++)
+    {
+        if (loadorder[i] == LOADORDER_BI)
+        {
+            TRACE( "Trying built-in exe %s\n", debugstr_a(buffer) );
+            if (wine_dll_load_main_exe( buffer, NULL, 0, 1 ))
+            {
+                *handle = 0;
+                return TRUE;
+            }
+            break;
+        }
+        if (loadorder[i] == LOADORDER_INVALID) break;
+    }
+
+    /* no builtin found, try native without extension in case it is a Unix app */
+
+    if (SearchPathA( NULL, name, NULL, buflen, buffer, NULL ))
+    {
+        TRACE( "Trying native/Unix binary %s\n", debugstr_a(buffer) );
+        if ((*handle = CreateFileA( buffer, GENERIC_READ, FILE_SHARE_READ,
+                                    NULL, OPEN_EXISTING, 0, 0 )) != INVALID_HANDLE_VALUE)
+            return TRUE;
+    }
+    return FALSE;
+}
+
+
 /***********************************************************************
  *           process_init
  *
@@ -266,16 +379,13 @@
     {
         req->ldt_copy  = &wine_ldt_copy;
         req->ppid      = getppid();
-        wine_server_set_reply( req, main_exe_name, sizeof(main_exe_name)-1 );
         if ((ret = !wine_server_call_err( req )))
         {
-            size_t len = wine_server_reply_size( reply );
-            main_exe_name[len] = 0;
-            main_exe_file      = reply->exe_file;
-            main_create_flags  = reply->create_flags;
-            info_size     = reply->info_size;
-            info          = reply->info;
-            server_startticks               = reply->server_start;
+            main_exe_file     = reply->exe_file;
+            main_create_flags = reply->create_flags;
+            info_size         = reply->info_size;
+            info              = reply->info;
+            server_startticks = reply->server_start;
             current_startupinfo.hStdInput   = reply->hstdin;
             current_startupinfo.hStdOutput  = reply->hstdout;
             current_startupinfo.hStdError   = reply->hstderr;
@@ -419,112 +529,92 @@
 
 
 /***********************************************************************
- *           open_winelib_app
- *
- * Try to open the Winelib app .so file based on argv[0] or WINEPRELOAD.
- */
-void *open_winelib_app( char *argv[] )
-{
-    void *ret = NULL;
-    char *tmp;
-    const char *name;
-    char errStr[100];
-
-    if ((name = getenv( "WINEPRELOAD" )))
-    {
-        if (!(ret = wine_dll_load_main_exe( name, 0, errStr, sizeof(errStr) )))
-        {
-            MESSAGE( "%s: could not load '%s' as specified in the WINEPRELOAD environment variable: %s\n",
-                     argv[0], name, errStr );
-            ExitProcess(1);
-        }
-    }
-    else
-    {
-        const char *argv0 = main_exe_name;
-        if (!*argv0)
-        {
-            /* if argv[0] is "wine", don't try to load anything */
-            argv0 = argv[0];
-            if (!(name = strrchr( argv0, '/' ))) name = argv0;
-            else name++;
-            if (!strcmp( name, "wine" )) return NULL;
-        }
-        /* now try argv[0] with ".so" appended */
-        if ((tmp = HeapAlloc( GetProcessHeap(), 0, strlen(argv0) + 8 )))
-        {
-            strcpy( tmp, argv0 );
-            strcat( tmp, ".exe.so" );
-            /* search in PATH only if there was no '/' in argv[0] */
-            ret = wine_dll_load_main_exe( tmp, (name == argv0), errStr, sizeof(errStr) );
-            if (!ret && !argv[1] && !main_exe_name[0])
-            {
-                /* if no argv[1], this will be better than displaying usage */
-                MESSAGE( "%s: could not load library '%s' as Winelib application: %s\n",
-                         argv[0], tmp, errStr );
-                ExitProcess(1);
-            }
-            HeapFree( GetProcessHeap(), 0, tmp );
-        }
-    }
-    return ret;
-}
-
-/***********************************************************************
  *           PROCESS_InitWine
  *
  * Wine initialisation: load and start the main exe file.
  */
 void PROCESS_InitWine( int argc, char *argv[], LPSTR win16_exe_name, HANDLE *win16_exe_file )
 {
+    char error[100];
     DWORD stack_size = 0;
 
     /* Initialize everything */
     if (!process_init( argv )) exit(1);
 
-    if (open_winelib_app( argv )) goto found; /* try to open argv[0] as a winelib app */
-
     argv++;  /* remove argv[0] (wine itself) */
 
+    TRACE( "starting process name=%s file=%x argv[0]=%s\n",
+           debugstr_a(main_exe_name), main_exe_file, debugstr_a(argv[0]) );
+
     if (!main_exe_name[0])
     {
         if (!argv[0]) OPTIONS_Usage();
 
-        /* open the exe file */
-        if (!SearchPathA( NULL, argv[0], ".exe", sizeof(main_exe_name), main_exe_name, NULL) &&
-            !SearchPathA( NULL, argv[0], NULL, sizeof(main_exe_name), main_exe_name, NULL))
+        if (!find_exe_file( argv[0], main_exe_name, sizeof(main_exe_name), &main_exe_file ))
         {
             MESSAGE( "%s: cannot find '%s'\n", argv0, argv[0] );
-            goto error;
+            ExitProcess(1);
         }
-    }
-
-    if (!main_exe_file)
-    {
-        if ((main_exe_file = CreateFileA( main_exe_name, GENERIC_READ, FILE_SHARE_READ,
-                                          NULL, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE)
+        if (main_exe_file == INVALID_HANDLE_VALUE)
         {
             MESSAGE( "%s: cannot open '%s'\n", argv0, main_exe_name );
-            goto error;
+            ExitProcess(1);
         }
     }
 
-    /* first try Win32 format; this will fail if the file is not a PE binary */
-    if ((current_process.module = PE_LoadImage( main_exe_file, main_exe_name, 0 )))
+    if (!main_exe_file)  /* no file handle -> Winelib app */
     {
-        if (PE_HEADER(current_process.module)->FileHeader.Characteristics & IMAGE_FILE_DLL)
-            ExitProcess( ERROR_BAD_EXE_FORMAT );
-        goto found;
+        TRACE( "starting Winelib app %s\n", debugstr_a(main_exe_name) );
+        if (wine_dll_load_main_exe( get_basename(main_exe_name), error, sizeof(error), 0 ))
+            goto found;
+        MESSAGE( "%s: cannot open builtin library for '%s': %s\n", argv0, main_exe_name, error );
+        ExitProcess(1);
     }
 
-    /* it must be 16-bit or DOS format */
-    NtCurrentTeb()->tibflags &= ~TEBF_WIN32;
-    current_process.flags |= PDB32_WIN16_PROC;
-    strcpy( win16_exe_name, main_exe_name );
-    main_exe_name[0] = 0;
-    *win16_exe_file = main_exe_file;
-    main_exe_file = 0;
-    _EnterWin16Lock();
+    switch( MODULE_GetBinaryType( main_exe_file ))
+    {
+    case BINARY_UNKNOWN:
+        MESSAGE( "%s: cannot determine executable type for '%s'\n", argv0, main_exe_name );
+        ExitProcess(1);
+    case BINARY_PE_EXE:
+        TRACE( "starting Win32 binary %s\n", debugstr_a(main_exe_name) );
+        if ((current_process.module = PE_LoadImage( main_exe_file, main_exe_name, 0 ))) goto found;
+        MESSAGE( "%s: could not load '%s' as Win32 binary\n", argv0, main_exe_name );
+        ExitProcess(1);
+    case BINARY_PE_DLL:
+        MESSAGE( "%s: '%s' is a DLL, not an executable\n", argv0, main_exe_name );
+        ExitProcess(1);
+    case BINARY_WIN16:
+    case BINARY_DOS:
+        TRACE( "starting Win16/DOS binary %s\n", debugstr_a(main_exe_name) );
+        NtCurrentTeb()->tibflags &= ~TEBF_WIN32;
+        current_process.flags |= PDB32_WIN16_PROC;
+        strcpy( win16_exe_name, main_exe_name );
+        main_exe_name[0] = 0;
+        *win16_exe_file = main_exe_file;
+        main_exe_file = 0;
+        _EnterWin16Lock();
+        goto found;
+    case BINARY_OS216:
+        MESSAGE( "%s: '%s' is an OS/2 binary, not supported\n", argv0, main_exe_name );
+        ExitProcess(1);
+    case BINARY_UNIX_EXE:
+        MESSAGE( "%s: '%s' is a Unix binary, not supported\n", argv0, main_exe_name );
+        ExitProcess(1);
+    case BINARY_UNIX_LIB:
+        {
+            DOS_FULL_NAME full_name;
+            const char *name = main_exe_name;
+
+            TRACE( "starting Winelib app %s\n", debugstr_a(main_exe_name) );
+            if (DOSFS_GetFullName( name, TRUE, &full_name )) name = full_name.long_name;
+            CloseHandle( main_exe_file );
+            main_exe_file = 0;
+            if (wine_dlopen( name, RTLD_NOW, error, sizeof(error) )) goto found;
+            MESSAGE( "%s: could not load '%s': %s\n", argv0, main_exe_name, error );
+            ExitProcess(1);
+        }
+    }
 
  found:
     /* build command line */
@@ -680,7 +770,6 @@
         {
             if (memcmp( p, "PATH=", 5 ) &&
                 memcmp( p, "HOME=", 5 ) &&
-                memcmp( p, "WINEPRELOAD=", 12 ) &&
                 memcmp( p, "WINEPREFIX=", 11 )) *envptr++ = (char *)p;
         }
         *envptr = 0;
@@ -734,10 +823,6 @@
         }
     }
     free( argv[0] );
-
-    /* finally try the current directory */
-    argv[0] = "./wine";
-    execve( argv[0], argv, envp );
 }
 
 
@@ -796,43 +881,21 @@
 
 
 /***********************************************************************
- *           PROCESS_Create
+ *           create_process
  *
  * Create a new process. If hFile is a valid handle we have an exe
- * file, and we exec a new copy of wine to load it; otherwise we
- * simply exec the specified filename as a Unix process.
+ * file, otherwise it is a Winelib app.
  */
-BOOL PROCESS_Create( HANDLE hFile, LPCSTR filename, LPSTR cmd_line, LPCSTR env,
-                     LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
-                     BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
-                     LPPROCESS_INFORMATION info, LPCSTR lpCurrentDirectory )
+static BOOL create_process( HANDLE hFile, LPCSTR filename, LPSTR cmd_line, LPCSTR env,
+                            LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
+                            BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
+                            LPPROCESS_INFORMATION info, LPCSTR unixdir )
 {
     BOOL ret;
-    const char *unixfilename = NULL;
-    const char *unixdir = NULL;
-    DOS_FULL_NAME full_dir, full_name;
     HANDLE load_done_evt = 0;
     HANDLE process_info;
     startup_info_t startup_info;
 
-    info->hThread = info->hProcess = 0;
-    info->dwProcessId = info->dwThreadId = 0;
-
-    if (lpCurrentDirectory)
-    {
-        if (DOSFS_GetFullName( lpCurrentDirectory, TRUE, &full_dir ))
-            unixdir = full_dir.long_name;
-    }
-    else
-    {
-        char buf[MAX_PATH];
-        if (GetCurrentDirectoryA(sizeof(buf),buf))
-        {
-            if (DOSFS_GetFullName( buf, TRUE, &full_dir ))
-                unixdir = full_dir.long_name;
-        }
-    }
-
     /* fill the startup info structure */
 
     startup_info.size        = sizeof(startup_info);
@@ -874,20 +937,11 @@
             req->hstderr = GetStdHandle( STD_ERROR_HANDLE );
         }
 
-        if (!hFile)  /* unix process */
-        {
-            unixfilename = filename;
-            if (DOSFS_GetFullName( filename, TRUE, &full_name ))
-                unixfilename = full_name.long_name;
-            nameptr = unixfilename;
-        }
-        else  /* new wine process */
-        {
-            if (GetLongPathNameA( filename, buf, MAX_PATH ))
-                nameptr = buf;
-            else
-                nameptr = filename;
-        }
+        if (GetLongPathNameA( filename, buf, MAX_PATH ))
+            nameptr = buf;
+        else
+            nameptr = filename;
+
         startup_info.filename_len = strlen(nameptr);
         wine_server_add_data( req, &startup_info, sizeof(startup_info) );
         wine_server_add_data( req, nameptr, startup_info.filename_len );
@@ -903,7 +957,7 @@
 
     /* fork and execute */
 
-    if (fork_and_exec( unixfilename, cmd_line, env, unixdir ) == -1)
+    if (fork_and_exec( NULL, cmd_line, env, unixdir ) == -1)
     {
         CloseHandle( process_info );
         return FALSE;
@@ -956,6 +1010,260 @@
 }
 
 
+/*************************************************************************
+ *               get_file_name
+ *
+ * Helper for CreateProcess: retrieve the file name to load from the
+ * app name and command line. Store the file name in buffer, and
+ * return a possibly modified command line.
+ * Also returns a handle to the opened file if it's a Windows binary.
+ */
+static LPSTR get_file_name( LPCSTR appname, LPSTR cmdline, LPSTR buffer,
+                            int buflen, HANDLE *handle )
+{
+    char *name, *pos, *ret = NULL;
+    const char *p;
+
+    /* if we have an app name, everything is easy */
+
+    if (appname)
+    {
+        /* use the unmodified app name as file name */
+        lstrcpynA( buffer, appname, buflen );
+        *handle = open_exe_file( buffer );
+        if (!(ret = cmdline))
+        {
+            /* no command-line, create one */
+            if ((ret = HeapAlloc( GetProcessHeap(), 0, strlen(appname) + 3 )))
+                sprintf( ret, "\"%s\"", appname );
+        }
+        return ret;
+    }
+
+    if (!cmdline)
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return NULL;
+    }
+
+    /* first check for a quoted file name */
+
+    if ((cmdline[0] == '"') && ((p = strchr( cmdline + 1, '"' ))))
+    {
+        int len = p - cmdline - 1;
+        /* extract the quoted portion as file name */
+        if (!(name = HeapAlloc( GetProcessHeap(), 0, len + 1 ))) return NULL;
+        memcpy( name, cmdline + 1, len );
+        name[len] = 0;
+
+        if (find_exe_file( name, buffer, buflen, handle ))
+            ret = cmdline;  /* no change necessary */
+        goto done;
+    }
+
+    /* now try the command-line word by word */
+
+    if (!(name = HeapAlloc( GetProcessHeap(), 0, strlen(cmdline) + 1 ))) return NULL;
+    pos = name;
+    p = cmdline;
+
+    while (*p)
+    {
+        do *pos++ = *p++; while (*p && *p != ' ');
+        *pos = 0;
+        if (find_exe_file( name, buffer, buflen, handle ))
+        {
+            ret = cmdline;
+            break;
+        }
+    }
+
+    if (!ret || !strchr( name, ' ' )) goto done;  /* no change necessary */
+
+    /* now build a new command-line with quotes */
+
+    if (!(ret = HeapAlloc( GetProcessHeap(), 0, strlen(cmdline) + 3 ))) goto done;
+    sprintf( ret, "\"%s\"%s", name, p );
+
+ done:
+    HeapFree( GetProcessHeap(), 0, name );
+    return ret;
+}
+
+
+/**********************************************************************
+ *       CreateProcessA          (KERNEL32.@)
+ */
+BOOL WINAPI CreateProcessA( LPCSTR app_name, LPSTR cmd_line, LPSECURITY_ATTRIBUTES process_attr,
+                            LPSECURITY_ATTRIBUTES thread_attr, BOOL inherit,
+                            DWORD flags, LPVOID env, LPCSTR cur_dir,
+                            LPSTARTUPINFOA startup_info, LPPROCESS_INFORMATION info )
+{
+    BOOL retv = FALSE;
+    HANDLE hFile = 0;
+    const char *unixdir = NULL;
+    DOS_FULL_NAME full_dir;
+    char name[MAX_PATH];
+    LPSTR tidy_cmdline;
+
+    /* Process the AppName and/or CmdLine to get module name and path */
+
+    TRACE("app %s cmdline %s\n", debugstr_a(app_name), debugstr_a(cmd_line) );
+
+    if (!(tidy_cmdline = get_file_name( app_name, cmd_line, name, sizeof(name), &hFile )))
+        return FALSE;
+    if (hFile == INVALID_HANDLE_VALUE) goto done;
+
+    /* Warn if unsupported features are used */
+
+    if (flags & NORMAL_PRIORITY_CLASS)
+        FIXME("(%s,...): NORMAL_PRIORITY_CLASS ignored\n", name);
+    if (flags & IDLE_PRIORITY_CLASS)
+        FIXME("(%s,...): IDLE_PRIORITY_CLASS ignored\n", name);
+    if (flags & HIGH_PRIORITY_CLASS)
+        FIXME("(%s,...): HIGH_PRIORITY_CLASS ignored\n", name);
+    if (flags & REALTIME_PRIORITY_CLASS)
+        FIXME("(%s,...): REALTIME_PRIORITY_CLASS ignored\n", name);
+    if (flags & CREATE_NEW_PROCESS_GROUP)
+        FIXME("(%s,...): CREATE_NEW_PROCESS_GROUP ignored\n", name);
+    if (flags & CREATE_UNICODE_ENVIRONMENT)
+        FIXME("(%s,...): CREATE_UNICODE_ENVIRONMENT ignored\n", name);
+    if (flags & CREATE_SEPARATE_WOW_VDM)
+        FIXME("(%s,...): CREATE_SEPARATE_WOW_VDM ignored\n", name);
+    if (flags & CREATE_SHARED_WOW_VDM)
+        FIXME("(%s,...): CREATE_SHARED_WOW_VDM ignored\n", name);
+    if (flags & CREATE_DEFAULT_ERROR_MODE)
+        FIXME("(%s,...): CREATE_DEFAULT_ERROR_MODE ignored\n", name);
+    if (flags & CREATE_NO_WINDOW)
+        FIXME("(%s,...): CREATE_NO_WINDOW ignored\n", name);
+    if (flags & PROFILE_USER)
+        FIXME("(%s,...): PROFILE_USER ignored\n", name);
+    if (flags & PROFILE_KERNEL)
+        FIXME("(%s,...): PROFILE_KERNEL ignored\n", name);
+    if (flags & PROFILE_SERVER)
+        FIXME("(%s,...): PROFILE_SERVER ignored\n", name);
+    if (startup_info->lpDesktop)
+        FIXME("(%s,...): startup_info->lpDesktop %s ignored\n",
+              name, debugstr_a(startup_info->lpDesktop));
+    if (startup_info->dwFlags & STARTF_RUNFULLSCREEN)
+        FIXME("(%s,...): STARTF_RUNFULLSCREEN ignored\n", name);
+    if (startup_info->dwFlags & STARTF_FORCEONFEEDBACK)
+        FIXME("(%s,...): STARTF_FORCEONFEEDBACK ignored\n", name);
+    if (startup_info->dwFlags & STARTF_FORCEOFFFEEDBACK)
+        FIXME("(%s,...): STARTF_FORCEOFFFEEDBACK ignored\n", name);
+    if (startup_info->dwFlags & STARTF_USEHOTKEY)
+        FIXME("(%s,...): STARTF_USEHOTKEY ignored\n", name);
+
+    if (cur_dir)
+    {
+        if (DOSFS_GetFullName( cur_dir, TRUE, &full_dir ))
+            unixdir = full_dir.long_name;
+    }
+    else
+    {
+        char buf[MAX_PATH];
+        if (GetCurrentDirectoryA(sizeof(buf),buf))
+        {
+            if (DOSFS_GetFullName( buf, TRUE, &full_dir )) unixdir = full_dir.long_name;
+        }
+    }
+
+    info->hThread = info->hProcess = 0;
+    info->dwProcessId = info->dwThreadId = 0;
+
+    /* Determine executable type */
+
+    if (!hFile)  /* builtin exe */
+    {
+        TRACE( "starting %s as Winelib app\n", debugstr_a(name) );
+        retv = create_process( 0, name, tidy_cmdline, env, process_attr, thread_attr,
+                               inherit, flags, startup_info, info, unixdir );
+        goto done;
+    }
+
+    switch( MODULE_GetBinaryType( hFile ))
+    {
+    case BINARY_PE_EXE:
+    case BINARY_WIN16:
+    case BINARY_DOS:
+        TRACE( "starting %s as Windows binary\n", debugstr_a(name) );
+        retv = create_process( hFile, name, tidy_cmdline, env, process_attr, thread_attr,
+                               inherit, flags, startup_info, info, unixdir );
+        break;
+    case BINARY_OS216:
+        FIXME( "%s is OS/2 binary, not supported\n", debugstr_a(name) );
+        SetLastError( ERROR_BAD_EXE_FORMAT );
+        break;
+    case BINARY_PE_DLL:
+        TRACE( "not starting %s since it is a dll\n", debugstr_a(name) );
+        SetLastError( ERROR_BAD_EXE_FORMAT );
+        break;
+    case BINARY_UNIX_LIB:
+        TRACE( "%s is a Unix library, starting as Winelib app\n", debugstr_a(name) );
+        retv = create_process( hFile, name, tidy_cmdline, env, process_attr, thread_attr,
+                               inherit, flags, startup_info, info, unixdir );
+        break;
+    case BINARY_UNIX_EXE:
+    case BINARY_UNKNOWN:
+        {
+            /* unknown file, try as unix executable */
+
+            DOS_FULL_NAME full_name;
+            const char *unixfilename = name;
+
+            TRACE( "starting %s as Unix binary\n", debugstr_a(name) );
+            if (DOSFS_GetFullName( name, TRUE, &full_name )) unixfilename = full_name.long_name;
+            retv = (fork_and_exec( unixfilename, tidy_cmdline, env, unixdir ) != -1);
+        }
+        break;
+    }
+    CloseHandle( hFile );
+
+ done:
+    if (tidy_cmdline != cmd_line) HeapFree( GetProcessHeap(), 0, tidy_cmdline );
+    return retv;
+}
+
+
+/**********************************************************************
+ *       CreateProcessW          (KERNEL32.@)
+ * NOTES
+ *  lpReserved is not converted
+ */
+BOOL WINAPI CreateProcessW( LPCWSTR app_name, LPWSTR cmd_line, LPSECURITY_ATTRIBUTES process_attr,
+                            LPSECURITY_ATTRIBUTES thread_attr, BOOL inherit, DWORD flags,
+                            LPVOID env, LPCWSTR cur_dir, LPSTARTUPINFOW startup_info,
+                            LPPROCESS_INFORMATION info )
+{
+    BOOL ret;
+    STARTUPINFOA StartupInfoA;
+
+    LPSTR app_nameA = HEAP_strdupWtoA (GetProcessHeap(),0,app_name);
+    LPSTR cmd_lineA = HEAP_strdupWtoA (GetProcessHeap(),0,cmd_line);
+    LPSTR cur_dirA = HEAP_strdupWtoA (GetProcessHeap(),0,cur_dir);
+
+    memcpy (&StartupInfoA, startup_info, sizeof(STARTUPINFOA));
+    StartupInfoA.lpDesktop = HEAP_strdupWtoA (GetProcessHeap(),0,startup_info->lpDesktop);
+    StartupInfoA.lpTitle = HEAP_strdupWtoA (GetProcessHeap(),0,startup_info->lpTitle);
+
+    TRACE_(win32)("(%s,%s,...)\n", debugstr_w(app_name), debugstr_w(cmd_line));
+
+    if (startup_info->lpReserved)
+      FIXME_(win32)("StartupInfo.lpReserved is used, please report (%s)\n",
+                    debugstr_w(startup_info->lpReserved));
+
+    ret = CreateProcessA( app_nameA,  cmd_lineA, process_attr, thread_attr,
+                          inherit, flags, env, cur_dirA, &StartupInfoA, info );
+
+    HeapFree( GetProcessHeap(), 0, cur_dirA );
+    HeapFree( GetProcessHeap(), 0, cmd_lineA );
+    HeapFree( GetProcessHeap(), 0, StartupInfoA.lpDesktop );
+    HeapFree( GetProcessHeap(), 0, StartupInfoA.lpTitle );
+
+    return ret;
+}
+
+
 /***********************************************************************
  *           ExitProcess   (KERNEL32.@)
  */
diff --git a/tools/winewrapper b/tools/winewrapper
new file mode 100755
index 0000000..4a44006
--- /dev/null
+++ b/tools/winewrapper
@@ -0,0 +1,92 @@
+#!/bin/sh
+#
+# Wrapper script to run Wine and Winelib apps from inside the source tree
+#
+# Copyright (C) 2002 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
+#
+
+# first determine the directory that contains the app itself
+
+appdir=""
+case "$0" in
+  */*)
+    # $0 contains a path, use it
+    appdir=`dirname "$0"`
+    ;;
+  *)
+    # no directory in $0, search in PATH
+    saved_ifs=$IFS
+    IFS=:
+    for d in $PATH
+    do
+      IFS=$saved_ifs
+      if [ -x "$d/$0" ]
+      then
+        appdir="$d"
+        break
+      fi
+    done
+    ;;
+esac
+
+# now find the top-level directory of the source tree
+
+if [ -x "$appdir/server/wineserver" ]
+then topdir="$appdir"
+elif [ -x "$appdir/../server/wineserver" ]
+then topdir="$appdir/.."
+elif [ -x "$appdir/../../server/wineserver" ]
+then topdir="$appdir/../.."
+elif [ -x "$appdir/../../../server/wineserver" ]
+then topdir="$appdir/../../.."
+else
+  echo "$0: could not locate Wine source tree"
+  exit 1
+fi
+
+# setup the environment
+
+topdir=`cd "$topdir" && pwd`
+
+if [ -n "$LD_LIBRARY_PATH" ]
+then
+  LD_LIBRARY_PATH="$topdir/dlls:$topdir/library:$topdir/unicode:$topdir/tsx11:$LD_LIBRARY_PATH"
+else
+  LD_LIBRARY_PATH="$topdir/dlls:$topdir/library:$topdir/unicode:$topdir/tsx11"
+fi
+WINEDLLPATH="$topdir/dlls:$topdir/programs"
+WINESERVER="$topdir/server/wineserver"
+WINELOADER="$topdir/miscemu/wine"
+export LD_LIBRARY_PATH WINEDLLPATH WINESERVER WINELOADER
+
+# and run the application
+
+case "$0" in
+  wine|*/wine)
+    exec "$WINELOADER" "$@"
+    ;;
+  */*)
+    [ -f "$0.exe.so" ] && exec "$WINELOADER" "$0.exe.so" "$@"
+    echo "$0: cannot find corresponding application"
+    exit 1
+    ;;
+  *)
+    [ -f "$appdir/$0.exe.so" ] && exec "$WINELOADER" "$appdir/$0.exe.so" "$@"
+    echo "$0: cannot find corresponding application"
+    exit 1
+    ;;
+esac
diff --git a/win32/console.c b/win32/console.c
index 274f71b..3b31bf7 100644
--- a/win32/console.c
+++ b/win32/console.c
@@ -82,7 +82,7 @@
     STARTUPINFOA	si;
     PROCESS_INFORMATION	pi;
     HANDLE		hEvent = 0;
-    LPSTR		p, path = NULL;
+    LPSTR		p;
     OBJECT_ATTRIBUTES	attr;
 
     attr.Length                   = sizeof(attr);
@@ -109,55 +109,6 @@
 	ERR("Couldn't launch Wine console from WINECONSOLE env var... trying default access\n");
     }
 
-    /* then the regular installation dir */
-    ret = snprintf(buffer, sizeof(buffer), "%s --use-event=%d", BINDIR "/wineconsole", hEvent);
-    if ((ret > -1) && (ret < sizeof(buffer)) &&
-	CreateProcessA(NULL, buffer, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &si, &pi))
-	goto succeed;
-
-    /* then try the dir where we were started from */
-    if ((path = HeapAlloc(GetProcessHeap(), 0, strlen(full_argv0) + sizeof(buffer))))
-    {
-	int	n;
-
-	if ((p = strrchr(strcpy( path, full_argv0 ), '/')))
-	{
-	    p++;
-	    sprintf(p, "wineconsole --use-event=%d", hEvent);
-	    if (CreateProcessA(NULL, path, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &si, &pi))
-		goto succeed;
-	    sprintf(p, "programs/wineconsole/wineconsole --use-event=%d", hEvent);
-	    if (CreateProcessA(NULL, path, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &si, &pi))
-		goto succeed;
-	}
-
-	n = readlink(full_argv0, buffer, sizeof(buffer));
-	if (n != -1 && n < sizeof(buffer))
-	{
-	    buffer[n] = 0;
-	    if (buffer[0] == '/') /* absolute path ? */
-		strcpy(path, buffer);
-	    else if ((p = strrchr(strcpy( path, full_argv0 ), '/')))
-	    {
-		strcpy(p + 1, buffer);
-	    }
-	    else *path = 0;
-
-	    if ((p = strrchr(path, '/')))
-	    {
-		p++;
-		sprintf(p, "wineconsole --use-event=%d", hEvent);
-		if (CreateProcessA(NULL, path, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &si, &pi))
-		    goto succeed;
-		sprintf(p, "programs/wineconsole/wineconsole --use-event=%d", hEvent);
-		if (CreateProcessA(NULL, path, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &si, &pi))
-		    goto succeed;
-	    }
-	} else perror("readlink");
-
-	HeapFree(GetProcessHeap(), 0, path);	path = NULL;
-    }
-	
     /* then try the regular PATH */
     sprintf(buffer, "wineconsole --use-event=%d\n", hEvent);
     if (CreateProcessA(NULL, buffer, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &si, &pi))
@@ -166,7 +117,6 @@
     goto the_end;
 
  succeed:    
-    if (path) HeapFree(GetProcessHeap(), 0, path);
     if (WaitForSingleObject(hEvent, INFINITE) != WAIT_OBJECT_0) goto the_end;
     CloseHandle(hEvent);
     
@@ -176,7 +126,6 @@
 
  the_end:
     ERR("Can't allocate console\n");
-    if (path) 		HeapFree(GetProcessHeap(), 0, path);
     CloseHandle(hEvent);
     return FALSE;
 }
diff --git a/winedefault.reg b/winedefault.reg
index 630f3cb..86e9888 100644
--- a/winedefault.reg
+++ b/winedefault.reg
@@ -87,7 +87,7 @@
 #
 [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\AeDebug]
 # command line to start a debugger when an exception occurs
-"Debugger"="debugger/winedbg %ld %ld"
+"Debugger"="winedbg %ld %ld"
 # to 0 if a message box has to be presented before running the debugger
 "Auto"="1"