Bernhard Loos : mountmgr, ntoskrnl: METHOD_BUFFERED uses irp->AssociatedIrp .SystemBuffer for both input and output.

Alexandre Julliard julliard at winehq.org
Tue Nov 8 12:23:10 CST 2011


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

Author: Bernhard Loos <bernhardloos at googlemail.com>
Date:   Tue Nov  1 13:03:12 2011 +0100

mountmgr, ntoskrnl: METHOD_BUFFERED uses irp->AssociatedIrp.SystemBuffer for both input and output.

---

 dlls/mountmgr.sys/device.c   |    8 ++++----
 dlls/mountmgr.sys/mountmgr.c |   41 +++++++++++++++++++++++++----------------
 dlls/ntoskrnl.exe/ntoskrnl.c |   14 +++++++++++++-
 3 files changed, 42 insertions(+), 21 deletions(-)

diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c
index a3aa81c..3f393e7 100644
--- a/dlls/mountmgr.sys/device.c
+++ b/dlls/mountmgr.sys/device.c
@@ -890,7 +890,7 @@ static NTSTATUS WINAPI harddisk_ioctl( DEVICE_OBJECT *device, IRP *irp )
         info.TracksPerCylinder = 255;
         info.SectorsPerTrack = 63;
         info.BytesPerSector = 512;
-        memcpy( irp->MdlAddress->StartVa, &info, len );
+        memcpy( irp->AssociatedIrp.SystemBuffer, &info, len );
         irp->IoStatus.Information = len;
         irp->IoStatus.u.Status = STATUS_SUCCESS;
         break;
@@ -910,7 +910,7 @@ static NTSTATUS WINAPI harddisk_ioctl( DEVICE_OBJECT *device, IRP *irp )
         info.DiskSize.QuadPart = info.Geometry.Cylinders.QuadPart * info.Geometry.TracksPerCylinder *
                                  info.Geometry.SectorsPerTrack * info.Geometry.BytesPerSector;
         info.Data[0]  = 0;
-        memcpy( irp->MdlAddress->StartVa, &info, len );
+        memcpy( irp->AssociatedIrp.SystemBuffer, &info, len );
         irp->IoStatus.Information = len;
         irp->IoStatus.u.Status = STATUS_SUCCESS;
         break;
@@ -919,7 +919,7 @@ static NTSTATUS WINAPI harddisk_ioctl( DEVICE_OBJECT *device, IRP *irp )
     {
         DWORD len = min( sizeof(dev->devnum), irpsp->Parameters.DeviceIoControl.OutputBufferLength );
 
-        memcpy( irp->MdlAddress->StartVa, &dev->devnum, len );
+        memcpy( irp->AssociatedIrp.SystemBuffer, &dev->devnum, len );
         irp->IoStatus.Information = len;
         irp->IoStatus.u.Status = STATUS_SUCCESS;
         break;
@@ -932,7 +932,7 @@ static NTSTATUS WINAPI harddisk_ioctl( DEVICE_OBJECT *device, IRP *irp )
         DWORD len = min( 32, irpsp->Parameters.DeviceIoControl.OutputBufferLength );
 
         FIXME( "returning zero-filled buffer for IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS\n" );
-        memset( irp->MdlAddress->StartVa, 0, len );
+        memset( irp->AssociatedIrp.SystemBuffer, 0, len );
         irp->IoStatus.Information = len;
         irp->IoStatus.u.Status = STATUS_SUCCESS;
         break;
diff --git a/dlls/mountmgr.sys/mountmgr.c b/dlls/mountmgr.sys/mountmgr.c
index 4e9900f..afb9d92 100644
--- a/dlls/mountmgr.sys/mountmgr.c
+++ b/dlls/mountmgr.sys/mountmgr.c
@@ -153,12 +153,12 @@ static BOOL matching_mount_point( const struct mount_point *mount, const MOUNTMG
 }
 
 /* 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 )
+static NTSTATUS query_mount_points( void *buff, SIZE_T insize,
+                                    SIZE_T outsize, IO_STATUS_BLOCK *iosb )
 {
     UINT count, pos, size;
-    const MOUNTMGR_MOUNT_POINT *input = in_buff;
-    MOUNTMGR_MOUNT_POINTS *info = out_buff;
+    MOUNTMGR_MOUNT_POINT *input = buff;
+    MOUNTMGR_MOUNT_POINTS *info;
     struct mount_point *mount;
 
     /* sanity checks */
@@ -185,11 +185,18 @@ static NTSTATUS query_mount_points( const void *in_buff, SIZE_T insize,
 
     if (size > outsize)
     {
+        info = buff;
         if (size >= sizeof(info->Size)) info->Size = size;
         iosb->Information = sizeof(info->Size);
         return STATUS_MORE_ENTRIES;
     }
 
+    input = HeapAlloc( GetProcessHeap(), 0, insize );
+    if (!input)
+        return STATUS_NO_MEMORY;
+    memcpy( input, buff, insize );
+    info = buff;
+
     info->NumberOfMountPoints = count;
     count = 0;
     LIST_FOR_EACH_ENTRY( mount, &mount_points_list, struct mount_point, entry )
@@ -198,23 +205,24 @@ static NTSTATUS query_mount_points( const void *in_buff, SIZE_T insize,
 
         info->MountPoints[count].DeviceNameOffset = pos;
         info->MountPoints[count].DeviceNameLength = mount->name.Length;
-        memcpy( (char *)out_buff + pos, mount->name.Buffer, mount->name.Length );
+        memcpy( (char *)buff + pos, mount->name.Buffer, mount->name.Length );
         pos += mount->name.Length;
 
         info->MountPoints[count].SymbolicLinkNameOffset = pos;
         info->MountPoints[count].SymbolicLinkNameLength = mount->link.Length;
-        memcpy( (char *)out_buff + pos, mount->link.Buffer, mount->link.Length );
+        memcpy( (char *)buff + pos, mount->link.Buffer, mount->link.Length );
         pos += mount->link.Length;
 
         info->MountPoints[count].UniqueIdOffset = pos;
         info->MountPoints[count].UniqueIdLength = mount->id_len;
-        memcpy( (char *)out_buff + pos, mount->id, mount->id_len );
+        memcpy( (char *)buff + pos, mount->id, mount->id_len );
         pos += mount->id_len;
         pos = (pos + sizeof(WCHAR) - 1) & ~(sizeof(WCHAR) - 1);
         count++;
     }
     info->Size = pos;
     iosb->Information = pos;
+    HeapFree( GetProcessHeap(), 0, input );
     return STATUS_SUCCESS;
 }
 
@@ -271,11 +279,11 @@ 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 )
+static NTSTATUS query_unix_drive( void *buff, SIZE_T insize,
+                                  SIZE_T outsize, IO_STATUS_BLOCK *iosb )
 {
-    const struct mountmgr_unix_drive *input = in_buff;
-    struct mountmgr_unix_drive *output = out_buff;
+    const struct mountmgr_unix_drive *input = buff;
+    struct mountmgr_unix_drive *output = NULL;
     char *device, *mount_point;
     int letter = tolowerW( input->letter );
     NTSTATUS status;
@@ -302,6 +310,9 @@ static NTSTATUS query_unix_drive( const void *in_buff, SIZE_T insize,
     if (device) size += strlen(device) + 1;
     if (mount_point) size += strlen(mount_point) + 1;
 
+    input = NULL;
+    output = buff;
+
     if (size > outsize)
     {
         iosb->Information = 0;
@@ -364,9 +375,8 @@ static NTSTATUS WINAPI mountmgr_ioctl( DEVICE_OBJECT *device, IRP *irp )
     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,
+        irp->IoStatus.u.Status = query_mount_points( irp->AssociatedIrp.SystemBuffer,
                                                      irpsp->Parameters.DeviceIoControl.InputBufferLength,
-                                                     irp->MdlAddress->StartVa,
                                                      irpsp->Parameters.DeviceIoControl.OutputBufferLength,
                                                      &irp->IoStatus );
         break;
@@ -374,15 +384,14 @@ static NTSTATUS WINAPI mountmgr_ioctl( DEVICE_OBJECT *device, IRP *irp )
         if (irpsp->Parameters.DeviceIoControl.InputBufferLength < sizeof(struct mountmgr_unix_drive))
             return STATUS_INVALID_PARAMETER;
         irp->IoStatus.Information = 0;
-        irp->IoStatus.u.Status = define_unix_drive( irpsp->Parameters.DeviceIoControl.Type3InputBuffer,
+        irp->IoStatus.u.Status = define_unix_drive( irp->AssociatedIrp.SystemBuffer,
                                                     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,
+        irp->IoStatus.u.Status = query_unix_drive( irp->AssociatedIrp.SystemBuffer,
                                                    irpsp->Parameters.DeviceIoControl.InputBufferLength,
-                                                   irp->MdlAddress->StartVa,
                                                    irpsp->Parameters.DeviceIoControl.OutputBufferLength,
                                                    &irp->IoStatus );
         break;
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index 9c7916e..b00c070 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -32,6 +32,7 @@
 #include "windef.h"
 #include "winternl.h"
 #include "excpt.h"
+#include "winioctl.h"
 #include "ddk/ntddk.h"
 #include "wine/unicode.h"
 #include "wine/server.h"
@@ -151,7 +152,13 @@ static NTSTATUS process_ioctl( DEVICE_OBJECT *device, ULONG code, void *in_buff,
     memset( &mdl, 0x77, sizeof(mdl) );
 
     irp.RequestorMode = UserMode;
-    irp.AssociatedIrp.SystemBuffer = in_buff;
+    if ((code & 3) == METHOD_BUFFERED)
+    {
+        irp.AssociatedIrp.SystemBuffer = HeapAlloc( GetProcessHeap(), 0, max( in_size, *out_size ) );
+        if (!irp.AssociatedIrp.SystemBuffer)
+            return STATUS_NO_MEMORY;
+        memcpy( irp.AssociatedIrp.SystemBuffer, in_buff, in_size );
+    }
     irp.UserBuffer = out_buff;
     irp.MdlAddress = &mdl;
     irp.Tail.Overlay.s.u2.CurrentStackLocation = &irpsp;
@@ -186,6 +193,11 @@ static NTSTATUS process_ioctl( DEVICE_OBJECT *device, ULONG code, void *in_buff,
                  GetCurrentThreadId(), dispatch, device, &irp, status );
 
     *out_size = (irp.IoStatus.u.Status >= 0) ? irp.IoStatus.Information : 0;
+    if ((code & 3) == METHOD_BUFFERED)
+    {
+        memcpy( out_buff, irp.AssociatedIrp.SystemBuffer, *out_size );
+        HeapFree( GetProcessHeap(), 0, irp.AssociatedIrp.SystemBuffer );
+    }
     return irp.IoStatus.u.Status;
 }
 




More information about the wine-cvs mailing list