From 4a334aed3c9a02f9417e76de83b5fb62f3b3751f Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 20 Apr 2005 15:43:36 +0000 Subject: [PATCH] Move all the old config conversion code to a new oldconfig.c file, and get rid of misc/registry.c and the misc directory. --- DEVELOPERS-HINTS | 1 - configure | 5 - configure.ac | 1 - dlls/kernel/Makefile.in | 7 +- misc/registry.c => dlls/kernel/oldconfig.c | 627 ++++++++++++++------- dlls/kernel/process.c | 9 +- dlls/kernel/volume.c | 231 -------- 7 files changed, 415 insertions(+), 466 deletions(-) rename misc/registry.c => dlls/kernel/oldconfig.c (64%) diff --git a/DEVELOPERS-HINTS b/DEVELOPERS-HINTS index f70c4905737..3dacadf7605 100644 --- a/DEVELOPERS-HINTS +++ b/DEVELOPERS-HINTS @@ -247,7 +247,6 @@ Miscellaneous: Note: these directories will ultimately get moved into their respective dlls. - misc/ - KERNEL registry windows/ - USER window management diff --git a/configure b/configure index 35ffd97d06a..a62ac7af448 100755 --- a/configure +++ b/configure @@ -20032,8 +20032,6 @@ esac ac_config_commands="$ac_config_commands include/wine" - ac_config_commands="$ac_config_commands misc" - ac_config_commands="$ac_config_commands programs/regedit/tests" ac_config_commands="$ac_config_commands windows" @@ -20854,7 +20852,6 @@ do "dlls/user/resources" ) CONFIG_COMMANDS="$CONFIG_COMMANDS dlls/user/resources" ;; "dlls/wineps/data" ) CONFIG_COMMANDS="$CONFIG_COMMANDS dlls/wineps/data" ;; "include/wine" ) CONFIG_COMMANDS="$CONFIG_COMMANDS include/wine" ;; - "misc" ) CONFIG_COMMANDS="$CONFIG_COMMANDS misc" ;; "programs/regedit/tests" ) CONFIG_COMMANDS="$CONFIG_COMMANDS programs/regedit/tests" ;; "windows" ) CONFIG_COMMANDS="$CONFIG_COMMANDS windows" ;; "include/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS include/config.h" ;; @@ -21668,8 +21665,6 @@ echo "$as_me: creating dlls/user/resources" >&6;} && mkdir "dlls/user/resources" echo "$as_me: creating dlls/wineps/data" >&6;} && mkdir "dlls/wineps/data") ;; include/wine ) test -d "include/wine" || ({ echo "$as_me:$LINENO: creating include/wine" >&5 echo "$as_me: creating include/wine" >&6;} && mkdir "include/wine") ;; - misc ) test -d "misc" || ({ echo "$as_me:$LINENO: creating misc" >&5 -echo "$as_me: creating misc" >&6;} && mkdir "misc") ;; programs/regedit/tests ) test -d "programs/regedit/tests" || ({ echo "$as_me:$LINENO: creating programs/regedit/tests" >&5 echo "$as_me: creating programs/regedit/tests" >&6;} && mkdir "programs/regedit/tests") ;; windows ) test -d "windows" || ({ echo "$as_me:$LINENO: creating windows" >&5 diff --git a/configure.ac b/configure.ac index 3dfc1f3fe47..6e77d69562b 100644 --- a/configure.ac +++ b/configure.ac @@ -1484,7 +1484,6 @@ WINE_CONFIG_EXTRA_DIR(dlls/user/dde) WINE_CONFIG_EXTRA_DIR(dlls/user/resources) WINE_CONFIG_EXTRA_DIR(dlls/wineps/data) WINE_CONFIG_EXTRA_DIR(include/wine) -WINE_CONFIG_EXTRA_DIR(misc) WINE_CONFIG_EXTRA_DIR(programs/regedit/tests) WINE_CONFIG_EXTRA_DIR(windows) diff --git a/dlls/kernel/Makefile.in b/dlls/kernel/Makefile.in index 1a163f03ac0..d4815330a28 100644 --- a/dlls/kernel/Makefile.in +++ b/dlls/kernel/Makefile.in @@ -17,7 +17,6 @@ SPEC_SRCS16 = \ windebug.spec C_SRCS = \ - $(TOPOBJDIR)/misc/registry.c \ actctx.c \ atom.c \ change.c \ @@ -44,6 +43,7 @@ C_SRCS = \ module.c \ ne_module.c \ ne_segment.c \ + oldconfig.c \ path.c \ powermgnt.c \ process.c \ @@ -91,10 +91,7 @@ MC_SRCS = \ EXTRA_OBJS = $(ASM_SRCS:.s=.o) SUBDIRS = tests -EXTRASUBDIRS = \ - $(TOPOBJDIR)/misc \ - messages \ - nls +EXTRASUBDIRS = messages nls @MAKE_DLL_RULES@ diff --git a/misc/registry.c b/dlls/kernel/oldconfig.c similarity index 64% rename from misc/registry.c rename to dlls/kernel/oldconfig.c index 6afc440cc78..7c18274e42e 100644 --- a/misc/registry.c +++ b/dlls/kernel/oldconfig.c @@ -1,13 +1,7 @@ /* - * Registry Functions + * Support for converting from old configuration format * - * Copyright 1996 Marcus Meissner - * Copyright 1998 Matthew Becker - * Copyright 1999 Sylvain St-Germain - * - * December 21, 1997 - Kevin Cozens - * Fixed bugs in the _w95_loadreg() function. Added extra information - * regarding the format of the Windows '95 registry files. + * Copyright 2005 Alexandre Julliard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,24 +17,16 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * TODO - * Security access - * Option handling - * Time for RegEnumKey*, RegQueryInfoKey* + * NOTES + * This file should be removed after a suitable transition period. */ #include "config.h" #include "wine/port.h" -#include -#include #include +#include #include -#ifdef HAVE_UNISTD_H -# include -#endif -#include -#include #include #include #ifdef HAVE_SYS_IOCTL_H @@ -52,41 +38,40 @@ #define NONAMELESSUNION #define NONAMELESSSTRUCT -#include "ntstatus.h" #include "windef.h" #include "winbase.h" -#include "winerror.h" +#include "winreg.h" +#include "winnls.h" +#include "winternl.h" +#include "ntstatus.h" #include "winioctl.h" #include "ntddscsi.h" - #include "wine/library.h" #include "wine/server.h" #include "wine/unicode.h" - #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(reg); -/****************************************************************************** - * allocate_default_keys [Internal] - * Registry initialisation, allocates some default keys. - */ -static ULONG allocate_default_keys(void) +/* create symlinks for the DOS drives; helper for create_dos_devices */ +static int create_drives( int devices_only ) { - static const WCHAR StatDataW[] = {'D','y','n','D','a','t','a','\\', - 'P','e','r','f','S','t','a','t','s','\\', - 'S','t','a','t','D','a','t','a',0}; - static const WCHAR ConfigManagerW[] = {'D','y','n','D','a','t','a','\\', - 'C','o','n','f','i','g',' ','M','a','n','a','g','e','r','\\', - 'E','n','u','m',0}; - static const WCHAR Clone[] = {'M','a','c','h','i','n','e','\\', - 'S','y','s','t','e','m','\\', - 'C','l','o','n','e',0}; + static const WCHAR PathW[] = {'P','a','t','h',0}; + static const WCHAR DeviceW[] = {'D','e','v','i','c','e',0}; + WCHAR driveW[] = {'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','\\','D','r','i','v','e',' ','A',0}; + const char *config_dir = wine_get_config_dir(); + OBJECT_ATTRIBUTES attr; + UNICODE_STRING nameW; + char tmp[1024*sizeof(WCHAR) + sizeof(KEY_VALUE_PARTIAL_INFORMATION)]; + char dest[1024]; + char *buffer; + WCHAR *p, name[3]; HKEY hkey; - ULONG dispos; - OBJECT_ATTRIBUTES attr; - UNICODE_STRING nameW; + DWORD dummy; + int i, count = 0; attr.Length = sizeof(attr); attr.RootDirectory = 0; @@ -95,178 +80,207 @@ static ULONG allocate_default_keys(void) attr.SecurityDescriptor = NULL; attr.SecurityQualityOfService = NULL; - RtlInitUnicodeString( &nameW, StatDataW ); - if (!NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, &dispos )) NtClose( hkey ); - if (dispos == REG_OPENED_EXISTING_KEY) - return dispos; /* someone else already loaded the registry */ + /* create symlinks for the drive roots */ - RtlInitUnicodeString( &nameW, ConfigManagerW ); - if (!NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL )) NtClose( hkey ); - - /* this key is generated when the nt-core booted successfully */ - RtlInitUnicodeString( &nameW, Clone ); - if (!NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL )) NtClose( hkey ); - - return dispos; -} - - -/****************************************************************** - * init_cdrom_registry - * - * Initializes registry to contain scsi info about the cdrom in NT. - * All devices (even not real scsi ones) have this info in NT. - * TODO: for now it only works for non scsi devices - * NOTE: programs usually read these registry entries after sending the - * IOCTL_SCSI_GET_ADDRESS ioctl to the cdrom - */ -static void init_cdrom_registry( HANDLE handle ) -{ - OBJECT_ATTRIBUTES attr; - UNICODE_STRING nameW; - WCHAR dataW[50]; - DWORD lenW; - char buffer[40]; - DWORD value; - const char *data; - HKEY scsiKey; - HKEY portKey; - HKEY busKey; - HKEY targetKey; - DWORD disp; - IO_STATUS_BLOCK io; - SCSI_ADDRESS scsi_addr; - - if (NtDeviceIoControlFile( handle, 0, NULL, NULL, &io, IOCTL_SCSI_GET_ADDRESS, - NULL, 0, &scsi_addr, sizeof(scsi_addr) )) - return; - - attr.Length = sizeof(attr); - attr.RootDirectory = 0; - attr.ObjectName = &nameW; - attr.Attributes = 0; - attr.SecurityDescriptor = NULL; - attr.SecurityQualityOfService = NULL; - - /* Ensure there is Scsi key */ - if (!RtlCreateUnicodeStringFromAsciiz( &nameW, "Machine\\HARDWARE\\DEVICEMAP\\Scsi" ) || - NtCreateKey( &scsiKey, KEY_ALL_ACCESS, &attr, 0, - NULL, REG_OPTION_VOLATILE, &disp )) + if (!devices_only) for (i = 0; i < 26; i++) { - ERR("Cannot create DEVICEMAP\\Scsi registry key\n" ); - return; - } - RtlFreeUnicodeString( &nameW ); + RtlInitUnicodeString( &nameW, driveW ); + nameW.Buffer[(nameW.Length / sizeof(WCHAR)) - 1] = 'A' + i; + if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) != STATUS_SUCCESS) continue; - snprintf(buffer,sizeof(buffer),"Scsi Port %d",scsi_addr.PortNumber); - attr.RootDirectory = scsiKey; - if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) || - NtCreateKey( &portKey, KEY_ALL_ACCESS, &attr, 0, - NULL, REG_OPTION_VOLATILE, &disp )) - { - ERR("Cannot create DEVICEMAP\\Scsi Port registry key\n" ); - return; - } - RtlFreeUnicodeString( &nameW ); - - RtlCreateUnicodeStringFromAsciiz( &nameW, "Driver" ); - data = "atapi"; - RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data)); - NtSetValueKey( portKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW ); - RtlFreeUnicodeString( &nameW ); - value = 10; - RtlCreateUnicodeStringFromAsciiz( &nameW, "FirstBusTimeScanInMs" ); - NtSetValueKey( portKey,&nameW, 0, REG_DWORD, (BYTE *)&value, sizeof(DWORD)); - RtlFreeUnicodeString( &nameW ); - value = 0; -#ifdef HDIO_GET_DMA - { - int fd, dma; - if (!wine_server_handle_to_fd( handle, 0, &fd, NULL )) + RtlInitUnicodeString( &nameW, PathW ); + if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy )) { - if (ioctl(fd,HDIO_GET_DMA, &dma) != -1) value = dma; - wine_server_release_fd( handle, fd ); + WCHAR path[1024]; + WCHAR *data = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data; + ExpandEnvironmentStringsW( data, path, sizeof(path)/sizeof(WCHAR) ); + + p = path + strlenW(path) - 1; + while ((p > path) && (*p == '/')) *p-- = '\0'; + + name[0] = 'a' + i; + name[1] = ':'; + name[2] = 0; + + if (path[0] != '/') + { + /* relative paths are relative to config dir */ + memmove( path + 3, path, (strlenW(path) + 1) * sizeof(WCHAR) ); + path[0] = '.'; + path[1] = '.'; + path[2] = '/'; + } + if (DefineDosDeviceW( DDD_RAW_TARGET_PATH, name, path )) + { + WideCharToMultiByte(CP_UNIXCP, 0, path, -1, dest, sizeof(dest), NULL, NULL); + MESSAGE( "Created symlink %s/dosdevices/%c: -> %s\n", + wine_get_config_dir(), 'a' + i, dest ); + count++; + } } + NtClose( hkey ); } -#endif - RtlCreateUnicodeStringFromAsciiz( &nameW, "DMAEnabled" ); - NtSetValueKey( portKey,&nameW, 0, REG_DWORD, (BYTE *)&value, sizeof(DWORD)); - RtlFreeUnicodeString( &nameW ); - snprintf(buffer,40,"Scsi Bus %d", scsi_addr.PathId); - attr.RootDirectory = portKey; - if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) || - NtCreateKey( &busKey, KEY_ALL_ACCESS, &attr, 0, - NULL, REG_OPTION_VOLATILE, &disp )) - { - ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus registry key\n" ); - return; - } - RtlFreeUnicodeString( &nameW ); + /* create symlinks for the drive devices */ - attr.RootDirectory = busKey; - if (!RtlCreateUnicodeStringFromAsciiz( &nameW, "Initiator Id 255" ) || - NtCreateKey( &targetKey, KEY_ALL_ACCESS, &attr, 0, - NULL, REG_OPTION_VOLATILE, &disp )) - { - ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus\\Initiator Id 255 registry key\n" ); - return; - } - RtlFreeUnicodeString( &nameW ); - NtClose( targetKey ); + buffer = HeapAlloc( GetProcessHeap(), 0, + strlen(config_dir) + sizeof("/dosdevices/a::") ); + strcpy( buffer, config_dir ); + strcat( buffer, "/dosdevices/a::" ); - snprintf(buffer,40,"Target Id %d", scsi_addr.TargetId); - attr.RootDirectory = busKey; - if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) || - NtCreateKey( &targetKey, KEY_ALL_ACCESS, &attr, 0, - NULL, REG_OPTION_VOLATILE, &disp )) - { - ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus 0\\Target Id registry key\n" ); - return; - } - RtlFreeUnicodeString( &nameW ); - - RtlCreateUnicodeStringFromAsciiz( &nameW, "Type" ); - data = "CdRomPeripheral"; - RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data)); - NtSetValueKey( targetKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW ); - RtlFreeUnicodeString( &nameW ); - /* FIXME - maybe read the real identifier?? */ - RtlCreateUnicodeStringFromAsciiz( &nameW, "Identifier" ); - data = "Wine CDROM"; - RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data)); - NtSetValueKey( targetKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW ); - RtlFreeUnicodeString( &nameW ); - /* FIXME - we always use Cdrom0 - do not know about the nt behaviour */ - RtlCreateUnicodeStringFromAsciiz( &nameW, "DeviceName" ); - data = "Cdrom0"; - RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data)); - NtSetValueKey( targetKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW ); - RtlFreeUnicodeString( &nameW ); - - NtClose( targetKey ); - NtClose( busKey ); - NtClose( portKey ); - NtClose( scsiKey ); -} - - -/* create the hardware registry branch */ -static void create_hardware_branch(void) -{ - int i; - HANDLE handle; - char drive[] = "\\\\.\\A:"; - - /* create entries for cdroms */ for (i = 0; i < 26; i++) { - drive[4] = 'A' + i; - handle = CreateFileA( drive, 0, 0, NULL, OPEN_EXISTING, 0, 0 ); - if (handle == INVALID_HANDLE_VALUE) continue; - init_cdrom_registry( handle ); - CloseHandle( handle ); + RtlInitUnicodeString( &nameW, driveW ); + nameW.Buffer[(nameW.Length / sizeof(WCHAR)) - 1] = 'A' + i; + if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) != STATUS_SUCCESS) continue; + + RtlInitUnicodeString( &nameW, DeviceW ); + if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy )) + { + WCHAR *data = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data; + WideCharToMultiByte(CP_UNIXCP, 0, data, -1, dest, sizeof(dest), NULL, NULL); + + buffer[strlen(buffer) - 3] = 'a' + i; + if (!symlink( dest, buffer )) + { + MESSAGE( "Created symlink %s/dosdevices/%c:: -> %s\n", + wine_get_config_dir(), 'a' + i, dest ); + count++; + } + } + NtClose( hkey ); } + HeapFree( GetProcessHeap(), 0, buffer ); + + return count; +} + + +/* create the device files for the new device naming scheme */ +static void create_dos_devices(void) +{ + const char *config_dir = wine_get_config_dir(); + char *buffer; + int i, count = 0; + + if (!(buffer = HeapAlloc( GetProcessHeap(), 0, + strlen(config_dir) + sizeof("/dosdevices/a::") ))) + return; + + strcpy( buffer, config_dir ); + strcat( buffer, "/dosdevices" ); + + if (!mkdir( buffer, 0777 )) /* we created it, so now create the devices */ + { + HKEY hkey; + DWORD dummy; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING nameW; + WCHAR *p, *devnameW; + char tmp[128]; + WCHAR com[5] = {'C','O','M','1',0}; + WCHAR lpt[5] = {'L','P','T','1',0}; + + static const WCHAR serialportsW[] = {'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','\\', + 'S','e','r','i','a','l','P','o','r','t','s',0}; + static const WCHAR parallelportsW[] = {'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','\\', + 'P','a','r','a','l','l','e','l','P','o','r','t','s',0}; + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = &nameW; + attr.Attributes = 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + RtlInitUnicodeString( &nameW, serialportsW ); + + if (!NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr )) + { + RtlInitUnicodeString( &nameW, com ); + for (i = 1; i <= 9; i++) + { + com[3] = '0' + i; + if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, + tmp, sizeof(tmp), &dummy )) + { + devnameW = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data; + if ((p = strchrW( devnameW, ',' ))) *p = 0; + if (DefineDosDeviceW( DDD_RAW_TARGET_PATH, com, devnameW )) + { + char devname[32]; + WideCharToMultiByte(CP_UNIXCP, 0, devnameW, -1, + devname, sizeof(devname), NULL, NULL); + MESSAGE( "Created symlink %s/dosdevices/com%d -> %s\n", config_dir, i, devname ); + count++; + } + } + } + NtClose( hkey ); + } + + RtlInitUnicodeString( &nameW, parallelportsW ); + if (!NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr )) + { + RtlInitUnicodeString( &nameW, lpt ); + for (i = 1; i <= 9; i++) + { + lpt[3] = '0' + i; + if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, + tmp, sizeof(tmp), &dummy )) + { + devnameW = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data; + if ((p = strchrW( devnameW, ',' ))) *p = 0; + if (DefineDosDeviceW( DDD_RAW_TARGET_PATH, lpt, devnameW )) + { + char devname[32]; + WideCharToMultiByte(CP_UNIXCP, 0, devnameW, -1, + devname, sizeof(devname), NULL, NULL); + MESSAGE( "Created symlink %s/dosdevices/lpt%d -> %s\n", config_dir, i, devname ); + count++; + } + } + } + NtClose( hkey ); + } + count += create_drives( FALSE ); + } + else + { + struct stat st; + int i; + + /* it is possible that the serial/parallel devices have been created but */ + /* not the drives; check for at least one drive symlink to catch that case */ + strcat( buffer, "/a:" ); + for (i = 0; i < 26; i++) + { + buffer[strlen(buffer)-2] = 'a' + i; + if (!lstat( buffer, &st )) break; + } + if (i == 26) count += create_drives( FALSE ); + else + { + strcat( buffer, ":" ); + for (i = 0; i < 26; i++) + { + buffer[strlen(buffer)-3] = 'a' + i; + if (!lstat( buffer, &st )) break; + } + if (i == 26) count += create_drives( TRUE ); + } + } + + if (count) + MESSAGE( "\nYou can now remove the [SerialPorts], [ParallelPorts], and [Drive] sections\n" + "in your configuration file, they are replaced by the above symlinks.\n\n" ); + + HeapFree( GetProcessHeap(), 0, buffer ); } @@ -433,7 +447,7 @@ static void convert_environment( HKEY hkey_current_user ) debugstr_w( (WCHAR*)info->Data ) ); } } - + /* Test for existence of winsysdir */ RtlInitUnicodeString( &nameW, winsysdirW ); if (NtQueryValueKey(hkey_env, &nameW, KeyValuePartialInformation, buffer, sizeof(buffer), &dummy )) @@ -453,15 +467,19 @@ static void convert_environment( HKEY hkey_current_user ) } -/* load all registry (native and global and home) */ -void SHELL_LoadRegistry( void ) +/* registry initialisation, allocates some default keys. */ +static ULONG allocate_default_keys(void) { - HKEY hkey_current_user; + static const WCHAR StatDataW[] = {'D','y','n','D','a','t','a','\\', + 'P','e','r','f','S','t','a','t','s','\\', + 'S','t','a','t','D','a','t','a',0}; + static const WCHAR ConfigManagerW[] = {'D','y','n','D','a','t','a','\\', + 'C','o','n','f','i','g',' ','M','a','n','a','g','e','r','\\', + 'E','n','u','m',0}; + HKEY hkey; + ULONG dispos; OBJECT_ATTRIBUTES attr; UNICODE_STRING nameW; - ULONG dispos; - - TRACE("(void)\n"); attr.Length = sizeof(attr); attr.RootDirectory = 0; @@ -470,14 +488,190 @@ void SHELL_LoadRegistry( void ) attr.SecurityDescriptor = NULL; attr.SecurityQualityOfService = NULL; - dispos = allocate_default_keys(); + RtlInitUnicodeString( &nameW, StatDataW ); + if (!NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, &dispos )) NtClose( hkey ); if (dispos == REG_OPENED_EXISTING_KEY) + return dispos; /* someone else already loaded the registry */ + + RtlInitUnicodeString( &nameW, ConfigManagerW ); + if (!NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL )) NtClose( hkey ); + + return dispos; +} + + +/****************************************************************** + * init_cdrom_registry + * + * Initializes registry to contain scsi info about the cdrom in NT. + * All devices (even not real scsi ones) have this info in NT. + * TODO: for now it only works for non scsi devices + * NOTE: programs usually read these registry entries after sending the + * IOCTL_SCSI_GET_ADDRESS ioctl to the cdrom + */ +static void init_cdrom_registry( HANDLE handle ) +{ + OBJECT_ATTRIBUTES attr; + UNICODE_STRING nameW; + WCHAR dataW[50]; + DWORD lenW; + char buffer[40]; + DWORD value; + const char *data; + HKEY scsiKey; + HKEY portKey; + HKEY busKey; + HKEY targetKey; + DWORD disp; + IO_STATUS_BLOCK io; + SCSI_ADDRESS scsi_addr; + + if (NtDeviceIoControlFile( handle, 0, NULL, NULL, &io, IOCTL_SCSI_GET_ADDRESS, + NULL, 0, &scsi_addr, sizeof(scsi_addr) )) + return; + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = &nameW; + attr.Attributes = 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + + /* Ensure there is Scsi key */ + if (!RtlCreateUnicodeStringFromAsciiz( &nameW, "Machine\\HARDWARE\\DEVICEMAP\\Scsi" ) || + NtCreateKey( &scsiKey, KEY_ALL_ACCESS, &attr, 0, + NULL, REG_OPTION_VOLATILE, &disp )) + { + ERR("Cannot create DEVICEMAP\\Scsi registry key\n" ); + return; + } + RtlFreeUnicodeString( &nameW ); + + snprintf(buffer,sizeof(buffer),"Scsi Port %d",scsi_addr.PortNumber); + attr.RootDirectory = scsiKey; + if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) || + NtCreateKey( &portKey, KEY_ALL_ACCESS, &attr, 0, + NULL, REG_OPTION_VOLATILE, &disp )) + { + ERR("Cannot create DEVICEMAP\\Scsi Port registry key\n" ); + return; + } + RtlFreeUnicodeString( &nameW ); + + RtlCreateUnicodeStringFromAsciiz( &nameW, "Driver" ); + data = "atapi"; + RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data)); + NtSetValueKey( portKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW ); + RtlFreeUnicodeString( &nameW ); + value = 10; + RtlCreateUnicodeStringFromAsciiz( &nameW, "FirstBusTimeScanInMs" ); + NtSetValueKey( portKey,&nameW, 0, REG_DWORD, (BYTE *)&value, sizeof(DWORD)); + RtlFreeUnicodeString( &nameW ); + value = 0; +#ifdef HDIO_GET_DMA + { + int fd, dma; + if (!wine_server_handle_to_fd( handle, 0, &fd, NULL )) + { + if (ioctl(fd,HDIO_GET_DMA, &dma) != -1) value = dma; + wine_server_release_fd( handle, fd ); + } + } +#endif + RtlCreateUnicodeStringFromAsciiz( &nameW, "DMAEnabled" ); + NtSetValueKey( portKey,&nameW, 0, REG_DWORD, (BYTE *)&value, sizeof(DWORD)); + RtlFreeUnicodeString( &nameW ); + + snprintf(buffer,40,"Scsi Bus %d", scsi_addr.PathId); + attr.RootDirectory = portKey; + if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) || + NtCreateKey( &busKey, KEY_ALL_ACCESS, &attr, 0, + NULL, REG_OPTION_VOLATILE, &disp )) + { + ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus registry key\n" ); + return; + } + RtlFreeUnicodeString( &nameW ); + + attr.RootDirectory = busKey; + if (!RtlCreateUnicodeStringFromAsciiz( &nameW, "Initiator Id 255" ) || + NtCreateKey( &targetKey, KEY_ALL_ACCESS, &attr, 0, + NULL, REG_OPTION_VOLATILE, &disp )) + { + ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus\\Initiator Id 255 registry key\n" ); + return; + } + RtlFreeUnicodeString( &nameW ); + NtClose( targetKey ); + + snprintf(buffer,40,"Target Id %d", scsi_addr.TargetId); + attr.RootDirectory = busKey; + if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) || + NtCreateKey( &targetKey, KEY_ALL_ACCESS, &attr, 0, + NULL, REG_OPTION_VOLATILE, &disp )) + { + ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus 0\\Target Id registry key\n" ); + return; + } + RtlFreeUnicodeString( &nameW ); + + RtlCreateUnicodeStringFromAsciiz( &nameW, "Type" ); + data = "CdRomPeripheral"; + RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data)); + NtSetValueKey( targetKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW ); + RtlFreeUnicodeString( &nameW ); + /* FIXME - maybe read the real identifier?? */ + RtlCreateUnicodeStringFromAsciiz( &nameW, "Identifier" ); + data = "Wine CDROM"; + RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data)); + NtSetValueKey( targetKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW ); + RtlFreeUnicodeString( &nameW ); + /* FIXME - we always use Cdrom0 - do not know about the nt behaviour */ + RtlCreateUnicodeStringFromAsciiz( &nameW, "DeviceName" ); + data = "Cdrom0"; + RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data)); + NtSetValueKey( targetKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW ); + RtlFreeUnicodeString( &nameW ); + + NtClose( targetKey ); + NtClose( busKey ); + NtClose( portKey ); + NtClose( scsiKey ); +} + + +/* create the hardware registry branch */ +static void create_hardware_branch(void) +{ + int i; + HANDLE handle; + char drive[] = "\\\\.\\A:"; + + /* create entries for cdroms (skipping A: and B:) */ + for (i = 2; i < 26; i++) + { + drive[4] = 'A' + i; + handle = CreateFileA( drive, 0, 0, NULL, OPEN_EXISTING, 0, 0 ); + if (handle == INVALID_HANDLE_VALUE) continue; + init_cdrom_registry( handle ); + CloseHandle( handle ); + } +} + + +/*********************************************************************** + * convert_old_config + */ +void convert_old_config(void) +{ + HKEY hkey_current_user; + + if (allocate_default_keys() == REG_OPENED_EXISTING_KEY) return; /* someone else already loaded the registry */ RtlOpenCurrentUser( KEY_ALL_ACCESS, &hkey_current_user ); - /* load home registries */ - + /* load the user registry (FIXME: should be done at server init time) */ SERVER_START_REQ( load_user_registries ) { req->hkey = hkey_current_user; @@ -485,14 +679,13 @@ void SHELL_LoadRegistry( void ) } SERVER_END_REQ; - /* create hardware registry branch */ - - create_hardware_branch(); - - /* convert keys from config file to new registry format */ - + /* convert old configuration */ + create_dos_devices(); convert_drive_types(); convert_environment( hkey_current_user ); - NtClose(hkey_current_user); + /* create some hardware keys (FIXME: should not be done here) */ + create_hardware_branch(); + + NtClose( hkey_current_user ); } diff --git a/dlls/kernel/process.c b/dlls/kernel/process.c index de81ecc5363..5c63387b8cc 100644 --- a/dlls/kernel/process.c +++ b/dlls/kernel/process.c @@ -86,7 +86,7 @@ static const WCHAR pifW[] = {'.','p','i','f',0}; static const WCHAR winevdmW[] = {'w','i','n','e','v','d','m','.','e','x','e',0}; extern void SHELL_LoadRegistry(void); -extern void VOLUME_CreateDevices(void); +extern void convert_old_config(void); extern void VERSION_Init( const WCHAR *appname ); extern void LOCALE_Init(void); @@ -995,11 +995,8 @@ static BOOL process_init(void) /* Copy the parent environment */ if (!build_initial_environment( __wine_main_environ )) return FALSE; - /* Create device symlinks */ - VOLUME_CreateDevices(); - - /* registry initialisation */ - SHELL_LoadRegistry(); + /* convert old configuration to new format */ + convert_old_config(); /* global boot finished, the rest is process-local */ SERVER_START_REQ( boot_done ) diff --git a/dlls/kernel/volume.c b/dlls/kernel/volume.c index f464c6f6cdc..2599278c236 100644 --- a/dlls/kernel/volume.c +++ b/dlls/kernel/volume.c @@ -215,237 +215,6 @@ static UINT get_registry_drive_type( const WCHAR *root ) } -/* create symlinks for the DOS drives; helper for VOLUME_CreateDevices */ -static int create_drives( int devices_only ) -{ - static const WCHAR PathW[] = {'P','a','t','h',0}; - static const WCHAR DeviceW[] = {'D','e','v','i','c','e',0}; - WCHAR driveW[] = {'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','\\','D','r','i','v','e',' ','A',0}; - OBJECT_ATTRIBUTES attr; - UNICODE_STRING nameW; - char tmp[1024*sizeof(WCHAR) + sizeof(KEY_VALUE_PARTIAL_INFORMATION)]; - char dest[1024]; - WCHAR *p, name[3]; - HKEY hkey; - DWORD dummy; - int i, count = 0; - - attr.Length = sizeof(attr); - attr.RootDirectory = 0; - attr.ObjectName = &nameW; - attr.Attributes = 0; - attr.SecurityDescriptor = NULL; - attr.SecurityQualityOfService = NULL; - - /* create symlinks for the drive roots */ - - if (!devices_only) for (i = 0; i < 26; i++) - { - RtlInitUnicodeString( &nameW, driveW ); - nameW.Buffer[(nameW.Length / sizeof(WCHAR)) - 1] = 'A' + i; - if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) != STATUS_SUCCESS) continue; - - RtlInitUnicodeString( &nameW, PathW ); - if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy )) - { - WCHAR path[1024]; - WCHAR *data = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data; - ExpandEnvironmentStringsW( data, path, sizeof(path)/sizeof(WCHAR) ); - - p = path + strlenW(path) - 1; - while ((p > path) && (*p == '/')) *p-- = '\0'; - - name[0] = 'a' + i; - name[1] = ':'; - name[2] = 0; - - if (path[0] != '/') - { - /* relative paths are relative to config dir */ - memmove( path + 3, path, (strlenW(path) + 1) * sizeof(WCHAR) ); - path[0] = '.'; - path[1] = '.'; - path[2] = '/'; - } - if (DefineDosDeviceW( DDD_RAW_TARGET_PATH, name, path )) - { - WideCharToMultiByte(CP_UNIXCP, 0, path, -1, dest, sizeof(dest), NULL, NULL); - MESSAGE( "Created symlink %s/dosdevices/%c: -> %s\n", - wine_get_config_dir(), 'a' + i, dest ); - count++; - } - } - NtClose( hkey ); - } - - /* create symlinks for the drive devices */ - - for (i = 0; i < 26; i++) - { - RtlInitUnicodeString( &nameW, driveW ); - nameW.Buffer[(nameW.Length / sizeof(WCHAR)) - 1] = 'A' + i; - if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) != STATUS_SUCCESS) continue; - - RtlInitUnicodeString( &nameW, DeviceW ); - if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy )) - { - char *path, *p; - WCHAR devname[] = {'A',':',':',0 }; - WCHAR *data = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data; - WideCharToMultiByte(CP_UNIXCP, 0, data, -1, dest, sizeof(dest), NULL, NULL); - path = get_dos_device_path( devname ); - p = path + strlen(path); - p[-3] = 'a' + i; - if (!symlink( dest, path )) - { - MESSAGE( "Created symlink %s/dosdevices/%c:: -> %s\n", - wine_get_config_dir(), 'a' + i, dest ); - count++; - } - HeapFree( GetProcessHeap(), 0, path ); - } - NtClose( hkey ); - } - - return count; -} - - -/*********************************************************************** - * VOLUME_CreateDevices - * - * Create the device files for the new device naming scheme. - * Should go away after a transition period. - */ -void VOLUME_CreateDevices(void) -{ - const char *config_dir = wine_get_config_dir(); - char *buffer; - int i, count = 0; - - if (!(buffer = HeapAlloc( GetProcessHeap(), 0, - strlen(config_dir) + sizeof("/dosdevices/a::") ))) - return; - - strcpy( buffer, config_dir ); - strcat( buffer, "/dosdevices" ); - - if (!mkdir( buffer, 0777 )) /* we created it, so now create the devices */ - { - HKEY hkey; - DWORD dummy; - OBJECT_ATTRIBUTES attr; - UNICODE_STRING nameW; - WCHAR *p, *devnameW; - char tmp[128]; - WCHAR com[5] = {'C','O','M','1',0}; - WCHAR lpt[5] = {'L','P','T','1',0}; - - static const WCHAR serialportsW[] = {'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','\\', - 'S','e','r','i','a','l','P','o','r','t','s',0}; - static const WCHAR parallelportsW[] = {'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','\\', - 'P','a','r','a','l','l','e','l','P','o','r','t','s',0}; - - attr.Length = sizeof(attr); - attr.RootDirectory = 0; - attr.ObjectName = &nameW; - attr.Attributes = 0; - attr.SecurityDescriptor = NULL; - attr.SecurityQualityOfService = NULL; - RtlInitUnicodeString( &nameW, serialportsW ); - - if (!NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr )) - { - RtlInitUnicodeString( &nameW, com ); - for (i = 1; i <= 9; i++) - { - com[3] = '0' + i; - if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, - tmp, sizeof(tmp), &dummy )) - { - devnameW = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data; - if ((p = strchrW( devnameW, ',' ))) *p = 0; - if (DefineDosDeviceW( DDD_RAW_TARGET_PATH, com, devnameW )) - { - char devname[32]; - WideCharToMultiByte(CP_UNIXCP, 0, devnameW, -1, - devname, sizeof(devname), NULL, NULL); - MESSAGE( "Created symlink %s/dosdevices/com%d -> %s\n", config_dir, i, devname ); - count++; - } - } - } - NtClose( hkey ); - } - - RtlInitUnicodeString( &nameW, parallelportsW ); - if (!NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr )) - { - RtlInitUnicodeString( &nameW, lpt ); - for (i = 1; i <= 9; i++) - { - lpt[3] = '0' + i; - if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, - tmp, sizeof(tmp), &dummy )) - { - devnameW = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data; - if ((p = strchrW( devnameW, ',' ))) *p = 0; - if (DefineDosDeviceW( DDD_RAW_TARGET_PATH, lpt, devnameW )) - { - char devname[32]; - WideCharToMultiByte(CP_UNIXCP, 0, devnameW, -1, - devname, sizeof(devname), NULL, NULL); - MESSAGE( "Created symlink %s/dosdevices/lpt%d -> %s\n", config_dir, i, devname ); - count++; - } - } - } - NtClose( hkey ); - } - count += create_drives( FALSE ); - } - else - { - struct stat st; - int i; - - /* it is possible that the serial/parallel devices have been created but */ - /* not the drives; check for at least one drive symlink to catch that case */ - strcat( buffer, "/a:" ); - for (i = 0; i < 26; i++) - { - buffer[strlen(buffer)-2] = 'a' + i; - if (!lstat( buffer, &st )) break; - } - if (i == 26) count += create_drives( FALSE ); - else - { - strcat( buffer, ":" ); - for (i = 0; i < 26; i++) - { - buffer[strlen(buffer)-3] = 'a' + i; - if (!lstat( buffer, &st )) break; - } - if (i == 26) count += create_drives( TRUE ); - } - } - - if (count) - MESSAGE( "\nYou can now remove the [SerialPorts], [ParallelPorts], and [Drive] sections\n" - "in your configuration file, they are replaced by the above symlinks.\n\n" ); - - HeapFree( GetProcessHeap(), 0, buffer ); -} - - /****************************************************************** * VOLUME_FindCdRomDataBestVoldesc */