ntdll: Move the current directory initialization to the Unix library.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
c1dc5021ac
commit
df5e476487
|
@ -306,58 +306,3 @@ BOOLEAN WINAPI RtlDoesFileExists_U(LPCWSTR file_name)
|
|||
RtlFreeUnicodeString( &nt_name );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* DIR_get_unix_cwd
|
||||
*
|
||||
* Retrieve the Unix name of the current directory; helper for wine_unix_to_nt_file_name.
|
||||
* Returned value must be freed by caller.
|
||||
*/
|
||||
NTSTATUS DIR_get_unix_cwd( char **cwd )
|
||||
{
|
||||
CURDIR *curdir;
|
||||
HANDLE handle;
|
||||
NTSTATUS status;
|
||||
ANSI_STRING name;
|
||||
|
||||
RtlAcquirePebLock();
|
||||
|
||||
if (NtCurrentTeb()->Tib.SubSystemTib) /* FIXME: hack */
|
||||
curdir = &((WIN16_SUBSYSTEM_TIB *)NtCurrentTeb()->Tib.SubSystemTib)->curdir;
|
||||
else
|
||||
curdir = &NtCurrentTeb()->Peb->ProcessParameters->CurrentDirectory;
|
||||
|
||||
if (!(handle = curdir->Handle))
|
||||
{
|
||||
UNICODE_STRING dirW;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
IO_STATUS_BLOCK io;
|
||||
|
||||
if (!RtlDosPathNameToNtPathName_U( curdir->DosPath.Buffer, &dirW, NULL, NULL ))
|
||||
{
|
||||
status = STATUS_OBJECT_NAME_INVALID;
|
||||
goto done;
|
||||
}
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = 0;
|
||||
attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||
attr.ObjectName = &dirW;
|
||||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
|
||||
status = NtOpenFile( &handle, SYNCHRONIZE, &attr, &io, 0,
|
||||
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT );
|
||||
RtlFreeUnicodeString( &dirW );
|
||||
if (status != STATUS_SUCCESS) goto done;
|
||||
}
|
||||
|
||||
status = server_get_unix_name( handle, &name );
|
||||
if (!status) *cwd = name.Buffer;
|
||||
|
||||
if (!curdir->Handle) NtClose( handle );
|
||||
|
||||
done:
|
||||
RtlReleasePebLock();
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -574,69 +574,13 @@ char **build_envp( const WCHAR *envW )
|
|||
*/
|
||||
static void get_current_directory( UNICODE_STRING *dir )
|
||||
{
|
||||
const char *pwd;
|
||||
char *cwd;
|
||||
int size;
|
||||
|
||||
dir->Length = 0;
|
||||
|
||||
/* try to get it from the Unix cwd */
|
||||
|
||||
for (size = 1024; ; size *= 2)
|
||||
{
|
||||
if (!(cwd = RtlAllocateHeap( GetProcessHeap(), 0, size ))) break;
|
||||
if (getcwd( cwd, size )) break;
|
||||
RtlFreeHeap( GetProcessHeap(), 0, cwd );
|
||||
if (errno == ERANGE) continue;
|
||||
cwd = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* try to use PWD if it is valid, so that we don't resolve symlinks */
|
||||
|
||||
pwd = getenv( "PWD" );
|
||||
if (cwd)
|
||||
{
|
||||
struct stat st1, st2;
|
||||
|
||||
if (!pwd || stat( pwd, &st1 ) == -1 ||
|
||||
(!stat( cwd, &st2 ) && (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino)))
|
||||
pwd = cwd;
|
||||
}
|
||||
|
||||
if (pwd)
|
||||
{
|
||||
ANSI_STRING unix_name;
|
||||
UNICODE_STRING nt_name;
|
||||
|
||||
RtlInitAnsiString( &unix_name, pwd );
|
||||
if (!wine_unix_to_nt_file_name( &unix_name, &nt_name ))
|
||||
{
|
||||
/* skip the \??\ prefix */
|
||||
if (nt_name.Length > 6 * sizeof(WCHAR) && nt_name.Buffer[5] == ':')
|
||||
{
|
||||
dir->Length = nt_name.Length - 4 * sizeof(WCHAR);
|
||||
memcpy( dir->Buffer, nt_name.Buffer + 4, dir->Length );
|
||||
}
|
||||
else /* change \??\ to \\?\ */
|
||||
{
|
||||
dir->Length = nt_name.Length;
|
||||
memcpy( dir->Buffer, nt_name.Buffer, dir->Length );
|
||||
dir->Buffer[1] = '\\';
|
||||
}
|
||||
RtlFreeUnicodeString( &nt_name );
|
||||
}
|
||||
}
|
||||
unix_funcs->get_initial_directory( dir );
|
||||
|
||||
if (!dir->Length) /* still not initialized */
|
||||
{
|
||||
MESSAGE("Warning: could not find DOS drive for current working directory '%s', "
|
||||
"starting in the Windows directory.\n", cwd ? cwd : "" );
|
||||
dir->Length = wcslen( windows_dir ) * sizeof(WCHAR);
|
||||
memcpy( dir->Buffer, windows_dir, dir->Length );
|
||||
}
|
||||
RtlFreeHeap( GetProcessHeap(), 0, cwd );
|
||||
|
||||
/* add trailing backslash */
|
||||
if (dir->Buffer[dir->Length / sizeof(WCHAR) - 1] != '\\')
|
||||
{
|
||||
|
@ -1550,6 +1494,5 @@ done:
|
|||
RtlInitUnicodeString( &curdir, windows_dir );
|
||||
RtlSetCurrentDirectory_U( &curdir );
|
||||
}
|
||||
if (!params->CurrentDirectory.Handle) chdir("/"); /* avoid locking removable devices */
|
||||
set_wow64_environment( ¶ms->Environment );
|
||||
}
|
||||
|
|
|
@ -118,7 +118,6 @@ extern const struct unix_funcs *unix_funcs DECLSPEC_HIDDEN;
|
|||
extern NTSTATUS FILE_GetNtStatus(void) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name ) DECLSPEC_HIDDEN;
|
||||
extern void init_directories(void) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS DIR_get_unix_cwd( char **cwd ) DECLSPEC_HIDDEN;
|
||||
extern unsigned int DIR_get_drives_info( struct drive_info info[MAX_DOS_DRIVES] ) DECLSPEC_HIDDEN;
|
||||
|
||||
/* virtual memory */
|
||||
|
|
|
@ -854,6 +854,75 @@ NTSTATUS CDECL get_initial_environment( WCHAR **wargv[], WCHAR *env, SIZE_T *siz
|
|||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* get_initial_directory
|
||||
*
|
||||
* Get the current directory at startup.
|
||||
*/
|
||||
void CDECL get_initial_directory( UNICODE_STRING *dir )
|
||||
{
|
||||
const char *pwd;
|
||||
char *cwd;
|
||||
int size;
|
||||
|
||||
dir->Length = 0;
|
||||
|
||||
/* try to get it from the Unix cwd */
|
||||
|
||||
for (size = 1024; ; size *= 2)
|
||||
{
|
||||
if (!(cwd = malloc( size ))) break;
|
||||
if (getcwd( cwd, size )) break;
|
||||
free( cwd );
|
||||
if (errno == ERANGE) continue;
|
||||
cwd = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* try to use PWD if it is valid, so that we don't resolve symlinks */
|
||||
|
||||
pwd = getenv( "PWD" );
|
||||
if (cwd)
|
||||
{
|
||||
struct stat st1, st2;
|
||||
|
||||
if (!pwd || stat( pwd, &st1 ) == -1 ||
|
||||
(!stat( cwd, &st2 ) && (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino)))
|
||||
pwd = cwd;
|
||||
}
|
||||
|
||||
if (pwd)
|
||||
{
|
||||
ANSI_STRING unix_name;
|
||||
UNICODE_STRING nt_name;
|
||||
|
||||
RtlInitAnsiString( &unix_name, pwd );
|
||||
if (!unix_to_nt_file_name( &unix_name, &nt_name ))
|
||||
{
|
||||
/* skip the \??\ prefix */
|
||||
if (nt_name.Length > 6 * sizeof(WCHAR) && nt_name.Buffer[5] == ':')
|
||||
{
|
||||
dir->Length = nt_name.Length - 4 * sizeof(WCHAR);
|
||||
memcpy( dir->Buffer, nt_name.Buffer + 4, dir->Length );
|
||||
}
|
||||
else /* change \??\ to \\?\ */
|
||||
{
|
||||
dir->Length = nt_name.Length;
|
||||
memcpy( dir->Buffer, nt_name.Buffer, dir->Length );
|
||||
dir->Buffer[1] = '\\';
|
||||
}
|
||||
RtlFreeUnicodeString( &nt_name );
|
||||
}
|
||||
}
|
||||
|
||||
if (!dir->Length) /* still not initialized */
|
||||
MESSAGE("Warning: could not find DOS drive for current working directory '%s', "
|
||||
"starting in the Windows directory.\n", cwd ? cwd : "" );
|
||||
free( cwd );
|
||||
chdir( "/" ); /* avoid locking removable devices */
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* get_unix_codepage
|
||||
*
|
||||
|
|
|
@ -951,6 +951,7 @@ static struct unix_funcs unix_funcs =
|
|||
fast_RtlWakeConditionVariable,
|
||||
get_main_args,
|
||||
get_initial_environment,
|
||||
get_initial_directory,
|
||||
get_paths,
|
||||
get_dll_path,
|
||||
get_unix_codepage,
|
||||
|
|
|
@ -481,18 +481,26 @@ static ULONG get_env_size( const RTL_USER_PROCESS_PARAMETERS *params, char **win
|
|||
/***********************************************************************
|
||||
* get_unix_curdir
|
||||
*/
|
||||
static char *get_unix_curdir( const RTL_USER_PROCESS_PARAMETERS *params )
|
||||
static int get_unix_curdir( const RTL_USER_PROCESS_PARAMETERS *params )
|
||||
{
|
||||
UNICODE_STRING nt_name;
|
||||
ANSI_STRING unix_name;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
IO_STATUS_BLOCK io;
|
||||
NTSTATUS status;
|
||||
HANDLE handle;
|
||||
int fd = -1;
|
||||
|
||||
if (!RtlDosPathNameToNtPathName_U( params->CurrentDirectory.DosPath.Buffer, &nt_name, NULL, NULL ))
|
||||
return NULL;
|
||||
status = nt_to_unix_file_name( &nt_name, &unix_name, FILE_OPEN_IF, FALSE );
|
||||
return -1;
|
||||
InitializeObjectAttributes( &attr, &nt_name, OBJ_CASE_INSENSITIVE, 0, NULL );
|
||||
status = NtOpenFile( &handle, FILE_TRAVERSE | SYNCHRONIZE, &attr, &io,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT );
|
||||
RtlFreeUnicodeString( &nt_name );
|
||||
if (status && status != STATUS_NO_SUCH_FILE) return NULL;
|
||||
return unix_name.Buffer;
|
||||
if (status) return -1;
|
||||
server_handle_to_fd( handle, FILE_TRAVERSE, &fd, NULL );
|
||||
NtClose( handle );
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
|
@ -519,8 +527,8 @@ static void set_stdio_fd( int stdin_fd, int stdout_fd )
|
|||
/***********************************************************************
|
||||
* spawn_process
|
||||
*/
|
||||
NTSTATUS CDECL spawn_process( const RTL_USER_PROCESS_PARAMETERS *params, int socketfd,
|
||||
const char *unixdir, char *winedebug, const pe_image_info_t *pe_info )
|
||||
static NTSTATUS spawn_process( const RTL_USER_PROCESS_PARAMETERS *params, int socketfd,
|
||||
int unixdir, char *winedebug, const pe_image_info_t *pe_info )
|
||||
{
|
||||
const int is_child_64bit = (pe_info->cpu == CPU_x86_64 || pe_info->cpu == CPU_ARM64);
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
|
@ -548,8 +556,11 @@ NTSTATUS CDECL spawn_process( const RTL_USER_PROCESS_PARAMETERS *params, int soc
|
|||
if (stdout_fd != -1) close( stdout_fd );
|
||||
|
||||
if (winedebug) putenv( winedebug );
|
||||
if (unixdir) chdir( unixdir );
|
||||
|
||||
if (unixdir != -1)
|
||||
{
|
||||
fchdir( unixdir );
|
||||
close( unixdir );
|
||||
}
|
||||
argv = build_argv( ¶ms->CommandLine, 2 );
|
||||
|
||||
exec_wineloader( argv, socketfd, is_child_64bit,
|
||||
|
@ -630,7 +641,7 @@ NTSTATUS CDECL exec_process( const UNICODE_STRING *cmdline, const pe_image_info_
|
|||
*
|
||||
* Fork and exec a new Unix binary, checking for errors.
|
||||
*/
|
||||
static NTSTATUS fork_and_exec( UNICODE_STRING *path, const char *unix_dir,
|
||||
static NTSTATUS fork_and_exec( UNICODE_STRING *path, int unixdir,
|
||||
const RTL_USER_PROCESS_PARAMETERS *params )
|
||||
{
|
||||
pid_t pid;
|
||||
|
@ -681,8 +692,11 @@ static NTSTATUS fork_and_exec( UNICODE_STRING *path, const char *unix_dir,
|
|||
|
||||
argv = build_argv( ¶ms->CommandLine, 0 );
|
||||
envp = build_envp( params->Environment );
|
||||
if (unix_dir) chdir( unix_dir );
|
||||
|
||||
if (unixdir != -1)
|
||||
{
|
||||
fchdir( unixdir );
|
||||
close( unixdir );
|
||||
}
|
||||
execve( unix_name.Buffer, argv, envp );
|
||||
}
|
||||
|
||||
|
@ -741,10 +755,10 @@ NTSTATUS WINAPI NtCreateUserProcess( HANDLE *process_handle_ptr, HANDLE *thread_
|
|||
HANDLE file_handle, process_info = 0, process_handle = 0, thread_handle = 0;
|
||||
struct object_attributes *objattr;
|
||||
data_size_t attr_len;
|
||||
char *unixdir = NULL, *winedebug = NULL;
|
||||
char *winedebug = NULL;
|
||||
startup_info_t *startup_info = NULL;
|
||||
ULONG startup_info_size, env_size;
|
||||
int socketfd[2] = { -1, -1 };
|
||||
int unixdir, socketfd[2] = { -1, -1 };
|
||||
pe_image_info_t pe_info;
|
||||
CLIENT_ID id;
|
||||
HANDLE parent = 0, debug = 0, token = 0;
|
||||
|
@ -943,9 +957,9 @@ done:
|
|||
if (process_handle) NtClose( process_handle );
|
||||
if (thread_handle) NtClose( thread_handle );
|
||||
if (socketfd[0] != -1) close( socketfd[0] );
|
||||
if (unixdir != -1) close( unixdir );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, startup_info );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, winedebug );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, unixdir );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@ int CDECL mmap_enum_reserved_areas( int (CDECL *enum_func)(void *base, SIZE_T s
|
|||
int top_down ) DECLSPEC_HIDDEN;
|
||||
extern void CDECL get_main_args( int *argc, char **argv[], char **envp[] ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL get_initial_environment( WCHAR **wargv[], WCHAR *env, SIZE_T *size ) DECLSPEC_HIDDEN;
|
||||
extern void CDECL get_initial_directory( UNICODE_STRING *dir ) DECLSPEC_HIDDEN;
|
||||
extern void CDECL get_unix_codepage( CPTABLEINFO *table ) DECLSPEC_HIDDEN;
|
||||
extern void CDECL get_locales( WCHAR *sys, WCHAR *user ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL virtual_map_section( HANDLE handle, PVOID *addr_ptr, unsigned short zero_bits_64, SIZE_T commit_size,
|
||||
|
|
|
@ -28,7 +28,7 @@ struct ldt_copy;
|
|||
struct msghdr;
|
||||
|
||||
/* increment this when you change the function table */
|
||||
#define NTDLL_UNIXLIB_VERSION 51
|
||||
#define NTDLL_UNIXLIB_VERSION 52
|
||||
|
||||
struct unix_funcs
|
||||
{
|
||||
|
@ -259,6 +259,7 @@ struct unix_funcs
|
|||
/* environment functions */
|
||||
void (CDECL *get_main_args)( int *argc, char **argv[], char **envp[] );
|
||||
NTSTATUS (CDECL *get_initial_environment)( WCHAR **wargv[], WCHAR *env, SIZE_T *size );
|
||||
void (CDECL *get_initial_directory)( UNICODE_STRING *dir );
|
||||
void (CDECL *get_paths)( const char **builddir, const char **datadir, const char **configdir );
|
||||
void (CDECL *get_dll_path)( const char ***paths, SIZE_T *maxlen );
|
||||
void (CDECL *get_unix_codepage)( CPTABLEINFO *table );
|
||||
|
|
Loading…
Reference in New Issue