diff --git a/dlls/kernel/Makefile.in b/dlls/kernel/Makefile.in index 27d3842d3cc..843e51ae732 100644 --- a/dlls/kernel/Makefile.in +++ b/dlls/kernel/Makefile.in @@ -18,7 +18,6 @@ SPEC_SRCS16 = \ 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 0605200ffc1..b022f4b6d28 100644 --- a/dlls/kernel/kernel_private.h +++ b/dlls/kernel/kernel_private.h @@ -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); diff --git a/dlls/kernel/process.c b/dlls/kernel/process.c index f85f887c07b..c09b655e05a 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 @@ 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 ); @@ -779,6 +782,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 * @@ -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( ¶ms->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; } diff --git a/files/directory.c b/files/directory.c deleted file mode 100644 index fffb9e852e0..00000000000 --- 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 -#include -#include -#include -#include -#include -#include -#ifdef HAVE_UNISTD_H -# include -#endif -#include -#ifdef HAVE_SYS_ERRNO_H -#include -#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 d6528e1326a..f75f1f441b8 100644 --- a/misc/registry.c +++ b/misc/registry.c @@ -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);