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 KSSTREAM_POINTER StreamPointer
;
15 PFNKSSTREAMPOINTER Callback
;
19 struct _KSISTREAM_POINTER
*Next
;
21 }KSISTREAM_POINTER
, *PKSISTREAM_POINTER
;
25 KSBASIC_HEADER BasicHeader
;
27 PKSIOBJECT_HEADER ObjectHeader
;
28 KSPROCESSPIN ProcessPin
;
35 KMUTEX ProcessingMutex
;
36 PFILE_OBJECT FileObject
;
42 KSPIN_LOCK IrpListLock
;
44 PKSISTREAM_POINTER ClonedStreamPointer
;
45 PKSISTREAM_POINTER LeadingEdgeStreamPointer
;
46 PKSISTREAM_POINTER TrailingStreamPointer
;
50 PFNKSPINHANDSHAKE Handshake
;
51 PFNKSPINFRAMERETURN FrameReturn
;
52 PFNKSPINIRPCOMPLETION IrpCompletion
;
54 KSCLOCK_FUNCTIONTABLE ClockTable
;
55 PFILE_OBJECT ClockFileObject
;
56 IKsReferenceClockVtbl
* lpVtblReferenceClock
;
57 PKSDEFAULTCLOCK DefaultClock
;
61 NTSTATUS NTAPI
IKsPin_PinStatePropertyHandler(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
62 NTSTATUS NTAPI
IKsPin_PinDataFormatPropertyHandler(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
63 NTSTATUS NTAPI
IKsPin_PinAllocatorFramingPropertyHandler(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
64 NTSTATUS NTAPI
IKsPin_PinStreamAllocator(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
65 NTSTATUS NTAPI
IKsPin_PinMasterClock(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
66 NTSTATUS NTAPI
IKsPin_PinPipeId(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
70 DEFINE_KSPROPERTY_CONNECTIONSET(PinConnectionSet
, IKsPin_PinStatePropertyHandler
, IKsPin_PinDataFormatPropertyHandler
, IKsPin_PinAllocatorFramingPropertyHandler
);
71 DEFINE_KSPROPERTY_STREAMSET(PinStreamSet
, IKsPin_PinStreamAllocator
, IKsPin_PinMasterClock
, IKsPin_PinPipeId
);
74 // KSPROPSETID_Connection
75 // KSPROPERTY_CONNECTION_ACQUIREORDERING
76 // KSPROPSETID_StreamInterface
77 // KSPROPERTY_STREAMINTERFACE_HEADERSIZE
79 KSPROPERTY_SET PinPropertySet
[] =
82 &KSPROPSETID_Connection
,
83 sizeof(PinConnectionSet
) / sizeof(KSPROPERTY_ITEM
),
84 (const KSPROPERTY_ITEM
*)&PinConnectionSet
,
90 sizeof(PinStreamSet
) / sizeof(KSPROPERTY_ITEM
),
91 (const KSPROPERTY_ITEM
*)&PinStreamSet
,
97 const GUID KSPROPSETID_Connection
= {0x1D58C920L
, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
98 const GUID KSPROPSETID_Stream
= {0x65aaba60L
, 0x98ae, 0x11cf, {0xa1, 0x0d, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4}};
99 const GUID KSPROPSETID_Clock
= {0xDF12A4C0L
, 0xAC17, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
103 IKsPin_PinStreamAllocator(
105 IN PKSIDENTIFIER Request
,
109 return STATUS_NOT_IMPLEMENTED
;
114 IKsPin_PinMasterClock(
116 IN PKSIDENTIFIER Request
,
119 PIO_STACK_LOCATION IoStack
;
120 PKSIOBJECT_HEADER ObjectHeader
;
122 NTSTATUS Status
= STATUS_SUCCESS
;
124 PFILE_OBJECT FileObject
;
125 KPROCESSOR_MODE Mode
;
129 /* get current irp stack */
130 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
132 DPRINT("IKsPin_PinMasterClock\n");
135 ASSERT(IoStack
->FileObject
);
136 ASSERT(IoStack
->FileObject
->FsContext2
);
138 /* get the object header */
139 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
141 /* locate ks pin implemention from KSPIN offset */
142 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
144 /* acquire control mutex */
145 KeWaitForSingleObject(This
->BasicHeader
.ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
147 Handle
= (PHANDLE
)Data
;
149 if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
151 if (This
->Pin
.Descriptor
->PinDescriptor
.Communication
!= KSPIN_COMMUNICATION_NONE
&&
152 This
->Pin
.Descriptor
->Dispatch
&&
153 (This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_IMPLEMENT_CLOCK
))
156 Status
= STATUS_SUCCESS
;
160 /* no clock available */
161 Status
= STATUS_UNSUCCESSFUL
;
164 else if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
166 if (This
->Pin
.ClientState
!= KSSTATE_STOP
)
168 /* can only set in stopped state */
169 Status
= STATUS_INVALID_DEVICE_STATE
;
175 Mode
= ExGetPreviousMode();
177 Status
= ObReferenceObjectByHandle(*Handle
, SYNCHRONIZE
| DIRECTORY_QUERY
, IoFileObjectType
, Mode
, (PVOID
*)&FileObject
, NULL
);
179 DPRINT("IKsPin_PinMasterClock ObReferenceObjectByHandle %lx\n", Status
);
180 if (NT_SUCCESS(Status
))
182 Property
.Set
= KSPROPSETID_Clock
;
183 Property
.Id
= KSPROPERTY_CLOCK_FUNCTIONTABLE
;
184 Property
.Flags
= KSPROPERTY_TYPE_GET
;
186 Status
= KsSynchronousIoControlDevice(FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, &Property
, sizeof(KSPROPERTY
), &This
->ClockTable
, sizeof(KSCLOCK_FUNCTIONTABLE
), &BytesReturned
);
188 DPRINT("IKsPin_PinMasterClock KSPROPERTY_CLOCK_FUNCTIONTABLE %lx\n", Status
);
190 if (NT_SUCCESS(Status
))
192 This
->ClockFileObject
= FileObject
;
196 ObDereferenceObject(FileObject
);
202 /* zeroing clock handle */
203 RtlZeroMemory(&This
->ClockTable
, sizeof(KSCLOCK_FUNCTIONTABLE
));
204 Status
= STATUS_SUCCESS
;
205 if (This
->ClockFileObject
)
207 FileObject
= This
->ClockFileObject
;
208 This
->ClockFileObject
= NULL
;
210 ObDereferenceObject(This
->ClockFileObject
);
216 /* release processing mutex */
217 KeReleaseMutex(This
->BasicHeader
.ControlMutex
, FALSE
);
219 DPRINT("IKsPin_PinStatePropertyHandler Status %lx\n", Status
);
229 IN PKSIDENTIFIER Request
,
233 return STATUS_NOT_IMPLEMENTED
;
239 IKsPin_PinStatePropertyHandler(
241 IN PKSIDENTIFIER Request
,
244 PIO_STACK_LOCATION IoStack
;
245 PKSIOBJECT_HEADER ObjectHeader
;
247 NTSTATUS Status
= STATUS_SUCCESS
;
251 /* get current irp stack */
252 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
254 DPRINT("IKsPin_PinStatePropertyHandler\n");
257 ASSERT(IoStack
->FileObject
);
258 ASSERT(IoStack
->FileObject
->FsContext2
);
260 /* get the object header */
261 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
263 /* locate ks pin implemention from KSPIN offset */
264 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
266 /* acquire control mutex */
267 KeWaitForSingleObject(This
->BasicHeader
.ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
270 NewState
= (PKSSTATE
)Data
;
272 if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
274 *NewState
= This
->Pin
.DeviceState
;
275 Irp
->IoStatus
.Information
= sizeof(KSSTATE
);
277 else if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
279 if (This
->Pin
.Descriptor
->Dispatch
->SetDeviceState
)
281 /* backup old state */
282 OldState
= This
->Pin
.ClientState
;
285 This
->Pin
.ClientState
= *NewState
;
287 /* check if it supported */
288 Status
= This
->Pin
.Descriptor
->Dispatch
->SetDeviceState(&This
->Pin
, *NewState
, OldState
);
290 DPRINT("IKsPin_PinStatePropertyHandler NewState %lu Result %lx\n", *NewState
, Status
);
292 if (!NT_SUCCESS(Status
))
294 /* revert to old state */
295 This
->Pin
.ClientState
= OldState
;
300 /* update device state */
301 This
->Pin
.DeviceState
= *NewState
;
306 /* just set new state */
307 This
->Pin
.DeviceState
= *NewState
;
308 This
->Pin
.ClientState
= *NewState
;
312 /* release processing mutex */
313 KeReleaseMutex(This
->BasicHeader
.ControlMutex
, FALSE
);
315 DPRINT("IKsPin_PinStatePropertyHandler Status %lx\n", Status
);
321 IKsPin_PinAllocatorFramingPropertyHandler(
323 IN PKSIDENTIFIER Request
,
327 return STATUS_NOT_IMPLEMENTED
;
332 IKsPin_PinDataFormatPropertyHandler(
334 IN PKSPROPERTY Request
,
337 PIO_STACK_LOCATION IoStack
;
338 PKSIOBJECT_HEADER ObjectHeader
;
340 NTSTATUS Status
= STATUS_SUCCESS
;
342 /* get current irp stack */
343 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
345 DPRINT("IKsPin_PinDataFormatPropertyHandler\n");
348 ASSERT(IoStack
->FileObject
);
349 ASSERT(IoStack
->FileObject
->FsContext2
);
351 /* get the object header */
352 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
354 /* locate ks pin implemention from KSPIN offset */
355 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
357 /* acquire control mutex */
358 KeWaitForSingleObject(This
->BasicHeader
.ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
360 if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
362 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< This
->Pin
.ConnectionFormat
->FormatSize
)
364 /* buffer too small */
365 Irp
->IoStatus
.Information
= This
->Pin
.ConnectionFormat
->FormatSize
;
366 Status
= STATUS_BUFFER_TOO_SMALL
;
371 RtlMoveMemory(Data
, This
->Pin
.ConnectionFormat
, This
->Pin
.ConnectionFormat
->FormatSize
);
374 else if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
377 if (This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_FIXED_FORMAT
)
379 /* format cannot be changed */
380 Status
= STATUS_INVALID_DEVICE_REQUEST
;
384 /* FIXME check if the format is supported */
385 Status
= _KsEdit(This
->Pin
.Bag
, (PVOID
*)&This
->Pin
.ConnectionFormat
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, This
->Pin
.ConnectionFormat
->FormatSize
, 0);
387 if (NT_SUCCESS(Status
))
389 /* store new format */
390 RtlMoveMemory(This
->Pin
.ConnectionFormat
, Data
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
);
395 /* release processing mutex */
396 KeReleaseMutex(This
->BasicHeader
.ControlMutex
, FALSE
);
398 DPRINT("IKsPin_PinDataFormatPropertyHandler Status %lx\n", Status
);
405 IKsPin_fnQueryInterface(
410 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtbl
);
412 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
))
414 *Output
= &This
->lpVtbl
;
415 _InterlockedIncrement(&This
->ref
);
416 return STATUS_SUCCESS
;
419 return STATUS_UNSUCCESSFUL
;
427 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtbl
);
429 return InterlockedIncrement(&This
->ref
);
437 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtbl
);
439 InterlockedDecrement(&This
->ref
);
446 /* Return new reference count */
452 IKsPin_fnTransferKsIrp(
455 IN IKsTransport
**OutTransport
)
458 return STATUS_NOT_IMPLEMENTED
;
463 IKsPin_fnDiscardKsIrp(
466 IN IKsTransport
* *OutTransport
)
476 IN IKsTransport
* TransportIn
,
477 OUT IKsTransport
** OutTransportIn
,
478 OUT IKsTransport
* *OutTransportOut
,
479 IN KSPIN_DATAFLOW DataFlow
)
482 return STATUS_NOT_IMPLEMENTED
;
487 IKsPin_fnSetDeviceState(
491 IN IKsTransport
* *OutTransport
)
494 return STATUS_NOT_IMPLEMENTED
;
499 IKsPin_fnSetResetState(
501 IN KSRESET ResetState
,
502 OUT IKsTransport
* * OutTransportOut
)
509 IKsPin_fnGetTransportConfig(
511 IN
struct KSPTRANSPORTCONFIG
* TransportConfig
,
512 OUT IKsTransport
** OutTransportIn
,
513 OUT IKsTransport
** OutTransportOut
)
516 return STATUS_NOT_IMPLEMENTED
;
521 IKsPin_fnSetTransportConfig(
523 IN
struct KSPTRANSPORTCONFIG
const * TransportConfig
,
524 OUT IKsTransport
** OutTransportIn
,
525 OUT IKsTransport
** OutTransportOut
)
528 return STATUS_NOT_IMPLEMENTED
;
533 IKsPin_fnResetTransportConfig(
535 OUT IKsTransport
** OutTransportIn
,
536 OUT IKsTransport
** OutTransportOut
)
539 return STATUS_NOT_IMPLEMENTED
;
553 IKsPin_fnGetProcessPin(
562 IKsPin_fnAttemptBypass(
566 return STATUS_NOT_IMPLEMENTED
;
571 IKsPin_fnAttemptUnbypass(
575 return STATUS_NOT_IMPLEMENTED
;
580 IKsPin_fnGenerateConnectionEvents(
589 IKsPin_fnClientSetDeviceState(
595 return STATUS_NOT_IMPLEMENTED
;
598 static IKsPinVtbl vt_IKsPin
=
600 IKsPin_fnQueryInterface
,
603 IKsPin_fnTransferKsIrp
,
604 IKsPin_fnDiscardKsIrp
,
606 IKsPin_fnSetDeviceState
,
607 IKsPin_fnSetResetState
,
608 IKsPin_fnGetTransportConfig
,
609 IKsPin_fnSetTransportConfig
,
610 IKsPin_fnResetTransportConfig
,
612 IKsPin_fnGetProcessPin
,
613 IKsPin_fnAttemptBypass
,
614 IKsPin_fnAttemptUnbypass
,
615 IKsPin_fnGenerateConnectionEvents
,
616 IKsPin_fnClientSetDeviceState
620 //==============================================================
624 IKsReferenceClock_fnQueryInterface(
625 IKsReferenceClock
* iface
,
629 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
631 return IKsPin_fnQueryInterface((IKsPin
*)&This
->lpVtbl
, refiid
, Output
);
636 IKsReferenceClock_fnAddRef(
637 IKsReferenceClock
* iface
)
639 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
641 return IKsPin_fnAddRef((IKsPin
*)&This
->lpVtbl
);
646 IKsReferenceClock_fnRelease(
647 IKsReferenceClock
* iface
)
649 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
651 return IKsPin_fnRelease((IKsPin
*)&This
->lpVtbl
);
656 IKsReferenceClock_fnGetTime(
657 IKsReferenceClock
* iface
)
661 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
663 if (!This
->ClockFileObject
|| !This
->ClockTable
.GetTime
)
669 Result
= This
->ClockTable
.GetTime(This
->ClockFileObject
);
677 IKsReferenceClock_fnGetPhysicalTime(
678 IKsReferenceClock
* iface
)
682 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
684 if (!This
->ClockFileObject
|| !This
->ClockTable
.GetPhysicalTime
)
690 Result
= This
->ClockTable
.GetPhysicalTime(This
->ClockFileObject
);
699 IKsReferenceClock_fnGetCorrelatedTime(
700 IKsReferenceClock
* iface
,
701 OUT PLONGLONG SystemTime
)
705 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
707 if (!This
->ClockFileObject
|| !This
->ClockTable
.GetCorrelatedTime
)
713 Result
= This
->ClockTable
.GetCorrelatedTime(This
->ClockFileObject
, SystemTime
);
722 IKsReferenceClock_fnGetCorrelatedPhysicalTime(
723 IKsReferenceClock
* iface
,
724 OUT PLONGLONG SystemTime
)
728 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
730 if (!This
->ClockFileObject
|| !This
->ClockTable
.GetCorrelatedPhysicalTime
)
736 Result
= This
->ClockTable
.GetCorrelatedPhysicalTime(This
->ClockFileObject
, SystemTime
);
744 IKsReferenceClock_fnGetResolution(
745 IKsReferenceClock
* iface
,
746 OUT PKSRESOLUTION Resolution
)
751 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
753 DPRINT1("IKsReferenceClock_fnGetResolution\n");
755 if (!This
->ClockFileObject
)
757 Resolution
->Error
= 0;
758 Resolution
->Granularity
= 1;
759 DPRINT1("IKsReferenceClock_fnGetResolution Using HACK\n");
760 return STATUS_SUCCESS
;
764 if (!This
->ClockFileObject
)
765 return STATUS_DEVICE_NOT_READY
;
768 Property
.Set
= KSPROPSETID_Clock
;
769 Property
.Id
= KSPROPERTY_CLOCK_RESOLUTION
;
770 Property
.Flags
= KSPROPERTY_TYPE_GET
;
772 return KsSynchronousIoControlDevice(This
->ClockFileObject
, KernelMode
, IOCTL_KS_PROPERTY
, &Property
, sizeof(KSPROPERTY
), Resolution
, sizeof(KSRESOLUTION
), &BytesReturned
);
778 IKsReferenceClock_fnGetState(
779 IKsReferenceClock
* iface
,
785 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
787 DPRINT1("IKsReferenceClock_fnGetState\n");
789 if (!This
->ClockFileObject
)
791 *State
= This
->Pin
.ClientState
;
792 DPRINT1("IKsReferenceClock_fnGetState Using HACK\n");
793 return STATUS_SUCCESS
;
797 if (!This
->ClockFileObject
)
798 return STATUS_DEVICE_NOT_READY
;
801 Property
.Set
= KSPROPSETID_Clock
;
802 Property
.Id
= KSPROPERTY_CLOCK_RESOLUTION
;
803 Property
.Flags
= KSPROPERTY_TYPE_GET
;
805 return KsSynchronousIoControlDevice(This
->ClockFileObject
, KernelMode
, IOCTL_KS_PROPERTY
, &Property
, sizeof(KSPROPERTY
), State
, sizeof(KSSTATE
), &BytesReturned
);
808 static IKsReferenceClockVtbl vt_ReferenceClock
=
810 IKsReferenceClock_fnQueryInterface
,
811 IKsReferenceClock_fnAddRef
,
812 IKsReferenceClock_fnRelease
,
813 IKsReferenceClock_fnGetTime
,
814 IKsReferenceClock_fnGetPhysicalTime
,
815 IKsReferenceClock_fnGetCorrelatedTime
,
816 IKsReferenceClock_fnGetCorrelatedPhysicalTime
,
817 IKsReferenceClock_fnGetResolution
,
818 IKsReferenceClock_fnGetState
822 //==============================================================
830 KsPinAcquireProcessingMutex(
833 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
835 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
845 IN PKSGATE AndGate OPTIONAL
)
847 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
849 /* FIXME attach to filter's and gate (filter-centric processing) */
851 This
->AttachedGate
= AndGate
;
852 This
->OrGate
= FALSE
;
862 IN PKSGATE OrGate OPTIONAL
)
864 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
866 /* FIXME attach to filter's and gate (filter-centric processing) */
868 This
->AttachedGate
= OrGate
;
880 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
882 return This
->AttachedGate
;
890 KsPinAttemptProcessing(
892 IN BOOLEAN Asynchronous
)
894 DPRINT("KsPinAttemptProcessing\n");
904 KsPinGetAvailableByteCount(
906 OUT PLONG InputDataBytes OPTIONAL
,
907 OUT PLONG OutputBufferBytes OPTIONAL
)
910 return STATUS_NOT_IMPLEMENTED
;
918 KsPinGetConnectedFilterInterface(
920 IN
const GUID
* InterfaceId
,
921 OUT PVOID
* Interface
)
924 return STATUS_NOT_IMPLEMENTED
;
932 KsPinGetConnectedPinDeviceObject(
944 KsPinGetConnectedPinFileObject(
956 KsPinGetConnectedPinInterface(
958 IN
const GUID
* InterfaceId
,
959 OUT PVOID
* Interface
)
962 return STATUS_NOT_IMPLEMENTED
;
970 KsPinGetCopyRelationships(
972 OUT PKSPIN
* CopySource
,
973 OUT PKSPIN
* DelegateBranch
)
983 KsPinGetNextSiblingPin(
986 return KsGetNextSibling((PVOID
)Pin
);
994 KsPinGetParentFilter(
997 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
999 /* return parent filter */
1000 return This
->BasicHeader
.Parent
.KsFilter
;
1008 KsPinGetReferenceClockInterface(
1010 OUT PIKSREFERENCECLOCK
* Interface
)
1012 NTSTATUS Status
= STATUS_DEVICE_NOT_READY
;
1013 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1015 if (This
->ClockFileObject
)
1017 /* clock is available */
1018 *Interface
= (PIKSREFERENCECLOCK
)&This
->lpVtblReferenceClock
;
1019 Status
= STATUS_SUCCESS
;
1022 *Interface
= (PIKSREFERENCECLOCK
)&This
->lpVtblReferenceClock
;
1023 Status
= STATUS_SUCCESS
;
1025 DPRINT("KsPinGetReferenceClockInterface Pin %p Interface %p Status %x\n", Pin
, Interface
, Status
);
1035 KsPinRegisterFrameReturnCallback(
1037 IN PFNKSPINFRAMERETURN FrameReturn
)
1039 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1041 /* register frame return callback */
1042 This
->FrameReturn
= FrameReturn
;
1050 KsPinRegisterHandshakeCallback(
1052 IN PFNKSPINHANDSHAKE Handshake
)
1054 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1056 /* register private protocol handshake callback */
1057 This
->Handshake
= Handshake
;
1065 KsPinRegisterIrpCompletionCallback(
1067 IN PFNKSPINIRPCOMPLETION IrpCompletion
)
1069 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1071 /* register irp completion callback */
1072 This
->IrpCompletion
= IrpCompletion
;
1080 KsPinRegisterPowerCallbacks(
1082 IN PFNKSPINPOWER Sleep OPTIONAL
,
1083 IN PFNKSPINPOWER Wake OPTIONAL
)
1085 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1087 /* register power callbacks */
1088 This
->Sleep
= Sleep
;
1097 KsPinReleaseProcessingMutex(
1100 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1102 /* release processing mutex */
1103 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
1115 PKSIOBJECT_HEADER ObjectHeader
;
1117 PKSBASIC_HEADER Header
;
1118 PIO_STACK_LOCATION IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1120 DPRINT("KsGetPinFromIrp\n");
1122 /* get object header */
1123 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
1128 Pin
= (PKSPIN
)ObjectHeader
->ObjectType
;
1129 Header
= (PKSBASIC_HEADER
)((ULONG_PTR
)Pin
- sizeof(KSBASIC_HEADER
));
1132 ASSERT(Header
->Type
== KsObjectTypePin
);
1134 /* return object type */
1145 KsPinSetPinClockTime(
1159 IN PVOID Data OPTIONAL
,
1160 IN ULONG Size OPTIONAL
,
1161 IN PKSSTREAM_HEADER StreamHeader OPTIONAL
,
1162 IN PVOID Context OPTIONAL
)
1165 return STATUS_UNSUCCESSFUL
;
1174 KsPinSubmitFrameMdl(
1176 IN PMDL Mdl OPTIONAL
,
1177 IN PKSSTREAM_HEADER StreamHeader OPTIONAL
,
1178 IN PVOID Context OPTIONAL
)
1181 return STATUS_UNSUCCESSFUL
;
1191 IN PKSPROCESSPIN ProcessPin
)
1203 KsPinGetLeadingEdgeStreamPointer(
1205 IN KSSTREAM_POINTER_STATE State
)
1208 DPRINT("KsPinGetLeadingEdgeStreamPointer Pin %p State %x\n", Pin
, State
);
1219 KsPinGetTrailingEdgeStreamPointer(
1221 IN KSSTREAM_POINTER_STATE State
)
1233 KsStreamPointerSetStatusCode(
1234 IN PKSSTREAM_POINTER StreamPointer
,
1238 return STATUS_UNSUCCESSFUL
;
1247 KsStreamPointerLock(
1248 IN PKSSTREAM_POINTER StreamPointer
)
1251 return STATUS_UNSUCCESSFUL
;
1260 KsStreamPointerUnlock(
1261 IN PKSSTREAM_POINTER StreamPointer
,
1265 DPRINT("KsStreamPointerUnlock\n");
1275 KsStreamPointerAdvanceOffsetsAndUnlock(
1276 IN PKSSTREAM_POINTER StreamPointer
,
1281 DPRINT("KsStreamPointerAdvanceOffsets\n");
1292 KsStreamPointerDelete(
1293 IN PKSSTREAM_POINTER StreamPointer
)
1296 PKSISTREAM_POINTER Cur
, Last
;
1297 PKSISTREAM_POINTER Pointer
= (PKSISTREAM_POINTER
)StreamPointer
;
1299 DPRINT("KsStreamPointerDelete\n");
1301 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pointer
->StreamPointer
.Pin
, IKsPinImpl
, Pin
);
1303 /* point to first stream pointer */
1305 Cur
= This
->ClonedStreamPointer
;
1307 while(Cur
!= Pointer
&& Cur
)
1310 /* iterate to next cloned pointer */
1316 /* you naughty driver */
1322 /* remove first cloned pointer */
1323 This
->ClonedStreamPointer
= Pointer
->Next
;
1327 Last
->Next
= Pointer
->Next
;
1330 /* FIXME make sure no timeouts are pending */
1340 KsStreamPointerClone(
1341 IN PKSSTREAM_POINTER StreamPointer
,
1342 IN PFNKSSTREAMPOINTER CancelCallback OPTIONAL
,
1343 IN ULONG ContextSize
,
1344 OUT PKSSTREAM_POINTER
* CloneStreamPointer
)
1347 DPRINT("KsStreamPointerClone\n");
1349 return STATUS_NOT_IMPLEMENTED
;
1358 KsStreamPointerAdvanceOffsets(
1359 IN PKSSTREAM_POINTER StreamPointer
,
1365 return STATUS_NOT_IMPLEMENTED
;
1374 KsStreamPointerAdvance(
1375 IN PKSSTREAM_POINTER StreamPointer
)
1378 return STATUS_NOT_IMPLEMENTED
;
1387 KsStreamPointerGetMdl(
1388 IN PKSSTREAM_POINTER StreamPointer
)
1400 KsStreamPointerGetIrp(
1401 IN PKSSTREAM_POINTER StreamPointer
,
1402 OUT PBOOLEAN FirstFrameInIrp OPTIONAL
,
1403 OUT PBOOLEAN LastFrameInIrp OPTIONAL
)
1415 KsStreamPointerScheduleTimeout(
1416 IN PKSSTREAM_POINTER StreamPointer
,
1417 IN PFNKSSTREAMPOINTER Callback
,
1418 IN ULONGLONG Interval
)
1420 LARGE_INTEGER DueTime
;
1421 PKSISTREAM_POINTER Pointer
= (PKSISTREAM_POINTER
)StreamPointer
;
1423 /* setup timer callback */
1424 Pointer
->Callback
= Callback
;
1426 /* setup expiration */
1427 DueTime
.QuadPart
= (LONGLONG
)Interval
;
1429 /* setup the timer */
1430 KeSetTimer(&Pointer
->Timer
, DueTime
, &Pointer
->TimerDpc
);
1440 KsStreamPointerCancelTimeout(
1441 IN PKSSTREAM_POINTER StreamPointer
)
1443 PKSISTREAM_POINTER Pointer
= (PKSISTREAM_POINTER
)StreamPointer
;
1445 KeCancelTimer(&Pointer
->Timer
);
1455 KsPinGetFirstCloneStreamPointer(
1460 DPRINT("KsPinGetFirstCloneStreamPointer %p\n", Pin
);
1462 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1463 /* return first cloned stream pointer */
1464 return &This
->ClonedStreamPointer
->StreamPointer
;
1473 KsStreamPointerGetNextClone(
1474 IN PKSSTREAM_POINTER StreamPointer
)
1476 PKSISTREAM_POINTER Pointer
= (PKSISTREAM_POINTER
)StreamPointer
;
1478 DPRINT("KsStreamPointerGetNextClone\n");
1480 /* is there a another cloned stream pointer */
1484 /* return next stream pointer */
1485 return &Pointer
->Next
->StreamPointer
;
1488 IKsPin_DispatchKsStream(
1489 PDEVICE_OBJECT DeviceObject
,
1493 PKSPROCESSPIN_INDEXENTRY ProcessPinIndex
;
1495 NTSTATUS Status
= STATUS_SUCCESS
;
1497 DPRINT("IKsPin_DispatchKsStream\n");
1499 /* FIXME handle reset states */
1500 ASSERT(This
->Pin
.ResetState
== KSRESET_END
);
1502 /* mark irp as pending */
1503 IoMarkIrpPending(Irp
);
1505 /* add irp to cancelable queue */
1506 KsAddIrpToCancelableQueue(&This
->IrpList
, &This
->IrpListLock
, Irp
, KsListEntryTail
, NULL
/* FIXME */);
1508 if (This
->Pin
.Descriptor
->Dispatch
->Process
)
1510 /* it is a pin centric avstream */
1512 //Status = This->Pin.Descriptor->Dispatch->Process(&This->Pin);
1517 /* filter-centric avstream */
1518 ASSERT(This
->Filter
);
1520 ProcessPinIndex
= This
->Filter
->lpVtbl
->GetProcessDispatch(This
->Filter
);
1521 Filter
= This
->Filter
->lpVtbl
->GetStruct(This
->Filter
);
1523 ASSERT(ProcessPinIndex
);
1525 ASSERT(Filter
->Descriptor
);
1526 ASSERT(Filter
->Descriptor
->Dispatch
);
1528 if (!Filter
->Descriptor
->Dispatch
->Process
)
1530 /* invalid device request */
1531 DPRINT("Filter Centric Processing No Process Routine\n");
1532 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1533 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1534 return STATUS_UNSUCCESSFUL
;
1537 Status
= Filter
->Descriptor
->Dispatch
->Process(Filter
, ProcessPinIndex
);
1539 DPRINT("IKsPin_DispatchKsStream FilterCentric: Status %lx \n", Status
);
1547 IKsPin_DispatchKsProperty(
1548 PDEVICE_OBJECT DeviceObject
,
1553 PKSPROPERTY Property
;
1554 PIO_STACK_LOCATION IoStack
;
1555 UNICODE_STRING GuidString
;
1556 ULONG PropertySetsCount
= 0, PropertyItemSize
= 0;
1557 const KSPROPERTY_SET
* PropertySets
= NULL
;
1560 ASSERT(This
->Pin
.Descriptor
);
1562 /* get current irp stack */
1563 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1566 if (This
->Pin
.Descriptor
->AutomationTable
)
1568 /* use available driver property sets */
1569 PropertySetsCount
= This
->Pin
.Descriptor
->AutomationTable
->PropertySetsCount
;
1570 PropertySets
= This
->Pin
.Descriptor
->AutomationTable
->PropertySets
;
1571 PropertyItemSize
= This
->Pin
.Descriptor
->AutomationTable
->PropertyItemSize
;
1575 /* try driver provided property sets */
1576 Status
= KspPropertyHandler(Irp
,
1582 if (Status
!= STATUS_NOT_FOUND
)
1584 /* property was handled by driver */
1585 if (Status
!= STATUS_PENDING
)
1587 Irp
->IoStatus
.Status
= Status
;
1588 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1593 /* try our properties */
1594 Status
= KspPropertyHandler(Irp
,
1595 sizeof(PinPropertySet
) / sizeof(KSPROPERTY_SET
),
1600 if (Status
!= STATUS_NOT_FOUND
)
1602 /* property was handled by driver */
1603 if (Status
!= STATUS_PENDING
)
1605 Irp
->IoStatus
.Status
= Status
;
1606 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1611 /* property was not handled */
1612 Property
= (PKSPROPERTY
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1614 RtlStringFromGUID(&Property
->Set
, &GuidString
);
1615 DPRINT("IKsPin_DispatchKsProperty Unhandled property Set |%S| Id %u Flags %x\n", GuidString
.Buffer
, Property
->Id
, Property
->Flags
);
1616 RtlFreeUnicodeString(&GuidString
);
1618 Irp
->IoStatus
.Status
= STATUS_NOT_FOUND
;
1619 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1621 return STATUS_NOT_FOUND
;
1627 IKsPin_DispatchDeviceIoControl(
1628 IN PDEVICE_OBJECT DeviceObject
,
1631 PIO_STACK_LOCATION IoStack
;
1632 PKSIOBJECT_HEADER ObjectHeader
;
1635 /* get current irp stack */
1636 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1639 ASSERT(IoStack
->FileObject
);
1640 ASSERT(IoStack
->FileObject
->FsContext2
);
1642 /* get the object header */
1643 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
1645 /* locate ks pin implemention from KSPIN offset */
1646 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
1648 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_PROPERTY
)
1650 /* handle ks properties */
1651 return IKsPin_DispatchKsProperty(DeviceObject
, Irp
, This
);
1654 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_WRITE_STREAM
||
1655 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_READ_STREAM
)
1657 /* handle ks properties */
1658 return IKsPin_DispatchKsStream(DeviceObject
, Irp
, This
);
1662 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
1663 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1664 return STATUS_NOT_IMPLEMENTED
;
1670 IN PDEVICE_OBJECT DeviceObject
,
1673 PIO_STACK_LOCATION IoStack
;
1674 PKSIOBJECT_HEADER ObjectHeader
;
1676 NTSTATUS Status
= STATUS_SUCCESS
;
1678 /* get current irp stack */
1679 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1682 ASSERT(IoStack
->FileObject
);
1683 ASSERT(IoStack
->FileObject
->FsContext2
);
1685 /* get the object header */
1686 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
1688 /* locate ks pin implemention fro KSPIN offset */
1689 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
1691 /* acquire filter control mutex */
1692 KsFilterAcquireControl(&This
->Pin
);
1694 if (This
->Pin
.Descriptor
->Dispatch
->Close
)
1696 /* call pin close routine */
1697 Status
= This
->Pin
.Descriptor
->Dispatch
->Close(&This
->Pin
, Irp
);
1699 if (!NT_SUCCESS(Status
))
1702 Irp
->IoStatus
.Status
= Status
;
1703 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1707 /* FIXME remove pin from filter pin list and decrement reference count */
1709 if (Status
!= STATUS_PENDING
)
1711 Irp
->IoStatus
.Status
= Status
;
1712 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1717 /* release filter control mutex */
1718 KsFilterReleaseControl(&This
->Pin
);
1725 IKsPin_DispatchCreateAllocator(
1726 IN PDEVICE_OBJECT DeviceObject
,
1731 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
1732 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1733 return STATUS_NOT_IMPLEMENTED
;
1738 IKsPin_DispatchCreateClock(
1739 IN PDEVICE_OBJECT DeviceObject
,
1743 NTSTATUS Status
= STATUS_SUCCESS
;
1745 KSRESOLUTION Resolution
;
1746 PKSRESOLUTION pResolution
= NULL
;
1747 PKSOBJECT_CREATE_ITEM CreateItem
;
1749 DPRINT("IKsPin_DispatchCreateClock\n");
1751 /* get the create item */
1752 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
1757 /* get the pin object */
1758 Pin
= (PKSPIN
)CreateItem
->Context
;
1763 /* locate ks pin implemention fro KSPIN offset */
1764 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1767 ASSERT(This
->BasicHeader
.Type
== KsObjectTypePin
);
1768 ASSERT(This
->BasicHeader
.ControlMutex
);
1770 /* acquire control mutex */
1771 KsAcquireControl(Pin
);
1773 if ((This
->Pin
.Descriptor
->PinDescriptor
.Communication
!= KSPIN_COMMUNICATION_NONE
&&
1774 This
->Pin
.Descriptor
->Dispatch
) ||
1775 (This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_IMPLEMENT_CLOCK
))
1777 if (!This
->DefaultClock
)
1779 if (This
->Pin
.Descriptor
->Dispatch
&& This
->Pin
.Descriptor
->Dispatch
->Clock
)
1781 if (This
->Pin
.Descriptor
->Dispatch
->Clock
->Resolution
)
1783 This
->Pin
.Descriptor
->Dispatch
->Clock
->Resolution(&This
->Pin
, &Resolution
);
1784 pResolution
= &Resolution
;
1787 Status
= KsAllocateDefaultClockEx(&This
->DefaultClock
,
1789 (PFNKSSETTIMER
)This
->Pin
.Descriptor
->Dispatch
->Clock
->SetTimer
,
1790 (PFNKSCANCELTIMER
)This
->Pin
.Descriptor
->Dispatch
->Clock
->CancelTimer
,
1791 (PFNKSCORRELATEDTIME
)This
->Pin
.Descriptor
->Dispatch
->Clock
->CorrelatedTime
,
1797 Status
= KsAllocateDefaultClockEx(&This
->DefaultClock
, (PVOID
)&This
->Pin
, NULL
, NULL
, NULL
, NULL
, 0);
1801 if (NT_SUCCESS(Status
))
1803 Status
= KsCreateDefaultClock(Irp
, This
->DefaultClock
);
1807 DPRINT("IKsPin_DispatchCreateClock %lx\n", Status
);
1809 /* release control mutex */
1810 KsReleaseControl(Pin
);
1813 Irp
->IoStatus
.Status
= Status
;
1814 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1820 IKsPin_DispatchCreateNode(
1821 IN PDEVICE_OBJECT DeviceObject
,
1826 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
1827 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1828 return STATUS_NOT_IMPLEMENTED
;
1831 static KSDISPATCH_TABLE PinDispatchTable
=
1833 IKsPin_DispatchDeviceIoControl
,
1834 KsDispatchInvalidDeviceRequest
,
1835 KsDispatchInvalidDeviceRequest
,
1836 KsDispatchInvalidDeviceRequest
,
1838 KsDispatchQuerySecurity
,
1839 KsDispatchSetSecurity
,
1840 KsDispatchFastIoDeviceControlFailure
,
1841 KsDispatchFastReadFailure
,
1842 KsDispatchFastReadFailure
1847 IN PDEVICE_OBJECT DeviceObject
,
1849 IN PKSDEVICE KsDevice
,
1850 IN IKsFilterFactory
* FilterFactory
,
1851 IN IKsFilter
* Filter
,
1852 IN PKSPIN_CONNECT Connect
,
1853 IN KSPIN_DESCRIPTOR_EX
* Descriptor
)
1856 PIO_STACK_LOCATION IoStack
;
1858 PDEVICE_EXTENSION DeviceExtension
;
1859 PKSOBJECT_CREATE_ITEM CreateItem
;
1861 PKSDATAFORMAT DataFormat
;
1862 PKSBASIC_HEADER BasicHeader
;
1865 ASSERT(Descriptor
->Dispatch
);
1867 DPRINT("KspCreatePin PinId %lu Flags %x\n", Connect
->PinId
, Descriptor
->Flags
);
1869 //Output Pin: KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY
1870 //Input Pin: KSPIN_FLAG_FIXED_FORMAT|KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT|KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING
1872 /* get current irp stack */
1873 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1875 /* get device extension */
1876 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1878 /* get ks device interface */
1879 Device
= (IKsDevice
*)&DeviceExtension
->DeviceHeader
->lpVtblIKsDevice
;
1881 /* first allocate pin ctx */
1882 This
= AllocateItem(NonPagedPool
, sizeof(IKsPinImpl
));
1885 /* not enough memory */
1886 return STATUS_INSUFFICIENT_RESOURCES
;
1889 /* allocate create item */
1890 CreateItem
= AllocateItem(NonPagedPool
, sizeof(KSOBJECT_CREATE_ITEM
) * 3);
1893 /* not enough memory */
1895 DPRINT("KspCreatePin OutOfMemory\n");
1896 return STATUS_INSUFFICIENT_RESOURCES
;
1899 /* initialize basic header */
1900 This
->BasicHeader
.KsDevice
= KsDevice
;
1901 This
->BasicHeader
.Type
= KsObjectTypePin
;
1902 This
->BasicHeader
.Parent
.KsFilter
= Filter
->lpVtbl
->GetStruct(Filter
);
1904 ASSERT(This
->BasicHeader
.Parent
.KsFilter
);
1906 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)This
->BasicHeader
.Parent
.KsFilter
- sizeof(KSBASIC_HEADER
));
1908 This
->BasicHeader
.ControlMutex
= BasicHeader
->ControlMutex
;
1909 ASSERT(This
->BasicHeader
.ControlMutex
);
1912 InitializeListHead(&This
->BasicHeader
.EventList
);
1913 KeInitializeSpinLock(&This
->BasicHeader
.EventListLock
);
1915 /* initialize pin */
1916 This
->lpVtbl
= &vt_IKsPin
;
1917 This
->lpVtblReferenceClock
= &vt_ReferenceClock
;
1919 This
->FileObject
= IoStack
->FileObject
;
1920 This
->Filter
= Filter
;
1921 KeInitializeMutex(&This
->ProcessingMutex
, 0);
1922 InitializeListHead(&This
->IrpList
);
1923 KeInitializeSpinLock(&This
->IrpListLock
);
1926 /* allocate object bag */
1927 This
->Pin
.Bag
= AllocateItem(NonPagedPool
, sizeof(KSIOBJECT_BAG
));
1930 /* not enough memory */
1932 FreeItem(CreateItem
);
1933 return STATUS_INSUFFICIENT_RESOURCES
;
1936 /* initialize object bag */
1937 Device
->lpVtbl
->InitializeObjectBag(Device
, This
->Pin
.Bag
, NULL
);
1940 DataFormat
= (PKSDATAFORMAT
)(Connect
+ 1);
1942 /* initialize pin descriptor */
1943 This
->Pin
.Descriptor
= Descriptor
;
1944 This
->Pin
.Context
= NULL
;
1945 This
->Pin
.Id
= Connect
->PinId
;
1946 This
->Pin
.Communication
= Descriptor
->PinDescriptor
.Communication
;
1947 This
->Pin
.ConnectionIsExternal
= FALSE
; //FIXME
1948 RtlMoveMemory(&This
->Pin
.ConnectionInterface
, &Connect
->Interface
, sizeof(KSPIN_INTERFACE
));
1949 RtlMoveMemory(&This
->Pin
.ConnectionMedium
, &Connect
->Medium
, sizeof(KSPIN_MEDIUM
));
1950 RtlMoveMemory(&This
->Pin
.ConnectionPriority
, &Connect
->Priority
, sizeof(KSPRIORITY
));
1952 /* allocate format */
1953 Status
= _KsEdit(This
->Pin
.Bag
, (PVOID
*)&This
->Pin
.ConnectionFormat
, DataFormat
->FormatSize
, DataFormat
->FormatSize
, 0);
1954 if (!NT_SUCCESS(Status
))
1956 /* failed to allocate format */
1957 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
1959 FreeItem(CreateItem
);
1960 return STATUS_INSUFFICIENT_RESOURCES
;
1964 RtlMoveMemory((PVOID
)This
->Pin
.ConnectionFormat
, DataFormat
, DataFormat
->FormatSize
);
1966 This
->Pin
.AttributeList
= NULL
; //FIXME
1967 This
->Pin
.StreamHeaderSize
= sizeof(KSSTREAM_HEADER
);
1968 This
->Pin
.DataFlow
= Descriptor
->PinDescriptor
.DataFlow
;
1969 This
->Pin
.DeviceState
= KSSTATE_STOP
;
1970 This
->Pin
.ResetState
= KSRESET_END
;
1971 This
->Pin
.ClientState
= KSSTATE_STOP
;
1973 /* intialize allocator create item */
1974 CreateItem
[0].Context
= (PVOID
)&This
->Pin
;
1975 CreateItem
[0].Create
= IKsPin_DispatchCreateAllocator
;
1976 CreateItem
[0].Flags
= KSCREATE_ITEM_FREEONSTOP
;
1977 RtlInitUnicodeString(&CreateItem
[0].ObjectClass
, KSSTRING_Allocator
);
1979 /* intialize clock create item */
1980 CreateItem
[1].Context
= (PVOID
)&This
->Pin
;
1981 CreateItem
[1].Create
= IKsPin_DispatchCreateClock
;
1982 CreateItem
[1].Flags
= KSCREATE_ITEM_FREEONSTOP
;
1983 RtlInitUnicodeString(&CreateItem
[1].ObjectClass
, KSSTRING_Clock
);
1985 /* intialize topology node create item */
1986 CreateItem
[2].Context
= (PVOID
)&This
->Pin
;
1987 CreateItem
[2].Create
= IKsPin_DispatchCreateNode
;
1988 CreateItem
[2].Flags
= KSCREATE_ITEM_FREEONSTOP
;
1989 RtlInitUnicodeString(&CreateItem
[2].ObjectClass
, KSSTRING_TopologyNode
);
1991 /* now allocate object header */
1992 Status
= KsAllocateObjectHeader((KSOBJECT_HEADER
*)&This
->ObjectHeader
, 3, CreateItem
, Irp
, &PinDispatchTable
);
1993 if (!NT_SUCCESS(Status
))
1995 /* failed to create object header */
1996 DPRINT("KspCreatePin KsAllocateObjectHeader failed %lx\n", Status
);
1997 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
1999 FreeItem(CreateItem
);
2001 /* return failure code */
2005 /* add extra info to object header */
2006 This
->ObjectHeader
->Type
= KsObjectTypePin
;
2007 This
->ObjectHeader
->Unknown
= (PUNKNOWN
)&This
->lpVtbl
;
2008 This
->ObjectHeader
->ObjectType
= (PVOID
)&This
->Pin
;
2010 if (!Descriptor
->Dispatch
|| !Descriptor
->Dispatch
->Process
)
2012 /* the pin is part of filter-centric processing filter
2013 * add process pin to filter
2015 This
->ProcessPin
.BytesAvailable
= 0;
2016 This
->ProcessPin
.BytesUsed
= 0;
2017 This
->ProcessPin
.CopySource
= NULL
;
2018 This
->ProcessPin
.Data
= NULL
;
2019 This
->ProcessPin
.DelegateBranch
= NULL
;
2020 This
->ProcessPin
.Flags
= 0;
2021 This
->ProcessPin
.InPlaceCounterpart
= NULL
;
2022 This
->ProcessPin
.Pin
= &This
->Pin
;
2023 This
->ProcessPin
.StreamPointer
= (PKSSTREAM_POINTER
)This
->LeadingEdgeStreamPointer
;
2024 This
->ProcessPin
.Terminate
= FALSE
;
2026 Status
= Filter
->lpVtbl
->AddProcessPin(Filter
, &This
->ProcessPin
);
2027 DPRINT("KspCreatePin AddProcessPin %lx\n", Status
);
2029 if (!NT_SUCCESS(Status
))
2031 /* failed to add process pin */
2032 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2033 KsFreeObjectHeader(&This
->ObjectHeader
);
2035 FreeItem(CreateItem
);
2036 /* return failure code */
2041 /* FIXME add pin instance to filter instance */
2044 if (Descriptor
->Dispatch
&& Descriptor
->Dispatch
->SetDataFormat
)
2046 Status
= Descriptor
->Dispatch
->SetDataFormat(&This
->Pin
, NULL
, NULL
, This
->Pin
.ConnectionFormat
, NULL
);
2047 DPRINT("KspCreatePin SetDataFormat %lx\n", Status
);
2052 /* does the driver have a pin dispatch */
2053 if (Descriptor
->Dispatch
&& Descriptor
->Dispatch
->Create
)
2055 /* now inform the driver to create a new pin */
2056 Status
= Descriptor
->Dispatch
->Create(&This
->Pin
, Irp
);
2057 DPRINT("KspCreatePin DispatchCreate %lx\n", Status
);
2062 DPRINT("KspCreatePin Status %lx\n", Status
);
2064 if (!NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
)
2066 /* failed to create pin, release resources */
2067 KsFreeObjectHeader((KSOBJECT_HEADER
)This
->ObjectHeader
);
2068 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2071 /* return failure code */