- 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); This->Pins[Index]->lpVtbl->Close(This->Pins[Index], DeviceObject, NULL);
} }
} }
@ -298,8 +297,49 @@ IPortFilterWavePci_fnFastDeviceIoControl(
OUT PIO_STATUS_BLOCK StatusBlock, OUT PIO_STATUS_BLOCK StatusBlock,
IN PDEVICE_OBJECT DeviceObject) IN PDEVICE_OBJECT DeviceObject)
{ {
UNIMPLEMENTED ULONG Index;
return FALSE; 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 PIRP Irp,
IN PSUBDEVICE_DESCRIPTOR Descriptor); 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 PDEVICE_OBJECT
GetDeviceObject( GetDeviceObject(
IPortWaveCyclic* iface); IPortWaveCyclic* iface);

View file

@ -8,9 +8,18 @@
#include "private.h" #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 NTSTATUS
HandlePropertyInstances( HandlePropertyInstances(
IN PIRP Irp, IN PIO_STATUS_BLOCK IoStatus,
IN PKSIDENTIFIER Request, IN PKSIDENTIFIER Request,
IN OUT PVOID Data, IN OUT PVOID Data,
IN PSUBDEVICE_DESCRIPTOR Descriptor, IN PSUBDEVICE_DESCRIPTOR Descriptor,
@ -21,8 +30,8 @@ HandlePropertyInstances(
if (Pin->PinId >= Descriptor->Factory.PinDescriptorCount) if (Pin->PinId >= Descriptor->Factory.PinDescriptorCount)
{ {
Irp->IoStatus.Information = 0; IoStatus->Information = 0;
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; IoStatus->Status = STATUS_INVALID_PARAMETER;
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
@ -35,14 +44,14 @@ HandlePropertyInstances(
Instances->CurrentCount = Descriptor->Factory.Instances[Pin->PinId].CurrentPinInstanceCount; Instances->CurrentCount = Descriptor->Factory.Instances[Pin->PinId].CurrentPinInstanceCount;
Irp->IoStatus.Information = sizeof(KSPIN_CINSTANCES); IoStatus->Information = sizeof(KSPIN_CINSTANCES);
Irp->IoStatus.Status = STATUS_SUCCESS; IoStatus->Status = STATUS_SUCCESS;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS NTSTATUS
HandleNecessaryPropertyInstances( HandleNecessaryPropertyInstances(
IN PIRP Irp, IN PIO_STATUS_BLOCK IoStatus,
IN PKSIDENTIFIER Request, IN PKSIDENTIFIER Request,
IN OUT PVOID Data, IN OUT PVOID Data,
IN PSUBDEVICE_DESCRIPTOR Descriptor) IN PSUBDEVICE_DESCRIPTOR Descriptor)
@ -52,36 +61,78 @@ HandleNecessaryPropertyInstances(
if (Pin->PinId >= Descriptor->Factory.PinDescriptorCount) if (Pin->PinId >= Descriptor->Factory.PinDescriptorCount)
{ {
Irp->IoStatus.Information = 0; IoStatus->Information = 0;
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; IoStatus->Status = STATUS_INVALID_PARAMETER;
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
Result = (PULONG)Data; Result = (PULONG)Data;
*Result = Descriptor->Factory.Instances[Pin->PinId].MinFilterInstanceCount; *Result = Descriptor->Factory.Instances[Pin->PinId].MinFilterInstanceCount;
Irp->IoStatus.Information = sizeof(ULONG); IoStatus->Information = sizeof(ULONG);
Irp->IoStatus.Status = STATUS_SUCCESS; IoStatus->Status = STATUS_SUCCESS;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS NTSTATUS
HandleDataIntersection( HandleDataIntersection(
IN PIRP Irp, IN PIO_STATUS_BLOCK IoStatus,
IN PKSIDENTIFIER Request, IN PKSIDENTIFIER Request,
IN OUT PVOID Data, 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; IIrpTarget * IrpTarget;
IPort *Port; IPort *Port;
ISubdevice *SubDevice; ISubdevice *SubDevice;
KSP_PIN * Pin = (KSP_PIN*)Request;
PKSOBJECT_CREATE_ITEM CreateItem;
PKSMULTIPLE_ITEM MultipleItem; NTSTATUS Status = STATUS_UNSUCCESSFUL;
PKSDATARANGE DataRange;
PIO_STACK_LOCATION IoStack; Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
NTSTATUS Status; ASSERT(Descriptor);
ULONG Index, Length;
/* Access the create item */ /* Access the create item */
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
@ -105,50 +156,9 @@ HandleDataIntersection(
KeBugCheck(0); KeBugCheck(0);
} }
/* Access parameters */ /* get current stack location */
MultipleItem = (PKSMULTIPLE_ITEM)(Pin + 1);
DataRange = (PKSDATARANGE)(MultipleItem + 1);
/* Get current stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp); 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) switch(Request->Id)
{ {
case KSPROPERTY_PIN_CTYPES: case KSPROPERTY_PIN_CTYPES:
@ -163,27 +173,101 @@ PinPropertyHandler(
Status = KsPinPropertyHandler(Irp, Request, Data, Descriptor->Factory.PinDescriptorCount, Descriptor->Factory.KsPinDescriptor); Status = KsPinPropertyHandler(Irp, Request, Data, Descriptor->Factory.PinDescriptorCount, Descriptor->Factory.KsPinDescriptor);
break; break;
case KSPROPERTY_PIN_GLOBALCINSTANCES: case KSPROPERTY_PIN_GLOBALCINSTANCES:
Status = HandlePropertyInstances(Irp, Request, Data, Descriptor, TRUE); Status = HandlePropertyInstances(&Irp->IoStatus, Request, Data, Descriptor, TRUE);
break; break;
case KSPROPERTY_PIN_CINSTANCES: case KSPROPERTY_PIN_CINSTANCES:
Status = HandlePropertyInstances(Irp, Request, Data, Descriptor, FALSE); Status = HandlePropertyInstances(&Irp->IoStatus, Request, Data, Descriptor, FALSE);
break; break;
case KSPROPERTY_PIN_NECESSARYINSTANCES: case KSPROPERTY_PIN_NECESSARYINSTANCES:
Status = HandleNecessaryPropertyInstances(Irp, Request, Data, Descriptor); Status = HandleNecessaryPropertyInstances(&Irp->IoStatus, Request, Data, Descriptor);
break; break;
case KSPROPERTY_PIN_DATAINTERSECTION: case KSPROPERTY_PIN_DATAINTERSECTION:
Status = HandleDataIntersection(Irp, Request, Data, Descriptor); Status = HandleDataIntersection(&Irp->IoStatus, Request, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Descriptor, SubDevice);
break; break;
case KSPROPERTY_PIN_PHYSICALCONNECTION: case KSPROPERTY_PIN_PHYSICALCONNECTION:
case KSPROPERTY_PIN_CONSTRAINEDDATARANGES: case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
DPRINT1("Unhandled %x\n", Request->Id); UNIMPLEMENTED
Status = STATUS_SUCCESS; Status = STATUS_NOT_IMPLEMENTED;
break; break;
default: 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; return Status;
} }
@ -201,13 +285,62 @@ TopologyPropertyHandler(
NULL /* FIXME */); 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 NTSTATUS
NTAPI NTAPI
PcPropertyHandler( PcPropertyHandler(
IN PIRP Irp, IN PIRP Irp,
IN PSUBDEVICE_DESCRIPTOR Descriptor) IN PSUBDEVICE_DESCRIPTOR Descriptor)
{ {
ULONG Index, ItemIndex; ULONG Index;
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
PKSPROPERTY Property; PKSPROPERTY Property;
PFNKSHANDLER PropertyHandler = NULL; 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)) KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PVOID)Descriptor;
{ DPRINT("Calling property handler %p\n", PropertyHandler);
for(ItemIndex = 0; ItemIndex < Descriptor->FilterPropertySet.Properties[Index].PropertiesCount; ItemIndex++) Status = PropertyHandler(Irp, Property, Irp->UserBuffer);
{
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;
}
}
}
} }
RtlStringFromGUID(&Property->Set, &GuidString); RtlStringFromGUID(&Property->Set, &GuidString);
DPRINT1("Unhandeled property: Set %S Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags); DPRINT1("Unhandeled property: Set %S Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
RtlFreeUnicodeString(&GuidString); 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); IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NOT_IMPLEMENTED; return Status;
} }