Alexandre Julliard : mountmgr.sys: Implemented the IOCTL_MOUNTMGR_QUERY_POINTS request.

Alexandre Julliard julliard at winehq.org
Mon Jan 7 08:38:57 CST 2008


Module: wine
Branch: master
Commit: 838f12539bf54370d0c344d8b6d880ac303ffb39
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=838f12539bf54370d0c344d8b6d880ac303ffb39

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Jan  4 14:28:47 2008 +0100

mountmgr.sys: Implemented the IOCTL_MOUNTMGR_QUERY_POINTS request.

---

 dlls/mountmgr.sys/mountmgr.c |   97 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 97 insertions(+), 0 deletions(-)

diff --git a/dlls/mountmgr.sys/mountmgr.c b/dlls/mountmgr.sys/mountmgr.c
index 875bd79..1ea73e4 100644
--- a/dlls/mountmgr.sys/mountmgr.c
+++ b/dlls/mountmgr.sys/mountmgr.c
@@ -217,6 +217,94 @@ static NTSTATUS add_mount_point( DRIVER_OBJECT *driver, DWORD type, int drive,
     return STATUS_SUCCESS;
 }
 
+/* check if a given mount point matches the requested specs */
+static BOOL matching_mount_point( const struct mount_point *mount, const MOUNTMGR_MOUNT_POINT *spec )
+{
+    if (spec->SymbolicLinkNameOffset)
+    {
+        const WCHAR *name = (const WCHAR *)((const char *)spec + spec->SymbolicLinkNameOffset);
+        if (spec->SymbolicLinkNameLength != mount->link.Length) return FALSE;
+        if (memicmpW( name, mount->link.Buffer, mount->link.Length/sizeof(WCHAR)))
+            return FALSE;
+    }
+    if (spec->DeviceNameOffset)
+    {
+        const WCHAR *name = (const WCHAR *)((const char *)spec + spec->DeviceNameOffset);
+        const UNICODE_STRING *dev_name = get_device_name( mount->device );
+        if (spec->DeviceNameLength != dev_name->Length) return FALSE;
+        if (memicmpW( name, dev_name->Buffer, dev_name->Length/sizeof(WCHAR)))
+            return FALSE;
+    }
+    if (spec->UniqueIdOffset)
+    {
+        const void *id = ((const char *)spec + spec->UniqueIdOffset);
+        if (spec->UniqueIdLength != mount->id_len) return FALSE;
+        if (memcmp( id, mount->id, mount->id_len )) return FALSE;
+    }
+    return TRUE;
+}
+
+/* implementation of IOCTL_MOUNTMGR_QUERY_POINTS */
+static NTSTATUS query_mount_points( const void *in_buff, SIZE_T insize,
+                                    void *out_buff, SIZE_T outsize, IO_STATUS_BLOCK *iosb )
+{
+    UINT i, j, pos, size;
+    const MOUNTMGR_MOUNT_POINT *input = in_buff;
+    MOUNTMGR_MOUNT_POINTS *info = out_buff;
+    UNICODE_STRING *dev_name;
+
+    /* sanity checks */
+    if (input->SymbolicLinkNameOffset + input->SymbolicLinkNameLength > insize ||
+        input->UniqueIdOffset + input->UniqueIdLength > insize ||
+        input->DeviceNameOffset + input->DeviceNameLength > insize ||
+        input->SymbolicLinkNameOffset + input->SymbolicLinkNameLength < input->SymbolicLinkNameOffset ||
+        input->UniqueIdOffset + input->UniqueIdLength < input->UniqueIdOffset ||
+        input->DeviceNameOffset + input->DeviceNameLength < input->DeviceNameOffset)
+        return STATUS_INVALID_PARAMETER;
+
+    for (i = j = size = 0; i < MAX_MOUNT_POINTS; i++)
+    {
+        if (!mount_points[i].device) continue;
+        if (!matching_mount_point( &mount_points[i], input )) continue;
+        size += get_device_name(mount_points[i].device)->Length;
+        size += mount_points[i].link.Length;
+        j++;
+    }
+    pos = FIELD_OFFSET( MOUNTMGR_MOUNT_POINTS, MountPoints[j] );
+    size += pos;
+
+    if (size > outsize)
+    {
+        if (size >= sizeof(info->Size)) info->Size = size;
+        iosb->Information = sizeof(info->Size);
+        return STATUS_MORE_ENTRIES;
+    }
+
+    info->NumberOfMountPoints = j;
+    for (i = j = 0; i < MAX_MOUNT_POINTS; i++)
+    {
+        if (!mount_points[i].device) continue;
+        if (!matching_mount_point( &mount_points[i], input )) continue;
+        info->MountPoints[j].UniqueIdOffset = 0;  /* FIXME */
+        info->MountPoints[j].UniqueIdLength = 0;
+
+        dev_name = get_device_name( mount_points[i].device );
+        info->MountPoints[j].DeviceNameOffset = pos;
+        info->MountPoints[j].DeviceNameLength = dev_name->Length;
+        memcpy( (char *)out_buff + pos, dev_name->Buffer, dev_name->Length );
+        pos += dev_name->Length;
+
+        info->MountPoints[j].SymbolicLinkNameOffset = pos;
+        info->MountPoints[j].SymbolicLinkNameLength = mount_points[i].link.Length;
+        memcpy( (char *)out_buff + pos, mount_points[i].link.Buffer, mount_points[i].link.Length );
+        pos += mount_points[i].link.Length;
+        j++;
+    }
+    info->Size = pos;
+    iosb->Information = pos;
+    return STATUS_SUCCESS;
+}
+
 /* handler for ioctls on the mount manager device */
 static NTSTATUS WINAPI mountmgr_ioctl( DEVICE_OBJECT *device, IRP *irp )
 {
@@ -229,6 +317,15 @@ static NTSTATUS WINAPI mountmgr_ioctl( DEVICE_OBJECT *device, IRP *irp )
 
     switch(irpsp->Parameters.DeviceIoControl.IoControlCode)
     {
+    case IOCTL_MOUNTMGR_QUERY_POINTS:
+        if (irpsp->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_MOUNT_POINT))
+            return STATUS_INVALID_PARAMETER;
+        irp->IoStatus.u.Status = query_mount_points( 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;




More information about the wine-cvs mailing list