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.
This commit is contained in:
parent
df234a9f9f
commit
3536316a31
|
@ -4,4 +4,3 @@ autom4te.cache
|
|||
config.cache
|
||||
config.log
|
||||
config.status
|
||||
wine
|
||||
|
|
|
@ -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
|
||||
|
|
107
Makefile.in
107
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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
530
loader/module.c
530
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 );
|
||||
}
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
Makefile
|
||||
wine
|
||||
wine.spec.c
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
Makefile
|
||||
Makeprog.rules
|
||||
wineapploader
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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" "$@"
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.@)
|
||||
*/
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
Loading…
Reference in New Issue