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