- Implement FastDeviceIoControl for IPortFilterWavePci

- Partly implement fast property handler

svn path=/trunk/; revision=40640
This commit is contained in:
Johannes Anderwald 2009-04-21 21:44:15 +00:00
parent cbc24ae88e
commit 5979b226fa
3 changed files with 269 additions and 121 deletions

View file

@ -244,7 +244,6 @@ IPortFilterWavePci_fnClose(
{
This->Pins[Index]->lpVtbl->Close(This->Pins[Index], DeviceObject, NULL);
}
}
@ -298,8 +297,49 @@ IPortFilterWavePci_fnFastDeviceIoControl(
OUT PIO_STATUS_BLOCK StatusBlock,
IN PDEVICE_OBJECT DeviceObject)
{
UNIMPLEMENTED
return FALSE;
ULONG Index;
PKSPROPERTY Property;
NTSTATUS Status;
ISubdevice * SubDevice = NULL;
PSUBDEVICE_DESCRIPTOR Descriptor = NULL;
IPortFilterWavePciImpl * This = (IPortFilterWavePciImpl *)iface;
Property = (PKSPROPERTY)InputBuffer;
if (InputBufferLength < sizeof(KSPROPERTY))
return FALSE;
/* get private interface */
Status = This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&SubDevice);
if (!NT_SUCCESS(Status))
return FALSE;
/* get descriptor */
Status = SubDevice->lpVtbl->GetDescriptor(SubDevice, &Descriptor);
if (!NT_SUCCESS(Status))
{
SubDevice->lpVtbl->Release(SubDevice);
return FALSE;
}
Status = STATUS_UNSUCCESSFUL;
for(Index = 0; Index < Descriptor->FilterPropertySet.FreeKsPropertySetOffset; Index++)
{
if (IsEqualGUIDAligned(&Property->Set, Descriptor->FilterPropertySet.Properties[Index].Set))
{
Status = FastPropertyHandler(FileObject, (PKSPROPERTY)InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, StatusBlock,
1,
&Descriptor->FilterPropertySet.Properties[Index],
Descriptor, SubDevice);
break;
}
}
if (NT_SUCCESS(Status))
return TRUE;
else
return FALSE;
}
/*

View file

@ -249,6 +249,20 @@ PcPropertyHandler(
IN PIRP Irp,
IN PSUBDEVICE_DESCRIPTOR Descriptor);
NTSTATUS
NTAPI
FastPropertyHandler(
IN PFILE_OBJECT FileObject,
IN PKSPROPERTY UNALIGNED Property,
IN ULONG PropertyLength,
IN OUT PVOID UNALIGNED Data,
IN ULONG DataLength,
OUT PIO_STATUS_BLOCK IoStatus,
IN ULONG PropertySetsCount,
IN const KSPROPERTY_SET *PropertySet,
IN PSUBDEVICE_DESCRIPTOR Descriptor,
IN ISubdevice *SubDevice);
PDEVICE_OBJECT
GetDeviceObject(
IPortWaveCyclic* iface);

View file

@ -8,9 +8,18 @@
#include "private.h"
NTSTATUS
FindPropertyHandler(
IN PIO_STATUS_BLOCK IoStatus,
IN PSUBDEVICE_DESCRIPTOR Descriptor,
IN PKSPROPERTY Property,
IN ULONG InputBufferLength,
IN ULONG OutputBufferLength,
OUT PFNKSHANDLER *PropertyHandler);
NTSTATUS
HandlePropertyInstances(
IN PIRP Irp,
IN PIO_STATUS_BLOCK IoStatus,
IN PKSIDENTIFIER Request,
IN OUT PVOID Data,
IN PSUBDEVICE_DESCRIPTOR Descriptor,
@ -21,8 +30,8 @@ HandlePropertyInstances(
if (Pin->PinId >= Descriptor->Factory.PinDescriptorCount)
{
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
IoStatus->Information = 0;
IoStatus->Status = STATUS_INVALID_PARAMETER;
return STATUS_INVALID_PARAMETER;
}
@ -35,14 +44,14 @@ HandlePropertyInstances(
Instances->CurrentCount = Descriptor->Factory.Instances[Pin->PinId].CurrentPinInstanceCount;
Irp->IoStatus.Information = sizeof(KSPIN_CINSTANCES);
Irp->IoStatus.Status = STATUS_SUCCESS;
IoStatus->Information = sizeof(KSPIN_CINSTANCES);
IoStatus->Status = STATUS_SUCCESS;
return STATUS_SUCCESS;
}
NTSTATUS
HandleNecessaryPropertyInstances(
IN PIRP Irp,
IN PIO_STATUS_BLOCK IoStatus,
IN PKSIDENTIFIER Request,
IN OUT PVOID Data,
IN PSUBDEVICE_DESCRIPTOR Descriptor)
@ -52,36 +61,78 @@ HandleNecessaryPropertyInstances(
if (Pin->PinId >= Descriptor->Factory.PinDescriptorCount)
{
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
IoStatus->Information = 0;
IoStatus->Status = STATUS_INVALID_PARAMETER;
return STATUS_INVALID_PARAMETER;
}
Result = (PULONG)Data;
*Result = Descriptor->Factory.Instances[Pin->PinId].MinFilterInstanceCount;
Irp->IoStatus.Information = sizeof(ULONG);
Irp->IoStatus.Status = STATUS_SUCCESS;
IoStatus->Information = sizeof(ULONG);
IoStatus->Status = STATUS_SUCCESS;
return STATUS_SUCCESS;
}
NTSTATUS
HandleDataIntersection(
IN PIRP Irp,
IN PIO_STATUS_BLOCK IoStatus,
IN PKSIDENTIFIER Request,
IN OUT PVOID Data,
IN PSUBDEVICE_DESCRIPTOR Descriptor)
IN ULONG DataLength,
IN PSUBDEVICE_DESCRIPTOR Descriptor,
IN ISubdevice *SubDevice)
{
KSP_PIN * Pin = (KSP_PIN*)Request;
PKSMULTIPLE_ITEM MultipleItem;
PKSDATARANGE DataRange;
NTSTATUS Status = STATUS_NO_MATCH;
ULONG Index, Length;
/* Access parameters */
MultipleItem = (PKSMULTIPLE_ITEM)(Pin + 1);
DataRange = (PKSDATARANGE)(MultipleItem + 1);
for(Index = 0; Index < MultipleItem->Count; Index++)
{
/* Call miniport's properitary handler */
ASSERT(Descriptor->Factory.KsPinDescriptor[Pin->PinId].DataRangesCount);
ASSERT(Descriptor->Factory.KsPinDescriptor[Pin->PinId].DataRanges[0]);
Status = SubDevice->lpVtbl->DataRangeIntersection(SubDevice, Pin->PinId, DataRange, (PKSDATARANGE)Descriptor->Factory.KsPinDescriptor[Pin->PinId].DataRanges[0],
DataLength, Data, &Length);
if (Status == STATUS_SUCCESS)
{
IoStatus->Information = Length;
break;
}
DataRange = UlongToPtr(PtrToUlong(DataRange) + DataRange->FormatSize);
}
IoStatus->Status = Status;
return Status;
}
NTSTATUS
NTAPI
PinPropertyHandler(
IN PIRP Irp,
IN PKSIDENTIFIER Request,
IN OUT PVOID Data)
{
PKSOBJECT_CREATE_ITEM CreateItem;
PSUBDEVICE_DESCRIPTOR Descriptor;
PIO_STACK_LOCATION IoStack;
IIrpTarget * IrpTarget;
IPort *Port;
ISubdevice *SubDevice;
KSP_PIN * Pin = (KSP_PIN*)Request;
PKSOBJECT_CREATE_ITEM CreateItem;
PKSMULTIPLE_ITEM MultipleItem;
PKSDATARANGE DataRange;
PIO_STACK_LOCATION IoStack;
NTSTATUS Status;
ULONG Index, Length;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
ASSERT(Descriptor);
/* Access the create item */
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
@ -105,50 +156,9 @@ HandleDataIntersection(
KeBugCheck(0);
}
/* Access parameters */
MultipleItem = (PKSMULTIPLE_ITEM)(Pin + 1);
DataRange = (PKSDATARANGE)(MultipleItem + 1);
/* Get current stack location */
/* get current stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
for(Index = 0; Index < MultipleItem->Count; Index++)
{
/* Call miniport's properitary handler */
ASSERT(Descriptor->Factory.KsPinDescriptor[Pin->PinId].DataRangesCount);
ASSERT(Descriptor->Factory.KsPinDescriptor[Pin->PinId].DataRanges[0]);
Status = SubDevice->lpVtbl->DataRangeIntersection(SubDevice, Pin->PinId, DataRange, (PKSDATARANGE)Descriptor->Factory.KsPinDescriptor[Pin->PinId].DataRanges[0],
IoStack->Parameters.DeviceIoControl.OutputBufferLength, Data, &Length);
if (Status == STATUS_SUCCESS)
{
Irp->IoStatus.Information = Length;
break;
}
DataRange = UlongToPtr(PtrToUlong(DataRange) + DataRange->FormatSize);
}
/* Release reference */
Port->lpVtbl->Release(Port);
Irp->IoStatus.Status = Status;
return Status;
}
NTSTATUS
NTAPI
PinPropertyHandler(
IN PIRP Irp,
IN PKSIDENTIFIER Request,
IN OUT PVOID Data)
{
PSUBDEVICE_DESCRIPTOR Descriptor;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
ASSERT(Descriptor);
switch(Request->Id)
{
case KSPROPERTY_PIN_CTYPES:
@ -163,27 +173,101 @@ PinPropertyHandler(
Status = KsPinPropertyHandler(Irp, Request, Data, Descriptor->Factory.PinDescriptorCount, Descriptor->Factory.KsPinDescriptor);
break;
case KSPROPERTY_PIN_GLOBALCINSTANCES:
Status = HandlePropertyInstances(Irp, Request, Data, Descriptor, TRUE);
Status = HandlePropertyInstances(&Irp->IoStatus, Request, Data, Descriptor, TRUE);
break;
case KSPROPERTY_PIN_CINSTANCES:
Status = HandlePropertyInstances(Irp, Request, Data, Descriptor, FALSE);
Status = HandlePropertyInstances(&Irp->IoStatus, Request, Data, Descriptor, FALSE);
break;
case KSPROPERTY_PIN_NECESSARYINSTANCES:
Status = HandleNecessaryPropertyInstances(Irp, Request, Data, Descriptor);
Status = HandleNecessaryPropertyInstances(&Irp->IoStatus, Request, Data, Descriptor);
break;
case KSPROPERTY_PIN_DATAINTERSECTION:
Status = HandleDataIntersection(Irp, Request, Data, Descriptor);
Status = HandleDataIntersection(&Irp->IoStatus, Request, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Descriptor, SubDevice);
break;
case KSPROPERTY_PIN_PHYSICALCONNECTION:
case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
DPRINT1("Unhandled %x\n", Request->Id);
Status = STATUS_SUCCESS;
UNIMPLEMENTED
Status = STATUS_NOT_IMPLEMENTED;
break;
default:
Status = STATUS_NOT_FOUND;
UNIMPLEMENTED
Status = STATUS_UNSUCCESSFUL;
}
/* Release reference */
Port->lpVtbl->Release(Port);
return Status;
}
NTSTATUS
NTAPI
FastPropertyHandler(
IN PFILE_OBJECT FileObject,
IN PKSPROPERTY UNALIGNED Property,
IN ULONG PropertyLength,
IN OUT PVOID UNALIGNED Data,
IN ULONG DataLength,
OUT PIO_STATUS_BLOCK IoStatus,
IN ULONG PropertySetsCount,
IN const KSPROPERTY_SET *PropertySet,
IN PSUBDEVICE_DESCRIPTOR Descriptor,
IN ISubdevice *SubDevice)
{
PFNKSHANDLER PropertyHandler = NULL;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
ASSERT(Descriptor);
if (!IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Pin))
{
/* the fast handler only supports pin properties */
return Status;
}
/* property handler is used to verify input parameters */
Status = FindPropertyHandler(IoStatus, Descriptor, Property, PropertyLength, DataLength, &PropertyHandler);
if (!NT_SUCCESS(Status))
{
return Status;
}
switch(Property->Id)
{
case KSPROPERTY_PIN_CTYPES:
case KSPROPERTY_PIN_DATAFLOW:
case KSPROPERTY_PIN_DATARANGES:
case KSPROPERTY_PIN_INTERFACES:
case KSPROPERTY_PIN_MEDIUMS:
case KSPROPERTY_PIN_COMMUNICATION:
case KSPROPERTY_PIN_CATEGORY:
case KSPROPERTY_PIN_NAME:
case KSPROPERTY_PIN_PROPOSEDATAFORMAT:
Status = KsFastPropertyHandler(FileObject, Property, PropertyLength, Data, DataLength, IoStatus, PropertySetsCount, PropertySet);
break;
case KSPROPERTY_PIN_GLOBALCINSTANCES:
Status = HandlePropertyInstances(IoStatus, Property, Data, Descriptor, TRUE);
break;
case KSPROPERTY_PIN_CINSTANCES:
Status = HandlePropertyInstances(IoStatus, Property, Data, Descriptor, FALSE);
break;
case KSPROPERTY_PIN_NECESSARYINSTANCES:
Status = HandleNecessaryPropertyInstances(IoStatus, Property, Data, Descriptor);
break;
case KSPROPERTY_PIN_DATAINTERSECTION:
Status = HandleDataIntersection(IoStatus, Property, Data, DataLength, Descriptor, SubDevice);
break;
case KSPROPERTY_PIN_PHYSICALCONNECTION:
case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
UNIMPLEMENTED
Status = STATUS_NOT_IMPLEMENTED;
break;
default:
UNIMPLEMENTED
Status = STATUS_UNSUCCESSFUL;
}
return Status;
}
@ -201,13 +285,62 @@ TopologyPropertyHandler(
NULL /* FIXME */);
}
NTSTATUS
FindPropertyHandler(
IN PIO_STATUS_BLOCK IoStatus,
IN PSUBDEVICE_DESCRIPTOR Descriptor,
IN PKSPROPERTY Property,
IN ULONG InputBufferLength,
IN ULONG OutputBufferLength,
OUT PFNKSHANDLER *PropertyHandler)
{
ULONG Index, ItemIndex;
for(Index = 0; Index < Descriptor->FilterPropertySet.FreeKsPropertySetOffset; Index++)
{
if (IsEqualGUIDAligned(&Property->Set, Descriptor->FilterPropertySet.Properties[Index].Set))
{
for(ItemIndex = 0; ItemIndex < Descriptor->FilterPropertySet.Properties[Index].PropertiesCount; ItemIndex++)
{
if (Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].PropertyId == Property->Id)
{
if (Property->Flags & KSPROPERTY_TYPE_SET)
*PropertyHandler = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].SetPropertyHandler;
if (Property->Flags & KSPROPERTY_TYPE_GET)
*PropertyHandler = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].GetPropertyHandler;
if (Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinProperty > InputBufferLength)
{
/* too small input buffer */
IoStatus->Information = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinProperty;
IoStatus->Status = STATUS_BUFFER_TOO_SMALL;
return STATUS_BUFFER_TOO_SMALL;
}
if (Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinData > OutputBufferLength)
{
/* too small output buffer */
IoStatus->Information = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinData;
IoStatus->Status = STATUS_BUFFER_TOO_SMALL;
return STATUS_BUFFER_TOO_SMALL;
}
return STATUS_SUCCESS;
}
}
}
}
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
NTAPI
PcPropertyHandler(
IN PIRP Irp,
IN PSUBDEVICE_DESCRIPTOR Descriptor)
{
ULONG Index, ItemIndex;
ULONG Index;
PIO_STACK_LOCATION IoStack;
PKSPROPERTY Property;
PFNKSHANDLER PropertyHandler = NULL;
@ -259,60 +392,21 @@ PcPropertyHandler(
}
}
for(Index = 0; Index < Descriptor->FilterPropertySet.FreeKsPropertySetOffset; Index++)
Status = FindPropertyHandler(&Irp->IoStatus, Descriptor, Property, IoStack->Parameters.DeviceIoControl.InputBufferLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength, &PropertyHandler);
if (PropertyHandler)
{
if (IsEqualGUIDAligned(&Property->Set, Descriptor->FilterPropertySet.Properties[Index].Set))
{
for(ItemIndex = 0; ItemIndex < Descriptor->FilterPropertySet.Properties[Index].PropertiesCount; ItemIndex++)
{
if (Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].PropertyId == Property->Id)
{
if (Property->Flags & KSPROPERTY_TYPE_SET)
PropertyHandler = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].SetPropertyHandler;
if (Property->Flags & KSPROPERTY_TYPE_GET)
PropertyHandler = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].GetPropertyHandler;
if (Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinProperty > IoStack->Parameters.DeviceIoControl.InputBufferLength)
{
/* too small input buffer */
Irp->IoStatus.Information = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinProperty;
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_BUFFER_TOO_SMALL;
}
if (Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinData > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
{
/* too small output buffer */
Irp->IoStatus.Information = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinData;
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_BUFFER_TOO_SMALL;
}
if (PropertyHandler)
{
KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PVOID)Descriptor;
DPRINT("Calling property handler %p\n", PropertyHandler);
Status = PropertyHandler(Irp, Property, Irp->UserBuffer);
}
/* the information member is set by the handler */
Irp->IoStatus.Status = Status;
DPRINT("Result %x Length %u\n", Status, Irp->IoStatus.Information);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
}
}
KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PVOID)Descriptor;
DPRINT("Calling property handler %p\n", PropertyHandler);
Status = PropertyHandler(Irp, Property, Irp->UserBuffer);
}
RtlStringFromGUID(&Property->Set, &GuidString);
DPRINT1("Unhandeled property: Set %S Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
RtlFreeUnicodeString(&GuidString);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
/* the information member is set by the handler */
Irp->IoStatus.Status = Status;
DPRINT("Result %x Length %u\n", Status, Irp->IoStatus.Information);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NOT_IMPLEMENTED;
return Status;
}