Set environment variables from the HKCU\Environment key too.
Moved current directory initialisation to process.c.
Make sure to always pass the correct current directory in the process
parameters for child processes.
diff --git a/dlls/kernel/process.c b/dlls/kernel/process.c
index be7c66a..f85f887 100644
--- a/dlls/kernel/process.c
+++ b/dlls/kernel/process.c
@@ -398,36 +398,20 @@
/***********************************************************************
- * set_registry_environment
+ * set_registry_variables
*
- * Set the environment variables specified in the registry.
+ * Set environment variables by enumerating the values of a key;
+ * helper for set_registry_environment().
*/
-static void set_registry_environment(void)
+static void set_registry_variables( HKEY hkey )
{
- static const WCHAR env_keyW[] = {'M','a','c','h','i','n','e','\\',
- 'S','y','s','t','e','m','\\',
- 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
- 'C','o','n','t','r','o','l','\\',
- 'S','e','s','s','i','o','n',' ','M','a','n','a','g','e','r','\\',
- 'E','n','v','i','r','o','n','m','e','n','t',0};
- OBJECT_ATTRIBUTES attr;
- UNICODE_STRING nameW, env_name, env_value;
+ UNICODE_STRING env_name, env_value;
NTSTATUS status;
- HKEY hkey;
DWORD size;
int index;
char buffer[1024 + sizeof(KEY_VALUE_FULL_INFORMATION)];
KEY_VALUE_FULL_INFORMATION *info = (KEY_VALUE_FULL_INFORMATION *)buffer;
- attr.Length = sizeof(attr);
- attr.RootDirectory = 0;
- attr.ObjectName = &nameW;
- attr.Attributes = 0;
- attr.SecurityDescriptor = NULL;
- attr.SecurityQualityOfService = NULL;
- RtlInitUnicodeString( &nameW, env_keyW );
- if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) != STATUS_SUCCESS) return;
-
for (index = 0; ; index++)
{
status = NtEnumerateValueKey( hkey, index, KeyValueFullInformation,
@@ -443,7 +427,52 @@
env_value.Length--; /* don't count terminating null if any */
RtlSetEnvironmentVariable( NULL, &env_name, &env_value );
}
- NtClose( hkey );
+}
+
+
+/***********************************************************************
+ * set_registry_environment
+ *
+ * Set the environment variables specified in the registry.
+ */
+static void set_registry_environment(void)
+{
+ static const WCHAR env_keyW[] = {'M','a','c','h','i','n','e','\\',
+ 'S','y','s','t','e','m','\\',
+ 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
+ 'C','o','n','t','r','o','l','\\',
+ 'S','e','s','s','i','o','n',' ','M','a','n','a','g','e','r','\\',
+ 'E','n','v','i','r','o','n','m','e','n','t',0};
+ static const WCHAR envW[] = {'E','n','v','i','r','o','n','m','e','n','t',0};
+
+ OBJECT_ATTRIBUTES attr;
+ UNICODE_STRING nameW;
+ HKEY hkey;
+
+ attr.Length = sizeof(attr);
+ attr.RootDirectory = 0;
+ attr.ObjectName = &nameW;
+ attr.Attributes = 0;
+ attr.SecurityDescriptor = NULL;
+ attr.SecurityQualityOfService = NULL;
+
+ /* first the system environment variables */
+ RtlInitUnicodeString( &nameW, env_keyW );
+ if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) == STATUS_SUCCESS)
+ {
+ set_registry_variables( hkey );
+ NtClose( hkey );
+ }
+
+ /* then the ones for the current user */
+ if (RtlOpenCurrentUser( KEY_ALL_ACCESS, (HKEY *)&attr.RootDirectory ) != STATUS_SUCCESS) return;
+ RtlInitUnicodeString( &nameW, envW );
+ if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) == STATUS_SUCCESS)
+ {
+ set_registry_variables( hkey );
+ NtClose( hkey );
+ }
+ NtClose( attr.RootDirectory );
}
@@ -693,6 +722,64 @@
/***********************************************************************
+ * 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;
+ 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;
+ }
+
+ if (cwd)
+ {
+ WCHAR *dirW;
+ int lenW = MultiByteToWideChar( CP_UNIXCP, 0, cwd, -1, NULL, 0 );
+ if ((dirW = HeapAlloc( GetProcessHeap(), 0, lenW * sizeof(WCHAR) )))
+ {
+ MultiByteToWideChar( CP_UNIXCP, 0, cwd, -1, dirW, lenW );
+ RtlInitUnicodeString( &dir_str, dirW );
+ RtlSetCurrentDirectory_U( &dir_str );
+ RtlFreeUnicodeString( &dir_str );
+ }
+ }
+
+ 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 );
+ }
+ if (cwd) HeapFree( GetProcessHeap(), 0, cwd );
+
+done:
+ if (!cur_dir->Handle) chdir("/"); /* change to root directory so as not to lock cdroms */
+ TRACE( "starting in %s %p\n", debugstr_w( cur_dir->DosPath.Buffer ), cur_dir->Handle );
+}
+
+
+/***********************************************************************
* process_init
*
* Main process initialisation code
@@ -746,15 +833,9 @@
wine_server_fd_to_handle( 1, GENERIC_WRITE|SYNCHRONIZE, TRUE, ¶ms->hStdOutput );
wine_server_fd_to_handle( 2, GENERIC_WRITE|SYNCHRONIZE, TRUE, ¶ms->hStdError );
- /* <hack: to be changed later on> */
- params->CurrentDirectory.DosPath.Length = 3 * sizeof(WCHAR);
+ params->CurrentDirectory.DosPath.Length = 0;
params->CurrentDirectory.DosPath.MaximumLength = RtlGetLongestNtPathLength() * sizeof(WCHAR);
params->CurrentDirectory.DosPath.Buffer = RtlAllocateHeap( GetProcessHeap(), 0, params->CurrentDirectory.DosPath.MaximumLength);
- params->CurrentDirectory.DosPath.Buffer[0] = 'C';
- params->CurrentDirectory.DosPath.Buffer[1] = ':';
- params->CurrentDirectory.DosPath.Buffer[2] = '\\';
- params->CurrentDirectory.DosPath.Buffer[3] = '\0';
- /* </hack: to be changed later on> */
}
else
{
@@ -798,6 +879,8 @@
/* initialise DOS directories */
if (!DIR_Init()) return FALSE;
+ init_current_directory( ¶ms->CurrentDirectory );
+
/* registry initialisation */
SHELL_LoadRegistry();
@@ -1215,10 +1298,10 @@
* create_user_params
*/
static RTL_USER_PROCESS_PARAMETERS *create_user_params( LPCWSTR filename, LPCWSTR cmdline,
- const STARTUPINFOW *startup )
+ LPCWSTR cur_dir, const STARTUPINFOW *startup )
{
RTL_USER_PROCESS_PARAMETERS *params;
- UNICODE_STRING image_str, cmdline_str, desktop, title;
+ UNICODE_STRING image_str, cmdline_str, curdir_str, desktop, title;
NTSTATUS status;
WCHAR buffer[MAX_PATH];
@@ -1229,10 +1312,13 @@
RtlInitUnicodeString( &image_str, buffer );
RtlInitUnicodeString( &cmdline_str, cmdline );
+ if (cur_dir) RtlInitUnicodeString( &curdir_str, cur_dir );
if (startup->lpDesktop) RtlInitUnicodeString( &desktop, startup->lpDesktop );
if (startup->lpTitle) RtlInitUnicodeString( &title, startup->lpTitle );
- status = RtlCreateProcessParameters( ¶ms, &image_str, NULL, NULL, &cmdline_str, NULL,
+ status = RtlCreateProcessParameters( ¶ms, &image_str, NULL,
+ cur_dir ? &curdir_str : NULL,
+ &cmdline_str, NULL,
startup->lpTitle ? &title : NULL,
startup->lpDesktop ? &desktop : NULL,
NULL, NULL );
@@ -1266,7 +1352,7 @@
* file, otherwise it is a Winelib app.
*/
static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPWSTR env,
- LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
+ LPCWSTR cur_dir, LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
BOOL inherit, DWORD flags, LPSTARTUPINFOW startup,
LPPROCESS_INFORMATION info, LPCSTR unixdir )
{
@@ -1281,7 +1367,7 @@
if (!env) env = GetEnvironmentStringsW();
- if (!(params = create_user_params( filename, cmd_line, startup )))
+ if (!(params = create_user_params( filename, cmd_line, cur_dir, startup )))
return FALSE;
/* create the synchronization pipes */
@@ -1449,7 +1535,7 @@
*
* Create a new VDM process for a 16-bit or DOS application.
*/
-static BOOL create_vdm_process( LPCWSTR filename, LPWSTR cmd_line, LPWSTR env,
+static BOOL create_vdm_process( LPCWSTR filename, LPWSTR cmd_line, LPWSTR env, LPCWSTR cur_dir,
LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
BOOL inherit, DWORD flags, LPSTARTUPINFOW startup,
LPPROCESS_INFORMATION info, LPCSTR unixdir )
@@ -1466,7 +1552,7 @@
return FALSE;
}
sprintfW( new_cmd_line, argsW, winevdmW, filename, cmd_line );
- ret = create_process( 0, winevdmW, new_cmd_line, env, psa, tsa, inherit,
+ ret = create_process( 0, winevdmW, new_cmd_line, env, cur_dir, psa, tsa, inherit,
flags, startup, info, unixdir );
HeapFree( GetProcessHeap(), 0, new_cmd_line );
return ret;
@@ -1478,10 +1564,10 @@
*
* Create a new cmd shell process for a .BAT file.
*/
-static BOOL create_cmd_process( LPCWSTR filename, LPWSTR cmd_line, LPVOID env,
+static BOOL create_cmd_process( LPCWSTR filename, LPWSTR cmd_line, LPVOID env, LPCWSTR cur_dir,
LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
BOOL inherit, DWORD flags, LPSTARTUPINFOW startup,
- LPPROCESS_INFORMATION info, LPCWSTR cur_dir )
+ LPPROCESS_INFORMATION info )
{
static const WCHAR comspecW[] = {'C','O','M','S','P','E','C',0};
@@ -1695,7 +1781,7 @@
if (!hFile) /* builtin exe */
{
TRACE( "starting %s as Winelib app\n", debugstr_w(name) );
- retv = create_process( 0, name, tidy_cmdline, envW, process_attr, thread_attr,
+ retv = create_process( 0, name, tidy_cmdline, envW, cur_dir, process_attr, thread_attr,
inherit, flags, startup_info, info, unixdir );
goto done;
}
@@ -1704,13 +1790,13 @@
{
case BINARY_PE_EXE:
TRACE( "starting %s as Win32 binary\n", debugstr_w(name) );
- retv = create_process( hFile, name, tidy_cmdline, envW, process_attr, thread_attr,
+ retv = create_process( hFile, name, tidy_cmdline, envW, cur_dir, process_attr, thread_attr,
inherit, flags, startup_info, info, unixdir );
break;
case BINARY_WIN16:
case BINARY_DOS:
TRACE( "starting %s as Win16/DOS binary\n", debugstr_w(name) );
- retv = create_vdm_process( name, tidy_cmdline, envW, process_attr, thread_attr,
+ retv = create_vdm_process( name, tidy_cmdline, envW, cur_dir, process_attr, thread_attr,
inherit, flags, startup_info, info, unixdir );
break;
case BINARY_OS216:
@@ -1723,7 +1809,7 @@
break;
case BINARY_UNIX_LIB:
TRACE( "%s is a Unix library, starting as Winelib app\n", debugstr_w(name) );
- retv = create_process( hFile, name, tidy_cmdline, envW, process_attr, thread_attr,
+ retv = create_process( hFile, name, tidy_cmdline, envW, cur_dir, process_attr, thread_attr,
inherit, flags, startup_info, info, unixdir );
break;
case BINARY_UNKNOWN:
@@ -1733,15 +1819,15 @@
if (!strcmpiW( p, comW ))
{
TRACE( "starting %s as DOS binary\n", debugstr_w(name) );
- retv = create_vdm_process( name, tidy_cmdline, envW, process_attr, thread_attr,
+ retv = create_vdm_process( name, tidy_cmdline, envW, cur_dir, process_attr, thread_attr,
inherit, flags, startup_info, info, unixdir );
break;
}
if (!strcmpiW( p, batW ))
{
TRACE( "starting %s as batch binary\n", debugstr_w(name) );
- retv = create_cmd_process( name, tidy_cmdline, envW, process_attr, thread_attr,
- inherit, flags, startup_info, info, cur_dir );
+ retv = create_cmd_process( name, tidy_cmdline, envW, cur_dir, process_attr, thread_attr,
+ inherit, flags, startup_info, info );
break;
}
}
diff --git a/files/directory.c b/files/directory.c
index 27ecabc..fffb9e8 100644
--- a/files/directory.c
+++ b/files/directory.c
@@ -107,7 +107,6 @@
OBJECT_ATTRIBUTES attr;
UNICODE_STRING nameW;
HKEY hkey;
- char path[MAX_PATHNAME_LEN];
WCHAR longpath[MAX_PATHNAME_LEN];
WCHAR *tmp_dir, *profile_dir;
static const WCHAR wineW[] = {'M','a','c','h','i','n','e','\\',
@@ -153,26 +152,6 @@
return 0;
}
- if (!getcwd( path, MAX_PATHNAME_LEN ))
- {
- MESSAGE("Warning: could not get current Unix working directory, "
- "starting in the Windows directory.\n" );
- SetCurrentDirectoryW( DIR_Windows );
- }
- else
- {
- MultiByteToWideChar( CP_UNIXCP, 0, path, -1, longpath, MAX_PATHNAME_LEN);
- GetFullPathNameW( longpath, MAX_PATHNAME_LEN, longpath, NULL );
- if (!SetCurrentDirectoryW( longpath ))
- {
- MESSAGE("Warning: could not find DOS drive for current working directory '%s', "
- "starting in the Windows directory.\n", path );
- SetCurrentDirectoryW( DIR_Windows );
- }
- else if (!NtCurrentTeb()->Peb->ProcessParameters->CurrentDirectory.Handle)
- chdir("/"); /* change to root directory so as not to lock cdroms */
- }
-
/* Set the environment variables */
/* set COMSPEC only if it doesn't exist already */