diff --git a/.cvsignore b/.cvsignore index 38068e2268d..bae1588bb54 100644 --- a/.cvsignore +++ b/.cvsignore @@ -4,4 +4,3 @@ autom4te.cache config.cache config.log config.status -wine diff --git a/Make.rules.in b/Make.rules.in index a871b184ed7..676cc272d5e 100644 --- a/Make.rules.in +++ b/Make.rules.in @@ -68,6 +68,7 @@ LINTFLAGS = @LINTFLAGS@ 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 @@ LIBTSX11 = -L$(TOPOBJDIR)/tsx11 -lwine_tsx11 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 @@ LINTS = $(C_SRCS:.c=.ln) $(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 @@ testclean:: $(SUBDIRS:%=%/__testclean__) $(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 @@ $(SUBDIRS:%=%/__test__): dummy @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 @@ $(TESTMAIN): $(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 f5a89ad5aab..7cf7ebfc275 100644 --- a/Makefile.in +++ b/Makefile.in @@ -20,50 +20,33 @@ SRCDIR = @srcdir@ 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 @@ TESTSUBDIRS = \ 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 @@ Make.rules: Make.rules.in configure @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 f1df256b7d8..9829173cb7c 100644 --- a/dlls/Makedll.rules.in +++ b/dlls/Makedll.rules.in @@ -35,14 +35,16 @@ $(MODULE).so: $(ALL_OBJS) Makefile.in # 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 f53a9ea99cc..4a276fbe008 100644 --- a/dlls/x11drv/clipboard.c +++ b/dlls/x11drv/clipboard.c @@ -288,8 +288,6 @@ BOOL X11DRV_CLIPBOARD_LaunchServer() 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 b62d6491b1b..ca851d8e8ea 100644 --- a/documentation/Makefile.in +++ b/documentation/Makefile.in @@ -65,7 +65,7 @@ $(BOOKNAME).ps: $(BOOK_SRCS) 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 4baa1d5d7fa..596682917cf 100644 --- a/documentation/samples/config +++ b/documentation/samples/config @@ -107,6 +107,8 @@ WINE REGISTRY Version 2 "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 1d1b2278d5c..4d31b043585 100644 --- a/documentation/wine.man.in +++ b/documentation/wine.man.in @@ -254,31 +254,30 @@ processes, it is possible to run a number of truly independent .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 @@ The .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 8c5b360b035..1e0146abfd6 100644 --- a/include/module.h +++ b/include/module.h @@ -186,6 +186,19 @@ enum loadorder_type 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 WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD fl 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 @@ extern int BUILTIN32_dlclose( void *handle ); /* 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 8b356128bca..515c4bb8007 100644 --- a/include/wine/library.h +++ b/include/wine/library.h @@ -33,8 +33,7 @@ extern void *wine_dlsym( void *handle, const char *symbol, char *error, int erro 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 10352c4bfb5..60aefe4bed5 100644 --- a/library/loader.c +++ b/library/loader.c @@ -118,7 +118,7 @@ inline static int file_exists( const char *name ) /* 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 @@ static void *dlopen_dll( const char *name, char *error, int errorsize ) 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 @@ void *wine_dll_load( const char *filename, char *error, int errorsize ) return (void *)1; } } - return dlopen_dll( filename, error, errorsize ); + return dlopen_dll( filename, error, errorsize, 0 ); } @@ -393,46 +392,9 @@ void wine_dll_unload( void *handle ) /*********************************************************************** * 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 5d7c3066f01..ad09e2a41aa 100644 --- a/loader/module.c +++ b/loader/module.c @@ -518,10 +518,11 @@ WINE_MODREF *MODULE_FindModule( * 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 @@ static DWORD MODULE_Decide_OS2_OldWin(HANDLE hfile, IMAGE_DOS_HEADER *mz, IMAGE_ 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 @@ good: 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 @@ good: * 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 @@ BOOL WINAPI GetBinaryTypeA( LPCSTR lpApplicationName, LPDWORD lpBinaryType ) /* 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 @@ HINSTANCE WINAPI LoadModule( LPCSTR name, LPVOID paramBlock ) } -/************************************************************************* - * 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 @@ HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags) 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 25613a4affe..1bf52a43217 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 ca523c4290c..7a96f379017 100644 --- a/miscemu/Makefile.in +++ b/miscemu/Makefile.in @@ -3,19 +3,32 @@ TOPSRCDIR = @top_srcdir@ 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 968fe91f6a6..a2bb39512c5 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 76fe18ea1df..acaccfecd58 100644 --- a/programs/Makefile.in +++ b/programs/Makefile.in @@ -4,8 +4,33 @@ SRCDIR = @srcdir@ 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 \ @@ -14,44 +39,71 @@ INSTALLSUBDIRS = \ 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 -check test:: $(SUBDIRS:%=%/__test__) - checklink:: $(SUBDIRS:%=%/__checklink__) +check test:: $(SUBDIRS:%=%/__test__) + +# 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 1abc1acb3c0..9d9615e55c8 100644 --- a/programs/Makeprog.rules.in +++ b/programs/Makeprog.rules.in @@ -32,8 +32,8 @@ $(MODULE).spec.c: $(RC_SRCS:.rc=.res) $(SYMBOLFILE) $(WINEBUILD) $(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 @@ $(MODULE): $(ALL_OBJS) $(RCOBJS) Makefile.in # 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 @@ $(TESTRESULTS): $(MODULE)$(DLLEXT) # 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 4ff4f6fb7ac..2e8cf4554f8 100644 --- a/programs/avitools/Makefile.in +++ b/programs/avitools/Makefile.in @@ -15,25 +15,25 @@ C_SRCS = \ @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 @@ aviplay.exe: aviplay.o 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 00000000000..2c746f47385 --- /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 6ac52dd2580..04f52f6e462 100644 --- a/programs/winetest/Makefile.in +++ b/programs/winetest/Makefile.in @@ -28,13 +28,6 @@ all: wtmain.o 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 5b3974b7d58..9c6afc46ba3 100755 --- a/programs/winetest/runtest +++ b/programs/winetest/runtest @@ -119,11 +119,12 @@ if (defined($topobjdir)) { 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 @@ else } # 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 c8523eeb408..aabae962050 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -488,24 +488,12 @@ static void start_server( const char *oldcwd ) { 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 f192f3bac96..b6e885ce19d 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 @@ void PROCESS_CallUserSignalProc( UINT uCode, HMODULE16 hModule ) 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 @@ static BOOL process_init( char *argv[] ) { 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; @@ -418,58 +528,6 @@ static void start_process(void) } -/*********************************************************************** - * 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 * @@ -477,54 +535,86 @@ void *open_winelib_app( char *argv[] ) */ 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 @@ static char **build_envp( const char *env, const char *extra_env ) { 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 @@ static void exec_wine_binary( char **argv, char **envp ) } } free( argv[0] ); - - /* finally try the current directory */ - argv[0] = "./wine"; - execve( argv[0], argv, envp ); } @@ -796,43 +881,21 @@ static int fork_and_exec( const char *filename, char *cmdline, /*********************************************************************** - * 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 @@ BOOL PROCESS_Create( HANDLE hFile, LPCSTR filename, LPSTR cmd_line, LPCSTR env, 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 @@ BOOL PROCESS_Create( HANDLE hFile, LPCSTR filename, LPSTR cmd_line, LPCSTR env, /* 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 @@ BOOL PROCESS_Create( HANDLE hFile, LPCSTR filename, LPSTR cmd_line, LPCSTR env, } +/************************************************************************* + * 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 00000000000..4a44006618c --- /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 274f71b5457..3b31bf70d1f 100644 --- a/win32/console.c +++ b/win32/console.c @@ -82,7 +82,7 @@ static BOOL start_console_renderer(void) 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 @@ static BOOL start_console_renderer(void) 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 @@ static BOOL start_console_renderer(void) 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 @@ static BOOL start_console_renderer(void) 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 630f3cb4531..86e98887f22 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"