mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-05 18:01:34 +00:00
Added support for loading a Winelib app linked as a .so from the wine
launcher, based on the value of argv[0].
This commit is contained in:
parent
70098f6990
commit
591832ec2e
3 changed files with 100 additions and 10 deletions
|
@ -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_set_callback( load_dll_callback_t load );
|
||||||
extern void *wine_dll_load( const char *filename );
|
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 );
|
extern void wine_dll_unload( void *handle );
|
||||||
|
|
||||||
/* debugging */
|
/* debugging */
|
||||||
|
|
|
@ -350,3 +350,53 @@ void wine_dll_unload( void *handle )
|
||||||
if (handle != (void *)1) dlclose( handle );
|
if (handle != (void *)1) dlclose( handle );
|
||||||
#endif
|
#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;
|
||||||
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "wine/winbase16.h"
|
#include "wine/winbase16.h"
|
||||||
#include "wine/exception.h"
|
#include "wine/exception.h"
|
||||||
|
#include "wine/library.h"
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
#include "drive.h"
|
#include "drive.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
@ -170,6 +171,7 @@ static BOOL process_init( char *argv[] )
|
||||||
|
|
||||||
/* store the program name */
|
/* store the program name */
|
||||||
argv0 = argv[0];
|
argv0 = argv[0];
|
||||||
|
main_exe_argv = argv;
|
||||||
|
|
||||||
/* Fill the initial process structure */
|
/* Fill the initial process structure */
|
||||||
current_process.exit_code = STILL_ACTIVE;
|
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
|
* PROCESS_InitWine
|
||||||
*
|
*
|
||||||
|
@ -378,6 +415,8 @@ void PROCESS_InitWine( int argc, char *argv[] )
|
||||||
/* Initialize everything */
|
/* Initialize everything */
|
||||||
if (!process_init( argv )) exit(1);
|
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) */
|
main_exe_argv = ++argv; /* remove argv[0] (wine itself) */
|
||||||
|
|
||||||
if (!main_exe_name[0])
|
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)
|
if (PE_HEADER(main_module)->FileHeader.Characteristics & IMAGE_FILE_DLL)
|
||||||
ExitProcess( ERROR_BAD_EXE_FORMAT );
|
ExitProcess( ERROR_BAD_EXE_FORMAT );
|
||||||
stack_size = PE_HEADER(main_module)->OptionalHeader.SizeOfStackReserve;
|
stack_size = PE_HEADER(main_module)->OptionalHeader.SizeOfStackReserve;
|
||||||
|
goto found;
|
||||||
}
|
}
|
||||||
else /* it must be 16-bit or DOS format */
|
|
||||||
{
|
/* it must be 16-bit or DOS format */
|
||||||
NtCurrentTeb()->tibflags &= ~TEBF_WIN32;
|
NtCurrentTeb()->tibflags &= ~TEBF_WIN32;
|
||||||
current_process.flags |= PDB32_WIN16_PROC;
|
current_process.flags |= PDB32_WIN16_PROC;
|
||||||
main_exe_name[0] = 0;
|
main_exe_name[0] = 0;
|
||||||
CloseHandle( main_exe_file );
|
CloseHandle( main_exe_file );
|
||||||
main_exe_file = INVALID_HANDLE_VALUE;
|
main_exe_file = INVALID_HANDLE_VALUE;
|
||||||
SYSLEVEL_EnterWin16Lock();
|
SYSLEVEL_EnterWin16Lock();
|
||||||
}
|
|
||||||
|
|
||||||
|
found:
|
||||||
/* allocate main thread stack */
|
/* allocate main thread stack */
|
||||||
if (!THREAD_InitStack( NtCurrentTeb(), stack_size, TRUE )) goto error;
|
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[] )
|
void PROCESS_InitWinelib( int argc, char *argv[] )
|
||||||
{
|
{
|
||||||
if (!process_init( argv )) exit(1);
|
if (!process_init( argv )) exit(1);
|
||||||
main_exe_argv = argv;
|
|
||||||
|
|
||||||
/* allocate main thread stack */
|
/* allocate main thread stack */
|
||||||
if (!THREAD_InitStack( NtCurrentTeb(), 0, TRUE )) ExitProcess( GetLastError() );
|
if (!THREAD_InitStack( NtCurrentTeb(), 0, TRUE )) ExitProcess( GetLastError() );
|
||||||
|
|
Loading…
Reference in a new issue