Added support for loading a Winelib app linked as a .so from the wine

launcher, based on the value of argv[0].
oldstable
Alexandre Julliard 2000-11-10 01:38:28 +00:00
parent 70098f6990
commit 591832ec2e
3 changed files with 100 additions and 10 deletions

View File

@ -15,6 +15,7 @@ typedef void (*load_dll_callback_t)( void *, const char * );
extern void wine_dll_set_callback( load_dll_callback_t load );
extern void *wine_dll_load( const char *filename );
extern void *wine_dll_load_main_exe( const char *name, int search_path );
extern void wine_dll_unload( void *handle );
/* debugging */

View File

@ -350,3 +350,53 @@ void wine_dll_unload( void *handle )
if (handle != (void *)1) dlclose( handle );
#endif
}
/***********************************************************************
* wine_dll_load_main_exe
*
* Try to load the .so for the main exe, optionally searching for it in PATH.
*/
void *wine_dll_load_main_exe( const char *name, int search_path )
{
void *ret = NULL;
#ifdef HAVE_DL_API
const char *path = NULL;
if (search_path) path = getenv( "PATH" );
if (!path)
{
/* no path, try only the specified name */
ret = dlopen( name, RTLD_NOW );
}
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 = dlopen( basename - len, RTLD_NOW ))) break;
}
if (!*p) break;
path = p + 1;
}
if (tmp != buffer) free( tmp );
}
}
#endif /* HAVE_DL_API */
return ret;
}

View File

@ -14,6 +14,7 @@
#include <unistd.h>
#include "wine/winbase16.h"
#include "wine/exception.h"
#include "wine/library.h"
#include "process.h"
#include "drive.h"
#include "main.h"
@ -170,6 +171,7 @@ static BOOL process_init( char *argv[] )
/* store the program name */
argv0 = argv[0];
main_exe_argv = argv;
/* Fill the initial process structure */
current_process.exit_code = STILL_ACTIVE;
@ -366,6 +368,41 @@ 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( const char *argv0 )
{
void *ret = NULL;
char *tmp;
const char *name;
if ((name = getenv( "WINEPRELOAD" )))
{
ret = wine_dll_load_main_exe( name, 0 );
}
else
{
/* if argv[0] is "wine", don't try to load anything */
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) + 4 )))
{
strcpy( tmp, argv0 );
strcat( tmp, ".so" );
/* search in PATH only if there was no '/' in argv[0] */
ret = wine_dll_load_main_exe( tmp, (name == argv0) );
HeapFree( GetProcessHeap(), 0, tmp );
}
}
return ret;
}
/***********************************************************************
* PROCESS_InitWine
*
@ -378,6 +415,8 @@ void PROCESS_InitWine( int argc, char *argv[] )
/* Initialize everything */
if (!process_init( argv )) exit(1);
if (open_winelib_app( argv[0] )) goto found; /* try to open argv[0] as a winelib app */
main_exe_argv = ++argv; /* remove argv[0] (wine itself) */
if (!main_exe_name[0])
@ -409,17 +448,18 @@ void PROCESS_InitWine( int argc, char *argv[] )
if (PE_HEADER(main_module)->FileHeader.Characteristics & IMAGE_FILE_DLL)
ExitProcess( ERROR_BAD_EXE_FORMAT );
stack_size = PE_HEADER(main_module)->OptionalHeader.SizeOfStackReserve;
}
else /* it must be 16-bit or DOS format */
{
NtCurrentTeb()->tibflags &= ~TEBF_WIN32;
current_process.flags |= PDB32_WIN16_PROC;
main_exe_name[0] = 0;
CloseHandle( main_exe_file );
main_exe_file = INVALID_HANDLE_VALUE;
SYSLEVEL_EnterWin16Lock();
goto found;
}
/* it must be 16-bit or DOS format */
NtCurrentTeb()->tibflags &= ~TEBF_WIN32;
current_process.flags |= PDB32_WIN16_PROC;
main_exe_name[0] = 0;
CloseHandle( main_exe_file );
main_exe_file = INVALID_HANDLE_VALUE;
SYSLEVEL_EnterWin16Lock();
found:
/* allocate main thread stack */
if (!THREAD_InitStack( NtCurrentTeb(), stack_size, TRUE )) goto error;
@ -439,7 +479,6 @@ void PROCESS_InitWine( int argc, char *argv[] )
void PROCESS_InitWinelib( int argc, char *argv[] )
{
if (!process_init( argv )) exit(1);
main_exe_argv = argv;
/* allocate main thread stack */
if (!THREAD_InitStack( NtCurrentTeb(), 0, TRUE )) ExitProcess( GetLastError() );