[RFC] kernel32: Try to get the drive type from the mountmgr first
ale.goujon at gmail.com
Sat Jul 28 08:28:37 CDT 2012
On 07/22/2012 03:36 PM, Alexandre Goujon wrote:
> Should fix bug #17037
> dlls/kernel32/tests/volume.c | 2 ++
> dlls/kernel32/volume.c | 3 ++-
> 2 files changed, 4 insertions(+), 1 deletion(-)
> diff --git a/dlls/kernel32/tests/volume.c b/dlls/kernel32/tests/volume.c
> index 8152ae1..175095f 100644
> --- a/dlls/kernel32/tests/volume.c
> +++ b/dlls/kernel32/tests/volume.c
> @@ -908,6 +908,8 @@ static void test_cdrom_ioctl(void)
> handle = CreateFileA(drive_full_path, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
> if(handle == INVALID_HANDLE_VALUE)
> + /* GetDriveType also reports DRIVE_CDROM even if there is no disc in is the drive.
> + In this case, the last error is ERROR_ACCESS_DENIED */
> trace("Failed to open the device : %u\n", GetLastError());
> diff --git a/dlls/kernel32/volume.c b/dlls/kernel32/volume.c
> index 8377e41..cdd4e46 100644
> --- a/dlls/kernel32/volume.c
> +++ b/dlls/kernel32/volume.c
> @@ -1538,6 +1538,7 @@ UINT WINAPI GetDriveTypeW(LPCWSTR root) /* [in] String describing drive */
> HANDLE handle;
> UINT ret;
> + if ((ret = get_mountmgr_drive_type( root )) != DRIVE_UNKNOWN) return ret;
> if (!open_device_root( root, &handle )) return DRIVE_NO_ROOT_DIR;
> status = NtQueryVolumeInformationFile( handle, &io, &info, sizeof(info), FileFsDeviceInformation );
> @@ -1557,7 +1558,7 @@ UINT WINAPI GetDriveTypeW(LPCWSTR root) /* [in] String describing drive */
> 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 if ((ret = get_mountmgr_drive_type( root )) == DRIVE_UNKNOWN) ret = DRIVE_FIXED;
> + else ret = DRIVE_FIXED;
> ret = DRIVE_UNKNOWN;
This one is marked as Pending meaning it's unclear at first glance why
this change is needed.
So here's a detailed explanation.
The app in bug #17037 calls GetDriveType on each drive from A to Z
looking for a CD drive.
It appears genuine GetDriveType returns DRIVE_CDROM even if no disc is
in the drive.
Let's suppose D is the letter mapped to your CD drive.
Calling GetDriveTypeW( L"D:\" ) will first try to get a handle from
open_device_root which fails.
The last error is STATUS_OBJECT_PATH_NOT_FOUND, hence the bug.
In fact, open_device_root calls NtOpenFile with \??\D:\.
Following the call chain, the culprit is nt_to_unix_file_name_attr which
calls stat() on "/home/<yourlogin>/.wine/dosdevices/d:/".
This file doesn't exist because the drive has no mount point but
"/home/alex/.wine/dosdevices/d::/" does exist.
Either I had to change nt_to_unix_file_name_attr to call stat(D::) in
case where stat(D:) fails or use the mountmgr.
And as get_mountmgr_drive_type was already called in GetDriveType, I
though moving the call before open_device_root was simpler and less
invasive than modifying nt_to_unix_file_name_attr.
Is it the proper way to fix the bug ?
Any idea on how to get that one in ?
More information about the wine-devel