Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
a2963dac
Commit
a2963dac
authored
Apr 23, 2004
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Reimplemented GetLogicalDrives, GetLogicalDriveStrings and
GetDriveType using the new symlink mechanism. Made GetDriveType attempt to autodetect the type if not specified in the registry.
parent
438369af
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
221 additions
and
196 deletions
+221
-196
volume.c
dlls/kernel/volume.c
+218
-0
drive.c
files/drive.c
+3
-196
No files found.
dlls/kernel/volume.c
View file @
a2963dac
...
...
@@ -65,6 +65,16 @@ enum fs_type
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 */
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 */
static
int
create_drives
(
void
)
{
...
...
@@ -1167,6 +1221,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.@)
*
* This function is used to acquire the size of the available and
...
...
files/drive.c
View file @
a2963dac
...
...
@@ -67,23 +67,11 @@ typedef struct
LPWSTR
dos_cwd
;
/* cwd in DOS format without leading or trailing \ */
char
*
unix_cwd
;
/* cwd in Unix format without leading or trailing / */
char
*
device
;
/* raw device path */
UINT
type
;
/* drive type */
dev_t
dev
;
/* unix device number */
ino_t
ino
;
/* unix inode number */
}
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
static
DOSDRIVE
DOSDrives
[
MAX_DOS_DRIVES
];
...
...
@@ -101,23 +89,6 @@ inline static char *heap_strdup( const char *str )
}
/***********************************************************************
* 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
*/
int
DRIVE_Init
(
void
)
...
...
@@ -140,7 +111,6 @@ int DRIVE_Init(void)
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
};
static
const
WCHAR
DeviceW
[]
=
{
'D'
,
'e'
,
'v'
,
'i'
,
'c'
,
'e'
,
0
};
attr
.
Length
=
sizeof
(
attr
);
...
...
@@ -180,7 +150,6 @@ int DRIVE_Init(void)
drive
->
device
=
NULL
;
drive
->
dev
=
drive_stat_buffer
.
st_dev
;
drive
->
ino
=
drive_stat_buffer
.
st_ino
;
drive
->
type
=
DRIVE_FIXED
;
root
=
NULL
;
symlink_count
++
;
}
...
...
@@ -246,20 +215,11 @@ int DRIVE_Init(void)
drive
->
device
=
NULL
;
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
))
{
WCHAR
*
data
=
(
WCHAR
*
)((
KEY_VALUE_PARTIAL_INFORMATION
*
)
tmp
)
->
Data
;
drive
->
type
=
DRIVE_GetDriveType
(
i
,
data
);
}
/* Get the device */
RtlInitUnicodeString
(
&
nameW
,
DeviceW
);
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
);
}
/* Make the first hard disk the current drive */
if
((
DRIVE_CurDrive
==
-
1
)
&&
(
drive
->
type
==
DRIVE_FIXED
))
DRIVE_CurDrive
=
i
;
count
++
;
TRACE
(
"Drive %c: path=%s type=%s dev=%x ino=%x
\n
"
,
'A'
+
i
,
drive
->
root
,
debugstr_w
(
DRIVE_Types
[
drive
->
type
]),
(
int
)
drive
->
dev
,
(
int
)
drive
->
ino
);
TRACE
(
"Drive %c: path=%s dev=%x ino=%x
\n
"
,
'A'
+
i
,
drive
->
root
,
(
int
)
drive
->
dev
,
(
int
)
drive
->
ino
);
}
next:
...
...
@@ -291,7 +246,6 @@ int DRIVE_Init(void)
DOSDrives
[
2
].
root
=
heap_strdup
(
"/"
);
DOSDrives
[
2
].
dos_cwd
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
DOSDrives
[
2
].
dos_cwd
[
0
]));
DOSDrives
[
2
].
unix_cwd
=
heap_strdup
(
""
);
DOSDrives
[
2
].
type
=
DRIVE_FIXED
;
DOSDrives
[
2
].
device
=
NULL
;
DRIVE_CurDrive
=
2
;
}
...
...
@@ -299,7 +253,7 @@ int DRIVE_Init(void)
/* Make sure the current drive is valid */
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
)
{
...
...
@@ -563,16 +517,6 @@ const char * DRIVE_GetDevice( int drive )
}
/***********************************************************************
* DRIVE_GetType
*/
static
UINT
DRIVE_GetType
(
int
drive
)
{
if
(
!
DRIVE_IsValid
(
drive
))
return
DRIVE_NO_ROOT_DIR
;
return
DOSDrives
[
drive
].
type
;
}
/***********************************************************************
* DRIVE_Chdir
*/
int
DRIVE_Chdir
(
int
drive
,
LPCWSTR
path
)
...
...
@@ -685,70 +629,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)
*/
UINT16
WINAPI
GetCurrentDirectory16
(
UINT16
buflen
,
LPSTR
buf
)
...
...
@@ -868,76 +748,3 @@ BOOL WINAPI SetCurrentDirectoryA( LPCSTR dir )
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
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
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment