[RFC] kernel32: Try to get the drive type from the mountmgr first

GOUJON Alexandre 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());
>               continue;
>           }
> 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;
>               break;
>           default:
>               ret = DRIVE_UNKNOWN;
Hi,

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 mailing list