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
;
155 ASSERT(ObjectHeader
);
157 /* locate ks pin implemention from KSPIN offset */
158 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
163 Handle
= (PHANDLE
)Data
;
165 if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
167 if (This
->Pin
.Descriptor
->PinDescriptor
.Communication
!= KSPIN_COMMUNICATION_NONE
&&
168 This
->Pin
.Descriptor
->Dispatch
&&
169 (This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_IMPLEMENT_CLOCK
))
172 Status
= STATUS_SUCCESS
;
176 /* no clock available */
177 Status
= STATUS_UNSUCCESSFUL
;
180 else if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
182 if (This
->Pin
.ClientState
!= KSSTATE_STOP
)
184 /* can only set in stopped state */
185 Status
= STATUS_INVALID_DEVICE_STATE
;
191 Mode
= ExGetPreviousMode();
193 Status
= ObReferenceObjectByHandle(*Handle
, SYNCHRONIZE
| DIRECTORY_QUERY
, IoFileObjectType
, Mode
, (PVOID
*)&FileObject
, NULL
);
195 DPRINT("IKsPin_PinMasterClock ObReferenceObjectByHandle %lx\n", Status
);
196 if (NT_SUCCESS(Status
))
198 Property
.Set
= KSPROPSETID_Clock
;
199 Property
.Id
= KSPROPERTY_CLOCK_FUNCTIONTABLE
;
200 Property
.Flags
= KSPROPERTY_TYPE_GET
;
202 Status
= KsSynchronousIoControlDevice(FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, &Property
, sizeof(KSPROPERTY
), &This
->ClockTable
, sizeof(KSCLOCK_FUNCTIONTABLE
), &BytesReturned
);
204 DPRINT("IKsPin_PinMasterClock KSPROPERTY_CLOCK_FUNCTIONTABLE %lx\n", Status
);
206 if (NT_SUCCESS(Status
))
208 This
->ClockFileObject
= FileObject
;
212 ObDereferenceObject(FileObject
);
218 /* zeroing clock handle */
219 RtlZeroMemory(&This
->ClockTable
, sizeof(KSCLOCK_FUNCTIONTABLE
));
220 Status
= STATUS_SUCCESS
;
221 if (This
->ClockFileObject
)
223 FileObject
= This
->ClockFileObject
;
224 This
->ClockFileObject
= NULL
;
226 ObDereferenceObject(This
->ClockFileObject
);
232 DPRINT("IKsPin_PinMasterClock 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_DispatchDeviceIoControl(
1913 IN PDEVICE_OBJECT DeviceObject
,
1916 PIO_STACK_LOCATION IoStack
;
1917 PKSIOBJECT_HEADER ObjectHeader
;
1920 UNICODE_STRING GuidString
;
1921 PKSPROPERTY Property
;
1924 /* get current irp stack */
1925 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1928 ASSERT(IoStack
->FileObject
);
1929 ASSERT(IoStack
->FileObject
->FsContext2
);
1931 /* get the object header */
1932 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
1934 /* locate ks pin implemention from KSPIN offset */
1935 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
1937 /* current irp stack */
1938 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1940 /* get property from input buffer */
1941 Property
= (PKSPROPERTY
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1944 ASSERT(IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
>= sizeof(KSIDENTIFIER
));
1945 ASSERT(This
->Pin
.Descriptor
->AutomationTable
);
1947 RtlStringFromGUID(&Property
->Set
, &GuidString
);
1948 DPRINT("IKsPin_DispatchDeviceIoControl property Set |%S| Id %u Flags %x\n", GuidString
.Buffer
, Property
->Id
, Property
->Flags
);
1949 RtlFreeUnicodeString(&GuidString
);
1952 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_METHOD
)
1954 const KSMETHOD_SET
*MethodSet
= NULL
;
1955 ULONG MethodItemSize
= 0;
1957 /* check if the driver supports method sets */
1958 if (This
->Pin
.Descriptor
->AutomationTable
->MethodSetsCount
)
1960 SetCount
= This
->Pin
.Descriptor
->AutomationTable
->MethodSetsCount
;
1961 MethodSet
= This
->Pin
.Descriptor
->AutomationTable
->MethodSets
;
1962 MethodItemSize
= This
->Pin
.Descriptor
->AutomationTable
->MethodItemSize
;
1965 /* call method set handler */
1966 Status
= KspMethodHandlerWithAllocator(Irp
, SetCount
, MethodSet
, NULL
, MethodItemSize
);
1968 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_PROPERTY
)
1970 const KSPROPERTY_SET
*PropertySet
= NULL
;
1971 ULONG PropertyItemSize
= 0;
1973 /* check if the driver supports method sets */
1974 if (This
->Pin
.Descriptor
->AutomationTable
->PropertySetsCount
)
1976 SetCount
= This
->Pin
.Descriptor
->AutomationTable
->PropertySetsCount
;
1977 PropertySet
= This
->Pin
.Descriptor
->AutomationTable
->PropertySets
;
1978 PropertyItemSize
= This
->Pin
.Descriptor
->AutomationTable
->PropertyItemSize
;
1981 /* needed for our property handlers */
1982 KSPROPERTY_ITEM_IRP_STORAGE(Irp
) = (KSPROPERTY_ITEM
*)This
;
1984 /* call property handler */
1985 Status
= KspPropertyHandler(Irp
, SetCount
, PropertySet
, NULL
, PropertyItemSize
);
1990 ASSERT(IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_ENABLE_EVENT
||
1991 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_DISABLE_EVENT
);
1993 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_ENABLE_EVENT
)
1995 /* call enable event handlers */
1996 Status
= KspEnableEvent(Irp
,
1997 This
->Pin
.Descriptor
->AutomationTable
->EventSetsCount
,
1998 (PKSEVENT_SET
)This
->Pin
.Descriptor
->AutomationTable
->EventSets
,
1999 &This
->BasicHeader
.EventList
,
2001 (PVOID
)&This
->BasicHeader
.EventListLock
,
2003 This
->Pin
.Descriptor
->AutomationTable
->EventItemSize
);
2007 /* disable event handler */
2008 Status
= KsDisableEvent(Irp
, &This
->BasicHeader
.EventList
, KSEVENTS_SPINLOCK
, &This
->BasicHeader
.EventListLock
);
2012 RtlStringFromGUID(&Property
->Set
, &GuidString
);
2013 DPRINT("IKsPin_DispatchDeviceIoControl property Set |%S| Id %u Flags %x Status %lx ResultLength %lu\n", GuidString
.Buffer
, Property
->Id
, Property
->Flags
, Status
, Irp
->IoStatus
.Information
);
2014 RtlFreeUnicodeString(&GuidString
);
2016 if (Status
!= STATUS_PENDING
)
2018 Irp
->IoStatus
.Status
= Status
;
2019 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2029 IN PDEVICE_OBJECT DeviceObject
,
2032 PIO_STACK_LOCATION IoStack
;
2033 PKSIOBJECT_HEADER ObjectHeader
;
2035 NTSTATUS Status
= STATUS_SUCCESS
;
2037 /* get current irp stack */
2038 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2041 ASSERT(IoStack
->FileObject
);
2042 ASSERT(IoStack
->FileObject
->FsContext2
);
2044 /* get the object header */
2045 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
2047 /* locate ks pin implemention fro KSPIN offset */
2048 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
2050 if (This
->Pin
.Descriptor
->Dispatch
->Close
)
2052 /* call pin close routine */
2053 Status
= This
->Pin
.Descriptor
->Dispatch
->Close(&This
->Pin
, Irp
);
2055 if (!NT_SUCCESS(Status
))
2058 Irp
->IoStatus
.Status
= Status
;
2059 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2063 /* remove pin from filter pin list and decrement reference count */
2064 IKsFilter_RemovePin(This
->Filter
->lpVtbl
->GetStruct(This
->Filter
), &This
->Pin
);
2066 if (Status
!= STATUS_PENDING
)
2068 Irp
->IoStatus
.Status
= Status
;
2069 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2079 IKsPin_DispatchCreateAllocator(
2080 IN PDEVICE_OBJECT DeviceObject
,
2085 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
2086 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2087 return STATUS_NOT_IMPLEMENTED
;
2092 IKsPin_DispatchCreateClock(
2093 IN PDEVICE_OBJECT DeviceObject
,
2097 NTSTATUS Status
= STATUS_SUCCESS
;
2099 KSRESOLUTION Resolution
;
2100 PKSRESOLUTION pResolution
= NULL
;
2101 PKSOBJECT_CREATE_ITEM CreateItem
;
2103 DPRINT("IKsPin_DispatchCreateClock\n");
2105 /* get the create item */
2106 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
2111 /* get the pin object */
2112 Pin
= (PKSPIN
)CreateItem
->Context
;
2117 /* locate ks pin implemention fro KSPIN offset */
2118 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
2121 ASSERT(This
->BasicHeader
.Type
== KsObjectTypePin
);
2122 ASSERT(This
->BasicHeader
.ControlMutex
);
2124 /* acquire control mutex */
2125 KsAcquireControl(Pin
);
2127 if ((This
->Pin
.Descriptor
->PinDescriptor
.Communication
!= KSPIN_COMMUNICATION_NONE
&&
2128 This
->Pin
.Descriptor
->Dispatch
) ||
2129 (This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_IMPLEMENT_CLOCK
))
2131 if (!This
->DefaultClock
)
2133 if (This
->Pin
.Descriptor
->Dispatch
&& This
->Pin
.Descriptor
->Dispatch
->Clock
)
2135 if (This
->Pin
.Descriptor
->Dispatch
->Clock
->Resolution
)
2137 This
->Pin
.Descriptor
->Dispatch
->Clock
->Resolution(&This
->Pin
, &Resolution
);
2138 pResolution
= &Resolution
;
2141 Status
= KsAllocateDefaultClockEx(&This
->DefaultClock
,
2143 (PFNKSSETTIMER
)This
->Pin
.Descriptor
->Dispatch
->Clock
->SetTimer
,
2144 (PFNKSCANCELTIMER
)This
->Pin
.Descriptor
->Dispatch
->Clock
->CancelTimer
,
2145 (PFNKSCORRELATEDTIME
)This
->Pin
.Descriptor
->Dispatch
->Clock
->CorrelatedTime
,
2151 Status
= KsAllocateDefaultClockEx(&This
->DefaultClock
, (PVOID
)&This
->Pin
, NULL
, NULL
, NULL
, NULL
, 0);
2155 if (NT_SUCCESS(Status
))
2157 Status
= KsCreateDefaultClock(Irp
, This
->DefaultClock
);
2161 DPRINT("IKsPin_DispatchCreateClock %lx\n", Status
);
2163 /* release control mutex */
2164 KsReleaseControl(Pin
);
2167 Irp
->IoStatus
.Status
= Status
;
2168 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2174 IKsPin_DispatchCreateNode(
2175 IN PDEVICE_OBJECT DeviceObject
,
2180 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
2181 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2182 return STATUS_NOT_IMPLEMENTED
;
2185 static KSDISPATCH_TABLE PinDispatchTable
=
2187 IKsPin_DispatchDeviceIoControl
,
2188 KsDispatchInvalidDeviceRequest
,
2189 KsDispatchInvalidDeviceRequest
,
2190 KsDispatchInvalidDeviceRequest
,
2192 KsDispatchQuerySecurity
,
2193 KsDispatchSetSecurity
,
2194 KsDispatchFastIoDeviceControlFailure
,
2195 KsDispatchFastReadFailure
,
2196 KsDispatchFastReadFailure
2201 IN PDEVICE_OBJECT DeviceObject
,
2203 IN PKSDEVICE KsDevice
,
2204 IN IKsFilterFactory
* FilterFactory
,
2205 IN IKsFilter
* Filter
,
2206 IN PKSPIN_CONNECT Connect
,
2207 IN KSPIN_DESCRIPTOR_EX
* Descriptor
)
2210 PIO_STACK_LOCATION IoStack
;
2212 PDEVICE_EXTENSION DeviceExtension
;
2213 PKSOBJECT_CREATE_ITEM CreateItem
;
2215 PKSDATAFORMAT DataFormat
;
2216 PKSBASIC_HEADER BasicHeader
;
2218 ULONG FrameSize
= 0;
2219 ULONG NumFrames
= 0;
2220 KSAUTOMATION_TABLE AutomationTable
;
2223 ASSERT(Descriptor
->Dispatch
);
2225 DPRINT("KspCreatePin PinId %lu Flags %x\n", Connect
->PinId
, Descriptor
->Flags
);
2227 //Output Pin: KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY
2228 //Input Pin: KSPIN_FLAG_FIXED_FORMAT|KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT|KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING
2231 if (Descriptor
->AllocatorFraming
)
2233 DPRINT("KspCreatePin Dataflow %lu\n", Descriptor
->PinDescriptor
.DataFlow
);
2234 DPRINT("KspCreatePin CountItems %lu\n", Descriptor
->AllocatorFraming
->CountItems
);
2235 DPRINT("KspCreatePin PinFlags %lx\n", Descriptor
->AllocatorFraming
->PinFlags
);
2236 DPRINT("KspCreatePin OutputCompression RatioNumerator %lu RatioDenominator %lu RatioConstantMargin %lu\n", Descriptor
->AllocatorFraming
->OutputCompression
.RatioNumerator
,
2237 Descriptor
->AllocatorFraming
->OutputCompression
.RatioDenominator
, Descriptor
->AllocatorFraming
->OutputCompression
.RatioConstantMargin
);
2238 DPRINT("KspCreatePin PinWeight %lx\n", Descriptor
->AllocatorFraming
->PinWeight
);
2240 for(Index
= 0; Index
< Descriptor
->AllocatorFraming
->CountItems
; Index
++)
2242 DPRINT("KspCreatePin Index %lu MemoryFlags %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].MemoryFlags
);
2243 DPRINT("KspCreatePin Index %lu BusFlags %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].BusFlags
);
2244 DPRINT("KspCreatePin Index %lu Flags %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].Flags
);
2245 DPRINT("KspCreatePin Index %lu Frames %lu\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].Frames
);
2246 DPRINT("KspCreatePin Index %lu FileAlignment %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].FileAlignment
);
2247 DPRINT("KspCreatePin Index %lu MemoryTypeWeight %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].MemoryTypeWeight
);
2248 DPRINT("KspCreatePin Index %lu PhysicalRange MinFrameSize %lu MaxFrameSize %lu Stepping %lu\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].PhysicalRange
.MinFrameSize
,
2249 Descriptor
->AllocatorFraming
->FramingItem
[Index
].PhysicalRange
.MaxFrameSize
,
2250 Descriptor
->AllocatorFraming
->FramingItem
[Index
].PhysicalRange
.Stepping
);
2252 DPRINT("KspCreatePin Index %lu FramingRange MinFrameSize %lu MaxFrameSize %lu Stepping %lu InPlaceWeight %lu NotInPlaceWeight %lu\n",
2254 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.Range
.MinFrameSize
,
2255 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.Range
.MaxFrameSize
,
2256 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.Range
.Stepping
,
2257 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.InPlaceWeight
,
2258 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.NotInPlaceWeight
);
2260 FrameSize
= Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.Range
.MaxFrameSize
;
2261 NumFrames
= Descriptor
->AllocatorFraming
->FramingItem
[Index
].Frames
;
2267 /* default to 50 * 188 (MPEG2 TS packet size) */
2276 /* get current irp stack */
2277 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2279 /* get device extension */
2280 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
2282 /* get ks device interface */
2283 Device
= (IKsDevice
*)&DeviceExtension
->DeviceHeader
->lpVtblIKsDevice
;
2285 /* first allocate pin ctx */
2286 This
= AllocateItem(NonPagedPool
, sizeof(IKsPinImpl
));
2289 /* not enough memory */
2290 return STATUS_INSUFFICIENT_RESOURCES
;
2293 /* allocate create item */
2294 CreateItem
= AllocateItem(NonPagedPool
, sizeof(KSOBJECT_CREATE_ITEM
) * 3);
2297 /* not enough memory */
2299 DPRINT("KspCreatePin OutOfMemory\n");
2300 return STATUS_INSUFFICIENT_RESOURCES
;
2303 /* initialize basic header */
2304 This
->BasicHeader
.KsDevice
= KsDevice
;
2305 This
->BasicHeader
.Type
= KsObjectTypePin
;
2306 This
->BasicHeader
.Parent
.KsFilter
= Filter
->lpVtbl
->GetStruct(Filter
);
2307 InitializeListHead(&This
->BasicHeader
.EventList
);
2308 KeInitializeSpinLock(&This
->BasicHeader
.EventListLock
);
2310 ASSERT(This
->BasicHeader
.Parent
.KsFilter
);
2312 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)This
->BasicHeader
.Parent
.KsFilter
- sizeof(KSBASIC_HEADER
));
2314 This
->BasicHeader
.ControlMutex
= BasicHeader
->ControlMutex
;
2315 ASSERT(This
->BasicHeader
.ControlMutex
);
2317 InitializeListHead(&This
->BasicHeader
.EventList
);
2318 KeInitializeSpinLock(&This
->BasicHeader
.EventListLock
);
2320 /* initialize pin */
2321 This
->lpVtbl
= &vt_IKsPin
;
2322 This
->FrameSize
= FrameSize
;
2323 This
->NumFrames
= NumFrames
;
2324 This
->lpVtblReferenceClock
= &vt_ReferenceClock
;
2326 This
->FileObject
= IoStack
->FileObject
;
2327 This
->Filter
= Filter
;
2328 KeInitializeMutex(&This
->ProcessingMutex
, 0);
2329 InitializeListHead(&This
->IrpList
);
2330 KeInitializeSpinLock(&This
->IrpListLock
);
2332 /* allocate object bag */
2333 This
->Pin
.Bag
= AllocateItem(NonPagedPool
, sizeof(KSIOBJECT_BAG
));
2336 /* not enough memory */
2338 FreeItem(CreateItem
);
2339 return STATUS_INSUFFICIENT_RESOURCES
;
2342 /* initialize object bag */
2343 Device
->lpVtbl
->InitializeObjectBag(Device
, This
->Pin
.Bag
, NULL
);
2345 /* allocate pin descriptor */
2346 This
->Pin
.Descriptor
= AllocateItem(NonPagedPool
, sizeof(KSPIN_DESCRIPTOR_EX
));
2347 if (!This
->Pin
.Descriptor
)
2349 /* not enough memory */
2350 KsFreeObjectBag(This
->Pin
.Bag
);
2352 FreeItem(CreateItem
);
2353 return STATUS_INSUFFICIENT_RESOURCES
;
2356 /* copy pin descriptor */
2357 RtlMoveMemory((PVOID
)This
->Pin
.Descriptor
, Descriptor
, sizeof(KSPIN_DESCRIPTOR_EX
));
2359 /* initialize automation table */
2360 RtlZeroMemory(&AutomationTable
, sizeof(KSAUTOMATION_TABLE
));
2362 AutomationTable
.PropertyItemSize
= sizeof(KSPROPERTY_ITEM
);
2363 AutomationTable
.PropertySets
= PinPropertySet
;
2364 AutomationTable
.PropertySetsCount
= sizeof(PinPropertySet
) / sizeof(KSPROPERTY_SET
);
2366 /* merge in pin property sets */
2367 Status
= KsMergeAutomationTables((PKSAUTOMATION_TABLE
*)&This
->Pin
.Descriptor
->AutomationTable
, (PKSAUTOMATION_TABLE
)Descriptor
->AutomationTable
, &AutomationTable
, This
->Pin
.Bag
);
2369 if (!NT_SUCCESS(Status
))
2371 /* not enough memory */
2372 KsFreeObjectBag(This
->Pin
.Bag
);
2374 FreeItem(CreateItem
);
2379 DataFormat
= (PKSDATAFORMAT
)(Connect
+ 1);
2381 /* initialize pin descriptor */
2382 This
->Pin
.Context
= NULL
;
2383 This
->Pin
.Id
= Connect
->PinId
;
2384 This
->Pin
.Communication
= Descriptor
->PinDescriptor
.Communication
;
2385 This
->Pin
.ConnectionIsExternal
= FALSE
; //FIXME
2386 RtlMoveMemory(&This
->Pin
.ConnectionInterface
, &Connect
->Interface
, sizeof(KSPIN_INTERFACE
));
2387 RtlMoveMemory(&This
->Pin
.ConnectionMedium
, &Connect
->Medium
, sizeof(KSPIN_MEDIUM
));
2388 RtlMoveMemory(&This
->Pin
.ConnectionPriority
, &Connect
->Priority
, sizeof(KSPRIORITY
));
2390 /* allocate format */
2391 Status
= _KsEdit(This
->Pin
.Bag
, (PVOID
*)&This
->Pin
.ConnectionFormat
, DataFormat
->FormatSize
, DataFormat
->FormatSize
, 0);
2392 if (!NT_SUCCESS(Status
))
2394 /* failed to allocate format */
2395 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2397 FreeItem(CreateItem
);
2398 return STATUS_INSUFFICIENT_RESOURCES
;
2402 RtlMoveMemory((PVOID
)This
->Pin
.ConnectionFormat
, DataFormat
, DataFormat
->FormatSize
);
2404 This
->Pin
.AttributeList
= NULL
; //FIXME
2405 This
->Pin
.StreamHeaderSize
= sizeof(KSSTREAM_HEADER
);
2406 This
->Pin
.DataFlow
= Descriptor
->PinDescriptor
.DataFlow
;
2407 This
->Pin
.DeviceState
= KSSTATE_STOP
;
2408 This
->Pin
.ResetState
= KSRESET_END
;
2409 This
->Pin
.ClientState
= KSSTATE_STOP
;
2411 /* intialize allocator create item */
2412 CreateItem
[0].Context
= (PVOID
)&This
->Pin
;
2413 CreateItem
[0].Create
= IKsPin_DispatchCreateAllocator
;
2414 CreateItem
[0].Flags
= KSCREATE_ITEM_FREEONSTOP
;
2415 RtlInitUnicodeString(&CreateItem
[0].ObjectClass
, KSSTRING_Allocator
);
2417 /* intialize clock create item */
2418 CreateItem
[1].Context
= (PVOID
)&This
->Pin
;
2419 CreateItem
[1].Create
= IKsPin_DispatchCreateClock
;
2420 CreateItem
[1].Flags
= KSCREATE_ITEM_FREEONSTOP
;
2421 RtlInitUnicodeString(&CreateItem
[1].ObjectClass
, KSSTRING_Clock
);
2423 /* intialize topology node create item */
2424 CreateItem
[2].Context
= (PVOID
)&This
->Pin
;
2425 CreateItem
[2].Create
= IKsPin_DispatchCreateNode
;
2426 CreateItem
[2].Flags
= KSCREATE_ITEM_FREEONSTOP
;
2427 RtlInitUnicodeString(&CreateItem
[2].ObjectClass
, KSSTRING_TopologyNode
);
2429 /* now allocate object header */
2430 Status
= KsAllocateObjectHeader((KSOBJECT_HEADER
*)&This
->ObjectHeader
, 3, CreateItem
, Irp
, &PinDispatchTable
);
2431 if (!NT_SUCCESS(Status
))
2433 /* failed to create object header */
2434 DPRINT("KspCreatePin KsAllocateObjectHeader failed %lx\n", Status
);
2435 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2437 FreeItem(CreateItem
);
2439 /* return failure code */
2443 /* add extra info to object header */
2444 This
->ObjectHeader
->Type
= KsObjectTypePin
;
2445 This
->ObjectHeader
->Unknown
= (PUNKNOWN
)&This
->lpVtbl
;
2446 This
->ObjectHeader
->ObjectType
= (PVOID
)&This
->Pin
;
2448 if (!Descriptor
->Dispatch
|| !Descriptor
->Dispatch
->Process
)
2450 /* the pin is part of filter-centric processing filter
2451 * add process pin to filter
2453 This
->ProcessPin
.BytesAvailable
= 0;
2454 This
->ProcessPin
.BytesUsed
= 0;
2455 This
->ProcessPin
.CopySource
= NULL
;
2456 This
->ProcessPin
.Data
= NULL
;
2457 This
->ProcessPin
.DelegateBranch
= NULL
;
2458 This
->ProcessPin
.Flags
= 0;
2459 This
->ProcessPin
.InPlaceCounterpart
= NULL
;
2460 This
->ProcessPin
.Pin
= &This
->Pin
;
2461 This
->ProcessPin
.StreamPointer
= (PKSSTREAM_POINTER
)&This
->LeadingEdgeStreamPointer
.StreamPointer
;
2462 This
->ProcessPin
.Terminate
= FALSE
;
2464 Status
= Filter
->lpVtbl
->AddProcessPin(Filter
, &This
->ProcessPin
);
2465 DPRINT("KspCreatePin AddProcessPin %lx\n", Status
);
2467 if (!NT_SUCCESS(Status
))
2469 /* failed to add process pin */
2470 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2471 KsFreeObjectHeader(&This
->ObjectHeader
);
2473 FreeItem(CreateItem
);
2474 /* return failure code */
2478 else if (Descriptor
->Dispatch
&& Descriptor
->Dispatch
->Process
)
2480 /* pin centric processing filter */
2482 /* initialize work item */
2483 ExInitializeWorkItem(&This
->PinWorkQueueItem
, IKsPin_PinCentricWorker
, (PVOID
)This
);
2485 /* allocate counted work item */
2486 Status
= KsRegisterCountedWorker(HyperCriticalWorkQueue
, &This
->PinWorkQueueItem
, &This
->PinWorker
);
2488 if (!NT_SUCCESS(Status
))
2490 DPRINT("Failed to register Worker %lx\n", Status
);
2491 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2492 KsFreeObjectHeader(&This
->ObjectHeader
);
2494 FreeItem(CreateItem
);
2498 if (This
->Pin
.Descriptor
->PinDescriptor
.DataFlow
== KSPIN_DATAFLOW_IN
)
2499 This
->LeadingEdgeStreamPointer
.StreamPointer
.Offset
= &This
->LeadingEdgeStreamPointer
.StreamPointer
.OffsetIn
;
2501 This
->LeadingEdgeStreamPointer
.StreamPointer
.Offset
= &This
->LeadingEdgeStreamPointer
.StreamPointer
.OffsetOut
;
2504 KeInitializeEvent(&This
->FrameComplete
, NotificationEvent
, FALSE
);
2508 /* FIXME add pin instance to filter instance */
2509 IKsFilter_AddPin(Filter
->lpVtbl
->GetStruct(Filter
), &This
->Pin
);
2511 if (Descriptor
->Dispatch
&& Descriptor
->Dispatch
->SetDataFormat
)
2513 Status
= Descriptor
->Dispatch
->SetDataFormat(&This
->Pin
, NULL
, NULL
, This
->Pin
.ConnectionFormat
, NULL
);
2514 DPRINT("KspCreatePin SetDataFormat %lx\n", Status
);
2518 /* does the driver have a pin dispatch */
2519 if (Descriptor
->Dispatch
&& Descriptor
->Dispatch
->Create
)
2521 /* now inform the driver to create a new pin */
2522 Status
= Descriptor
->Dispatch
->Create(&This
->Pin
, Irp
);
2523 DPRINT("KspCreatePin DispatchCreate %lx\n", Status
);
2527 DPRINT("KspCreatePin Status %lx\n", Status
);
2529 if (!NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
)
2531 /* failed to create pin, release resources */
2532 IKsFilter_RemovePin(Filter
->lpVtbl
->GetStruct(Filter
), &This
->Pin
);
2533 KsFreeObjectHeader((KSOBJECT_HEADER
)This
->ObjectHeader
);
2534 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2537 /* return failure code */