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"