- Implement KsGetFirstChild, KsGetNextSibling

- Implement IKsFilter_fnAddProcessPin, IKsFilter_fnRemoveProcessPin
- Remove old code for attaching so that it works with KsGetFirstChild
- Implement attach of filter factories to the device header
- Unimplement a few functions which were wrong
- Implement KsDispatchSpecificProperty

svn path=/trunk/; revision=42699
This commit is contained in:
Johannes Anderwald 2009-08-15 13:45:06 +00:00
parent bde6b65191
commit d1ff4911cb
9 changed files with 335 additions and 137 deletions

View file

@ -1891,7 +1891,7 @@ KsGetBusEnumPnpDeviceObject(
}
/*
@unimplemented
@implemented
*/
KSDDKAPI
PVOID
@ -1899,12 +1899,19 @@ NTAPI
KsGetFirstChild(
IN PVOID Object)
{
UNIMPLEMENTED
return NULL;
PKSBASIC_HEADER BasicHeader;
/* get the basic header */
BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
/* type has to be either a device or a filter factory */
ASSERT(BasicHeader->Type == KsObjectTypeDevice || BasicHeader->Type == KsObjectTypeFilterFactory);
return (PVOID)BasicHeader->FirstChild.Filter;
}
/*
@unimplemented
@implemented
*/
KSDDKAPI
PVOID
@ -1912,8 +1919,15 @@ NTAPI
KsGetNextSibling(
IN PVOID Object)
{
UNIMPLEMENTED
return NULL;
PKSBASIC_HEADER BasicHeader;
/* get the basic header */
BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
ASSERT(BasicHeader->Type == KsObjectTypeDevice || BasicHeader->Type == KsObjectTypeFilterFactory ||
BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
return (PVOID)BasicHeader->Next.Pin;
}
/*

View file

@ -32,6 +32,9 @@ typedef struct
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}};
@ -284,8 +287,43 @@ IKsFilter_fnAddProcessPin(
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
@ -294,8 +332,33 @@ IKsFilter_fnRemoveProcessPin(
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
@ -437,8 +500,8 @@ IKsFilter_DispatchClose(
/* 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);
@ -726,6 +789,15 @@ IKsFilter_CreateDescriptors(
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)
@ -852,6 +924,50 @@ IKsFilter_CopyFilterDescriptor(
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(
@ -921,6 +1037,54 @@ IKsFilter_DispatchCreateNode(
}
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(
@ -1016,10 +1180,6 @@ 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))
@ -1030,17 +1190,6 @@ KspCreateFilter(
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)
{
@ -1055,9 +1204,6 @@ KspCreateFilter(
/* 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);
@ -1081,6 +1227,8 @@ KspCreateFilter(
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;
@ -1205,6 +1353,7 @@ KsFilterCreatePinFactory (
ULONG *PinInstanceCount;
KSPIN_DESCRIPTOR_EX * PinDescriptorsEx;
KSPIN_DESCRIPTOR * PinDescriptors;
PKSPIN *FirstPin;
IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
/* calculate existing count */
@ -1234,6 +1383,17 @@ KsFilterCreatePinFactory (
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)
{
@ -1241,11 +1401,13 @@ KsFilterCreatePinFactory (
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 */
@ -1258,6 +1420,7 @@ KsFilterCreatePinFactory (
This->PinDescriptors = PinDescriptors;
This->PinInstanceCount = PinInstanceCount;
This->FirstPin = FirstPin;
/* store new pin id */
*PinID = This->PinDescriptorCount;
@ -1304,7 +1467,7 @@ KsFilterGetChildPinCount(
}
/*
@unimplemented
@implemented
*/
KSDDKAPI
PKSPIN
@ -1313,8 +1476,16 @@ KsFilterGetFirstChildPin(
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];
}
/*

View file

@ -21,17 +21,8 @@ typedef struct
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(
@ -155,6 +146,47 @@ IKsFilterFactory_fnSetDeviceClassesState(
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(
@ -196,7 +228,6 @@ IKsFilterFactory_fnInitialize(
InitializeListHead(&This->SymbolicLinkList);
InitializeListHead(&This->FilterInstanceList);
/* initialize filter factory control mutex */
KeInitializeMutex(&This->Header.ControlMutex, 0);
@ -273,62 +304,13 @@ IKsFilterFactory_fnInitialize(
}
}
/* 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,
@ -336,9 +318,7 @@ static IKsFilterFactoryVtbl vt_IKsFilterFactoryVtbl =
IKsFilterFactory_fnRelease,
IKsFilterFactory_fnGetStruct,
IKsFilterFactory_fnSetDeviceClassesState,
IKsFilterFactory_fnInitialize,
IKsFilterFactory_fnAddFilterInstance,
IKsFilterFactory_fnRemoveFilterInstance
IKsFilterFactory_fnInitialize
};

View file

@ -114,20 +114,6 @@ KsDispatchSetSecurity(
return Status;
}
/*
@unimplemented
*/
KSDDKAPI
NTSTATUS
NTAPI
KsDispatchSpecificProperty(
IN PIRP Irp,
IN PFNKSHANDLER Handler)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
}
/*
@unimplemented
*/

View file

@ -117,13 +117,18 @@ KspCopyCreateRequest(
NTSTATUS
KspCreatePin(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PIRP Irp,
IN PKSDEVICE KsDevice,
IN IKsFilterFactory * FilterFactory,
IN IKsFilterFactory * FilterFactory,
IN IKsFilter* Filter,
IN PKSPIN_CONNECT Connect,
IN KSPIN_DESCRIPTOR_EX* Descriptor);
NTSTATUS
IKsFilter_AddPin(
IKsFilter * Filter,
PKSPIN Pin);
NTSTATUS
KspAddCreateItemToList(
OUT PLIST_ENTRY ListHead,

View file

@ -237,12 +237,6 @@ DECLARE_INTERFACE_(IKsFilterFactory, IUnknown)
IN PFNKSFILTERFACTORYPOWER SleepCallback OPTIONAL,
IN PFNKSFILTERFACTORYPOWER WakeCallback OPTIONAL,
OUT PKSFILTERFACTORY *FilterFactory OPTIONAL)PURE;
STDMETHOD_(NTSTATUS, AddFilterInstance)(THIS_
IN IKsFilter *Filter)PURE;
STDMETHOD_(NTSTATUS, RemoveFilterInstance)(THIS_
IN IKsFilter *Filter)PURE;
};

View file

@ -62,13 +62,26 @@ typedef struct
KMUTEX ControlMutex;
LIST_ENTRY EventList;
KSPIN_LOCK EventListLock;
union
{
PKSDEVICE KsDevice;
PKSFILTERFACTORY KsFilterFactory;
PKSFILTER KsFilter;
}Parent;
union
{
PKSFILTERFACTORY FilterFactory;
PKSFILTER Filter;
PKSPIN Pin;
}Next;
union
{
PKSFILTERFACTORY FilterFactory;
PKSFILTER Filter;
}FirstChild;
}KSBASIC_HEADER, *PKSBASIC_HEADER;
typedef struct

View file

@ -25,6 +25,7 @@ typedef struct
KSBASIC_HEADER BasicHeader;
KSPIN Pin;
PKSIOBJECT_HEADER ObjectHeader;
KSPROCESSPIN ProcessPin;
LIST_ENTRY Entry;
IKsPinVtbl *lpVtbl;
@ -370,17 +371,15 @@ KsPinGetConnectedFilterInterface(
}
/*
@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;
}
/*
@ -391,11 +390,12 @@ NTAPI
KsPinGetConnectedPinFileObject(
IN PKSPIN Pin)
{
UNIMPLEMENTED
return NULL;
}
/*
@implemented
@unimplemented
*/
NTSTATUS
NTAPI
@ -404,14 +404,8 @@ KsPinGetConnectedPinInterface(
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;
}
/*
@ -1186,6 +1180,30 @@ KspCreatePin(
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)
{
@ -1204,7 +1222,5 @@ KspCreatePin(
return Status;
}
/* FIXME add pin instance to filter instance */
return Status;
}

View file

@ -200,7 +200,7 @@ FindFastPropertyHandler(
/*
@unimplemented
@implemented
*/
KSDDKAPI
BOOLEAN
@ -280,3 +280,22 @@ KsFastPropertyHandler(
}
return FALSE;
}
/*
@implemented
*/
KSDDKAPI
NTSTATUS
NTAPI
KsDispatchSpecificProperty(
IN PIRP Irp,
IN PFNKSHANDLER Handler)
{
PIO_STACK_LOCATION IoStack;
/* get current irp stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
return Handler(Irp, IoStack->Parameters.DeviceIoControl.Type3InputBuffer, Irp->UserBuffer);
}