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

This commit is contained in:
Bernhard Loos 2011-11-01 13:03:12 +01:00 committed by Alexandre Julliard
parent 6221e300bc
commit a1377319bc
3 changed files with 42 additions and 21 deletions

View File

@ -890,7 +890,7 @@ static NTSTATUS WINAPI harddisk_ioctl( DEVICE_OBJECT *device, IRP *irp )
info.TracksPerCylinder = 255; info.TracksPerCylinder = 255;
info.SectorsPerTrack = 63; info.SectorsPerTrack = 63;
info.BytesPerSector = 512; info.BytesPerSector = 512;
memcpy( irp->MdlAddress->StartVa, &info, len ); memcpy( irp->AssociatedIrp.SystemBuffer, &info, len );
irp->IoStatus.Information = len; irp->IoStatus.Information = len;
irp->IoStatus.u.Status = STATUS_SUCCESS; irp->IoStatus.u.Status = STATUS_SUCCESS;
break; 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.DiskSize.QuadPart = info.Geometry.Cylinders.QuadPart * info.Geometry.TracksPerCylinder *
info.Geometry.SectorsPerTrack * info.Geometry.BytesPerSector; info.Geometry.SectorsPerTrack * info.Geometry.BytesPerSector;
info.Data[0] = 0; info.Data[0] = 0;
memcpy( irp->MdlAddress->StartVa, &info, len ); memcpy( irp->AssociatedIrp.SystemBuffer, &info, len );
irp->IoStatus.Information = len; irp->IoStatus.Information = len;
irp->IoStatus.u.Status = STATUS_SUCCESS; irp->IoStatus.u.Status = STATUS_SUCCESS;
break; 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 ); 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.Information = len;
irp->IoStatus.u.Status = STATUS_SUCCESS; irp->IoStatus.u.Status = STATUS_SUCCESS;
break; break;
@ -932,7 +932,7 @@ static NTSTATUS WINAPI harddisk_ioctl( DEVICE_OBJECT *device, IRP *irp )
DWORD len = min( 32, irpsp->Parameters.DeviceIoControl.OutputBufferLength ); DWORD len = min( 32, irpsp->Parameters.DeviceIoControl.OutputBufferLength );
FIXME( "returning zero-filled buffer for IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS\n" ); 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.Information = len;
irp->IoStatus.u.Status = STATUS_SUCCESS; irp->IoStatus.u.Status = STATUS_SUCCESS;
break; break;

View File

@ -153,12 +153,12 @@ static BOOL matching_mount_point( const struct mount_point *mount, const MOUNTMG
} }
/* implementation of IOCTL_MOUNTMGR_QUERY_POINTS */ /* implementation of IOCTL_MOUNTMGR_QUERY_POINTS */
static NTSTATUS query_mount_points( const void *in_buff, SIZE_T insize, static NTSTATUS query_mount_points( void *buff, SIZE_T insize,
void *out_buff, SIZE_T outsize, IO_STATUS_BLOCK *iosb ) SIZE_T outsize, IO_STATUS_BLOCK *iosb )
{ {
UINT count, pos, size; UINT count, pos, size;
const MOUNTMGR_MOUNT_POINT *input = in_buff; MOUNTMGR_MOUNT_POINT *input = buff;
MOUNTMGR_MOUNT_POINTS *info = out_buff; MOUNTMGR_MOUNT_POINTS *info;
struct mount_point *mount; struct mount_point *mount;
/* sanity checks */ /* sanity checks */
@ -185,11 +185,18 @@ static NTSTATUS query_mount_points( const void *in_buff, SIZE_T insize,
if (size > outsize) if (size > outsize)
{ {
info = buff;
if (size >= sizeof(info->Size)) info->Size = size; if (size >= sizeof(info->Size)) info->Size = size;
iosb->Information = sizeof(info->Size); iosb->Information = sizeof(info->Size);
return STATUS_MORE_ENTRIES; return STATUS_MORE_ENTRIES;
} }
input = HeapAlloc( GetProcessHeap(), 0, insize );
if (!input)
return STATUS_NO_MEMORY;
memcpy( input, buff, insize );
info = buff;
info->NumberOfMountPoints = count; info->NumberOfMountPoints = count;
count = 0; count = 0;
LIST_FOR_EACH_ENTRY( mount, &mount_points_list, struct mount_point, entry ) 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].DeviceNameOffset = pos;
info->MountPoints[count].DeviceNameLength = mount->name.Length; 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; pos += mount->name.Length;
info->MountPoints[count].SymbolicLinkNameOffset = pos; info->MountPoints[count].SymbolicLinkNameOffset = pos;
info->MountPoints[count].SymbolicLinkNameLength = mount->link.Length; 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; pos += mount->link.Length;
info->MountPoints[count].UniqueIdOffset = pos; info->MountPoints[count].UniqueIdOffset = pos;
info->MountPoints[count].UniqueIdLength = mount->id_len; 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 += mount->id_len;
pos = (pos + sizeof(WCHAR) - 1) & ~(sizeof(WCHAR) - 1); pos = (pos + sizeof(WCHAR) - 1) & ~(sizeof(WCHAR) - 1);
count++; count++;
} }
info->Size = pos; info->Size = pos;
iosb->Information = pos; iosb->Information = pos;
HeapFree( GetProcessHeap(), 0, input );
return STATUS_SUCCESS; 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 */ /* implementation of IOCTL_MOUNTMGR_QUERY_UNIX_DRIVE */
static NTSTATUS query_unix_drive( const void *in_buff, SIZE_T insize, static NTSTATUS query_unix_drive( void *buff, SIZE_T insize,
void *out_buff, SIZE_T outsize, IO_STATUS_BLOCK *iosb ) SIZE_T outsize, IO_STATUS_BLOCK *iosb )
{ {
const struct mountmgr_unix_drive *input = in_buff; const struct mountmgr_unix_drive *input = buff;
struct mountmgr_unix_drive *output = out_buff; struct mountmgr_unix_drive *output = NULL;
char *device, *mount_point; char *device, *mount_point;
int letter = tolowerW( input->letter ); int letter = tolowerW( input->letter );
NTSTATUS status; 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 (device) size += strlen(device) + 1;
if (mount_point) size += strlen(mount_point) + 1; if (mount_point) size += strlen(mount_point) + 1;
input = NULL;
output = buff;
if (size > outsize) if (size > outsize)
{ {
iosb->Information = 0; iosb->Information = 0;
@ -364,9 +375,8 @@ static NTSTATUS WINAPI mountmgr_ioctl( DEVICE_OBJECT *device, IRP *irp )
case IOCTL_MOUNTMGR_QUERY_POINTS: case IOCTL_MOUNTMGR_QUERY_POINTS:
if (irpsp->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_MOUNT_POINT)) if (irpsp->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_MOUNT_POINT))
return STATUS_INVALID_PARAMETER; 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, irpsp->Parameters.DeviceIoControl.InputBufferLength,
irp->MdlAddress->StartVa,
irpsp->Parameters.DeviceIoControl.OutputBufferLength, irpsp->Parameters.DeviceIoControl.OutputBufferLength,
&irp->IoStatus ); &irp->IoStatus );
break; 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)) if (irpsp->Parameters.DeviceIoControl.InputBufferLength < sizeof(struct mountmgr_unix_drive))
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
irp->IoStatus.Information = 0; 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 ); irpsp->Parameters.DeviceIoControl.InputBufferLength );
break; break;
case IOCTL_MOUNTMGR_QUERY_UNIX_DRIVE: case IOCTL_MOUNTMGR_QUERY_UNIX_DRIVE:
if (irpsp->Parameters.DeviceIoControl.InputBufferLength < sizeof(struct mountmgr_unix_drive)) if (irpsp->Parameters.DeviceIoControl.InputBufferLength < sizeof(struct mountmgr_unix_drive))
return STATUS_INVALID_PARAMETER; 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, irpsp->Parameters.DeviceIoControl.InputBufferLength,
irp->MdlAddress->StartVa,
irpsp->Parameters.DeviceIoControl.OutputBufferLength, irpsp->Parameters.DeviceIoControl.OutputBufferLength,
&irp->IoStatus ); &irp->IoStatus );
break; break;

View File

@ -32,6 +32,7 @@
#include "windef.h" #include "windef.h"
#include "winternl.h" #include "winternl.h"
#include "excpt.h" #include "excpt.h"
#include "winioctl.h"
#include "ddk/ntddk.h" #include "ddk/ntddk.h"
#include "wine/unicode.h" #include "wine/unicode.h"
#include "wine/server.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) ); memset( &mdl, 0x77, sizeof(mdl) );
irp.RequestorMode = UserMode; 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.UserBuffer = out_buff;
irp.MdlAddress = &mdl; irp.MdlAddress = &mdl;
irp.Tail.Overlay.s.u2.CurrentStackLocation = &irpsp; 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 ); GetCurrentThreadId(), dispatch, device, &irp, status );
*out_size = (irp.IoStatus.u.Status >= 0) ? irp.IoStatus.Information : 0; *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; return irp.IoStatus.u.Status;
} }