diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c index 9036654832c..00b59ed617c 100644 --- a/dlls/mountmgr.sys/device.c +++ b/dlls/mountmgr.sys/device.c @@ -568,6 +568,22 @@ NTSTATUS remove_dos_device( int letter, const char *udi ) return STATUS_NO_SUCH_DEVICE; } +/* query information about an existing dos drive, by letter or udi */ +NTSTATUS query_dos_device( int letter, DWORD *type, const char **device, const char **mount_point ) +{ + struct dos_drive *drive; + + LIST_FOR_EACH_ENTRY( drive, &drives_list, struct dos_drive, entry ) + { + if (drive->drive != letter) continue; + if (type) *type = drive->type; + if (device) *device = drive->unix_device; + if (mount_point) *mount_point = drive->unix_mount; + return STATUS_SUCCESS; + } + return STATUS_NO_SUCH_DEVICE; +} + /* handler for ioctls on the harddisk device */ static NTSTATUS WINAPI harddisk_ioctl( DEVICE_OBJECT *device, IRP *irp ) { diff --git a/dlls/mountmgr.sys/mountmgr.c b/dlls/mountmgr.sys/mountmgr.c index c633588217f..3c1aa88668b 100644 --- a/dlls/mountmgr.sys/mountmgr.c +++ b/dlls/mountmgr.sys/mountmgr.c @@ -265,6 +265,61 @@ static NTSTATUS define_unix_drive( const void *in_buff, SIZE_T insize ) } } +/* implementation of IOCTL_MOUNTMGR_QUERY_UNIX_DRIVE */ +static NTSTATUS query_unix_drive( const void *in_buff, SIZE_T insize, + void *out_buff, SIZE_T outsize, IO_STATUS_BLOCK *iosb ) +{ + const struct mountmgr_unix_drive *input = in_buff; + struct mountmgr_unix_drive *output = out_buff; + const char *device, *mount_point; + int letter = tolowerW( input->letter ); + NTSTATUS status; + DWORD size, type; + char *ptr; + + if (letter < 'a' || letter > 'z') return STATUS_INVALID_PARAMETER; + + if ((status = query_dos_device( letter - 'a', &type, &device, &mount_point ))) return status; + + size = sizeof(*output); + if (device) size += strlen(device) + 1; + if (mount_point) size += strlen(mount_point) + 1; + + if (size > outsize) + { + if (size >= FIELD_OFFSET( struct mountmgr_unix_drive, size ) + sizeof(output->size)) + output->size = size; + iosb->Information = FIELD_OFFSET( struct mountmgr_unix_drive, size ) + sizeof(output->size); + return STATUS_MORE_ENTRIES; + } + output->size = size; + output->letter = letter; + output->type = type; + ptr = (char *)(output + 1); + + if (mount_point) + { + output->mount_point_offset = ptr - (char *)output; + strcpy( ptr, mount_point ); + ptr += strlen(ptr) + 1; + } + else output->mount_point_offset = 0; + + if (device) + { + output->device_offset = ptr - (char *)output; + strcpy( ptr, device ); + ptr += strlen(ptr) + 1; + } + else output->device_offset = 0; + + TRACE( "returning %c: dev %s mount %s type %u\n", + letter, debugstr_a(device), debugstr_a(mount_point), type ); + + iosb->Information = ptr - (char *)output; + return STATUS_SUCCESS; +} + /* handler for ioctls on the mount manager device */ static NTSTATUS WINAPI mountmgr_ioctl( DEVICE_OBJECT *device, IRP *irp ) { @@ -293,6 +348,15 @@ static NTSTATUS WINAPI mountmgr_ioctl( DEVICE_OBJECT *device, IRP *irp ) irp->IoStatus.u.Status = define_unix_drive( irpsp->Parameters.DeviceIoControl.Type3InputBuffer, irpsp->Parameters.DeviceIoControl.InputBufferLength ); break; + case IOCTL_MOUNTMGR_QUERY_UNIX_DRIVE: + if (irpsp->Parameters.DeviceIoControl.InputBufferLength < sizeof(struct mountmgr_unix_drive)) + return STATUS_INVALID_PARAMETER; + irp->IoStatus.u.Status = query_unix_drive( irpsp->Parameters.DeviceIoControl.Type3InputBuffer, + irpsp->Parameters.DeviceIoControl.InputBufferLength, + irp->MdlAddress->StartVa, + irpsp->Parameters.DeviceIoControl.OutputBufferLength, + &irp->IoStatus ); + break; default: FIXME( "ioctl %x not supported\n", irpsp->Parameters.DeviceIoControl.IoControlCode ); irp->IoStatus.u.Status = STATUS_NOT_SUPPORTED; diff --git a/dlls/mountmgr.sys/mountmgr.h b/dlls/mountmgr.sys/mountmgr.h index 1b4b3f632fc..63e9b75da10 100644 --- a/dlls/mountmgr.sys/mountmgr.h +++ b/dlls/mountmgr.sys/mountmgr.h @@ -43,6 +43,7 @@ extern void initialize_diskarbitration(void); extern NTSTATUS add_dos_device( int letter, const char *udi, const char *device, const char *mount_point, DWORD type ); extern NTSTATUS remove_dos_device( int letter, const char *udi ); +extern NTSTATUS query_dos_device( int letter, DWORD *type, const char **device, const char **mount_point ); extern NTSTATUS WINAPI harddisk_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *path ); /* mount point functions */ diff --git a/include/ddk/mountmgr.h b/include/ddk/mountmgr.h index 05eeeac282c..f0e836f6e11 100644 --- a/include/ddk/mountmgr.h +++ b/include/ddk/mountmgr.h @@ -53,6 +53,7 @@ static const WCHAR MOUNTMGR_DOS_DEVICE_NAME[] = {'\\','\\','.','\\','M','o','u', #ifdef WINE_MOUNTMGR_EXTENSIONS #define IOCTL_MOUNTMGR_DEFINE_UNIX_DRIVE CTL_CODE(MOUNTMGRCONTROLTYPE, 32, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_MOUNTMGR_QUERY_UNIX_DRIVE CTL_CODE(MOUNTMGRCONTROLTYPE, 33, METHOD_BUFFERED, FILE_READ_ACCESS) struct mountmgr_unix_drive {