Reimplemented GetLogicalDrives, GetLogicalDriveStrings and
GetDriveType using the new symlink mechanism. Made GetDriveType attempt to autodetect the type if not specified in the registry.
This commit is contained in:
parent
438369af9a
commit
a2963dacc3
|
@ -65,6 +65,16 @@ enum fs_type
|
||||||
FS_ISO9660
|
FS_ISO9660
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const WCHAR drive_types[][8] =
|
||||||
|
{
|
||||||
|
{ 0 }, /* DRIVE_UNKNOWN */
|
||||||
|
{ 0 }, /* DRIVE_NO_ROOT_DIR */
|
||||||
|
{'f','l','o','p','p','y',0}, /* DRIVE_REMOVABLE */
|
||||||
|
{'h','d',0}, /* DRIVE_FIXED */
|
||||||
|
{'n','e','t','w','o','r','k',0}, /* DRIVE_REMOTE */
|
||||||
|
{'c','d','r','o','m',0}, /* DRIVE_CDROM */
|
||||||
|
{'r','a','m','d','i','s','k',0} /* DRIVE_RAMDISK */
|
||||||
|
};
|
||||||
|
|
||||||
/* read a Unix symlink; returned buffer must be freed by caller */
|
/* read a Unix symlink; returned buffer must be freed by caller */
|
||||||
static char *read_symlink( const char *path )
|
static char *read_symlink( const char *path )
|
||||||
|
@ -154,6 +164,50 @@ static BOOL open_device_root( LPCWSTR root, HANDLE *handle )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* fetch the type of a drive from the registry */
|
||||||
|
static UINT get_registry_drive_type( int drive )
|
||||||
|
{
|
||||||
|
OBJECT_ATTRIBUTES attr;
|
||||||
|
UNICODE_STRING nameW;
|
||||||
|
HKEY hkey;
|
||||||
|
DWORD dummy;
|
||||||
|
UINT ret = DRIVE_UNKNOWN;
|
||||||
|
char tmp[32 + sizeof(KEY_VALUE_PARTIAL_INFORMATION)];
|
||||||
|
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};
|
||||||
|
|
||||||
|
attr.Length = sizeof(attr);
|
||||||
|
attr.RootDirectory = 0;
|
||||||
|
attr.ObjectName = &nameW;
|
||||||
|
attr.Attributes = 0;
|
||||||
|
attr.SecurityDescriptor = NULL;
|
||||||
|
attr.SecurityQualityOfService = NULL;
|
||||||
|
RtlInitUnicodeString( &nameW, driveW );
|
||||||
|
nameW.Buffer[(nameW.Length / sizeof(WCHAR)) - 1] = 'A' + drive;
|
||||||
|
if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) != STATUS_SUCCESS) return DRIVE_UNKNOWN;
|
||||||
|
|
||||||
|
RtlInitUnicodeString( &nameW, TypeW );
|
||||||
|
if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy ))
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
WCHAR *data = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(drive_types)/sizeof(drive_types[0]); i++)
|
||||||
|
{
|
||||||
|
if (!strcmpiW( data, drive_types[i] ))
|
||||||
|
{
|
||||||
|
ret = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NtClose( hkey );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* 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(void)
|
||||||
{
|
{
|
||||||
|
@ -1166,6 +1220,170 @@ DWORD WINAPI QueryDosDeviceA( LPCSTR devname, LPSTR target, DWORD bufsize )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* GetLogicalDrives (KERNEL32.@)
|
||||||
|
*/
|
||||||
|
DWORD WINAPI GetLogicalDrives(void)
|
||||||
|
{
|
||||||
|
const char *config_dir = wine_get_config_dir();
|
||||||
|
struct stat st;
|
||||||
|
char *buffer, *dev;
|
||||||
|
DWORD ret = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!(buffer = HeapAlloc( GetProcessHeap(), 0, strlen(config_dir) + sizeof("/dosdevices/a:") )))
|
||||||
|
{
|
||||||
|
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
strcpy( buffer, config_dir );
|
||||||
|
strcat( buffer, "/dosdevices/a:" );
|
||||||
|
dev = buffer + strlen(buffer) - 2;
|
||||||
|
|
||||||
|
for (i = 0; i < 26; i++)
|
||||||
|
{
|
||||||
|
*dev = 'a' + i;
|
||||||
|
if (!stat( buffer, &st )) ret |= (1 << i);
|
||||||
|
}
|
||||||
|
HeapFree( GetProcessHeap(), 0, buffer );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* GetLogicalDriveStringsA (KERNEL32.@)
|
||||||
|
*/
|
||||||
|
UINT WINAPI GetLogicalDriveStringsA( UINT len, LPSTR buffer )
|
||||||
|
{
|
||||||
|
DWORD drives = GetLogicalDrives();
|
||||||
|
UINT drive, count;
|
||||||
|
|
||||||
|
for (drive = count = 0; drive < 26; drive++) if (drives & (1 << drive)) count++;
|
||||||
|
if ((count * 4) + 1 > len) return count * 4 + 1;
|
||||||
|
|
||||||
|
for (drive = 0; drive < 26; drive++)
|
||||||
|
{
|
||||||
|
if (drives & (1 << drive))
|
||||||
|
{
|
||||||
|
*buffer++ = 'a' + drive;
|
||||||
|
*buffer++ = ':';
|
||||||
|
*buffer++ = '\\';
|
||||||
|
*buffer++ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*buffer = 0;
|
||||||
|
return count * 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* GetLogicalDriveStringsW (KERNEL32.@)
|
||||||
|
*/
|
||||||
|
UINT WINAPI GetLogicalDriveStringsW( UINT len, LPWSTR buffer )
|
||||||
|
{
|
||||||
|
DWORD drives = GetLogicalDrives();
|
||||||
|
UINT drive, count;
|
||||||
|
|
||||||
|
for (drive = count = 0; drive < 26; drive++) if (drives & (1 << drive)) count++;
|
||||||
|
if ((count * 4) + 1 > len) return count * 4 + 1;
|
||||||
|
|
||||||
|
for (drive = 0; drive < 26; drive++)
|
||||||
|
{
|
||||||
|
if (drives & (1 << drive))
|
||||||
|
{
|
||||||
|
*buffer++ = 'a' + drive;
|
||||||
|
*buffer++ = ':';
|
||||||
|
*buffer++ = '\\';
|
||||||
|
*buffer++ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*buffer = 0;
|
||||||
|
return count * 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* GetDriveTypeW (KERNEL32.@)
|
||||||
|
*
|
||||||
|
* Returns the type of the disk drive specified. If root is NULL the
|
||||||
|
* root of the current directory is used.
|
||||||
|
*
|
||||||
|
* RETURNS
|
||||||
|
*
|
||||||
|
* Type of drive (from Win32 SDK):
|
||||||
|
*
|
||||||
|
* DRIVE_UNKNOWN unable to find out anything about the drive
|
||||||
|
* DRIVE_NO_ROOT_DIR nonexistent root dir
|
||||||
|
* DRIVE_REMOVABLE the disk can be removed from the machine
|
||||||
|
* DRIVE_FIXED the disk can not be removed from the machine
|
||||||
|
* DRIVE_REMOTE network disk
|
||||||
|
* DRIVE_CDROM CDROM drive
|
||||||
|
* DRIVE_RAMDISK virtual disk in RAM
|
||||||
|
*/
|
||||||
|
UINT WINAPI GetDriveTypeW(LPCWSTR root) /* [in] String describing drive */
|
||||||
|
{
|
||||||
|
FILE_FS_DEVICE_INFORMATION info;
|
||||||
|
IO_STATUS_BLOCK io;
|
||||||
|
NTSTATUS status;
|
||||||
|
HANDLE handle;
|
||||||
|
UINT ret;
|
||||||
|
|
||||||
|
if (!open_device_root( root, &handle )) return DRIVE_NO_ROOT_DIR;
|
||||||
|
|
||||||
|
status = NtQueryVolumeInformationFile( handle, &io, &info, sizeof(info), FileFsDeviceInformation );
|
||||||
|
NtClose( handle );
|
||||||
|
if (status != STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
SetLastError( RtlNtStatusToDosError(status) );
|
||||||
|
ret = DRIVE_UNKNOWN;
|
||||||
|
}
|
||||||
|
else if ((ret = get_registry_drive_type( toupperW(root[0]) - 'A' )) == DRIVE_UNKNOWN)
|
||||||
|
{
|
||||||
|
switch (info.DeviceType)
|
||||||
|
{
|
||||||
|
case FILE_DEVICE_CD_ROM_FILE_SYSTEM: ret = DRIVE_CDROM; break;
|
||||||
|
case FILE_DEVICE_VIRTUAL_DISK: ret = DRIVE_RAMDISK; break;
|
||||||
|
case FILE_DEVICE_NETWORK_FILE_SYSTEM: ret = DRIVE_REMOTE; break;
|
||||||
|
case FILE_DEVICE_DISK_FILE_SYSTEM:
|
||||||
|
if (info.Characteristics & FILE_REMOTE_DEVICE) ret = DRIVE_REMOTE;
|
||||||
|
else if (info.Characteristics & FILE_REMOVABLE_MEDIA) ret = DRIVE_REMOVABLE;
|
||||||
|
else ret = DRIVE_FIXED;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = DRIVE_UNKNOWN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TRACE( "%s -> %d\n", debugstr_w(root), ret );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* GetDriveTypeA (KERNEL32.@)
|
||||||
|
*/
|
||||||
|
UINT WINAPI GetDriveTypeA( LPCSTR root )
|
||||||
|
{
|
||||||
|
UNICODE_STRING rootW;
|
||||||
|
UINT ret;
|
||||||
|
|
||||||
|
if (root)
|
||||||
|
{
|
||||||
|
if( !RtlCreateUnicodeStringFromAsciiz(&rootW, root))
|
||||||
|
{
|
||||||
|
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
||||||
|
return DRIVE_NO_ROOT_DIR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else rootW.Buffer = NULL;
|
||||||
|
|
||||||
|
ret = GetDriveTypeW(rootW.Buffer);
|
||||||
|
|
||||||
|
RtlFreeUnicodeString(&rootW);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* GetDiskFreeSpaceExW (KERNEL32.@)
|
* GetDiskFreeSpaceExW (KERNEL32.@)
|
||||||
*
|
*
|
||||||
|
|
199
files/drive.c
199
files/drive.c
|
@ -67,23 +67,11 @@ typedef struct
|
||||||
LPWSTR dos_cwd; /* cwd in DOS format without leading or trailing \ */
|
LPWSTR dos_cwd; /* cwd in DOS format without leading or trailing \ */
|
||||||
char *unix_cwd; /* cwd in Unix format without leading or trailing / */
|
char *unix_cwd; /* cwd in Unix format without leading or trailing / */
|
||||||
char *device; /* raw device path */
|
char *device; /* raw device path */
|
||||||
UINT type; /* drive type */
|
|
||||||
dev_t dev; /* unix device number */
|
dev_t dev; /* unix device number */
|
||||||
ino_t ino; /* unix inode number */
|
ino_t ino; /* unix inode number */
|
||||||
} DOSDRIVE;
|
} DOSDRIVE;
|
||||||
|
|
||||||
|
|
||||||
static const WCHAR DRIVE_Types[][8] =
|
|
||||||
{
|
|
||||||
{ 0 }, /* DRIVE_UNKNOWN */
|
|
||||||
{ 0 }, /* DRIVE_NO_ROOT_DIR */
|
|
||||||
{'f','l','o','p','p','y',0}, /* DRIVE_REMOVABLE */
|
|
||||||
{'h','d',0}, /* DRIVE_FIXED */
|
|
||||||
{'n','e','t','w','o','r','k',0}, /* DRIVE_REMOTE */
|
|
||||||
{'c','d','r','o','m',0}, /* DRIVE_CDROM */
|
|
||||||
{'r','a','m','d','i','s','k',0} /* DRIVE_RAMDISK */
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MAX_DOS_DRIVES 26
|
#define MAX_DOS_DRIVES 26
|
||||||
|
|
||||||
static DOSDRIVE DOSDrives[MAX_DOS_DRIVES];
|
static DOSDRIVE DOSDrives[MAX_DOS_DRIVES];
|
||||||
|
@ -100,23 +88,6 @@ inline static char *heap_strdup( const char *str )
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* DRIVE_GetDriveType
|
|
||||||
*/
|
|
||||||
static inline UINT DRIVE_GetDriveType( INT drive, LPCWSTR value )
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < sizeof(DRIVE_Types)/sizeof(DRIVE_Types[0]); i++)
|
|
||||||
{
|
|
||||||
if (!strcmpiW( value, DRIVE_Types[i] )) return i;
|
|
||||||
}
|
|
||||||
MESSAGE("Drive %c: unknown drive type %s, defaulting to 'hd'.\n",
|
|
||||||
'A' + drive, debugstr_w(value) );
|
|
||||||
return DRIVE_FIXED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* DRIVE_Init
|
* DRIVE_Init
|
||||||
*/
|
*/
|
||||||
|
@ -140,7 +111,6 @@ int DRIVE_Init(void)
|
||||||
const char *config_dir = wine_get_config_dir();
|
const char *config_dir = wine_get_config_dir();
|
||||||
|
|
||||||
static const WCHAR PathW[] = {'P','a','t','h',0};
|
static const WCHAR PathW[] = {'P','a','t','h',0};
|
||||||
static const WCHAR TypeW[] = {'T','y','p','e',0};
|
|
||||||
static const WCHAR DeviceW[] = {'D','e','v','i','c','e',0};
|
static const WCHAR DeviceW[] = {'D','e','v','i','c','e',0};
|
||||||
|
|
||||||
attr.Length = sizeof(attr);
|
attr.Length = sizeof(attr);
|
||||||
|
@ -180,7 +150,6 @@ int DRIVE_Init(void)
|
||||||
drive->device = NULL;
|
drive->device = NULL;
|
||||||
drive->dev = drive_stat_buffer.st_dev;
|
drive->dev = drive_stat_buffer.st_dev;
|
||||||
drive->ino = drive_stat_buffer.st_ino;
|
drive->ino = drive_stat_buffer.st_ino;
|
||||||
drive->type = DRIVE_FIXED;
|
|
||||||
root = NULL;
|
root = NULL;
|
||||||
symlink_count++;
|
symlink_count++;
|
||||||
}
|
}
|
||||||
|
@ -246,20 +215,11 @@ int DRIVE_Init(void)
|
||||||
drive->device = NULL;
|
drive->device = NULL;
|
||||||
drive->dev = drive_stat_buffer.st_dev;
|
drive->dev = drive_stat_buffer.st_dev;
|
||||||
drive->ino = drive_stat_buffer.st_ino;
|
drive->ino = drive_stat_buffer.st_ino;
|
||||||
drive->type = DRIVE_FIXED;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drive->root)
|
if (drive->root)
|
||||||
{
|
{
|
||||||
/* Get the drive type */
|
|
||||||
RtlInitUnicodeString( &nameW, TypeW );
|
|
||||||
if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy ))
|
|
||||||
{
|
|
||||||
WCHAR *data = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data;
|
|
||||||
drive->type = DRIVE_GetDriveType( i, data );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the device */
|
/* Get the device */
|
||||||
RtlInitUnicodeString( &nameW, DeviceW );
|
RtlInitUnicodeString( &nameW, DeviceW );
|
||||||
if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy ))
|
if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy ))
|
||||||
|
@ -270,14 +230,9 @@ int DRIVE_Init(void)
|
||||||
WideCharToMultiByte(CP_UNIXCP, 0, data, -1, drive->device, len, NULL, NULL);
|
WideCharToMultiByte(CP_UNIXCP, 0, data, -1, drive->device, len, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make the first hard disk the current drive */
|
|
||||||
if ((DRIVE_CurDrive == -1) && (drive->type == DRIVE_FIXED))
|
|
||||||
DRIVE_CurDrive = i;
|
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
TRACE("Drive %c: path=%s type=%s dev=%x ino=%x\n",
|
TRACE("Drive %c: path=%s dev=%x ino=%x\n",
|
||||||
'A' + i, drive->root, debugstr_w(DRIVE_Types[drive->type]),
|
'A' + i, drive->root, (int)drive->dev, (int)drive->ino );
|
||||||
(int)drive->dev, (int)drive->ino );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
next:
|
next:
|
||||||
|
@ -291,7 +246,6 @@ int DRIVE_Init(void)
|
||||||
DOSDrives[2].root = heap_strdup( "/" );
|
DOSDrives[2].root = heap_strdup( "/" );
|
||||||
DOSDrives[2].dos_cwd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DOSDrives[2].dos_cwd[0]));
|
DOSDrives[2].dos_cwd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DOSDrives[2].dos_cwd[0]));
|
||||||
DOSDrives[2].unix_cwd = heap_strdup( "" );
|
DOSDrives[2].unix_cwd = heap_strdup( "" );
|
||||||
DOSDrives[2].type = DRIVE_FIXED;
|
|
||||||
DOSDrives[2].device = NULL;
|
DOSDrives[2].device = NULL;
|
||||||
DRIVE_CurDrive = 2;
|
DRIVE_CurDrive = 2;
|
||||||
}
|
}
|
||||||
|
@ -299,7 +253,7 @@ int DRIVE_Init(void)
|
||||||
/* Make sure the current drive is valid */
|
/* Make sure the current drive is valid */
|
||||||
if (DRIVE_CurDrive == -1)
|
if (DRIVE_CurDrive == -1)
|
||||||
{
|
{
|
||||||
for (i = 0, drive = DOSDrives; i < MAX_DOS_DRIVES; i++, drive++)
|
for (i = 2, drive = DOSDrives; i < MAX_DOS_DRIVES; i++, drive++)
|
||||||
{
|
{
|
||||||
if (drive->root)
|
if (drive->root)
|
||||||
{
|
{
|
||||||
|
@ -562,16 +516,6 @@ const char * DRIVE_GetDevice( int drive )
|
||||||
return (DRIVE_IsValid( drive )) ? DOSDrives[drive].device : NULL;
|
return (DRIVE_IsValid( drive )) ? DOSDrives[drive].device : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* DRIVE_GetType
|
|
||||||
*/
|
|
||||||
static UINT DRIVE_GetType( int drive )
|
|
||||||
{
|
|
||||||
if (!DRIVE_IsValid( drive )) return DRIVE_NO_ROOT_DIR;
|
|
||||||
return DOSDrives[drive].type;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* DRIVE_Chdir
|
* DRIVE_Chdir
|
||||||
*/
|
*/
|
||||||
|
@ -684,70 +628,6 @@ WCHAR *DRIVE_BuildEnv(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* GetDriveTypeW (KERNEL32.@)
|
|
||||||
*
|
|
||||||
* Returns the type of the disk drive specified. If root is NULL the
|
|
||||||
* root of the current directory is used.
|
|
||||||
*
|
|
||||||
* RETURNS
|
|
||||||
*
|
|
||||||
* Type of drive (from Win32 SDK):
|
|
||||||
*
|
|
||||||
* DRIVE_UNKNOWN unable to find out anything about the drive
|
|
||||||
* DRIVE_NO_ROOT_DIR nonexistent root dir
|
|
||||||
* DRIVE_REMOVABLE the disk can be removed from the machine
|
|
||||||
* DRIVE_FIXED the disk can not be removed from the machine
|
|
||||||
* DRIVE_REMOTE network disk
|
|
||||||
* DRIVE_CDROM CDROM drive
|
|
||||||
* DRIVE_RAMDISK virtual disk in RAM
|
|
||||||
*/
|
|
||||||
UINT WINAPI GetDriveTypeW(LPCWSTR root) /* [in] String describing drive */
|
|
||||||
{
|
|
||||||
int drive;
|
|
||||||
TRACE("(%s)\n", debugstr_w(root));
|
|
||||||
|
|
||||||
if (NULL == root) drive = DRIVE_GetCurrentDrive();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((root[1]) && (root[1] != ':'))
|
|
||||||
{
|
|
||||||
WARN("invalid root %s\n", debugstr_w(root));
|
|
||||||
return DRIVE_NO_ROOT_DIR;
|
|
||||||
}
|
|
||||||
drive = toupperW(root[0]) - 'A';
|
|
||||||
}
|
|
||||||
return DRIVE_GetType(drive);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* GetDriveTypeA (KERNEL32.@)
|
|
||||||
*/
|
|
||||||
UINT WINAPI GetDriveTypeA( LPCSTR root )
|
|
||||||
{
|
|
||||||
UNICODE_STRING rootW;
|
|
||||||
UINT ret = 0;
|
|
||||||
|
|
||||||
if (root)
|
|
||||||
{
|
|
||||||
if( !RtlCreateUnicodeStringFromAsciiz(&rootW, root))
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
rootW.Buffer = NULL;
|
|
||||||
|
|
||||||
ret = GetDriveTypeW(rootW.Buffer);
|
|
||||||
|
|
||||||
RtlFreeUnicodeString(&rootW);
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* GetCurrentDirectory (KERNEL.411)
|
* GetCurrentDirectory (KERNEL.411)
|
||||||
*/
|
*/
|
||||||
|
@ -868,76 +748,3 @@ BOOL WINAPI SetCurrentDirectoryA( LPCSTR dir )
|
||||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* GetLogicalDriveStringsA (KERNEL32.@)
|
|
||||||
*/
|
|
||||||
UINT WINAPI GetLogicalDriveStringsA( UINT len, LPSTR buffer )
|
|
||||||
{
|
|
||||||
int drive, count;
|
|
||||||
|
|
||||||
for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++)
|
|
||||||
if (DRIVE_IsValid(drive)) count++;
|
|
||||||
if ((count * 4) + 1 <= len)
|
|
||||||
{
|
|
||||||
LPSTR p = buffer;
|
|
||||||
for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
|
|
||||||
if (DRIVE_IsValid(drive))
|
|
||||||
{
|
|
||||||
*p++ = 'a' + drive;
|
|
||||||
*p++ = ':';
|
|
||||||
*p++ = '\\';
|
|
||||||
*p++ = '\0';
|
|
||||||
}
|
|
||||||
*p = '\0';
|
|
||||||
return count * 4;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return (count * 4) + 1; /* account for terminating null */
|
|
||||||
/* The API tells about these different return values */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* GetLogicalDriveStringsW (KERNEL32.@)
|
|
||||||
*/
|
|
||||||
UINT WINAPI GetLogicalDriveStringsW( UINT len, LPWSTR buffer )
|
|
||||||
{
|
|
||||||
int drive, count;
|
|
||||||
|
|
||||||
for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++)
|
|
||||||
if (DRIVE_IsValid(drive)) count++;
|
|
||||||
if (count * 4 * sizeof(WCHAR) <= len)
|
|
||||||
{
|
|
||||||
LPWSTR p = buffer;
|
|
||||||
for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
|
|
||||||
if (DRIVE_IsValid(drive))
|
|
||||||
{
|
|
||||||
*p++ = (WCHAR)('a' + drive);
|
|
||||||
*p++ = (WCHAR)':';
|
|
||||||
*p++ = (WCHAR)'\\';
|
|
||||||
*p++ = (WCHAR)'\0';
|
|
||||||
}
|
|
||||||
*p = (WCHAR)'\0';
|
|
||||||
}
|
|
||||||
return count * 4 * sizeof(WCHAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* GetLogicalDrives (KERNEL32.@)
|
|
||||||
*/
|
|
||||||
DWORD WINAPI GetLogicalDrives(void)
|
|
||||||
{
|
|
||||||
DWORD ret = 0;
|
|
||||||
int drive;
|
|
||||||
|
|
||||||
for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
|
|
||||||
{
|
|
||||||
if ( (DRIVE_IsValid(drive)) ||
|
|
||||||
(DOSDrives[drive].type == DRIVE_CDROM)) /* audio CD is also valid */
|
|
||||||
ret |= (1 << drive);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue