Commit ad546918 authored by Alexandre Julliard's avatar Alexandre Julliard

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.
parent e83afa73
......@@ -18,7 +18,6 @@ SPEC_SRCS16 = \
windebug.spec
C_SRCS = \
$(TOPOBJDIR)/files/directory.c \
$(TOPOBJDIR)/files/smb.c \
$(TOPOBJDIR)/misc/registry.c \
actctx.c \
......
......@@ -50,8 +50,8 @@ extern HMODULE kernel32_handle;
#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);
......
......@@ -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 @@ static unsigned int server_startticks;
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 comW[] = {'.','c','o','m',0};
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 @@ done:
/***********************************************************************
* 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 @@ static BOOL process_init( char *argv[], char **environ )
/* Create device symlinks */
VOLUME_CreateDevices();
/* initialise DOS directories */
if (!DIR_Init()) return FALSE;
init_current_directory( &params->CurrentDirectory );
/* registry initialisation */
......@@ -894,6 +945,8 @@ static BOOL process_init( char *argv[], char **environ )
if (!info_size) set_registry_environment();
init_windows_dirs();
return TRUE;
}
......
/*
* 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;
}
......@@ -390,7 +390,7 @@ static void _w31_dumptree(unsigned short idx, unsigned char *txt,
/******************************************************************************
* _w31_loadreg [Internal]
*/
static void _w31_loadreg(void)
static void _w31_loadreg( const WCHAR *path )
{
HANDLE hf;
HKEY root;
......@@ -400,7 +400,6 @@ static void _w31_loadreg(void)
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 @@ static void _w31_loadreg(void)
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 @@ static void _load_windows_registry( HKEY hkey_local_machine, HKEY hkey_current_u
}
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 @@ static void convert_drive_types(void)
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 @@ static void convert_drive_types(void)
}
/* 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 @@ void SHELL_LoadRegistry( void )
/* 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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment