Author: janderwald
Date: Fri Apr 2 18:38:48 2010
New Revision: 46685
URL:
http://svn.reactos.org/svn/reactos?rev=46685&view=rev
Log:
[KS]
- Instantiated pins use as the control mutex the mutex from the filter
- Fix KsAcquireControl & KsReleaseControl
- Fix handling of IRP_MN_QUERY_INTERFACE
- Filter centric ks filters expect an array of KSPROCESSPIN_INDEXENTRY. Allocate array
when intializing filter / new pin factory is added
- Store result of pin intersection handler when result is STATUS_BUFFER_OVERFLOW
- Implement setting / retrieving of master clock
- Implement setting / retrieving pin state
- Partly implement setting pin data format
- Implement IKsReferenceClock interface
- Implement KsPinGetReferenceClockInterface
- Add sanity checks to KsGetPinFromIrp
- Partly implement handling IOCTL_KS_READ_STREAM / IOCTL_KS_WRITE_STREAM
- Supply filter property sets when an IOCTL_KS_PROPERTY request arrives
- Release again filter mutex when closing the pin
- Implement allocating a clock
- Tuner pin fails with STATUS_IO_DEVICE_ERROR when set to KSSTATE_RUN, needs more
investigation
Modified:
trunk/reactos/drivers/ksfilter/ks/api.c
trunk/reactos/drivers/ksfilter/ks/device.c
trunk/reactos/drivers/ksfilter/ks/driver.c
trunk/reactos/drivers/ksfilter/ks/filter.c
trunk/reactos/drivers/ksfilter/ks/filterfactory.c
trunk/reactos/drivers/ksfilter/ks/kstypes.h
trunk/reactos/drivers/ksfilter/ks/pin.c
trunk/reactos/drivers/ksfilter/ks/priv.h
trunk/reactos/drivers/ksfilter/ks/property.c
Modified: trunk/reactos/drivers/ksfilter/ks/api.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/api.c?…
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/api.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/api.c [iso-8859-1] Fri Apr 2 18:38:48 2010
@@ -1589,7 +1589,7 @@
/* sanity check */
ASSERT(BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type ==
KsObjectTypePin);
- KeWaitForSingleObject(&BasicHeader->ControlMutex, Executive, KernelMode,
FALSE, NULL);
+ KeWaitForSingleObject(BasicHeader->ControlMutex, Executive, KernelMode, FALSE,
NULL);
}
@@ -1606,7 +1606,7 @@
/* sanity check */
ASSERT(BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type ==
KsObjectTypePin);
- KeReleaseMutex(&BasicHeader->ControlMutex, FALSE);
+ KeReleaseMutex(BasicHeader->ControlMutex, FALSE);
}
Modified: trunk/reactos/drivers/ksfilter/ks/device.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/device…
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/device.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/device.c [iso-8859-1] Fri Apr 2 18:38:48 2010
@@ -492,7 +492,7 @@
}
case IRP_MN_QUERY_INTERFACE:
{
- Status = STATUS_SUCCESS;
+ Status = STATUS_UNSUCCESSFUL;
/* check for pnp notification support */
if (Dispatch)
{
@@ -508,6 +508,7 @@
if (NT_SUCCESS(Status))
{
/* driver supports a private interface */
+ DPRINT1("IRP_MN_QUERY_INTERFACE Device supports interface\n");
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
Modified: trunk/reactos/drivers/ksfilter/ks/driver.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/driver…
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/driver.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/driver.c [iso-8859-1] Fri Apr 2 18:38:48 2010
@@ -39,10 +39,10 @@
{
PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object -
sizeof(KSBASIC_HEADER));
- DPRINT("KsGetDevice %p BasicHeader %p Type %x\n", Object, BasicHeader,
BasicHeader->Type);
-
- ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory || BasicHeader->Type ==
KsObjectTypeFilter || BasicHeader->Type == BasicHeader->Type);
+ ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory || BasicHeader->Type ==
KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
ASSERT(BasicHeader->KsDevice);
+ ASSERT(BasicHeader->KsDevice->Started);
+ ASSERT(BasicHeader->KsDevice->PhysicalDeviceObject);
return BasicHeader->KsDevice;
}
Modified: trunk/reactos/drivers/ksfilter/ks/filter.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/filter…
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/filter.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/filter.c [iso-8859-1] Fri Apr 2 18:38:48 2010
@@ -26,6 +26,7 @@
ULONG PinDescriptorCount;
PKSFILTERFACTORY Factory;
PFILE_OBJECT FileObject;
+ KMUTEX ControlMutex;
KMUTEX ProcessingMutex;
@@ -34,7 +35,7 @@
ULONG *PinInstanceCount;
PKSPIN * FirstPin;
- KSPROCESSPIN_INDEXENTRY ProcessPinIndex;
+ PKSPROCESSPIN_INDEXENTRY ProcessPinIndex;
}IKsFilterImpl;
@@ -294,18 +295,20 @@
/* first acquire processing mutex */
KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE,
NULL);
- /* edit process pin descriptor */
- Status = _KsEdit(This->Filter.Bag,
- (PVOID*)&This->ProcessPinIndex.Pins,
- (This->ProcessPinIndex.Count + 1) * sizeof(PKSPROCESSPIN),
- (This->ProcessPinIndex.Count) * sizeof(PKSPROCESSPIN),
+ /* sanity check */
+ ASSERT(This->PinDescriptorCount > ProcessPin->Pin->Id);
+
+ /* allocate new process pin array */
+ Status = _KsEdit(This->Filter.Bag,
(PVOID*)&This->ProcessPinIndex[ProcessPin->Pin->Id].Pins,
+ (This->PinDescriptorCount + 1) * sizeof(PKSPROCESSPIN),
+ This->PinDescriptorCount * sizeof(PKSPROCESSPIN),
0);
if (NT_SUCCESS(Status))
{
- /* add new process pin */
- This->ProcessPinIndex.Pins[This->ProcessPinIndex.Count] = ProcessPin;
- This->ProcessPinIndex.Count++;
+ /* 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 */
@@ -321,25 +324,39 @@
IN PKSPROCESSPIN ProcessPin)
{
ULONG Index;
+ ULONG Count;
+ PKSPROCESSPIN * Pins;
+
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--;
- }
+ /* 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 */
@@ -394,8 +411,9 @@
IKsFilter_fnGetProcessDispatch(
IKsFilter * iface)
{
- UNIMPLEMENTED
- return NULL;
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl,
lpVtbl);
+
+ return This->ProcessPinIndex;
}
static IKsFilterVtbl vt_IKsFilter =
@@ -619,7 +637,7 @@
Data,
&Length);
- if (Status == STATUS_SUCCESS)
+ if (Status == STATUS_SUCCESS || Status == STATUS_BUFFER_OVERFLOW)
{
IoStatus->Information = Length;
break;
@@ -784,6 +802,7 @@
This->PinInstanceCount = NULL;
This->PinDescriptors = NULL;
This->PinDescriptorsEx = NULL;
+ This->ProcessPinIndex = NULL;
This->PinDescriptorCount = 0;
/* initialize topology descriptor */
@@ -842,8 +861,6 @@
return Status;
}
-
-
/* add new pin factory */
RtlMoveMemory(This->PinDescriptorsEx, FilterDescriptor->PinDescriptors,
sizeof(KSPIN_DESCRIPTOR_EX) * FilterDescriptor->PinDescriptorsCount);
@@ -852,8 +869,19 @@
RtlMoveMemory(&This->PinDescriptors[Index],
&FilterDescriptor->PinDescriptors[Index].PinDescriptor, sizeof(KSPIN_DESCRIPTOR));
}
+ /* 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;
+ }
+
/* store new pin descriptor count */
This->PinDescriptorCount = FilterDescriptor->PinDescriptorsCount;
+
}
if (FilterDescriptor->NodeDescriptorsCount)
@@ -991,7 +1019,7 @@
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);
@@ -1029,7 +1057,7 @@
}
/* release control mutex */
- KeReleaseMutex(&This->Header.ControlMutex, FALSE);
+ KeReleaseMutex(This->Header.ControlMutex, FALSE);
if (Status != STATUS_PENDING)
{
@@ -1175,6 +1203,8 @@
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;
@@ -1202,7 +1232,8 @@
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);
@@ -1224,8 +1255,9 @@
if (Factory->FilterDescriptor->Dispatch->Create)
{
/* now let driver initialize the filter instance */
- DPRINT("Before instantiating filter Filter %p This %p KSBASIC_HEADER
%u\n", &This->Filter, This, sizeof(KSBASIC_HEADER));
+
ASSERT(This->Header.KsDevice);
+ ASSERT(This->Header.KsDevice->Started);
Status =
Factory->FilterDescriptor->Dispatch->Create(&This->Filter, Irp);
if (!NT_SUCCESS(Status) && Status != STATUS_PENDING)
@@ -1432,6 +1464,17 @@
RtlMoveMemory(&This->PinDescriptorsEx[This->PinDescriptorCount],
InPinDescriptor, sizeof(KSPIN_DESCRIPTOR_EX));
RtlMoveMemory(&This->PinDescriptors[This->PinDescriptorCount],
&InPinDescriptor->PinDescriptor, sizeof(KSPIN_DESCRIPTOR));
+
+ /* allocate process pin index */
+ Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex,
sizeof(KSPROCESSPIN_INDEXENTRY) * Count,
+ sizeof(KSPROCESSPIN_INDEXENTRY) * This->PinDescriptorCount, 0);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("KsFilterCreatePinFactory _KsEdit failed %lx\n", Status);
+ return Status;
+ }
+
/* store new pin id */
*PinID = This->PinDescriptorCount;
Modified: trunk/reactos/drivers/ksfilter/ks/filterfactory.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/filter…
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/filterfactory.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/filterfactory.c [iso-8859-1] Fri Apr 2 18:38:48
2010
@@ -21,6 +21,8 @@
PFNKSFILTERFACTORYPOWER WakeCallback;
LIST_ENTRY SymbolicLinkList;
+ KMUTEX ControlMutex;
+
}IKsFilterFactoryImpl;
VOID
@@ -225,16 +227,15 @@
This->Header.Parent.KsDevice =
&DeviceExtension->DeviceHeader->KsDevice;
This->DeviceHeader = DeviceExtension->DeviceHeader;
+ /* initialize filter factory control mutex */
+ This->Header.ControlMutex = &This->ControlMutex;
+ KeInitializeMutex(This->Header.ControlMutex, 0);
+
/* unused fields */
- KeInitializeMutex(&This->Header.ControlMutex, 0);
InitializeListHead(&This->Header.EventList);
KeInitializeSpinLock(&This->Header.EventListLock);
-
InitializeListHead(&This->SymbolicLinkList);
-
- /* initialize filter factory control mutex */
- KeInitializeMutex(&This->Header.ControlMutex, 0);
/* does the device use a reference string */
if (RefString || !Descriptor->ReferenceGuid)
Modified: trunk/reactos/drivers/ksfilter/ks/kstypes.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/kstype…
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/kstypes.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/kstypes.h [iso-8859-1] Fri Apr 2 18:38:48 2010
@@ -58,7 +58,7 @@
{
KSOBJECTTYPE Type;
PKSDEVICE KsDevice;
- KMUTEX ControlMutex;
+ PRKMUTEX ControlMutex;
LIST_ENTRY EventList;
KSPIN_LOCK EventListLock;
union
Modified: trunk/reactos/drivers/ksfilter/ks/pin.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/pin.c?…
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/pin.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/pin.c [iso-8859-1] Fri Apr 2 18:38:48 2010
@@ -29,8 +29,9 @@
LIST_ENTRY Entry;
IKsPinVtbl *lpVtbl;
-
LONG ref;
+
+ IKsFilter * Filter;
KMUTEX ProcessingMutex;
PFILE_OBJECT FileObject;
@@ -50,7 +51,354 @@
PFNKSPINFRAMERETURN FrameReturn;
PFNKSPINIRPCOMPLETION IrpCompletion;
+ KSCLOCK_FUNCTIONTABLE ClockTable;
+ PFILE_OBJECT ClockFileObject;
+ IKsReferenceClockVtbl * lpVtblReferenceClock;
+ PKSDEFAULTCLOCK DefaultClock;
+
}IKsPinImpl;
+
+NTSTATUS NTAPI IKsPin_PinStatePropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN
OUT PVOID Data);
+NTSTATUS NTAPI IKsPin_PinDataFormatPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request,
IN OUT PVOID Data);
+NTSTATUS NTAPI IKsPin_PinAllocatorFramingPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER
Request, IN OUT PVOID Data);
+NTSTATUS NTAPI IKsPin_PinStreamAllocator(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT
PVOID Data);
+NTSTATUS NTAPI IKsPin_PinMasterClock(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID
Data);
+NTSTATUS NTAPI IKsPin_PinPipeId(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID
Data);
+
+
+
+DEFINE_KSPROPERTY_CONNECTIONSET(PinConnectionSet, IKsPin_PinStatePropertyHandler,
IKsPin_PinDataFormatPropertyHandler, IKsPin_PinAllocatorFramingPropertyHandler);
+DEFINE_KSPROPERTY_STREAMSET(PinStreamSet, IKsPin_PinStreamAllocator,
IKsPin_PinMasterClock, IKsPin_PinPipeId);
+
+//TODO
+// KSPROPSETID_Connection
+// KSPROPERTY_CONNECTION_ACQUIREORDERING
+// KSPROPSETID_StreamInterface
+// KSPROPERTY_STREAMINTERFACE_HEADERSIZE
+
+KSPROPERTY_SET PinPropertySet[] =
+{
+ {
+ &KSPROPSETID_Connection,
+ sizeof(PinConnectionSet) / sizeof(KSPROPERTY_ITEM),
+ (const KSPROPERTY_ITEM*)&PinConnectionSet,
+ 0,
+ NULL
+ },
+ {
+ &KSPROPSETID_Stream,
+ sizeof(PinStreamSet) / sizeof(KSPROPERTY_ITEM),
+ (const KSPROPERTY_ITEM*)&PinStreamSet,
+ 0,
+ NULL
+ }
+};
+
+const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5,
0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
+const GUID KSPROPSETID_Stream = {0x65aaba60L, 0x98ae, 0x11cf, {0xa1,
0x0d, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4}};
+const GUID KSPROPSETID_Clock = {0xDF12A4C0L, 0xAC17, 0x11CF, {0xA5,
0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
+
+NTSTATUS
+NTAPI
+IKsPin_PinStreamAllocator(
+ IN PIRP Irp,
+ IN PKSIDENTIFIER Request,
+ IN OUT PVOID Data)
+{
+ UNIMPLEMENTED
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+NTAPI
+IKsPin_PinMasterClock(
+ IN PIRP Irp,
+ IN PKSIDENTIFIER Request,
+ IN OUT PVOID Data)
+{
+ PIO_STACK_LOCATION IoStack;
+ PKSIOBJECT_HEADER ObjectHeader;
+ IKsPinImpl * This;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PHANDLE Handle;
+ PFILE_OBJECT FileObject;
+ KPROCESSOR_MODE Mode;
+ KSPROPERTY Property;
+ ULONG BytesReturned;
+
+ /* get current irp stack */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ DPRINT("IKsPin_PinMasterClock\n");
+
+ /* sanity check */
+ ASSERT(IoStack->FileObject);
+ ASSERT(IoStack->FileObject->FsContext2);
+
+ /* get the object header */
+ ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
+
+ /* locate ks pin implemention from KSPIN offset */
+ This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin);
+
+ /* acquire control mutex */
+ KeWaitForSingleObject(This->BasicHeader.ControlMutex, Executive, KernelMode,
FALSE, NULL);
+
+ Handle = (PHANDLE)Data;
+
+ if (Request->Flags & KSPROPERTY_TYPE_GET)
+ {
+ if (This->Pin.Descriptor->PinDescriptor.Communication !=
KSPIN_COMMUNICATION_NONE &&
+ This->Pin.Descriptor->Dispatch &&
+ (This->Pin.Descriptor->Flags & KSPIN_FLAG_IMPLEMENT_CLOCK))
+ {
+ *Handle = NULL;
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ /* no clock available */
+ Status = STATUS_UNSUCCESSFUL;
+ }
+ }
+ else if (Request->Flags & KSPROPERTY_TYPE_SET)
+ {
+ if (This->Pin.ClientState != KSSTATE_STOP)
+ {
+ /* can only set in stopped state */
+ Status = STATUS_INVALID_DEVICE_STATE;
+ }
+ else
+ {
+ if (*Handle)
+ {
+ Mode = ExGetPreviousMode();
+
+ Status = ObReferenceObjectByHandle(*Handle, SYNCHRONIZE |
DIRECTORY_QUERY, IoFileObjectType, Mode, (PVOID*)&FileObject, NULL);
+
+ DPRINT("IKsPin_PinMasterClock ObReferenceObjectByHandle %lx\n",
Status);
+ if (NT_SUCCESS(Status))
+ {
+ Property.Set = KSPROPSETID_Clock;
+ Property.Id = KSPROPERTY_CLOCK_FUNCTIONTABLE;
+ Property.Flags = KSPROPERTY_TYPE_GET;
+
+ Status = KsSynchronousIoControlDevice(FileObject, KernelMode,
IOCTL_KS_PROPERTY, &Property, sizeof(KSPROPERTY), &This->ClockTable,
sizeof(KSCLOCK_FUNCTIONTABLE), &BytesReturned);
+
+ DPRINT("IKsPin_PinMasterClock KSPROPERTY_CLOCK_FUNCTIONTABLE
%lx\n", Status);
+
+ if (NT_SUCCESS(Status))
+ {
+ This->ClockFileObject = FileObject;
+ }
+ else
+ {
+ ObDereferenceObject(FileObject);
+ }
+ }
+ }
+ else
+ {
+ /* zeroing clock handle */
+ RtlZeroMemory(&This->ClockTable, sizeof(KSCLOCK_FUNCTIONTABLE));
+ Status = STATUS_SUCCESS;
+ if (This->ClockFileObject)
+ {
+ FileObject = This->ClockFileObject;
+ This->ClockFileObject = NULL;
+
+ ObDereferenceObject(This->ClockFileObject);
+ }
+ }
+ }
+ }
+
+ /* release processing mutex */
+ KeReleaseMutex(This->BasicHeader.ControlMutex, FALSE);
+
+ DPRINT("IKsPin_PinStatePropertyHandler Status %lx\n", Status);
+ return Status;
+}
+
+
+
+NTSTATUS
+NTAPI
+IKsPin_PinPipeId(
+ IN PIRP Irp,
+ IN PKSIDENTIFIER Request,
+ IN OUT PVOID Data)
+{
+ UNIMPLEMENTED
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+
+NTSTATUS
+NTAPI
+IKsPin_PinStatePropertyHandler(
+ IN PIRP Irp,
+ IN PKSIDENTIFIER Request,
+ IN OUT PVOID Data)
+{
+ PIO_STACK_LOCATION IoStack;
+ PKSIOBJECT_HEADER ObjectHeader;
+ IKsPinImpl * This;
+ NTSTATUS Status = STATUS_SUCCESS;
+ KSSTATE OldState;
+ PKSSTATE NewState;
+
+ /* get current irp stack */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ DPRINT("IKsPin_PinStatePropertyHandler\n");
+
+ /* sanity check */
+ ASSERT(IoStack->FileObject);
+ ASSERT(IoStack->FileObject->FsContext2);
+
+ /* get the object header */
+ ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
+
+ /* locate ks pin implemention from KSPIN offset */
+ This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin);
+
+ /* acquire control mutex */
+ KeWaitForSingleObject(This->BasicHeader.ControlMutex, Executive, KernelMode,
FALSE, NULL);
+
+ /* grab state */
+ NewState = (PKSSTATE)Data;
+
+ if (Request->Flags & KSPROPERTY_TYPE_GET)
+ {
+ *NewState = This->Pin.DeviceState;
+ Irp->IoStatus.Information = sizeof(KSSTATE);
+ }
+ else if (Request->Flags & KSPROPERTY_TYPE_SET)
+ {
+ if (This->Pin.Descriptor->Dispatch->SetDeviceState)
+ {
+ /* backup old state */
+ OldState = This->Pin.ClientState;
+
+ /* set new state */
+ This->Pin.ClientState = *NewState;
+
+ /* check if it supported */
+ Status =
This->Pin.Descriptor->Dispatch->SetDeviceState(&This->Pin, *NewState,
OldState);
+
+ DPRINT("IKsPin_PinStatePropertyHandler NewState %lu Result %lx\n",
*NewState, Status);
+
+ if (!NT_SUCCESS(Status))
+ {
+ /* revert to old state */
+ This->Pin.ClientState = OldState;
+ DbgBreakPoint();
+ }
+ else
+ {
+ /* update device state */
+ This->Pin.DeviceState = *NewState;
+ }
+ }
+ else
+ {
+ /* just set new state */
+ This->Pin.DeviceState = *NewState;
+ This->Pin.ClientState = *NewState;
+ }
+ }
+
+ /* release processing mutex */
+ KeReleaseMutex(This->BasicHeader.ControlMutex, FALSE);
+
+ DPRINT("IKsPin_PinStatePropertyHandler Status %lx\n", Status);
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+IKsPin_PinAllocatorFramingPropertyHandler(
+ IN PIRP Irp,
+ IN PKSIDENTIFIER Request,
+ IN OUT PVOID Data)
+{
+ UNIMPLEMENTED
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+NTAPI
+IKsPin_PinDataFormatPropertyHandler(
+ IN PIRP Irp,
+ IN PKSPROPERTY Request,
+ IN OUT PVOID Data)
+{
+ PIO_STACK_LOCATION IoStack;
+ PKSIOBJECT_HEADER ObjectHeader;
+ IKsPinImpl * This;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ /* get current irp stack */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ DPRINT("IKsPin_PinDataFormatPropertyHandler\n");
+
+ /* sanity check */
+ ASSERT(IoStack->FileObject);
+ ASSERT(IoStack->FileObject->FsContext2);
+
+ /* get the object header */
+ ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
+
+ /* locate ks pin implemention from KSPIN offset */
+ This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin);
+
+ /* acquire control mutex */
+ KeWaitForSingleObject(This->BasicHeader.ControlMutex, Executive, KernelMode,
FALSE, NULL);
+
+ if (Request->Flags & KSPROPERTY_TYPE_GET)
+ {
+ if (IoStack->Parameters.DeviceIoControl.OutputBufferLength <
This->Pin.ConnectionFormat->FormatSize)
+ {
+ /* buffer too small */
+ Irp->IoStatus.Information = This->Pin.ConnectionFormat->FormatSize;
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ /* copy format */
+ RtlMoveMemory(Data, This->Pin.ConnectionFormat,
This->Pin.ConnectionFormat->FormatSize);
+ }
+ }
+ else if (Request->Flags & KSPROPERTY_TYPE_SET)
+ {
+ /* set format */
+ if (This->Pin.Descriptor->Flags & KSPIN_FLAG_FIXED_FORMAT)
+ {
+ /* format cannot be changed */
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ }
+ else
+ {
+ /* FIXME check if the format is supported */
+ Status = _KsEdit(This->Pin.Bag,
(PVOID*)&This->Pin.ConnectionFormat,
IoStack->Parameters.DeviceIoControl.OutputBufferLength,
This->Pin.ConnectionFormat->FormatSize, 0);
+
+ if (NT_SUCCESS(Status))
+ {
+ /* store new format */
+ RtlMoveMemory(This->Pin.ConnectionFormat, Data,
IoStack->Parameters.DeviceIoControl.OutputBufferLength);
+ }
+ }
+ }
+
+ /* release processing mutex */
+ KeReleaseMutex(This->BasicHeader.ControlMutex, FALSE);
+
+ DPRINT("IKsPin_PinDataFormatPropertyHandler Status %lx\n", Status);
+
+ return Status;
+}
NTSTATUS
NTAPI
@@ -67,6 +415,7 @@
_InterlockedIncrement(&This->ref);
return STATUS_SUCCESS;
}
+ DbgBreakPoint();
return STATUS_UNSUCCESSFUL;
}
@@ -270,6 +619,209 @@
//==============================================================
+NTSTATUS
+NTAPI
+IKsReferenceClock_fnQueryInterface(
+ IKsReferenceClock * iface,
+ IN REFIID refiid,
+ OUT PVOID* Output)
+{
+ IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl,
lpVtblReferenceClock);
+
+ return IKsPin_fnQueryInterface((IKsPin*)&This->lpVtbl, refiid, Output);
+}
+
+ULONG
+NTAPI
+IKsReferenceClock_fnAddRef(
+ IKsReferenceClock * iface)
+{
+ IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl,
lpVtblReferenceClock);
+
+ return IKsPin_fnAddRef((IKsPin*)&This->lpVtbl);
+}
+
+ULONG
+NTAPI
+IKsReferenceClock_fnRelease(
+ IKsReferenceClock * iface)
+{
+ IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl,
lpVtblReferenceClock);
+
+ return IKsPin_fnRelease((IKsPin*)&This->lpVtbl);
+}
+
+LONGLONG
+NTAPI
+IKsReferenceClock_fnGetTime(
+ IKsReferenceClock * iface)
+{
+ LONGLONG Result;
+
+ IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl,
lpVtblReferenceClock);
+
+ if (!This->ClockFileObject || !This->ClockTable.GetTime)
+ {
+ Result = 0;
+ }
+ else
+ {
+ Result = This->ClockTable.GetTime(This->ClockFileObject);
+ }
+
+ return Result;
+}
+
+LONGLONG
+NTAPI
+IKsReferenceClock_fnGetPhysicalTime(
+ IKsReferenceClock * iface)
+{
+ LONGLONG Result;
+
+ IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl,
lpVtblReferenceClock);
+
+ if (!This->ClockFileObject || !This->ClockTable.GetPhysicalTime)
+ {
+ Result = 0;
+ }
+ else
+ {
+ Result = This->ClockTable.GetPhysicalTime(This->ClockFileObject);
+ }
+
+ return Result;
+}
+
+
+LONGLONG
+NTAPI
+IKsReferenceClock_fnGetCorrelatedTime(
+ IKsReferenceClock * iface,
+ OUT PLONGLONG SystemTime)
+{
+ LONGLONG Result;
+
+ IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl,
lpVtblReferenceClock);
+
+ if (!This->ClockFileObject || !This->ClockTable.GetCorrelatedTime)
+ {
+ Result = 0;
+ }
+ else
+ {
+ Result = This->ClockTable.GetCorrelatedTime(This->ClockFileObject,
SystemTime);
+ }
+
+ return Result;
+}
+
+
+LONGLONG
+NTAPI
+IKsReferenceClock_fnGetCorrelatedPhysicalTime(
+ IKsReferenceClock * iface,
+ OUT PLONGLONG SystemTime)
+{
+ LONGLONG Result;
+
+ IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl,
lpVtblReferenceClock);
+
+ if (!This->ClockFileObject || !This->ClockTable.GetCorrelatedPhysicalTime)
+ {
+ Result = 0;
+ }
+ else
+ {
+ Result = This->ClockTable.GetCorrelatedPhysicalTime(This->ClockFileObject,
SystemTime);
+ }
+
+ return Result;
+}
+
+NTSTATUS
+NTAPI
+IKsReferenceClock_fnGetResolution(
+ IKsReferenceClock * iface,
+ OUT PKSRESOLUTION Resolution)
+{
+ KSPROPERTY Property;
+ ULONG BytesReturned;
+
+ IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl,
lpVtblReferenceClock);
+
+ DPRINT1("IKsReferenceClock_fnGetResolution\n");
+
+ if (!This->ClockFileObject)
+ {
+ Resolution->Error = 0;
+ Resolution->Granularity = 1;
+ DPRINT1("IKsReferenceClock_fnGetResolution Using HACK\n");
+ return STATUS_SUCCESS;
+ }
+
+
+ if (!This->ClockFileObject)
+ return STATUS_DEVICE_NOT_READY;
+
+
+ Property.Set = KSPROPSETID_Clock;
+ Property.Id = KSPROPERTY_CLOCK_RESOLUTION;
+ Property.Flags = KSPROPERTY_TYPE_GET;
+
+ return KsSynchronousIoControlDevice(This->ClockFileObject, KernelMode,
IOCTL_KS_PROPERTY, &Property, sizeof(KSPROPERTY), Resolution, sizeof(KSRESOLUTION),
&BytesReturned);
+
+}
+
+NTSTATUS
+NTAPI
+IKsReferenceClock_fnGetState(
+ IKsReferenceClock * iface,
+ OUT PKSSTATE State)
+{
+ KSPROPERTY Property;
+ ULONG BytesReturned;
+
+ IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl,
lpVtblReferenceClock);
+
+ DPRINT1("IKsReferenceClock_fnGetState\n");
+
+ if (!This->ClockFileObject)
+ {
+ *State = This->Pin.ClientState;
+ DPRINT1("IKsReferenceClock_fnGetState Using HACK\n");
+ return STATUS_SUCCESS;
+ }
+
+
+ if (!This->ClockFileObject)
+ return STATUS_DEVICE_NOT_READY;
+
+
+ Property.Set = KSPROPSETID_Clock;
+ Property.Id = KSPROPERTY_CLOCK_RESOLUTION;
+ Property.Flags = KSPROPERTY_TYPE_GET;
+
+ return KsSynchronousIoControlDevice(This->ClockFileObject, KernelMode,
IOCTL_KS_PROPERTY, &Property, sizeof(KSPROPERTY), State, sizeof(KSSTATE),
&BytesReturned);
+}
+
+static IKsReferenceClockVtbl vt_ReferenceClock =
+{
+ IKsReferenceClock_fnQueryInterface,
+ IKsReferenceClock_fnAddRef,
+ IKsReferenceClock_fnRelease,
+ IKsReferenceClock_fnGetTime,
+ IKsReferenceClock_fnGetPhysicalTime,
+ IKsReferenceClock_fnGetCorrelatedTime,
+ IKsReferenceClock_fnGetCorrelatedPhysicalTime,
+ IKsReferenceClock_fnGetResolution,
+ IKsReferenceClock_fnGetState
+};
+
+
+//==============================================================
+
+
/*
@implemented
*/
@@ -340,6 +892,7 @@
IN BOOLEAN Asynchronous)
{
DPRINT("KsPinAttemptProcessing\n");
+DbgBreakPoint();
UNIMPLEMENTED
}
@@ -448,7 +1001,7 @@
}
/*
- @unimplemented
+ @implemented
*/
NTSTATUS
NTAPI
@@ -456,9 +1009,22 @@
IN PKSPIN Pin,
OUT PIKSREFERENCECLOCK* Interface)
{
- UNIMPLEMENTED
- DPRINT("KsPinGetReferenceClockInterface Pin %p Interface %p\n", Pin,
Interface);
- return STATUS_UNSUCCESSFUL;
+ NTSTATUS Status = STATUS_DEVICE_NOT_READY;
+ IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
+
+ if (This->ClockFileObject)
+ {
+ /* clock is available */
+ *Interface = (PIKSREFERENCECLOCK)&This->lpVtblReferenceClock;
+ Status = STATUS_SUCCESS;
+ }
+//HACK
+ *Interface = (PIKSREFERENCECLOCK)&This->lpVtblReferenceClock;
+ Status = STATUS_SUCCESS;
+
+ DPRINT("KsPinGetReferenceClockInterface Pin %p Interface %p Status %x\n",
Pin, Interface, Status);
+
+ return Status;
}
/*
@@ -547,15 +1113,26 @@
IN PIRP Irp)
{
PKSIOBJECT_HEADER ObjectHeader;
+ PKSPIN Pin;
+ PKSBASIC_HEADER Header;
PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
DPRINT("KsGetPinFromIrp\n");
/* get object header */
ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
+
+ if (!ObjectHeader)
+ return NULL;
+
+ Pin = (PKSPIN)ObjectHeader->ObjectType;
+ Header = (PKSBASIC_HEADER)((ULONG_PTR)Pin - sizeof(KSBASIC_HEADER));
+
+ /* sanity check */
+ ASSERT(Header->Type == KsObjectTypePin);
+
/* return object type */
- return (PKSPIN)ObjectHeader->ObjectType;
-
+ return Pin;
}
@@ -629,6 +1206,7 @@
{
UNIMPLEMENTED
DPRINT("KsPinGetLeadingEdgeStreamPointer Pin %p State %x\n", Pin, State);
+DbgBreakPoint();
return NULL;
}
@@ -685,6 +1263,7 @@
{
UNIMPLEMENTED
DPRINT("KsStreamPointerUnlock\n");
+DbgBreakPoint();
}
/*
@@ -700,7 +1279,7 @@
IN BOOLEAN Eject)
{
DPRINT("KsStreamPointerAdvanceOffsets\n");
-
+DbgBreakPoint();
UNIMPLEMENTED
}
@@ -718,7 +1297,7 @@
PKSISTREAM_POINTER Pointer = (PKSISTREAM_POINTER)StreamPointer;
DPRINT("KsStreamPointerDelete\n");
-
+DbgBreakPoint();
This = (IKsPinImpl*)CONTAINING_RECORD(Pointer->StreamPointer.Pin, IKsPinImpl,
Pin);
/* point to first stream pointer */
@@ -766,6 +1345,7 @@
{
UNIMPLEMENTED
DPRINT("KsStreamPointerClone\n");
+DbgBreakPoint();
return STATUS_NOT_IMPLEMENTED;
}
@@ -878,7 +1458,7 @@
IKsPinImpl * This;
DPRINT("KsPinGetFirstCloneStreamPointer %p\n", Pin);
-
+DbgBreakPoint();
This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
/* return first cloned stream pointer */
return &This->ClonedStreamPointer->StreamPointer;
@@ -896,7 +1476,7 @@
PKSISTREAM_POINTER Pointer = (PKSISTREAM_POINTER)StreamPointer;
DPRINT("KsStreamPointerGetNextClone\n");
-
+DbgBreakPoint();
/* is there a another cloned stream pointer */
if (!Pointer->Next)
return NULL;
@@ -904,6 +1484,64 @@
/* return next stream pointer */
return &Pointer->Next->StreamPointer;
}
+NTSTATUS
+IKsPin_DispatchKsStream(
+ PDEVICE_OBJECT DeviceObject,
+ PIRP Irp,
+ IKsPinImpl * This)
+{
+ PKSPROCESSPIN_INDEXENTRY ProcessPinIndex;
+ PKSFILTER Filter;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ DPRINT("IKsPin_DispatchKsStream\n");
+
+ /* FIXME handle reset states */
+ ASSERT(This->Pin.ResetState == KSRESET_END);
+
+ /* mark irp as pending */
+ IoMarkIrpPending(Irp);
+
+ /* add irp to cancelable queue */
+ KsAddIrpToCancelableQueue(&This->IrpList, &This->IrpListLock, Irp,
KsListEntryTail, NULL /* FIXME */);
+
+ if (This->Pin.Descriptor->Dispatch->Process)
+ {
+ /* it is a pin centric avstream */
+ ASSERT(0);
+ //Status = This->Pin.Descriptor->Dispatch->Process(&This->Pin);
+ /* TODO */
+ }
+ else
+ {
+ /* filter-centric avstream */
+ ASSERT(This->Filter);
+
+ ProcessPinIndex =
This->Filter->lpVtbl->GetProcessDispatch(This->Filter);
+ Filter = This->Filter->lpVtbl->GetStruct(This->Filter);
+
+ ASSERT(ProcessPinIndex);
+ ASSERT(Filter);
+ ASSERT(Filter->Descriptor);
+ ASSERT(Filter->Descriptor->Dispatch);
+
+ if (!Filter->Descriptor->Dispatch->Process)
+ {
+ /* invalid device request */
+ DPRINT("Filter Centric Processing No Process Routine\n");
+ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ Status = Filter->Descriptor->Dispatch->Process(Filter,
ProcessPinIndex);
+
+ DPRINT("IKsPin_DispatchKsStream FilterCentric: Status %lx \n",
Status);
+ }
+
+ return Status;
+}
+
NTSTATUS
IKsPin_DispatchKsProperty(
@@ -940,8 +1578,6 @@
PropertySets,
NULL,
PropertyItemSize);
-
- DPRINT("IKsPin_DispatchKsProperty PropertySetCount %lu Status %lu\n",
PropertySetsCount, Status);
if (Status != STATUS_NOT_FOUND)
{
@@ -954,6 +1590,24 @@
return Status;
}
+ /* try our properties */
+ Status = KspPropertyHandler(Irp,
+ sizeof(PinPropertySet) / sizeof(KSPROPERTY_SET),
+ PinPropertySet,
+ NULL,
+ 0);
+
+ if (Status != STATUS_NOT_FOUND)
+ {
+ /* property was handled by driver */
+ if (Status != STATUS_PENDING)
+ {
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ }
+ return Status;
+ }
+
/* property was not handled */
Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
@@ -971,6 +1625,48 @@
NTSTATUS
NTAPI
IKsPin_DispatchDeviceIoControl(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION IoStack;
+ PKSIOBJECT_HEADER ObjectHeader;
+ IKsPinImpl * This;
+
+ /* get current irp stack */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ /* sanity check */
+ ASSERT(IoStack->FileObject);
+ ASSERT(IoStack->FileObject->FsContext2);
+
+ /* get the object header */
+ ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
+
+ /* locate ks pin implemention from KSPIN offset */
+ This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin);
+
+ if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY)
+ {
+ /* handle ks properties */
+ return IKsPin_DispatchKsProperty(DeviceObject, Irp, This);
+ }
+
+ if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM ||
+ IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_READ_STREAM)
+ {
+ /* handle ks properties */
+ return IKsPin_DispatchKsStream(DeviceObject, Irp, This);
+ }
+
+ UNIMPLEMENTED;
+ Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+NTAPI
+IKsPin_Close(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
@@ -989,75 +1685,11 @@
/* get the object header */
ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
- /* locate ks pin implemention from KSPIN offset */
- This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin);
-
- if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY)
- {
- /* handle ks properties */
- return IKsPin_DispatchKsProperty(DeviceObject, Irp, This);
- }
-
-
- if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_WRITE_STREAM
&& IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_READ_STREAM)
- {
- UNIMPLEMENTED;
- Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_NOT_IMPLEMENTED;
- }
-
- /* mark irp as pending */
- IoMarkIrpPending(Irp);
-
- /* add irp to cancelable queue */
- KsAddIrpToCancelableQueue(&This->IrpList, &This->IrpListLock, Irp,
KsListEntryTail, NULL /* FIXME */);
-
- if (This->Pin.Descriptor->Dispatch->Process)
- {
- /* it is a pin centric avstream */
- Status = This->Pin.Descriptor->Dispatch->Process(&This->Pin);
-
- /* TODO */
- }
- else
- {
- /* TODO
- * filter-centric avstream
- */
- UNIMPLEMENTED
- }
-
- return Status;
-}
-
-NTSTATUS
-NTAPI
-IKsPin_Close(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- PIO_STACK_LOCATION IoStack;
- PKSIOBJECT_HEADER ObjectHeader;
- IKsPinImpl * This;
- NTSTATUS Status = STATUS_SUCCESS;
-
- /* get current irp stack */
- IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- /* sanity check */
- ASSERT(IoStack->FileObject);
- ASSERT(IoStack->FileObject->FsContext2);
-
- /* get the object header */
- ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
-
/* locate ks pin implemention fro KSPIN offset */
This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin);
/* acquire filter control mutex */
- KsFilterAcquireControl(This->BasicHeader.Parent.KsFilter);
+ KsFilterAcquireControl(&This->Pin);
if (This->Pin.Descriptor->Dispatch->Close)
{
@@ -1082,6 +1714,9 @@
}
}
+ /* release filter control mutex */
+ KsFilterReleaseControl(&This->Pin);
+
return Status;
}
@@ -1104,11 +1739,80 @@
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
- UNIMPLEMENTED;
-
- Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+ PKSPIN Pin;
+ NTSTATUS Status = STATUS_SUCCESS;
+ IKsPinImpl * This;
+ KSRESOLUTION Resolution;
+ PKSRESOLUTION pResolution = NULL;
+ PKSOBJECT_CREATE_ITEM CreateItem;
+
+ DPRINT("IKsPin_DispatchCreateClock\n");
+
+ /* get the create item */
+ CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
+
+ /* sanity check */
+ ASSERT(CreateItem);
+
+ /* get the pin object */
+ Pin = (PKSPIN)CreateItem->Context;
+
+ /* sanity check */
+ ASSERT(Pin);
+
+ /* locate ks pin implemention fro KSPIN offset */
+ This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
+
+ /* sanity check */
+ ASSERT(This->BasicHeader.Type == KsObjectTypePin);
+ ASSERT(This->BasicHeader.ControlMutex);
+
+ /* acquire control mutex */
+ KsAcquireControl(Pin);
+
+ if ((This->Pin.Descriptor->PinDescriptor.Communication !=
KSPIN_COMMUNICATION_NONE &&
+ This->Pin.Descriptor->Dispatch) ||
+ (This->Pin.Descriptor->Flags & KSPIN_FLAG_IMPLEMENT_CLOCK))
+ {
+ if (!This->DefaultClock)
+ {
+ if (This->Pin.Descriptor->Dispatch &&
This->Pin.Descriptor->Dispatch->Clock)
+ {
+ if (This->Pin.Descriptor->Dispatch->Clock->Resolution)
+ {
+
This->Pin.Descriptor->Dispatch->Clock->Resolution(&This->Pin,
&Resolution);
+ pResolution = &Resolution;
+ }
+
+ Status = KsAllocateDefaultClockEx(&This->DefaultClock,
+ (PVOID)&This->Pin,
+
(PFNKSSETTIMER)This->Pin.Descriptor->Dispatch->Clock->SetTimer,
+
(PFNKSCANCELTIMER)This->Pin.Descriptor->Dispatch->Clock->CancelTimer,
+
(PFNKSCORRELATEDTIME)This->Pin.Descriptor->Dispatch->Clock->CorrelatedTime,
+ pResolution,
+ 0);
+ }
+ else
+ {
+ Status = KsAllocateDefaultClockEx(&This->DefaultClock,
(PVOID)&This->Pin, NULL, NULL, NULL, NULL, 0);
+ }
+ }
+
+ if (NT_SUCCESS(Status))
+ {
+ Status = KsCreateDefaultClock(Irp, This->DefaultClock);
+ }
+ }
+
+ DPRINT("IKsPin_DispatchCreateClock %lx\n", Status);
+
+ /* release control mutex */
+ KsReleaseControl(Pin);
+
+ /* done */
+ Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_NOT_IMPLEMENTED;
+ return Status;
}
NTSTATUS
@@ -1141,7 +1845,7 @@
NTSTATUS
KspCreatePin(
IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
+ IN PIRP Irp,
IN PKSDEVICE KsDevice,
IN IKsFilterFactory * FilterFactory,
IN IKsFilter* Filter,
@@ -1155,11 +1859,15 @@
PKSOBJECT_CREATE_ITEM CreateItem;
NTSTATUS Status;
PKSDATAFORMAT DataFormat;
+ PKSBASIC_HEADER BasicHeader;
/* sanity checks */
ASSERT(Descriptor->Dispatch);
- DPRINT("KspCreatePin\n");
+ DPRINT("KspCreatePin PinId %lu Flags %x\n", Connect->PinId,
Descriptor->Flags);
+
+//Output Pin: KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY
+//Input Pin:
KSPIN_FLAG_FIXED_FORMAT|KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT|KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING
/* get current irp stack */
IoStack = IoGetCurrentIrpStackLocation(Irp);
@@ -1192,14 +1900,24 @@
This->BasicHeader.KsDevice = KsDevice;
This->BasicHeader.Type = KsObjectTypePin;
This->BasicHeader.Parent.KsFilter = Filter->lpVtbl->GetStruct(Filter);
- KeInitializeMutex(&This->BasicHeader.ControlMutex, 0);
+
+ ASSERT(This->BasicHeader.Parent.KsFilter);
+
+ BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)This->BasicHeader.Parent.KsFilter -
sizeof(KSBASIC_HEADER));
+
+ This->BasicHeader.ControlMutex = BasicHeader->ControlMutex;
+ ASSERT(This->BasicHeader.ControlMutex);
+
+
InitializeListHead(&This->BasicHeader.EventList);
KeInitializeSpinLock(&This->BasicHeader.EventListLock);
/* initialize pin */
This->lpVtbl = &vt_IKsPin;
+ This->lpVtblReferenceClock = &vt_ReferenceClock;
This->ref = 1;
This->FileObject = IoStack->FileObject;
+ This->Filter = Filter;
KeInitializeMutex(&This->ProcessingMutex, 0);
InitializeListHead(&This->IrpList);
KeInitializeSpinLock(&This->IrpListLock);
@@ -1216,12 +1934,12 @@
}
/* initialize object bag */
- Device->lpVtbl->InitializeObjectBag(Device, This->Pin.Bag,
&This->BasicHeader.ControlMutex); /* is using control mutex right? */
+ Device->lpVtbl->InitializeObjectBag(Device, This->Pin.Bag, NULL);
/* get format */
DataFormat = (PKSDATAFORMAT)(Connect + 1);
- /* initialize ks pin descriptor */
+ /* initialize pin descriptor */
This->Pin.Descriptor = Descriptor;
This->Pin.Context = NULL;
This->Pin.Id = Connect->PinId;
@@ -1253,19 +1971,19 @@
This->Pin.ClientState = KSSTATE_STOP;
/* intialize allocator create item */
- CreateItem[0].Context = (PVOID)This;
+ CreateItem[0].Context = (PVOID)&This->Pin;
CreateItem[0].Create = IKsPin_DispatchCreateAllocator;
CreateItem[0].Flags = KSCREATE_ITEM_FREEONSTOP;
RtlInitUnicodeString(&CreateItem[0].ObjectClass, KSSTRING_Allocator);
/* intialize clock create item */
- CreateItem[1].Context = (PVOID)This;
+ CreateItem[1].Context = (PVOID)&This->Pin;
CreateItem[1].Create = IKsPin_DispatchCreateClock;
CreateItem[1].Flags = KSCREATE_ITEM_FREEONSTOP;
RtlInitUnicodeString(&CreateItem[1].ObjectClass, KSSTRING_Clock);
/* intialize topology node create item */
- CreateItem[2].Context = (PVOID)This;
+ CreateItem[2].Context = (PVOID)&This->Pin;
CreateItem[2].Create = IKsPin_DispatchCreateNode;
CreateItem[2].Flags = KSCREATE_ITEM_FREEONSTOP;
RtlInitUnicodeString(&CreateItem[2].ObjectClass, KSSTRING_TopologyNode);
@@ -1289,15 +2007,21 @@
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
*/
+ This->ProcessPin.BytesAvailable = 0;
+ This->ProcessPin.BytesUsed = 0;
+ This->ProcessPin.CopySource = NULL;
+ This->ProcessPin.Data = NULL;
+ This->ProcessPin.DelegateBranch = NULL;
+ This->ProcessPin.Flags = 0;
+ This->ProcessPin.InPlaceCounterpart = NULL;
+ This->ProcessPin.Pin = &This->Pin;
+ This->ProcessPin.StreamPointer =
(PKSSTREAM_POINTER)This->LeadingEdgeStreamPointer;
+ This->ProcessPin.Terminate = FALSE;
Status = Filter->lpVtbl->AddProcessPin(Filter, &This->ProcessPin);
DPRINT("KspCreatePin AddProcessPin %lx\n", Status);
@@ -1307,7 +2031,8 @@
/* failed to add process pin */
KsFreeObjectBag((KSOBJECT_BAG)This->Pin.Bag);
KsFreeObjectHeader(&This->ObjectHeader);
-
+ FreeItem(This);
+ FreeItem(CreateItem);
/* return failure code */
return Status;
}
@@ -1315,6 +2040,15 @@
/* FIXME add pin instance to filter instance */
+
+ if (Descriptor->Dispatch && Descriptor->Dispatch->SetDataFormat)
+ {
+ Status = Descriptor->Dispatch->SetDataFormat(&This->Pin, NULL, NULL,
This->Pin.ConnectionFormat, NULL);
+ DPRINT("KspCreatePin SetDataFormat %lx\n", Status);
+ DbgBreakPoint();
+ }
+
+
/* does the driver have a pin dispatch */
if (Descriptor->Dispatch && Descriptor->Dispatch->Create)
{
@@ -1322,6 +2056,8 @@
Status = Descriptor->Dispatch->Create(&This->Pin, Irp);
DPRINT("KspCreatePin DispatchCreate %lx\n", Status);
}
+
+
DPRINT("KspCreatePin Status %lx\n", Status);
Modified: trunk/reactos/drivers/ksfilter/ks/priv.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/priv.h…
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/priv.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/priv.h [iso-8859-1] Fri Apr 2 18:38:48 2010
@@ -35,3 +35,24 @@
DEFINE_KSPROPERTY_ITEM_PIN_CONSTRAINEDDATARANGES(PropGeneral),\
DEFINE_KSPROPERTY_ITEM_PIN_PROPOSEDATAFORMAT(PropGeneral)\
}
+
+#define DEFINE_KSPROPERTY_CONNECTIONSET(PinSet,\
+ PropStateHandler, PropDataFormatHandler, PropAllocatorFraming)\
+DEFINE_KSPROPERTY_TABLE(PinSet) {\
+ DEFINE_KSPROPERTY_ITEM_CONNECTION_STATE(PropStateHandler, PropStateHandler),\
+ DEFINE_KSPROPERTY_ITEM_CONNECTION_DATAFORMAT(PropDataFormatHandler,
PropDataFormatHandler),\
+ DEFINE_KSPROPERTY_ITEM_CONNECTION_ALLOCATORFRAMING(PropAllocatorFraming)\
+}
+
+
+#define DEFINE_KSPROPERTY_STREAMSET(PinSet,\
+ PropStreamAllocator, PropMasterClock, PropPipeId)\
+DEFINE_KSPROPERTY_TABLE(PinSet) {\
+ DEFINE_KSPROPERTY_ITEM_STREAM_ALLOCATOR(PropStreamAllocator, PropStreamAllocator),\
+ DEFINE_KSPROPERTY_ITEM_STREAM_MASTERCLOCK(PropMasterClock, PropMasterClock),\
+ DEFINE_KSPROPERTY_ITEM_STREAM_PIPE_ID(PropPipeId, PropPipeId)\
+}
+
+
+
+
Modified: trunk/reactos/drivers/ksfilter/ks/property.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/proper…
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/property.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/property.c [iso-8859-1] Fri Apr 2 18:38:48 2010
@@ -137,7 +137,7 @@
/* get input property request */
Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
- DPRINT("KspPropertyHandler Irp %p PropertySetsCount %u PropertySet %p Allocator
%p PropertyItemSize %u ExpectedPropertyItemSize %u\n", Irp, PropertySetsCount,
PropertySet, Allocator, PropertyItemSize, sizeof(KSPROPERTY_ITEM));
+// DPRINT("KspPropertyHandler Irp %p PropertySetsCount %u PropertySet %p
Allocator %p PropertyItemSize %u ExpectedPropertyItemSize %u\n", Irp,
PropertySetsCount, PropertySet, Allocator, PropertyItemSize, sizeof(KSPROPERTY_ITEM));
/* sanity check */
ASSERT(PropertyItemSize == 0 || PropertyItemSize == sizeof(KSPROPERTY_ITEM));