2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/ksfilter/ks/worker.c
5 * PURPOSE: KS pin functions
6 * PROGRAMMER: Johannes Anderwald
12 typedef struct _KSISTREAM_POINTER
14 PFNKSSTREAMPOINTER Callback
;
18 struct _KSISTREAM_POINTER
*Next
;
23 KSSTREAM_POINTER StreamPointer
;
25 }KSISTREAM_POINTER
, *PKSISTREAM_POINTER
;
29 KSBASIC_HEADER BasicHeader
;
31 PKSIOBJECT_HEADER ObjectHeader
;
32 KSPROCESSPIN ProcessPin
;
39 KMUTEX ProcessingMutex
;
40 PFILE_OBJECT FileObject
;
46 KSPIN_LOCK IrpListLock
;
47 volatile LONG IrpCount
;
49 PKSISTREAM_POINTER ClonedStreamPointer
;
50 KSISTREAM_POINTER LeadingEdgeStreamPointer
;
51 KSISTREAM_POINTER TrailingStreamPointer
;
55 PFNKSPINHANDSHAKE Handshake
;
56 PFNKSPINFRAMERETURN FrameReturn
;
57 PFNKSPINIRPCOMPLETION IrpCompletion
;
59 KSCLOCK_FUNCTIONTABLE ClockTable
;
60 PFILE_OBJECT ClockFileObject
;
61 IKsReferenceClockVtbl
* lpVtblReferenceClock
;
62 PKSDEFAULTCLOCK DefaultClock
;
65 WORK_QUEUE_ITEM PinWorkQueueItem
;
74 NTSTATUS NTAPI
IKsPin_PinStatePropertyHandler(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
75 NTSTATUS NTAPI
IKsPin_PinDataFormatPropertyHandler(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
76 NTSTATUS NTAPI
IKsPin_PinAllocatorFramingPropertyHandler(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
77 NTSTATUS NTAPI
IKsPin_PinStreamAllocator(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
78 NTSTATUS NTAPI
IKsPin_PinMasterClock(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
79 NTSTATUS NTAPI
IKsPin_PinPipeId(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
83 DEFINE_KSPROPERTY_CONNECTIONSET(PinConnectionSet
, IKsPin_PinStatePropertyHandler
, IKsPin_PinDataFormatPropertyHandler
, IKsPin_PinAllocatorFramingPropertyHandler
);
84 DEFINE_KSPROPERTY_STREAMSET(PinStreamSet
, IKsPin_PinStreamAllocator
, IKsPin_PinMasterClock
, IKsPin_PinPipeId
);
87 // KSPROPSETID_Connection
88 // KSPROPERTY_CONNECTION_ACQUIREORDERING
89 // KSPROPSETID_StreamInterface
90 // KSPROPERTY_STREAMINTERFACE_HEADERSIZE
92 KSPROPERTY_SET PinPropertySet
[] =
95 &KSPROPSETID_Connection
,
96 sizeof(PinConnectionSet
) / sizeof(KSPROPERTY_ITEM
),
97 (const KSPROPERTY_ITEM
*)&PinConnectionSet
,
103 sizeof(PinStreamSet
) / sizeof(KSPROPERTY_ITEM
),
104 (const KSPROPERTY_ITEM
*)&PinStreamSet
,
110 const GUID KSPROPSETID_Connection
= {0x1D58C920L
, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
111 const GUID KSPROPSETID_Stream
= {0x65aaba60L
, 0x98ae, 0x11cf, {0xa1, 0x0d, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4}};
112 const GUID KSPROPSETID_Clock
= {0xDF12A4C0L
, 0xAC17, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
116 IKsPin_PinStreamAllocator(
118 IN PKSIDENTIFIER Request
,
122 return STATUS_NOT_IMPLEMENTED
;
127 IKsPin_PinMasterClock(
129 IN PKSIDENTIFIER Request
,
132 PIO_STACK_LOCATION IoStack
;
133 PKSIOBJECT_HEADER ObjectHeader
;
135 NTSTATUS Status
= STATUS_SUCCESS
;
137 PFILE_OBJECT FileObject
;
138 KPROCESSOR_MODE Mode
;
142 /* get current irp stack */
143 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
145 DPRINT("IKsPin_PinMasterClock\n");
148 ASSERT(IoStack
->FileObject
);
149 ASSERT(IoStack
->FileObject
->FsContext2
);
151 /* get the object header */
152 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
154 /* locate ks pin implemention from KSPIN offset */
155 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
157 /* acquire control mutex */
158 KeWaitForSingleObject(This
->BasicHeader
.ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
160 Handle
= (PHANDLE
)Data
;
162 if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
164 if (This
->Pin
.Descriptor
->PinDescriptor
.Communication
!= KSPIN_COMMUNICATION_NONE
&&
165 This
->Pin
.Descriptor
->Dispatch
&&
166 (This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_IMPLEMENT_CLOCK
))
169 Status
= STATUS_SUCCESS
;
173 /* no clock available */
174 Status
= STATUS_UNSUCCESSFUL
;
177 else if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
179 if (This
->Pin
.ClientState
!= KSSTATE_STOP
)
181 /* can only set in stopped state */
182 Status
= STATUS_INVALID_DEVICE_STATE
;
188 Mode
= ExGetPreviousMode();
190 Status
= ObReferenceObjectByHandle(*Handle
, SYNCHRONIZE
| DIRECTORY_QUERY
, IoFileObjectType
, Mode
, (PVOID
*)&FileObject
, NULL
);
192 DPRINT("IKsPin_PinMasterClock ObReferenceObjectByHandle %lx\n", Status
);
193 if (NT_SUCCESS(Status
))
195 Property
.Set
= KSPROPSETID_Clock
;
196 Property
.Id
= KSPROPERTY_CLOCK_FUNCTIONTABLE
;
197 Property
.Flags
= KSPROPERTY_TYPE_GET
;
199 Status
= KsSynchronousIoControlDevice(FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, &Property
, sizeof(KSPROPERTY
), &This
->ClockTable
, sizeof(KSCLOCK_FUNCTIONTABLE
), &BytesReturned
);
201 DPRINT("IKsPin_PinMasterClock KSPROPERTY_CLOCK_FUNCTIONTABLE %lx\n", Status
);
203 if (NT_SUCCESS(Status
))
205 This
->ClockFileObject
= FileObject
;
209 ObDereferenceObject(FileObject
);
215 /* zeroing clock handle */
216 RtlZeroMemory(&This
->ClockTable
, sizeof(KSCLOCK_FUNCTIONTABLE
));
217 Status
= STATUS_SUCCESS
;
218 if (This
->ClockFileObject
)
220 FileObject
= This
->ClockFileObject
;
221 This
->ClockFileObject
= NULL
;
223 ObDereferenceObject(This
->ClockFileObject
);
229 /* release processing mutex */
230 KeReleaseMutex(This
->BasicHeader
.ControlMutex
, FALSE
);
232 DPRINT("IKsPin_PinStatePropertyHandler Status %lx\n", Status
);
242 IN PKSIDENTIFIER Request
,
246 return STATUS_NOT_IMPLEMENTED
;
252 IKsPin_PinStatePropertyHandler(
254 IN PKSIDENTIFIER Request
,
257 PIO_STACK_LOCATION IoStack
;
258 PKSIOBJECT_HEADER ObjectHeader
;
260 NTSTATUS Status
= STATUS_SUCCESS
;
264 /* get current irp stack */
265 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
267 DPRINT("IKsPin_PinStatePropertyHandler\n");
270 ASSERT(IoStack
->FileObject
);
271 ASSERT(IoStack
->FileObject
->FsContext2
);
273 /* get the object header */
274 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
276 /* locate ks pin implemention from KSPIN offset */
277 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
279 /* acquire control mutex */
280 KeWaitForSingleObject(This
->BasicHeader
.ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
283 NewState
= (PKSSTATE
)Data
;
285 if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
287 *NewState
= This
->Pin
.DeviceState
;
288 Irp
->IoStatus
.Information
= sizeof(KSSTATE
);
290 else if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
292 if (This
->Pin
.Descriptor
->Dispatch
->SetDeviceState
)
294 /* backup old state */
295 OldState
= This
->Pin
.ClientState
;
298 This
->Pin
.ClientState
= *NewState
;
299 This
->Pin
.DeviceState
= *NewState
;
301 /* check if it supported */
302 Status
= This
->Pin
.Descriptor
->Dispatch
->SetDeviceState(&This
->Pin
, *NewState
, OldState
);
304 DPRINT("IKsPin_PinStatePropertyHandler NewState %lu Result %lx\n", *NewState
, Status
);
306 if (!NT_SUCCESS(Status
))
308 /* revert to old state */
309 This
->Pin
.ClientState
= OldState
;
310 This
->Pin
.DeviceState
= OldState
;
311 DPRINT("IKsPin_PinStatePropertyHandler failed to set state %lx Result %lx\n", *NewState
, Status
);
316 /* update device state */
317 This
->Pin
.DeviceState
= *NewState
;
322 /* just set new state */
323 This
->Pin
.DeviceState
= *NewState
;
324 This
->Pin
.ClientState
= *NewState
;
328 /* release processing mutex */
329 KeReleaseMutex(This
->BasicHeader
.ControlMutex
, FALSE
);
331 DPRINT("IKsPin_PinStatePropertyHandler Status %lx\n", Status
);
337 IKsPin_PinAllocatorFramingPropertyHandler(
339 IN PKSIDENTIFIER Request
,
343 return STATUS_NOT_IMPLEMENTED
;
348 IKsPin_PinDataFormatPropertyHandler(
350 IN PKSPROPERTY Request
,
353 PIO_STACK_LOCATION IoStack
;
354 PKSIOBJECT_HEADER ObjectHeader
;
356 NTSTATUS Status
= STATUS_SUCCESS
;
358 /* get current irp stack */
359 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
361 DPRINT("IKsPin_PinDataFormatPropertyHandler\n");
364 ASSERT(IoStack
->FileObject
);
365 ASSERT(IoStack
->FileObject
->FsContext2
);
367 /* get the object header */
368 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
370 /* locate ks pin implemention from KSPIN offset */
371 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
373 /* acquire control mutex */
374 KeWaitForSingleObject(This
->BasicHeader
.ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
376 if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
378 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< This
->Pin
.ConnectionFormat
->FormatSize
)
380 /* buffer too small */
381 Irp
->IoStatus
.Information
= This
->Pin
.ConnectionFormat
->FormatSize
;
382 Status
= STATUS_BUFFER_TOO_SMALL
;
387 RtlMoveMemory(Data
, This
->Pin
.ConnectionFormat
, This
->Pin
.ConnectionFormat
->FormatSize
);
390 else if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
393 if (This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_FIXED_FORMAT
)
395 /* format cannot be changed */
396 Status
= STATUS_INVALID_DEVICE_REQUEST
;
400 /* FIXME check if the format is supported */
401 Status
= _KsEdit(This
->Pin
.Bag
, (PVOID
*)&This
->Pin
.ConnectionFormat
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, This
->Pin
.ConnectionFormat
->FormatSize
, 0);
403 if (NT_SUCCESS(Status
))
405 /* store new format */
406 RtlMoveMemory(This
->Pin
.ConnectionFormat
, Data
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
);
411 /* release processing mutex */
412 KeReleaseMutex(This
->BasicHeader
.ControlMutex
, FALSE
);
414 DPRINT("IKsPin_PinDataFormatPropertyHandler Status %lx\n", Status
);
421 IKsPin_fnQueryInterface(
426 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtbl
);
428 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
))
430 *Output
= &This
->lpVtbl
;
431 _InterlockedIncrement(&This
->ref
);
432 return STATUS_SUCCESS
;
434 DPRINT("IKsPin_fnQueryInterface\n");
436 return STATUS_UNSUCCESSFUL
;
444 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtbl
);
446 return InterlockedIncrement(&This
->ref
);
454 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtbl
);
456 InterlockedDecrement(&This
->ref
);
463 /* Return new reference count */
469 IKsPin_fnTransferKsIrp(
472 IN IKsTransport
**OutTransport
)
475 return STATUS_NOT_IMPLEMENTED
;
480 IKsPin_fnDiscardKsIrp(
483 IN IKsTransport
* *OutTransport
)
493 IN IKsTransport
* TransportIn
,
494 OUT IKsTransport
** OutTransportIn
,
495 OUT IKsTransport
* *OutTransportOut
,
496 IN KSPIN_DATAFLOW DataFlow
)
499 return STATUS_NOT_IMPLEMENTED
;
504 IKsPin_fnSetDeviceState(
508 IN IKsTransport
* *OutTransport
)
511 return STATUS_NOT_IMPLEMENTED
;
516 IKsPin_fnSetResetState(
518 IN KSRESET ResetState
,
519 OUT IKsTransport
* * OutTransportOut
)
526 IKsPin_fnGetTransportConfig(
528 IN
struct KSPTRANSPORTCONFIG
* TransportConfig
,
529 OUT IKsTransport
** OutTransportIn
,
530 OUT IKsTransport
** OutTransportOut
)
533 return STATUS_NOT_IMPLEMENTED
;
538 IKsPin_fnSetTransportConfig(
540 IN
struct KSPTRANSPORTCONFIG
const * TransportConfig
,
541 OUT IKsTransport
** OutTransportIn
,
542 OUT IKsTransport
** OutTransportOut
)
545 return STATUS_NOT_IMPLEMENTED
;
550 IKsPin_fnResetTransportConfig(
552 OUT IKsTransport
** OutTransportIn
,
553 OUT IKsTransport
** OutTransportOut
)
556 return STATUS_NOT_IMPLEMENTED
;
570 IKsPin_fnGetProcessPin(
579 IKsPin_fnAttemptBypass(
583 return STATUS_NOT_IMPLEMENTED
;
588 IKsPin_fnAttemptUnbypass(
592 return STATUS_NOT_IMPLEMENTED
;
597 IKsPin_fnGenerateConnectionEvents(
606 IKsPin_fnClientSetDeviceState(
612 return STATUS_NOT_IMPLEMENTED
;
615 static IKsPinVtbl vt_IKsPin
=
617 IKsPin_fnQueryInterface
,
620 IKsPin_fnTransferKsIrp
,
621 IKsPin_fnDiscardKsIrp
,
623 IKsPin_fnSetDeviceState
,
624 IKsPin_fnSetResetState
,
625 IKsPin_fnGetTransportConfig
,
626 IKsPin_fnSetTransportConfig
,
627 IKsPin_fnResetTransportConfig
,
629 IKsPin_fnGetProcessPin
,
630 IKsPin_fnAttemptBypass
,
631 IKsPin_fnAttemptUnbypass
,
632 IKsPin_fnGenerateConnectionEvents
,
633 IKsPin_fnClientSetDeviceState
637 //==============================================================
641 IKsReferenceClock_fnQueryInterface(
642 IKsReferenceClock
* iface
,
646 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
648 return IKsPin_fnQueryInterface((IKsPin
*)&This
->lpVtbl
, refiid
, Output
);
653 IKsReferenceClock_fnAddRef(
654 IKsReferenceClock
* iface
)
656 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
658 return IKsPin_fnAddRef((IKsPin
*)&This
->lpVtbl
);
663 IKsReferenceClock_fnRelease(
664 IKsReferenceClock
* iface
)
666 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
668 return IKsPin_fnRelease((IKsPin
*)&This
->lpVtbl
);
673 IKsReferenceClock_fnGetTime(
674 IKsReferenceClock
* iface
)
678 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
681 DPRINT1("IKsReferenceClock_fnGetTime\n");
683 if (!This
->ClockFileObject
|| !This
->ClockTable
.GetTime
)
689 Result
= This
->ClockTable
.GetTime(This
->ClockFileObject
);
697 IKsReferenceClock_fnGetPhysicalTime(
698 IKsReferenceClock
* iface
)
702 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
704 DPRINT1("IKsReferenceClock_fnGetPhysicalTime\n");
707 if (!This
->ClockFileObject
|| !This
->ClockTable
.GetPhysicalTime
)
713 Result
= This
->ClockTable
.GetPhysicalTime(This
->ClockFileObject
);
722 IKsReferenceClock_fnGetCorrelatedTime(
723 IKsReferenceClock
* iface
,
724 OUT PLONGLONG SystemTime
)
728 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
730 DPRINT1("IKsReferenceClock_fnGetCorrelatedTime\n");
732 if (!This
->ClockFileObject
|| !This
->ClockTable
.GetCorrelatedTime
)
738 Result
= This
->ClockTable
.GetCorrelatedTime(This
->ClockFileObject
, SystemTime
);
747 IKsReferenceClock_fnGetCorrelatedPhysicalTime(
748 IKsReferenceClock
* iface
,
749 OUT PLONGLONG SystemTime
)
753 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
755 DPRINT1("IKsReferenceClock_fnGetCorrelatedPhysicalTime\n");
757 if (!This
->ClockFileObject
|| !This
->ClockTable
.GetCorrelatedPhysicalTime
)
763 Result
= This
->ClockTable
.GetCorrelatedPhysicalTime(This
->ClockFileObject
, SystemTime
);
771 IKsReferenceClock_fnGetResolution(
772 IKsReferenceClock
* iface
,
773 OUT PKSRESOLUTION Resolution
)
778 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
780 DPRINT1("IKsReferenceClock_fnGetResolution\n");
782 if (!This
->ClockFileObject
)
784 Resolution
->Error
= 0;
785 Resolution
->Granularity
= 1;
786 DPRINT1("IKsReferenceClock_fnGetResolution Using HACK\n");
787 return STATUS_SUCCESS
;
791 if (!This
->ClockFileObject
)
792 return STATUS_DEVICE_NOT_READY
;
795 Property
.Set
= KSPROPSETID_Clock
;
796 Property
.Id
= KSPROPERTY_CLOCK_RESOLUTION
;
797 Property
.Flags
= KSPROPERTY_TYPE_GET
;
799 return KsSynchronousIoControlDevice(This
->ClockFileObject
, KernelMode
, IOCTL_KS_PROPERTY
, &Property
, sizeof(KSPROPERTY
), Resolution
, sizeof(KSRESOLUTION
), &BytesReturned
);
805 IKsReferenceClock_fnGetState(
806 IKsReferenceClock
* iface
,
812 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
814 DPRINT1("IKsReferenceClock_fnGetState\n");
816 if (!This
->ClockFileObject
)
818 *State
= This
->Pin
.ClientState
;
819 DPRINT1("IKsReferenceClock_fnGetState Using HACK\n");
820 return STATUS_SUCCESS
;
824 if (!This
->ClockFileObject
)
825 return STATUS_DEVICE_NOT_READY
;
828 Property
.Set
= KSPROPSETID_Clock
;
829 Property
.Id
= KSPROPERTY_CLOCK_RESOLUTION
;
830 Property
.Flags
= KSPROPERTY_TYPE_GET
;
832 return KsSynchronousIoControlDevice(This
->ClockFileObject
, KernelMode
, IOCTL_KS_PROPERTY
, &Property
, sizeof(KSPROPERTY
), State
, sizeof(KSSTATE
), &BytesReturned
);
835 static IKsReferenceClockVtbl vt_ReferenceClock
=
837 IKsReferenceClock_fnQueryInterface
,
838 IKsReferenceClock_fnAddRef
,
839 IKsReferenceClock_fnRelease
,
840 IKsReferenceClock_fnGetTime
,
841 IKsReferenceClock_fnGetPhysicalTime
,
842 IKsReferenceClock_fnGetCorrelatedTime
,
843 IKsReferenceClock_fnGetCorrelatedPhysicalTime
,
844 IKsReferenceClock_fnGetResolution
,
845 IKsReferenceClock_fnGetState
849 //==============================================================
857 KsPinAcquireProcessingMutex(
860 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
862 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
872 IN PKSGATE AndGate OPTIONAL
)
874 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
876 /* FIXME attach to filter's and gate (filter-centric processing) */
878 This
->AttachedGate
= AndGate
;
879 This
->OrGate
= FALSE
;
889 IN PKSGATE OrGate OPTIONAL
)
891 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
893 /* FIXME attach to filter's and gate (filter-centric processing) */
895 This
->AttachedGate
= OrGate
;
907 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
909 return This
->AttachedGate
;
917 KsPinAttemptProcessing(
919 IN BOOLEAN Asynchronous
)
921 DPRINT("KsPinAttemptProcessing\n");
931 KsPinGetAvailableByteCount(
933 OUT PLONG InputDataBytes OPTIONAL
,
934 OUT PLONG OutputBufferBytes OPTIONAL
)
937 return STATUS_NOT_IMPLEMENTED
;
945 KsPinGetConnectedFilterInterface(
947 IN
const GUID
* InterfaceId
,
948 OUT PVOID
* Interface
)
951 return STATUS_NOT_IMPLEMENTED
;
959 KsPinGetConnectedPinDeviceObject(
971 KsPinGetConnectedPinFileObject(
983 KsPinGetConnectedPinInterface(
985 IN
const GUID
* InterfaceId
,
986 OUT PVOID
* Interface
)
989 return STATUS_NOT_IMPLEMENTED
;
997 KsPinGetCopyRelationships(
999 OUT PKSPIN
* CopySource
,
1000 OUT PKSPIN
* DelegateBranch
)
1010 KsPinGetNextSiblingPin(
1013 return KsGetNextSibling((PVOID
)Pin
);
1021 KsPinGetParentFilter(
1024 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1026 /* return parent filter */
1027 return This
->BasicHeader
.Parent
.KsFilter
;
1035 KsPinGetReferenceClockInterface(
1037 OUT PIKSREFERENCECLOCK
* Interface
)
1039 NTSTATUS Status
= STATUS_DEVICE_NOT_READY
;
1040 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1042 if (This
->ClockFileObject
)
1044 /* clock is available */
1045 *Interface
= (PIKSREFERENCECLOCK
)&This
->lpVtblReferenceClock
;
1046 Status
= STATUS_SUCCESS
;
1049 *Interface
= (PIKSREFERENCECLOCK
)&This
->lpVtblReferenceClock
;
1050 Status
= STATUS_SUCCESS
;
1052 DPRINT("KsPinGetReferenceClockInterface Pin %p Interface %p Status %x\n", Pin
, Interface
, Status
);
1062 KsPinRegisterFrameReturnCallback(
1064 IN PFNKSPINFRAMERETURN FrameReturn
)
1066 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1068 /* register frame return callback */
1069 This
->FrameReturn
= FrameReturn
;
1077 KsPinRegisterHandshakeCallback(
1079 IN PFNKSPINHANDSHAKE Handshake
)
1081 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1083 /* register private protocol handshake callback */
1084 This
->Handshake
= Handshake
;
1092 KsPinRegisterIrpCompletionCallback(
1094 IN PFNKSPINIRPCOMPLETION IrpCompletion
)
1096 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1098 /* register irp completion callback */
1099 This
->IrpCompletion
= IrpCompletion
;
1107 KsPinRegisterPowerCallbacks(
1109 IN PFNKSPINPOWER Sleep OPTIONAL
,
1110 IN PFNKSPINPOWER Wake OPTIONAL
)
1112 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1114 /* register power callbacks */
1115 This
->Sleep
= Sleep
;
1124 KsPinReleaseProcessingMutex(
1127 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1129 /* release processing mutex */
1130 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
1142 PKSIOBJECT_HEADER ObjectHeader
;
1144 PKSBASIC_HEADER Header
;
1145 PIO_STACK_LOCATION IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1147 DPRINT("KsGetPinFromIrp\n");
1149 /* get object header */
1150 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
1155 Pin
= (PKSPIN
)ObjectHeader
->ObjectType
;
1156 Header
= (PKSBASIC_HEADER
)((ULONG_PTR
)Pin
- sizeof(KSBASIC_HEADER
));
1159 ASSERT(Header
->Type
== KsObjectTypePin
);
1161 /* return object type */
1172 KsPinSetPinClockTime(
1186 IN PVOID Data OPTIONAL
,
1187 IN ULONG Size OPTIONAL
,
1188 IN PKSSTREAM_HEADER StreamHeader OPTIONAL
,
1189 IN PVOID Context OPTIONAL
)
1192 return STATUS_UNSUCCESSFUL
;
1201 KsPinSubmitFrameMdl(
1203 IN PMDL Mdl OPTIONAL
,
1204 IN PKSSTREAM_HEADER StreamHeader OPTIONAL
,
1205 IN PVOID Context OPTIONAL
)
1208 return STATUS_UNSUCCESSFUL
;
1218 IN PKSPROCESSPIN ProcessPin
)
1225 IKsPin_PrepareStreamHeader(
1226 IN IKsPinImpl
* This
,
1227 IN PKSISTREAM_POINTER StreamPointer
)
1229 PKSSTREAM_HEADER Header
;
1233 StreamPointer
->Irp
= KsRemoveIrpFromCancelableQueue(&This
->IrpList
, &This
->IrpListLock
, KsListEntryHead
, KsAcquireAndRemoveOnlySingleItem
);
1234 if (!StreamPointer
->Irp
)
1236 /* run out of mappings */
1237 DPRINT("OutOfMappings\n");
1238 return STATUS_DEVICE_NOT_READY
;
1241 InterlockedDecrement(&This
->IrpCount
);
1242 KsDecrementCountedWorker(This
->PinWorker
);
1244 /* get stream header */
1245 if (StreamPointer
->Irp
->RequestorMode
== UserMode
)
1246 Header
= (PKSSTREAM_HEADER
)StreamPointer
->Irp
->AssociatedIrp
.SystemBuffer
;
1248 Header
= (PKSSTREAM_HEADER
)StreamPointer
->Irp
->UserBuffer
;
1250 /* initialize stream pointer */
1251 StreamPointer
->Callback
= NULL
;
1252 StreamPointer
->Length
= max(Header
->DataUsed
, Header
->FrameExtent
);
1253 StreamPointer
->Next
= NULL
;
1254 StreamPointer
->Offset
= 0;
1255 StreamPointer
->Pin
= &This
->Pin
;
1256 StreamPointer
->Data
= Header
->Data
;
1258 StreamPointer
->StreamPointer
.Context
= NULL
;
1259 StreamPointer
->StreamPointer
.Pin
= &This
->Pin
;
1260 StreamPointer
->StreamPointer
.StreamHeader
= Header
;
1262 if (This
->Pin
.Descriptor
->PinDescriptor
.DataFlow
== KSPIN_DATAFLOW_IN
)
1263 StreamPointer
->StreamPointer
.Offset
= &StreamPointer
->StreamPointer
.OffsetIn
;
1265 StreamPointer
->StreamPointer
.Offset
= &StreamPointer
->StreamPointer
.OffsetOut
;
1267 StreamPointer
->StreamPointer
.Offset
->Alignment
= 0;
1268 StreamPointer
->StreamPointer
.Offset
->Count
= 0;
1269 StreamPointer
->StreamPointer
.Offset
->Data
= NULL
;
1270 StreamPointer
->StreamPointer
.Offset
->Remaining
= 0;
1272 ASSERT(StreamPointer
->StreamPointer
.Offset
->Remaining
== 0);
1274 //StreamPointer->Offset += StreamPointer->StreamPointer.Offset->Count;
1276 ASSERT(StreamPointer
->Length
> StreamPointer
->Offset
);
1277 ASSERT(StreamPointer
->StreamPointer
.StreamHeader
);
1278 ASSERT(This
->FrameSize
);
1280 /* calculate length */
1281 /* TODO split into frames */
1282 Length
= StreamPointer
->Length
;
1287 StreamPointer
->StreamPointer
.Offset
->Alignment
= 0;
1288 StreamPointer
->StreamPointer
.Context
= NULL
;
1289 StreamPointer
->StreamPointer
.Pin
= &This
->Pin
;
1290 StreamPointer
->StreamPointer
.Offset
->Count
= Length
;
1291 StreamPointer
->StreamPointer
.Offset
->Remaining
= Length
;
1292 StreamPointer
->StreamPointer
.Offset
->Data
= (PVOID
)((ULONG_PTR
)StreamPointer
->Data
+ StreamPointer
->Offset
);
1293 StreamPointer
->StreamPointer
.StreamHeader
->FrameExtent
= Length
;
1294 if (StreamPointer
->StreamPointer
.StreamHeader
->DataUsed
)
1295 StreamPointer
->StreamPointer
.StreamHeader
->DataUsed
= Length
;
1297 StreamPointer
->StreamPointer
.StreamHeader
->Data
= StreamPointer
->StreamPointer
.Offset
->Data
;
1299 return STATUS_SUCCESS
;
1309 KsPinGetLeadingEdgeStreamPointer(
1311 IN KSSTREAM_POINTER_STATE State
)
1316 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1318 DPRINT("KsPinGetLeadingEdgeStreamPointer Pin %p State %x Count %lu Remaining %lu\n", Pin
, State
,
1319 This
->LeadingEdgeStreamPointer
.Length
,
1320 This
->LeadingEdgeStreamPointer
.Offset
);
1323 ASSERT(State
== KSSTREAM_POINTER_STATE_LOCKED
);
1325 if (State
== KSSTREAM_POINTER_STATE_LOCKED
)
1327 if (!This
->LeadingEdgeStreamPointer
.Irp
|| This
->LeadingEdgeStreamPointer
.StreamPointer
.Offset
->Remaining
== 0)
1329 Status
= IKsPin_PrepareStreamHeader(This
, &This
->LeadingEdgeStreamPointer
);
1330 if (!NT_SUCCESS(Status
))
1334 DPRINT("KsPinGetLeadingEdgeStreamPointer NewOffset %lu TotalLength %lu\n", This
->LeadingEdgeStreamPointer
.Offset
, This
->LeadingEdgeStreamPointer
.Length
);
1337 return &This
->LeadingEdgeStreamPointer
.StreamPointer
;
1346 KsPinGetTrailingEdgeStreamPointer(
1348 IN KSSTREAM_POINTER_STATE State
)
1360 KsStreamPointerSetStatusCode(
1361 IN PKSSTREAM_POINTER StreamPointer
,
1365 return STATUS_UNSUCCESSFUL
;
1374 KsStreamPointerLock(
1375 IN PKSSTREAM_POINTER StreamPointer
)
1378 return STATUS_UNSUCCESSFUL
;
1387 KsStreamPointerUnlock(
1388 IN PKSSTREAM_POINTER StreamPointer
,
1391 PKSISTREAM_POINTER Pointer
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1393 DPRINT("KsStreamPointerUnlock StreamPointer %pEject %lu\n", StreamPointer
, Eject
);
1395 Pointer
->Irp
= NULL
;
1404 KsStreamPointerAdvanceOffsetsAndUnlock(
1405 IN PKSSTREAM_POINTER StreamPointer
,
1410 DPRINT("KsStreamPointerAdvanceOffsets InUsed %lu OutUsed %lu Eject %lu\n", InUsed
, OutUsed
, Eject
);
1421 KsStreamPointerDelete(
1422 IN PKSSTREAM_POINTER StreamPointer
)
1425 PKSISTREAM_POINTER Cur
, Last
;
1426 PKSISTREAM_POINTER Pointer
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1428 DPRINT("KsStreamPointerDelete %p\n", Pointer
);
1430 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pointer
->StreamPointer
.Pin
, IKsPinImpl
, Pin
);
1432 /* point to first stream pointer */
1434 Cur
= This
->ClonedStreamPointer
;
1436 while(Cur
!= Pointer
&& Cur
)
1439 /* iterate to next cloned pointer */
1445 /* you naughty driver */
1451 /* remove first cloned pointer */
1452 This
->ClonedStreamPointer
= Pointer
->Next
;
1456 Last
->Next
= Pointer
->Next
;
1459 /* FIXME make sure no timeouts are pending */
1469 KsStreamPointerClone(
1470 IN PKSSTREAM_POINTER StreamPointer
,
1471 IN PFNKSSTREAMPOINTER CancelCallback OPTIONAL
,
1472 IN ULONG ContextSize
,
1473 OUT PKSSTREAM_POINTER
* CloneStreamPointer
)
1476 PKSISTREAM_POINTER CurFrame
;
1477 PKSISTREAM_POINTER NewFrame
;
1482 DPRINT("KsStreamPointerClone StreamPointer %p CancelCallback %p ContextSize %p CloneStreamPointer %p\n", StreamPointer
, CancelCallback
, ContextSize
, CloneStreamPointer
);
1484 /* get stream pointer */
1485 CurFrame
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1487 /* calculate context size */
1488 Size
= sizeof(KSISTREAM_POINTER
) + ContextSize
;
1490 /* allocate new stream pointer */
1491 NewFrame
= (PKSISTREAM_POINTER
)ExAllocatePool(NonPagedPool
, Size
);
1494 return STATUS_INSUFFICIENT_RESOURCES
;
1496 /* get current irp stack location */
1497 RefCount
= (ULONG
)CurFrame
->Irp
->Tail
.Overlay
.DriverContext
[0];
1499 /* increment reference count */
1501 CurFrame
->Irp
->Tail
.Overlay
.DriverContext
[0] = (PVOID
)RefCount
;
1503 /* copy stream pointer */
1504 RtlMoveMemory(NewFrame
, CurFrame
, sizeof(KSISTREAM_POINTER
));
1507 This
= (IKsPinImpl
*)CONTAINING_RECORD(CurFrame
->Pin
, IKsPinImpl
, Pin
);
1509 /* prepare stream header in case required */
1510 if (CurFrame
->StreamPointer
.Offset
->Remaining
== 0)
1512 Status
= IKsPin_PrepareStreamHeader(This
, NewFrame
);
1513 if (!NT_SUCCESS(Status
))
1516 return STATUS_DEVICE_NOT_READY
;
1521 NewFrame
->StreamPointer
.Context
= (NewFrame
+ 1);
1524 if (This
->Pin
.Descriptor
->PinDescriptor
.DataFlow
== KSPIN_DATAFLOW_IN
)
1525 NewFrame
->StreamPointer
.Offset
= &NewFrame
->StreamPointer
.OffsetIn
;
1527 NewFrame
->StreamPointer
.Offset
= &NewFrame
->StreamPointer
.OffsetOut
;
1531 NewFrame
->StreamPointer
.Pin
= &This
->Pin
;
1533 ASSERT(NewFrame
->StreamPointer
.Pin
);
1534 ASSERT(NewFrame
->StreamPointer
.Context
);
1535 ASSERT(NewFrame
->StreamPointer
.Offset
);
1536 ASSERT(NewFrame
->StreamPointer
.StreamHeader
);
1539 *CloneStreamPointer
= &NewFrame
->StreamPointer
;
1541 DPRINT("KsStreamPointerClone CloneStreamPointer %p\n", *CloneStreamPointer
);
1543 return STATUS_SUCCESS
;
1552 KsStreamPointerAdvanceOffsets(
1553 IN PKSSTREAM_POINTER StreamPointer
,
1558 PKSISTREAM_POINTER CurFrame
;
1562 DPRINT("KsStreamPointerAdvanceOffsets StreamPointer %p InUsed %lu OutUsed %lu Eject %lu\n", StreamPointer
, InUsed
, OutUsed
, Eject
);
1564 /* get stream pointer */
1565 CurFrame
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1568 This
= (IKsPinImpl
*)CONTAINING_RECORD(CurFrame
->Pin
, IKsPinImpl
, Pin
);
1571 ASSERT(InUsed
== 0);
1575 DPRINT("KsStreamPointerAdvanceOffsets Offset %lu Length %lu NewOffset %lu Remaining %lu LeadingEdge %p DataUsed %lu\n", CurFrame
->Offset
, CurFrame
->Length
, CurFrame
->Offset
+ OutUsed
,
1576 CurFrame
->StreamPointer
.OffsetOut
.Remaining
, &This
->LeadingEdgeStreamPointer
.StreamPointer
, CurFrame
->StreamPointer
.StreamHeader
->DataUsed
);
1579 if (This
->Pin
.Descriptor
->PinDescriptor
.DataFlow
== KSPIN_DATAFLOW_IN
)
1581 ASSERT(CurFrame
->StreamPointer
.OffsetIn
.Remaining
>= InUsed
);
1582 CurFrame
->StreamPointer
.OffsetIn
.Remaining
-= InUsed
;
1583 CurFrame
->StreamPointer
.OffsetIn
.Data
= (PVOID
)((ULONG_PTR
)CurFrame
->StreamPointer
.OffsetIn
.Data
+ InUsed
);
1587 if (!CurFrame
->StreamPointer
.OffsetOut
.Remaining
)
1589 Status
= IKsPin_PrepareStreamHeader(This
, CurFrame
);
1590 if (!NT_SUCCESS(Status
))
1592 return STATUS_DEVICE_NOT_READY
;
1597 ASSERT(CurFrame
->StreamPointer
.OffsetOut
.Remaining
>= OutUsed
);
1598 CurFrame
->StreamPointer
.OffsetOut
.Remaining
-= OutUsed
;
1599 CurFrame
->StreamPointer
.OffsetOut
.Data
= (PVOID
)((ULONG_PTR
)CurFrame
->StreamPointer
.OffsetOut
.Data
+ OutUsed
);
1603 return STATUS_SUCCESS
;
1612 KsStreamPointerAdvance(
1613 IN PKSSTREAM_POINTER StreamPointer
)
1617 return STATUS_NOT_IMPLEMENTED
;
1626 KsStreamPointerGetMdl(
1627 IN PKSSTREAM_POINTER StreamPointer
)
1639 KsStreamPointerGetIrp(
1640 IN PKSSTREAM_POINTER StreamPointer
,
1641 OUT PBOOLEAN FirstFrameInIrp OPTIONAL
,
1642 OUT PBOOLEAN LastFrameInIrp OPTIONAL
)
1654 KsStreamPointerScheduleTimeout(
1655 IN PKSSTREAM_POINTER StreamPointer
,
1656 IN PFNKSSTREAMPOINTER Callback
,
1657 IN ULONGLONG Interval
)
1659 LARGE_INTEGER DueTime
;
1660 PKSISTREAM_POINTER Pointer
;
1662 /* get stream pointer */
1663 Pointer
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1665 /* setup timer callback */
1666 Pointer
->Callback
= Callback
;
1668 /* setup expiration */
1669 DueTime
.QuadPart
= (LONGLONG
)Interval
;
1671 /* setup the timer */
1672 KeSetTimer(&Pointer
->Timer
, DueTime
, &Pointer
->TimerDpc
);
1682 KsStreamPointerCancelTimeout(
1683 IN PKSSTREAM_POINTER StreamPointer
)
1685 PKSISTREAM_POINTER Pointer
;
1687 /* get stream pointer */
1688 Pointer
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1690 KeCancelTimer(&Pointer
->Timer
);
1700 KsPinGetFirstCloneStreamPointer(
1705 DPRINT("KsPinGetFirstCloneStreamPointer %p\n", Pin
);
1707 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1709 if (!This
->ClonedStreamPointer
)
1712 /* return first cloned stream pointer */
1713 return &This
->ClonedStreamPointer
->StreamPointer
;
1722 KsStreamPointerGetNextClone(
1723 IN PKSSTREAM_POINTER StreamPointer
)
1725 PKSISTREAM_POINTER Pointer
;
1727 DPRINT("KsStreamPointerGetNextClone\n");
1729 /* get stream pointer */
1730 Pointer
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1732 /* is there a another cloned stream pointer */
1736 /* return next stream pointer */
1737 return &Pointer
->Next
->StreamPointer
;
1742 IKsPin_PinCentricWorker(
1746 IKsPinImpl
* This
= (IKsPinImpl
*)Parameter
;
1748 DPRINT("IKsPin_PinCentricWorker\n");
1752 ASSERT(This
->Pin
.Descriptor
);
1753 ASSERT(This
->Pin
.Descriptor
->Dispatch
);
1754 ASSERT(This
->Pin
.Descriptor
->Dispatch
->Process
);
1755 ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL
);
1756 ASSERT(!(This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_DISPATCH_LEVEL_PROCESSING
));
1757 ASSERT(!(This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_GENERATE_MAPPINGS
));
1761 DPRINT("IKsPin_PinCentricWorker calling Pin Process Routine\n");
1763 Status
= This
->Pin
.Descriptor
->Dispatch
->Process(&This
->Pin
);
1764 DPRINT("IKsPin_PinCentricWorker Status %lx, Offset %lu Length %lu\n", Status
,
1765 This
->LeadingEdgeStreamPointer
.Offset
,
1766 This
->LeadingEdgeStreamPointer
.Length
);
1769 }while(This
->IrpCount
);
1775 IKsPin_DispatchKsStream(
1776 PDEVICE_OBJECT DeviceObject
,
1780 PKSPROCESSPIN_INDEXENTRY ProcessPinIndex
;
1781 PKSSTREAM_HEADER Header
;
1784 PIO_STACK_LOCATION IoStack
;
1785 NTSTATUS Status
= STATUS_SUCCESS
;
1787 DPRINT("IKsPin_DispatchKsStream\n");
1789 /* FIXME handle reset states */
1790 ASSERT(This
->Pin
.ResetState
== KSRESET_END
);
1792 /* get current stack location */
1793 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1795 /* probe stream pointer */
1796 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_WRITE_STREAM
)
1797 Status
= KsProbeStreamIrp(Irp
, KSSTREAM_WRITE
| KSPROBE_ALLOCATEMDL
| KSPROBE_PROBEANDLOCK
| KSPROBE_SYSTEMADDRESS
, This
->Pin
.StreamHeaderSize
);
1799 Status
= KsProbeStreamIrp(Irp
, KSSTREAM_READ
| KSPROBE_ALLOCATEMDL
| KSPROBE_PROBEANDLOCK
| KSPROBE_SYSTEMADDRESS
, This
->Pin
.StreamHeaderSize
);
1801 if (!NT_SUCCESS(Status
))
1803 DPRINT1("KsProbeStreamIrp failed with %x\n", Status
);
1805 Irp
->IoStatus
.Status
= Status
;
1806 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1810 if (Irp
->RequestorMode
== UserMode
)
1811 Header
= (PKSSTREAM_HEADER
)Irp
->AssociatedIrp
.SystemBuffer
;
1813 Header
= (PKSSTREAM_HEADER
)Irp
->UserBuffer
;
1817 DPRINT("NoHeader Canceling Irp %p\n", Irp
);
1818 Irp
->IoStatus
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
1819 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1823 /* calculate num headers */
1824 NumHeaders
= IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
/ Header
->Size
;
1826 /* assume headers of same length */
1827 ASSERT(IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
% Header
->Size
== 0);
1829 /* FIXME support multiple stream headers */
1830 ASSERT(NumHeaders
== 1);
1832 if (Irp
->RequestorMode
== UserMode
)
1834 /* prepare header */
1835 ASSERT(Irp
->MdlAddress
);
1836 Header
->Data
= MmGetSystemAddressForMdlSafe(Irp
->MdlAddress
, NormalPagePriority
);
1840 DPRINT("NoHeader->Data Canceling Irp %p\n", Irp
);
1841 Irp
->IoStatus
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
1842 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1850 if (This
->Pin
.Descriptor
->Dispatch
->Process
)
1852 /* it is a pin centric avstream */
1854 /* mark irp as pending */
1855 IoMarkIrpPending(Irp
);
1857 /* add irp to cancelable queue */
1858 KsAddIrpToCancelableQueue(&This
->IrpList
, &This
->IrpListLock
, Irp
, KsListEntryTail
, NULL
/* FIXME */);
1861 ASSERT(!(This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_DISPATCH_LEVEL_PROCESSING
));
1862 ASSERT(This
->PinWorker
);
1864 InterlockedIncrement(&This
->IrpCount
);
1866 DPRINT("IKsPin_DispatchKsStream IrpCount %lu\n", This
->IrpCount
);
1868 /* start the processing loop */
1869 KsIncrementCountedWorker(This
->PinWorker
);
1871 Status
= STATUS_PENDING
;
1875 /* filter-centric avstream */
1876 ASSERT(This
->Filter
);
1878 ProcessPinIndex
= This
->Filter
->lpVtbl
->GetProcessDispatch(This
->Filter
);
1879 Filter
= This
->Filter
->lpVtbl
->GetStruct(This
->Filter
);
1881 ASSERT(ProcessPinIndex
);
1883 ASSERT(Filter
->Descriptor
);
1884 ASSERT(Filter
->Descriptor
->Dispatch
);
1886 if (!Filter
->Descriptor
->Dispatch
->Process
)
1888 /* invalid device request */
1889 DPRINT("Filter Centric Processing No Process Routine\n");
1890 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1891 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1892 return STATUS_UNSUCCESSFUL
;
1895 /* mark irp as pending */
1896 IoMarkIrpPending(Irp
);
1898 /* add irp to cancelable queue */
1899 KsAddIrpToCancelableQueue(&This
->IrpList
, &This
->IrpListLock
, Irp
, KsListEntryTail
, NULL
/* FIXME */);
1901 Status
= Filter
->Descriptor
->Dispatch
->Process(Filter
, ProcessPinIndex
);
1903 DPRINT("IKsPin_DispatchKsStream FilterCentric: Status %lx \n", Status
);
1912 IKsPin_DispatchKsProperty(
1913 PDEVICE_OBJECT DeviceObject
,
1918 PKSPROPERTY Property
;
1919 PIO_STACK_LOCATION IoStack
;
1920 UNICODE_STRING GuidString
;
1921 ULONG PropertySetsCount
= 0, PropertyItemSize
= 0;
1922 const KSPROPERTY_SET
* PropertySets
= NULL
;
1925 ASSERT(This
->Pin
.Descriptor
);
1927 /* get current irp stack */
1928 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1931 if (This
->Pin
.Descriptor
->AutomationTable
)
1933 /* use available driver property sets */
1934 PropertySetsCount
= This
->Pin
.Descriptor
->AutomationTable
->PropertySetsCount
;
1935 PropertySets
= This
->Pin
.Descriptor
->AutomationTable
->PropertySets
;
1936 PropertyItemSize
= This
->Pin
.Descriptor
->AutomationTable
->PropertyItemSize
;
1940 /* try driver provided property sets */
1941 Status
= KspPropertyHandler(Irp
,
1947 if (Status
!= STATUS_NOT_FOUND
)
1949 /* property was handled by driver */
1950 if (Status
!= STATUS_PENDING
)
1952 Irp
->IoStatus
.Status
= Status
;
1953 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1958 /* try our properties */
1959 Status
= KspPropertyHandler(Irp
,
1960 sizeof(PinPropertySet
) / sizeof(KSPROPERTY_SET
),
1965 if (Status
!= STATUS_NOT_FOUND
)
1967 /* property was handled by driver */
1968 if (Status
!= STATUS_PENDING
)
1970 Irp
->IoStatus
.Status
= Status
;
1971 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1976 /* property was not handled */
1977 Property
= (PKSPROPERTY
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1979 RtlStringFromGUID(&Property
->Set
, &GuidString
);
1980 DPRINT("IKsPin_DispatchKsProperty Unhandled property Set |%S| Id %u Flags %x\n", GuidString
.Buffer
, Property
->Id
, Property
->Flags
);
1981 RtlFreeUnicodeString(&GuidString
);
1983 Irp
->IoStatus
.Status
= STATUS_NOT_FOUND
;
1984 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1986 return STATUS_NOT_FOUND
;
1992 IKsPin_DispatchDeviceIoControl(
1993 IN PDEVICE_OBJECT DeviceObject
,
1996 PIO_STACK_LOCATION IoStack
;
1997 PKSIOBJECT_HEADER ObjectHeader
;
2000 /* get current irp stack */
2001 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2004 ASSERT(IoStack
->FileObject
);
2005 ASSERT(IoStack
->FileObject
->FsContext2
);
2007 /* get the object header */
2008 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
2010 /* locate ks pin implemention from KSPIN offset */
2011 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
2013 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_PROPERTY
)
2015 /* handle ks properties */
2016 return IKsPin_DispatchKsProperty(DeviceObject
, Irp
, This
);
2019 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_WRITE_STREAM
||
2020 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_READ_STREAM
)
2022 /* handle ks properties */
2023 return IKsPin_DispatchKsStream(DeviceObject
, Irp
, This
);
2027 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
2028 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2029 return STATUS_NOT_IMPLEMENTED
;
2035 IN PDEVICE_OBJECT DeviceObject
,
2038 PIO_STACK_LOCATION IoStack
;
2039 PKSIOBJECT_HEADER ObjectHeader
;
2041 NTSTATUS Status
= STATUS_SUCCESS
;
2043 /* get current irp stack */
2044 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2047 ASSERT(IoStack
->FileObject
);
2048 ASSERT(IoStack
->FileObject
->FsContext2
);
2050 /* get the object header */
2051 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
2053 /* locate ks pin implemention fro KSPIN offset */
2054 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
2056 /* acquire filter control mutex */
2057 KsFilterAcquireControl(&This
->Pin
);
2059 if (This
->Pin
.Descriptor
->Dispatch
->Close
)
2061 /* call pin close routine */
2062 Status
= This
->Pin
.Descriptor
->Dispatch
->Close(&This
->Pin
, Irp
);
2064 if (!NT_SUCCESS(Status
))
2067 Irp
->IoStatus
.Status
= Status
;
2068 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2072 /* FIXME remove pin from filter pin list and decrement reference count */
2074 if (Status
!= STATUS_PENDING
)
2076 Irp
->IoStatus
.Status
= Status
;
2077 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2082 /* release filter control mutex */
2083 KsFilterReleaseControl(&This
->Pin
);
2090 IKsPin_DispatchCreateAllocator(
2091 IN PDEVICE_OBJECT DeviceObject
,
2096 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
2097 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2098 return STATUS_NOT_IMPLEMENTED
;
2103 IKsPin_DispatchCreateClock(
2104 IN PDEVICE_OBJECT DeviceObject
,
2108 NTSTATUS Status
= STATUS_SUCCESS
;
2110 KSRESOLUTION Resolution
;
2111 PKSRESOLUTION pResolution
= NULL
;
2112 PKSOBJECT_CREATE_ITEM CreateItem
;
2114 DPRINT("IKsPin_DispatchCreateClock\n");
2116 /* get the create item */
2117 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
2122 /* get the pin object */
2123 Pin
= (PKSPIN
)CreateItem
->Context
;
2128 /* locate ks pin implemention fro KSPIN offset */
2129 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
2132 ASSERT(This
->BasicHeader
.Type
== KsObjectTypePin
);
2133 ASSERT(This
->BasicHeader
.ControlMutex
);
2135 /* acquire control mutex */
2136 KsAcquireControl(Pin
);
2138 if ((This
->Pin
.Descriptor
->PinDescriptor
.Communication
!= KSPIN_COMMUNICATION_NONE
&&
2139 This
->Pin
.Descriptor
->Dispatch
) ||
2140 (This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_IMPLEMENT_CLOCK
))
2142 if (!This
->DefaultClock
)
2144 if (This
->Pin
.Descriptor
->Dispatch
&& This
->Pin
.Descriptor
->Dispatch
->Clock
)
2146 if (This
->Pin
.Descriptor
->Dispatch
->Clock
->Resolution
)
2148 This
->Pin
.Descriptor
->Dispatch
->Clock
->Resolution(&This
->Pin
, &Resolution
);
2149 pResolution
= &Resolution
;
2152 Status
= KsAllocateDefaultClockEx(&This
->DefaultClock
,
2154 (PFNKSSETTIMER
)This
->Pin
.Descriptor
->Dispatch
->Clock
->SetTimer
,
2155 (PFNKSCANCELTIMER
)This
->Pin
.Descriptor
->Dispatch
->Clock
->CancelTimer
,
2156 (PFNKSCORRELATEDTIME
)This
->Pin
.Descriptor
->Dispatch
->Clock
->CorrelatedTime
,
2162 Status
= KsAllocateDefaultClockEx(&This
->DefaultClock
, (PVOID
)&This
->Pin
, NULL
, NULL
, NULL
, NULL
, 0);
2166 if (NT_SUCCESS(Status
))
2168 Status
= KsCreateDefaultClock(Irp
, This
->DefaultClock
);
2172 DPRINT("IKsPin_DispatchCreateClock %lx\n", Status
);
2174 /* release control mutex */
2175 KsReleaseControl(Pin
);
2178 Irp
->IoStatus
.Status
= Status
;
2179 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2185 IKsPin_DispatchCreateNode(
2186 IN PDEVICE_OBJECT DeviceObject
,
2191 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
2192 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2193 return STATUS_NOT_IMPLEMENTED
;
2196 static KSDISPATCH_TABLE PinDispatchTable
=
2198 IKsPin_DispatchDeviceIoControl
,
2199 KsDispatchInvalidDeviceRequest
,
2200 KsDispatchInvalidDeviceRequest
,
2201 KsDispatchInvalidDeviceRequest
,
2203 KsDispatchQuerySecurity
,
2204 KsDispatchSetSecurity
,
2205 KsDispatchFastIoDeviceControlFailure
,
2206 KsDispatchFastReadFailure
,
2207 KsDispatchFastReadFailure
2212 IN PDEVICE_OBJECT DeviceObject
,
2214 IN PKSDEVICE KsDevice
,
2215 IN IKsFilterFactory
* FilterFactory
,
2216 IN IKsFilter
* Filter
,
2217 IN PKSPIN_CONNECT Connect
,
2218 IN KSPIN_DESCRIPTOR_EX
* Descriptor
)
2221 PIO_STACK_LOCATION IoStack
;
2223 PDEVICE_EXTENSION DeviceExtension
;
2224 PKSOBJECT_CREATE_ITEM CreateItem
;
2226 PKSDATAFORMAT DataFormat
;
2227 PKSBASIC_HEADER BasicHeader
;
2229 ULONG FrameSize
= 0;
2230 ULONG NumFrames
= 0;
2233 ASSERT(Descriptor
->Dispatch
);
2235 DPRINT("KspCreatePin PinId %lu Flags %x\n", Connect
->PinId
, Descriptor
->Flags
);
2237 //Output Pin: KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY
2238 //Input Pin: KSPIN_FLAG_FIXED_FORMAT|KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT|KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING
2241 if (Descriptor
->AllocatorFraming
)
2243 DPRINT("KspCreatePin Dataflow %lu\n", Descriptor
->PinDescriptor
.DataFlow
);
2244 DPRINT("KspCreatePin CountItems %lu\n", Descriptor
->AllocatorFraming
->CountItems
);
2245 DPRINT("KspCreatePin PinFlags %lx\n", Descriptor
->AllocatorFraming
->PinFlags
);
2246 DPRINT("KspCreatePin OutputCompression RatioNumerator %lu RatioDenominator %lu RatioConstantMargin %lu\n", Descriptor
->AllocatorFraming
->OutputCompression
.RatioNumerator
,
2247 Descriptor
->AllocatorFraming
->OutputCompression
.RatioDenominator
, Descriptor
->AllocatorFraming
->OutputCompression
.RatioConstantMargin
);
2248 DPRINT("KspCreatePin PinWeight %lx\n", Descriptor
->AllocatorFraming
->PinWeight
);
2250 for(Index
= 0; Index
< Descriptor
->AllocatorFraming
->CountItems
; Index
++)
2252 DPRINT("KspCreatePin Index %lu MemoryFlags %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].MemoryFlags
);
2253 DPRINT("KspCreatePin Index %lu BusFlags %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].BusFlags
);
2254 DPRINT("KspCreatePin Index %lu Flags %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].Flags
);
2255 DPRINT("KspCreatePin Index %lu Frames %lu\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].Frames
);
2256 DPRINT("KspCreatePin Index %lu FileAlignment %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].FileAlignment
);
2257 DPRINT("KspCreatePin Index %lu MemoryTypeWeight %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].MemoryTypeWeight
);
2258 DPRINT("KspCreatePin Index %lu PhysicalRange MinFrameSize %lu MaxFrameSize %lu Stepping %lu\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].PhysicalRange
.MinFrameSize
,
2259 Descriptor
->AllocatorFraming
->FramingItem
[Index
].PhysicalRange
.MaxFrameSize
,
2260 Descriptor
->AllocatorFraming
->FramingItem
[Index
].PhysicalRange
.Stepping
);
2262 DPRINT("KspCreatePin Index %lu FramingRange MinFrameSize %lu MaxFrameSize %lu Stepping %lu InPlaceWeight %lu NotInPlaceWeight %lu\n",
2264 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.Range
.MinFrameSize
,
2265 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.Range
.MaxFrameSize
,
2266 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.Range
.Stepping
,
2267 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.InPlaceWeight
,
2268 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.NotInPlaceWeight
);
2270 FrameSize
= Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.Range
.MaxFrameSize
;
2271 NumFrames
= Descriptor
->AllocatorFraming
->FramingItem
[Index
].Frames
;
2277 /* default to 50 * 188 (MPEG2 TS packet size) */
2286 /* get current irp stack */
2287 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2289 /* get device extension */
2290 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
2292 /* get ks device interface */
2293 Device
= (IKsDevice
*)&DeviceExtension
->DeviceHeader
->lpVtblIKsDevice
;
2295 /* first allocate pin ctx */
2296 This
= AllocateItem(NonPagedPool
, sizeof(IKsPinImpl
));
2299 /* not enough memory */
2300 return STATUS_INSUFFICIENT_RESOURCES
;
2303 /* allocate create item */
2304 CreateItem
= AllocateItem(NonPagedPool
, sizeof(KSOBJECT_CREATE_ITEM
) * 3);
2307 /* not enough memory */
2309 DPRINT("KspCreatePin OutOfMemory\n");
2310 return STATUS_INSUFFICIENT_RESOURCES
;
2313 /* initialize basic header */
2314 This
->BasicHeader
.KsDevice
= KsDevice
;
2315 This
->BasicHeader
.Type
= KsObjectTypePin
;
2316 This
->BasicHeader
.Parent
.KsFilter
= Filter
->lpVtbl
->GetStruct(Filter
);
2318 ASSERT(This
->BasicHeader
.Parent
.KsFilter
);
2320 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)This
->BasicHeader
.Parent
.KsFilter
- sizeof(KSBASIC_HEADER
));
2322 This
->BasicHeader
.ControlMutex
= BasicHeader
->ControlMutex
;
2323 ASSERT(This
->BasicHeader
.ControlMutex
);
2325 InitializeListHead(&This
->BasicHeader
.EventList
);
2326 KeInitializeSpinLock(&This
->BasicHeader
.EventListLock
);
2328 /* initialize pin */
2329 This
->lpVtbl
= &vt_IKsPin
;
2330 This
->FrameSize
= FrameSize
;
2331 This
->NumFrames
= NumFrames
;
2332 This
->lpVtblReferenceClock
= &vt_ReferenceClock
;
2334 This
->FileObject
= IoStack
->FileObject
;
2335 This
->Filter
= Filter
;
2336 KeInitializeMutex(&This
->ProcessingMutex
, 0);
2337 InitializeListHead(&This
->IrpList
);
2338 KeInitializeSpinLock(&This
->IrpListLock
);
2340 /* allocate object bag */
2341 This
->Pin
.Bag
= AllocateItem(NonPagedPool
, sizeof(KSIOBJECT_BAG
));
2344 /* not enough memory */
2346 FreeItem(CreateItem
);
2347 return STATUS_INSUFFICIENT_RESOURCES
;
2350 /* initialize object bag */
2351 Device
->lpVtbl
->InitializeObjectBag(Device
, This
->Pin
.Bag
, NULL
);
2354 DataFormat
= (PKSDATAFORMAT
)(Connect
+ 1);
2356 /* initialize pin descriptor */
2357 This
->Pin
.Descriptor
= Descriptor
;
2358 This
->Pin
.Context
= NULL
;
2359 This
->Pin
.Id
= Connect
->PinId
;
2360 This
->Pin
.Communication
= Descriptor
->PinDescriptor
.Communication
;
2361 This
->Pin
.ConnectionIsExternal
= FALSE
; //FIXME
2362 RtlMoveMemory(&This
->Pin
.ConnectionInterface
, &Connect
->Interface
, sizeof(KSPIN_INTERFACE
));
2363 RtlMoveMemory(&This
->Pin
.ConnectionMedium
, &Connect
->Medium
, sizeof(KSPIN_MEDIUM
));
2364 RtlMoveMemory(&This
->Pin
.ConnectionPriority
, &Connect
->Priority
, sizeof(KSPRIORITY
));
2366 /* allocate format */
2367 Status
= _KsEdit(This
->Pin
.Bag
, (PVOID
*)&This
->Pin
.ConnectionFormat
, DataFormat
->FormatSize
, DataFormat
->FormatSize
, 0);
2368 if (!NT_SUCCESS(Status
))
2370 /* failed to allocate format */
2371 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2373 FreeItem(CreateItem
);
2374 return STATUS_INSUFFICIENT_RESOURCES
;
2378 RtlMoveMemory((PVOID
)This
->Pin
.ConnectionFormat
, DataFormat
, DataFormat
->FormatSize
);
2380 This
->Pin
.AttributeList
= NULL
; //FIXME
2381 This
->Pin
.StreamHeaderSize
= sizeof(KSSTREAM_HEADER
);
2382 This
->Pin
.DataFlow
= Descriptor
->PinDescriptor
.DataFlow
;
2383 This
->Pin
.DeviceState
= KSSTATE_STOP
;
2384 This
->Pin
.ResetState
= KSRESET_END
;
2385 This
->Pin
.ClientState
= KSSTATE_STOP
;
2387 /* intialize allocator create item */
2388 CreateItem
[0].Context
= (PVOID
)&This
->Pin
;
2389 CreateItem
[0].Create
= IKsPin_DispatchCreateAllocator
;
2390 CreateItem
[0].Flags
= KSCREATE_ITEM_FREEONSTOP
;
2391 RtlInitUnicodeString(&CreateItem
[0].ObjectClass
, KSSTRING_Allocator
);
2393 /* intialize clock create item */
2394 CreateItem
[1].Context
= (PVOID
)&This
->Pin
;
2395 CreateItem
[1].Create
= IKsPin_DispatchCreateClock
;
2396 CreateItem
[1].Flags
= KSCREATE_ITEM_FREEONSTOP
;
2397 RtlInitUnicodeString(&CreateItem
[1].ObjectClass
, KSSTRING_Clock
);
2399 /* intialize topology node create item */
2400 CreateItem
[2].Context
= (PVOID
)&This
->Pin
;
2401 CreateItem
[2].Create
= IKsPin_DispatchCreateNode
;
2402 CreateItem
[2].Flags
= KSCREATE_ITEM_FREEONSTOP
;
2403 RtlInitUnicodeString(&CreateItem
[2].ObjectClass
, KSSTRING_TopologyNode
);
2405 /* now allocate object header */
2406 Status
= KsAllocateObjectHeader((KSOBJECT_HEADER
*)&This
->ObjectHeader
, 3, CreateItem
, Irp
, &PinDispatchTable
);
2407 if (!NT_SUCCESS(Status
))
2409 /* failed to create object header */
2410 DPRINT("KspCreatePin KsAllocateObjectHeader failed %lx\n", Status
);
2411 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2413 FreeItem(CreateItem
);
2415 /* return failure code */
2419 /* add extra info to object header */
2420 This
->ObjectHeader
->Type
= KsObjectTypePin
;
2421 This
->ObjectHeader
->Unknown
= (PUNKNOWN
)&This
->lpVtbl
;
2422 This
->ObjectHeader
->ObjectType
= (PVOID
)&This
->Pin
;
2424 if (!Descriptor
->Dispatch
|| !Descriptor
->Dispatch
->Process
)
2426 /* the pin is part of filter-centric processing filter
2427 * add process pin to filter
2429 This
->ProcessPin
.BytesAvailable
= 0;
2430 This
->ProcessPin
.BytesUsed
= 0;
2431 This
->ProcessPin
.CopySource
= NULL
;
2432 This
->ProcessPin
.Data
= NULL
;
2433 This
->ProcessPin
.DelegateBranch
= NULL
;
2434 This
->ProcessPin
.Flags
= 0;
2435 This
->ProcessPin
.InPlaceCounterpart
= NULL
;
2436 This
->ProcessPin
.Pin
= &This
->Pin
;
2437 This
->ProcessPin
.StreamPointer
= (PKSSTREAM_POINTER
)&This
->LeadingEdgeStreamPointer
.StreamPointer
;
2438 This
->ProcessPin
.Terminate
= FALSE
;
2440 Status
= Filter
->lpVtbl
->AddProcessPin(Filter
, &This
->ProcessPin
);
2441 DPRINT("KspCreatePin AddProcessPin %lx\n", Status
);
2443 if (!NT_SUCCESS(Status
))
2445 /* failed to add process pin */
2446 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2447 KsFreeObjectHeader(&This
->ObjectHeader
);
2449 FreeItem(CreateItem
);
2450 /* return failure code */
2454 else if (Descriptor
->Dispatch
&& Descriptor
->Dispatch
->Process
)
2456 /* pin centric processing filter */
2458 /* initialize work item */
2459 ExInitializeWorkItem(&This
->PinWorkQueueItem
, IKsPin_PinCentricWorker
, (PVOID
)This
);
2461 /* allocate counted work item */
2462 Status
= KsRegisterCountedWorker(HyperCriticalWorkQueue
, &This
->PinWorkQueueItem
, &This
->PinWorker
);
2464 if (!NT_SUCCESS(Status
))
2466 DPRINT("Failed to register Worker %lx\n", Status
);
2467 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2468 KsFreeObjectHeader(&This
->ObjectHeader
);
2470 FreeItem(CreateItem
);
2474 if (This
->Pin
.Descriptor
->PinDescriptor
.DataFlow
== KSPIN_DATAFLOW_IN
)
2475 This
->LeadingEdgeStreamPointer
.StreamPointer
.Offset
= &This
->LeadingEdgeStreamPointer
.StreamPointer
.OffsetIn
;
2477 This
->LeadingEdgeStreamPointer
.StreamPointer
.Offset
= &This
->LeadingEdgeStreamPointer
.StreamPointer
.OffsetOut
;
2480 KeInitializeEvent(&This
->FrameComplete
, NotificationEvent
, FALSE
);
2484 /* FIXME add pin instance to filter instance */
2487 if (Descriptor
->Dispatch
&& Descriptor
->Dispatch
->SetDataFormat
)
2489 Status
= Descriptor
->Dispatch
->SetDataFormat(&This
->Pin
, NULL
, NULL
, This
->Pin
.ConnectionFormat
, NULL
);
2490 DPRINT("KspCreatePin SetDataFormat %lx\n", Status
);
2494 /* does the driver have a pin dispatch */
2495 if (Descriptor
->Dispatch
&& Descriptor
->Dispatch
->Create
)
2497 /* now inform the driver to create a new pin */
2498 Status
= Descriptor
->Dispatch
->Create(&This
->Pin
, Irp
);
2499 DPRINT("KspCreatePin DispatchCreate %lx\n", Status
);
2503 DPRINT("KspCreatePin Status %lx\n", Status
);
2505 if (!NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
)
2507 /* failed to create pin, release resources */
2508 KsFreeObjectHeader((KSOBJECT_HEADER
)This
->ObjectHeader
);
2509 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2512 /* return failure code */