diff --git a/include/main.h b/include/main.h index 7fd0713612d..d22826fa965 100644 --- a/include/main.h +++ b/include/main.h @@ -7,7 +7,7 @@ #include "windef.h" -extern BOOL MAIN_MainInit( char *argv[] ); +extern BOOL MAIN_MainInit(void); extern void MAIN_WineInit(void); extern int MAIN_GetLanguageID(char*lang, char*country, char*charset, char*dialect); extern void MAIN_ParseDebugOptions(const char *options); diff --git a/include/options.h b/include/options.h index 5df01054e32..550028681ec 100644 --- a/include/options.h +++ b/include/options.h @@ -21,6 +21,7 @@ struct options extern struct options Options; extern const char *argv0; +extern const char *full_argv0; extern void OPTIONS_Usage(void) WINE_NORETURN; extern void OPTIONS_ParseOptions( char *argv[] ); diff --git a/include/process.h b/include/process.h index b98cf9f7f55..37d182a1a73 100644 --- a/include/process.h +++ b/include/process.h @@ -147,7 +147,6 @@ extern DWORD WINAPI MapProcessHandle( HANDLE handle ); extern BOOL ENV_BuildEnvironment(void); /* scheduler/process.c */ -extern BOOL PROCESS_Init(void); extern void PROCESS_InitWine( int argc, char *argv[] ) WINE_NORETURN; extern void PROCESS_InitWinelib( int argc, char *argv[] ) WINE_NORETURN; extern PDB *PROCESS_IdToPDB( DWORD id ); diff --git a/loader/dos/module.c b/loader/dos/module.c index 8acf083a707..aa20c4ca6c5 100644 --- a/loader/dos/module.c +++ b/loader/dos/module.c @@ -432,7 +432,7 @@ BOOL MZ_InitTask( LPDOSTASK lpDosTask ) /* now load dosmod */ /* check argv[0]-derived paths first, since the newest dosmod is most likely there * (at least it was once for Andreas Mohr, so I decided to make it easier for him) */ - fpath=strrchr(strcpy(path,argv0),'/'); + fpath=strrchr(strcpy(path,full_argv0),'/'); if (fpath) { strcpy(fpath,"/dosmod"); execl(path,fname,farg,NULL); diff --git a/loader/main.c b/loader/main.c index ea1a70769f6..44cb3d20c76 100644 --- a/loader/main.c +++ b/loader/main.c @@ -27,16 +27,8 @@ DEFAULT_DEBUG_CHANNEL(server); /*********************************************************************** * Main initialisation routine */ -BOOL MAIN_MainInit( char *argv[] ) +BOOL MAIN_MainInit(void) { - /* store the program name */ - argv0 = argv[0]; - - /* Create the initial process */ - if (!PROCESS_Init()) return FALSE; - - /* Parse command line arguments */ - OPTIONS_ParseOptions( argv ); MAIN_WineInit(); /* Load the configuration file */ diff --git a/misc/options.c b/misc/options.c index d2607349803..9c1b576759b 100644 --- a/misc/options.c +++ b/misc/options.c @@ -40,7 +40,8 @@ struct options Options = NULL /* Alternate config file name */ }; -const char *argv0; +const char *argv0; /* the original argv[0] */ +const char *full_argv0; /* the full path of argv[0] (if known) */ static char *inherit_str; /* options to pass to child processes */ diff --git a/scheduler/client.c b/scheduler/client.c index dbe1af37450..5888975d591 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -459,6 +459,20 @@ int CLIENT_InitServer(void) break; } + /* if argv[0] is a relative path, make it absolute */ + full_argv0 = argv0; + if (oldcwd && argv0[0] != '/' && strchr( argv0, '/' )) + { + char *new_argv0 = malloc( strlen(oldcwd) + strlen(argv0) + 2 ); + if (new_argv0) + { + strcpy( new_argv0, oldcwd ); + strcat( new_argv0, "/" ); + strcat( new_argv0, argv0 ); + full_argv0 = new_argv0; + } + } + /* get the server directory name */ if (gethostname( hostname, sizeof(hostname) ) == -1) fatal_perror( "gethostname" ); configdir = get_config_dir(); diff --git a/scheduler/process.c b/scheduler/process.c index 8aea56c144f..656e81d88b1 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -171,13 +171,18 @@ void PROCESS_CallUserSignalProc( UINT uCode, HMODULE hModule ) /*********************************************************************** - * PROCESS_Init + * process_init + * + * Main process initialisation code */ -BOOL PROCESS_Init(void) +static BOOL process_init( char *argv[] ) { struct init_process_request *req; PDB *pdb = PROCESS_Current(); + /* store the program name */ + argv0 = argv[0]; + /* Fill the initial process structure */ pdb->exit_code = STILL_ACTIVE; pdb->threads = 1; @@ -227,7 +232,10 @@ BOOL PROCESS_Init(void) /* Initialize syslevel handling */ SYSLEVEL_Init(); - return TRUE; + /* Parse command line arguments */ + OPTIONS_ParseOptions( argv ); + + return MAIN_MainInit(); } @@ -396,8 +404,8 @@ static void PROCESS_Start( HMODULE main_module, LPSTR filename ) { /* if no explicit filename, use argv[0] */ if (!(filename = malloc( MAX_PATH ))) ExitProcess(1); - if (!GetFullPathNameA( argv0, MAX_PATH, filename, NULL )) - lstrcpynA( filename, argv0, MAX_PATH ); + if (!GetLongPathNameA( full_argv0, filename, MAX_PATH )) + lstrcpynA( filename, full_argv0, MAX_PATH ); } /* load main module */ @@ -432,7 +440,7 @@ void PROCESS_InitWine( int argc, char *argv[] ) DWORD type; /* Initialize everything */ - if (!MAIN_MainInit( argv )) exit(1); + if (!process_init( argv )) exit(1); main_exe_argv = ++argv; /* remove argv[0] (wine itself) */ @@ -519,7 +527,7 @@ void PROCESS_InitWinelib( int argc, char *argv[] ) { HMODULE main_module; - if (!MAIN_MainInit( argv )) exit(1); + if (!process_init( argv )) exit(1); /* create 32-bit module for main exe */ if (!(main_module = BUILTIN32_LoadExeModule())) ExitProcess( GetLastError() ); @@ -636,11 +644,11 @@ static void exec_wine_binary( char **argv, char **envp ) execve( argv[0], argv, envp ); /* now try the path of argv0 of the current binary */ - if (!(argv[0] = malloc( strlen(argv0) + 6 ))) return; - if ((ptr = strrchr( argv0, '/' ))) + if (!(argv[0] = malloc( strlen(full_argv0) + 6 ))) return; + if ((ptr = strrchr( full_argv0, '/' ))) { - memcpy( argv[0], argv0, ptr - argv0 ); - strcpy( argv[0] + (ptr - argv0), "/wine" ); + memcpy( argv[0], full_argv0, ptr - full_argv0 ); + strcpy( argv[0] + (ptr - full_argv0), "/wine" ); execve( argv[0], argv, envp ); } free( argv[0] ); @@ -781,7 +789,7 @@ BOOL PROCESS_Create( HFILE hFile, LPCSTR filename, LPSTR cmd_line, LPCSTR env, } else /* new wine process */ { - if (!GetFullPathNameA( filename, server_remaining(req->filename), req->filename, NULL )) + if (!GetLongPathNameA( filename, req->filename, server_remaining(req->filename) )) lstrcpynA( req->filename, filename, server_remaining(req->filename) ); } if (server_call( REQ_NEW_PROCESS )) return FALSE;