KSBASIC_HEADER Header;
KSFILTER Filter;
- IKsFilterVtbl *lpVtbl;
IKsControlVtbl *lpVtblKsControl;
IKsFilterFactory * FilterFactory;
+ IKsProcessingObjectVtbl * lpVtblKsProcessingObject;
LONG ref;
PKSIOBJECT_HEADER ObjectHeader;
KSTOPOLOGY Topology;
- KSPIN_DESCRIPTOR * PinDescriptors;
- ULONG PinDescriptorCount;
PKSFILTERFACTORY Factory;
PFILE_OBJECT FileObject;
+ KMUTEX ControlMutex;
KMUTEX ProcessingMutex;
+ PKSWORKER Worker;
+ WORK_QUEUE_ITEM WorkItem;
+ KSGATE Gate;
PFNKSFILTERPOWER Sleep;
PFNKSFILTERPOWER Wake;
ULONG *PinInstanceCount;
PKSPIN * FirstPin;
- KSPROCESSPIN_INDEXENTRY ProcessPinIndex;
+ PKSPROCESSPIN_INDEXENTRY ProcessPinIndex;
}IKsFilterImpl;
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, KspTopologyPropertyHandler);
-DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet, KspPinPropertyHandler, KspPinPropertyHandler, KspPinPropertyHandler);
+DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet, FilterTopologyPropertyHandler);
+DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet, FilterPinPropertyHandler, FilterPinPropertyHandler, FilterPinPropertyHandler);
KSPROPERTY_SET FilterPropertySet[] =
{
}
};
+NTSTATUS
+NTAPI
+IKsProcessingObject_fnQueryInterface(
+ IKsProcessingObject * iface,
+ IN REFIID refiid,
+ OUT PVOID* Output)
+{
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject);
+
+ if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
+ {
+ *Output = &This->Header.OuterUnknown;
+ _InterlockedIncrement(&This->ref);
+ return STATUS_SUCCESS;
+ }
+ return STATUS_UNSUCCESSFUL;
+}
+
+ULONG
+NTAPI
+IKsProcessingObject_fnAddRef(
+ IKsProcessingObject * iface)
+{
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject);
+
+ return InterlockedIncrement(&This->ref);
+}
+
+ULONG
+NTAPI
+IKsProcessingObject_fnRelease(
+ IKsProcessingObject * iface)
+{
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject);
+
+ InterlockedDecrement(&This->ref);
+
+ /* Return new reference count */
+ return This->ref;
+}
+
+VOID
+NTAPI
+IKsProcessingObject_fnProcessingObjectWork(
+ IKsProcessingObject * iface)
+{
+ NTSTATUS Status;
+ LARGE_INTEGER TimeOut;
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject);
+
+ DPRINT1("processing object\n");
+ /* first check if running at passive level */
+ if (KeGetCurrentIrql() == PASSIVE_LEVEL)
+ {
+ /* acquire processing mutex */
+ KeWaitForSingleObject(&This->ControlMutex, Executive, KernelMode, FALSE, NULL);
+ }
+ else
+ {
+ /* dispatch level processing */
+ if (KeReadStateMutex(&This->ControlMutex) == 0)
+ {
+ /* some thread was faster */
+ DPRINT1("processing object too slow\n");
+ return;
+ }
+
+ /* acquire processing mutex */
+ TimeOut.QuadPart = 0LL;
+ Status = KeWaitForSingleObject(&This->ControlMutex, Executive, KernelMode, FALSE, &TimeOut);
+
+ if (Status == STATUS_TIMEOUT)
+ {
+ /* some thread was faster */
+ DPRINT1("processing object too slow\n");
+ return;
+ }
+ }
+
+ do
+ {
+
+ /* check if the and-gate has been enabled again */
+ if (&This->Gate.Count != 0)
+ {
+ /* gate is open */
+DPRINT1("processing object gate open\n");
+ break;
+ }
+
+ DPRINT1("IKsProcessingObject_fnProcessingObjectWork not implemented\n");
+ ASSERT(0);
+
+ }while(TRUE);
+
+ /* release process mutex */
+ KeReleaseMutex(&This->ProcessingMutex, FALSE);
+}
+
+PKSGATE
+NTAPI
+IKsProcessingObject_fnGetAndGate(
+ IKsProcessingObject * iface)
+{
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject);
+
+ /* return and gate */
+ return &This->Gate;
+}
+
+VOID
+NTAPI
+IKsProcessingObject_fnProcess(
+ IKsProcessingObject * iface,
+ IN BOOLEAN Asynchronous)
+{
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject);
+
+ /* should the action be asynchronous */
+ if (Asynchronous)
+ {
+ /* queue work item */
+ KsQueueWorkItem(This->Worker, &This->WorkItem);
+DPRINT1("queueing\n");
+ /* done */
+ return;
+ }
+
+ /* does the filter require explicit deferred processing */
+ if ((This->Filter.Descriptor->Flags & (KSFILTER_FLAG_DISPATCH_LEVEL_PROCESSING | KSFILTER_FLAG_CRITICAL_PROCESSING | KSFILTER_FLAG_HYPERCRITICAL_PROCESSING)) &&
+ KeGetCurrentIrql() > PASSIVE_LEVEL)
+ {
+ /* queue work item */
+ KsQueueWorkItem(This->Worker, &This->WorkItem);
+DPRINT1("queueing\n");
+ /* done */
+ return;
+ }
+DPRINT1("invoke\n");
+ /* call worker routine directly */
+ iface->lpVtbl->ProcessingObjectWork(iface);
+}
+
+VOID
+NTAPI
+IKsProcessingObject_fnReset(
+ IKsProcessingObject * iface)
+{
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject);
+
+ /* acquire processing mutex */
+ KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL);
+
+ /* check if the filter supports dispatch routines */
+ if (This->Filter.Descriptor->Dispatch)
+ {
+ /* has the filter a reset routine */
+ if (This->Filter.Descriptor->Dispatch->Reset)
+ {
+ /* reset filter */
+ This->Filter.Descriptor->Dispatch->Reset(&This->Filter);
+ }
+ }
+
+ /* release process mutex */
+ KeReleaseMutex(&This->ProcessingMutex, FALSE);
+}
+
+VOID
+NTAPI
+IKsProcessingObject_fnTriggerNotification(
+ IKsProcessingObject * iface)
+{
+
+}
+
+static IKsProcessingObjectVtbl vt_IKsProcessingObject =
+{
+ IKsProcessingObject_fnQueryInterface,
+ IKsProcessingObject_fnAddRef,
+ IKsProcessingObject_fnRelease,
+ IKsProcessingObject_fnProcessingObjectWork,
+ IKsProcessingObject_fnGetAndGate,
+ IKsProcessingObject_fnProcess,
+ IKsProcessingObject_fnReset,
+ IKsProcessingObject_fnTriggerNotification
+};
+
+
+//---------------------------------------------------------------------------------------------------------
NTSTATUS
NTAPI
IKsControl_fnQueryInterface(
if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
{
- *Output = &This->lpVtbl;
+ *Output = &This->Header.OuterUnknown;
_InterlockedIncrement(&This->ref);
return STATUS_SUCCESS;
}
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;
}
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
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);
}
IKsFilter_fnRelease(
IKsFilter * iface)
{
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
InterlockedDecrement(&This->ref);
IKsFilter_fnGetStruct(
IKsFilter * iface)
{
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
return &This->Filter;
}
IKsFilter * iface,
IN PKSPROCESSPIN ProcessPin)
{
- PKSPROCESSPIN *Pins;
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+ NTSTATUS Status;
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
/* 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;
+ /* sanity check */
+ ASSERT(This->Filter.Descriptor->PinDescriptorsCount > ProcessPin->Pin->Id);
- /* free old process pin */
- FreeItem(This->ProcessPinIndex.Pins);
+ /* 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);
- /* store new process pin index */
- This->ProcessPinIndex.Pins = Pins;
- This->ProcessPinIndex.Count++;
+ 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);
- if (Pins)
- return STATUS_SUCCESS;
- else
- return STATUS_INSUFFICIENT_RESOURCES;
-
+ return Status;
}
NTSTATUS
IN PKSPROCESSPIN ProcessPin)
{
ULONG Index;
- IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+ ULONG Count;
+ PKSPROCESSPIN * Pins;
+
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
/* 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++)
+ /* 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 (This->ProcessPinIndex.Pins[Index] == ProcessPin)
+ if (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--;
+ 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 */
IKsFilter_fnGetProcessDispatch(
IKsFilter * iface)
{
- UNIMPLEMENTED
- return NULL;
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
+
+ return This->ProcessPinIndex;
}
static IKsFilterVtbl vt_IKsFilter =
Irp->IoStatus.Status = Status;
/* complete and forget irp */
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ CompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
return Status;
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)
/* save the result */
Irp->IoStatus.Status = Status;
/* complete irp */
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ CompleteRequest(Irp, IO_NO_INCREMENT);
- /* FIXME remove our instance from the filter factory */
- ASSERT(0);
+ /* remove our instance from the filter factory */
+ IKsFilter_RemoveFilterFromFilterFactory(This, This->Factory);
/* free object header */
KsFreeObjectHeader(This->ObjectHeader);
/* complete and forget */
Irp->IoStatus.Status = Status;
/* complete irp */
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ CompleteRequest(Irp, IO_NO_INCREMENT);
}
/* done */
KSPIN_CINSTANCES * Instances;
KSP_PIN * Pin = (KSP_PIN*)Request;
- if (!This->Factory->FilterDescriptor || !This->Factory->FilterDescriptor->PinDescriptorsCount)
+ if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount)
{
/* no filter / pin descriptor */
IoStatus->Status = STATUS_NOT_IMPLEMENTED;
}
/* ignore custom structs for now */
- ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
- ASSERT(This->Factory->FilterDescriptor->PinDescriptorsCount > 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->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].InstancesPossible;
+ Instances->PossibleCount = This->Filter.Descriptor->PinDescriptors[Pin->PinId].InstancesPossible;
/* current instance count */
Instances->CurrentCount = This->PinInstanceCount[Pin->PinId];
PULONG Result;
KSP_PIN * Pin = (KSP_PIN*)Request;
- if (!This->Factory->FilterDescriptor || !This->Factory->FilterDescriptor->PinDescriptorsCount)
+ if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount)
{
/* no filter / pin descriptor */
IoStatus->Status = STATUS_NOT_IMPLEMENTED;
}
/* ignore custom structs for now */
- ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
- ASSERT(This->Factory->FilterDescriptor->PinDescriptorsCount > Pin->PinId);
+ ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
+ ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId);
Result = (PULONG)Data;
- *Result = This->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].InstancesNecessary;
+ *Result = This->Filter.Descriptor->PinDescriptors[Pin->PinId].InstancesNecessary;
IoStatus->Information = sizeof(ULONG);
IoStatus->Status = STATUS_SUCCESS;
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);
- if (!This->Factory->FilterDescriptor || !This->Factory->FilterDescriptor->PinDescriptorsCount)
+ /* 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;
}
/* ignore custom structs for now */
- ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
- ASSERT(This->Factory->FilterDescriptor->PinDescriptorsCount > Pin->PinId);
+ ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
+ ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId);
- if (This->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].IntersectHandler == NULL ||
- This->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges == NULL ||
- This->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].PinDescriptor.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;
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->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].IntersectHandler(NULL, /* context */
- Irp,
- Pin,
- DataRange,
- (PKSDATAFORMAT)This->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges,
- DataLength,
- Data,
- &Length);
-
- if (Status == STATUS_SUCCESS)
+ 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
-KspPinPropertyHandler(
+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)
/* get filter implementation */
This = (IKsFilterImpl*)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
+ /* sanity check */
+ ASSERT(This);
+
/* get current stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
case KSPROPERTY_PIN_COMMUNICATION:
case KSPROPERTY_PIN_CATEGORY:
case KSPROPERTY_PIN_NAME:
- case KSPROPERTY_PIN_PROPOSEDATAFORMAT:
- Status = KsPinPropertyHandler(Irp, Request, Data, This->PinDescriptorCount, This->PinDescriptors);
+ 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);
case KSPROPERTY_PIN_DATAINTERSECTION:
Status = KspHandleDataIntersection(Irp, &Irp->IoStatus, Request, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength, This);
break;
- case KSPROPERTY_PIN_PHYSICALCONNECTION:
- case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
- UNIMPLEMENTED
- Status = STATUS_NOT_IMPLEMENTED;
- break;
default:
UNIMPLEMENTED
- Status = STATUS_UNSUCCESSFUL;
+ Status = STATUS_NOT_FOUND;
}
+ //DPRINT("KspPinPropertyHandler Pins %lu Request->Id %lu Status %lx\n", This->PinDescriptorCount, Request->Id, Status);
+
return Status;
}
IKsFilterImpl * This;
NTSTATUS Status;
PKSFILTER FilterInstance;
+ UNICODE_STRING GuidString;
+ PKSPROPERTY Property;
+ ULONG SetCount = 0;
/* obtain filter from object header */
Status = IKsFilter_GetFilterFromIrp(Irp, &Filter);
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);
- if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY)
+ /* 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)
{
- UNIMPLEMENTED;
+ const KSMETHOD_SET *MethodSet = NULL;
+ ULONG MethodItemSize = 0;
- /* release filter interface */
- Filter->lpVtbl->Release(Filter);
+ /* 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;
+ }
- /* complete and forget irp */
- Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_NOT_IMPLEMENTED;
+ /* 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;
- /* call property handler supported by ks */
- Status = KspPropertyHandler(Irp, 2, FilterPropertySet, NULL, sizeof(KSPROPERTY_ITEM));
+ /* 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;
- if (Status == STATUS_NOT_FOUND)
+ /* call property handler */
+ Status = KspPropertyHandler(Irp, SetCount, PropertySet, NULL, PropertyItemSize);
+ }
+ else
{
- /* get filter instance */
- FilterInstance = Filter->lpVtbl->GetStruct(Filter);
+ /* sanity check */
+ ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT ||
+ IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_DISABLE_EVENT);
- /* check if the driver supports property sets */
- if (FilterInstance->Descriptor->AutomationTable && FilterInstance->Descriptor->AutomationTable->PropertySetsCount)
+ if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT)
{
- /* call driver's filter property handler */
- Status = KspPropertyHandler(Irp,
- FilterInstance->Descriptor->AutomationTable->PropertySetsCount,
- FilterInstance->Descriptor->AutomationTable->PropertySets,
- NULL,
- FilterInstance->Descriptor->AutomationTable->PropertyItemSize);
+ /* 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);
}
}
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ 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;
+ CompleteRequest(Irp, IO_NO_INCREMENT);
+ }
/* done */
return Status;
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)
{
- /* allocate pin instance count array */
- This->PinInstanceCount = AllocateItem(NonPagedPool, sizeof(ULONG) * FilterDescriptor->PinDescriptorsCount);
- if(!This->PinDescriptors)
+ /* 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))
{
- return STATUS_INSUFFICIENT_RESOURCES;
+ DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status);
+ return Status;
}
- /* allocate first pin array */
- This->FirstPin = AllocateItem(NonPagedPool, sizeof(PKSPIN) * FilterDescriptor->PinDescriptorsCount);
- if(!This->FirstPin)
+ /* 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))
{
- FreeItem(This->PinDescriptors);
- return STATUS_INSUFFICIENT_RESOURCES;
+ 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);
- /* allocate pin descriptor array */
- This->PinDescriptors = AllocateItem(NonPagedPool, sizeof(KSPIN_DESCRIPTOR) * FilterDescriptor->PinDescriptorsCount);
- if(!This->PinDescriptors)
+ if (!NT_SUCCESS(Status))
{
- FreeItem(This->PinInstanceCount);
- return STATUS_INSUFFICIENT_RESOURCES;
+ DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status);
+ return Status;
}
- /* set pin count */
- This->PinDescriptorCount = FilterDescriptor->PinDescriptorsCount;
- /* now copy those pin descriptors over */
- for(Index = 0; Index < FilterDescriptor->PinDescriptorsCount; Index++)
+ /* 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))
{
- /* copy one pin per time */
- RtlMoveMemory(&This->PinDescriptors[Index], &FilterDescriptor->PinDescriptors[Index].PinDescriptor, sizeof(KSPIN_DESCRIPTOR));
+ DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status);
+ return Status;
}
+
}
- /* 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;
- if (This->Topology.TopologyNodesCount > 0)
+ 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)
{
- This->Topology.TopologyNodes = AllocateItem(NonPagedPool, sizeof(GUID) * This->Topology.TopologyNodesCount);
+ /* 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) * This->Topology.TopologyNodesCount);
+ 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;
}
- for(Index = 0; Index < This->Topology.TopologyNodesCount; Index++)
+ 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 */
- RtlMoveMemory((PVOID)&This->Topology.TopologyNodes[Index], FilterDescriptor->NodeDescriptors[Index].Type, sizeof(GUID));
+ if (FilterDescriptor->NodeDescriptors[Index].Type)
+ RtlMoveMemory((PVOID)&This->Topology.TopologyNodes[Index], FilterDescriptor->NodeDescriptors[Index].Type, sizeof(GUID));
+
/* copy topology name */
- RtlMoveMemory((PVOID)&This->Topology.TopologyNodesNames[Index], FilterDescriptor->NodeDescriptors[Index].Name, sizeof(GUID));
+ if (FilterDescriptor->NodeDescriptors[Index].Name)
+ RtlMoveMemory((PVOID)&This->Topology.TopologyNodesNames[Index], FilterDescriptor->NodeDescriptors[Index].Name, sizeof(GUID));
}
}
-
/* done! */
return STATUS_SUCCESS;
}
IKsFilterImpl * This,
const KSFILTER_DESCRIPTOR* FilterDescriptor)
{
- This->Filter.Descriptor = (const KSFILTER_DESCRIPTOR*)AllocateItem(NonPagedPool, sizeof(KSFILTER_DESCRIPTOR));
+ NTSTATUS Status;
+ KSAUTOMATION_TABLE AutomationTable;
+
+ This->Filter.Descriptor = AllocateItem(NonPagedPool, sizeof(KSFILTER_DESCRIPTOR));
if (!This->Filter.Descriptor)
return STATUS_INSUFFICIENT_RESOURCES;
- /* copy all fields */
- RtlMoveMemory((PVOID)This->Filter.Descriptor, FilterDescriptor, sizeof(KSFILTER_DESCRIPTOR));
-
-
- /* perform deep copy of pin descriptors */
- if (FilterDescriptor->PinDescriptorsCount)
- {
- KSPIN_DESCRIPTOR_EX * PinDescriptors = (KSPIN_DESCRIPTOR_EX *)AllocateItem(NonPagedPool, FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount);
-
-
- if (!PinDescriptors)
- {
- FreeItem((PVOID)This->Filter.Descriptor);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- RtlMoveMemory((PVOID)PinDescriptors, FilterDescriptor->PinDescriptors, FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount);
-
- /* brain-dead gcc hack */
- RtlMoveMemory((PVOID)&This->Filter.Descriptor->PinDescriptors, PinDescriptors, sizeof(PKSPIN_DESCRIPTOR_EX));
-
- }
-
- /* perform deep copy of node descriptors */
- if (FilterDescriptor->NodeDescriptorsCount)
+ Status = KsAddItemToObjectBag(This->Filter.Bag, (PVOID)This->Filter.Descriptor, NULL);
+ if (!NT_SUCCESS(Status))
{
- KSNODE_DESCRIPTOR* NodeDescriptor = AllocateItem(NonPagedPool, FilterDescriptor->NodeDescriptorsCount * FilterDescriptor->NodeDescriptorSize);
- if (!NodeDescriptor)
- {
- if (This->Filter.Descriptor->PinDescriptors)
- FreeItem((PVOID)This->Filter.Descriptor->PinDescriptors);
- FreeItem((PVOID)This->Filter.Descriptor);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- RtlMoveMemory((PVOID)NodeDescriptor, FilterDescriptor->NodeDescriptors, FilterDescriptor->NodeDescriptorsCount * FilterDescriptor->NodeDescriptorSize);
-
- /* brain-dead gcc hack */
- RtlMoveMemory((PVOID)&This->Filter.Descriptor->NodeDescriptors, NodeDescriptor, sizeof(PKSNODE_DESCRIPTOR));
+ FreeItem((PVOID)This->Filter.Descriptor);
+ This->Filter.Descriptor = NULL;
+ return STATUS_INSUFFICIENT_RESOURCES;
}
- /* perform deep copy of connections descriptors */
- if (FilterDescriptor->NodeDescriptorsCount)
- {
- KSTOPOLOGY_CONNECTION* Connections = AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY_CONNECTION) * FilterDescriptor->ConnectionsCount);
- if (!Connections)
- {
- if (This->Filter.Descriptor->PinDescriptors)
- FreeItem((PVOID)This->Filter.Descriptor->PinDescriptors);
+ /* copy filter descriptor fields */
+ RtlMoveMemory((PVOID)This->Filter.Descriptor, FilterDescriptor, sizeof(KSFILTER_DESCRIPTOR));
- if (This->Filter.Descriptor->NodeDescriptors)
- FreeItem((PVOID)This->Filter.Descriptor->PinDescriptors);
+ /* zero automation table */
+ RtlZeroMemory(&AutomationTable, sizeof(KSAUTOMATION_TABLE));
- FreeItem((PVOID)This->Filter.Descriptor);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
+ /* setup filter property sets */
+ AutomationTable.PropertyItemSize = sizeof(KSPROPERTY_ITEM);
+ AutomationTable.PropertySetsCount = 2;
+ AutomationTable.PropertySets = FilterPropertySet;
- RtlMoveMemory((PVOID)Connections, FilterDescriptor->Connections, sizeof(KSTOPOLOGY_CONNECTION) * FilterDescriptor->ConnectionsCount);
+ /* merge filter automation table */
+ Status = KsMergeAutomationTables((PKSAUTOMATION_TABLE*)&This->Filter.Descriptor->AutomationTable, (PKSAUTOMATION_TABLE)FilterDescriptor->AutomationTable, &AutomationTable, This->Filter.Bag);
- /* brain-dead gcc hack */
- RtlMoveMemory((PVOID)&This->Filter.Descriptor->Connections, Connections, sizeof(PKSTOPOLOGY_CONNECTION));
- }
-
- return STATUS_SUCCESS;
+ return Status;
}
-NTSTATUS
+VOID
IKsFilter_AddPin(
- IKsFilter * Filter,
+ PKSFILTER Filter,
PKSPIN Pin)
{
PKSPIN NextPin, CurPin;
PKSBASIC_HEADER BasicHeader;
- IKsFilterImpl * This = (IKsFilterImpl*)Filter;
+ 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)
{
/* welcome first pin */
This->FirstPin[Pin->Id] = Pin;
- return STATUS_SUCCESS;
+ This->PinInstanceCount[Pin->Id]++;
+ return;
}
/* get first pin */
/* store pin */
BasicHeader->Next.Pin = Pin;
+}
- return STATUS_SUCCESS;
+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);
}
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);
+ 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->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->lpVtbl, Connect, (KSPIN_DESCRIPTOR_EX*)&This->Filter.Descriptor->PinDescriptors[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]);
- if (NT_SUCCESS(Status))
- {
- /* successfully created pin, increment pin instance count */
- This->PinInstanceCount[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);
+ KeReleaseMutex(This->Header.ControlMutex, FALSE);
if (Status != STATUS_PENDING)
{
/* complete request */
Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ CompleteRequest(Irp, IO_NO_INCREMENT);
}
+
/* done */
+ DPRINT("IKsFilter_DispatchCreatePin Result %lx\n", Status);
return Status;
}
{
UNIMPLEMENTED
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
}
/* found last entry */
break;
}
- }while(FilterFactory);
+ }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);
+}
+
+VOID
+NTAPI
+IKsFilter_FilterCentricWorker(
+ IN PVOID Ctx)
+{
+ IKsProcessingObject * Object = (IKsProcessingObject*)Ctx;
+
+ /* sanity check */
+ ASSERT(Object);
+
+ /* perform work */
+ Object->lpVtbl->ProcessingObjectWork(Object);
+}
+
NTSTATUS
NTAPI
KspCreateFilter(
/* get the filter factory */
Factory = iface->lpVtbl->GetStruct(iface);
- if (!Factory || !Factory->FilterDescriptor || !Factory->FilterDescriptor->Dispatch || !Factory->FilterDescriptor->Dispatch->Create)
+ if (!Factory || !Factory->FilterDescriptor)
{
/* Sorry it just will not work */
return STATUS_UNSUCCESSFUL;
}
+ if (Factory->FilterDescriptor->Flags & KSFILTER_FLAG_DENY_USERMODE_ACCESS)
+ {
+ if (Irp->RequestorMode == UserMode)
+ {
+ /* filter not accessible from user mode */
+ DPRINT1("Access denied\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+ }
+
/* allocate filter instance */
- This = AllocateItem(NonPagedPool, sizeof(IKsFilterFactory));
+ This = AllocateItem(NonPagedPool, sizeof(IKsFilterImpl));
if (!This)
+ {
+ DPRINT1("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);
+ DPRINT1("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);
- /* initialize object bag */
- This->Filter.Bag = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_BAG));
- if (!This->Filter.Bag)
- {
- /* no memory */
- FreeItem(This);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
/* allocate create items */
CreateItem = AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM) * 2);
if (!CreateItem)
{
/* no memory */
+ FreeItem(This->Filter.Bag);
FreeItem(This);
+ DPRINT1("KspCreateFilter OutOfMemory\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlInitUnicodeString(&CreateItem[1].ObjectClass, KSSTRING_TopologyNode);
- KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice;
- KsDevice->lpVtbl->InitializeObjectBag(KsDevice, (PKSIOBJECT_BAG)This->Filter.Bag, NULL);
-
/* initialize filter instance */
This->ref = 1;
- This->lpVtbl = &vt_IKsFilter;
+ This->Header.OuterUnknown = (PUNKNOWN)&vt_IKsFilter;
This->lpVtblKsControl = &vt_IKsControl;
+ This->lpVtblKsProcessingObject = &vt_IKsProcessingObject;
- This->Filter.Descriptor = Factory->FilterDescriptor;
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;
- KeInitializeMutex(&This->Header.ControlMutex, 0);
+ This->Header.ControlMutex = &This->ControlMutex;
+ KeInitializeMutex(This->Header.ControlMutex, 0);
InitializeListHead(&This->Header.EventList);
KeInitializeSpinLock(&This->Header.EventListLock);
+ /* initialize and gate */
+ KsGateInitializeAnd(&This->Gate, NULL);
+
+ /* FIXME initialize and gate based on pin flags */
+
+ /* initialize work item */
+ ExInitializeWorkItem(&This->WorkItem, IKsFilter_FilterCentricWorker, (PVOID)This->lpVtblKsProcessingObject);
+
+ /* allocate counted work item */
+ Status = KsRegisterCountedWorker(HyperCriticalWorkQueue, &This->WorkItem, &This->Worker);
+ if (!NT_SUCCESS(Status))
+ {
+ /* what can go wrong, goes wrong */
+ DPRINT1("KsRegisterCountedWorker failed with %lx\n", Status);
+ FreeItem(This);
+ FreeItem(CreateItem);
+ return Status;
+ }
+
/* allocate the stream descriptors */
Status = IKsFilter_CreateDescriptors(This, (PKSFILTER_DESCRIPTOR)Factory->FilterDescriptor);
if (!NT_SUCCESS(Status))
{
/* what can go wrong, goes wrong */
+ DPRINT1("IKsFilter_CreateDescriptors failed with %lx\n", Status);
+ KsUnregisterWorker(This->Worker);
FreeItem(This);
FreeItem(CreateItem);
return Status;
}
+
+
/* does the filter have a filter dispatch */
if (Factory->FilterDescriptor->Dispatch)
{
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)
DPRINT1("Driver: Status %x\n", Status);
/* free filter instance */
+ KsUnregisterWorker(This->Worker);
FreeItem(This);
FreeItem(CreateItem);
return Status;
/* 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 */
+ DPRINT1("KspCreateFilter done %lx KsDevice %p\n", Status, This->Header.KsDevice);
return Status;
}
KeReleaseMutex(&This->ProcessingMutex, FALSE);
}
+
/*
@implemented
*/
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;
- /* FIXME verify connections */
+ /* 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 (This->Filter.Descriptor->ConnectionsCount)
+ if (!NT_SUCCESS(Status))
{
- /* copy old connections */
- RtlMoveMemory(Connections, This->Filter.Descriptor->Connections, sizeof(KSTOPOLOGY_CONNECTION) * This->Filter.Descriptor->ConnectionsCount);
+ /* failed */
+ DPRINT("KsFilterAddTopologyConnections KsEdit failed with %lx\n", Status);
+ return Status;
}
- /* add new connections */
- RtlMoveMemory((PVOID)(Connections + This->Filter.Descriptor->ConnectionsCount), NewTopologyConnections, NewConnectionsCount);
-
- /* add the new connections */
- RtlMoveMemory((PVOID)&This->Filter.Descriptor->ConnectionsCount, &Count, sizeof(ULONG)); /* brain-dead gcc hack */
+ /* FIXME verify connections */
- /* free old connections array */
- if (This->Filter.Descriptor->ConnectionsCount)
- {
- FreeItem((PVOID)This->Filter.Descriptor->Connections);
- }
+ /* copy new connections */
+ RtlMoveMemory((PVOID)&This->Filter.Descriptor->Connections[This->Filter.Descriptor->ConnectionsCount],
+ NewTopologyConnections,
+ NewConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION));
- /* brain-dead gcc hack */
- RtlMoveMemory((PVOID)&This->Filter.Descriptor->Connections, Connections, 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_SUCCESS;
+ return Status;
}
/*
- @unimplemented
+ @implemented
*/
KSDDKAPI
VOID
IN PKSFILTER Filter,
IN BOOLEAN Asynchronous)
{
- UNIMPLEMENTED
+ PKSGATE Gate;
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
+
+ /* get gate */
+ Gate = This->lpVtblKsProcessingObject->GetAndGate((IKsProcessingObject*)This->lpVtblKsProcessingObject);
+
+ if (!KsGateCaptureThreshold(Gate))
+ {
+ /* filter control gate is closed */
+ DPRINT1("Gate %p Closed %x\n", Gate, Gate->Count);
+ return;
+ }
+DPRINT1("processing\n");
+ /* try initiate processing */
+ This->lpVtblKsProcessingObject->Process((IKsProcessingObject*)This->lpVtblKsProcessingObject, Asynchronous);
}
/*
OUT PULONG PinID)
{
ULONG Count;
- ULONG *PinInstanceCount;
- KSPIN_DESCRIPTOR_EX * PinDescriptorsEx;
- KSPIN_DESCRIPTOR * PinDescriptors;
- PKSPIN *FirstPin;
+ NTSTATUS Status;
IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
- /* calculate existing count */
- Count = This->PinDescriptorCount + 1;
+ DPRINT("KsFilterCreatePinFactory\n");
- /* allocate pin descriptors array */
- PinDescriptorsEx = AllocateItem(NonPagedPool, max(This->Filter.Descriptor->PinDescriptorSize, sizeof(KSPIN_DESCRIPTOR_EX)) * Count);
- if (!PinDescriptorsEx)
- return STATUS_INSUFFICIENT_RESOURCES;
+ /* calculate new count */
+ Count = This->Filter.Descriptor->PinDescriptorsCount + 1;
- /* allocate pin instance count array */
- PinInstanceCount = AllocateItem(NonPagedPool, sizeof(ULONG) * Count);
- if (!PinInstanceCount)
- {
- /* not enough memory */
- FreeItem(PinDescriptorsEx);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
+ /* sanity check */
+ ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
- /* allocate pin descriptor array for pin property handling */
- PinDescriptors = AllocateItem(NonPagedPool, sizeof(KSPIN_DESCRIPTOR) * Count);
- if (!PinDescriptors)
+ /* 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))
{
- /* not enough memory */
- FreeItem(PinDescriptorsEx);
- FreeItem(PinInstanceCount);
- return STATUS_INSUFFICIENT_RESOURCES;
+ /* failed */
+ DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status);
+ return Status;
}
- /* allocate first pin array */
- FirstPin = AllocateItem(NonPagedPool, sizeof(PKSPIN) * Count);
- if (!FirstPin)
+ /* 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))
{
- /* not enough memory */
- FreeItem(PinDescriptorsEx);
- FreeItem(PinInstanceCount);
- FreeItem(PinDescriptors);
- return STATUS_INSUFFICIENT_RESOURCES;
+ /* failed */
+ DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status);
+ return Status;
}
- /* now copy all fields */
- if (Count > 1)
+ /* 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))
{
- /* copy old descriptors */
- 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);
+ /* failed */
+ DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status);
+ return Status;
}
/* add new pin factory */
- RtlMoveMemory((PVOID)((ULONG_PTR)PinDescriptorsEx + max(This->Filter.Descriptor->PinDescriptorSize, sizeof(KSPIN_DESCRIPTOR_EX)) * This->PinDescriptorCount), InPinDescriptor, sizeof(KSPIN_DESCRIPTOR));
- RtlMoveMemory((PVOID)(PinDescriptors + This->PinDescriptorCount), &InPinDescriptor->PinDescriptor, sizeof(KSPIN_DESCRIPTOR));
+ RtlMoveMemory((PVOID)&This->Filter.Descriptor->PinDescriptors[This->Filter.Descriptor->PinDescriptorsCount], InPinDescriptor, sizeof(KSPIN_DESCRIPTOR_EX));
- /* replace old descriptor by using a gcc-compliant hack */
- RtlMoveMemory((PVOID)&This->Filter.Descriptor->PinDescriptors, PinDescriptorsEx, sizeof(KSPIN_DESCRIPTOR_EX*));
- RtlMoveMemory((PVOID)&This->Filter.Descriptor->PinDescriptorsCount, &Count, sizeof(ULONG));
+ /* allocate process pin index */
+ Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex, sizeof(KSPROCESSPIN_INDEXENTRY) * Count,
+ sizeof(KSPROCESSPIN_INDEXENTRY) * This->Filter.Descriptor->PinDescriptorsCount, 0);
- This->PinDescriptors = PinDescriptors;
- This->PinInstanceCount = PinInstanceCount;
- This->FirstPin = FirstPin;
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("KsFilterCreatePinFactory _KsEdit failed %lx\n", Status);
+ return Status;
+ }
/* 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");
return STATUS_SUCCESS;
}
KsFilterGetAndGate(
IN PKSFILTER Filter)
{
- UNIMPLEMENTED
- return NULL;
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
+
+ /* return and-gate */
+ return &This->Gate;
}
/*
{
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;
{
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;
PIO_STACK_LOCATION IoStack;
PKSIOBJECT_HEADER ObjectHeader;
+ DPRINT("KsGetFilterFromIrp\n");
+
/* get current irp stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);