Use environment variables instead of config file entries to specify
path, profile, temp, windows and system directories.
Convert existing config file entries to registry values under
HKCU\Environment.
diff --git a/dlls/kernel/Makefile.in b/dlls/kernel/Makefile.in
index 27d3842..843e51a 100644
--- a/dlls/kernel/Makefile.in
+++ b/dlls/kernel/Makefile.in
@@ -18,7 +18,6 @@
windebug.spec
C_SRCS = \
- $(TOPOBJDIR)/files/directory.c \
$(TOPOBJDIR)/files/smb.c \
$(TOPOBJDIR)/misc/registry.c \
actctx.c \
diff --git a/dlls/kernel/kernel_private.h b/dlls/kernel/kernel_private.h
index 0605200..b022f4b 100644
--- a/dlls/kernel/kernel_private.h
+++ b/dlls/kernel/kernel_private.h
@@ -50,8 +50,8 @@
#define DOS_TABLE_SIZE 256
extern HANDLE dos_handles[DOS_TABLE_SIZE];
-extern WCHAR *DIR_Windows;
-extern WCHAR *DIR_System;
+extern const WCHAR *DIR_Windows;
+extern const WCHAR *DIR_System;
extern void PTHREAD_Init(void);
extern BOOL WOWTHUNK_Init(void);
diff --git a/dlls/kernel/process.c b/dlls/kernel/process.c
index f85f887..c09b655 100644
--- a/dlls/kernel/process.c
+++ b/dlls/kernel/process.c
@@ -45,6 +45,7 @@
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(process);
+WINE_DECLARE_DEBUG_CHANNEL(file);
WINE_DECLARE_DEBUG_CHANNEL(server);
WINE_DECLARE_DEBUG_CHANNEL(relay);
@@ -67,6 +68,9 @@
int main_create_flags = 0;
HMODULE kernel32_handle = 0;
+const WCHAR *DIR_Windows = NULL;
+const WCHAR *DIR_System = NULL;
+
/* Process flags */
#define PDB32_DEBUGGED 0x0001 /* Process is being debugged */
#define PDB32_WIN16_PROC 0x0008 /* Win16 process */
@@ -79,7 +83,6 @@
static const WCHAR batW[] = {'.','b','a','t',0};
static const WCHAR winevdmW[] = {'w','i','n','e','v','d','m','.','e','x','e',0};
-extern int DIR_Init(void);
extern void SHELL_LoadRegistry(void);
extern void VOLUME_CreateDevices(void);
extern void VERSION_Init( const WCHAR *appname );
@@ -780,6 +783,57 @@
/***********************************************************************
+ * init_windows_dirs
+ *
+ * Initialize the windows and system directories from the environment.
+ */
+static void init_windows_dirs(void)
+{
+ static const WCHAR windirW[] = {'w','i','n','d','i','r',0};
+ static const WCHAR winsysdirW[] = {'w','i','n','s','y','s','d','i','r',0};
+ static const WCHAR default_windirW[] = {'c',':','\\','w','i','n','d','o','w','s',0};
+ static const WCHAR default_sysdirW[] = {'c',':','\\','w','i','n','d','o','w','s','\\','s','y','s','t','e','m',0};
+
+ DWORD len;
+ WCHAR *buffer;
+
+ if ((len = GetEnvironmentVariableW( windirW, NULL, 0 )))
+ {
+ buffer = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+ GetEnvironmentVariableW( windirW, buffer, len );
+ DIR_Windows = buffer;
+ }
+ else
+ {
+ DIR_Windows = default_windirW;
+ SetEnvironmentVariableW( windirW, DIR_Windows );
+ }
+
+ if ((len = GetEnvironmentVariableW( winsysdirW, NULL, 0 )))
+ {
+ buffer = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+ GetEnvironmentVariableW( winsysdirW, buffer, len );
+ DIR_System = buffer;
+ }
+ else
+ {
+ DIR_System = default_sysdirW;
+ SetEnvironmentVariableW( winsysdirW, DIR_System );
+ }
+
+ if (GetFileAttributesW( DIR_Windows ) == INVALID_FILE_ATTRIBUTES)
+ MESSAGE( "Warning: the specified Windows directory %s is not accessible.\n",
+ debugstr_w(DIR_Windows) );
+ if (GetFileAttributesW( DIR_System ) == INVALID_FILE_ATTRIBUTES)
+ MESSAGE( "Warning: the specified System directory %s is not accessible.\n",
+ debugstr_w(DIR_System) );
+
+ TRACE_(file)( "WindowsDir = %s\n", debugstr_w(DIR_Windows) );
+ TRACE_(file)( "SystemDir = %s\n", debugstr_w(DIR_System) );
+}
+
+
+/***********************************************************************
* process_init
*
* Main process initialisation code
@@ -876,9 +930,6 @@
/* Create device symlinks */
VOLUME_CreateDevices();
- /* initialise DOS directories */
- if (!DIR_Init()) return FALSE;
-
init_current_directory( ¶ms->CurrentDirectory );
/* registry initialisation */
@@ -894,6 +945,8 @@
if (!info_size) set_registry_environment();
+ init_windows_dirs();
+
return TRUE;
}
diff --git a/files/directory.c b/files/directory.c
deleted file mode 100644
index fffb9e8..0000000
--- a/files/directory.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * DOS directories functions
- *
- * Copyright 1995 Alexandre Julliard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "config.h"
-
-#include <ctype.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#include <errno.h>
-#ifdef HAVE_SYS_ERRNO_H
-#include <sys/errno.h>
-#endif
-
-#include "ntstatus.h"
-#include "windef.h"
-#include "winbase.h"
-#include "wine/winbase16.h"
-#include "wingdi.h"
-#include "wine/winuser16.h"
-#include "winerror.h"
-#include "winreg.h"
-#include "winternl.h"
-#include "thread.h"
-#include "wine/unicode.h"
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(dosfs);
-WINE_DECLARE_DEBUG_CHANNEL(file);
-
-#define MAX_PATHNAME_LEN 1024
-
-WCHAR *DIR_Windows = NULL;
-WCHAR *DIR_System = NULL;
-
-/***********************************************************************
- * DIR_GetPath
- *
- * Get a path name from the wine.ini file and make sure it is valid.
- */
-static WCHAR *DIR_GetPath( HKEY hkey, LPCWSTR keyname, LPCWSTR defval, BOOL warn )
-{
- UNICODE_STRING nameW;
- DWORD dummy;
- WCHAR tmp[MAX_PATHNAME_LEN];
- const WCHAR *path;
- const char *mess;
- WCHAR *ret;
- DWORD attr;
-
- RtlInitUnicodeString( &nameW, keyname );
- if (hkey && !NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy ))
- path = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data;
- else
- path = defval;
-
- attr = GetFileAttributesW( path );
- if (attr == INVALID_FILE_ATTRIBUTES) mess = "does not exist";
- else if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) mess = "not a directory";
- else
- {
- DWORD len = GetFullPathNameW( path, 0, NULL, NULL );
- ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
- if (ret) GetFullPathNameW( path, len, ret, NULL );
- return ret;
- }
-
- if (warn)
- {
- MESSAGE("Invalid path %s for %s directory: %s.\n",
- debugstr_w(path), debugstr_w(keyname), mess);
- MESSAGE("Perhaps you have not properly edited your Wine configuration file (%s/config)\n",
- wine_get_config_dir());
- }
- return NULL;
-}
-
-
-/***********************************************************************
- * DIR_Init
- */
-int DIR_Init(void)
-{
- OBJECT_ATTRIBUTES attr;
- UNICODE_STRING nameW;
- HKEY hkey;
- WCHAR longpath[MAX_PATHNAME_LEN];
- WCHAR *tmp_dir, *profile_dir;
- static const WCHAR wineW[] = {'M','a','c','h','i','n','e','\\',
- 'S','o','f','t','w','a','r','e','\\',
- 'W','i','n','e','\\','W','i','n','e','\\',
- 'C','o','n','f','i','g','\\','W','i','n','e',0};
- static const WCHAR windowsW[] = {'w','i','n','d','o','w','s',0};
- static const WCHAR systemW[] = {'s','y','s','t','e','m',0};
- static const WCHAR tempW[] = {'t','e','m','p',0};
- static const WCHAR profileW[] = {'p','r','o','f','i','l','e',0};
- static const WCHAR windows_dirW[] = {'c',':','\\','w','i','n','d','o','w','s',0};
- static const WCHAR system_dirW[] = {'c',':','\\','w','i','n','d','o','w','s','\\','s','y','s','t','e','m',0};
- static const WCHAR temp_dirW[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','m','p',0};
- static const WCHAR pathW[] = {'p','a','t','h',0};
- static const WCHAR path_dirW[] = {'c',':','\\','w','i','n','d','o','w','s',';',
- 'c',':','\\','w','i','n','d','o','w','s','\\','s','y','s','t','e','m',0};
- static const WCHAR path_capsW[] = {'P','A','T','H',0};
- static const WCHAR temp_capsW[] = {'T','E','M','P',0};
- static const WCHAR tmp_capsW[] = {'T','M','P',0};
- static const WCHAR windirW[] = {'w','i','n','d','i','r',0};
- static const WCHAR winsysdirW[] = {'w','i','n','s','y','s','d','i','r',0};
- static const WCHAR userprofileW[] = {'U','S','E','R','P','R','O','F','I','L','E',0};
- static const WCHAR systemrootW[] = {'S','Y','S','T','E','M','R','O','O','T',0};
- static const WCHAR wcmdW[] = {'\\','w','c','m','d','.','e','x','e',0};
- static const WCHAR comspecW[] = {'C','O','M','S','P','E','C',0};
- static const WCHAR empty_strW[] = { 0 };
-
- attr.Length = sizeof(attr);
- attr.RootDirectory = 0;
- attr.ObjectName = &nameW;
- attr.Attributes = 0;
- attr.SecurityDescriptor = NULL;
- attr.SecurityQualityOfService = NULL;
-
- RtlInitUnicodeString( &nameW, wineW );
- if (NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL )) hkey = 0;
-
- if (!(DIR_Windows = DIR_GetPath( hkey, windowsW, windows_dirW, TRUE )) ||
- !(DIR_System = DIR_GetPath( hkey, systemW, system_dirW, TRUE )) ||
- !(tmp_dir = DIR_GetPath( hkey, tempW, temp_dirW, TRUE )))
- {
- if (hkey) NtClose( hkey );
- return 0;
- }
-
- /* Set the environment variables */
-
- /* set COMSPEC only if it doesn't exist already */
- if (!GetEnvironmentVariableW( comspecW, NULL, 0 ))
- {
- strcpyW( longpath, DIR_System );
- strcatW( longpath, wcmdW );
- SetEnvironmentVariableW( comspecW, longpath );
- }
-
- /* set PATH only if not set already */
- if (!GetEnvironmentVariableW( path_capsW, NULL, 0 ))
- {
- WCHAR tmp[MAX_PATHNAME_LEN];
- DWORD dummy;
- const WCHAR *path = path_dirW;
-
- RtlInitUnicodeString( &nameW, pathW );
- if (hkey && !NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation,
- tmp, sizeof(tmp), &dummy ))
- {
- path = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data;
- }
-
- if (strchrW(path, '/'))
- {
- MESSAGE("Fix your wine config (%s/config) to use DOS drive syntax in [wine] 'Path=' statement! (no '/' allowed)\n", wine_get_config_dir() );
- ExitProcess(1);
- }
- SetEnvironmentVariableW( path_capsW, path );
- TRACE("Path = %s\n", debugstr_w(path) );
- }
-
- if (!GetEnvironmentVariableW( temp_capsW, NULL, 0 ))
- SetEnvironmentVariableW( temp_capsW, tmp_dir );
- if (!GetEnvironmentVariableW( tmp_capsW, NULL, 0 ))
- SetEnvironmentVariableW( tmp_capsW, tmp_dir );
-
- SetEnvironmentVariableW( windirW, DIR_Windows );
- SetEnvironmentVariableW( systemrootW, DIR_Windows );
- SetEnvironmentVariableW( winsysdirW, DIR_System );
-
- TRACE("WindowsDir = %s\n", debugstr_w(DIR_Windows) );
- TRACE("SystemDir = %s\n", debugstr_w(DIR_System) );
- TRACE("TempDir = %s\n", debugstr_w(tmp_dir) );
- TRACE("SYSTEMROOT = %s\n", debugstr_w(DIR_Windows) );
-
- HeapFree( GetProcessHeap(), 0, tmp_dir );
-
- if ((profile_dir = DIR_GetPath( hkey, profileW, empty_strW, FALSE )))
- {
- TRACE("USERPROFILE= %s\n", debugstr_w(profile_dir) );
- SetEnvironmentVariableW( userprofileW, profile_dir );
- HeapFree( GetProcessHeap(), 0, profile_dir );
- }
-
- if (hkey) NtClose( hkey );
-
- return 1;
-}
diff --git a/misc/registry.c b/misc/registry.c
index d6528e1..f75f1f4 100644
--- a/misc/registry.c
+++ b/misc/registry.c
@@ -390,7 +390,7 @@
/******************************************************************************
* _w31_loadreg [Internal]
*/
-static void _w31_loadreg(void)
+static void _w31_loadreg( const WCHAR *path )
{
HANDLE hf;
HKEY root;
@@ -400,7 +400,6 @@
struct _w31_tabent* tab = NULL;
unsigned char* txt = NULL;
unsigned int len;
- OFSTRUCT ofs;
ULONG lastmodified;
NTSTATUS status;
IO_STATUS_BLOCK iosb;
@@ -409,8 +408,8 @@
TRACE("(void)\n");
- hf = (HANDLE)OpenFile("reg.dat",&ofs,OF_READ);
- if (hf==(HANDLE)HFILE_ERROR) return;
+ hf = CreateFileW( path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
+ if (hf==INVALID_HANDLE_VALUE) return;
/* read & dump header */
if (NtReadFile(hf, 0, NULL, NULL, &iosb,
@@ -1598,9 +1597,14 @@
}
case REG_WIN31:
+ {
+ static const WCHAR reg_datW[] = {'\\','r','e','g','.','d','a','t',0};
/* FIXME: here we should convert to *.reg file supported by server and call REQ_LOAD_REGISTRY, see REG_WIN95 case */
- _w31_loadreg();
+ strcpyW(path, windir);
+ strcatW(path, reg_datW);
+ _w31_loadreg( path );
break;
+ }
case REG_DONTLOAD:
TRACE("REG_DONTLOAD\n");
@@ -1803,7 +1807,11 @@
RtlInitUnicodeString( &nameW, drive_types_keyW );
if (NtCreateKey( &hkey_new, KEY_ALL_ACCESS, &attr, 0, NULL, 0, &disp )) return;
- if (disp != REG_CREATED_NEW_KEY) return;
+ if (disp != REG_CREATED_NEW_KEY)
+ {
+ NtClose( hkey_new );
+ return;
+ }
for (i = 0; i < 26; i++)
{
@@ -1828,6 +1836,107 @@
}
+/* convert the environment variable entries from the old format to the new one */
+static void convert_environment( HKEY hkey_current_user )
+{
+ static const WCHAR wineW[] = {'M','a','c','h','i','n','e','\\',
+ 'S','o','f','t','w','a','r','e','\\',
+ 'W','i','n','e','\\','W','i','n','e','\\',
+ 'C','o','n','f','i','g','\\','W','i','n','e',0};
+ static const WCHAR windowsW[] = {'w','i','n','d','o','w','s',0};
+ static const WCHAR systemW[] = {'s','y','s','t','e','m',0};
+ static const WCHAR windirW[] = {'w','i','n','d','i','r',0};
+ static const WCHAR winsysdirW[] = {'w','i','n','s','y','s','d','i','r',0};
+ static const WCHAR envW[] = {'E','n','v','i','r','o','n','m','e','n','t',0};
+ static const WCHAR tempW[] = {'T','E','M','P',0};
+ static const WCHAR tmpW[] = {'T','M','P',0};
+ static const WCHAR pathW[] = {'P','A','T','H',0};
+ static const WCHAR profileW[] = {'p','r','o','f','i','l','e',0};
+ static const WCHAR userprofileW[] = {'U','S','E','R','P','R','O','F','I','L','E',0};
+
+ char buffer[1024*sizeof(WCHAR) + sizeof(KEY_VALUE_PARTIAL_INFORMATION)];
+ KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer;
+ OBJECT_ATTRIBUTES attr;
+ UNICODE_STRING nameW;
+ DWORD dummy;
+ ULONG disp;
+ HKEY hkey_old, hkey_env;
+
+ attr.Length = sizeof(attr);
+ attr.RootDirectory = 0;
+ attr.ObjectName = &nameW;
+ attr.Attributes = 0;
+ attr.SecurityDescriptor = NULL;
+ attr.SecurityQualityOfService = NULL;
+ RtlInitUnicodeString( &nameW, wineW );
+
+ if (NtOpenKey( &hkey_old, KEY_ALL_ACCESS, &attr ) != STATUS_SUCCESS) return;
+
+ attr.RootDirectory = hkey_current_user;
+ RtlInitUnicodeString( &nameW, envW );
+ if (NtCreateKey( &hkey_env, KEY_ALL_ACCESS, &attr, 0, NULL, 0, &disp ))
+ {
+ NtClose( hkey_old );
+ return;
+ }
+ if (disp != REG_CREATED_NEW_KEY) goto done;
+
+ /* convert TEMP */
+ RtlInitUnicodeString( &nameW, tempW );
+ if (!NtQueryValueKey( hkey_old, &nameW, KeyValuePartialInformation, buffer, sizeof(buffer), &dummy ))
+ {
+ NtSetValueKey( hkey_env, &nameW, 0, info->Type, info->Data, info->DataLength );
+ RtlInitUnicodeString( &nameW, tmpW );
+ NtSetValueKey( hkey_env, &nameW, 0, info->Type, info->Data, info->DataLength );
+ MESSAGE( "Converted temp dir to new entry HKCU\\Environment \"TEMP\" = %s\n",
+ debugstr_w( (WCHAR*)info->Data ) );
+ }
+
+ /* convert PATH */
+ RtlInitUnicodeString( &nameW, pathW );
+ if (!NtQueryValueKey( hkey_old, &nameW, KeyValuePartialInformation, buffer, sizeof(buffer), &dummy ))
+ {
+ NtSetValueKey( hkey_env, &nameW, 0, info->Type, info->Data, info->DataLength );
+ MESSAGE( "Converted path dir to new entry HKCU\\Environment \"PATH\" = %s\n",
+ debugstr_w( (WCHAR*)info->Data ) );
+ }
+
+ /* convert USERPROFILE */
+ RtlInitUnicodeString( &nameW, profileW );
+ if (!NtQueryValueKey( hkey_old, &nameW, KeyValuePartialInformation, buffer, sizeof(buffer), &dummy ))
+ {
+ RtlInitUnicodeString( &nameW, userprofileW );
+ NtSetValueKey( hkey_env, &nameW, 0, info->Type, info->Data, info->DataLength );
+ MESSAGE( "Converted profile dir to new entry HKCU\\Environment \"USERPROFILE\" = %s\n",
+ debugstr_w( (WCHAR*)info->Data ) );
+ }
+
+ /* convert windir */
+ RtlInitUnicodeString( &nameW, windowsW );
+ if (!NtQueryValueKey( hkey_old, &nameW, KeyValuePartialInformation, buffer, sizeof(buffer), &dummy ))
+ {
+ RtlInitUnicodeString( &nameW, windirW );
+ NtSetValueKey( hkey_env, &nameW, 0, info->Type, info->Data, info->DataLength );
+ MESSAGE( "Converted windows dir to new entry HKCU\\Environment \"windir\" = %s\n",
+ debugstr_w( (WCHAR*)info->Data ) );
+ }
+
+ /* convert winsysdir */
+ RtlInitUnicodeString( &nameW, systemW );
+ if (!NtQueryValueKey( hkey_old, &nameW, KeyValuePartialInformation, buffer, sizeof(buffer), &dummy ))
+ {
+ RtlInitUnicodeString( &nameW, winsysdirW );
+ NtSetValueKey( hkey_env, &nameW, 0, info->Type, info->Data, info->DataLength );
+ MESSAGE( "Converted system dir to new entry HKCU\\Environment \"winsysdir\" = %s\n",
+ debugstr_w( (WCHAR*)info->Data ) );
+ }
+
+done:
+ NtClose( hkey_old );
+ NtClose( hkey_env );
+}
+
+
/* load all registry (native and global and home) */
void SHELL_LoadRegistry( void )
{
@@ -1977,6 +2086,7 @@
/* convert keys from config file to new registry format */
convert_drive_types();
+ convert_environment( hkey_current_user );
NtClose(hkey_users_default);
NtClose(hkey_current_user);