Author: janderwald Date: Fri Apr 9 20:31:53 2010 New Revision: 46794
URL: http://svn.reactos.org/svn/reactos?rev=46794&view=rev Log: [KS] - Return status success from unimplemented IKsClock_DispatchClose - Implement handling of KSPROPERTY_PIN_CONSTRAINEDDATARANGES property - Forward unhandled irps to lower device object - Fix asserts in KspHandleDataIntersection. The function is still a grotesk hack - Simply handling of property requests by merging filter properties into filter descriptor - Implement KsMethodHandler, KsMethodHandlerWithAllocator, KsFastMethodHandler - Fix a bug in KsPinGetFirstCloneStreamPointer - Implement handling of KSPROPSETID_Topology (KspTopologyHandler)
Modified: trunk/reactos/drivers/ksfilter/ks/api.c trunk/reactos/drivers/ksfilter/ks/clocks.c trunk/reactos/drivers/ksfilter/ks/connectivity.c trunk/reactos/drivers/ksfilter/ks/device.c trunk/reactos/drivers/ksfilter/ks/filter.c trunk/reactos/drivers/ksfilter/ks/irp.c trunk/reactos/drivers/ksfilter/ks/ksfunc.h trunk/reactos/drivers/ksfilter/ks/methods.c trunk/reactos/drivers/ksfilter/ks/pin.c trunk/reactos/drivers/ksfilter/ks/topology.c
Modified: trunk/reactos/drivers/ksfilter/ks/api.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/api.c?r... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/api.c [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/api.c [iso-8859-1] Fri Apr 9 20:31:53 2010 @@ -2195,8 +2195,8 @@ return AutomationTableA->PropertySetsCount;
/* sanity check */ - DPRINT("AutomationTableA EventItemSize %lu PropertySetsCount %lu\n", AutomationTableA->PropertyItemSize, AutomationTableA->PropertySetsCount); - DPRINT("AutomationTableB EventItemSize %lu PropertySetsCount %lu\n", AutomationTableB->PropertyItemSize, AutomationTableB->PropertySetsCount); + DPRINT("AutomationTableA PropertyItemSize %lu PropertySetsCount %lu\n", AutomationTableA->PropertyItemSize, AutomationTableA->PropertySetsCount); + DPRINT("AutomationTableB PropertyItemSize %lu PropertySetsCount %lu\n", AutomationTableB->PropertyItemSize, AutomationTableB->PropertySetsCount); ASSERT(AutomationTableA->PropertyItemSize == AutomationTableB->PropertyItemSize);
/* now iterate all property sets and compare their guids */
Modified: trunk/reactos/drivers/ksfilter/ks/clocks.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/clocks.... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/clocks.c [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/clocks.c [iso-8859-1] Fri Apr 9 20:31:53 2010 @@ -112,13 +112,11 @@ { UNIMPLEMENTED
- Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_NOT_IMPLEMENTED; -} - - + return STATUS_SUCCESS; +}
static KSDISPATCH_TABLE DispatchTable = {
Modified: trunk/reactos/drivers/ksfilter/ks/connectivity.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/connect... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/connectivity.c [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/connectivity.c [iso-8859-1] Fri Apr 9 20:31:53 2010 @@ -287,11 +287,13 @@ PKSDATAFORMAT_WAVEFORMATEX WaveFormatIn; PKEY_VALUE_PARTIAL_INFORMATION KeyInfo; NTSTATUS Status = STATUS_NOT_SUPPORTED; + ULONG Count; + const PKSDATARANGE* DataRanges;
IoStack = IoGetCurrentIrpStackLocation(Irp); Buffer = Irp->UserBuffer;
- 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);
switch(Property->Id) { @@ -322,6 +324,7 @@ break;
case KSPROPERTY_PIN_DATARANGES: + case KSPROPERTY_PIN_CONSTRAINEDDATARANGES: Pin = (KSP_PIN*)Property; if (Pin->PinId >= DescriptorsCount) { @@ -330,9 +333,20 @@ break; } Size = sizeof(KSMULTIPLE_ITEM); - for (Index = 0; Index < Descriptor[Pin->PinId].DataRangesCount; Index++) - { - Size += Descriptor[Pin->PinId].DataRanges[Index]->FormatSize; + if (Property->Id == KSPROPERTY_PIN_DATARANGES || Descriptor[Pin->PinId].ConstrainedDataRangesCount == 0) + { + DataRanges = Descriptor[Pin->PinId].DataRanges; + Count = Descriptor[Pin->PinId].DataRangesCount; + } + else + { + DataRanges = Descriptor[Pin->PinId].ConstrainedDataRanges; + Count = Descriptor[Pin->PinId].ConstrainedDataRangesCount; + } + + for (Index = 0; Index < Count; Index++) + { + Size += ((DataRanges[Index]->FormatSize + 0x7) & ~0x7); }
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == 0) @@ -354,16 +368,9 @@ break; }
- if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSMULTIPLE_ITEM)) - { - /* buffer too small */ - Status = STATUS_BUFFER_TOO_SMALL; - break; - } - /* store descriptor size */ Item->Size = Size; - Item->Count = Descriptor[Pin->PinId].DataRangesCount; + Item->Count = Count;
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(KSMULTIPLE_ITEM)) { @@ -374,10 +381,29 @@
/* now copy all dataranges */ Data = (PUCHAR)(Item +1); - for (Index = 0; Index < Descriptor[Pin->PinId].DataRangesCount; Index++) - { - RtlMoveMemory(Data, Descriptor[Pin->PinId].DataRanges[Index], Descriptor[Pin->PinId].DataRanges[Index]->FormatSize); - Data = ((PUCHAR)Data + Descriptor[Pin->PinId].DataRanges[Index]->FormatSize); + + /* alignment assert */ + ASSERT(((ULONG_PTR)Data & 0x7) == 0); + + for (Index = 0; Index < Count; Index++) + { + UNICODE_STRING GuidString; + /* convert the guid to string */ + RtlStringFromGUID(&DataRanges[Index]->MajorFormat, &GuidString); + DPRINT("Index %lu MajorFormat %S\n", Index, GuidString.Buffer); + RtlStringFromGUID(&DataRanges[Index]->SubFormat, &GuidString); + DPRINT("Index %lu SubFormat %S\n", Index, GuidString.Buffer); + RtlStringFromGUID(&DataRanges[Index]->Specifier, &GuidString); + DPRINT("Index %lu Specifier %S\n", Index, GuidString.Buffer); + RtlStringFromGUID(&DataRanges[Index]->Specifier, &GuidString); + DPRINT("Index %lu FormatSize %lu Flags %lu SampleSize %lu Reserved %lu KSDATAFORMAT %lu\n", Index, + DataRanges[Index]->FormatSize, DataRanges[Index]->Flags, DataRanges[Index]->SampleSize, DataRanges[Index]->Reserved, sizeof(KSDATAFORMAT)); + + RtlMoveMemory(Data, DataRanges[Index], DataRanges[Index]->FormatSize); + Data = ((PUCHAR)Data + DataRanges[Index]->FormatSize); + /* alignment assert */ + ASSERT(((ULONG_PTR)Data & 0x7) == 0); + Data = (PVOID)(((ULONG_PTR)Data + 0x7) & ~0x7); }
Status = STATUS_SUCCESS; @@ -442,7 +468,9 @@ break; }
+ //DPRINT("Pin %lu Communication %lu\n", Pin->PinId, Descriptor[Pin->PinId].Communication); *((KSPIN_COMMUNICATION*)Buffer) = Descriptor[Pin->PinId].Communication; + Status = STATUS_SUCCESS; Irp->IoStatus.Information = Size; break;
Modified: trunk/reactos/drivers/ksfilter/ks/device.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/device.... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/device.c [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/device.c [iso-8859-1] Fri Apr 9 20:31:53 2010 @@ -567,8 +567,12 @@ } default: DPRINT1("unhandled function %u\n", IoStack->MinorFunction); + /* pass the irp down the driver stack */ + Status = KspForwardIrpSynchronous(DeviceObject, Irp); + + Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_NOT_SUPPORTED; + return Status; } }
Modified: trunk/reactos/drivers/ksfilter/ks/filter.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/filter.... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/filter.c [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/filter.c [iso-8859-1] Fri Apr 9 20:31:53 2010 @@ -611,7 +611,7 @@ DataRange = (PKSDATARANGE)(MultipleItem + 1);
/* FIXME make sure its 64 bit aligned */ - ASSERT(((ULONG_PTR)DataRange & 0x3F) == 0); + ASSERT(((ULONG_PTR)DataRange & 0x7) == 0);
if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount) { @@ -635,29 +635,63 @@
for(Index = 0; Index < MultipleItem->Count; Index++) { + UNICODE_STRING MajorFormat, SubFormat, Specifier; + /* convert the guid to string */ + RtlStringFromGUID(&DataRange->MajorFormat, &MajorFormat); + RtlStringFromGUID(&DataRange->SubFormat, &SubFormat); + RtlStringFromGUID(&DataRange->Specifier, &Specifier); + + DPRINT("Index %lu MajorFormat %S SubFormat %S Specifier %S FormatSize %lu SampleSize %lu Align %lu Flags %lx Reserved %lx DataLength %lu\n", Index, MajorFormat.Buffer, SubFormat.Buffer, Specifier.Buffer, + DataRange->FormatSize, DataRange->SampleSize, DataRange->Alignment, DataRange->Flags, DataRange->Reserved, DataLength); + + /* FIXME implement KsPinDataIntersectionEx */ /* Call miniport's properitary handler */ - Status = This->PinDescriptorsEx[Pin->PinId].IntersectHandler(NULL, /* context */ + Status = This->PinDescriptorsEx[Pin->PinId].IntersectHandler(&This->Filter, Irp, Pin, DataRange, - (PKSDATAFORMAT)This->PinDescriptorsEx[Pin->PinId].PinDescriptor.DataRanges, + This->PinDescriptorsEx[Pin->PinId].PinDescriptor.DataRanges[0], /* HACK */ DataLength, Data, &Length);
- if (Status == STATUS_SUCCESS || Status == STATUS_BUFFER_OVERFLOW) - { + if (Status == STATUS_SUCCESS || Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) + { + ASSERT(Length); IoStatus->Information = Length; + if (Status != STATUS_SUCCESS) + Status = STATUS_MORE_ENTRIES; break; } + DataRange = UlongToPtr(PtrToUlong(DataRange) + DataRange->FormatSize); /* FIXME make sure its 64 bit aligned */ - ASSERT(((ULONG_PTR)DataRange & 0x3F) == 0); + ASSERT(((ULONG_PTR)DataRange & 0x7) == 0); }
IoStatus->Status = Status; return Status; } + +NTSTATUS +NTAPI +KspTopologyPropertyHandler( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + IKsFilterImpl * This; + + /* get filter implementation */ + This = (IKsFilterImpl*)KSPROPERTY_ITEM_IRP_STORAGE(Irp); + + /* sanity check */ + ASSERT(This); + + return KsTopologyPropertyHandler(Irp, Request, Data, &This->Topology); + +} +
NTSTATUS NTAPI @@ -672,6 +706,9 @@
/* get filter implementation */ This = (IKsFilterImpl*)KSPROPERTY_ITEM_IRP_STORAGE(Irp); + + /* sanity check */ + ASSERT(This);
/* get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); @@ -686,7 +723,7 @@ case KSPROPERTY_PIN_COMMUNICATION: case KSPROPERTY_PIN_CATEGORY: case KSPROPERTY_PIN_NAME: - case KSPROPERTY_PIN_PROPOSEDATAFORMAT: + case KSPROPERTY_PIN_CONSTRAINEDDATARANGES: Status = KsPinPropertyHandler(Irp, Request, Data, This->PinDescriptorCount, This->PinDescriptors); break; case KSPROPERTY_PIN_GLOBALCINSTANCES: @@ -702,16 +739,11 @@ case KSPROPERTY_PIN_DATAINTERSECTION: Status = KspHandleDataIntersection(Irp, &Irp->IoStatus, Request, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength, This); break; - case KSPROPERTY_PIN_PHYSICALCONNECTION: - case KSPROPERTY_PIN_CONSTRAINEDDATARANGES: - UNIMPLEMENTED - Status = STATUS_NOT_IMPLEMENTED; - break; default: UNIMPLEMENTED - Status = STATUS_UNSUCCESSFUL; - } - DPRINT("KspPinPropertyHandler Pins %lu Request->Id %lu Status %lx\n", This->PinDescriptorCount, Request->Id, Status); + Status = STATUS_NOT_FOUND; + } + //DPRINT("KspPinPropertyHandler Pins %lu Request->Id %lu Status %lx\n", This->PinDescriptorCount, Request->Id, Status);
return Status; @@ -730,6 +762,7 @@ PKSFILTER FilterInstance; UNICODE_STRING GuidString; PKSPROPERTY Property; + ULONG SetCount = 0;
/* obtain filter from object header */ Status = IKsFilter_GetFilterFromIrp(Irp, &Filter); @@ -742,47 +775,70 @@ /* current irp stack */ IoStack = IoGetCurrentIrpStackLocation(Irp);
- /* property was not handled */ + /* get property from input buffer */ Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + + /* sanity check */ + ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSIDENTIFIER)); + + /* get filter instance */ + FilterInstance = Filter->lpVtbl->GetStruct(Filter);
RtlStringFromGUID(&Property->Set, &GuidString); DPRINT("IKsFilter_DispatchDeviceIoControl property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags); RtlFreeUnicodeString(&GuidString);
- - if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY) - { + if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_METHOD) + { + const KSMETHOD_SET *MethodSet = NULL; + ULONG MethodItemSize = 0; + + /* check if the driver supports method sets */ + if (FilterInstance->Descriptor->AutomationTable && FilterInstance->Descriptor->AutomationTable->MethodSetsCount) + { + SetCount = FilterInstance->Descriptor->AutomationTable->MethodSetsCount; + MethodSet = FilterInstance->Descriptor->AutomationTable->MethodSets; + MethodItemSize = FilterInstance->Descriptor->AutomationTable->MethodItemSize; + } + + /* call method set handler */ + Status = KspMethodHandlerWithAllocator(Irp, SetCount, MethodSet, NULL, MethodItemSize); + } + else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) + { + const KSPROPERTY_SET *PropertySet = NULL; + ULONG PropertyItemSize = 0; + + /* check if the driver supports method sets */ + if (FilterInstance->Descriptor->AutomationTable && FilterInstance->Descriptor->AutomationTable->PropertySetsCount) + { + SetCount = FilterInstance->Descriptor->AutomationTable->PropertySetsCount; + PropertySet = FilterInstance->Descriptor->AutomationTable->PropertySets; + PropertyItemSize = FilterInstance->Descriptor->AutomationTable->PropertyItemSize; + } + + /* needed for our property handlers */ + KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (KSPROPERTY_ITEM*)This; + + /* call property handler */ + Status = KspPropertyHandler(Irp, SetCount, PropertySet, NULL, PropertyItemSize); + } + else + { + /* sanity check */ + ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT || + IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_DISABLE_EVENT); + + Status = STATUS_NOT_FOUND; UNIMPLEMENTED; - - /* release filter interface */ - Filter->lpVtbl->Release(Filter); - - /* complete and forget irp */ - Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_NOT_IMPLEMENTED; - } - - /* call property handler supported by ks */ - KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (KSPROPERTY_ITEM*)This; - Status = KspPropertyHandler(Irp, 2, FilterPropertySet, NULL, sizeof(KSPROPERTY_ITEM)); - - if (Status == STATUS_NOT_FOUND) - { - /* get filter instance */ - FilterInstance = Filter->lpVtbl->GetStruct(Filter); - - /* check if the driver supports property sets */ - if (FilterInstance->Descriptor->AutomationTable && FilterInstance->Descriptor->AutomationTable->PropertySetsCount) - { - /* call driver's filter property handler */ - Status = KspPropertyHandler(Irp, - FilterInstance->Descriptor->AutomationTable->PropertySetsCount, - FilterInstance->Descriptor->AutomationTable->PropertySets, - NULL, - FilterInstance->Descriptor->AutomationTable->PropertyItemSize); - } - } + } + + RtlStringFromGUID(&Property->Set, &GuidString); + DPRINT("IKsFilter_DispatchDeviceIoControl property Set |%S| Id %u Flags %x Status %lx ResultLength %lu\n", GuidString.Buffer, Property->Id, Property->Flags, Status, Irp->IoStatus.Information); + RtlFreeUnicodeString(&GuidString); + + /* release filter */ + Filter->lpVtbl->Release(Filter);
if (Status != STATUS_PENDING) { @@ -953,6 +1009,7 @@ const KSFILTER_DESCRIPTOR* FilterDescriptor) { NTSTATUS Status; + KSAUTOMATION_TABLE AutomationTable;
This->Filter.Descriptor = AllocateItem(NonPagedPool, sizeof(KSFILTER_DESCRIPTOR)); if (!This->Filter.Descriptor) @@ -968,6 +1025,17 @@
/* copy filter descriptor fields */ RtlMoveMemory((PVOID)This->Filter.Descriptor, FilterDescriptor, sizeof(KSFILTER_DESCRIPTOR)); + + /* zero automation table */ + RtlZeroMemory(&AutomationTable, sizeof(KSAUTOMATION_TABLE)); + + /* setup filter property sets */ + AutomationTable.PropertyItemSize = sizeof(KSPROPERTY_ITEM); + AutomationTable.PropertySetsCount = 2; + AutomationTable.PropertySets = FilterPropertySet; + + /* merge filter automation table */ + Status = KsMergeAutomationTables((PKSAUTOMATION_TABLE*)&This->Filter.Descriptor->AutomationTable, (PKSAUTOMATION_TABLE)FilterDescriptor->AutomationTable, &AutomationTable, This->Filter.Bag);
return Status; } @@ -1303,7 +1371,6 @@ This->lpVtbl = &vt_IKsFilter; This->lpVtblKsControl = &vt_IKsControl;
- This->Filter.Descriptor = Factory->FilterDescriptor; This->Factory = Factory; This->FilterFactory = iface; This->FileObject = IoStack->FileObject;
Modified: trunk/reactos/drivers/ksfilter/ks/irp.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/irp.c?r... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/irp.c [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/irp.c [iso-8859-1] Fri Apr 9 20:31:53 2010 @@ -1720,9 +1720,11 @@ PLIST_ENTRY Entry; PCREATE_ITEM_ENTRY CreateItemEntry;
+#ifndef MS_KSUSER /* remove '' slash */ Buffer++; BufferSize -= sizeof(WCHAR); +#endif
/* point to first entry */ Entry = ListHead->Flink;
Modified: trunk/reactos/drivers/ksfilter/ks/ksfunc.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/ksfunc.... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/ksfunc.h [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/ksfunc.h [iso-8859-1] Fri Apr 9 20:31:53 2010 @@ -156,3 +156,12 @@ IN PKSIDEVICE_HEADER DeviceHeader, IN BOOLEAN NewState);
+NTSTATUS +NTAPI +KspMethodHandlerWithAllocator( + IN PIRP Irp, + IN ULONG MethodSetsCount, + IN const KSMETHOD_SET *MethodSet, + IN PFNKSALLOCATOR Allocator OPTIONAL, + IN ULONG MethodItemSize OPTIONAL); +
Modified: trunk/reactos/drivers/ksfilter/ks/methods.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/methods... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/methods.c [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/methods.c [iso-8859-1] Fri Apr 9 20:31:53 2010 @@ -8,8 +8,186 @@
#include "priv.h"
+NTSTATUS +FindMethodHandler( + IN PIO_STATUS_BLOCK IoStatus, + IN const KSMETHOD_SET* MethodSet, + IN ULONG MethodSetCount, + IN PKSMETHOD Method, + IN ULONG InputBufferLength, + IN ULONG OutputBufferLength, + OUT PVOID OutputBuffer, + OUT PFNKSHANDLER *MethodHandler, + OUT PKSMETHOD_SET * Set) +{ + ULONG Index, ItemIndex; + + /* TODO */ + ASSERT((Method->Flags & KSMETHOD_TYPE_SETSUPPORT) == 0); + + for(Index = 0; Index < MethodSetCount; Index++) + { + ASSERT(MethodSet[Index].Set); + + if (IsEqualGUIDAligned(&Method->Set, MethodSet[Index].Set)) + { + for(ItemIndex = 0; ItemIndex < MethodSet[Index].MethodsCount; ItemIndex++) + { + if (MethodSet[Index].MethodItem[ItemIndex].MethodId == Method->Id) + { + if (MethodSet[Index].MethodItem[ItemIndex].MinMethod > InputBufferLength) + { + /* too small input buffer */ + IoStatus->Information = MethodSet[Index].MethodItem[ItemIndex].MinMethod; + return STATUS_INVALID_PARAMETER; + } + + if (MethodSet[Index].MethodItem[ItemIndex].MinData > OutputBufferLength) + { + /* too small output buffer */ + IoStatus->Information = MethodSet[Index].MethodItem[ItemIndex].MinData; + return STATUS_MORE_ENTRIES; + } + if (Method->Flags & KSMETHOD_TYPE_BASICSUPPORT) + { + PULONG Flags; + PKSPROPERTY_DESCRIPTION Description; + + if (sizeof(ULONG) > OutputBufferLength) + { + /* too small buffer */ + return STATUS_INVALID_PARAMETER; + } + + /* get output buffer */ + Flags = (PULONG)OutputBuffer; + + /* set flags flags */ + *Flags = MethodSet[Index].MethodItem[ItemIndex].Flags; + + IoStatus->Information = sizeof(ULONG); + + if (OutputBufferLength >= sizeof(KSPROPERTY_DESCRIPTION)) + { + /* get output buffer */ + Description = (PKSPROPERTY_DESCRIPTION)OutputBuffer; + + /* store result */ + Description->DescriptionSize = sizeof(KSPROPERTY_DESCRIPTION); + Description->PropTypeSet.Set = KSPROPTYPESETID_General; + Description->PropTypeSet.Id = 0; + Description->PropTypeSet.Flags = 0; + Description->MembersListCount = 0; + Description->Reserved = 0; + + IoStatus->Information = sizeof(KSPROPERTY_DESCRIPTION); + } + return STATUS_SUCCESS; + } + *MethodHandler = MethodSet[Index].MethodItem[ItemIndex].MethodHandler; + *Set = (PKSMETHOD_SET)&MethodSet[Index]; + return STATUS_SUCCESS; + } + } + } + } + return STATUS_NOT_FOUND; +} + +NTSTATUS +NTAPI +KspMethodHandlerWithAllocator( + IN PIRP Irp, + IN ULONG MethodSetsCount, + IN const KSMETHOD_SET *MethodSet, + IN PFNKSALLOCATOR Allocator OPTIONAL, + IN ULONG MethodItemSize OPTIONAL) +{ + PKSMETHOD Method; + PKSMETHOD_SET Set; + PIO_STACK_LOCATION IoStack; + NTSTATUS Status; + PFNKSHANDLER MethodHandler = NULL; + ULONG Index; + LPGUID Guid; + + /* get current irp stack */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* check if inputbuffer at least holds KSMETHOD item */ + if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSMETHOD)) + { + /* invalid parameter */ + Irp->IoStatus.Information = sizeof(KSPROPERTY); + return STATUS_INVALID_BUFFER_SIZE; + } + + /* FIXME probe the input / output buffer if from user mode */ + + /* get input property request */ + Method = (PKSMETHOD)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + +// DPRINT("KspMethodHandlerWithAllocator Irp %p PropertySetsCount %u PropertySet %p Allocator %p PropertyItemSize %u ExpectedPropertyItemSize %u\n", Irp, PropertySetsCount, PropertySet, Allocator, PropertyItemSize, sizeof(KSPROPERTY_ITEM)); + + /* sanity check */ + ASSERT(MethodItemSize == 0 || MethodItemSize == sizeof(KSMETHOD_ITEM)); + + /* find the method handler */ + Status = FindMethodHandler(&Irp->IoStatus, MethodSet, MethodSetsCount, Method, IoStack->Parameters.DeviceIoControl.InputBufferLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Irp->UserBuffer, &MethodHandler, &Set); + + if (NT_SUCCESS(Status) && MethodHandler) + { + /* call method handler */ + KSMETHOD_SET_IRP_STORAGE(Irp) = Set; + Status = MethodHandler(Irp, Method, Irp->UserBuffer); + + if (Status == STATUS_BUFFER_TOO_SMALL) + { + /* output buffer is too small */ + if (Allocator) + { + /* allocate the requested amount */ + Status = Allocator(Irp, Irp->IoStatus.Information, FALSE); + + /* check if the block was allocated */ + if (!NT_SUCCESS(Status)) + { + /* no memory */ + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* re-call method handler */ + Status = MethodHandler(Irp, Method, Irp->UserBuffer); + } + } + } + else if (IsEqualGUIDAligned(&Method->Set, &GUID_NULL) && Method->Id == 0 && Method->Flags == KSMETHOD_TYPE_SETSUPPORT) + { + // store output size + Irp->IoStatus.Information = sizeof(GUID) * MethodSetsCount; + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GUID) * MethodSetsCount) + { + // buffer too small + return STATUS_MORE_ENTRIES; + } + + // get output buffer + Guid = (LPGUID)Irp->UserBuffer; + + // copy property guids from property sets + for(Index = 0; Index < MethodSetsCount; Index++) + { + RtlMoveMemory(&Guid[Index], MethodSet[Index].Set, sizeof(GUID)); + } + return STATUS_SUCCESS; + } + + /* done */ + return Status; +} + /* - @unimplemented + @implemented */ KSDDKAPI NTSTATUS @@ -19,12 +197,11 @@ IN ULONG MethodSetsCount, IN PKSMETHOD_SET MethodSet) { - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; + return KspMethodHandlerWithAllocator(Irp, MethodSetsCount, MethodSet, NULL, 0); }
/* - @unimplemented + @implemented */ KSDDKAPI NTSTATUS @@ -36,12 +213,39 @@ IN PFNKSALLOCATOR Allocator OPTIONAL, IN ULONG MethodItemSize OPTIONAL) { - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; -} + return KspMethodHandlerWithAllocator(Irp, MethodSetsCount, MethodSet, Allocator, MethodItemSize); +} + + +NTSTATUS +FindFastMethodHandler( + IN ULONG FastIoCount, + IN const KSFASTMETHOD_ITEM * FastIoTable, + IN PKSMETHOD MethodId, + OUT PFNKSFASTHANDLER * FastPropertyHandler) +{ + ULONG Index; + + /* iterate through all items */ + for(Index = 0; Index < FastIoCount; Index++) + { + if (MethodId->Id == FastIoTable[Index].MethodId) + { + if (FastIoTable[Index].MethodSupported) + { + *FastPropertyHandler = FastIoTable[Index].MethodHandler; + return STATUS_SUCCESS; + } + } + + } + /* no fast property handler found */ + return STATUS_NOT_FOUND; +} +
/* - @unimplemented + @implemented */ KSDDKAPI BOOLEAN @@ -56,6 +260,68 @@ IN ULONG MethodSetsCount, IN const KSMETHOD_SET* MethodSet) { - UNIMPLEMENTED; + KSMETHOD MethodRequest; + KPROCESSOR_MODE Mode; + NTSTATUS Status = STATUS_SUCCESS; + ULONG Index; + PFNKSFASTHANDLER FastMethodHandler; + + if (MethodLength < sizeof(KSPROPERTY)) + { + /* invalid request */ + return FALSE; + } + + /* get previous mode */ + Mode = ExGetPreviousMode(); + + if (Mode == KernelMode) + { + /* just copy it */ + RtlMoveMemory(&MethodRequest, Method, sizeof(KSMETHOD)); + } + else + { + /* need to probe the buffer */ + _SEH2_TRY + { + ProbeForRead(Method, sizeof(KSPROPERTY), sizeof(UCHAR)); + RtlMoveMemory(&MethodRequest, Method, sizeof(KSMETHOD)); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Exception, get the error code */ + Status = _SEH2_GetExceptionCode(); + }_SEH2_END; + + if (!NT_SUCCESS(Status)) + return FALSE; + } + + /* are there any property sets provided */ + if (MethodSetsCount) + { + /* iterate through all property sets count */ + Index = 0; + do + { + /* does the property id match */ + if (IsEqualGUIDAligned(MethodSet[Index].Set, &MethodRequest.Set)) + { + /* try to find a fast property handler */ + Status = FindFastMethodHandler(MethodSet[Index].FastIoCount, MethodSet[Index].FastIoTable, &MethodRequest, &FastMethodHandler); + + if (NT_SUCCESS(Status)) + { + /* call fast property handler */ + ASSERT(MethodLength == sizeof(KSMETHOD)); /* FIXME check if property length is bigger -> copy params */ + ASSERT(Mode == KernelMode); /* FIXME need to probe usermode output buffer */ + return FastMethodHandler(FileObject, &MethodRequest, sizeof(KSMETHOD), Data, DataLength, IoStatus); + } + } + /* move to next item */ + Index++; + }while(Index < MethodSetsCount); + } return FALSE; }
Modified: trunk/reactos/drivers/ksfilter/ks/pin.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/pin.c?r... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/pin.c [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/pin.c [iso-8859-1] Fri Apr 9 20:31:53 2010 @@ -21,6 +21,7 @@ ULONG Offset; ULONG Length; KSSTREAM_POINTER StreamPointer; + KSPIN_LOCK Lock; }KSISTREAM_POINTER, *PKSISTREAM_POINTER;
typedef struct @@ -307,6 +308,7 @@ /* revert to old state */ This->Pin.ClientState = OldState; This->Pin.DeviceState = OldState; + DPRINT("IKsPin_PinStatePropertyHandler failed to set state %lx Result %lx\n", *NewState, Status); DbgBreakPoint(); } else @@ -429,6 +431,7 @@ _InterlockedIncrement(&This->ref); return STATUS_SUCCESS; } +DPRINT("IKsPin_fnQueryInterface\n"); DbgBreakPoint(); return STATUS_UNSUCCESSFUL; } @@ -674,6 +677,9 @@
IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
+ + DPRINT1("IKsReferenceClock_fnGetTime\n"); + if (!This->ClockFileObject || !This->ClockTable.GetTime) { Result = 0; @@ -694,6 +700,9 @@ LONGLONG Result;
IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); + + DPRINT1("IKsReferenceClock_fnGetPhysicalTime\n"); +
if (!This->ClockFileObject || !This->ClockTable.GetPhysicalTime) { @@ -718,6 +727,8 @@
IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
+ DPRINT1("IKsReferenceClock_fnGetCorrelatedTime\n"); + if (!This->ClockFileObject || !This->ClockTable.GetCorrelatedTime) { Result = 0; @@ -740,6 +751,8 @@ LONGLONG Result;
IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); + + DPRINT1("IKsReferenceClock_fnGetCorrelatedPhysicalTime\n");
if (!This->ClockFileObject || !This->ClockTable.GetCorrelatedPhysicalTime) { @@ -1226,6 +1239,7 @@ }
InterlockedDecrement(&This->IrpCount); + KsDecrementCountedWorker(This->PinWorker);
/* get stream header */ if (StreamPointer->Irp->RequestorMode == UserMode) @@ -1374,9 +1388,11 @@ IN PKSSTREAM_POINTER StreamPointer, IN BOOLEAN Eject) { - UNIMPLEMENTED + PKSISTREAM_POINTER Pointer = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER, StreamPointer); + DPRINT("KsStreamPointerUnlock StreamPointer %pEject %lu\n", StreamPointer, Eject); - DbgBreakPoint(); + + Pointer->Irp = NULL; }
/* @@ -1687,8 +1703,12 @@ IKsPinImpl * This;
DPRINT("KsPinGetFirstCloneStreamPointer %p\n", Pin); -DbgBreakPoint(); + This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); + + if (!This->ClonedStreamPointer) + return NULL; + /* return first cloned stream pointer */ return &This->ClonedStreamPointer->StreamPointer; } @@ -1708,7 +1728,6 @@ DbgBreakPoint(); /* get stream pointer */ Pointer = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER, StreamPointer); -
/* is there a another cloned stream pointer */ if (!Pointer->Next)
Modified: trunk/reactos/drivers/ksfilter/ks/topology.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/topolog... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/topology.c [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/topology.c [iso-8859-1] Fri Apr 9 20:31:53 2010 @@ -270,13 +270,3 @@ return Status; }
-NTSTATUS -NTAPI -KspTopologyPropertyHandler( - IN PIRP Irp, - IN PKSIDENTIFIER Request, - IN OUT PVOID Data) -{ - - return STATUS_NOT_IMPLEMENTED; -}