Commit 553a75e1 authored by Alexandre Julliard's avatar Alexandre Julliard

Use symlinks in dosdevices/ for the drive devices too.

Store drive types in the registry instead of in the config file. Added some more code to convert existing config to the new scheme.
parent 8db4d73d
...@@ -19,7 +19,6 @@ SPEC_SRCS16 = \ ...@@ -19,7 +19,6 @@ SPEC_SRCS16 = \
C_SRCS = \ C_SRCS = \
$(TOPOBJDIR)/files/directory.c \ $(TOPOBJDIR)/files/directory.c \
$(TOPOBJDIR)/files/drive.c \
$(TOPOBJDIR)/files/file.c \ $(TOPOBJDIR)/files/file.c \
$(TOPOBJDIR)/files/smb.c \ $(TOPOBJDIR)/files/smb.c \
$(TOPOBJDIR)/misc/options.c \ $(TOPOBJDIR)/misc/options.c \
......
...@@ -733,8 +733,8 @@ static BOOL process_init( char *argv[], char **environ ) ...@@ -733,8 +733,8 @@ static BOOL process_init( char *argv[], char **environ )
/* Parse command line arguments */ /* Parse command line arguments */
if (!info_size) OPTIONS_ParseOptions( argv ); if (!info_size) OPTIONS_ParseOptions( argv );
/* initialise DOS drives */ /* Create device symlinks */
if (!DRIVE_Init()) return FALSE; VOLUME_CreateDevices();
/* initialise DOS directories */ /* initialise DOS directories */
if (!DIR_Init()) return FALSE; if (!DIR_Init()) return FALSE;
...@@ -742,9 +742,6 @@ static BOOL process_init( char *argv[], char **environ ) ...@@ -742,9 +742,6 @@ static BOOL process_init( char *argv[], char **environ )
/* registry initialisation */ /* registry initialisation */
SHELL_LoadRegistry(); SHELL_LoadRegistry();
/* Create device symlinks */
VOLUME_CreateDevices();
/* global boot finished, the rest is process-local */ /* global boot finished, the rest is process-local */
SERVER_START_REQ( boot_done ) SERVER_START_REQ( boot_done )
{ {
......
...@@ -167,35 +167,36 @@ static BOOL open_device_root( LPCWSTR root, HANDLE *handle ) ...@@ -167,35 +167,36 @@ static BOOL open_device_root( LPCWSTR root, HANDLE *handle )
/* fetch the type of a drive from the registry */ /* fetch the type of a drive from the registry */
static UINT get_registry_drive_type( const WCHAR *root ) static UINT get_registry_drive_type( const WCHAR *root )
{ {
static const WCHAR drive_types_keyW[] = {'M','a','c','h','i','n','e','\\',
'S','o','f','t','w','a','r','e','\\',
'W','i','n','e','\\',
'D','r','i','v','e','s',0 };
OBJECT_ATTRIBUTES attr; OBJECT_ATTRIBUTES attr;
UNICODE_STRING nameW; UNICODE_STRING nameW;
HKEY hkey; HKEY hkey;
DWORD dummy; DWORD dummy;
UINT ret = DRIVE_UNKNOWN; UINT ret = DRIVE_UNKNOWN;
char tmp[32 + sizeof(KEY_VALUE_PARTIAL_INFORMATION)]; char tmp[32 + sizeof(KEY_VALUE_PARTIAL_INFORMATION)];
WCHAR path[MAX_PATH]; WCHAR driveW[] = {'A',':',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};
static const WCHAR TypeW[] = {'T','y','p','e',0};
if (!root)
{
GetCurrentDirectoryW( MAX_PATH, path );
root = path;
}
attr.Length = sizeof(attr); attr.Length = sizeof(attr);
attr.RootDirectory = 0; attr.RootDirectory = 0;
attr.ObjectName = &nameW; attr.ObjectName = &nameW;
attr.Attributes = 0; attr.Attributes = 0;
attr.SecurityDescriptor = NULL; attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL; attr.SecurityQualityOfService = NULL;
RtlInitUnicodeString( &nameW, driveW ); RtlInitUnicodeString( &nameW, drive_types_keyW );
nameW.Buffer[(nameW.Length / sizeof(WCHAR)) - 1] = root[0];
if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) != STATUS_SUCCESS) return DRIVE_UNKNOWN; if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) != STATUS_SUCCESS) return DRIVE_UNKNOWN;
RtlInitUnicodeString( &nameW, TypeW ); if (root) driveW[0] = root[0];
else
{
WCHAR path[MAX_PATH];
GetCurrentDirectoryW( MAX_PATH, path );
driveW[0] = path[0];
}
RtlInitUnicodeString( &nameW, driveW );
if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy )) if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy ))
{ {
int i; int i;
...@@ -216,25 +217,99 @@ static UINT get_registry_drive_type( const WCHAR *root ) ...@@ -216,25 +217,99 @@ static UINT get_registry_drive_type( const WCHAR *root )
/* create symlinks for the DOS drives; helper for VOLUME_CreateDevices */ /* create symlinks for the DOS drives; helper for VOLUME_CreateDevices */
static int create_drives(void) static int create_drives( int devices_only )
{ {
WCHAR name[3], rootW[MAX_PATHNAME_LEN]; 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; 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++) for (i = 0; i < 26; i++)
{ {
const char *root = DRIVE_GetRoot( i ); RtlInitUnicodeString( &nameW, driveW );
if (!root) continue; nameW.Buffer[(nameW.Length / sizeof(WCHAR)) - 1] = 'A' + i;
name[0] = 'a' + i; if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) != STATUS_SUCCESS) continue;
name[1] = ':';
name[2] = 0; RtlInitUnicodeString( &nameW, DeviceW );
if (MultiByteToWideChar( CP_UNIXCP, 0, root, -1, rootW, MAX_PATHNAME_LEN ) && if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy ))
DefineDosDeviceW( DDD_RAW_TARGET_PATH, name, rootW ))
{ {
MESSAGE( "Created symlink %s/dosdevices/%c: -> %s\n", wine_get_config_dir(), 'a' + i, root ); char *path, *p;
count++; 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; return count;
} }
...@@ -336,7 +411,7 @@ void VOLUME_CreateDevices(void) ...@@ -336,7 +411,7 @@ void VOLUME_CreateDevices(void)
} }
NtClose( hkey ); NtClose( hkey );
} }
count += create_drives(); count += create_drives( FALSE );
} }
else else
{ {
...@@ -351,13 +426,22 @@ void VOLUME_CreateDevices(void) ...@@ -351,13 +426,22 @@ void VOLUME_CreateDevices(void)
buffer[strlen(buffer)-2] = 'a' + i; buffer[strlen(buffer)-2] = 'a' + i;
if (!lstat( buffer, &st )) break; if (!lstat( buffer, &st )) break;
} }
if (i == 26) count += create_drives(); 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) if (count)
MESSAGE( "\nYou can now remove the [SerialPorts] and [ParallelPorts] sections\n" MESSAGE( "\nYou can now remove the [SerialPorts], [ParallelPorts], and [Drive] sections\n"
"in your configuration file, as well as the \"Path=\" definitions in\n" "in your configuration file, they are replaced by the above symlinks.\n\n" );
"the drive sections, they are replaced by the above symlinks.\n\n" );
HeapFree( GetProcessHeap(), 0, buffer ); HeapFree( GetProcessHeap(), 0, buffer );
} }
......
...@@ -840,7 +840,7 @@ static NTSTATUS get_dos_device( const WCHAR *name, UINT name_len, ANSI_STRING *u ...@@ -840,7 +840,7 @@ static NTSTATUS get_dos_device( const WCHAR *name, UINT name_len, ANSI_STRING *u
for (i = 0; i < name_len; i++) for (i = 0; i < name_len; i++)
if (name[i] <= 32 || name[i] >= 127) return STATUS_OBJECT_NAME_NOT_FOUND; if (name[i] <= 32 || name[i] >= 127) return STATUS_OBJECT_NAME_NOT_FOUND;
unix_len = strlen(config_dir) + sizeof("/dosdevices/") + name_len; unix_len = strlen(config_dir) + sizeof("/dosdevices/") + name_len + 1;
if (!(unix_name = RtlAllocateHeap( GetProcessHeap(), 0, unix_len ))) if (!(unix_name = RtlAllocateHeap( GetProcessHeap(), 0, unix_len )))
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
...@@ -853,7 +853,11 @@ static NTSTATUS get_dos_device( const WCHAR *name, UINT name_len, ANSI_STRING *u ...@@ -853,7 +853,11 @@ static NTSTATUS get_dos_device( const WCHAR *name, UINT name_len, ANSI_STRING *u
dev[i] = 0; dev[i] = 0;
/* special case for drive devices */ /* special case for drive devices */
if (name_len == 2 && dev[1] == ':') dev[1] = '|'; if (name_len == 2 && dev[1] == ':')
{
dev[i++] = ':';
dev[i] = 0;
}
for (;;) for (;;)
{ {
......
...@@ -4,35 +4,6 @@ WINE REGISTRY Version 2 ...@@ -4,35 +4,6 @@ WINE REGISTRY Version 2
;; If you think it is necessary to show others your complete config for a ;; If you think it is necessary to show others your complete config for a
;; bug report, filter out empty lines and comments with ;; bug report, filter out empty lines and comments with
;; grep -v "^;" ~/.wine/config | grep '.' ;; grep -v "^;" ~/.wine/config | grep '.'
;;
;; MS-DOS drives configuration
;;
;; Each section has the following format:
;; [Drive X]
;; "Path"="xxx" (Unix path for drive root)
;; "Type"="xxx" (supported types are 'floppy', 'hd', 'cdrom' and 'network')
;; "Device"="/dev/xx" (only if you want to allow raw device access)
;;
[Drive A]
"Type" = "floppy"
"Device" = "/dev/fd0"
[Drive C]
"Type" = "hd"
[Drive D]
"Type" = "cdrom"
; make sure that device is correct and has proper permissions !
"Device" = "/dev/cdrom"
[Drive E]
"Type" = "hd"
[Drive F]
"Type" = "network"
[Drive Z]
"Type" = "hd"
[wine] [wine]
"Windows" = "c:\\windows" "Windows" = "c:\\windows"
......
.\" -*- nroff -*- .\" -*- nroff -*-
.TH WINE.CONF 5 "September 2003" "Version 20030911" "Wine Configuration File" .TH WINE.CONF 5 "April 2004" "Version 20040408" "Wine Configuration File"
.SH NAME .SH NAME
wine.conf \- Wine configuration file wine.conf \- Wine configuration file
.SH DESCRIPTION .SH DESCRIPTION
...@@ -24,42 +24,12 @@ consist of lines of the form ...@@ -24,42 +24,12 @@ consist of lines of the form
The entry and value can be any text strings, included in double The entry and value can be any text strings, included in double
quotes; it can also contain references to environment variables quotes; it can also contain references to environment variables
surrounded by surrounded by
.I ${}. .I %
signs.
Inside the double quotes, special characters, backslashes and quotes Inside the double quotes, special characters, backslashes and quotes
must be escaped with backslashes. Supported section names and entries must be escaped with backslashes. Supported section names and entries
are listed below. are listed below.
.PP .PP
.B [Drive X]
.br
This section is used to specify the root directory and type of each emulated
.B DOS
drive, since most Windows applications require a DOS/MS-Windows based
disk drive & directory scheme, which is either provided by a real
DOS partition mounted somewhere or by some carefully crafted directory layout
on a Unix file system ("no-windows fake installation").
There is one such section for every drive you want to configure.
.PP
.I format: """Path""=""<rootdirectory>"""
.br
default: none
.br
If you mounted your dos partition as
.I /dos
and installed Microsoft Windows in
C:\\WINDOWS (thus it shows up as /dos/WINDOWS), then you should specify
.I """Path""=""/dos"""
in the
.I [Drive C]
section in order to configure /dos as the drive root of drive C:.
.PP
.I format: """Type""=""<type>"""
.br
default: "hd"
.br
Used to specify the drive type this drive appears as in Windows
or DOS programs; supported types are "floppy", "hd", "cdrom"
and "network".
.PP
.B [wine] .B [wine]
.br .br
.I format: """windows""=""<directory>""" .I format: """windows""=""<directory>"""
...@@ -331,11 +301,5 @@ file, the registry files, and the DOS device mappings. The default is ...@@ -331,11 +301,5 @@ file, the registry files, and the DOS device mappings. The default is
.TP .TP
.I $WINEPREFIX/config .I $WINEPREFIX/config
User-specific configuration file User-specific configuration file
.TP
.I $WINEPREFIX/dosdevices
Directory containing the DOS device mappings. Each file in that
directory is a symlink to the Unix device file implementing a given
device. For instance, if COM1 is mapped to /dev/ttyS0 you'd have a
symlink of the form $WINEPREFIX/dosdevices/com1 -> /dev/ttyS0.
.SH "SEE ALSO" .SH "SEE ALSO"
.BR wine (1) .BR wine (1)
...@@ -115,7 +115,8 @@ If set, the content of this variable is taken as the name of the directory where ...@@ -115,7 +115,8 @@ If set, the content of this variable is taken as the name of the directory where
.B wine .B wine
stores its data (the default is stores its data (the default is
.I $HOME/.wine .I $HOME/.wine
). This directory contains also the socket, which is used to communicate with the ). This directory is also used to identify the socket which is used to
communicate with the
.I wineserver. .I wineserver.
All All
.B wine .B wine
...@@ -254,18 +255,59 @@ always as native. ...@@ -254,18 +255,59 @@ always as native.
.TP .TP
.I DISPLAY .I DISPLAY
Specifies the X11 display to use. Specifies the X11 display to use.
.SH CONFIGURATION FILE .SH FILES
.B wine .TP
expects a configuration file ( .I @bindir@/wine
The
.B wine
program loader.
.TP
.I @bindir@/wineconsole
The
.B wine
program loader for CUI (console) applications.
.TP
.I @bindir@/wineserver
The
.B wine
server
.TP
.I @bindir@/winedbg
The
.B wine
debugger
.TP
.I @bindir@/wineclipsrv
The
.B wine
clipboard server
.TP
.I @dlldir@
Directory containing
.B wine's
shared libraries
.TP
.I $WINEPREFIX/config .I $WINEPREFIX/config
or User-specific configuration file, which must conform to the format specified
.I ~/.wine/config
if WINEPREFIX is not set), which must conform to the format specified
in the in the
.BR wine.conf (5) .BR wine.conf (5)
man page. A sample configuration file is documentation/samples/config in the man page. A sample configuration file is documentation/samples/config in the
.B wine .B wine
source archive. source archive.
.TP
.I $WINEPREFIX/dosdevices
Directory containing the DOS device mappings. Each file in that
directory is a symlink to the Unix device file implementing a given
device. For instance, if COM1 is mapped to /dev/ttyS0 you'd have a
symlink of the form $WINEPREFIX/dosdevices/com1 -> /dev/ttyS0.
.br
DOS drives are also specified with symlinks; for instance if drive D:
corresponds to the CDROM mounted at /mnt/cdrom, you'd have a symlink
$WINEPREFIX/dosdevices/d: -> /mnt/cdrom. The Unix device corresponding
to a DOS drive can be specified the same way, except with '::' instead
of ':'. So for the previous example, if the CDROM device is mounted
from /dev/hdc, the corresponding symlink would be
$WINEPREFIX/dosdevices/d:: -> /dev/hdc.
.SH AUTHORS .SH AUTHORS
.B wine .B wine
is available thanks to the work of many developers. For a listing is available thanks to the work of many developers. For a listing
...@@ -276,7 +318,7 @@ in the top-level directory of the source distribution. ...@@ -276,7 +318,7 @@ in the top-level directory of the source distribution.
.B wine .B wine
can be distributed under the terms of the LGPL license. A copy of the can be distributed under the terms of the LGPL license. A copy of the
license is in the file license is in the file
.B LICENSE .B COPYING.LIB
in the top-level directory of the source distribution. in the top-level directory of the source distribution.
.SH BUGS .SH BUGS
.PP .PP
...@@ -326,45 +368,6 @@ development, you might want to subscribe to the ...@@ -326,45 +368,6 @@ development, you might want to subscribe to the
.B wine .B wine
mailing lists at mailing lists at
.I http://www.winehq.org/forums .I http://www.winehq.org/forums
.SH FILES
.PD 0
.TP
.I @bindir@/wine
The
.B wine
program loader.
.TP
.I @bindir@/wineconsole
The
.B wine
program loader for CUI (console) applications.
.TP
.I @bindir@/wineserver
The
.B wine
server
.TP
.I @bindir@/winedbg
The
.B wine
debugger
.TP
.I @bindir@/wineclipsrv
The
.B wine
clipboard server
.TP
.I @dlldir@
Directory containing
.B wine's
shared libraries
.TP
.I ~/.wine/config
User-specific configuration file
.TP
.I ~/.wine
Directory containing user specific data managed by
.B wine.
.SH "SEE ALSO" .SH "SEE ALSO"
.BR wine.conf (5) .BR wine.conf (5)
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include "winerror.h" #include "winerror.h"
#include "winreg.h" #include "winreg.h"
#include "winternl.h" #include "winternl.h"
#include "thread.h"
#include "wine/unicode.h" #include "wine/unicode.h"
#include "file.h" #include "file.h"
#include "wine/debug.h" #include "wine/debug.h"
...@@ -108,8 +109,6 @@ int DIR_Init(void) ...@@ -108,8 +109,6 @@ int DIR_Init(void)
char path[MAX_PATHNAME_LEN]; char path[MAX_PATHNAME_LEN];
WCHAR longpath[MAX_PATHNAME_LEN]; WCHAR longpath[MAX_PATHNAME_LEN];
WCHAR *tmp_dir, *profile_dir; WCHAR *tmp_dir, *profile_dir;
int drive;
const char *cwd;
static const WCHAR wineW[] = {'M','a','c','h','i','n','e','\\', static const WCHAR wineW[] = {'M','a','c','h','i','n','e','\\',
'S','o','f','t','w','a','r','e','\\', 'S','o','f','t','w','a','r','e','\\',
'W','i','n','e','\\','W','i','n','e','\\', 'W','i','n','e','\\','W','i','n','e','\\',
...@@ -135,28 +134,6 @@ int DIR_Init(void) ...@@ -135,28 +134,6 @@ int DIR_Init(void)
static const WCHAR comspecW[] = {'C','O','M','S','P','E','C',0}; static const WCHAR comspecW[] = {'C','O','M','S','P','E','C',0};
static const WCHAR empty_strW[] = { 0 }; static const WCHAR empty_strW[] = { 0 };
if (!getcwd( path, MAX_PATHNAME_LEN ))
{
perror( "Could not get current directory" );
return 0;
}
cwd = path;
if ((drive = DRIVE_FindDriveRoot( &cwd )) == -1)
{
MESSAGE("Warning: could not find wine config [Drive x] entry "
"for current working directory %s; "
"starting in windows directory.\n", cwd );
}
else
{
longpath[0] = 'a' + drive;
longpath[1] = ':';
MultiByteToWideChar(CP_UNIXCP, 0, cwd, -1, longpath + 2, MAX_PATHNAME_LEN);
SetCurrentDirectoryW( longpath );
if(GetDriveTypeW(longpath)==DRIVE_CDROM)
chdir("/"); /* change to root directory so as not to lock cdroms */
}
attr.Length = sizeof(attr); attr.Length = sizeof(attr);
attr.RootDirectory = 0; attr.RootDirectory = 0;
attr.ObjectName = &nameW; attr.ObjectName = &nameW;
...@@ -175,7 +152,25 @@ int DIR_Init(void) ...@@ -175,7 +152,25 @@ int DIR_Init(void)
return 0; return 0;
} }
if (drive == -1) SetCurrentDirectoryW( DIR_Windows ); 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 the environment variables */
......
...@@ -174,78 +174,6 @@ void FILE_SetDosError(void) ...@@ -174,78 +174,6 @@ void FILE_SetDosError(void)
} }
/***********************************************************************
* FILE_CreateFile
*
* Implementation of CreateFile. Takes a Unix path name.
* Returns 0 on failure.
*/
HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
LPSECURITY_ATTRIBUTES sa, DWORD creation,
DWORD attributes, HANDLE template )
{
unsigned int err;
UINT disp, options;
HANDLE ret;
switch (creation)
{
case CREATE_ALWAYS: disp = FILE_OVERWRITE_IF; break;
case CREATE_NEW: disp = FILE_CREATE; break;
case OPEN_ALWAYS: disp = FILE_OPEN_IF; break;
case OPEN_EXISTING: disp = FILE_OPEN; break;
case TRUNCATE_EXISTING: disp = FILE_OVERWRITE; break;
default:
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
options = 0;
if (attributes & FILE_FLAG_BACKUP_SEMANTICS)
options |= FILE_OPEN_FOR_BACKUP_INTENT;
else
options |= FILE_NON_DIRECTORY_FILE;
if (attributes & FILE_FLAG_DELETE_ON_CLOSE)
options |= FILE_DELETE_ON_CLOSE;
if (!(attributes & FILE_FLAG_OVERLAPPED))
options |= FILE_SYNCHRONOUS_IO_ALERT;
if (attributes & FILE_FLAG_RANDOM_ACCESS)
options |= FILE_RANDOM_ACCESS;
attributes &= FILE_ATTRIBUTE_VALID_FLAGS;
SERVER_START_REQ( create_file )
{
req->access = access;
req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
req->sharing = sharing;
req->create = disp;
req->options = options;
req->attrs = attributes;
wine_server_add_data( req, filename, strlen(filename) );
SetLastError(0);
err = wine_server_call( req );
ret = reply->handle;
}
SERVER_END_REQ;
if (err)
{
/* In the case file creation was rejected due to CREATE_NEW flag
* was specified and file with that name already exists, correct
* last error is ERROR_FILE_EXISTS and not ERROR_ALREADY_EXISTS.
* Note: RtlNtStatusToDosError is not the subject to blame here.
*/
if (err == STATUS_OBJECT_NAME_COLLISION)
SetLastError( ERROR_FILE_EXISTS );
else
SetLastError( RtlNtStatusToDosError(err) );
}
if (!ret) WARN("Unable to create file '%s' (GLE %ld)\n", filename, GetLastError());
return ret;
}
static HANDLE FILE_OpenPipe(LPCWSTR name, DWORD access, LPSECURITY_ATTRIBUTES sa ) static HANDLE FILE_OpenPipe(LPCWSTR name, DWORD access, LPSECURITY_ATTRIBUTES sa )
{ {
HANDLE ret; HANDLE ret;
...@@ -368,18 +296,7 @@ HANDLE WINAPI CreateFileW( LPCWSTR filename, DWORD access, DWORD sharing, ...@@ -368,18 +296,7 @@ HANDLE WINAPI CreateFileW( LPCWSTR filename, DWORD access, DWORD sharing,
} }
else if (isalphaW(filename[4]) && filename[5] == ':' && filename[6] == '\0') else if (isalphaW(filename[4]) && filename[5] == ':' && filename[6] == '\0')
{ {
const char *device = DRIVE_GetDevice( toupperW(filename[4]) - 'A' ); dosdev = 0;
if (device)
{
ret = FILE_CreateFile( device, access, sharing, sa, creation,
attributes, template );
}
else
{
SetLastError( ERROR_ACCESS_DENIED );
return INVALID_HANDLE_VALUE;
}
goto done;
} }
else if ((dosdev = RtlIsDosDeviceName_U( filename + 4 ))) else if ((dosdev = RtlIsDosDeviceName_U( filename + 4 )))
{ {
......
...@@ -33,13 +33,6 @@ extern void FILE_SetDosError(void); ...@@ -33,13 +33,6 @@ extern void FILE_SetDosError(void);
/* files/directory.c */ /* files/directory.c */
extern int DIR_Init(void); extern int DIR_Init(void);
/* drive.c */
extern int DRIVE_Init(void);
extern int DRIVE_FindDriveRoot( const char **path );
extern int DRIVE_FindDriveRootW( LPCWSTR *path );
extern const char * DRIVE_GetRoot( int drive );
extern const char * DRIVE_GetDevice( int drive );
/* vxd.c */ /* vxd.c */
extern HANDLE VXD_Open( LPCWSTR filename, DWORD access, LPSECURITY_ATTRIBUTES sa ); extern HANDLE VXD_Open( LPCWSTR filename, DWORD access, LPSECURITY_ATTRIBUTES sa );
......
...@@ -1833,6 +1833,59 @@ static void create_hardware_branch(void) ...@@ -1833,6 +1833,59 @@ static void create_hardware_branch(void)
} }
/* convert the drive type entries from the old format to the new one */
static void convert_drive_types(void)
{
static const WCHAR TypeW[] = {'T','y','p','e',0};
static const WCHAR drive_types_keyW[] = {'M','a','c','h','i','n','e','\\',
'S','o','f','t','w','a','r','e','\\',
'W','i','n','e','\\',
'D','r','i','v','e','s',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};
char tmp[32*sizeof(WCHAR) + sizeof(KEY_VALUE_PARTIAL_INFORMATION)];
OBJECT_ATTRIBUTES attr;
UNICODE_STRING nameW;
DWORD dummy;
ULONG disp;
HKEY hkey_old, hkey_new;
int i;
attr.Length = sizeof(attr);
attr.RootDirectory = 0;
attr.ObjectName = &nameW;
attr.Attributes = 0;
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
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;
for (i = 0; i < 26; i++)
{
RtlInitUnicodeString( &nameW, driveW );
nameW.Buffer[(nameW.Length / sizeof(WCHAR)) - 1] = 'A' + i;
if (NtOpenKey( &hkey_old, KEY_ALL_ACCESS, &attr ) != STATUS_SUCCESS) continue;
RtlInitUnicodeString( &nameW, TypeW );
if (!NtQueryValueKey( hkey_old, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy ))
{
WCHAR valueW[] = {'A',':',0};
WCHAR *type = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data;
valueW[0] = 'A' + i;
RtlInitUnicodeString( &nameW, valueW );
NtSetValueKey( hkey_new, &nameW, 0, REG_SZ, type, (strlenW(type) + 1) * sizeof(WCHAR) );
MESSAGE( "Converted drive type to new entry HKLM\\Software\\Wine\\Drives \"%c:\" = %s\n",
'A' + i, debugstr_w(type) );
}
NtClose( hkey_old );
}
NtClose( hkey_new );
}
/* load all registry (native and global and home) */ /* load all registry (native and global and home) */
void SHELL_LoadRegistry( void ) void SHELL_LoadRegistry( void )
{ {
...@@ -2002,6 +2055,10 @@ void SHELL_LoadRegistry( void ) ...@@ -2002,6 +2055,10 @@ void SHELL_LoadRegistry( void )
_save_at_exit(hkey_users_default,"/" SAVE_LOCAL_REGBRANCH_USER_DEFAULT); _save_at_exit(hkey_users_default,"/" SAVE_LOCAL_REGBRANCH_USER_DEFAULT);
} }
/* convert keys from config file to new registry format */
convert_drive_types();
NtClose(hkey_users_default); NtClose(hkey_users_default);
NtClose(hkey_current_user); NtClose(hkey_current_user);
NtClose(hkey_users); NtClose(hkey_users);
......
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