mirror of
https://github.com/reactos/reactos.git
synced 2024-10-05 00:43:21 +00:00
[KS]
- Probe input / output parameters when requests are coming from user mode - Fix KspPinPropertyHandler to use the correct output parameter location - Fix KsHandleSizedListQuery to use the correct output parameter location - Tested in Vbox 4.1.4 r74291 - May fix a few sound drivers who are having user mode extra utility apps svn path=/trunk/; revision=54191
This commit is contained in:
parent
bb8b519d56
commit
0605f7832f
|
@ -333,7 +333,7 @@ KspPinPropertyHandler(
|
||||||
LPGUID Guid;
|
LPGUID Guid;
|
||||||
|
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
Buffer = Irp->UserBuffer;
|
Buffer = Data;
|
||||||
|
|
||||||
//DPRINT("KsPinPropertyHandler Irp %p Property %p Data %p DescriptorsCount %u Descriptor %p OutputLength %u Id %u\n", Irp, Property, Data, DescriptorsCount, Descriptor, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Property->Id);
|
//DPRINT("KsPinPropertyHandler Irp %p Property %p Data %p DescriptorsCount %u Descriptor %p OutputLength %u Id %u\n", Irp, Property, Data, DescriptorsCount, Descriptor, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Property->Id);
|
||||||
|
|
||||||
|
@ -775,7 +775,7 @@ KsHandleSizedListQuery(
|
||||||
Size = DataItemSize * DataItemsCount + sizeof(KSMULTIPLE_ITEM);
|
Size = DataItemSize * DataItemsCount + sizeof(KSMULTIPLE_ITEM);
|
||||||
|
|
||||||
/* get multiple item */
|
/* get multiple item */
|
||||||
Item = (PKSMULTIPLE_ITEM)Irp->UserBuffer;
|
Item = (PKSMULTIPLE_ITEM)Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
|
||||||
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == 0)
|
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -136,38 +136,131 @@ KspPropertyHandler(
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PFNKSHANDLER PropertyHandler = NULL;
|
PFNKSHANDLER PropertyHandler = NULL;
|
||||||
ULONG Index;
|
ULONG Index, InputBufferLength, OutputBufferLength, TotalSize;
|
||||||
LPGUID Guid;
|
LPGUID Guid;
|
||||||
|
|
||||||
/* get current irp stack */
|
/* get current irp stack */
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
/* get parameters */
|
||||||
|
OutputBufferLength = (IoStack->Parameters.DeviceIoControl.OutputBufferLength + 7) & ~7;
|
||||||
|
InputBufferLength = IoStack->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
|
|
||||||
|
/* check for invalid buffer length size */
|
||||||
|
if (OutputBufferLength < IoStack->Parameters.DeviceIoControl.OutputBufferLength)
|
||||||
|
{
|
||||||
|
/* unsigned overflow */
|
||||||
|
return STATUS_INVALID_BUFFER_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check for integer overflow */
|
||||||
|
if (InputBufferLength + OutputBufferLength < IoStack->Parameters.DeviceIoControl.OutputBufferLength)
|
||||||
|
{
|
||||||
|
/* overflow */
|
||||||
|
return STATUS_INVALID_BUFFER_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
/* check if inputbuffer at least holds KSPROPERTY item */
|
/* check if inputbuffer at least holds KSPROPERTY item */
|
||||||
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY))
|
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY))
|
||||||
{
|
{
|
||||||
/* invalid parameter */
|
/* invalid parameter */
|
||||||
Irp->IoStatus.Information = sizeof(KSPROPERTY);
|
|
||||||
return STATUS_INVALID_BUFFER_SIZE;
|
return STATUS_INVALID_BUFFER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME probe the input / output buffer if from user mode */
|
/* get total size */
|
||||||
|
TotalSize = InputBufferLength + OutputBufferLength;
|
||||||
|
|
||||||
/* get input property request */
|
/* get input property request */
|
||||||
Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
|
Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
|
||||||
|
|
||||||
// DPRINT("KspPropertyHandler Irp %p PropertySetsCount %u PropertySet %p Allocator %p PropertyItemSize %u ExpectedPropertyItemSize %u\n", Irp, PropertySetsCount, PropertySet, Allocator, PropertyItemSize, sizeof(KSPROPERTY_ITEM));
|
/* have the parameters been checked yet */
|
||||||
|
if (!Irp->AssociatedIrp.SystemBuffer)
|
||||||
|
{
|
||||||
|
/* is it from user mode */
|
||||||
|
if (Irp->RequestorMode == UserMode)
|
||||||
|
{
|
||||||
|
/* probe user buffer */
|
||||||
|
ProbeForRead(IoStack->Parameters.DeviceIoControl.Type3InputBuffer, InputBufferLength, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do we have an allocator */
|
||||||
|
if ((Allocator) && (Property->Flags & (KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET)))
|
||||||
|
{
|
||||||
|
/* call allocator */
|
||||||
|
Status = Allocator(Irp, TotalSize, (Property->Flags & KSPROPERTY_TYPE_GET));
|
||||||
|
|
||||||
|
/* check for success */
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* allocate buffer */
|
||||||
|
Irp->AssociatedIrp.SystemBuffer = AllocateItem(NonPagedPool, TotalSize);
|
||||||
|
|
||||||
|
/* sanity check */
|
||||||
|
ASSERT(Irp->AssociatedIrp.SystemBuffer != NULL);
|
||||||
|
|
||||||
|
/* mark irp as buffered so that changes the stream headers are propagated back */
|
||||||
|
Irp->Flags |= IRP_DEALLOCATE_BUFFER | IRP_BUFFERED_IO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now copy the buffer */
|
||||||
|
RtlCopyMemory((PVOID)((ULONG_PTR)Irp->AssociatedIrp.SystemBuffer + OutputBufferLength), IoStack->Parameters.DeviceIoControl.Type3InputBuffer, InputBufferLength);
|
||||||
|
|
||||||
|
/* use new property buffer */
|
||||||
|
Property = (PKSPROPERTY)((ULONG_PTR)Irp->AssociatedIrp.SystemBuffer + OutputBufferLength);
|
||||||
|
|
||||||
|
/* is it a set operation */
|
||||||
|
if (Property->Flags & KSPROPERTY_TYPE_SET)
|
||||||
|
{
|
||||||
|
/* for set operations, the output parameters need to be copied */
|
||||||
|
if (Irp->RequestorMode == UserMode)
|
||||||
|
{
|
||||||
|
/* probe user parameter */
|
||||||
|
ProbeForRead(Irp->UserBuffer, IoStack->Parameters.DeviceIoControl.OutputBufferLength, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy parameters, needs un-aligned parameter length */
|
||||||
|
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, Irp->UserBuffer, IoStack->Parameters.DeviceIoControl.OutputBufferLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* is there an output buffer */
|
||||||
|
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength)
|
||||||
|
{
|
||||||
|
/* is it from user mode */
|
||||||
|
if (Irp->RequestorMode == UserMode)
|
||||||
|
{
|
||||||
|
/* probe buffer for writing */
|
||||||
|
ProbeForWrite(Irp->UserBuffer, IoStack->Parameters.DeviceIoControl.OutputBufferLength, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Allocator || !(Property->Flags & KSPROPERTY_TYPE_GET))
|
||||||
|
{
|
||||||
|
/* it is an input operation */
|
||||||
|
Irp->Flags |= IRP_INPUT_OPERATION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* use new property buffer */
|
||||||
|
Property = (PKSPROPERTY)((ULONG_PTR)Irp->AssociatedIrp.SystemBuffer + OutputBufferLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT("KspPropertyHandler Irp %p PropertySetsCount %u PropertySet %p Allocator %p PropertyItemSize %u ExpectedPropertyItemSize %u\n", Irp, PropertySetsCount, PropertySet, Allocator, PropertyItemSize, sizeof(KSPROPERTY_ITEM));
|
||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
ASSERT(PropertyItemSize == 0 || PropertyItemSize == sizeof(KSPROPERTY_ITEM));
|
ASSERT(PropertyItemSize == 0 || PropertyItemSize == sizeof(KSPROPERTY_ITEM));
|
||||||
|
|
||||||
/* find the property handler */
|
/* find the property handler */
|
||||||
Status = FindPropertyHandler(&Irp->IoStatus, PropertySet, PropertySetsCount, Property, IoStack->Parameters.DeviceIoControl.InputBufferLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Irp->UserBuffer, &PropertyHandler, &Set);
|
Status = FindPropertyHandler(&Irp->IoStatus, PropertySet, PropertySetsCount, Property, InputBufferLength, OutputBufferLength, Irp->AssociatedIrp.SystemBuffer, &PropertyHandler, &Set);
|
||||||
|
|
||||||
if (NT_SUCCESS(Status) && PropertyHandler)
|
if (NT_SUCCESS(Status) && PropertyHandler)
|
||||||
{
|
{
|
||||||
/* call property handler */
|
/* call property handler */
|
||||||
KSPROPERTY_SET_IRP_STORAGE(Irp) = Set;
|
KSPROPERTY_SET_IRP_STORAGE(Irp) = Set;
|
||||||
Status = PropertyHandler(Irp, Property, Irp->UserBuffer);
|
Status = PropertyHandler(Irp, Property, Irp->AssociatedIrp.SystemBuffer);
|
||||||
|
|
||||||
if (Status == STATUS_BUFFER_TOO_SMALL)
|
if (Status == STATUS_BUFFER_TOO_SMALL)
|
||||||
{
|
{
|
||||||
|
@ -185,7 +278,7 @@ KspPropertyHandler(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* re-call property handler */
|
/* re-call property handler */
|
||||||
Status = PropertyHandler(Irp, Property, Irp->UserBuffer);
|
Status = PropertyHandler(Irp, Property, Irp->AssociatedIrp.SystemBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,7 +293,7 @@ KspPropertyHandler(
|
||||||
}
|
}
|
||||||
|
|
||||||
// get output buffer
|
// get output buffer
|
||||||
Guid = (LPGUID)Irp->UserBuffer;
|
Guid = (LPGUID)Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
|
||||||
// copy property guids from property sets
|
// copy property guids from property sets
|
||||||
for(Index = 0; Index < PropertySetsCount; Index++)
|
for(Index = 0; Index < PropertySetsCount; Index++)
|
||||||
|
|
Loading…
Reference in a new issue