From 99db21ebb0cfbc8ba60a7062d74cfab729417493 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Thu, 15 Apr 2010 10:07:38 +0000 Subject: [PATCH] [KS] - Fix typo - Store object interface functions in KSBASIC_HEADER OuterUnknown - Implement KsDeviceRegisterAdapterObject, KsRegisterAggregatedClientUnknown, KsGetOuterUnknown - Partly implement clock property functions - Rewrite KsValidateConnectRequest, KsPinPropertyHandler to handle KSPIN_DESCRIPTOR_EX, which is used by IKsFilter implementation - Dispatch unsupported interface requests to the clients registered inner aggregate (device / filter factory / filter / pin) - Rewrite filter functions which deal with KSPIN_DESCRIPTO, as the client can dynamically modify the PinDescriptors array - Handle matching create requests which differentiate in case - Implement pin allocator framing property handler svn path=/trunk/; revision=46878 --- reactos/drivers/ksfilter/ks/allocators.c | 2 +- reactos/drivers/ksfilter/ks/api.c | 38 ++- reactos/drivers/ksfilter/ks/bag.c | 2 +- reactos/drivers/ksfilter/ks/clocks.c | 266 +++++++++++++++++- reactos/drivers/ksfilter/ks/connectivity.c | 219 ++++++++------- reactos/drivers/ksfilter/ks/device.c | 62 +++-- reactos/drivers/ksfilter/ks/driver.c | 11 +- reactos/drivers/ksfilter/ks/filter.c | 288 ++++++++++---------- reactos/drivers/ksfilter/ks/filterfactory.c | 43 ++- reactos/drivers/ksfilter/ks/irp.c | 28 +- reactos/drivers/ksfilter/ks/ksfunc.h | 25 +- reactos/drivers/ksfilter/ks/ksiface.h | 4 +- reactos/drivers/ksfilter/ks/kstypes.h | 5 +- reactos/drivers/ksfilter/ks/misc.c | 11 +- reactos/drivers/ksfilter/ks/pin.c | 146 ++++++++-- reactos/drivers/ksfilter/ks/priv.h | 3 +- 16 files changed, 806 insertions(+), 347 deletions(-) diff --git a/reactos/drivers/ksfilter/ks/allocators.c b/reactos/drivers/ksfilter/ks/allocators.c index 3040a041837..5a4970f1b58 100644 --- a/reactos/drivers/ksfilter/ks/allocators.c +++ b/reactos/drivers/ksfilter/ks/allocators.c @@ -251,7 +251,7 @@ IKsAllocator_fnDeviceIoControl( } } - /* unhandeled request */ + /* unhandled request */ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; IoCompleteRequest(Irp, IO_NO_INCREMENT); diff --git a/reactos/drivers/ksfilter/ks/api.c b/reactos/drivers/ksfilter/ks/api.c index 6c0d8813772..2067de57648 100644 --- a/reactos/drivers/ksfilter/ks/api.c +++ b/reactos/drivers/ksfilter/ks/api.c @@ -1629,7 +1629,7 @@ KsAcquireDevice( DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice); /* get device interface*/ - KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice; + KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown; /* acquire device mutex */ KsDevice->lpVtbl->AcquireDevice(KsDevice); @@ -1647,7 +1647,7 @@ KsReleaseDevice( PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice); /* get device interface*/ - KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice; + KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown; /* release device mutex */ KsDevice->lpVtbl->ReleaseDevice(KsDevice); @@ -1670,7 +1670,7 @@ KsTerminateDevice( DeviceHeader = DeviceExtension->DeviceHeader; /* get device interface*/ - KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice; + KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown; /* now free device header */ KsFreeDeviceHeader((KSDEVICE_HEADER)DeviceHeader); @@ -1960,7 +1960,7 @@ KsDeviceGetBusData( } /* - @unimplemented + @implemented */ KSDDKAPI void @@ -1971,7 +1971,12 @@ KsDeviceRegisterAdapterObject( IN ULONG MaxMappingsByteCount, IN ULONG MappingTableStride) { - UNIMPLEMENTED + PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice); + + DeviceHeader->AdapterObject = AdapterObject; + DeviceHeader->MaxMappingsByteCount = MaxMappingsByteCount; + DeviceHeader->MappingTableStride = MappingTableStride; + } /* @@ -1984,6 +1989,7 @@ KsGetBusEnumIdentifier( IN PIRP Irp) { UNIMPLEMENTED + return STATUS_UNSUCCESSFUL; } @@ -2700,8 +2706,26 @@ KsRegisterAggregatedClientUnknown( IN PVOID Object, IN PUNKNOWN ClientUnknown) { - UNIMPLEMENTED - return NULL; + PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER)); + + /* sanity check */ + ASSERT(BasicHeader->Type == KsObjectTypeDevice || BasicHeader->Type == KsObjectTypeFilterFactory || + BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin); + + if (BasicHeader->ClientAggregate) + { + /* release existing aggregate */ + BasicHeader->ClientAggregate->lpVtbl->Release(BasicHeader->ClientAggregate); + } + + /* increment reference count */ + ClientUnknown->lpVtbl->AddRef(ClientUnknown); + + /* store client aggregate */ + BasicHeader->ClientAggregate = ClientUnknown; + + /* return objects outer unknown */ + return BasicHeader->OuterUnknown; } /* diff --git a/reactos/drivers/ksfilter/ks/bag.c b/reactos/drivers/ksfilter/ks/bag.c index d0b76cc8cd1..87f7a2bbef0 100644 --- a/reactos/drivers/ksfilter/ks/bag.c +++ b/reactos/drivers/ksfilter/ks/bag.c @@ -41,7 +41,7 @@ KsAllocateObjectBag( return STATUS_INSUFFICIENT_RESOURCES; /* get device interface */ - KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice; + KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown; /* initialize object bag */ return KsDevice->lpVtbl->InitializeObjectBag(KsDevice, Bag, NULL); diff --git a/reactos/drivers/ksfilter/ks/clocks.c b/reactos/drivers/ksfilter/ks/clocks.c index 2e7ff0e2a39..05064be740a 100644 --- a/reactos/drivers/ksfilter/ks/clocks.c +++ b/reactos/drivers/ksfilter/ks/clocks.c @@ -21,20 +21,235 @@ typedef struct PFNKSSETTIMER SetTimer; PFNKSCANCELTIMER CancelTimer; PFNKSCORRELATEDTIME CorrelatedTime; - KSRESOLUTION* Resolution; + LONGLONG Granularity; + LONGLONG Error; ULONG Flags; }KSIDEFAULTCLOCK, *PKSIDEFAULTCLOCK; typedef struct { - IKsClock *lpVtbl; LONG ref; PKSCLOCK_CREATE ClockCreate; PKSIDEFAULTCLOCK DefaultClock; PKSIOBJECT_HEADER ObjectHeader; }KSICLOCK, *PKSICLOCK; +NTSTATUS NTAPI ClockPropertyTime(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI ClockPropertyPhysicalTime(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI ClockPropertyCorrelatedTime(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI ClockPropertyCorrelatedPhysicalTime(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI ClockPropertyResolution(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI ClockPropertyState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI ClockPropertyFunctionTable(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); + +DEFINE_KSPROPERTY_CLOCKSET(ClockPropertyTable, ClockPropertyTime, ClockPropertyPhysicalTime, ClockPropertyCorrelatedTime, ClockPropertyCorrelatedPhysicalTime, ClockPropertyResolution, ClockPropertyState, ClockPropertyFunctionTable); + +KSPROPERTY_SET ClockPropertySet[] = +{ + { + &KSPROPSETID_Clock, + sizeof(ClockPropertyTable) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&ClockPropertyTable, + 0, + NULL + } +}; + +LONGLONG +FASTCALL +ClockGetPhysicalTime( + IN PFILE_OBJECT FileObject) +{ + UNIMPLEMENTED + return 0; +} + +LONGLONG +FASTCALL +ClockGetCorrelatedTime( + IN PFILE_OBJECT FileObject, + OUT PLONGLONG SystemTime) +{ + UNIMPLEMENTED + return 0; +} + +LONGLONG +FASTCALL +ClockGetTime( + IN PFILE_OBJECT FileObject) +{ + UNIMPLEMENTED + return 0; +} + +LONGLONG +FASTCALL +ClockGetCorrelatedPhysicalTime( + IN PFILE_OBJECT FileObject, + OUT PLONGLONG SystemTime) +{ + UNIMPLEMENTED + return 0; +} + +NTSTATUS +NTAPI +ClockPropertyTime( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + PLONGLONG Time = (PLONGLONG)Data; + PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp); + + DPRINT("ClockPropertyTime\n"); + + *Time = ClockGetTime(IoStack->FileObject); + + Irp->IoStatus.Information = sizeof(LONGLONG); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ClockPropertyPhysicalTime( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + PLONGLONG Time = (PLONGLONG)Data; + PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp); + + DPRINT("ClockPropertyPhysicalTime\n"); + + *Time = ClockGetPhysicalTime(IoStack->FileObject); + + Irp->IoStatus.Information = sizeof(LONGLONG); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ClockPropertyCorrelatedTime( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + PKSCORRELATED_TIME Time = (PKSCORRELATED_TIME)Data; + PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp); + + DPRINT("ClockPropertyCorrelatedTime\n"); + + Time->Time = ClockGetCorrelatedTime(IoStack->FileObject, &Time->SystemTime); + + Irp->IoStatus.Information = sizeof(KSCORRELATED_TIME); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ClockPropertyCorrelatedPhysicalTime( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + PKSCORRELATED_TIME Time = (PKSCORRELATED_TIME)Data; + PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp); + + DPRINT("ClockPropertyCorrelatedPhysicalTime\n"); + + Time->Time = ClockGetCorrelatedPhysicalTime(IoStack->FileObject, &Time->SystemTime); + + Irp->IoStatus.Information = sizeof(KSCORRELATED_TIME); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ClockPropertyResolution( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + PKSICLOCK Clock; + PKSIOBJECT_HEADER ObjectHeader; + PIO_STACK_LOCATION IoStack; + PKSRESOLUTION Resolution = (PKSRESOLUTION)Data; + + DPRINT("ClockPropertyResolution\n"); + + /* get stack location */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* get the object header */ + ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2; + + /* sanity check */ + ASSERT(ObjectHeader); + + /* locate ks pin implemention from KSPIN offset */ + Clock = (PKSICLOCK)ObjectHeader->ObjectType; + + Resolution->Error = Clock->DefaultClock->Error; + Resolution->Granularity = Clock->DefaultClock->Granularity; + + Irp->IoStatus.Information = sizeof(KSRESOLUTION); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ClockPropertyState( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + PKSICLOCK Clock; + PKSIOBJECT_HEADER ObjectHeader; + PKSSTATE State = (PKSSTATE)Data; + PIO_STACK_LOCATION IoStack; + + DPRINT("ClockPropertyState\n"); + + /* get stack location */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* get the object header */ + ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2; + + /* sanity check */ + ASSERT(ObjectHeader); + + /* locate ks pin implemention from KSPIN offset */ + Clock = (PKSICLOCK)ObjectHeader->ObjectType; + + *State = Clock->DefaultClock->State; + Irp->IoStatus.Information = sizeof(KSSTATE); + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ClockPropertyFunctionTable( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + PKSCLOCK_FUNCTIONTABLE Table = (PKSCLOCK_FUNCTIONTABLE)Data; + + DPRINT("ClockPropertyFunctionTable\n"); + + Table->GetCorrelatedPhysicalTime = ClockGetCorrelatedPhysicalTime; + Table->GetCorrelatedTime = ClockGetCorrelatedTime; + Table->GetPhysicalTime = ClockGetPhysicalTime; + Table->GetTime = ClockGetTime; + + return STATUS_SUCCESS; +} + /* @implemented @@ -96,7 +311,32 @@ IKsClock_DispatchDeviceIoControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - UNIMPLEMENTED + PIO_STACK_LOCATION IoStack; + UNICODE_STRING GuidString; + PKSPROPERTY Property; + NTSTATUS Status; + + DPRINT("IKsClock_DispatchDeviceIoControl\n"); + + /* get current io stack */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* FIXME support events */ + ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY); + + /* sanity check */ + ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSPROPERTY)); + + /* call property handler */ + Status = KsPropertyHandler(Irp, 1, ClockPropertySet); + + /* get property from input buffer */ + Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + + RtlStringFromGUID(&Property->Set, &GuidString); + DPRINT("IKsClock_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); + Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); @@ -145,7 +385,6 @@ KsCreateDefaultClock( NTSTATUS Status; PKSCLOCK_CREATE ClockCreate; PKSICLOCK Clock; - PKSOBJECT_CREATE_ITEM CreateItem; Status = KsValidateClockCreateRequest(Irp, &ClockCreate); if (!NT_SUCCESS(Status)) @@ -169,7 +408,7 @@ KsCreateDefaultClock( /* initialize clock */ /* FIXME IKsClock */ - Clock->ObjectHeader->Unknown = (PUNKNOWN)&Clock->lpVtbl; + Clock->ObjectHeader->ObjectType = (PVOID)Clock; Clock->ref = 1; Clock->ClockCreate = ClockCreate; Clock->DefaultClock = (PKSIDEFAULTCLOCK)DefaultClock; @@ -177,9 +416,6 @@ KsCreateDefaultClock( /* increment reference count */ InterlockedIncrement(&Clock->DefaultClock->ReferenceCount); - /* get create item */ - CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); - return Status; } @@ -228,9 +464,21 @@ KsAllocateDefaultClockEx( Clock->SetTimer = SetTimer; Clock->CancelTimer = CancelTimer; Clock->CorrelatedTime = CorrelatedTime; - Clock->Resolution = (PKSRESOLUTION)Resolution; Clock->Flags = Flags; + if (Resolution) + { + if (SetTimer) + { + Clock->Error = Resolution->Error; + } + + if (CorrelatedTime) + { + Clock->Granularity = Resolution->Granularity; + } + } + *DefaultClock = (PKSDEFAULTCLOCK)Clock; return STATUS_SUCCESS; } diff --git a/reactos/drivers/ksfilter/ks/connectivity.c b/reactos/drivers/ksfilter/ks/connectivity.c index ea75428632a..bcc55cc6f1f 100644 --- a/reactos/drivers/ksfilter/ks/connectivity.c +++ b/reactos/drivers/ksfilter/ks/connectivity.c @@ -23,6 +23,7 @@ KSPIN_MEDIUM StandardPinMedium = 0 }; +const GUID KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT = {0xf4aeb342, 0x0329, 0x4fdd, {0xa8, 0xfd, 0x4a, 0xff, 0x49, 0x26, 0xc9, 0x78}}; /* @implemented @@ -53,16 +54,12 @@ KsCreatePin( ConnectionHandle); } -/* - @unimplemented -*/ -KSDDKAPI NTSTATUS -NTAPI -KsValidateConnectRequest( - IN PIRP Irp, - IN ULONG DescriptorsCount, - IN KSPIN_DESCRIPTOR* Descriptor, +KspValidateConnectRequest( + IN PIRP Irp, + IN ULONG DescriptorsCount, + IN PVOID Descriptors, + IN ULONG DescriptorSize, OUT PKSPIN_CONNECT* Connect) { PKSPIN_CONNECT ConnectDetails; @@ -73,6 +70,7 @@ KsValidateConnectRequest( ULONG Index; ULONG Count; BOOLEAN Found; + PKSPIN_DESCRIPTOR Descriptor; /* did the caller miss the connect parameter */ if (!Connect) @@ -95,12 +93,24 @@ KsValidateConnectRequest( if (ConnectDetails->PinId >= DescriptorsCount) return STATUS_INVALID_PARAMETER; + if (DescriptorSize == sizeof(KSPIN_DESCRIPTOR)) + { + /* standard pin descriptor */ + Descriptor = (PKSPIN_DESCRIPTOR)((ULONG_PTR)Descriptors + sizeof(KSPIN_DESCRIPTOR) * ConnectDetails->PinId); + } + else + { + /* extended / variable pin descriptor */ + Descriptor = &((PKSPIN_DESCRIPTOR_EX)((ULONG_PTR)Descriptors + DescriptorSize * ConnectDetails->PinId))->PinDescriptor; + } + + /* does the pin have interface details filled in */ - if (Descriptor[ConnectDetails->PinId].InterfacesCount && Descriptor[ConnectDetails->PinId].Interfaces) + if (Descriptor->InterfacesCount && Descriptor->Interfaces) { /* use provided pin interface count */ - Count = Descriptor[ConnectDetails->PinId].InterfacesCount; - Interface = (PKSPIN_INTERFACE)Descriptor[ConnectDetails->PinId].Interfaces; + Count = Descriptor->InterfacesCount; + Interface = (PKSPIN_INTERFACE)Descriptor->Interfaces; } else { @@ -114,6 +124,13 @@ KsValidateConnectRequest( Index = 0; do { + UNICODE_STRING GuidString, GuidString2; + RtlStringFromGUID(&Interface[Index].Set, &GuidString); + RtlStringFromGUID(&ConnectDetails->Interface.Set, &GuidString2); + + DPRINT("Driver Interface %S Id %u\n", GuidString.Buffer, Interface[Index].Id); + DPRINT("Connect Interface %S Id %u\n", GuidString2.Buffer, ConnectDetails->Interface.Id); + if (IsEqualGUIDAligned(&Interface[Index].Set, &ConnectDetails->Interface.Set) && Interface[Index].Id == ConnectDetails->Interface.Id) { @@ -132,11 +149,11 @@ KsValidateConnectRequest( } /* does the pin have medium details filled in */ - if (Descriptor[ConnectDetails->PinId].MediumsCount && Descriptor[ConnectDetails->PinId].Mediums) + if (Descriptor->MediumsCount && Descriptor->Mediums) { /* use provided pin interface count */ - Count = Descriptor[ConnectDetails->PinId].MediumsCount; - Medium = (PKSPIN_MEDIUM)Descriptor[ConnectDetails->PinId].Mediums; + Count = Descriptor->MediumsCount; + Medium = (PKSPIN_MEDIUM)Descriptor->Mediums; } else { @@ -150,6 +167,14 @@ KsValidateConnectRequest( Index = 0; do { + UNICODE_STRING GuidString, GuidString2; + RtlStringFromGUID(&Medium[Index].Set, &GuidString); + RtlStringFromGUID(&ConnectDetails->Medium.Set, &GuidString2); + + DPRINT("Driver Medium %S Id %u\n", GuidString.Buffer, Medium[Index].Id); + DPRINT("Connect Medium %S Id %u\n", GuidString2.Buffer, ConnectDetails->Medium.Id); + + if (IsEqualGUIDAligned(&Medium[Index].Set, &ConnectDetails->Medium.Set) && Medium[Index].Id == ConnectDetails->Medium.Id) { @@ -157,6 +182,9 @@ KsValidateConnectRequest( Found = TRUE; break; } + + + /* iterate to next medium */ Index++; }while(Index < Count); @@ -174,6 +202,20 @@ KsValidateConnectRequest( return STATUS_SUCCESS; } +/* + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsValidateConnectRequest( + IN PIRP Irp, + IN ULONG DescriptorsCount, + IN KSPIN_DESCRIPTOR* Descriptor, + OUT PKSPIN_CONNECT* Connect) +{ + return KspValidateConnectRequest(Irp, DescriptorsCount, Descriptor, sizeof(KSPIN_DESCRIPTOR), Connect); +} NTSTATUS KspReadMediaCategory( @@ -265,18 +307,16 @@ KspReadMediaCategory( return Status; } -/* - @implemented -*/ KSDDKAPI NTSTATUS NTAPI -KsPinPropertyHandler( +KspPinPropertyHandler( IN PIRP Irp, IN PKSPROPERTY Property, IN OUT PVOID Data, IN ULONG DescriptorsCount, - IN const KSPIN_DESCRIPTOR* Descriptor) + IN const KSPIN_DESCRIPTOR* Descriptors, + IN ULONG DescriptorSize) { KSP_PIN * Pin; KSMULTIPLE_ITEM * Item; @@ -286,6 +326,7 @@ KsPinPropertyHandler( PKSDATARANGE_AUDIO *WaveFormatOut; PKSDATAFORMAT_WAVEFORMATEX WaveFormatIn; PKEY_VALUE_PARTIAL_INFORMATION KeyInfo; + const KSPIN_DESCRIPTOR *Descriptor; NTSTATUS Status = STATUS_NOT_SUPPORTED; ULONG Count; const PKSDATARANGE* DataRanges; @@ -295,6 +336,29 @@ KsPinPropertyHandler( //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); + /* convert to PKSP_PIN */ + Pin = (KSP_PIN*)Property; + + if (Property->Id != KSPROPERTY_PIN_CTYPES) + { + if (Pin->PinId >= DescriptorsCount) + { + /* invalid parameter */ + return STATUS_INVALID_PARAMETER; + } + } + + if (DescriptorSize == sizeof(KSPIN_DESCRIPTOR)) + { + /* it is simple pin descriptor */ + Descriptor = &Descriptors[Pin->PinId]; + } + else + { + /* get offset to pin descriptor */ + Descriptor = &(((PKSPIN_DESCRIPTOR_EX)((ULONG_PTR)Descriptors + Pin->PinId * DescriptorSize))->PinDescriptor); + } + switch(Property->Id) { case KSPROPERTY_PIN_CTYPES: @@ -303,13 +367,7 @@ KsPinPropertyHandler( Status = STATUS_SUCCESS; break; case KSPROPERTY_PIN_DATAFLOW: - Pin = (KSP_PIN*)Property; - if (Pin->PinId >= DescriptorsCount) - { - Status = STATUS_INVALID_PARAMETER; - Irp->IoStatus.Information = 0; - break; - } + Size = sizeof(KSPIN_DATAFLOW); if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size) { @@ -318,30 +376,26 @@ KsPinPropertyHandler( break; } - *((KSPIN_DATAFLOW*)Buffer) = Descriptor[Pin->PinId].DataFlow; + *((KSPIN_DATAFLOW*)Buffer) = Descriptor->DataFlow; Irp->IoStatus.Information = sizeof(KSPIN_DATAFLOW); Status = STATUS_SUCCESS; break; case KSPROPERTY_PIN_DATARANGES: case KSPROPERTY_PIN_CONSTRAINEDDATARANGES: - Pin = (KSP_PIN*)Property; - if (Pin->PinId >= DescriptorsCount) - { - Status = STATUS_INVALID_PARAMETER; - Irp->IoStatus.Information = 0; - break; - } + Size = sizeof(KSMULTIPLE_ITEM); - if (Property->Id == KSPROPERTY_PIN_DATARANGES || Descriptor[Pin->PinId].ConstrainedDataRangesCount == 0) + DPRINT("Id %lu PinId %lu DataRangesCount %lu ConstrainedDataRangesCount %lu\n", Property->Id, Pin->PinId, Descriptor->DataRangesCount, Descriptor->ConstrainedDataRangesCount); + + if (Property->Id == KSPROPERTY_PIN_DATARANGES || Descriptor->ConstrainedDataRangesCount == 0) { - DataRanges = Descriptor[Pin->PinId].DataRanges; - Count = Descriptor[Pin->PinId].DataRangesCount; + DataRanges = Descriptor->DataRanges; + Count = Descriptor->DataRangesCount; } else { - DataRanges = Descriptor[Pin->PinId].ConstrainedDataRanges; - Count = Descriptor[Pin->PinId].ConstrainedDataRangesCount; + DataRanges = Descriptor->ConstrainedDataRanges; + Count = Descriptor->ConstrainedDataRangesCount; } for (Index = 0; Index < Count; Index++) @@ -410,18 +464,11 @@ KsPinPropertyHandler( Irp->IoStatus.Information = Size; break; case KSPROPERTY_PIN_INTERFACES: - Pin = (KSP_PIN*)Property; - if (Pin->PinId >= DescriptorsCount) - { - Status = STATUS_INVALID_PARAMETER; - Irp->IoStatus.Information = 0; - break; - } - if (Descriptor[Pin->PinId].Interfaces) + if (Descriptor->Interfaces) { /* use mediums provided by driver */ - return KsHandleSizedListQuery(Irp, Descriptor[Pin->PinId].InterfacesCount, sizeof(KSPIN_MEDIUM), Descriptor[Pin->PinId].Interfaces); + return KsHandleSizedListQuery(Irp, Descriptor->InterfacesCount, sizeof(KSPIN_MEDIUM), Descriptor->Interfaces); } else { @@ -431,18 +478,11 @@ KsPinPropertyHandler( break; case KSPROPERTY_PIN_MEDIUMS: - Pin = (KSP_PIN*)Property; - if (Pin->PinId >= DescriptorsCount) - { - Status = STATUS_INVALID_PARAMETER; - Irp->IoStatus.Information = 0; - break; - } - if (Descriptor[Pin->PinId].MediumsCount) + if (Descriptor->MediumsCount) { /* use mediums provided by driver */ - return KsHandleSizedListQuery(Irp, Descriptor[Pin->PinId].MediumsCount, sizeof(KSPIN_MEDIUM), Descriptor[Pin->PinId].Mediums); + return KsHandleSizedListQuery(Irp, Descriptor->MediumsCount, sizeof(KSPIN_MEDIUM), Descriptor->Mediums); } else { @@ -452,13 +492,6 @@ KsPinPropertyHandler( break; case KSPROPERTY_PIN_COMMUNICATION: - Pin = (KSP_PIN*)Property; - if (Pin->PinId >= DescriptorsCount) - { - Status = STATUS_INVALID_PARAMETER; - Irp->IoStatus.Information = 0; - break; - } Size = sizeof(KSPIN_COMMUNICATION); if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size) @@ -468,21 +501,13 @@ KsPinPropertyHandler( break; } - //DPRINT("Pin %lu Communication %lu\n", Pin->PinId, Descriptor[Pin->PinId].Communication); - *((KSPIN_COMMUNICATION*)Buffer) = Descriptor[Pin->PinId].Communication; + *((KSPIN_COMMUNICATION*)Buffer) = Descriptor->Communication; Status = STATUS_SUCCESS; Irp->IoStatus.Information = Size; break; case KSPROPERTY_PIN_CATEGORY: - Pin = (KSP_PIN*)Property; - if (Pin->PinId >= DescriptorsCount) - { - Status = STATUS_INVALID_PARAMETER; - Irp->IoStatus.Information = 0; - break; - } Size = sizeof(GUID); if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size) @@ -491,9 +516,9 @@ KsPinPropertyHandler( Status = STATUS_BUFFER_TOO_SMALL; break; } - if (Descriptor[Pin->PinId].Category) + if (Descriptor->Category) { - RtlMoveMemory(Buffer, Descriptor[Pin->PinId].Category, sizeof(GUID)); + RtlMoveMemory(Buffer, Descriptor->Category, sizeof(GUID)); } Status = STATUS_SUCCESS; @@ -501,29 +526,20 @@ KsPinPropertyHandler( break; case KSPROPERTY_PIN_NAME: - Pin = (KSP_PIN*)Property; - if (Pin->PinId >= DescriptorsCount) - { - Status = STATUS_INVALID_PARAMETER; - Irp->IoStatus.Information = 0; - break; - } - - if (!Descriptor[Pin->PinId].Name) + if (!Descriptor->Name) { Irp->IoStatus.Information = 0; Status = STATUS_SUCCESS; break; } - Status = KspReadMediaCategory((LPGUID)Descriptor[Pin->PinId].Name, &KeyInfo); + Status = KspReadMediaCategory((LPGUID)Descriptor->Name, &KeyInfo); if (!NT_SUCCESS(Status)) { Irp->IoStatus.Information = 0; break; } - Irp->IoStatus.Information = KeyInfo->DataLength + sizeof(WCHAR); if (KeyInfo->DataLength + sizeof(WCHAR) > IoStack->Parameters.DeviceIoControl.OutputBufferLength) @@ -538,13 +554,6 @@ KsPinPropertyHandler( ExFreePool(KeyInfo); break; case KSPROPERTY_PIN_PROPOSEDATAFORMAT: - Pin = (KSP_PIN*)Property; - if (Pin->PinId >= DescriptorsCount) - { - Status = STATUS_INVALID_PARAMETER; - Irp->IoStatus.Information = 0; - break; - } Size = sizeof(KSDATAFORMAT); if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size) { @@ -561,14 +570,14 @@ KsPinPropertyHandler( } WaveFormatIn = (PKSDATAFORMAT_WAVEFORMATEX)Buffer; - if (!Descriptor[Pin->PinId].DataRanges || !Descriptor[Pin->PinId].DataRangesCount) + if (!Descriptor->DataRanges || !Descriptor->DataRangesCount) { Status = STATUS_UNSUCCESSFUL; Irp->IoStatus.Information = 0; break; } - WaveFormatOut = (PKSDATARANGE_AUDIO*)Descriptor[Pin->PinId].DataRanges; - for(Index = 0; Index < Descriptor[Pin->PinId].DataRangesCount; Index++) + WaveFormatOut = (PKSDATARANGE_AUDIO*)Descriptor->DataRanges; + for(Index = 0; Index < Descriptor->DataRangesCount; Index++) { if (WaveFormatOut[Index]->DataRange.FormatSize != sizeof(KSDATARANGE_AUDIO)) { @@ -605,6 +614,22 @@ KsPinPropertyHandler( return Status; } +/* + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsPinPropertyHandler( + IN PIRP Irp, + IN PKSPROPERTY Property, + IN OUT PVOID Data, + IN ULONG DescriptorsCount, + IN const KSPIN_DESCRIPTOR* Descriptor) +{ + return KspPinPropertyHandler(Irp, Property, Data, DescriptorsCount, Descriptor, sizeof(KSPIN_DESCRIPTOR)); +} + /* @unimplemented */ diff --git a/reactos/drivers/ksfilter/ks/device.c b/reactos/drivers/ksfilter/ks/device.c index 084728f3c89..432548c6d91 100644 --- a/reactos/drivers/ksfilter/ks/device.c +++ b/reactos/drivers/ksfilter/ks/device.c @@ -16,15 +16,29 @@ IKsDevice_fnQueryInterface( REFIID refiid, PVOID* Output) { - PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + NTSTATUS Status; + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); if (IsEqualGUIDAligned(refiid, &IID_IUnknown)) { - *Output = &This->lpVtblIKsDevice; + *Output = &This->BasicHeader.OuterUnknown; _InterlockedIncrement(&This->ref); return STATUS_SUCCESS; } + if (This->BasicHeader.ClientAggregate) + { + /* using client aggregate */ + Status = This->BasicHeader.ClientAggregate->lpVtbl->QueryInterface(This->BasicHeader.ClientAggregate, refiid, Output); + + if (NT_SUCCESS(Status)) + { + /* client aggregate supports interface */ + return Status; + } + } + + DPRINT("IKsDevice_fnQueryInterface no interface\n"); return STATUS_NOT_SUPPORTED; } @@ -33,7 +47,7 @@ NTAPI IKsDevice_fnAddRef( IN IKsDevice * iface) { - PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); return InterlockedIncrement(&This->ref); } @@ -43,7 +57,7 @@ NTAPI IKsDevice_fnRelease( IN IKsDevice * iface) { - PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); InterlockedDecrement(&This->ref); @@ -57,7 +71,7 @@ NTAPI IKsDevice_fnGetStruct( IN IKsDevice * iface) { - PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); return &This->KsDevice; } @@ -69,7 +83,7 @@ IKsDevice_fnInitializeObjectBag( IN PKSIOBJECT_BAG Bag, IN PRKMUTEX Mutex) { - PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); if (!Mutex) { @@ -93,7 +107,7 @@ NTAPI IKsDevice_fnAcquireDevice( IN IKsDevice * iface) { - PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); return KeWaitForSingleObject(&This->DeviceMutex, Executive, KernelMode, FALSE, NULL); } @@ -103,7 +117,7 @@ NTAPI IKsDevice_fnReleaseDevice( IN IKsDevice * iface) { - PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); return KeReleaseMutex(&This->DeviceMutex, FALSE); } @@ -113,12 +127,14 @@ NTAPI IKsDevice_fnGetAdapterObject( IN IKsDevice * iface, IN PADAPTER_OBJECT * Object, - IN PULONG Unknown1, - IN PULONG Unknown2) + IN PULONG MaxMappingsByteCount, + IN PULONG MappingTableStride) { - PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); *Object = This->AdapterObject; + *MaxMappingsByteCount = This->MaxMappingsByteCount; + *MappingTableStride = This->MappingTableStride; return STATUS_SUCCESS; @@ -131,7 +147,7 @@ IKsDevice_fnAddPowerEntry( IN struct KSPOWER_ENTRY * Entry, IN IKsPowerNotify* Notify) { - //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); UNIMPLEMENTED return STATUS_NOT_IMPLEMENTED; @@ -143,7 +159,7 @@ IKsDevice_fnRemovePowerEntry( IN IKsDevice * iface, IN struct KSPOWER_ENTRY * Entry) { - //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); UNIMPLEMENTED return STATUS_NOT_IMPLEMENTED; @@ -159,7 +175,7 @@ IKsDevice_fnPinStateChange( IN KSSTATE OldState, IN KSSTATE NewState) { - //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); UNIMPLEMENTED return STATUS_NOT_IMPLEMENTED; @@ -174,7 +190,7 @@ IKsDevice_fnArbitrateAdapterChannel( IN PDRIVER_CONTROL ExecutionRoutine, IN PVOID Context) { - PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); NTSTATUS Status; DPRINT("IKsDevice_fnArbitrateAdapterChannel NumberOfMapRegisters %lu ExecutionRoutine %p Context %p Irql %lu\n", NumberOfMapRegisters, ExecutionRoutine, Context, KeGetCurrentIrql()); @@ -196,7 +212,7 @@ IKsDevice_fnCheckIoCapability( IN IKsDevice * iface, IN ULONG Unknown) { - //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); UNIMPLEMENTED return STATUS_NOT_IMPLEMENTED; @@ -615,7 +631,7 @@ IKsDevice_Create( DeviceHeader = DeviceExtension->DeviceHeader; /* acquire list lock */ - IKsDevice_fnAcquireDevice((IKsDevice*)&DeviceHeader->lpVtblIKsDevice); + IKsDevice_fnAcquireDevice((IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown); /* sanity check */ ASSERT(IoStack->FileObject); @@ -654,7 +670,7 @@ IKsDevice_Create( } /* acquire list lock */ - IKsDevice_fnReleaseDevice((IKsDevice*)&DeviceHeader->lpVtblIKsDevice); + IKsDevice_fnReleaseDevice((IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown); if (Status != STATUS_PENDING) { @@ -726,7 +742,7 @@ KsInitializeDevice( } /* initialize IKsDevice interface */ - Header->lpVtblIKsDevice = &vt_IKsDevice; + Header->BasicHeader.OuterUnknown = (PUNKNOWN)&vt_IKsDevice; Header->ref = 1; /* allocate object bag */ @@ -810,7 +826,7 @@ KsReferenceSoftwareBusObject( PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header; /* get device interface */ - Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice; + Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown; if (Device) { @@ -834,7 +850,7 @@ KsReferenceBusObject( PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header; /* get device interface */ - Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice; + Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown; if (Device) { @@ -859,7 +875,7 @@ KsDereferenceBusObject( PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header; /* get device interface */ - Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice; + Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown; if (Device) { @@ -883,7 +899,7 @@ KsDereferenceSoftwareBusObject( DPRINT1("KsDereferenceSoftwareBusObject DeviceHeader %p\n", Header); /* get device interface */ - Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice; + Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown; if (Device) { diff --git a/reactos/drivers/ksfilter/ks/driver.c b/reactos/drivers/ksfilter/ks/driver.c index 0b6cf43a96e..c0195a4a97f 100644 --- a/reactos/drivers/ksfilter/ks/driver.c +++ b/reactos/drivers/ksfilter/ks/driver.c @@ -39,12 +39,19 @@ KsGetDevice( { PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER)); - DPRINT("KsGetDevice\n"); + DPRINT("KsGetDevice Type %lu KsDevice %p\n", BasicHeader->Type, BasicHeader->KsDevice); ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory || BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin); ASSERT(BasicHeader->KsDevice); - ASSERT(BasicHeader->KsDevice->Started); + ASSERT(BasicHeader->KsDevice->Descriptor); + ASSERT(BasicHeader->KsDevice->Bag); + ASSERT(BasicHeader->KsDevice->Context); + ASSERT(BasicHeader->KsDevice->FunctionalDeviceObject); ASSERT(BasicHeader->KsDevice->PhysicalDeviceObject); + ASSERT(BasicHeader->KsDevice->NextDeviceObject); + ASSERT(BasicHeader->KsDevice->Started); + ASSERT(BasicHeader->KsDevice->SystemPowerState == PowerSystemWorking); + ASSERT(BasicHeader->KsDevice->DevicePowerState == PowerDeviceD0); return BasicHeader->KsDevice; } diff --git a/reactos/drivers/ksfilter/ks/filter.c b/reactos/drivers/ksfilter/ks/filter.c index bcac218e848..5f4a74b9b64 100644 --- a/reactos/drivers/ksfilter/ks/filter.c +++ b/reactos/drivers/ksfilter/ks/filter.c @@ -14,16 +14,12 @@ typedef struct KSBASIC_HEADER Header; KSFILTER Filter; - IKsFilterVtbl *lpVtbl; IKsControlVtbl *lpVtblKsControl; IKsFilterFactory * FilterFactory; LONG ref; PKSIOBJECT_HEADER ObjectHeader; KSTOPOLOGY Topology; - KSPIN_DESCRIPTOR_EX * PinDescriptorsEx; - KSPIN_DESCRIPTOR * PinDescriptors; - ULONG PinDescriptorCount; PKSFILTERFACTORY Factory; PFILE_OBJECT FileObject; KMUTEX ControlMutex; @@ -49,9 +45,12 @@ IKsFilter_RemoveFilterFromFilterFactory( IKsFilterImpl * This, PKSFILTERFACTORY FilterFactory); +NTSTATUS NTAPI FilterTopologyPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI FilterPinPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); -DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet, KspTopologyPropertyHandler); -DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet, KspPinPropertyHandler, KspPinPropertyHandler, KspPinPropertyHandler); + +DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet, FilterTopologyPropertyHandler); +DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet, FilterPinPropertyHandler, FilterPinPropertyHandler, FilterPinPropertyHandler); KSPROPERTY_SET FilterPropertySet[] = { @@ -82,7 +81,7 @@ IKsControl_fnQueryInterface( if (IsEqualGUIDAligned(refiid, &IID_IUnknown)) { - *Output = &This->lpVtbl; + *Output = &This->Header.OuterUnknown; _InterlockedIncrement(&This->ref); return STATUS_SUCCESS; } @@ -185,12 +184,13 @@ IKsFilter_fnQueryInterface( IN REFIID refiid, OUT PVOID* Output) { - IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl); + NTSTATUS Status; + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); if (IsEqualGUIDAligned(refiid, &IID_IUnknown) || IsEqualGUIDAligned(refiid, &IID_IKsFilter)) { - *Output = &This->lpVtbl; + *Output = &This->Header.OuterUnknown; _InterlockedIncrement(&This->ref); return STATUS_SUCCESS; } @@ -201,7 +201,20 @@ IKsFilter_fnQueryInterface( return STATUS_SUCCESS; } - return STATUS_UNSUCCESSFUL; + if (This->Header.ClientAggregate) + { + /* using client aggregate */ + Status = This->Header.ClientAggregate->lpVtbl->QueryInterface(This->Header.ClientAggregate, refiid, Output); + + if (NT_SUCCESS(Status)) + { + /* client aggregate supports interface */ + return Status; + } + } + + DPRINT("IKsFilter_fnQueryInterface no interface\n"); + return STATUS_NOT_SUPPORTED; } ULONG @@ -209,7 +222,7 @@ NTAPI IKsFilter_fnAddRef( IKsFilter * iface) { - IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl); + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); return InterlockedIncrement(&This->ref); } @@ -219,7 +232,7 @@ NTAPI IKsFilter_fnRelease( IKsFilter * iface) { - IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl); + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); InterlockedDecrement(&This->ref); @@ -238,7 +251,7 @@ NTAPI IKsFilter_fnGetStruct( IKsFilter * iface) { - IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl); + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); return &This->Filter; } @@ -295,18 +308,18 @@ IKsFilter_fnAddProcessPin( IN PKSPROCESSPIN ProcessPin) { NTSTATUS Status; - IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl); + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); /* first acquire processing mutex */ KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL); /* sanity check */ - ASSERT(This->PinDescriptorCount > ProcessPin->Pin->Id); + ASSERT(This->Filter.Descriptor->PinDescriptorsCount > ProcessPin->Pin->Id); /* allocate new process pin array */ Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex[ProcessPin->Pin->Id].Pins, - (This->PinDescriptorCount + 1) * sizeof(PKSPROCESSPIN), - This->PinDescriptorCount * sizeof(PKSPROCESSPIN), + (This->Filter.Descriptor->PinDescriptorsCount + 1) * sizeof(PKSPROCESSPIN), + This->Filter.Descriptor->PinDescriptorsCount * sizeof(PKSPROCESSPIN), 0); if (NT_SUCCESS(Status)) @@ -332,7 +345,7 @@ IKsFilter_fnRemoveProcessPin( ULONG Count; PKSPROCESSPIN * Pins; - IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl); + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); /* first acquire processing mutex */ KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL); @@ -416,7 +429,7 @@ NTAPI IKsFilter_fnGetProcessDispatch( IKsFilter * iface) { - IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl); + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); return This->ProcessPinIndex; } @@ -495,13 +508,13 @@ IKsFilter_DispatchClose( return Status; /* get our real implementation */ - This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, lpVtbl); + This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Header.OuterUnknown); /* does the driver support notifications */ - if (This->Factory->FilterDescriptor && This->Factory->FilterDescriptor->Dispatch && This->Factory->FilterDescriptor->Dispatch->Close) + if (This->Filter.Descriptor && This->Filter.Descriptor->Dispatch && This->Filter.Descriptor->Dispatch->Close) { /* call driver's filter close function */ - Status = This->Factory->FilterDescriptor->Dispatch->Close(&This->Filter, Irp); + Status = This->Filter.Descriptor->Dispatch->Close(&This->Filter, Irp); } if (NT_SUCCESS(Status) && Status != STATUS_PENDING) @@ -540,7 +553,7 @@ KspHandlePropertyInstances( KSPIN_CINSTANCES * Instances; KSP_PIN * Pin = (KSP_PIN*)Request; - if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount) + if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount) { /* no filter / pin descriptor */ IoStatus->Status = STATUS_NOT_IMPLEMENTED; @@ -548,12 +561,12 @@ KspHandlePropertyInstances( } /* ignore custom structs for now */ - ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); - ASSERT(This->PinDescriptorCount > Pin->PinId); + ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); + ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId); Instances = (KSPIN_CINSTANCES*)Data; /* max instance count */ - Instances->PossibleCount = This->PinDescriptorsEx[Pin->PinId].InstancesPossible; + Instances->PossibleCount = This->Filter.Descriptor->PinDescriptors[Pin->PinId].InstancesPossible; /* current instance count */ Instances->CurrentCount = This->PinInstanceCount[Pin->PinId]; @@ -572,7 +585,7 @@ KspHandleNecessaryPropertyInstances( PULONG Result; KSP_PIN * Pin = (KSP_PIN*)Request; - if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount) + if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount) { /* no filter / pin descriptor */ IoStatus->Status = STATUS_NOT_IMPLEMENTED; @@ -580,11 +593,11 @@ KspHandleNecessaryPropertyInstances( } /* ignore custom structs for now */ - ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); - ASSERT(This->PinDescriptorCount > Pin->PinId); + ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); + ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId); Result = (PULONG)Data; - *Result = This->PinDescriptorsEx[Pin->PinId].InstancesNecessary; + *Result = This->Filter.Descriptor->PinDescriptors[Pin->PinId].InstancesNecessary; IoStatus->Information = sizeof(ULONG); IoStatus->Status = STATUS_SUCCESS; @@ -604,8 +617,15 @@ KspHandleDataIntersection( PKSDATARANGE DataRange; NTSTATUS Status = STATUS_NO_MATCH; ULONG Index, Length; + PIO_STACK_LOCATION IoStack; KSP_PIN * Pin = (KSP_PIN*)Request; + /* get stack location */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* sanity check */ + ASSERT(DataLength == IoStack->Parameters.DeviceIoControl.OutputBufferLength); + /* Access parameters */ MultipleItem = (PKSMULTIPLE_ITEM)(Pin + 1); DataRange = (PKSDATARANGE)(MultipleItem + 1); @@ -613,7 +633,7 @@ KspHandleDataIntersection( /* FIXME make sure its 64 bit aligned */ ASSERT(((ULONG_PTR)DataRange & 0x7) == 0); - if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount) + if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount) { /* no filter / pin descriptor */ IoStatus->Status = STATUS_NOT_IMPLEMENTED; @@ -621,12 +641,12 @@ KspHandleDataIntersection( } /* ignore custom structs for now */ - ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); - ASSERT(This->PinDescriptorCount > Pin->PinId); + ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); + ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId); - if (This->PinDescriptorsEx[Pin->PinId].IntersectHandler == NULL || - This->PinDescriptors[Pin->PinId].DataRanges == NULL || - This->PinDescriptors[Pin->PinId].DataRangesCount == 0) + if (This->Filter.Descriptor->PinDescriptors[Pin->PinId].IntersectHandler == NULL || + This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges == NULL || + This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRangesCount == 0) { /* no driver supported intersect handler / no provided data ranges */ IoStatus->Status = STATUS_NOT_IMPLEMENTED; @@ -641,26 +661,25 @@ KspHandleDataIntersection( 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); + DPRINT("KspHandleDataIntersection Index %lu PinId %lu MajorFormat %S SubFormat %S Specifier %S FormatSize %lu SampleSize %lu Align %lu Flags %lx Reserved %lx DataLength %lu\n", Index, Pin->PinId, 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(&This->Filter, - Irp, - Pin, - DataRange, - This->PinDescriptorsEx[Pin->PinId].PinDescriptor.DataRanges[0], /* HACK */ - DataLength, - Data, - &Length); + Status = This->Filter.Descriptor->PinDescriptors[Pin->PinId].IntersectHandler(&This->Filter, + Irp, + Pin, + DataRange, + This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges[0], /* HACK */ + DataLength, + Data, + &Length); + DPRINT("KspHandleDataIntersection Status %lx\n", Status); 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; } @@ -668,14 +687,13 @@ KspHandleDataIntersection( /* FIXME make sure its 64 bit aligned */ ASSERT(((ULONG_PTR)DataRange & 0x7) == 0); } - IoStatus->Status = Status; return Status; } NTSTATUS NTAPI -KspTopologyPropertyHandler( +FilterTopologyPropertyHandler( IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data) @@ -695,7 +713,7 @@ KspTopologyPropertyHandler( NTSTATUS NTAPI -KspPinPropertyHandler( +FilterPinPropertyHandler( IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data) @@ -724,7 +742,7 @@ KspPinPropertyHandler( case KSPROPERTY_PIN_CATEGORY: case KSPROPERTY_PIN_NAME: case KSPROPERTY_PIN_CONSTRAINEDDATARANGES: - Status = KsPinPropertyHandler(Irp, Request, Data, This->PinDescriptorCount, This->PinDescriptors); + Status = KspPinPropertyHandler(Irp, Request, Data, This->Filter.Descriptor->PinDescriptorsCount, (const KSPIN_DESCRIPTOR*)This->Filter.Descriptor->PinDescriptors, This->Filter.Descriptor->PinDescriptorSize); break; case KSPROPERTY_PIN_GLOBALCINSTANCES: Status = KspHandlePropertyInstances(&Irp->IoStatus, Request, Data, This, TRUE); @@ -770,7 +788,7 @@ IKsFilter_DispatchDeviceIoControl( return Status; /* get our real implementation */ - This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, lpVtbl); + This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Header.OuterUnknown); /* current irp stack */ IoStack = IoGetCurrentIrpStackLocation(Irp); @@ -781,16 +799,14 @@ IKsFilter_DispatchDeviceIoControl( /* get filter instance */ FilterInstance = Filter->lpVtbl->GetStruct(Filter); - /* sanity check */ ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSIDENTIFIER)); ASSERT(FilterInstance); ASSERT(FilterInstance->Descriptor); ASSERT(FilterInstance->Descriptor->AutomationTable); - RtlStringFromGUID(&Property->Set, &GuidString); - DPRINT("IKsFilter_DispatchDeviceIoControl property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags); - RtlFreeUnicodeString(&GuidString); + /* acquire control mutex */ + KeWaitForSingleObject(This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL); if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_METHOD) { @@ -859,6 +875,9 @@ IKsFilter_DispatchDeviceIoControl( /* release filter */ Filter->lpVtbl->Release(Filter); + /* release control mutex */ + KeReleaseMutex(This->Header.ControlMutex, FALSE); + if (Status != STATUS_PENDING) { Irp->IoStatus.Status = Status; @@ -895,10 +914,7 @@ IKsFilter_CreateDescriptors( /* initialize pin descriptors */ This->FirstPin = NULL; This->PinInstanceCount = NULL; - This->PinDescriptors = NULL; - This->PinDescriptorsEx = NULL; This->ProcessPinIndex = NULL; - This->PinDescriptorCount = 0; /* initialize topology descriptor */ This->Topology.CategoriesCount = FilterDescriptor->CategoriesCount; @@ -917,8 +933,8 @@ IKsFilter_CreateDescriptors( ASSERT(FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); /* store pin descriptors ex */ - Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinDescriptorsEx, sizeof(KSPIN_DESCRIPTOR_EX) * FilterDescriptor->PinDescriptorsCount, - sizeof(KSPIN_DESCRIPTOR_EX) * FilterDescriptor->PinDescriptorsCount, 0); + Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->Filter.Descriptor->PinDescriptors, FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount, + FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount, 0); if (!NT_SUCCESS(Status)) { @@ -926,17 +942,7 @@ IKsFilter_CreateDescriptors( return Status; } - /* store pin descriptors */ - Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinDescriptors, sizeof(KSPIN_DESCRIPTOR) * FilterDescriptor->PinDescriptorsCount, - sizeof(KSPIN_DESCRIPTOR) * FilterDescriptor->PinDescriptorsCount, 0); - - if (!NT_SUCCESS(Status)) - { - DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status); - return Status; - } - - /* store pin instance count ex */ + /* store pin instance count */ Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinInstanceCount, sizeof(ULONG) * FilterDescriptor->PinDescriptorsCount, sizeof(ULONG) * FilterDescriptor->PinDescriptorsCount, 0); @@ -957,12 +963,7 @@ IKsFilter_CreateDescriptors( } /* add new pin factory */ - RtlMoveMemory(This->PinDescriptorsEx, FilterDescriptor->PinDescriptors, sizeof(KSPIN_DESCRIPTOR_EX) * FilterDescriptor->PinDescriptorsCount); - - for(Index = 0; Index < FilterDescriptor->PinDescriptorsCount; Index++) - { - RtlMoveMemory(&This->PinDescriptors[Index], &FilterDescriptor->PinDescriptors[Index].PinDescriptor, sizeof(KSPIN_DESCRIPTOR)); - } + RtlMoveMemory((PVOID)This->Filter.Descriptor->PinDescriptors, FilterDescriptor->PinDescriptors, FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount); /* allocate process pin index */ Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex, sizeof(KSPROCESSPIN_INDEXENTRY) * FilterDescriptor->PinDescriptorsCount, @@ -974,9 +975,20 @@ IKsFilter_CreateDescriptors( return Status; } - /* store new pin descriptor count */ - This->PinDescriptorCount = FilterDescriptor->PinDescriptorsCount; + } + + if (FilterDescriptor->ConnectionsCount) + { + /* modify connections array */ + Status = _KsEdit(This->Filter.Bag, + (PVOID*)&This->Filter.Descriptor->Connections, + FilterDescriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION), + FilterDescriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION), + 0); + + This->Topology.TopologyConnections = This->Filter.Descriptor->Connections; + This->Topology.TopologyConnectionsCount = ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->ConnectionsCount = FilterDescriptor->ConnectionsCount; } if (FilterDescriptor->NodeDescriptorsCount) @@ -1070,7 +1082,7 @@ IKsFilter_AddPin( IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); /* sanity check */ - ASSERT(Pin->Id < This->PinDescriptorCount); + ASSERT(Pin->Id < This->Filter.Descriptor->PinDescriptorsCount); if (This->FirstPin[Pin->Id] == NULL) { @@ -1111,7 +1123,7 @@ IKsFilter_RemovePin( IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); /* sanity check */ - ASSERT(Pin->Id < This->PinDescriptorCount); + ASSERT(Pin->Id < This->Filter.Descriptor->PinDescriptorsCount); /* get first pin */ CurPin = This->FirstPin[Pin->Id]; @@ -1180,23 +1192,23 @@ IKsFilter_DispatchCreatePin( KeWaitForSingleObject(This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL); /* now validate the connect request */ - Status = KsValidateConnectRequest(Irp, This->PinDescriptorCount, This->PinDescriptors, &Connect); + Status = KspValidateConnectRequest(Irp, This->Filter.Descriptor->PinDescriptorsCount, (PVOID)This->Filter.Descriptor->PinDescriptors, This->Filter.Descriptor->PinDescriptorSize, &Connect); DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest %lx\n", Status); if (NT_SUCCESS(Status)) { /* sanity check */ - ASSERT(Connect->PinId < This->PinDescriptorCount); + ASSERT(Connect->PinId < This->Filter.Descriptor->PinDescriptorsCount); DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest PinId %lu CurrentInstanceCount %lu MaxPossible %lu\n", Connect->PinId, This->PinInstanceCount[Connect->PinId], - This->PinDescriptorsEx[Connect->PinId].InstancesPossible); + This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible); - if (This->PinInstanceCount[Connect->PinId] < This->PinDescriptorsEx[Connect->PinId].InstancesPossible) + if (This->PinInstanceCount[Connect->PinId] < This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible) { /* create the pin */ - Status = KspCreatePin(DeviceObject, Irp, This->Header.KsDevice, This->FilterFactory, (IKsFilter*)&This->lpVtbl, Connect, &This->PinDescriptorsEx[Connect->PinId]); + Status = KspCreatePin(DeviceObject, Irp, This->Header.KsDevice, This->FilterFactory, (IKsFilter*)&This->Header.OuterUnknown, Connect, (KSPIN_DESCRIPTOR_EX*)&This->Filter.Descriptor->PinDescriptors[Connect->PinId]); DPRINT("IKsFilter_DispatchCreatePin KspCreatePin %lx\n", Status); } @@ -1204,7 +1216,7 @@ IKsFilter_DispatchCreatePin( { /* maximum instance count reached, bye-bye */ Status = STATUS_UNSUCCESSFUL; - DPRINT("IKsFilter_DispatchCreatePin MaxInstance %lu CurInstance %lu %lx\n", This->PinDescriptorsEx[Connect->PinId].InstancesPossible, This->PinInstanceCount[Connect->PinId]); + DPRINT("IKsFilter_DispatchCreatePin MaxInstance %lu CurInstance %lu %lx\n", This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible, This->PinInstanceCount[Connect->PinId]); } } @@ -1388,7 +1400,7 @@ KspCreateFilter( DPRINT("KspCreateFilter OutOfMemory\n"); return STATUS_INSUFFICIENT_RESOURCES; } - KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice; + KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->BasicHeader.OuterUnknown; KsDevice->lpVtbl->InitializeObjectBag(KsDevice, (PKSIOBJECT_BAG)This->Filter.Bag, NULL); /* copy filter descriptor */ @@ -1432,7 +1444,7 @@ KspCreateFilter( /* initialize filter instance */ This->ref = 1; - This->lpVtbl = &vt_IKsFilter; + This->Header.OuterUnknown = (PUNKNOWN)&vt_IKsFilter; This->lpVtblKsControl = &vt_IKsControl; This->Factory = Factory; @@ -1496,14 +1508,14 @@ KspCreateFilter( /* initialize object header extra fields */ This->ObjectHeader->Type = KsObjectTypeFilter; - This->ObjectHeader->Unknown = (PUNKNOWN)&This->lpVtbl; + This->ObjectHeader->Unknown = (PUNKNOWN)&This->Header.OuterUnknown; This->ObjectHeader->ObjectType = (PVOID)&This->Filter; /* attach filter to filter factory */ IKsFilter_AttachFilterToFilterFactory(This, This->Header.Parent.KsFilterFactory); /* completed initialization */ - DPRINT("KspCreateFilter done %lx\n", Status); + DPRINT("KspCreateFilter done %lx KsDevice %p\n", Status, This->Header.KsDevice); return Status; } @@ -1548,40 +1560,42 @@ KsFilterAddTopologyConnections ( IN const KSTOPOLOGY_CONNECTION *const NewTopologyConnections) { ULONG Count; - KSTOPOLOGY_CONNECTION * Connections; + NTSTATUS Status; IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); + DPRINT("KsFilterAddTopologyConnections\n"); + + ASSERT(This->Filter.Descriptor); Count = This->Filter.Descriptor->ConnectionsCount + NewConnectionsCount; - /* allocate array */ - Connections = AllocateItem(NonPagedPool, Count * sizeof(KSTOPOLOGY_CONNECTION)); - if (!Connections) - return STATUS_INSUFFICIENT_RESOURCES; + + /* modify connections array */ + Status = _KsEdit(This->Filter.Bag, + (PVOID*)&This->Filter.Descriptor->Connections, + Count * sizeof(KSTOPOLOGY_CONNECTION), + This->Filter.Descriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION), + 0); + + if (!NT_SUCCESS(Status)) + { + /* failed */ + DPRINT("KsFilterAddTopologyConnections KsEdit failed with %lx\n", Status); + return Status; + } /* FIXME verify connections */ - if (This->Filter.Descriptor->ConnectionsCount) - { - /* copy old connections */ - RtlMoveMemory(Connections, This->Filter.Descriptor->Connections, sizeof(KSTOPOLOGY_CONNECTION) * This->Filter.Descriptor->ConnectionsCount); - } + /* copy new connections */ + RtlMoveMemory((PVOID)&This->Filter.Descriptor->Connections[This->Filter.Descriptor->ConnectionsCount], + NewTopologyConnections, + NewConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION)); - /* add new connections */ - RtlMoveMemory((PVOID)(Connections + This->Filter.Descriptor->ConnectionsCount), NewTopologyConnections, NewConnectionsCount); + /* update topology */ + This->Topology.TopologyConnectionsCount += NewConnectionsCount; + ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->ConnectionsCount += NewConnectionsCount; + This->Topology.TopologyConnections = This->Filter.Descriptor->Connections; - /* add the new connections */ - RtlMoveMemory((PVOID)&This->Filter.Descriptor->ConnectionsCount, &Count, sizeof(ULONG)); /* brain-dead gcc hack */ - - /* free old connections array */ - if (This->Filter.Descriptor->ConnectionsCount) - { - FreeItem((PVOID)This->Filter.Descriptor->Connections); - } - - /* brain-dead gcc hack */ - RtlMoveMemory((PVOID)&This->Filter.Descriptor->Connections, Connections, sizeof(KSTOPOLOGY_CONNECTION*)); - - return STATUS_SUCCESS; + return Status; } /* @@ -1630,13 +1644,13 @@ KsFilterCreatePinFactory ( DPRINT("KsFilterCreatePinFactory\n"); /* calculate new count */ - Count = This->PinDescriptorCount + 1; + Count = This->Filter.Descriptor->PinDescriptorsCount + 1; /* sanity check */ ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); - /* allocate pin descriptors ex array */ - Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinDescriptorsEx, Count * sizeof(KSPIN_DESCRIPTOR_EX), This->PinDescriptorCount * sizeof(KSPIN_DESCRIPTOR_EX), 0); + /* modify pin descriptors ex array */ + Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->Filter.Descriptor->PinDescriptors, Count * This->Filter.Descriptor->PinDescriptorSize, This->Filter.Descriptor->PinDescriptorsCount * This->Filter.Descriptor->PinDescriptorSize, 0); if (!NT_SUCCESS(Status)) { /* failed */ @@ -1644,8 +1658,8 @@ KsFilterCreatePinFactory ( return Status; } - /* allocate pin descriptors array */ - Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinDescriptors, Count * sizeof(KSPIN_DESCRIPTOR), This->PinDescriptorCount * sizeof(KSPIN_DESCRIPTOR), 0); + /* modify pin instance count array */ + Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->PinInstanceCount, sizeof(ULONG) * Count, sizeof(ULONG) * This->Filter.Descriptor->PinDescriptorsCount, 0); if (!NT_SUCCESS(Status)) { /* failed */ @@ -1653,18 +1667,8 @@ KsFilterCreatePinFactory ( return Status; } - - /* allocate pin instance count array */ - Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->PinInstanceCount, sizeof(ULONG) * Count, sizeof(ULONG) * This->PinDescriptorCount, 0); - if (!NT_SUCCESS(Status)) - { - /* failed */ - DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status); - return Status; - } - - /* allocate first pin array */ - Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->FirstPin, sizeof(PKSPIN) * Count, sizeof(PKSPIN) * This->PinDescriptorCount, 0); + /* modify first pin array */ + Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->FirstPin, sizeof(PKSPIN) * Count, sizeof(PKSPIN) * This->Filter.Descriptor->PinDescriptorsCount, 0); if (!NT_SUCCESS(Status)) { /* failed */ @@ -1673,13 +1677,11 @@ KsFilterCreatePinFactory ( } /* add new pin factory */ - RtlMoveMemory(&This->PinDescriptorsEx[This->PinDescriptorCount], InPinDescriptor, sizeof(KSPIN_DESCRIPTOR_EX)); - RtlMoveMemory(&This->PinDescriptors[This->PinDescriptorCount], &InPinDescriptor->PinDescriptor, sizeof(KSPIN_DESCRIPTOR)); - + RtlMoveMemory((PVOID)&This->Filter.Descriptor->PinDescriptors[This->Filter.Descriptor->PinDescriptorsCount], InPinDescriptor, sizeof(KSPIN_DESCRIPTOR_EX)); /* allocate process pin index */ Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex, sizeof(KSPROCESSPIN_INDEXENTRY) * Count, - sizeof(KSPROCESSPIN_INDEXENTRY) * This->PinDescriptorCount, 0); + sizeof(KSPROCESSPIN_INDEXENTRY) * This->Filter.Descriptor->PinDescriptorsCount, 0); if (!NT_SUCCESS(Status)) { @@ -1688,10 +1690,10 @@ KsFilterCreatePinFactory ( } /* store new pin id */ - *PinID = This->PinDescriptorCount; + *PinID = This->Filter.Descriptor->PinDescriptorsCount; /* increment pin descriptor count */ - This->PinDescriptorCount++; + ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->PinDescriptorsCount++; DPRINT("KsFilterCreatePinFactory done\n"); @@ -1724,7 +1726,7 @@ KsFilterGetChildPinCount( { IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); - if (PinId >= This->PinDescriptorCount) + if (PinId >= This->Filter.Descriptor->PinDescriptorsCount) { /* index is out of bounds */ return 0; @@ -1745,7 +1747,7 @@ KsFilterGetFirstChildPin( { IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); - if (PinId >= This->PinDescriptorCount) + if (PinId >= This->Filter.Descriptor->PinDescriptorsCount) { /* index is out of bounds */ return NULL; diff --git a/reactos/drivers/ksfilter/ks/filterfactory.c b/reactos/drivers/ksfilter/ks/filterfactory.c index 0e15bb76f3c..e60bfc41e81 100644 --- a/reactos/drivers/ksfilter/ks/filterfactory.c +++ b/reactos/drivers/ksfilter/ks/filterfactory.c @@ -14,7 +14,6 @@ typedef struct KSBASIC_HEADER Header; KSFILTERFACTORY FilterFactory; - IKsFilterFactoryVtbl *lpVtbl; LONG ref; PKSIDEVICE_HEADER DeviceHeader; PFNKSFILTERFACTORYPOWER SleepCallback; @@ -59,7 +58,7 @@ IKsFilterFactory_Create( Factory = (IKsFilterFactoryImpl*)CONTAINING_RECORD(CreateItem->Context, IKsFilterFactoryImpl, FilterFactory); /* get interface */ - iface = (IKsFilterFactory*)&Factory->lpVtbl; + iface = (IKsFilterFactory*)&Factory->Header.OuterUnknown; /* create a filter instance */ Status = KspCreateFilter(DeviceObject, Irp, iface); @@ -84,15 +83,31 @@ IKsFilterFactory_fnQueryInterface( IN REFIID refiid, OUT PVOID* Output) { - IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl); + NTSTATUS Status; + + IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown); if (IsEqualGUIDAligned(refiid, &IID_IUnknown)) { - *Output = &This->lpVtbl; + *Output = &This->Header.OuterUnknown; _InterlockedIncrement(&This->ref); return STATUS_SUCCESS; } - return STATUS_UNSUCCESSFUL; + + if (This->Header.ClientAggregate) + { + /* using client aggregate */ + Status = This->Header.ClientAggregate->lpVtbl->QueryInterface(This->Header.ClientAggregate, refiid, Output); + + if (NT_SUCCESS(Status)) + { + /* client aggregate supports interface */ + return Status; + } + } + + DPRINT("IKsFilterFactory_fnQueryInterface no interface\n"); + return STATUS_NOT_SUPPORTED; } ULONG @@ -100,7 +115,7 @@ NTAPI IKsFilterFactory_fnAddRef( IKsFilterFactory * iface) { - IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl); + IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown); return InterlockedIncrement(&This->ref); } @@ -110,7 +125,7 @@ NTAPI IKsFilterFactory_fnRelease( IKsFilterFactory * iface) { - IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl); + IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown); InterlockedDecrement(&This->ref); @@ -136,7 +151,7 @@ NTAPI IKsFilterFactory_fnGetStruct( IKsFilterFactory * iface) { - IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl); + IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown); return &This->FilterFactory; } @@ -147,7 +162,7 @@ IKsFilterFactory_fnSetDeviceClassesState( IKsFilterFactory * iface, IN BOOLEAN Enable) { - IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl); + IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown); return KspSetDeviceInterfacesState(&This->SymbolicLinkList, Enable); } @@ -213,7 +228,7 @@ IKsFilterFactory_fnInitialize( BOOL FreeString = FALSE; IKsDevice * KsDevice; - IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl); + IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown); /* get device extension */ DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; @@ -306,7 +321,7 @@ IKsFilterFactory_fnInitialize( if (This->FilterFactory.Bag) { /* initialize object bag */ - KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice; + KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->BasicHeader.OuterUnknown; KsDevice->lpVtbl->InitializeObjectBag(KsDevice, (PKSIOBJECT_BAG)This->FilterFactory.Bag, NULL); } } @@ -357,10 +372,10 @@ KspCreateFilterFactory( /* initialize struct */ This->ref = 1; - This->lpVtbl = &vt_IKsFilterFactoryVtbl; + This->Header.OuterUnknown = (PUNKNOWN)&vt_IKsFilterFactoryVtbl; /* map to com object */ - Filter = (IKsFilterFactory*)&This->lpVtbl; + Filter = (IKsFilterFactory*)&This->Header.OuterUnknown; /* initialize filter */ Status = Filter->lpVtbl->Initialize(Filter, DeviceObject, Descriptor, RefString, SecurityDescriptor, CreateItemFlags, SleepCallback, WakeCallback, FilterFactory); @@ -412,7 +427,7 @@ KsFilterFactorySetDeviceClassesState( IKsFilterFactory * Factory; IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(FilterFactory, IKsFilterFactoryImpl, FilterFactory); - Factory = (IKsFilterFactory*)&This->lpVtbl; + Factory = (IKsFilterFactory*)&This->Header.OuterUnknown; return Factory->lpVtbl->SetDeviceClassesState(Factory, NewState); } diff --git a/reactos/drivers/ksfilter/ks/irp.c b/reactos/drivers/ksfilter/ks/irp.c index 332be5cc389..0c6036e2059 100644 --- a/reactos/drivers/ksfilter/ks/irp.c +++ b/reactos/drivers/ksfilter/ks/irp.c @@ -1360,7 +1360,7 @@ KsRemoveIrpFromCancelableQueue( PLIST_ENTRY CurEntry; KIRQL OldIrql; - DPRINT("KsRemoveIrpFromCancelableQueue ListHead %p SpinLock %p ListLocation %x RemovalOperation %x\n", QueueHead, SpinLock, ListLocation, RemovalOperation); + //DPRINT("KsRemoveIrpFromCancelableQueue ListHead %p SpinLock %p ListLocation %x RemovalOperation %x\n", QueueHead, SpinLock, ListLocation, RemovalOperation); /* check parameters */ if (!QueueHead || !SpinLock) @@ -1719,6 +1719,8 @@ FindMatchingCreateItem( { PLIST_ENTRY Entry; PCREATE_ITEM_ENTRY CreateItemEntry; + UNICODE_STRING RefString; + #ifndef MS_KSUSER /* remove '\' slash */ @@ -1726,6 +1728,16 @@ FindMatchingCreateItem( BufferSize -= sizeof(WCHAR); #endif + if (!wcschr(Buffer, L'\\')) + { + RtlInitUnicodeString(&RefString, Buffer); + } + else + { + RefString.Buffer = Buffer; + RefString.Length = RefString.MaximumLength = ((ULONG_PTR)wcschr(Buffer, L'\\') - (ULONG_PTR)Buffer); + } + /* point to first entry */ Entry = ListHead->Flink; @@ -1753,9 +1765,9 @@ FindMatchingCreateItem( ASSERT(CreateItemEntry->CreateItem->ObjectClass.Buffer); - DPRINT("CreateItem %S Length %u Request %S %u\n", CreateItemEntry->CreateItem->ObjectClass.Buffer, + DPRINT("CreateItem %S Length %u Request %wZ %u\n", CreateItemEntry->CreateItem->ObjectClass.Buffer, CreateItemEntry->CreateItem->ObjectClass.Length, - Buffer, + &RefString, BufferSize); if (CreateItemEntry->CreateItem->ObjectClass.Length > BufferSize) @@ -1766,7 +1778,7 @@ FindMatchingCreateItem( } /* now check if the object class is the same */ - if (RtlCompareMemory(CreateItemEntry->CreateItem->ObjectClass.Buffer, Buffer, CreateItemEntry->CreateItem->ObjectClass.Length) == CreateItemEntry->CreateItem->ObjectClass.Length) + if (!RtlCompareUnicodeString(&CreateItemEntry->CreateItem->ObjectClass, &RefString, TRUE)) { /* found matching create item */ *OutCreateItem = CreateItemEntry; @@ -1994,7 +2006,7 @@ KsDispatchIrp( PKSIDEVICE_HEADER DeviceHeader; PDEVICE_EXTENSION DeviceExtension; - DPRINT("KsDispatchIrp DeviceObject %p Irp %p\n", DeviceObject, Irp); + //DPRINT("KsDispatchIrp DeviceObject %p Irp %p\n", DeviceObject, Irp); /* get device extension */ DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; @@ -2010,7 +2022,7 @@ KsDispatchIrp( if (IoStack->MajorFunction == IRP_MJ_CREATE) { /* check internal type */ - if (DeviceHeader->lpVtblIKsDevice) /* FIXME improve check */ + if (DeviceHeader->BasicHeader.OuterUnknown) /* FIXME improve check */ { /* AVStream client */ return IKsDevice_Create(DeviceObject, Irp); @@ -2042,7 +2054,7 @@ KsDispatchIrp( if (IoStack->MajorFunction == IRP_MJ_POWER) { /* check internal type */ - if (DeviceHeader->lpVtblIKsDevice) /* FIXME improve check */ + if (DeviceHeader->BasicHeader.OuterUnknown) /* FIXME improve check */ { /* AVStream client */ return IKsDevice_Power(DeviceObject, Irp); @@ -2056,7 +2068,7 @@ KsDispatchIrp( else if (IoStack->MajorFunction == IRP_MJ_PNP) /* dispatch pnp */ { /* check internal type */ - if (DeviceHeader->lpVtblIKsDevice) /* FIXME improve check */ + if (DeviceHeader->BasicHeader.OuterUnknown) /* FIXME improve check */ { /* AVStream client */ return IKsDevice_Pnp(DeviceObject, Irp); diff --git a/reactos/drivers/ksfilter/ks/ksfunc.h b/reactos/drivers/ksfilter/ks/ksfunc.h index 75d73ea4aab..636c616bcb2 100644 --- a/reactos/drivers/ksfilter/ks/ksfunc.h +++ b/reactos/drivers/ksfilter/ks/ksfunc.h @@ -84,19 +84,17 @@ VOID FreeItem( IN PVOID Item); -NTSTATUS -NTAPI -KspTopologyPropertyHandler( - IN PIRP Irp, - IN PKSIDENTIFIER Request, - IN OUT PVOID Data); - +KSDDKAPI NTSTATUS NTAPI KspPinPropertyHandler( - IN PIRP Irp, - IN PKSIDENTIFIER Request, - IN OUT PVOID Data); + IN PIRP Irp, + IN PKSPROPERTY Property, + IN OUT PVOID Data, + IN ULONG DescriptorsCount, + IN const KSPIN_DESCRIPTOR* Descriptors, + IN ULONG DescriptorSize); + NTSTATUS FindMatchingCreateItem( @@ -181,3 +179,10 @@ KspEnableEvent( IN PFNKSALLOCATOR Allocator OPTIONAL, IN ULONG EventItemSize OPTIONAL); +NTSTATUS +KspValidateConnectRequest( + IN PIRP Irp, + IN ULONG DescriptorsCount, + IN PVOID Descriptors, + IN ULONG DescriptorSize, + OUT PKSPIN_CONNECT* Connect); diff --git a/reactos/drivers/ksfilter/ks/ksiface.h b/reactos/drivers/ksfilter/ks/ksiface.h index 0977886beaf..ad95fc9a922 100644 --- a/reactos/drivers/ksfilter/ks/ksiface.h +++ b/reactos/drivers/ksfilter/ks/ksiface.h @@ -283,8 +283,8 @@ DECLARE_INTERFACE_(IKsDevice, IUnknown) STDMETHOD_(NTSTATUS, GetAdapterObject)(THIS_ IN PADAPTER_OBJECT * Object, - IN PULONG Unknown1, - IN PULONG Unknown2) PURE; + IN PULONG MaxMappingsByteCount, + IN PULONG MappingTableStride) PURE; STDMETHOD_(NTSTATUS, AddPowerEntry)(THIS_ IN struct KSPOWER_ENTRY * Entry, diff --git a/reactos/drivers/ksfilter/ks/kstypes.h b/reactos/drivers/ksfilter/ks/kstypes.h index 51b365aaaad..0e64312e095 100644 --- a/reactos/drivers/ksfilter/ks/kstypes.h +++ b/reactos/drivers/ksfilter/ks/kstypes.h @@ -61,6 +61,8 @@ typedef struct PRKMUTEX ControlMutex; LIST_ENTRY EventList; KSPIN_LOCK EventListLock; + PUNKNOWN ClientAggregate; + PUNKNOWN OuterUnknown; union { PKSDEVICE KsDevice; @@ -87,7 +89,6 @@ typedef struct { KSBASIC_HEADER BasicHeader; KSDEVICE KsDevice; - IKsDeviceVtbl *lpVtblIKsDevice; LONG ref; ERESOURCE SecurityLock; @@ -109,6 +110,8 @@ typedef struct LIST_ENTRY ObjectBags; PADAPTER_OBJECT AdapterObject; + ULONG MaxMappingsByteCount; + ULONG MappingTableStride; }KSIDEVICE_HEADER, *PKSIDEVICE_HEADER; diff --git a/reactos/drivers/ksfilter/ks/misc.c b/reactos/drivers/ksfilter/ks/misc.c index cc3d2cc9cca..dc814eae01e 100644 --- a/reactos/drivers/ksfilter/ks/misc.c +++ b/reactos/drivers/ksfilter/ks/misc.c @@ -175,16 +175,21 @@ KsGetObjectTypeFromIrp( } /* - @unimplemented + @implemented */ PUNKNOWN NTAPI KsGetOuterUnknown( IN PVOID Object) { - UNIMPLEMENTED - return NULL; + PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER)); + /* sanity check */ + ASSERT(BasicHeader->Type == KsObjectTypeDevice || BasicHeader->Type == KsObjectTypeFilterFactory || + BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin); + + /* return objects outer unknown */ + return BasicHeader->OuterUnknown; } /* diff --git a/reactos/drivers/ksfilter/ks/pin.c b/reactos/drivers/ksfilter/ks/pin.c index aa39c8deae1..019e5ce6023 100644 --- a/reactos/drivers/ksfilter/ks/pin.c +++ b/reactos/drivers/ksfilter/ks/pin.c @@ -32,7 +32,6 @@ typedef struct KSPROCESSPIN ProcessPin; LIST_ENTRY Entry; - IKsPinVtbl *lpVtbl; LONG ref; IKsFilter * Filter; @@ -296,7 +295,7 @@ IKsPin_PinStatePropertyHandler( /* set new state */ This->Pin.ClientState = *NewState; - This->Pin.DeviceState = *NewState; + This->Pin.DeviceState = KSSTATE_RUN; /* check if it supported */ Status = This->Pin.Descriptor->Dispatch->SetDeviceState(&This->Pin, *NewState, OldState); @@ -339,8 +338,67 @@ IKsPin_PinAllocatorFramingPropertyHandler( IN PKSIDENTIFIER Request, IN OUT PVOID Data) { - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; + PIO_STACK_LOCATION IoStack; + PKSIOBJECT_HEADER ObjectHeader; + IKsPinImpl * This; + ULONG Size; + NTSTATUS Status = STATUS_SUCCESS; + + /* get current irp stack */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* sanity check */ + ASSERT(IoStack->FileObject); + ASSERT(IoStack->FileObject->FsContext2); + + /* get the object header */ + ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2; + + /* locate ks pin implemention from KSPIN offset */ + This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin); + + /* setting allocator flags is not supported */ + ASSERT(!(Request->Flags & KSPROPERTY_TYPE_SET)); + + /* acquire control mutex */ + KeWaitForSingleObject(This->BasicHeader.ControlMutex, Executive, KernelMode, FALSE, NULL); + + if (This->Pin.Descriptor->AllocatorFraming) + { + /* calculate size */ + Size = FIELD_OFFSET(KSALLOCATOR_FRAMING_EX, FramingItem[0]) + This->Pin.Descriptor->AllocatorFraming->CountItems * sizeof(KS_FRAMING_ITEM); + + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == 0) + { + /* no buffer */ + Status = STATUS_BUFFER_OVERFLOW; + } + else if (Size > IoStack->Parameters.DeviceIoControl.OutputBufferLength) + { + /* buffer too small */ + Status = STATUS_BUFFER_TOO_SMALL; + } + else + { + /* copy buffer */ + RtlMoveMemory(Data, This->Pin.Descriptor->AllocatorFraming, Size); + } + + /* store size */ + Irp->IoStatus.Information = Size; + } + else + { + /* no allocator framing details */ + Status = STATUS_NOT_FOUND; + } + + /* release processing mutex */ + KeReleaseMutex(This->BasicHeader.ControlMutex, FALSE); + + DPRINT("IKsPin_PinAllocatorFramingPropertyHandler Status %lx\n", Status); + + return Status; } NTSTATUS @@ -423,17 +481,31 @@ IKsPin_fnQueryInterface( IN REFIID refiid, OUT PVOID* Output) { - IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtbl); + NTSTATUS Status; + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, BasicHeader.OuterUnknown); if (IsEqualGUIDAligned(refiid, &IID_IUnknown)) { - *Output = &This->lpVtbl; + *Output = &This->BasicHeader.OuterUnknown; _InterlockedIncrement(&This->ref); return STATUS_SUCCESS; } -DPRINT("IKsPin_fnQueryInterface\n"); - DbgBreakPoint(); - return STATUS_UNSUCCESSFUL; + + + if (This->BasicHeader.ClientAggregate) + { + /* using client aggregate */ + Status = This->BasicHeader.ClientAggregate->lpVtbl->QueryInterface(This->BasicHeader.ClientAggregate, refiid, Output); + + if (NT_SUCCESS(Status)) + { + /* client aggregate supports interface */ + return Status; + } + } + + DPRINT("IKsPin_fnQueryInterface no interface\n"); + return STATUS_NOT_SUPPORTED; } ULONG @@ -441,7 +513,7 @@ NTAPI IKsPin_fnAddRef( IKsPin * iface) { - IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtbl); + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, BasicHeader.OuterUnknown); return InterlockedIncrement(&This->ref); } @@ -451,7 +523,7 @@ NTAPI IKsPin_fnRelease( IKsPin * iface) { - IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtbl); + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, BasicHeader.OuterUnknown); InterlockedDecrement(&This->ref); @@ -645,7 +717,7 @@ IKsReferenceClock_fnQueryInterface( { IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); - return IKsPin_fnQueryInterface((IKsPin*)&This->lpVtbl, refiid, Output); + return IKsPin_fnQueryInterface((IKsPin*)&This->BasicHeader.OuterUnknown, refiid, Output); } ULONG @@ -655,7 +727,7 @@ IKsReferenceClock_fnAddRef( { IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); - return IKsPin_fnAddRef((IKsPin*)&This->lpVtbl); + return IKsPin_fnAddRef((IKsPin*)&This->BasicHeader.OuterUnknown); } ULONG @@ -665,7 +737,7 @@ IKsReferenceClock_fnRelease( { IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); - return IKsPin_fnRelease((IKsPin*)&This->lpVtbl); + return IKsPin_fnRelease((IKsPin*)&This->BasicHeader.OuterUnknown); } LONGLONG @@ -1032,7 +1104,7 @@ KsPinGetParentFilter( */ NTSTATUS NTAPI - KsPinGetReferenceClockInterface( +KsPinGetReferenceClockInterface( IN PKSPIN Pin, OUT PIKSREFERENCECLOCK* Interface) { @@ -1045,12 +1117,8 @@ NTAPI *Interface = (PIKSREFERENCECLOCK)&This->lpVtblReferenceClock; Status = STATUS_SUCCESS; } -//HACK - *Interface = (PIKSREFERENCECLOCK)&This->lpVtblReferenceClock; - Status = STATUS_SUCCESS; DPRINT("KsPinGetReferenceClockInterface Pin %p Interface %p Status %x\n", Pin, Interface, Status); - return Status; } @@ -1937,6 +2005,13 @@ IKsPin_DispatchDeviceIoControl( /* current irp stack */ IoStack = IoGetCurrentIrpStackLocation(Irp); + if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_READ_STREAM || + IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM) + { + /* handle ks stream packets */ + return IKsPin_DispatchKsStream(DeviceObject, Irp, This); + } + /* get property from input buffer */ Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; @@ -2227,10 +2302,10 @@ KspCreatePin( //Output Pin: KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY //Input Pin: KSPIN_FLAG_FIXED_FORMAT|KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT|KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING - + DPRINT("KspCreatePin Dataflow %lu\n", Descriptor->PinDescriptor.DataFlow); + DPRINT("KspCreatePin Communication %lu\n", Descriptor->PinDescriptor.Communication); if (Descriptor->AllocatorFraming) { - DPRINT("KspCreatePin Dataflow %lu\n", Descriptor->PinDescriptor.DataFlow); DPRINT("KspCreatePin CountItems %lu\n", Descriptor->AllocatorFraming->CountItems); DPRINT("KspCreatePin PinFlags %lx\n", Descriptor->AllocatorFraming->PinFlags); DPRINT("KspCreatePin OutputCompression RatioNumerator %lu RatioDenominator %lu RatioConstantMargin %lu\n", Descriptor->AllocatorFraming->OutputCompression.RatioNumerator, @@ -2262,6 +2337,27 @@ KspCreatePin( } } + for (Index = 0; Index < Descriptor->PinDescriptor.DataRangesCount; Index++) + { + UNICODE_STRING GuidString; + /* convert the guid to string */ + RtlStringFromGUID(&Descriptor->PinDescriptor.DataRanges[Index]->MajorFormat, &GuidString); + DPRINT("Index %lu MajorFormat %S\n", Index, GuidString.Buffer); + RtlStringFromGUID(&Descriptor->PinDescriptor.DataRanges[Index]->SubFormat, &GuidString); + DPRINT("Index %lu SubFormat %S\n", Index, GuidString.Buffer); + RtlStringFromGUID(&Descriptor->PinDescriptor.DataRanges[Index]->Specifier, &GuidString); + DPRINT("Index %lu Specifier %S\n", Index, GuidString.Buffer); + RtlStringFromGUID(&Descriptor->PinDescriptor.DataRanges[Index]->Specifier, &GuidString); + DPRINT("Index %lu FormatSize %lu Flags %lu SampleSize %lu Reserved %lu KSDATAFORMAT %lu\n", Index, + Descriptor->PinDescriptor.DataRanges[Index]->FormatSize, Descriptor->PinDescriptor.DataRanges[Index]->Flags, Descriptor->PinDescriptor.DataRanges[Index]->SampleSize, Descriptor->PinDescriptor.DataRanges[Index]->Reserved, sizeof(KSDATAFORMAT)); + + if (IsEqualGUIDAligned(&Descriptor->PinDescriptor.DataRanges[Index]->SubFormat, &KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT)) + { + PKS_DATARANGE_BDA_TRANSPORT Transport = (PKS_DATARANGE_BDA_TRANSPORT)&Descriptor->PinDescriptor.DataRanges[Index]; + DPRINT("KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT AvgTimePerFrame %I64u ulcbPhyiscalFrame %lu ulcbPhyiscalFrameAlignment %lu ulcbPhyiscalPacket %lu\n", Transport->BdaTransportInfo.AvgTimePerFrame, Transport->BdaTransportInfo.ulcbPhyiscalFrame, + Transport->BdaTransportInfo.ulcbPhyiscalFrameAlignment, Transport->BdaTransportInfo.ulcbPhyiscalPacket); + } + } if (!FrameSize) { /* default to 50 * 188 (MPEG2 TS packet size) */ @@ -2280,7 +2376,7 @@ KspCreatePin( DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; /* get ks device interface */ - Device = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice; + Device = (IKsDevice*)&DeviceExtension->DeviceHeader->BasicHeader.OuterUnknown; /* first allocate pin ctx */ This = AllocateItem(NonPagedPool, sizeof(IKsPinImpl)); @@ -2304,6 +2400,7 @@ KspCreatePin( This->BasicHeader.KsDevice = KsDevice; This->BasicHeader.Type = KsObjectTypePin; This->BasicHeader.Parent.KsFilter = Filter->lpVtbl->GetStruct(Filter); + This->BasicHeader.OuterUnknown = (PUNKNOWN)&vt_IKsPin; InitializeListHead(&This->BasicHeader.EventList); KeInitializeSpinLock(&This->BasicHeader.EventListLock); @@ -2318,7 +2415,6 @@ KspCreatePin( KeInitializeSpinLock(&This->BasicHeader.EventListLock); /* initialize pin */ - This->lpVtbl = &vt_IKsPin; This->FrameSize = FrameSize; This->NumFrames = NumFrames; This->lpVtblReferenceClock = &vt_ReferenceClock; @@ -2442,7 +2538,7 @@ KspCreatePin( /* add extra info to object header */ This->ObjectHeader->Type = KsObjectTypePin; - This->ObjectHeader->Unknown = (PUNKNOWN)&This->lpVtbl; + This->ObjectHeader->Unknown = (PUNKNOWN)&This->BasicHeader.OuterUnknown; This->ObjectHeader->ObjectType = (PVOID)&This->Pin; if (!Descriptor->Dispatch || !Descriptor->Dispatch->Process) @@ -2524,7 +2620,7 @@ KspCreatePin( } - DPRINT("KspCreatePin Status %lx\n", Status); + DPRINT("KspCreatePin Status %lx KsDevice %p\n", Status, KsDevice); if (!NT_SUCCESS(Status) && Status != STATUS_PENDING) { diff --git a/reactos/drivers/ksfilter/ks/priv.h b/reactos/drivers/ksfilter/ks/priv.h index ec5976be238..75b514158cc 100644 --- a/reactos/drivers/ksfilter/ks/priv.h +++ b/reactos/drivers/ksfilter/ks/priv.h @@ -18,6 +18,7 @@ #include "ksiface.h" #include "ksmedia.h" +#include "bdamedia.h" #define TAG_DEVICE_HEADER 'KSDH' #define REG_PINFLAG_B_MANY 0x4 /* strmif.h */ @@ -45,7 +46,7 @@ DEFINE_KSPROPERTY_TABLE(PinSet) {\ DEFINE_KSPROPERTY_TABLE(PinSet) {\ DEFINE_KSPROPERTY_ITEM_CONNECTION_STATE(PropStateHandler, PropStateHandler),\ DEFINE_KSPROPERTY_ITEM_CONNECTION_DATAFORMAT(PropDataFormatHandler, PropDataFormatHandler),\ - DEFINE_KSPROPERTY_ITEM_CONNECTION_ALLOCATORFRAMING(PropAllocatorFraming)\ + DEFINE_KSPROPERTY_ITEM_CONNECTION_ALLOCATORFRAMING_EX(PropAllocatorFraming)\ }