diff --git a/reactos/drivers/wdm/audio/backpln/portcls/filter_wavepci.c b/reactos/drivers/wdm/audio/backpln/portcls/filter_wavepci.c index 7706b76f0ea..3f1cc2ecf80 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/filter_wavepci.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/filter_wavepci.c @@ -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; } /* diff --git a/reactos/drivers/wdm/audio/backpln/portcls/private.h b/reactos/drivers/wdm/audio/backpln/portcls/private.h index 7ff45546244..7527e360ad4 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/private.h +++ b/reactos/drivers/wdm/audio/backpln/portcls/private.h @@ -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); diff --git a/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c b/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c index ec93086a565..951f4b6b2eb 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c @@ -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; }