Get the drive root directories from the symlinks in dosdevices/ if
they exist. Added creation of drive symlinks in the device transition code.
This commit is contained in:
parent
21e5909ac1
commit
0701b0748c
|
@ -148,6 +148,30 @@ static char *get_dos_device_path( LPCWSTR name )
|
|||
}
|
||||
|
||||
|
||||
/* create symlinks for the DOS drives; helper for VOLUME_CreateDevices */
|
||||
static int create_drives(void)
|
||||
{
|
||||
WCHAR name[3], rootW[MAX_PATHNAME_LEN];
|
||||
int i, count = 0;
|
||||
|
||||
for (i = 0; i < 26; i++)
|
||||
{
|
||||
const char *root = DRIVE_GetRoot( i );
|
||||
if (!root) continue;
|
||||
name[0] = 'a' + i;
|
||||
name[1] = ':';
|
||||
name[2] = 0;
|
||||
if (MultiByteToWideChar( CP_UNIXCP, 0, root, -1, rootW, MAX_PATHNAME_LEN ) &&
|
||||
DefineDosDeviceW( DDD_RAW_TARGET_PATH, name, rootW ))
|
||||
{
|
||||
MESSAGE( "Created symlink %s/dosdevices/%c: -> %s\n", wine_get_config_dir(), 'a' + i, root );
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* VOLUME_CreateDevices
|
||||
*
|
||||
|
@ -161,7 +185,7 @@ void VOLUME_CreateDevices(void)
|
|||
int i, count = 0;
|
||||
|
||||
if (!(buffer = HeapAlloc( GetProcessHeap(), 0,
|
||||
strlen(config_dir) + sizeof("/dosdevices") )))
|
||||
strlen(config_dir) + sizeof("/dosdevices") + 3 )))
|
||||
return;
|
||||
|
||||
strcpy( buffer, config_dir );
|
||||
|
@ -245,10 +269,29 @@ void VOLUME_CreateDevices(void)
|
|||
}
|
||||
NtClose( hkey );
|
||||
}
|
||||
if (count)
|
||||
MESSAGE( "\nYou can now remove the [SerialPorts] and [ParallelPorts] sections\n"
|
||||
"in your configuration file, they are replaced by the above symlinks.\n\n" );
|
||||
count += create_drives();
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
if (count)
|
||||
MESSAGE( "\nYou can now remove the [SerialPorts] and [ParallelPorts] sections\n"
|
||||
"in your configuration file, as well as the \"Path=\" definitions in\n"
|
||||
"the drive sections, they are replaced by the above symlinks.\n\n" );
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, buffer );
|
||||
}
|
||||
|
||||
|
|
145
files/drive.c
145
files/drive.c
|
@ -130,7 +130,7 @@ static inline UINT DRIVE_GetDriveType( INT drive, LPCWSTR value )
|
|||
*/
|
||||
int DRIVE_Init(void)
|
||||
{
|
||||
int i, len, count = 0;
|
||||
int i, len, symlink_count = 0, count = 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};
|
||||
|
@ -144,6 +144,8 @@ int DRIVE_Init(void)
|
|||
DWORD dummy;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
UNICODE_STRING nameW;
|
||||
char *root;
|
||||
const char *config_dir = wine_get_config_dir();
|
||||
|
||||
static const WCHAR PathW[] = {'P','a','t','h',0};
|
||||
static const WCHAR TypeW[] = {'T','y','p','e',0};
|
||||
|
@ -157,6 +159,45 @@ int DRIVE_Init(void)
|
|||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
|
||||
/* get the root of the drives from symlinks */
|
||||
|
||||
root = NULL;
|
||||
for (i = 0, drive = DOSDrives; i < MAX_DOS_DRIVES; i++, drive++)
|
||||
{
|
||||
if (!root)
|
||||
{
|
||||
root = HeapAlloc( GetProcessHeap(), 0, strlen(config_dir) + sizeof("/dosdevices/a:") );
|
||||
strcpy( root, config_dir );
|
||||
strcat( root, "/dosdevices/a:" );
|
||||
}
|
||||
root[strlen(root)-2] = 'a' + i;
|
||||
if (stat( root, &drive_stat_buffer ))
|
||||
{
|
||||
if (!lstat( root, &drive_stat_buffer))
|
||||
MESSAGE("Could not stat %s (%s), ignoring drive %c:\n",
|
||||
root, strerror(errno), 'a' + i);
|
||||
continue;
|
||||
}
|
||||
if (!S_ISDIR(drive_stat_buffer.st_mode))
|
||||
{
|
||||
MESSAGE("%s is not a directory, ignoring drive %c:\n", root, 'a' + i );
|
||||
continue;
|
||||
}
|
||||
drive->root = root;
|
||||
drive->dos_cwd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(drive->dos_cwd[0]));
|
||||
drive->unix_cwd = heap_strdup( "" );
|
||||
drive->device = NULL;
|
||||
drive->flags = 0;
|
||||
drive->dev = drive_stat_buffer.st_dev;
|
||||
drive->ino = drive_stat_buffer.st_ino;
|
||||
drive->type = DRIVE_FIXED;
|
||||
root = NULL;
|
||||
symlink_count++;
|
||||
}
|
||||
if (root) HeapFree( GetProcessHeap(), 0, root );
|
||||
|
||||
/* now get the parameters from the config file */
|
||||
|
||||
for (i = 0, drive = DOSDrives; i < MAX_DOS_DRIVES; i++, drive++)
|
||||
{
|
||||
RtlInitUnicodeString( &nameW, driveW );
|
||||
|
@ -164,57 +205,64 @@ int DRIVE_Init(void)
|
|||
if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) != STATUS_SUCCESS) continue;
|
||||
|
||||
/* Get the root path */
|
||||
RtlInitUnicodeString( &nameW, PathW );
|
||||
if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy ))
|
||||
if (!symlink_count)
|
||||
{
|
||||
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';
|
||||
|
||||
if (path[0] == '/')
|
||||
RtlInitUnicodeString( &nameW, PathW );
|
||||
if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy ))
|
||||
{
|
||||
len = WideCharToMultiByte(CP_UNIXCP, 0, path, -1, NULL, 0, NULL, NULL);
|
||||
drive->root = HeapAlloc(GetProcessHeap(), 0, len);
|
||||
WideCharToMultiByte(CP_UNIXCP, 0, path, -1, drive->root, len, NULL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* relative paths are relative to config dir */
|
||||
const char *config = wine_get_config_dir();
|
||||
len = strlen(config);
|
||||
len += WideCharToMultiByte(CP_UNIXCP, 0, path, -1, NULL, 0, NULL, NULL) + 2;
|
||||
drive->root = HeapAlloc( GetProcessHeap(), 0, len );
|
||||
len -= sprintf( drive->root, "%s/", config );
|
||||
WideCharToMultiByte(CP_UNIXCP, 0, path, -1,
|
||||
drive->root + strlen(drive->root), len, NULL, NULL);
|
||||
}
|
||||
WCHAR *data = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data;
|
||||
ExpandEnvironmentStringsW( data, path, sizeof(path)/sizeof(WCHAR) );
|
||||
|
||||
if (stat( drive->root, &drive_stat_buffer ))
|
||||
{
|
||||
MESSAGE("Could not stat %s (%s), ignoring drive %c:\n",
|
||||
drive->root, strerror(errno), 'A' + i);
|
||||
HeapFree( GetProcessHeap(), 0, drive->root );
|
||||
drive->root = NULL;
|
||||
goto next;
|
||||
}
|
||||
if (!S_ISDIR(drive_stat_buffer.st_mode))
|
||||
{
|
||||
MESSAGE("%s is not a directory, ignoring drive %c:\n",
|
||||
drive->root, 'A' + i );
|
||||
HeapFree( GetProcessHeap(), 0, drive->root );
|
||||
drive->root = NULL;
|
||||
goto next;
|
||||
}
|
||||
p = path + strlenW(path) - 1;
|
||||
while ((p > path) && (*p == '/')) *p-- = '\0';
|
||||
|
||||
drive->dos_cwd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(drive->dos_cwd[0]));
|
||||
drive->unix_cwd = heap_strdup( "" );
|
||||
drive->device = NULL;
|
||||
drive->flags = 0;
|
||||
drive->dev = drive_stat_buffer.st_dev;
|
||||
drive->ino = drive_stat_buffer.st_ino;
|
||||
if (path[0] == '/')
|
||||
{
|
||||
len = WideCharToMultiByte(CP_UNIXCP, 0, path, -1, NULL, 0, NULL, NULL);
|
||||
drive->root = HeapAlloc(GetProcessHeap(), 0, len);
|
||||
WideCharToMultiByte(CP_UNIXCP, 0, path, -1, drive->root, len, NULL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* relative paths are relative to config dir */
|
||||
const char *config = wine_get_config_dir();
|
||||
len = strlen(config);
|
||||
len += WideCharToMultiByte(CP_UNIXCP, 0, path, -1, NULL, 0, NULL, NULL) + 2;
|
||||
drive->root = HeapAlloc( GetProcessHeap(), 0, len );
|
||||
len -= sprintf( drive->root, "%s/", config );
|
||||
WideCharToMultiByte(CP_UNIXCP, 0, path, -1,
|
||||
drive->root + strlen(drive->root), len, NULL, NULL);
|
||||
}
|
||||
|
||||
if (stat( drive->root, &drive_stat_buffer ))
|
||||
{
|
||||
MESSAGE("Could not stat %s (%s), ignoring drive %c:\n",
|
||||
drive->root, strerror(errno), 'A' + i);
|
||||
HeapFree( GetProcessHeap(), 0, drive->root );
|
||||
drive->root = NULL;
|
||||
goto next;
|
||||
}
|
||||
if (!S_ISDIR(drive_stat_buffer.st_mode))
|
||||
{
|
||||
MESSAGE("%s is not a directory, ignoring drive %c:\n",
|
||||
drive->root, 'A' + i );
|
||||
HeapFree( GetProcessHeap(), 0, drive->root );
|
||||
drive->root = NULL;
|
||||
goto next;
|
||||
}
|
||||
|
||||
drive->dos_cwd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(drive->dos_cwd[0]));
|
||||
drive->unix_cwd = heap_strdup( "" );
|
||||
drive->device = NULL;
|
||||
drive->flags = 0;
|
||||
drive->dev = drive_stat_buffer.st_dev;
|
||||
drive->ino = drive_stat_buffer.st_ino;
|
||||
drive->type = DRIVE_FIXED;
|
||||
}
|
||||
}
|
||||
|
||||
if (drive->root)
|
||||
{
|
||||
/* Get the drive type */
|
||||
RtlInitUnicodeString( &nameW, TypeW );
|
||||
if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy ))
|
||||
|
@ -222,7 +270,6 @@ int DRIVE_Init(void)
|
|||
WCHAR *data = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data;
|
||||
drive->type = DRIVE_GetDriveType( i, data );
|
||||
}
|
||||
else drive->type = DRIVE_FIXED;
|
||||
|
||||
/* Get the device */
|
||||
RtlInitUnicodeString( &nameW, DeviceW );
|
||||
|
@ -266,7 +313,7 @@ int DRIVE_Init(void)
|
|||
NtClose( hkey );
|
||||
}
|
||||
|
||||
if (!count)
|
||||
if (!count && !symlink_count)
|
||||
{
|
||||
MESSAGE("Warning: no valid DOS drive found, check your configuration file.\n" );
|
||||
/* Create a C drive pointing to Unix root dir */
|
||||
|
|
Loading…
Reference in New Issue