Alexandre Julliard : kernel32: Move current directory initialization to ntdll.
Alexandre Julliard
julliard at winehq.org
Tue Oct 22 16:57:00 CDT 2019
Module: wine
Branch: master
Commit: 305b5a44c57015ff6b981f83c985c85b223058e8
URL: https://source.winehq.org/git/wine.git/?a=commit;h=305b5a44c57015ff6b981f83c985c85b223058e8
Author: Alexandre Julliard <julliard at winehq.org>
Date: Tue Oct 22 09:58:32 2019 +0200
kernel32: Move current directory initialization to ntdll.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/kernel32/process.c | 73 ---------------------------------------
dlls/ntdll/env.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 89 insertions(+), 76 deletions(-)
diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index 5cb470e0c7..a60aad6721 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -1085,78 +1085,6 @@ static BOOL build_command_line( WCHAR **argv )
}
-/***********************************************************************
- * init_current_directory
- *
- * Initialize the current directory from the Unix cwd or the parent info.
- */
-static void init_current_directory( CURDIR *cur_dir )
-{
- UNICODE_STRING dir_str;
- const char *pwd;
- char *cwd;
- int size;
-
- /* if we received a cur dir from the parent, try this first */
-
- if (cur_dir->DosPath.Length)
- {
- if (RtlSetCurrentDirectory_U( &cur_dir->DosPath ) == STATUS_SUCCESS) goto done;
- }
-
- /* now try to get it from the Unix cwd */
-
- for (size = 256; ; size *= 2)
- {
- if (!(cwd = HeapAlloc( GetProcessHeap(), 0, size ))) break;
- if (getcwd( cwd, size )) break;
- HeapFree( 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 ))
- {
- UNICODE_STRING dos_path;
- /* skip the \??\ prefix, nt_name is 0 terminated */
- RtlInitUnicodeString( &dos_path, nt_name.Buffer + 4 );
- RtlSetCurrentDirectory_U( &dos_path );
- RtlFreeUnicodeString( &nt_name );
- }
- }
-
- if (!cur_dir->DosPath.Length) /* still not initialized */
- {
- MESSAGE("Warning: could not find DOS drive for current working directory '%s', "
- "starting in the Windows directory.\n", cwd ? cwd : "" );
- RtlInitUnicodeString( &dir_str, DIR_Windows );
- RtlSetCurrentDirectory_U( &dir_str );
- }
- HeapFree( GetProcessHeap(), 0, cwd );
-
-done:
- TRACE( "starting in %s %p\n", debugstr_w( cur_dir->DosPath.Buffer ), cur_dir->Handle );
-}
-
-
/***********************************************************************
* init_windows_dirs
*/
@@ -1405,7 +1333,6 @@ void * CDECL __wine_kernel_init(void)
}
init_windows_dirs();
- init_current_directory( ¶ms->CurrentDirectory );
set_process_name( __wine_main_argc, __wine_main_argv );
set_library_wargv( __wine_main_argv );
diff --git a/dlls/ntdll/env.c b/dlls/ntdll/env.c
index 724faf0b8f..7b5f370083 100644
--- a/dlls/ntdll/env.c
+++ b/dlls/ntdll/env.c
@@ -21,7 +21,12 @@
#include "config.h"
#include <assert.h>
+#include <errno.h>
#include <stdarg.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
@@ -41,6 +46,8 @@ static WCHAR empty[] = {0};
static const UNICODE_STRING empty_str = { 0, sizeof(empty), empty };
static const UNICODE_STRING null_str = { 0, 0, NULL };
+static const WCHAR windows_dir[] = {'C',':','\\','w','i','n','d','o','w','s',0};
+
static inline SIZE_T get_env_length( const WCHAR *env )
{
const WCHAR *end = env;
@@ -48,6 +55,77 @@ static inline SIZE_T get_env_length( const WCHAR *env )
return end + 1 - env;
}
+/***********************************************************************
+ * get_current_directory
+ *
+ * Initialize the current directory from the Unix cwd.
+ */
+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 */
+ dir->Length = nt_name.Length - 4 * sizeof(WCHAR);
+ memcpy( dir->Buffer, nt_name.Buffer + 4, dir->Length );
+ 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 : "" );
+ dir->Length = strlenW( 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] != '\\')
+ {
+ dir->Buffer[dir->Length / sizeof(WCHAR)] = '\\';
+ dir->Length += sizeof(WCHAR);
+ }
+ dir->Buffer[dir->Length / sizeof(WCHAR)] = 0;
+}
+
+
/******************************************************************************
* NtQuerySystemEnvironmentValue [NTDLL.@]
*/
@@ -554,7 +632,7 @@ void init_user_process_params( SIZE_T data_size )
WCHAR *src;
SIZE_T info_size, env_size;
NTSTATUS status;
- startup_info_t *info;
+ startup_info_t *info = NULL;
RTL_USER_PROCESS_PARAMETERS *params = NULL;
UNICODE_STRING curdir, dllpath, imagepath, cmdline, title, desktop, shellinfo, runtime;
@@ -566,6 +644,8 @@ void init_user_process_params( SIZE_T data_size )
return;
NtCurrentTeb()->Peb->ProcessParameters = params;
+ get_current_directory( ¶ms->CurrentDirectory.DosPath );
+
if (isatty(0) || isatty(1) || isatty(2))
params->ConsoleHandle = (HANDLE)2; /* see kernel32/kernel_private.h */
if (!isatty(0))
@@ -575,7 +655,7 @@ void init_user_process_params( SIZE_T data_size )
if (!isatty(2))
wine_server_fd_to_handle( 2, GENERIC_WRITE|SYNCHRONIZE, OBJ_INHERIT, ¶ms->hStdError );
params->wShowWindow = 1; /* SW_SHOWNORMAL */
- return;
+ goto done;
}
if (!(info = RtlAllocateHeap( GetProcessHeap(), 0, data_size ))) return;
@@ -603,7 +683,6 @@ void init_user_process_params( SIZE_T data_size )
get_unicode_string( &shellinfo, &src, info->shellinfo_len );
get_unicode_string( &runtime, &src, info->runtime_len );
- curdir.MaximumLength = MAX_PATH * sizeof(WCHAR); /* current directory needs more space */
runtime.MaximumLength = runtime.Length; /* runtime info isn't a real string */
if (RtlCreateProcessParametersEx( ¶ms, &imagepath, &dllpath, &curdir, &cmdline, NULL,
@@ -637,6 +716,13 @@ void init_user_process_params( SIZE_T data_size )
done:
RtlFreeHeap( GetProcessHeap(), 0, info );
+ if (RtlSetCurrentDirectory_U( ¶ms->CurrentDirectory.DosPath ))
+ {
+ MESSAGE("wine: could not open working directory %s, starting in the Windows directory.\n",
+ debugstr_w( params->CurrentDirectory.DosPath.Buffer ));
+ RtlInitUnicodeString( &curdir, windows_dir );
+ RtlSetCurrentDirectory_U( &curdir );
+ }
}
More information about the wine-cvs
mailing list