+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS Kernel Streaming
- * FILE: drivers/ksfilter/ks/filter.c
- * PURPOSE: KS IKsFilter interface functions
- * PROGRAMMER: Johannes Anderwald
- */
-
-
-#include "priv.h"
-
-typedef struct
-{
- KSBASIC_HEADER Header;
- KSFILTER Filter;
-
- IKsControlVtbl *lpVtblKsControl;
- IKsFilterFactory * FilterFactory;
- LONG ref;
-
- PKSIOBJECT_HEADER ObjectHeader;
- KSTOPOLOGY Topology;
- PKSFILTERFACTORY Factory;
- PFILE_OBJECT FileObject;
- KMUTEX ControlMutex;
- KMUTEX ProcessingMutex;
-
-
- PFNKSFILTERPOWER Sleep;
- PFNKSFILTERPOWER Wake;
-
- ULONG *PinInstanceCount;
- PKSPIN * FirstPin;
- PKSPROCESSPIN_INDEXENTRY ProcessPinIndex;
-
-}IKsFilterImpl;
-
-const GUID IID_IKsControl = {0x28F54685L, 0x06FD, 0x11D2, {0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
-const GUID IID_IKsFilter = {0x3ef6ee44L, 0x0D41, 0x11d2, {0xbe, 0xDA, 0x00, 0xc0, 0x4f, 0x8e, 0xF4, 0x57}};
-const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
-const GUID KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
-
-VOID
-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, FilterTopologyPropertyHandler);
-DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet, FilterPinPropertyHandler, FilterPinPropertyHandler, FilterPinPropertyHandler);
-
-KSPROPERTY_SET FilterPropertySet[] =
-{
- {
- &KSPROPSETID_Topology,
- sizeof(IKsFilterTopologySet) / sizeof(KSPROPERTY_ITEM),
- (const KSPROPERTY_ITEM*)&IKsFilterTopologySet,
- 0,
- NULL
- },
- {
- &KSPROPSETID_Pin,
- sizeof(IKsFilterPinSet) / sizeof(KSPROPERTY_ITEM),
- (const KSPROPERTY_ITEM*)&IKsFilterPinSet,
- 0,
- NULL
- }
-};
-
-NTSTATUS
-NTAPI
-IKsControl_fnQueryInterface(
- IKsControl * iface,
- IN REFIID refiid,
- OUT PVOID* Output)
-{
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl);
-
- if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
- {
- *Output = &This->Header.OuterUnknown;
- _InterlockedIncrement(&This->ref);
- return STATUS_SUCCESS;
- }
- return STATUS_UNSUCCESSFUL;
-}
-
-ULONG
-NTAPI
-IKsControl_fnAddRef(
- IKsControl * iface)
-{
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl);
-
- return InterlockedIncrement(&This->ref);
-}
-
-ULONG
-NTAPI
-IKsControl_fnRelease(
- IKsControl * iface)
-{
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl);
-
- InterlockedDecrement(&This->ref);
-
- /* Return new reference count */
- return This->ref;
-}
-
-NTSTATUS
-NTAPI
-IKsControl_fnKsProperty(
- IKsControl * iface,
- IN PKSPROPERTY Property,
- IN ULONG PropertyLength,
- IN OUT PVOID PropertyData,
- IN ULONG DataLength,
- OUT ULONG* BytesReturned)
-{
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl);
-
- return KsSynchronousIoControlDevice(This->FileObject, KernelMode, IOCTL_KS_PROPERTY, Property, PropertyLength, PropertyData, DataLength, BytesReturned);
-}
-
-
-NTSTATUS
-NTAPI
-IKsControl_fnKsMethod(
- IKsControl * iface,
- IN PKSMETHOD Method,
- IN ULONG MethodLength,
- IN OUT PVOID MethodData,
- IN ULONG DataLength,
- OUT ULONG* BytesReturned)
-{
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl);
-
- return KsSynchronousIoControlDevice(This->FileObject, KernelMode, IOCTL_KS_METHOD, Method, MethodLength, MethodData, DataLength, BytesReturned);
-}
-
-
-NTSTATUS
-NTAPI
-IKsControl_fnKsEvent(
- IKsControl * iface,
- IN PKSEVENT Event OPTIONAL,
- IN ULONG EventLength,
- IN OUT PVOID EventData,
- IN ULONG DataLength,
- OUT ULONG* BytesReturned)
-{
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl);
-
- if (Event)
- {
- return KsSynchronousIoControlDevice(This->FileObject, KernelMode, IOCTL_KS_ENABLE_EVENT, Event, EventLength, EventData, DataLength, BytesReturned);
- }
- else
- {
- return KsSynchronousIoControlDevice(This->FileObject, KernelMode, IOCTL_KS_DISABLE_EVENT, EventData, DataLength, NULL, 0, BytesReturned);
- }
-
-}
-
-static IKsControlVtbl vt_IKsControl =
-{
- IKsControl_fnQueryInterface,
- IKsControl_fnAddRef,
- IKsControl_fnRelease,
- IKsControl_fnKsProperty,
- IKsControl_fnKsMethod,
- IKsControl_fnKsEvent
-};
-
-
-NTSTATUS
-NTAPI
-IKsFilter_fnQueryInterface(
- IKsFilter * iface,
- IN REFIID refiid,
- OUT PVOID* Output)
-{
- NTSTATUS Status;
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
-
- if (IsEqualGUIDAligned(refiid, &IID_IUnknown) ||
- IsEqualGUIDAligned(refiid, &IID_IKsFilter))
- {
- *Output = &This->Header.OuterUnknown;
- _InterlockedIncrement(&This->ref);
- return STATUS_SUCCESS;
- }
- else if (IsEqualGUIDAligned(refiid, &IID_IKsControl))
- {
- *Output = &This->lpVtblKsControl;
- _InterlockedIncrement(&This->ref);
- return STATUS_SUCCESS;
- }
-
- 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
-NTAPI
-IKsFilter_fnAddRef(
- IKsFilter * iface)
-{
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
-
- return InterlockedIncrement(&This->ref);
-}
-
-ULONG
-NTAPI
-IKsFilter_fnRelease(
- IKsFilter * iface)
-{
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
-
- InterlockedDecrement(&This->ref);
-
- if (This->ref == 0)
- {
- FreeItem(This);
- return 0;
- }
- /* Return new reference count */
- return This->ref;
-
-}
-
-PKSFILTER
-NTAPI
-IKsFilter_fnGetStruct(
- IKsFilter * iface)
-{
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
-
- return &This->Filter;
-}
-
-BOOL
-NTAPI
-IKsFilter_fnDoAllNecessaryPinsExist(
- IKsFilter * iface)
-{
- UNIMPLEMENTED
- return FALSE;
-}
-
-NTSTATUS
-NTAPI
-IKsFilter_fnCreateNode(
- IKsFilter * iface,
- IN PIRP Irp,
- IN IKsPin * Pin,
- IN PLIST_ENTRY ListEntry)
-{
- UNIMPLEMENTED
- return STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS
-NTAPI
-IKsFilter_fnBindProcessPinsToPipeSection(
- IKsFilter * iface,
- IN struct KSPROCESSPIPESECTION *Section,
- IN PVOID Create,
- IN PKSPIN KsPin,
- OUT IKsPin **Pin,
- OUT PKSGATE *OutGate)
-{
- UNIMPLEMENTED
- return STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS
-NTAPI
-IKsFilter_fnUnbindProcessPinsFromPipeSection(
- IKsFilter * iface,
- IN struct KSPROCESSPIPESECTION *Section)
-{
- UNIMPLEMENTED
- return STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS
-NTAPI
-IKsFilter_fnAddProcessPin(
- IKsFilter * iface,
- IN PKSPROCESSPIN ProcessPin)
-{
- NTSTATUS Status;
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
-
- /* first acquire processing mutex */
- KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL);
-
- /* sanity check */
- 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->Filter.Descriptor->PinDescriptorsCount + 1) * sizeof(PKSPROCESSPIN),
- This->Filter.Descriptor->PinDescriptorsCount * sizeof(PKSPROCESSPIN),
- 0);
-
- if (NT_SUCCESS(Status))
- {
- /* store process pin */
- This->ProcessPinIndex[ProcessPin->Pin->Id].Pins[This->ProcessPinIndex[ProcessPin->Pin->Id].Count] = ProcessPin;
- This->ProcessPinIndex[ProcessPin->Pin->Id].Count++;
- }
-
- /* release process mutex */
- KeReleaseMutex(&This->ProcessingMutex, FALSE);
-
- return Status;
-}
-
-NTSTATUS
-NTAPI
-IKsFilter_fnRemoveProcessPin(
- IKsFilter * iface,
- IN PKSPROCESSPIN ProcessPin)
-{
- ULONG Index;
- ULONG Count;
- PKSPROCESSPIN * Pins;
-
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
-
- /* first acquire processing mutex */
- KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL);
-
- /* sanity check */
- ASSERT(ProcessPin->Pin);
- ASSERT(ProcessPin->Pin->Id);
-
- Count = This->ProcessPinIndex[ProcessPin->Pin->Id].Count;
- Pins = This->ProcessPinIndex[ProcessPin->Pin->Id].Pins;
-
- /* search for current process pin */
- for(Index = 0; Index < Count; Index++)
- {
- if (Pins[Index] == ProcessPin)
- {
- RtlMoveMemory(&Pins[Index], &Pins[Index + 1], (Count - (Index + 1)) * sizeof(PKSPROCESSPIN));
- break;
- }
-
- }
-
- /* decrement pin count */
- This->ProcessPinIndex[ProcessPin->Pin->Id].Count--;
-
- if (!This->ProcessPinIndex[ProcessPin->Pin->Id].Count)
- {
- /* clear entry object bag will delete it */
- This->ProcessPinIndex[ProcessPin->Pin->Id].Pins = NULL;
- }
-
- /* release process mutex */
- KeReleaseMutex(&This->ProcessingMutex, FALSE);
-
- /* done */
- return STATUS_SUCCESS;
-}
-
-BOOL
-NTAPI
-IKsFilter_fnReprepareProcessPipeSection(
- IKsFilter * iface,
- IN struct KSPROCESSPIPESECTION *PipeSection,
- IN PULONG Data)
-{
- UNIMPLEMENTED
- return FALSE;
-}
-
-VOID
-NTAPI
-IKsFilter_fnDeliverResetState(
- IKsFilter * iface,
- IN struct KSPROCESSPIPESECTION *PipeSection,
- IN KSRESET ResetState)
-{
- UNIMPLEMENTED
-}
-
-BOOL
-NTAPI
-IKsFilter_fnIsFrameHolding(
- IKsFilter * iface)
-{
- UNIMPLEMENTED
- return FALSE;
-}
-
-VOID
-NTAPI
-IKsFilter_fnRegisterForCopyCallbacks(
- IKsFilter * iface,
- IKsQueue *Queue,
- BOOL Register)
-{
- UNIMPLEMENTED
-}
-
-PKSPROCESSPIN_INDEXENTRY
-NTAPI
-IKsFilter_fnGetProcessDispatch(
- IKsFilter * iface)
-{
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
-
- return This->ProcessPinIndex;
-}
-
-static IKsFilterVtbl vt_IKsFilter =
-{
- IKsFilter_fnQueryInterface,
- IKsFilter_fnAddRef,
- IKsFilter_fnRelease,
- IKsFilter_fnGetStruct,
- IKsFilter_fnDoAllNecessaryPinsExist,
- IKsFilter_fnCreateNode,
- IKsFilter_fnBindProcessPinsToPipeSection,
- IKsFilter_fnUnbindProcessPinsFromPipeSection,
- IKsFilter_fnAddProcessPin,
- IKsFilter_fnRemoveProcessPin,
- IKsFilter_fnReprepareProcessPipeSection,
- IKsFilter_fnDeliverResetState,
- IKsFilter_fnIsFrameHolding,
- IKsFilter_fnRegisterForCopyCallbacks,
- IKsFilter_fnGetProcessDispatch
-};
-
-NTSTATUS
-IKsFilter_GetFilterFromIrp(
- IN PIRP Irp,
- OUT IKsFilter **Filter)
-{
- PIO_STACK_LOCATION IoStack;
- PKSIOBJECT_HEADER ObjectHeader;
- NTSTATUS Status;
-
- /* get current irp stack */
- IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- /* santiy check */
- ASSERT(IoStack->FileObject != NULL);
-
- ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
-
- /* sanity is important */
- ASSERT(ObjectHeader != NULL);
- ASSERT(ObjectHeader->Type == KsObjectTypeFilter);
- ASSERT(ObjectHeader->Unknown != NULL);
-
- /* get our private interface */
- Status = ObjectHeader->Unknown->lpVtbl->QueryInterface(ObjectHeader->Unknown, &IID_IKsFilter, (PVOID*)Filter);
-
- if (!NT_SUCCESS(Status))
- {
- /* something is wrong here */
- DPRINT1("KS: Misbehaving filter %p\n", ObjectHeader->Unknown);
- Irp->IoStatus.Status = Status;
-
- /* complete and forget irp */
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
- }
- return Status;
-}
-
-
-NTSTATUS
-NTAPI
-IKsFilter_DispatchClose(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- IKsFilter * Filter;
- IKsFilterImpl * This;
- NTSTATUS Status;
-
- /* obtain filter from object header */
- Status = IKsFilter_GetFilterFromIrp(Irp, &Filter);
- if (!NT_SUCCESS(Status))
- return Status;
-
- /* get our real implementation */
- This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Header.OuterUnknown);
-
- /* does the driver support notifications */
- if (This->Filter.Descriptor && This->Filter.Descriptor->Dispatch && This->Filter.Descriptor->Dispatch->Close)
- {
- /* call driver's filter close function */
- Status = This->Filter.Descriptor->Dispatch->Close(&This->Filter, Irp);
- }
-
- if (NT_SUCCESS(Status) && Status != STATUS_PENDING)
- {
- /* save the result */
- Irp->IoStatus.Status = Status;
- /* complete irp */
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- /* remove our instance from the filter factory */
- IKsFilter_RemoveFilterFromFilterFactory(This, This->Factory);
-
- /* free object header */
- KsFreeObjectHeader(This->ObjectHeader);
- }
- else
- {
- /* complete and forget */
- Irp->IoStatus.Status = Status;
- /* complete irp */
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- }
-
- /* done */
- return Status;
-}
-
-NTSTATUS
-KspHandlePropertyInstances(
- IN PIO_STATUS_BLOCK IoStatus,
- IN PKSIDENTIFIER Request,
- IN OUT PVOID Data,
- IN IKsFilterImpl * This,
- IN BOOL Global)
-{
- KSPIN_CINSTANCES * Instances;
- KSP_PIN * Pin = (KSP_PIN*)Request;
-
- if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount)
- {
- /* no filter / pin descriptor */
- IoStatus->Status = STATUS_NOT_IMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
- }
-
- /* ignore custom structs for now */
- 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->Filter.Descriptor->PinDescriptors[Pin->PinId].InstancesPossible;
- /* current instance count */
- Instances->CurrentCount = This->PinInstanceCount[Pin->PinId];
-
- IoStatus->Information = sizeof(KSPIN_CINSTANCES);
- IoStatus->Status = STATUS_SUCCESS;
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-KspHandleNecessaryPropertyInstances(
- IN PIO_STATUS_BLOCK IoStatus,
- IN PKSIDENTIFIER Request,
- IN OUT PVOID Data,
- IN IKsFilterImpl * This)
-{
- PULONG Result;
- KSP_PIN * Pin = (KSP_PIN*)Request;
-
- if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount)
- {
- /* no filter / pin descriptor */
- IoStatus->Status = STATUS_NOT_IMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
- }
-
- /* ignore custom structs for now */
- ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
- ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId);
-
- Result = (PULONG)Data;
- *Result = This->Filter.Descriptor->PinDescriptors[Pin->PinId].InstancesNecessary;
-
- IoStatus->Information = sizeof(ULONG);
- IoStatus->Status = STATUS_SUCCESS;
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-KspHandleDataIntersection(
- IN PIRP Irp,
- IN PIO_STATUS_BLOCK IoStatus,
- IN PKSIDENTIFIER Request,
- IN OUT PVOID Data,
- IN ULONG DataLength,
- IN IKsFilterImpl * This)
-{
- PKSMULTIPLE_ITEM MultipleItem;
- 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);
-
- /* FIXME make sure its 64 bit aligned */
- ASSERT(((ULONG_PTR)DataRange & 0x7) == 0);
-
- if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount)
- {
- /* no filter / pin descriptor */
- IoStatus->Status = STATUS_NOT_IMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
- }
-
- /* ignore custom structs for now */
- ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
- ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId);
-
- 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;
- return STATUS_NOT_IMPLEMENTED;
- }
-
- 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("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->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;
- break;
- }
-
- DataRange = UlongToPtr(PtrToUlong(DataRange) + DataRange->FormatSize);
- /* FIXME make sure its 64 bit aligned */
- ASSERT(((ULONG_PTR)DataRange & 0x7) == 0);
- }
- IoStatus->Status = Status;
- return Status;
-}
-
-NTSTATUS
-NTAPI
-FilterTopologyPropertyHandler(
- 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
-FilterPinPropertyHandler(
- IN PIRP Irp,
- IN PKSIDENTIFIER Request,
- IN OUT PVOID Data)
-{
- PIO_STACK_LOCATION IoStack;
- IKsFilterImpl * This;
- NTSTATUS Status = STATUS_UNSUCCESSFUL;
-
- /* get filter implementation */
- This = (IKsFilterImpl*)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
-
- /* sanity check */
- ASSERT(This);
-
- /* get current stack location */
- IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- switch(Request->Id)
- {
- case KSPROPERTY_PIN_CTYPES:
- case KSPROPERTY_PIN_DATAFLOW:
- case KSPROPERTY_PIN_DATARANGES:
- case KSPROPERTY_PIN_INTERFACES:
- case KSPROPERTY_PIN_MEDIUMS:
- case KSPROPERTY_PIN_COMMUNICATION:
- case KSPROPERTY_PIN_CATEGORY:
- case KSPROPERTY_PIN_NAME:
- case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
- 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);
- break;
- case KSPROPERTY_PIN_CINSTANCES:
- Status = KspHandlePropertyInstances(&Irp->IoStatus, Request, Data, This, FALSE);
- break;
- case KSPROPERTY_PIN_NECESSARYINSTANCES:
- Status = KspHandleNecessaryPropertyInstances(&Irp->IoStatus, Request, Data, This);
- break;
-
- case KSPROPERTY_PIN_DATAINTERSECTION:
- Status = KspHandleDataIntersection(Irp, &Irp->IoStatus, Request, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength, This);
- break;
- default:
- UNIMPLEMENTED
- Status = STATUS_NOT_FOUND;
- }
- //DPRINT("KspPinPropertyHandler Pins %lu Request->Id %lu Status %lx\n", This->PinDescriptorCount, Request->Id, Status);
-
-
- return Status;
-}
-
-NTSTATUS
-NTAPI
-IKsFilter_DispatchDeviceIoControl(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- PIO_STACK_LOCATION IoStack;
- IKsFilter * Filter;
- IKsFilterImpl * This;
- NTSTATUS Status;
- PKSFILTER FilterInstance;
- UNICODE_STRING GuidString;
- PKSPROPERTY Property;
- ULONG SetCount = 0;
-
- /* obtain filter from object header */
- Status = IKsFilter_GetFilterFromIrp(Irp, &Filter);
- if (!NT_SUCCESS(Status))
- return Status;
-
- /* get our real implementation */
- This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Header.OuterUnknown);
-
- /* current irp stack */
- IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- /* get property from input buffer */
- Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
-
- /* 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);
-
- /* acquire control mutex */
- KeWaitForSingleObject(This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL);
-
- 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->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->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);
-
- if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT)
- {
- /* call enable event handlers */
- Status = KspEnableEvent(Irp,
- FilterInstance->Descriptor->AutomationTable->EventSetsCount,
- (PKSEVENT_SET)FilterInstance->Descriptor->AutomationTable->EventSets,
- &This->Header.EventList,
- KSEVENTS_SPINLOCK,
- (PVOID)&This->Header.EventListLock,
- NULL,
- FilterInstance->Descriptor->AutomationTable->EventItemSize);
- }
- else
- {
- /* disable event handler */
- Status = KsDisableEvent(Irp, &This->Header.EventList, KSEVENTS_SPINLOCK, &This->Header.EventListLock);
- }
- }
-
- 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);
-
- /* release control mutex */
- KeReleaseMutex(This->Header.ControlMutex, FALSE);
-
- if (Status != STATUS_PENDING)
- {
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- }
-
- /* done */
- return Status;
-}
-
-static KSDISPATCH_TABLE DispatchTable =
-{
- IKsFilter_DispatchDeviceIoControl,
- KsDispatchInvalidDeviceRequest,
- KsDispatchInvalidDeviceRequest,
- KsDispatchInvalidDeviceRequest,
- IKsFilter_DispatchClose,
- KsDispatchQuerySecurity,
- KsDispatchSetSecurity,
- KsDispatchFastIoDeviceControlFailure,
- KsDispatchFastReadFailure,
- KsDispatchFastReadFailure,
-};
-
-
-NTSTATUS
-IKsFilter_CreateDescriptors(
- IKsFilterImpl * This,
- KSFILTER_DESCRIPTOR* FilterDescriptor)
-{
- ULONG Index = 0;
- NTSTATUS Status;
-
- /* initialize pin descriptors */
- This->FirstPin = NULL;
- This->PinInstanceCount = NULL;
- This->ProcessPinIndex = NULL;
-
- /* initialize topology descriptor */
- This->Topology.CategoriesCount = FilterDescriptor->CategoriesCount;
- This->Topology.Categories = FilterDescriptor->Categories;
- This->Topology.TopologyNodesCount = FilterDescriptor->NodeDescriptorsCount;
- This->Topology.TopologyConnectionsCount = FilterDescriptor->ConnectionsCount;
- This->Topology.TopologyConnections = FilterDescriptor->Connections;
-
- /* are there any templates */
- if (FilterDescriptor->PinDescriptorsCount)
- {
- /* sanity check */
- ASSERT(FilterDescriptor->PinDescriptors);
-
- /* FIXME handle variable sized pin descriptors */
- ASSERT(FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
-
- /* store pin descriptors ex */
- Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->Filter.Descriptor->PinDescriptors, FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount,
- FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount, 0);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status);
- return Status;
- }
-
- /* store pin instance count */
- Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinInstanceCount, sizeof(ULONG) * FilterDescriptor->PinDescriptorsCount,
- sizeof(ULONG) * FilterDescriptor->PinDescriptorsCount, 0);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status);
- return Status;
- }
-
- /* store instantiated pin arrays */
- Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->FirstPin, sizeof(PKSPIN) * FilterDescriptor->PinDescriptorsCount,
- sizeof(PKSPIN) * FilterDescriptor->PinDescriptorsCount, 0);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status);
- return Status;
- }
-
- /* add new pin factory */
- 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,
- sizeof(KSPROCESSPIN_INDEXENTRY) * FilterDescriptor->PinDescriptorsCount, 0);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status);
- return Status;
- }
-
- }
-
-
- 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)
- {
- /* sanity check */
- ASSERT(FilterDescriptor->NodeDescriptors);
-
- /* FIXME handle variable sized node descriptors */
- ASSERT(FilterDescriptor->NodeDescriptorSize == sizeof(KSNODE_DESCRIPTOR));
-
- This->Topology.TopologyNodes = AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescriptor->NodeDescriptorsCount);
- /* allocate topology node types array */
- if (!This->Topology.TopologyNodes)
- {
- DPRINT("IKsFilter_CreateDescriptors OutOfMemory TopologyNodesCount %lu\n", FilterDescriptor->NodeDescriptorsCount);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- This->Topology.TopologyNodesNames = AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescriptor->NodeDescriptorsCount);
- /* allocate topology names array */
- if (!This->Topology.TopologyNodesNames)
- {
- FreeItem((PVOID)This->Topology.TopologyNodes);
- DPRINT("IKsFilter_CreateDescriptors OutOfMemory TopologyNodesCount %lu\n", FilterDescriptor->NodeDescriptorsCount);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- DPRINT("NodeDescriptorCount %lu\n", FilterDescriptor->NodeDescriptorsCount);
- for(Index = 0; Index < FilterDescriptor->NodeDescriptorsCount; Index++)
- {
- DPRINT("Index %lu Type %p Name %p\n", Index, FilterDescriptor->NodeDescriptors[Index].Type, FilterDescriptor->NodeDescriptors[Index].Name);
-
- /* copy topology type */
- if (FilterDescriptor->NodeDescriptors[Index].Type)
- RtlMoveMemory((PVOID)&This->Topology.TopologyNodes[Index], FilterDescriptor->NodeDescriptors[Index].Type, sizeof(GUID));
-
- /* copy topology name */
- if (FilterDescriptor->NodeDescriptors[Index].Name)
- RtlMoveMemory((PVOID)&This->Topology.TopologyNodesNames[Index], FilterDescriptor->NodeDescriptors[Index].Name, sizeof(GUID));
- }
- }
- /* done! */
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-IKsFilter_CopyFilterDescriptor(
- IKsFilterImpl * This,
- const KSFILTER_DESCRIPTOR* FilterDescriptor)
-{
- NTSTATUS Status;
- KSAUTOMATION_TABLE AutomationTable;
-
- This->Filter.Descriptor = AllocateItem(NonPagedPool, sizeof(KSFILTER_DESCRIPTOR));
- if (!This->Filter.Descriptor)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- Status = KsAddItemToObjectBag(This->Filter.Bag, (PVOID)This->Filter.Descriptor, NULL);
- if (!NT_SUCCESS(Status))
- {
- FreeItem((PVOID)This->Filter.Descriptor);
- This->Filter.Descriptor = NULL;
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* 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;
-}
-
-
-VOID
-IKsFilter_AddPin(
- PKSFILTER Filter,
- PKSPIN Pin)
-{
- PKSPIN NextPin, CurPin;
- PKSBASIC_HEADER BasicHeader;
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
-
- /* sanity check */
- ASSERT(Pin->Id < This->Filter.Descriptor->PinDescriptorsCount);
-
- if (This->FirstPin[Pin->Id] == NULL)
- {
- /* welcome first pin */
- This->FirstPin[Pin->Id] = Pin;
- This->PinInstanceCount[Pin->Id]++;
- return;
- }
-
- /* get first pin */
- CurPin = This->FirstPin[Pin->Id];
-
- do
- {
- /* get next instantiated pin */
- NextPin = KsPinGetNextSiblingPin(CurPin);
- if (!NextPin)
- break;
-
- NextPin = CurPin;
-
- }while(NextPin != NULL);
-
- /* get basic header */
- BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)CurPin - sizeof(KSBASIC_HEADER));
-
- /* store pin */
- BasicHeader->Next.Pin = Pin;
-}
-
-VOID
-IKsFilter_RemovePin(
- PKSFILTER Filter,
- PKSPIN Pin)
-{
- PKSPIN NextPin, CurPin, LastPin;
- PKSBASIC_HEADER BasicHeader;
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
-
- /* sanity check */
- ASSERT(Pin->Id < This->Filter.Descriptor->PinDescriptorsCount);
-
- /* get first pin */
- CurPin = This->FirstPin[Pin->Id];
-
- LastPin = NULL;
- do
- {
- /* get next instantiated pin */
- NextPin = KsPinGetNextSiblingPin(CurPin);
-
- if (CurPin == Pin)
- {
- if (LastPin)
- {
- /* get basic header of last pin */
- BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)LastPin - sizeof(KSBASIC_HEADER));
-
- BasicHeader->Next.Pin = NextPin;
- }
- else
- {
- /* erase last pin */
- This->FirstPin[Pin->Id] = NextPin;
- }
- /* decrement pin instance count */
- This->PinInstanceCount[Pin->Id]--;
- return;
- }
-
- if (!NextPin)
- break;
-
- LastPin = CurPin;
- NextPin = CurPin;
-
- }while(NextPin != NULL);
-
- /* pin not found */
- ASSERT(0);
-}
-
-
-NTSTATUS
-NTAPI
-IKsFilter_DispatchCreatePin(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- IKsFilterImpl * This;
- PKSOBJECT_CREATE_ITEM CreateItem;
- PKSPIN_CONNECT Connect;
- NTSTATUS Status;
-
- DPRINT("IKsFilter_DispatchCreatePin\n");
-
- /* get the create item */
- CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
-
- /* get the filter object */
- This = (IKsFilterImpl*)CreateItem->Context;
-
- /* sanity check */
- ASSERT(This->Header.Type == KsObjectTypeFilter);
-
- /* acquire control mutex */
- KeWaitForSingleObject(This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL);
-
- /* now validate the connect request */
- 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->Filter.Descriptor->PinDescriptorsCount);
-
- DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest PinId %lu CurrentInstanceCount %lu MaxPossible %lu\n", Connect->PinId,
- This->PinInstanceCount[Connect->PinId],
- This->Filter.Descriptor->PinDescriptors[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->Header.OuterUnknown, Connect, (KSPIN_DESCRIPTOR_EX*)&This->Filter.Descriptor->PinDescriptors[Connect->PinId]);
-
- DPRINT("IKsFilter_DispatchCreatePin KspCreatePin %lx\n", Status);
- }
- else
- {
- /* maximum instance count reached, bye-bye */
- Status = STATUS_UNSUCCESSFUL;
- DPRINT("IKsFilter_DispatchCreatePin MaxInstance %lu CurInstance %lu %lx\n", This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible, This->PinInstanceCount[Connect->PinId]);
- }
- }
-
- /* release control mutex */
- KeReleaseMutex(This->Header.ControlMutex, FALSE);
-
- if (Status != STATUS_PENDING)
- {
- /* complete request */
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- }
-
- /* done */
- DPRINT("IKsFilter_DispatchCreatePin Result %lx\n", Status);
- return Status;
-}
-
-NTSTATUS
-NTAPI
-IKsFilter_DispatchCreateNode(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- UNIMPLEMENTED
- Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_UNSUCCESSFUL;
-}
-
-
-VOID
-IKsFilter_AttachFilterToFilterFactory(
- IKsFilterImpl * This,
- PKSFILTERFACTORY FilterFactory)
-{
- PKSBASIC_HEADER BasicHeader;
- PKSFILTER Filter;
-
-
- /* get filter factory basic header */
- BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)FilterFactory - sizeof(KSBASIC_HEADER));
-
- /* sanity check */
- ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory);
-
- if (BasicHeader->FirstChild.FilterFactory == NULL)
- {
- /* welcome first instantiated filter */
- BasicHeader->FirstChild.Filter = &This->Filter;
- return;
- }
-
- /* set to first entry */
- Filter = BasicHeader->FirstChild.Filter;
-
- do
- {
- /* get basic header */
- BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Filter - sizeof(KSBASIC_HEADER));
- /* sanity check */
- ASSERT(BasicHeader->Type == KsObjectTypeFilter);
-
- if (BasicHeader->Next.Filter)
- {
- /* iterate to next filter factory */
- Filter = BasicHeader->Next.Filter;
- }
- else
- {
- /* found last entry */
- break;
- }
- }while(TRUE);
-
- /* attach filter factory */
- BasicHeader->Next.Filter = &This->Filter;
-}
-
-VOID
-IKsFilter_RemoveFilterFromFilterFactory(
- IKsFilterImpl * This,
- PKSFILTERFACTORY FilterFactory)
-{
- PKSBASIC_HEADER BasicHeader;
- PKSFILTER Filter, LastFilter;
-
- /* get filter factory basic header */
- BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)FilterFactory - sizeof(KSBASIC_HEADER));
-
- /* sanity check */
- ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory);
- ASSERT(BasicHeader->FirstChild.Filter != NULL);
-
-
- /* set to first entry */
- Filter = BasicHeader->FirstChild.Filter;
- LastFilter = NULL;
-
- do
- {
- if (Filter == &This->Filter)
- {
- if (LastFilter)
- {
- /* get basic header */
- BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)LastFilter - sizeof(KSBASIC_HEADER));
- /* remove filter instance */
- BasicHeader->Next.Filter = This->Header.Next.Filter;
- break;
- }
- else
- {
- /* remove filter instance */
- BasicHeader->FirstChild.Filter = This->Header.Next.Filter;
- break;
- }
- }
-
- /* get basic header */
- BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Filter - sizeof(KSBASIC_HEADER));
- /* sanity check */
- ASSERT(BasicHeader->Type == KsObjectTypeFilter);
-
- LastFilter = Filter;
- if (BasicHeader->Next.Filter)
- {
- /* iterate to next filter factory */
- Filter = BasicHeader->Next.Filter;
- }
- else
- {
- /* filter is not in list */
- ASSERT(0);
- break;
- }
- }while(TRUE);
-}
-
-NTSTATUS
-NTAPI
-KspCreateFilter(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN IKsFilterFactory *iface)
-{
- IKsFilterImpl * This;
- IKsDevice *KsDevice;
- PKSFILTERFACTORY Factory;
- PIO_STACK_LOCATION IoStack;
- PDEVICE_EXTENSION DeviceExtension;
- NTSTATUS Status;
- PKSOBJECT_CREATE_ITEM CreateItem;
-
- /* get device extension */
- DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- /* get the filter factory */
- Factory = iface->lpVtbl->GetStruct(iface);
-
- if (!Factory || !Factory->FilterDescriptor || !Factory->FilterDescriptor->Dispatch || !Factory->FilterDescriptor->Dispatch->Create)
- {
- /* Sorry it just will not work */
- return STATUS_UNSUCCESSFUL;
- }
-
- /* allocate filter instance */
- This = AllocateItem(NonPagedPool, sizeof(IKsFilterImpl));
- if (!This)
- {
- DPRINT("KspCreateFilter OutOfMemory\n");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* initialize object bag */
- This->Filter.Bag = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_BAG));
- if (!This->Filter.Bag)
- {
- /* no memory */
- FreeItem(This);
- DPRINT("KspCreateFilter OutOfMemory\n");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->BasicHeader.OuterUnknown;
- KsDevice->lpVtbl->InitializeObjectBag(KsDevice, (PKSIOBJECT_BAG)This->Filter.Bag, NULL);
-
- /* copy filter descriptor */
- Status = IKsFilter_CopyFilterDescriptor(This, Factory->FilterDescriptor);
- if (!NT_SUCCESS(Status))
- {
- /* not enough memory */
- FreeItem(This->Filter.Bag);
- FreeItem(This);
- DPRINT("KspCreateFilter IKsFilter_CopyFilterDescriptor failed %lx\n", Status);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* get current irp stack */
- IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- /* allocate create items */
- CreateItem = AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM) * 2);
- if (!CreateItem)
- {
- /* no memory */
- FreeItem(This->Filter.Bag);
- FreeItem(This);
- DPRINT("KspCreateFilter OutOfMemory\n");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- DPRINT("KspCreateFilter Flags %lx\n", Factory->FilterDescriptor->Flags);
-
- /* initialize pin create item */
- CreateItem[0].Create = IKsFilter_DispatchCreatePin;
- CreateItem[0].Context = (PVOID)This;
- CreateItem[0].Flags = KSCREATE_ITEM_FREEONSTOP;
- RtlInitUnicodeString(&CreateItem[0].ObjectClass, KSSTRING_Pin);
- /* initialize node create item */
- CreateItem[1].Create = IKsFilter_DispatchCreateNode;
- CreateItem[1].Context = (PVOID)This;
- CreateItem[1].Flags = KSCREATE_ITEM_FREEONSTOP;
- RtlInitUnicodeString(&CreateItem[1].ObjectClass, KSSTRING_TopologyNode);
-
-
- /* initialize filter instance */
- This->ref = 1;
- This->Header.OuterUnknown = (PUNKNOWN)&vt_IKsFilter;
- This->lpVtblKsControl = &vt_IKsControl;
-
- This->Factory = Factory;
- This->FilterFactory = iface;
- This->FileObject = IoStack->FileObject;
- KeInitializeMutex(&This->ProcessingMutex, 0);
- /* initialize basic header */
- This->Header.KsDevice = &DeviceExtension->DeviceHeader->KsDevice;
- This->Header.Parent.KsFilterFactory = iface->lpVtbl->GetStruct(iface);
- This->Header.Type = KsObjectTypeFilter;
- This->Header.ControlMutex = &This->ControlMutex;
- KeInitializeMutex(This->Header.ControlMutex, 0);
- InitializeListHead(&This->Header.EventList);
- KeInitializeSpinLock(&This->Header.EventListLock);
-
- /* allocate the stream descriptors */
- Status = IKsFilter_CreateDescriptors(This, (PKSFILTER_DESCRIPTOR)Factory->FilterDescriptor);
- if (!NT_SUCCESS(Status))
- {
- /* what can go wrong, goes wrong */
- FreeItem(This);
- FreeItem(CreateItem);
- DPRINT("IKsFilter_CreateDescriptors failed with %lx\n", Status);
- return Status;
- }
-
- /* does the filter have a filter dispatch */
- if (Factory->FilterDescriptor->Dispatch)
- {
- /* does it have a create routine */
- if (Factory->FilterDescriptor->Dispatch->Create)
- {
- /* now let driver initialize the filter instance */
-
- ASSERT(This->Header.KsDevice);
- ASSERT(This->Header.KsDevice->Started);
- Status = Factory->FilterDescriptor->Dispatch->Create(&This->Filter, Irp);
-
- if (!NT_SUCCESS(Status) && Status != STATUS_PENDING)
- {
- /* driver failed to initialize */
- DPRINT1("Driver: Status %x\n", Status);
-
- /* free filter instance */
- FreeItem(This);
- FreeItem(CreateItem);
- return Status;
- }
- }
- }
-
- /* now allocate the object header */
- Status = KsAllocateObjectHeader((PVOID*)&This->ObjectHeader, 2, CreateItem, Irp, &DispatchTable);
- if (!NT_SUCCESS(Status))
- {
- /* failed to allocate object header */
- DPRINT1("Failed to allocate object header %x\n", Status);
-
- return Status;
- }
-
- /* initialize object header extra fields */
- This->ObjectHeader->Type = KsObjectTypeFilter;
- 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 KsDevice %p\n", Status, This->Header.KsDevice);
- return Status;
-}
-
-/*
- @implemented
-*/
-KSDDKAPI
-VOID
-NTAPI
-KsFilterAcquireProcessingMutex(
- IN PKSFILTER Filter)
-{
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
-
- KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL);
-}
-
-/*
- @implemented
-*/
-KSDDKAPI
-VOID
-NTAPI
-KsFilterReleaseProcessingMutex(
- IN PKSFILTER Filter)
-{
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
-
- KeReleaseMutex(&This->ProcessingMutex, FALSE);
-}
-
-
-/*
- @implemented
-*/
-KSDDKAPI
-NTSTATUS
-NTAPI
-KsFilterAddTopologyConnections (
- IN PKSFILTER Filter,
- IN ULONG NewConnectionsCount,
- IN const KSTOPOLOGY_CONNECTION *const NewTopologyConnections)
-{
- ULONG Count;
- NTSTATUS Status;
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
-
- DPRINT("KsFilterAddTopologyConnections\n");
-
- ASSERT(This->Filter.Descriptor);
- Count = This->Filter.Descriptor->ConnectionsCount + NewConnectionsCount;
-
-
- /* 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 */
-
- /* copy new connections */
- RtlMoveMemory((PVOID)&This->Filter.Descriptor->Connections[This->Filter.Descriptor->ConnectionsCount],
- NewTopologyConnections,
- NewConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION));
-
- /* update topology */
- This->Topology.TopologyConnectionsCount += NewConnectionsCount;
- ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->ConnectionsCount += NewConnectionsCount;
- This->Topology.TopologyConnections = This->Filter.Descriptor->Connections;
-
- return Status;
-}
-
-/*
- @unimplemented
-*/
-KSDDKAPI
-VOID
-NTAPI
-KsFilterAttemptProcessing(
- IN PKSFILTER Filter,
- IN BOOLEAN Asynchronous)
-{
- UNIMPLEMENTED
-}
-
-/*
- @unimplemented
-*/
-KSDDKAPI
-NTSTATUS
-NTAPI
-KsFilterCreateNode (
- IN PKSFILTER Filter,
- IN const KSNODE_DESCRIPTOR *const NodeDescriptor,
- OUT PULONG NodeID)
-{
- UNIMPLEMENTED
- return STATUS_NOT_IMPLEMENTED;
-}
-
-/*
- @implemented
-*/
-KSDDKAPI
-NTSTATUS
-NTAPI
-KsFilterCreatePinFactory (
- IN PKSFILTER Filter,
- IN const KSPIN_DESCRIPTOR_EX *const InPinDescriptor,
- OUT PULONG PinID)
-{
- ULONG Count;
- NTSTATUS Status;
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
-
- DPRINT("KsFilterCreatePinFactory\n");
-
- /* calculate new count */
- Count = This->Filter.Descriptor->PinDescriptorsCount + 1;
-
- /* sanity check */
- ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
-
- /* 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 */
- DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status);
- return Status;
- }
-
- /* 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 */
- DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status);
- return Status;
- }
-
- /* 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 */
- DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status);
- return Status;
- }
-
- /* add new pin factory */
- 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->Filter.Descriptor->PinDescriptorsCount, 0);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT("KsFilterCreatePinFactory _KsEdit failed %lx\n", Status);
- return Status;
- }
-
- /* store new pin id */
- *PinID = This->Filter.Descriptor->PinDescriptorsCount;
-
- /* increment pin descriptor count */
- ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->PinDescriptorsCount++;
-
-
- DPRINT("KsFilterCreatePinFactory done\n");
- return STATUS_SUCCESS;
-
-}
-
-/*
- @unimplemented
-*/
-KSDDKAPI
-PKSGATE
-NTAPI
-KsFilterGetAndGate(
- IN PKSFILTER Filter)
-{
- UNIMPLEMENTED
- return NULL;
-}
-
-/*
- @implemented
-*/
-KSDDKAPI
-ULONG
-NTAPI
-KsFilterGetChildPinCount(
- IN PKSFILTER Filter,
- IN ULONG PinId)
-{
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
-
- if (PinId >= This->Filter.Descriptor->PinDescriptorsCount)
- {
- /* index is out of bounds */
- return 0;
- }
- /* return pin instance count */
- return This->PinInstanceCount[PinId];
-}
-
-/*
- @implemented
-*/
-KSDDKAPI
-PKSPIN
-NTAPI
-KsFilterGetFirstChildPin(
- IN PKSFILTER Filter,
- IN ULONG PinId)
-{
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
-
- if (PinId >= This->Filter.Descriptor->PinDescriptorsCount)
- {
- /* index is out of bounds */
- return NULL;
- }
-
- /* return first pin index */
- return This->FirstPin[PinId];
-}
-
-/*
- @implemented
-*/
-KSDDKAPI
-VOID
-NTAPI
-KsFilterRegisterPowerCallbacks(
- IN PKSFILTER Filter,
- IN PFNKSFILTERPOWER Sleep OPTIONAL,
- IN PFNKSFILTERPOWER Wake OPTIONAL)
-{
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
-
- This->Sleep = Sleep;
- This->Wake = Wake;
-}
-
-/*
- @implemented
-*/
-KSDDKAPI
-PKSFILTER
-NTAPI
-KsGetFilterFromIrp(
- IN PIRP Irp)
-{
- PIO_STACK_LOCATION IoStack;
- PKSIOBJECT_HEADER ObjectHeader;
-
- DPRINT("KsGetFilterFromIrp\n");
-
- /* get current irp stack location */
- IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- /* sanity check */
- ASSERT(IoStack->FileObject);
-
- /* get object header */
- ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
-
- if (ObjectHeader->Type == KsObjectTypeFilter)
- {
- /* irp is targeted at the filter */
- return (PKSFILTER)ObjectHeader->ObjectType;
- }
- else if (ObjectHeader->Type == KsObjectTypePin)
- {
- /* irp is for a pin */
- return KsPinGetParentFilter((PKSPIN)ObjectHeader->ObjectType);
- }
- else
- {
- /* irp is unappropiate to retrieve a filter */
- return NULL;
- }
-}