PFNKSFILTERPOWER Wake;
ULONG *PinInstanceCount;
+ PKSPIN * FirstPin;
+ KSPROCESSPIN_INDEXENTRY ProcessPinIndex;
+
}IKsFilterImpl;
const GUID IID_IKsControl = {0x28F54685L, 0x06FD, 0x11D2, {0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
IKsFilter * iface,
IN PKSPROCESSPIN ProcessPin)
{
- UNIMPLEMENTED
- return STATUS_NOT_IMPLEMENTED;
+ PKSPROCESSPIN *Pins;
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+
+ /* first acquire processing mutex */
+ KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL);
+
+ /* allocate new pins array */
+ Pins = AllocateItem(NonPagedPool, sizeof(PKSPROCESSPIN) * (This->ProcessPinIndex.Count + 1));
+
+ /* check if allocation succeeded */
+ if (Pins)
+ {
+ if (This->ProcessPinIndex.Count)
+ {
+ /* copy old pin index */
+ RtlMoveMemory(Pins, This->ProcessPinIndex.Pins, sizeof(PKSPROCESSPIN) * This->ProcessPinIndex.Count);
+ }
+
+ /* add new process pin */
+ Pins[This->ProcessPinIndex.Count] = ProcessPin;
+
+ /* free old process pin */
+ FreeItem(This->ProcessPinIndex.Pins);
+
+ /* store new process pin index */
+ This->ProcessPinIndex.Pins = Pins;
+ This->ProcessPinIndex.Count++;
+ }
+
+ /* release process mutex */
+ KeReleaseMutex(&This->ProcessingMutex, FALSE);
+
+ if (Pins)
+ return STATUS_SUCCESS;
+ else
+ return STATUS_INSUFFICIENT_RESOURCES;
+
}
NTSTATUS
IKsFilter * iface,
IN PKSPROCESSPIN ProcessPin)
{
- UNIMPLEMENTED
- return STATUS_NOT_IMPLEMENTED;
+ ULONG Index;
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+
+ /* first acquire processing mutex */
+ KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL);
+
+ /* iterate through process pin index array and search for the process pin to be removed */
+ for(Index = 0; Index < This->ProcessPinIndex.Count; Index++)
+ {
+ if (This->ProcessPinIndex.Pins[Index] == ProcessPin)
+ {
+ /* found process pin */
+ if (Index + 1 < This->ProcessPinIndex.Count)
+ {
+ /* erase entry */
+ RtlMoveMemory(&This->ProcessPinIndex.Pins[Index], &This->ProcessPinIndex.Pins[Index+1], This->ProcessPinIndex.Count - Index - 1);
+ }
+ /* decrement process pin count */
+ This->ProcessPinIndex.Count--;
+ }
+ }
+
+ /* release process mutex */
+ KeReleaseMutex(&This->ProcessingMutex, FALSE);
+
+ /* done */
+ return STATUS_SUCCESS;
}
BOOL
/* complete irp */
IoCompleteRequest(Irp, IO_NO_INCREMENT);
- /* remove our instance from the filter factory */
- This->FilterFactory->lpVtbl->RemoveFilterInstance(This->FilterFactory, Filter);
+ /* FIXME remove our instance from the filter factory */
+ ASSERT(0);
/* free object header */
KsFreeObjectHeader(This->ObjectHeader);
return STATUS_INSUFFICIENT_RESOURCES;
}
+ /* allocate first pin array */
+ This->FirstPin = AllocateItem(NonPagedPool, sizeof(PKSPIN) * FilterDescriptor->PinDescriptorsCount);
+ if(!This->FirstPin)
+ {
+ FreeItem(This->PinDescriptors);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+
/* allocate pin descriptor array */
This->PinDescriptors = AllocateItem(NonPagedPool, sizeof(KSPIN_DESCRIPTOR) * FilterDescriptor->PinDescriptorsCount);
if(!This->PinDescriptors)
return STATUS_SUCCESS;
}
+
+NTSTATUS
+IKsFilter_AddPin(
+ IKsFilter * Filter,
+ PKSPIN Pin)
+{
+ PKSPIN NextPin, CurPin;
+ PKSBASIC_HEADER BasicHeader;
+ IKsFilterImpl * This = (IKsFilterImpl*)Filter;
+
+ /* sanity check */
+ ASSERT(Pin->Id < This->PinDescriptorCount);
+
+ if (This->FirstPin[Pin->Id] == NULL)
+ {
+ /* welcome first pin */
+ This->FirstPin[Pin->Id] = Pin;
+ return STATUS_SUCCESS;
+ }
+
+ /* 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;
+
+ return STATUS_SUCCESS;
+}
+
+
NTSTATUS
NTAPI
IKsFilter_DispatchCreatePin(
}
+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(FilterFactory);
+
+ /* attach filter factory */
+ BasicHeader->Next.Filter = &This->Filter;
+}
+
NTSTATUS
NTAPI
KspCreateFilter(
InitializeListHead(&This->Header.EventList);
KeInitializeSpinLock(&This->Header.EventListLock);
-
-
-
-
/* allocate the stream descriptors */
Status = IKsFilter_CreateDescriptors(This, (PKSFILTER_DESCRIPTOR)Factory->FilterDescriptor);
if (!NT_SUCCESS(Status))
return Status;
}
- /* now add the filter instance to the filter factory */
- Status = iface->lpVtbl->AddFilterInstance(iface, (IKsFilter*)&This->lpVtbl);
-
- if (!NT_SUCCESS(Status))
- {
- /* failed to add filter */
- FreeItem(This);
- FreeItem(CreateItem);
- return Status;
- }
-
/* does the filter have a filter dispatch */
if (Factory->FilterDescriptor->Dispatch)
{
/* driver failed to initialize */
DPRINT1("Driver: Status %x\n", Status);
- /* remove filter instance from filter factory */
- iface->lpVtbl->RemoveFilterInstance(iface, (IKsFilter*)&This->lpVtbl);
-
/* free filter instance */
FreeItem(This);
FreeItem(CreateItem);
This->ObjectHeader->Unknown = (PUNKNOWN)&This->lpVtbl;
This->ObjectHeader->ObjectType = (PVOID)&This->Filter;
+ /* attach filter to filter factory */
+ IKsFilter_AttachFilterToFilterFactory(This, This->Header.Parent.KsFilterFactory);
/* completed initialization */
return Status;
ULONG *PinInstanceCount;
KSPIN_DESCRIPTOR_EX * PinDescriptorsEx;
KSPIN_DESCRIPTOR * PinDescriptors;
+ PKSPIN *FirstPin;
IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
/* calculate existing count */
return STATUS_INSUFFICIENT_RESOURCES;
}
+ /* allocate first pin array */
+ FirstPin = AllocateItem(NonPagedPool, sizeof(PKSPIN) * Count);
+ if (!FirstPin)
+ {
+ /* not enough memory */
+ FreeItem(PinDescriptorsEx);
+ FreeItem(PinInstanceCount);
+ FreeItem(PinDescriptors);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
/* now copy all fields */
if (Count > 1)
{
RtlMoveMemory(PinDescriptorsEx, This->Filter.Descriptor->PinDescriptors, max(This->Filter.Descriptor->PinDescriptorSize, sizeof(KSPIN_DESCRIPTOR_EX)) * This->PinDescriptorCount);
RtlMoveMemory(PinInstanceCount, This->PinInstanceCount, This->PinDescriptorCount * sizeof(ULONG));
RtlMoveMemory(PinDescriptors, This->PinDescriptors, sizeof(KSPIN_DESCRIPTOR) * This->PinDescriptorCount);
+ RtlMoveMemory(FirstPin, This->FirstPin, sizeof(PKSPIN) * This->PinDescriptorCount);
/* now free old descriptors */
FreeItem(This->PinInstanceCount);
FreeItem((PVOID)This->Filter.Descriptor->PinDescriptors);
FreeItem(This->PinDescriptors);
+ FreeItem(This->FirstPin);
}
/* add new pin factory */
This->PinDescriptors = PinDescriptors;
This->PinInstanceCount = PinInstanceCount;
+ This->FirstPin = FirstPin;
/* store new pin id */
*PinID = This->PinDescriptorCount;
}
/*
- @unimplemented
+ @implemented
*/
KSDDKAPI
PKSPIN
IN PKSFILTER Filter,
IN ULONG PinId)
{
- UNIMPLEMENTED
- return NULL;
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
+
+ if (PinId >= This->PinDescriptorCount)
+ {
+ /* index is out of bounds */
+ return NULL;
+ }
+
+ /* return first pin index */
+ return This->FirstPin[PinId];
}
/*
PFNKSFILTERFACTORYPOWER WakeCallback;
LIST_ENTRY SymbolicLinkList;
- LIST_ENTRY FilterInstanceList;
}IKsFilterFactoryImpl;
-typedef struct
-{
- LIST_ENTRY Entry;
- IKsFilter *FilterInstance;
-}FILTER_INSTANCE_ENTRY, *PFILTER_INSTANCE_ENTRY;
-
-
-
VOID
NTAPI
IKsFilterFactory_ItemFreeCb(
return KspSetDeviceInterfacesState(&This->SymbolicLinkList, Enable);
}
+VOID
+IKsFilterFactory_AttachFilterFactoryToDeviceHeader(
+ IKsFilterFactoryImpl * This,
+ PKSIDEVICE_HEADER DeviceHeader)
+{
+ PKSBASIC_HEADER BasicHeader;
+ PKSFILTERFACTORY FilterFactory;
+
+ if (DeviceHeader->BasicHeader.FirstChild.FilterFactory == NULL)
+ {
+ /* first attached filter factory */
+ DeviceHeader->BasicHeader.FirstChild.FilterFactory = &This->FilterFactory;
+ return;
+ }
+
+ /* set to first entry */
+ FilterFactory = DeviceHeader->BasicHeader.FirstChild.FilterFactory;
+
+ do
+ {
+ /* get basic header */
+ BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)FilterFactory - sizeof(KSBASIC_HEADER));
+ /* sanity check */
+ ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory);
+
+ if (BasicHeader->Next.FilterFactory)
+ {
+ /* iterate to next filter factory */
+ FilterFactory = BasicHeader->Next.FilterFactory;
+ }
+ else
+ {
+ /* found last entry */
+ break;
+ }
+ }while(FilterFactory);
+
+ /* attach filter factory */
+ BasicHeader->Next.FilterFactory = &This->FilterFactory;
+}
+
NTSTATUS
NTAPI
IKsFilterFactory_fnInitialize(
InitializeListHead(&This->SymbolicLinkList);
- InitializeListHead(&This->FilterInstanceList);
/* initialize filter factory control mutex */
KeInitializeMutex(&This->Header.ControlMutex, 0);
}
}
+ /* attach filterfactory to device header */
+ IKsFilterFactory_AttachFilterFactoryToDeviceHeader(This, DeviceExtension->DeviceHeader);
/* return result */
return Status;
}
-NTSTATUS
-NTAPI
-IKsFilterFactory_fnAddFilterInstance(
- IKsFilterFactory * iface,
- IN IKsFilter *FilterInstance)
-{
- PFILTER_INSTANCE_ENTRY Entry;
- IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
-
- /* allocate filter instance entry */
- Entry = AllocateItem(NonPagedPool, sizeof(FILTER_INSTANCE_ENTRY));
- if (!Entry)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- /* initialize filter instance entry */
- Entry->FilterInstance = FilterInstance;
-
- /* insert entry */
- InsertTailList(&This->FilterInstanceList, &Entry->Entry);
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-NTAPI
-IKsFilterFactory_fnRemoveFilterInstance(
- IKsFilterFactory * iface,
- IN IKsFilter *FilterInstance)
-{
- PFILTER_INSTANCE_ENTRY InstanceEntry;
- PLIST_ENTRY Entry;
- IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
-
- /* point to first entry */
- Entry = This->FilterInstanceList.Flink;
-
- while(Entry != &This->FilterInstanceList)
- {
- InstanceEntry = (PFILTER_INSTANCE_ENTRY)CONTAINING_RECORD(Entry, FILTER_INSTANCE_ENTRY, Entry);
- if (InstanceEntry->FilterInstance == FilterInstance)
- {
- /* found entry */
- RemoveEntryList(&InstanceEntry->Entry);
- FreeItem(InstanceEntry);
- return STATUS_SUCCESS;
- }
- }
-
- /* entry not in list! */
- return STATUS_NOT_FOUND;
-}
-
static IKsFilterFactoryVtbl vt_IKsFilterFactoryVtbl =
{
IKsFilterFactory_fnQueryInterface,
IKsFilterFactory_fnRelease,
IKsFilterFactory_fnGetStruct,
IKsFilterFactory_fnSetDeviceClassesState,
- IKsFilterFactory_fnInitialize,
- IKsFilterFactory_fnAddFilterInstance,
- IKsFilterFactory_fnRemoveFilterInstance
+ IKsFilterFactory_fnInitialize
};
KSBASIC_HEADER BasicHeader;
KSPIN Pin;
PKSIOBJECT_HEADER ObjectHeader;
+ KSPROCESSPIN ProcessPin;
LIST_ENTRY Entry;
IKsPinVtbl *lpVtbl;
}
/*
- @implemented
+ @unimplemented
*/
PDEVICE_OBJECT
NTAPI
KsPinGetConnectedPinDeviceObject(
IN PKSPIN Pin)
{
- IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
-
- /* return related file object */
- return IoGetRelatedDeviceObject(This->FileObject);
+ UNIMPLEMENTED
+ return NULL;
}
/*
KsPinGetConnectedPinFileObject(
IN PKSPIN Pin)
{
+ UNIMPLEMENTED
return NULL;
}
/*
- @implemented
+ @unimplemented
*/
NTSTATUS
NTAPI
IN const GUID* InterfaceId,
OUT PVOID* Interface)
{
- IKsPin * KsPin;
- IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
-
- /* get pin interface */
- KsPin = (IKsPin*)&This->lpVtbl;
-
- /* query pin interface for the requested interface */
- return KsPin->lpVtbl->QueryInterface(KsPin, InterfaceId, Interface);
+ UNIMPLEMENTED
+ return STATUS_NOT_IMPLEMENTED;
}
/*
This->ObjectHeader->Unknown = (PUNKNOWN)&This->lpVtbl;
This->ObjectHeader->ObjectType = (PVOID)&This->Pin;
+ /* setup process pin */
+ This->ProcessPin.Pin = &This->Pin;
+ This->ProcessPin.StreamPointer = (PKSSTREAM_POINTER)This->LeadingEdgeStreamPointer;
+
+ if (!Descriptor->Dispatch || !Descriptor->Dispatch->Process)
+ {
+ /* the pin is part of filter-centric processing filter
+ * add process pin to filter
+ */
+
+ Status = Filter->lpVtbl->AddProcessPin(Filter, &This->ProcessPin);
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed to add process pin */
+ KsFreeObjectBag((KSOBJECT_BAG)This->Pin.Bag);
+ KsFreeObjectHeader(&This->ObjectHeader);
+
+ /* return failure code */
+ return Status;
+ }
+ }
+
+ /* FIXME add pin instance to filter instance */
+
/* does the driver have a pin dispatch */
if (Descriptor->Dispatch && Descriptor->Dispatch->Create)
{
return Status;
}
- /* FIXME add pin instance to filter instance */
-
return Status;
}