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:
Alexandre Julliard 2002-05-22 21:32:49 +00:00
parent df234a9f9f
commit 3536316a31
26 changed files with 993 additions and 823 deletions

View File

@ -4,4 +4,3 @@ autom4te.cache
config.cache
config.log
config.status
wine

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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");

View File

@ -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)

View File

@ -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"

View File

@ -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

View File

@ -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 */

View File

@ -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;

View File

@ -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 );
}

View File

@ -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 );
}

View File

@ -1,2 +1,3 @@
Makefile
wine
wine.spec.c

View File

@ -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:

View File

@ -1,2 +1,3 @@
Makefile
Makeprog.rules
wineapploader

View File

@ -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:

View File

@ -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)

View File

@ -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:

52
programs/wineapploader.in Executable file
View File

@ -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" "$@"

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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.@)
*/

92
tools/winewrapper Executable file
View File

@ -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

View File

@ -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;
}

View File

@ -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"