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
16 typedef struct _KSISTREAM_POINTER
18 PFNKSSTREAMPOINTER Callback
;
22 struct _KSISTREAM_POINTER
*Next
;
27 KSSTREAM_POINTER StreamPointer
;
29 }KSISTREAM_POINTER
, *PKSISTREAM_POINTER
;
33 KSBASIC_HEADER BasicHeader
;
35 PKSIOBJECT_HEADER ObjectHeader
;
36 KSPROCESSPIN ProcessPin
;
42 KMUTEX ProcessingMutex
;
43 PFILE_OBJECT FileObject
;
49 KSPIN_LOCK IrpListLock
;
50 volatile LONG IrpCount
;
52 PKSISTREAM_POINTER ClonedStreamPointer
;
53 KSISTREAM_POINTER LeadingEdgeStreamPointer
;
54 KSISTREAM_POINTER TrailingStreamPointer
;
58 PFNKSPINHANDSHAKE Handshake
;
59 PFNKSPINFRAMERETURN FrameReturn
;
60 PFNKSPINIRPCOMPLETION IrpCompletion
;
62 KSCLOCK_FUNCTIONTABLE ClockTable
;
63 PFILE_OBJECT ClockFileObject
;
64 IKsReferenceClockVtbl
* lpVtblReferenceClock
;
65 PKSDEFAULTCLOCK DefaultClock
;
68 WORK_QUEUE_ITEM PinWorkQueueItem
;
77 NTSTATUS NTAPI
IKsPin_PinStatePropertyHandler(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
78 NTSTATUS NTAPI
IKsPin_PinDataFormatPropertyHandler(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
79 NTSTATUS NTAPI
IKsPin_PinAllocatorFramingPropertyHandler(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
80 NTSTATUS NTAPI
IKsPin_PinStreamAllocator(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
81 NTSTATUS NTAPI
IKsPin_PinMasterClock(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
82 NTSTATUS NTAPI
IKsPin_PinPipeId(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
86 DEFINE_KSPROPERTY_CONNECTIONSET(PinConnectionSet
, IKsPin_PinStatePropertyHandler
, IKsPin_PinDataFormatPropertyHandler
, IKsPin_PinAllocatorFramingPropertyHandler
);
87 DEFINE_KSPROPERTY_STREAMSET(PinStreamSet
, IKsPin_PinStreamAllocator
, IKsPin_PinMasterClock
, IKsPin_PinPipeId
);
90 // KSPROPSETID_Connection
91 // KSPROPERTY_CONNECTION_ACQUIREORDERING
92 // KSPROPSETID_StreamInterface
93 // KSPROPERTY_STREAMINTERFACE_HEADERSIZE
95 KSPROPERTY_SET PinPropertySet
[] =
98 &KSPROPSETID_Connection
,
99 sizeof(PinConnectionSet
) / sizeof(KSPROPERTY_ITEM
),
100 (const KSPROPERTY_ITEM
*)&PinConnectionSet
,
106 sizeof(PinStreamSet
) / sizeof(KSPROPERTY_ITEM
),
107 (const KSPROPERTY_ITEM
*)&PinStreamSet
,
113 const GUID KSPROPSETID_Connection
= {0x1D58C920L
, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
114 const GUID KSPROPSETID_Stream
= {0x65aaba60L
, 0x98ae, 0x11cf, {0xa1, 0x0d, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4}};
115 const GUID KSPROPSETID_Clock
= {0xDF12A4C0L
, 0xAC17, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
119 IKsPin_PinStreamAllocator(
121 IN PKSIDENTIFIER Request
,
125 return STATUS_NOT_IMPLEMENTED
;
130 IKsPin_PinMasterClock(
132 IN PKSIDENTIFIER Request
,
135 PIO_STACK_LOCATION IoStack
;
136 PKSIOBJECT_HEADER ObjectHeader
;
138 NTSTATUS Status
= STATUS_SUCCESS
;
140 PFILE_OBJECT FileObject
;
141 KPROCESSOR_MODE Mode
;
145 /* get current irp stack */
146 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
148 DPRINT("IKsPin_PinMasterClock\n");
151 ASSERT(IoStack
->FileObject
);
152 ASSERT(IoStack
->FileObject
->FsContext2
);
154 /* get the object header */
155 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
158 ASSERT(ObjectHeader
);
160 /* locate ks pin implemention from KSPIN offset */
161 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
166 Handle
= (PHANDLE
)Data
;
168 if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
170 if (This
->Pin
.Descriptor
->PinDescriptor
.Communication
!= KSPIN_COMMUNICATION_NONE
&&
171 This
->Pin
.Descriptor
->Dispatch
&&
172 (This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_IMPLEMENT_CLOCK
))
175 Status
= STATUS_SUCCESS
;
179 /* no clock available */
180 Status
= STATUS_UNSUCCESSFUL
;
183 else if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
185 if (This
->Pin
.ClientState
!= KSSTATE_STOP
)
187 /* can only set in stopped state */
188 Status
= STATUS_INVALID_DEVICE_STATE
;
194 Mode
= ExGetPreviousMode();
196 Status
= ObReferenceObjectByHandle(*Handle
, SYNCHRONIZE
| DIRECTORY_QUERY
, *IoFileObjectType
, Mode
, (PVOID
*)&FileObject
, NULL
);
198 DPRINT("IKsPin_PinMasterClock ObReferenceObjectByHandle %lx\n", Status
);
199 if (NT_SUCCESS(Status
))
201 Property
.Set
= KSPROPSETID_Clock
;
202 Property
.Id
= KSPROPERTY_CLOCK_FUNCTIONTABLE
;
203 Property
.Flags
= KSPROPERTY_TYPE_GET
;
205 Status
= KsSynchronousIoControlDevice(FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, &Property
, sizeof(KSPROPERTY
), &This
->ClockTable
, sizeof(KSCLOCK_FUNCTIONTABLE
), &BytesReturned
);
207 DPRINT("IKsPin_PinMasterClock KSPROPERTY_CLOCK_FUNCTIONTABLE %lx\n", Status
);
209 if (NT_SUCCESS(Status
))
211 This
->ClockFileObject
= FileObject
;
215 ObDereferenceObject(FileObject
);
221 /* zeroing clock handle */
222 RtlZeroMemory(&This
->ClockTable
, sizeof(KSCLOCK_FUNCTIONTABLE
));
223 Status
= STATUS_SUCCESS
;
224 if (This
->ClockFileObject
)
226 FileObject
= This
->ClockFileObject
;
227 This
->ClockFileObject
= NULL
;
229 ObDereferenceObject(This
->ClockFileObject
);
235 DPRINT("IKsPin_PinMasterClock Status %lx\n", Status
);
245 IN PKSIDENTIFIER Request
,
249 return STATUS_NOT_IMPLEMENTED
;
255 IKsPin_PinStatePropertyHandler(
257 IN PKSIDENTIFIER Request
,
260 PIO_STACK_LOCATION IoStack
;
261 PKSIOBJECT_HEADER ObjectHeader
;
263 NTSTATUS Status
= STATUS_SUCCESS
;
267 /* get current irp stack */
268 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
270 DPRINT("IKsPin_PinStatePropertyHandler\n");
273 ASSERT(IoStack
->FileObject
);
274 ASSERT(IoStack
->FileObject
->FsContext2
);
276 /* get the object header */
277 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
279 /* locate ks pin implemention from KSPIN offset */
280 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
282 /* acquire control mutex */
283 KeWaitForSingleObject(This
->BasicHeader
.ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
286 NewState
= (PKSSTATE
)Data
;
288 if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
290 *NewState
= This
->Pin
.DeviceState
;
291 Irp
->IoStatus
.Information
= sizeof(KSSTATE
);
293 else if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
295 if (This
->Pin
.Descriptor
->Dispatch
->SetDeviceState
)
297 /* backup old state */
298 OldState
= This
->Pin
.ClientState
;
301 This
->Pin
.ClientState
= *NewState
;
302 This
->Pin
.DeviceState
= KSSTATE_RUN
;
304 /* check if it supported */
305 Status
= This
->Pin
.Descriptor
->Dispatch
->SetDeviceState(&This
->Pin
, *NewState
, OldState
);
307 DPRINT("IKsPin_PinStatePropertyHandler NewState %lu Result %lx\n", *NewState
, Status
);
309 if (!NT_SUCCESS(Status
))
311 /* revert to old state */
312 This
->Pin
.ClientState
= OldState
;
313 This
->Pin
.DeviceState
= OldState
;
314 DPRINT("IKsPin_PinStatePropertyHandler failed to set state %lx Result %lx\n", *NewState
, Status
);
319 /* update device state */
320 This
->Pin
.DeviceState
= *NewState
;
325 /* just set new state */
326 This
->Pin
.DeviceState
= *NewState
;
327 This
->Pin
.ClientState
= *NewState
;
331 /* release processing mutex */
332 KeReleaseMutex(This
->BasicHeader
.ControlMutex
, FALSE
);
334 DPRINT("IKsPin_PinStatePropertyHandler Status %lx\n", Status
);
340 IKsPin_PinAllocatorFramingPropertyHandler(
342 IN PKSIDENTIFIER Request
,
345 PIO_STACK_LOCATION IoStack
;
346 PKSIOBJECT_HEADER ObjectHeader
;
349 NTSTATUS Status
= STATUS_SUCCESS
;
351 /* get current irp stack */
352 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
355 ASSERT(IoStack
->FileObject
);
356 ASSERT(IoStack
->FileObject
->FsContext2
);
358 /* get the object header */
359 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
361 /* locate ks pin implemention from KSPIN offset */
362 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
364 /* setting allocator flags is not supported */
365 ASSERT(!(Request
->Flags
& KSPROPERTY_TYPE_SET
));
367 /* acquire control mutex */
368 KeWaitForSingleObject(This
->BasicHeader
.ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
370 if (This
->Pin
.Descriptor
->AllocatorFraming
)
373 Size
= FIELD_OFFSET(KSALLOCATOR_FRAMING_EX
, FramingItem
[0]) + This
->Pin
.Descriptor
->AllocatorFraming
->CountItems
* sizeof(KS_FRAMING_ITEM
);
375 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== 0)
378 Status
= STATUS_BUFFER_OVERFLOW
;
380 else if (Size
> IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
)
382 /* buffer too small */
383 Status
= STATUS_BUFFER_TOO_SMALL
;
388 RtlMoveMemory(Data
, This
->Pin
.Descriptor
->AllocatorFraming
, Size
);
392 Irp
->IoStatus
.Information
= Size
;
396 /* no allocator framing details */
397 Status
= STATUS_NOT_FOUND
;
400 /* release processing mutex */
401 KeReleaseMutex(This
->BasicHeader
.ControlMutex
, FALSE
);
403 DPRINT("IKsPin_PinAllocatorFramingPropertyHandler Status %lx\n", Status
);
410 IKsPin_PinDataFormatPropertyHandler(
412 IN PKSPROPERTY Request
,
415 PIO_STACK_LOCATION IoStack
;
416 PKSIOBJECT_HEADER ObjectHeader
;
418 NTSTATUS Status
= STATUS_SUCCESS
;
420 /* get current irp stack */
421 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
423 DPRINT("IKsPin_PinDataFormatPropertyHandler\n");
426 ASSERT(IoStack
->FileObject
);
427 ASSERT(IoStack
->FileObject
->FsContext2
);
429 /* get the object header */
430 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
432 /* locate ks pin implemention from KSPIN offset */
433 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
435 /* acquire control mutex */
436 KeWaitForSingleObject(This
->BasicHeader
.ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
438 if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
440 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< This
->Pin
.ConnectionFormat
->FormatSize
)
442 /* buffer too small */
443 Irp
->IoStatus
.Information
= This
->Pin
.ConnectionFormat
->FormatSize
;
444 Status
= STATUS_BUFFER_TOO_SMALL
;
449 RtlMoveMemory(Data
, This
->Pin
.ConnectionFormat
, This
->Pin
.ConnectionFormat
->FormatSize
);
452 else if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
455 if (This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_FIXED_FORMAT
)
457 /* format cannot be changed */
458 Status
= STATUS_INVALID_DEVICE_REQUEST
;
462 /* FIXME check if the format is supported */
463 Status
= _KsEdit(This
->Pin
.Bag
, (PVOID
*)&This
->Pin
.ConnectionFormat
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, This
->Pin
.ConnectionFormat
->FormatSize
, 0);
465 if (NT_SUCCESS(Status
))
467 /* store new format */
468 RtlMoveMemory(This
->Pin
.ConnectionFormat
, Data
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
);
473 /* release processing mutex */
474 KeReleaseMutex(This
->BasicHeader
.ControlMutex
, FALSE
);
476 DPRINT("IKsPin_PinDataFormatPropertyHandler Status %lx\n", Status
);
483 IKsPin_fnQueryInterface(
489 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, BasicHeader
.OuterUnknown
);
491 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
))
493 *Output
= &This
->BasicHeader
.OuterUnknown
;
494 _InterlockedIncrement(&This
->ref
);
495 return STATUS_SUCCESS
;
499 if (This
->BasicHeader
.ClientAggregate
)
501 /* using client aggregate */
502 Status
= This
->BasicHeader
.ClientAggregate
->lpVtbl
->QueryInterface(This
->BasicHeader
.ClientAggregate
, refiid
, Output
);
504 if (NT_SUCCESS(Status
))
506 /* client aggregate supports interface */
511 DPRINT("IKsPin_fnQueryInterface no interface\n");
512 return STATUS_NOT_SUPPORTED
;
520 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, BasicHeader
.OuterUnknown
);
522 return InterlockedIncrement(&This
->ref
);
530 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, BasicHeader
.OuterUnknown
);
532 InterlockedDecrement(&This
->ref
);
539 /* Return new reference count */
545 IKsPin_fnTransferKsIrp(
548 IN IKsTransport
**OutTransport
)
551 return STATUS_NOT_IMPLEMENTED
;
556 IKsPin_fnDiscardKsIrp(
559 IN IKsTransport
* *OutTransport
)
569 IN IKsTransport
* TransportIn
,
570 OUT IKsTransport
** OutTransportIn
,
571 OUT IKsTransport
* *OutTransportOut
,
572 IN KSPIN_DATAFLOW DataFlow
)
575 return STATUS_NOT_IMPLEMENTED
;
580 IKsPin_fnSetDeviceState(
584 IN IKsTransport
* *OutTransport
)
587 return STATUS_NOT_IMPLEMENTED
;
592 IKsPin_fnSetResetState(
594 IN KSRESET ResetState
,
595 OUT IKsTransport
* * OutTransportOut
)
602 IKsPin_fnGetTransportConfig(
604 IN
struct KSPTRANSPORTCONFIG
* TransportConfig
,
605 OUT IKsTransport
** OutTransportIn
,
606 OUT IKsTransport
** OutTransportOut
)
609 return STATUS_NOT_IMPLEMENTED
;
614 IKsPin_fnSetTransportConfig(
616 IN
struct KSPTRANSPORTCONFIG
const * TransportConfig
,
617 OUT IKsTransport
** OutTransportIn
,
618 OUT IKsTransport
** OutTransportOut
)
621 return STATUS_NOT_IMPLEMENTED
;
626 IKsPin_fnResetTransportConfig(
628 OUT IKsTransport
** OutTransportIn
,
629 OUT IKsTransport
** OutTransportOut
)
632 return STATUS_NOT_IMPLEMENTED
;
646 IKsPin_fnGetProcessPin(
655 IKsPin_fnAttemptBypass(
659 return STATUS_NOT_IMPLEMENTED
;
664 IKsPin_fnAttemptUnbypass(
668 return STATUS_NOT_IMPLEMENTED
;
673 IKsPin_fnGenerateConnectionEvents(
682 IKsPin_fnClientSetDeviceState(
688 return STATUS_NOT_IMPLEMENTED
;
691 static IKsPinVtbl vt_IKsPin
=
693 IKsPin_fnQueryInterface
,
696 IKsPin_fnTransferKsIrp
,
697 IKsPin_fnDiscardKsIrp
,
699 IKsPin_fnSetDeviceState
,
700 IKsPin_fnSetResetState
,
701 IKsPin_fnGetTransportConfig
,
702 IKsPin_fnSetTransportConfig
,
703 IKsPin_fnResetTransportConfig
,
705 IKsPin_fnGetProcessPin
,
706 IKsPin_fnAttemptBypass
,
707 IKsPin_fnAttemptUnbypass
,
708 IKsPin_fnGenerateConnectionEvents
,
709 IKsPin_fnClientSetDeviceState
713 //==============================================================
717 IKsReferenceClock_fnQueryInterface(
718 IKsReferenceClock
* iface
,
722 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
724 return IKsPin_fnQueryInterface((IKsPin
*)&This
->BasicHeader
.OuterUnknown
, refiid
, Output
);
729 IKsReferenceClock_fnAddRef(
730 IKsReferenceClock
* iface
)
732 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
734 return IKsPin_fnAddRef((IKsPin
*)&This
->BasicHeader
.OuterUnknown
);
739 IKsReferenceClock_fnRelease(
740 IKsReferenceClock
* iface
)
742 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
744 return IKsPin_fnRelease((IKsPin
*)&This
->BasicHeader
.OuterUnknown
);
749 IKsReferenceClock_fnGetTime(
750 IKsReferenceClock
* iface
)
754 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
757 DPRINT1("IKsReferenceClock_fnGetTime\n");
759 if (!This
->ClockFileObject
|| !This
->ClockTable
.GetTime
)
765 Result
= This
->ClockTable
.GetTime(This
->ClockFileObject
);
773 IKsReferenceClock_fnGetPhysicalTime(
774 IKsReferenceClock
* iface
)
778 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
780 DPRINT1("IKsReferenceClock_fnGetPhysicalTime\n");
783 if (!This
->ClockFileObject
|| !This
->ClockTable
.GetPhysicalTime
)
789 Result
= This
->ClockTable
.GetPhysicalTime(This
->ClockFileObject
);
798 IKsReferenceClock_fnGetCorrelatedTime(
799 IKsReferenceClock
* iface
,
800 OUT PLONGLONG SystemTime
)
804 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
806 DPRINT1("IKsReferenceClock_fnGetCorrelatedTime\n");
808 if (!This
->ClockFileObject
|| !This
->ClockTable
.GetCorrelatedTime
)
814 Result
= This
->ClockTable
.GetCorrelatedTime(This
->ClockFileObject
, SystemTime
);
823 IKsReferenceClock_fnGetCorrelatedPhysicalTime(
824 IKsReferenceClock
* iface
,
825 OUT PLONGLONG SystemTime
)
829 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
831 DPRINT1("IKsReferenceClock_fnGetCorrelatedPhysicalTime\n");
833 if (!This
->ClockFileObject
|| !This
->ClockTable
.GetCorrelatedPhysicalTime
)
839 Result
= This
->ClockTable
.GetCorrelatedPhysicalTime(This
->ClockFileObject
, SystemTime
);
847 IKsReferenceClock_fnGetResolution(
848 IKsReferenceClock
* iface
,
849 OUT PKSRESOLUTION Resolution
)
854 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
856 DPRINT1("IKsReferenceClock_fnGetResolution\n");
858 if (!This
->ClockFileObject
)
860 Resolution
->Error
= 0;
861 Resolution
->Granularity
= 1;
862 DPRINT1("IKsReferenceClock_fnGetResolution Using HACK\n");
863 return STATUS_SUCCESS
;
867 if (!This
->ClockFileObject
)
868 return STATUS_DEVICE_NOT_READY
;
871 Property
.Set
= KSPROPSETID_Clock
;
872 Property
.Id
= KSPROPERTY_CLOCK_RESOLUTION
;
873 Property
.Flags
= KSPROPERTY_TYPE_GET
;
875 return KsSynchronousIoControlDevice(This
->ClockFileObject
, KernelMode
, IOCTL_KS_PROPERTY
, &Property
, sizeof(KSPROPERTY
), Resolution
, sizeof(KSRESOLUTION
), &BytesReturned
);
881 IKsReferenceClock_fnGetState(
882 IKsReferenceClock
* iface
,
888 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
890 DPRINT1("IKsReferenceClock_fnGetState\n");
892 if (!This
->ClockFileObject
)
894 *State
= This
->Pin
.ClientState
;
895 DPRINT1("IKsReferenceClock_fnGetState Using HACK\n");
896 return STATUS_SUCCESS
;
900 if (!This
->ClockFileObject
)
901 return STATUS_DEVICE_NOT_READY
;
904 Property
.Set
= KSPROPSETID_Clock
;
905 Property
.Id
= KSPROPERTY_CLOCK_RESOLUTION
;
906 Property
.Flags
= KSPROPERTY_TYPE_GET
;
908 return KsSynchronousIoControlDevice(This
->ClockFileObject
, KernelMode
, IOCTL_KS_PROPERTY
, &Property
, sizeof(KSPROPERTY
), State
, sizeof(KSSTATE
), &BytesReturned
);
911 static IKsReferenceClockVtbl vt_ReferenceClock
=
913 IKsReferenceClock_fnQueryInterface
,
914 IKsReferenceClock_fnAddRef
,
915 IKsReferenceClock_fnRelease
,
916 IKsReferenceClock_fnGetTime
,
917 IKsReferenceClock_fnGetPhysicalTime
,
918 IKsReferenceClock_fnGetCorrelatedTime
,
919 IKsReferenceClock_fnGetCorrelatedPhysicalTime
,
920 IKsReferenceClock_fnGetResolution
,
921 IKsReferenceClock_fnGetState
925 //==============================================================
933 KsPinAcquireProcessingMutex(
936 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
938 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
948 IN PKSGATE AndGate OPTIONAL
)
950 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
952 /* FIXME attach to filter's and gate (filter-centric processing) */
954 This
->AttachedGate
= AndGate
;
955 This
->OrGate
= FALSE
;
965 IN PKSGATE OrGate OPTIONAL
)
967 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
969 /* FIXME attach to filter's and gate (filter-centric processing) */
971 This
->AttachedGate
= OrGate
;
983 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
985 return This
->AttachedGate
;
993 KsPinAttemptProcessing(
995 IN BOOLEAN Asynchronous
)
997 DPRINT("KsPinAttemptProcessing\n");
1007 KsPinGetAvailableByteCount(
1009 OUT PLONG InputDataBytes OPTIONAL
,
1010 OUT PLONG OutputBufferBytes OPTIONAL
)
1013 return STATUS_NOT_IMPLEMENTED
;
1021 KsPinGetConnectedFilterInterface(
1023 IN
const GUID
* InterfaceId
,
1024 OUT PVOID
* Interface
)
1027 return STATUS_NOT_IMPLEMENTED
;
1035 KsPinGetConnectedPinDeviceObject(
1047 KsPinGetConnectedPinFileObject(
1059 KsPinGetConnectedPinInterface(
1061 IN
const GUID
* InterfaceId
,
1062 OUT PVOID
* Interface
)
1065 return STATUS_NOT_IMPLEMENTED
;
1073 KsPinGetCopyRelationships(
1075 OUT PKSPIN
* CopySource
,
1076 OUT PKSPIN
* DelegateBranch
)
1086 KsPinGetNextSiblingPin(
1089 return KsGetNextSibling((PVOID
)Pin
);
1097 KsPinGetParentFilter(
1100 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1102 /* return parent filter */
1103 return This
->BasicHeader
.Parent
.KsFilter
;
1111 KsPinGetReferenceClockInterface(
1113 OUT PIKSREFERENCECLOCK
* Interface
)
1115 NTSTATUS Status
= STATUS_DEVICE_NOT_READY
;
1116 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1118 if (This
->ClockFileObject
)
1120 /* clock is available */
1121 *Interface
= (PIKSREFERENCECLOCK
)&This
->lpVtblReferenceClock
;
1122 Status
= STATUS_SUCCESS
;
1125 DPRINT("KsPinGetReferenceClockInterface Pin %p Interface %p Status %x\n", Pin
, Interface
, Status
);
1134 KsPinRegisterFrameReturnCallback(
1136 IN PFNKSPINFRAMERETURN FrameReturn
)
1138 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1140 /* register frame return callback */
1141 This
->FrameReturn
= FrameReturn
;
1149 KsPinRegisterHandshakeCallback(
1151 IN PFNKSPINHANDSHAKE Handshake
)
1153 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1155 /* register private protocol handshake callback */
1156 This
->Handshake
= Handshake
;
1164 KsPinRegisterIrpCompletionCallback(
1166 IN PFNKSPINIRPCOMPLETION IrpCompletion
)
1168 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1170 /* register irp completion callback */
1171 This
->IrpCompletion
= IrpCompletion
;
1179 KsPinRegisterPowerCallbacks(
1181 IN PFNKSPINPOWER Sleep OPTIONAL
,
1182 IN PFNKSPINPOWER Wake OPTIONAL
)
1184 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1186 /* register power callbacks */
1187 This
->Sleep
= Sleep
;
1196 KsPinReleaseProcessingMutex(
1199 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1201 /* release processing mutex */
1202 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
1214 PKSIOBJECT_HEADER ObjectHeader
;
1216 PKSBASIC_HEADER Header
;
1217 PIO_STACK_LOCATION IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1219 DPRINT("KsGetPinFromIrp\n");
1221 /* get object header */
1222 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
1227 Pin
= (PKSPIN
)ObjectHeader
->ObjectType
;
1228 Header
= (PKSBASIC_HEADER
)((ULONG_PTR
)Pin
- sizeof(KSBASIC_HEADER
));
1231 ASSERT(Header
->Type
== KsObjectTypePin
);
1233 /* return object type */
1244 KsPinSetPinClockTime(
1258 IN PVOID Data OPTIONAL
,
1259 IN ULONG Size OPTIONAL
,
1260 IN PKSSTREAM_HEADER StreamHeader OPTIONAL
,
1261 IN PVOID Context OPTIONAL
)
1264 return STATUS_UNSUCCESSFUL
;
1273 KsPinSubmitFrameMdl(
1275 IN PMDL Mdl OPTIONAL
,
1276 IN PKSSTREAM_HEADER StreamHeader OPTIONAL
,
1277 IN PVOID Context OPTIONAL
)
1280 return STATUS_UNSUCCESSFUL
;
1290 IN PKSPROCESSPIN ProcessPin
)
1297 IKsPin_PrepareStreamHeader(
1298 IN IKsPinImpl
* This
,
1299 IN PKSISTREAM_POINTER StreamPointer
)
1301 PKSSTREAM_HEADER Header
;
1305 StreamPointer
->Irp
= KsRemoveIrpFromCancelableQueue(&This
->IrpList
, &This
->IrpListLock
, KsListEntryHead
, KsAcquireAndRemoveOnlySingleItem
);
1306 if (!StreamPointer
->Irp
)
1308 /* run out of mappings */
1309 DPRINT("OutOfMappings\n");
1310 return STATUS_DEVICE_NOT_READY
;
1313 InterlockedDecrement(&This
->IrpCount
);
1314 KsDecrementCountedWorker(This
->PinWorker
);
1316 /* get stream header */
1317 if (StreamPointer
->Irp
->RequestorMode
== UserMode
)
1318 Header
= (PKSSTREAM_HEADER
)StreamPointer
->Irp
->AssociatedIrp
.SystemBuffer
;
1320 Header
= (PKSSTREAM_HEADER
)StreamPointer
->Irp
->UserBuffer
;
1322 /* initialize stream pointer */
1323 StreamPointer
->Callback
= NULL
;
1324 StreamPointer
->Length
= max(Header
->DataUsed
, Header
->FrameExtent
);
1325 StreamPointer
->Next
= NULL
;
1326 StreamPointer
->Offset
= 0;
1327 StreamPointer
->Pin
= &This
->Pin
;
1328 StreamPointer
->Data
= Header
->Data
;
1330 StreamPointer
->StreamPointer
.Context
= NULL
;
1331 StreamPointer
->StreamPointer
.Pin
= &This
->Pin
;
1332 StreamPointer
->StreamPointer
.StreamHeader
= Header
;
1334 if (This
->Pin
.Descriptor
->PinDescriptor
.DataFlow
== KSPIN_DATAFLOW_IN
)
1335 StreamPointer
->StreamPointer
.Offset
= &StreamPointer
->StreamPointer
.OffsetIn
;
1337 StreamPointer
->StreamPointer
.Offset
= &StreamPointer
->StreamPointer
.OffsetOut
;
1340 StreamPointer
->StreamPointer
.Offset
->Alignment
= 0;
1342 StreamPointer
->StreamPointer
.Offset
->Count
= 0;
1343 StreamPointer
->StreamPointer
.Offset
->Data
= NULL
;
1344 StreamPointer
->StreamPointer
.Offset
->Remaining
= 0;
1346 ASSERT(StreamPointer
->StreamPointer
.Offset
->Remaining
== 0);
1348 //StreamPointer->Offset += StreamPointer->StreamPointer.Offset->Count;
1350 ASSERT(StreamPointer
->Length
> StreamPointer
->Offset
);
1351 ASSERT(StreamPointer
->StreamPointer
.StreamHeader
);
1352 ASSERT(This
->FrameSize
);
1354 /* calculate length */
1355 /* TODO split into frames */
1356 Length
= StreamPointer
->Length
;
1362 StreamPointer
->StreamPointer
.Offset
->Alignment
= 0;
1364 StreamPointer
->StreamPointer
.Context
= NULL
;
1365 StreamPointer
->StreamPointer
.Pin
= &This
->Pin
;
1366 StreamPointer
->StreamPointer
.Offset
->Count
= Length
;
1367 StreamPointer
->StreamPointer
.Offset
->Remaining
= Length
;
1368 StreamPointer
->StreamPointer
.Offset
->Data
= (PVOID
)((ULONG_PTR
)StreamPointer
->Data
+ StreamPointer
->Offset
);
1369 StreamPointer
->StreamPointer
.StreamHeader
->FrameExtent
= Length
;
1370 if (StreamPointer
->StreamPointer
.StreamHeader
->DataUsed
)
1371 StreamPointer
->StreamPointer
.StreamHeader
->DataUsed
= Length
;
1373 StreamPointer
->StreamPointer
.StreamHeader
->Data
= StreamPointer
->StreamPointer
.Offset
->Data
;
1375 return STATUS_SUCCESS
;
1385 KsPinGetLeadingEdgeStreamPointer(
1387 IN KSSTREAM_POINTER_STATE State
)
1392 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1394 DPRINT("KsPinGetLeadingEdgeStreamPointer Pin %p State %x Count %lu Remaining %lu\n", Pin
, State
,
1395 This
->LeadingEdgeStreamPointer
.Length
,
1396 This
->LeadingEdgeStreamPointer
.Offset
);
1399 ASSERT(State
== KSSTREAM_POINTER_STATE_LOCKED
);
1401 if (State
== KSSTREAM_POINTER_STATE_LOCKED
)
1403 if (!This
->LeadingEdgeStreamPointer
.Irp
|| This
->LeadingEdgeStreamPointer
.StreamPointer
.Offset
->Remaining
== 0)
1405 Status
= IKsPin_PrepareStreamHeader(This
, &This
->LeadingEdgeStreamPointer
);
1406 if (!NT_SUCCESS(Status
))
1410 DPRINT("KsPinGetLeadingEdgeStreamPointer NewOffset %lu TotalLength %lu\n", This
->LeadingEdgeStreamPointer
.Offset
, This
->LeadingEdgeStreamPointer
.Length
);
1413 return &This
->LeadingEdgeStreamPointer
.StreamPointer
;
1422 KsPinGetTrailingEdgeStreamPointer(
1424 IN KSSTREAM_POINTER_STATE State
)
1436 KsStreamPointerSetStatusCode(
1437 IN PKSSTREAM_POINTER StreamPointer
,
1441 return STATUS_UNSUCCESSFUL
;
1450 KsStreamPointerLock(
1451 IN PKSSTREAM_POINTER StreamPointer
)
1454 return STATUS_UNSUCCESSFUL
;
1463 KsStreamPointerUnlock(
1464 IN PKSSTREAM_POINTER StreamPointer
,
1467 PKSISTREAM_POINTER Pointer
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1469 DPRINT("KsStreamPointerUnlock StreamPointer %pEject %lu\n", StreamPointer
, Eject
);
1471 Pointer
->Irp
= NULL
;
1480 KsStreamPointerAdvanceOffsetsAndUnlock(
1481 IN PKSSTREAM_POINTER StreamPointer
,
1486 DPRINT("KsStreamPointerAdvanceOffsets InUsed %lu OutUsed %lu Eject %lu\n", InUsed
, OutUsed
, Eject
);
1497 KsStreamPointerDelete(
1498 IN PKSSTREAM_POINTER StreamPointer
)
1501 PKSISTREAM_POINTER Cur
, Last
;
1502 PKSISTREAM_POINTER Pointer
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1504 DPRINT("KsStreamPointerDelete %p\n", Pointer
);
1506 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pointer
->StreamPointer
.Pin
, IKsPinImpl
, Pin
);
1508 /* point to first stream pointer */
1510 Cur
= This
->ClonedStreamPointer
;
1512 while(Cur
!= Pointer
&& Cur
)
1515 /* iterate to next cloned pointer */
1521 /* you naughty driver */
1527 /* remove first cloned pointer */
1528 This
->ClonedStreamPointer
= Pointer
->Next
;
1532 Last
->Next
= Pointer
->Next
;
1535 /* FIXME make sure no timeouts are pending */
1545 KsStreamPointerClone(
1546 IN PKSSTREAM_POINTER StreamPointer
,
1547 IN PFNKSSTREAMPOINTER CancelCallback OPTIONAL
,
1548 IN ULONG ContextSize
,
1549 OUT PKSSTREAM_POINTER
* CloneStreamPointer
)
1552 PKSISTREAM_POINTER CurFrame
;
1553 PKSISTREAM_POINTER NewFrame
;
1558 DPRINT("KsStreamPointerClone StreamPointer %p CancelCallback %p ContextSize %p CloneStreamPointer %p\n", StreamPointer
, CancelCallback
, ContextSize
, CloneStreamPointer
);
1560 /* get stream pointer */
1561 CurFrame
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1563 /* calculate context size */
1564 Size
= sizeof(KSISTREAM_POINTER
) + ContextSize
;
1566 /* allocate new stream pointer */
1567 NewFrame
= (PKSISTREAM_POINTER
)AllocateItem(NonPagedPool
, Size
);
1570 return STATUS_INSUFFICIENT_RESOURCES
;
1572 /* get current irp stack location */
1573 RefCount
= (ULONG_PTR
)CurFrame
->Irp
->Tail
.Overlay
.DriverContext
[0];
1575 /* increment reference count */
1577 CurFrame
->Irp
->Tail
.Overlay
.DriverContext
[0] = (PVOID
)RefCount
;
1579 /* copy stream pointer */
1580 RtlMoveMemory(NewFrame
, CurFrame
, sizeof(KSISTREAM_POINTER
));
1583 This
= (IKsPinImpl
*)CONTAINING_RECORD(CurFrame
->Pin
, IKsPinImpl
, Pin
);
1585 /* prepare stream header in case required */
1586 if (CurFrame
->StreamPointer
.Offset
->Remaining
== 0)
1588 Status
= IKsPin_PrepareStreamHeader(This
, NewFrame
);
1589 if (!NT_SUCCESS(Status
))
1592 return STATUS_DEVICE_NOT_READY
;
1597 NewFrame
->StreamPointer
.Context
= (NewFrame
+ 1);
1600 if (This
->Pin
.Descriptor
->PinDescriptor
.DataFlow
== KSPIN_DATAFLOW_IN
)
1601 NewFrame
->StreamPointer
.Offset
= &NewFrame
->StreamPointer
.OffsetIn
;
1603 NewFrame
->StreamPointer
.Offset
= &NewFrame
->StreamPointer
.OffsetOut
;
1607 NewFrame
->StreamPointer
.Pin
= &This
->Pin
;
1609 ASSERT(NewFrame
->StreamPointer
.Pin
);
1610 ASSERT(NewFrame
->StreamPointer
.Context
);
1611 ASSERT(NewFrame
->StreamPointer
.Offset
);
1612 ASSERT(NewFrame
->StreamPointer
.StreamHeader
);
1615 *CloneStreamPointer
= &NewFrame
->StreamPointer
;
1617 DPRINT("KsStreamPointerClone CloneStreamPointer %p\n", *CloneStreamPointer
);
1619 return STATUS_SUCCESS
;
1628 KsStreamPointerAdvanceOffsets(
1629 IN PKSSTREAM_POINTER StreamPointer
,
1634 PKSISTREAM_POINTER CurFrame
;
1638 DPRINT("KsStreamPointerAdvanceOffsets StreamPointer %p InUsed %lu OutUsed %lu Eject %lu\n", StreamPointer
, InUsed
, OutUsed
, Eject
);
1640 /* get stream pointer */
1641 CurFrame
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1644 This
= (IKsPinImpl
*)CONTAINING_RECORD(CurFrame
->Pin
, IKsPinImpl
, Pin
);
1647 ASSERT(InUsed
== 0);
1651 DPRINT("KsStreamPointerAdvanceOffsets Offset %lu Length %lu NewOffset %lu Remaining %lu LeadingEdge %p DataUsed %lu\n", CurFrame
->Offset
, CurFrame
->Length
, CurFrame
->Offset
+ OutUsed
,
1652 CurFrame
->StreamPointer
.OffsetOut
.Remaining
, &This
->LeadingEdgeStreamPointer
.StreamPointer
, CurFrame
->StreamPointer
.StreamHeader
->DataUsed
);
1655 if (This
->Pin
.Descriptor
->PinDescriptor
.DataFlow
== KSPIN_DATAFLOW_IN
)
1657 ASSERT(CurFrame
->StreamPointer
.OffsetIn
.Remaining
>= InUsed
);
1658 CurFrame
->StreamPointer
.OffsetIn
.Remaining
-= InUsed
;
1659 CurFrame
->StreamPointer
.OffsetIn
.Data
= (PVOID
)((ULONG_PTR
)CurFrame
->StreamPointer
.OffsetIn
.Data
+ InUsed
);
1663 if (!CurFrame
->StreamPointer
.OffsetOut
.Remaining
)
1665 Status
= IKsPin_PrepareStreamHeader(This
, CurFrame
);
1666 if (!NT_SUCCESS(Status
))
1668 return STATUS_DEVICE_NOT_READY
;
1673 ASSERT(CurFrame
->StreamPointer
.OffsetOut
.Remaining
>= OutUsed
);
1674 CurFrame
->StreamPointer
.OffsetOut
.Remaining
-= OutUsed
;
1675 CurFrame
->StreamPointer
.OffsetOut
.Data
= (PVOID
)((ULONG_PTR
)CurFrame
->StreamPointer
.OffsetOut
.Data
+ OutUsed
);
1679 return STATUS_SUCCESS
;
1688 KsStreamPointerAdvance(
1689 IN PKSSTREAM_POINTER StreamPointer
)
1693 return STATUS_NOT_IMPLEMENTED
;
1702 KsStreamPointerGetMdl(
1703 IN PKSSTREAM_POINTER StreamPointer
)
1715 KsStreamPointerGetIrp(
1716 IN PKSSTREAM_POINTER StreamPointer
,
1717 OUT PBOOLEAN FirstFrameInIrp OPTIONAL
,
1718 OUT PBOOLEAN LastFrameInIrp OPTIONAL
)
1730 KsStreamPointerScheduleTimeout(
1731 IN PKSSTREAM_POINTER StreamPointer
,
1732 IN PFNKSSTREAMPOINTER Callback
,
1733 IN ULONGLONG Interval
)
1735 LARGE_INTEGER DueTime
;
1736 PKSISTREAM_POINTER Pointer
;
1738 /* get stream pointer */
1739 Pointer
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1741 /* setup timer callback */
1742 Pointer
->Callback
= Callback
;
1744 /* setup expiration */
1745 DueTime
.QuadPart
= (LONGLONG
)Interval
;
1747 /* setup the timer */
1748 KeSetTimer(&Pointer
->Timer
, DueTime
, &Pointer
->TimerDpc
);
1758 KsStreamPointerCancelTimeout(
1759 IN PKSSTREAM_POINTER StreamPointer
)
1761 PKSISTREAM_POINTER Pointer
;
1763 /* get stream pointer */
1764 Pointer
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1766 KeCancelTimer(&Pointer
->Timer
);
1776 KsPinGetFirstCloneStreamPointer(
1781 DPRINT("KsPinGetFirstCloneStreamPointer %p\n", Pin
);
1783 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1785 if (!This
->ClonedStreamPointer
)
1788 /* return first cloned stream pointer */
1789 return &This
->ClonedStreamPointer
->StreamPointer
;
1798 KsStreamPointerGetNextClone(
1799 IN PKSSTREAM_POINTER StreamPointer
)
1801 PKSISTREAM_POINTER Pointer
;
1803 DPRINT("KsStreamPointerGetNextClone\n");
1805 /* get stream pointer */
1806 Pointer
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1808 /* is there a another cloned stream pointer */
1812 /* return next stream pointer */
1813 return &Pointer
->Next
->StreamPointer
;
1818 IKsPin_PinCentricWorker(
1822 IKsPinImpl
* This
= (IKsPinImpl
*)Parameter
;
1824 DPRINT("IKsPin_PinCentricWorker\n");
1828 ASSERT(This
->Pin
.Descriptor
);
1829 ASSERT(This
->Pin
.Descriptor
->Dispatch
);
1830 ASSERT(This
->Pin
.Descriptor
->Dispatch
->Process
);
1831 ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL
);
1832 ASSERT(!(This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_DISPATCH_LEVEL_PROCESSING
));
1833 ASSERT(!(This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_GENERATE_MAPPINGS
));
1837 DPRINT("IKsPin_PinCentricWorker calling Pin Process Routine\n");
1839 Status
= This
->Pin
.Descriptor
->Dispatch
->Process(&This
->Pin
);
1840 DPRINT("IKsPin_PinCentricWorker Status %lx, Offset %lu Length %lu\n", Status
,
1841 This
->LeadingEdgeStreamPointer
.Offset
,
1842 This
->LeadingEdgeStreamPointer
.Length
);
1845 }while(This
->IrpCount
);
1851 IKsPin_DispatchKsStream(
1852 PDEVICE_OBJECT DeviceObject
,
1856 PKSPROCESSPIN_INDEXENTRY ProcessPinIndex
;
1857 PKSSTREAM_HEADER Header
;
1860 PIO_STACK_LOCATION IoStack
;
1861 NTSTATUS Status
= STATUS_SUCCESS
;
1863 DPRINT("IKsPin_DispatchKsStream\n");
1865 /* FIXME handle reset states */
1866 ASSERT(This
->Pin
.ResetState
== KSRESET_END
);
1868 /* get current stack location */
1869 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1871 /* probe stream pointer */
1872 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_WRITE_STREAM
)
1873 Status
= KsProbeStreamIrp(Irp
, KSSTREAM_WRITE
| KSPROBE_ALLOCATEMDL
| KSPROBE_PROBEANDLOCK
| KSPROBE_SYSTEMADDRESS
, This
->Pin
.StreamHeaderSize
);
1875 Status
= KsProbeStreamIrp(Irp
, KSSTREAM_READ
| KSPROBE_ALLOCATEMDL
| KSPROBE_PROBEANDLOCK
| KSPROBE_SYSTEMADDRESS
, This
->Pin
.StreamHeaderSize
);
1877 if (!NT_SUCCESS(Status
))
1879 DPRINT1("KsProbeStreamIrp failed with %x\n", Status
);
1881 Irp
->IoStatus
.Status
= Status
;
1882 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1886 if (Irp
->RequestorMode
== UserMode
)
1887 Header
= (PKSSTREAM_HEADER
)Irp
->AssociatedIrp
.SystemBuffer
;
1889 Header
= (PKSSTREAM_HEADER
)Irp
->UserBuffer
;
1893 DPRINT("NoHeader Canceling Irp %p\n", Irp
);
1894 Irp
->IoStatus
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
1895 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1899 /* calculate num headers */
1900 NumHeaders
= IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
/ Header
->Size
;
1902 /* assume headers of same length */
1903 ASSERT(IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
% Header
->Size
== 0);
1905 /* FIXME support multiple stream headers */
1906 ASSERT(NumHeaders
== 1);
1908 if (Irp
->RequestorMode
== UserMode
)
1910 /* prepare header */
1911 ASSERT(Irp
->MdlAddress
);
1912 Header
->Data
= MmGetSystemAddressForMdlSafe(Irp
->MdlAddress
, NormalPagePriority
);
1916 DPRINT("NoHeader->Data Canceling Irp %p\n", Irp
);
1917 Irp
->IoStatus
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
1918 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1926 if (This
->Pin
.Descriptor
->Dispatch
->Process
)
1928 /* it is a pin centric avstream */
1930 /* mark irp as pending */
1931 IoMarkIrpPending(Irp
);
1933 /* add irp to cancelable queue */
1934 KsAddIrpToCancelableQueue(&This
->IrpList
, &This
->IrpListLock
, Irp
, KsListEntryTail
, NULL
/* FIXME */);
1937 ASSERT(!(This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_DISPATCH_LEVEL_PROCESSING
));
1938 ASSERT(This
->PinWorker
);
1940 InterlockedIncrement(&This
->IrpCount
);
1942 DPRINT("IKsPin_DispatchKsStream IrpCount %lu\n", This
->IrpCount
);
1944 /* start the processing loop */
1945 KsIncrementCountedWorker(This
->PinWorker
);
1947 Status
= STATUS_PENDING
;
1951 /* filter-centric avstream */
1952 ASSERT(This
->Filter
);
1954 ProcessPinIndex
= This
->Filter
->lpVtbl
->GetProcessDispatch(This
->Filter
);
1955 Filter
= This
->Filter
->lpVtbl
->GetStruct(This
->Filter
);
1957 ASSERT(ProcessPinIndex
);
1959 ASSERT(Filter
->Descriptor
);
1960 ASSERT(Filter
->Descriptor
->Dispatch
);
1962 if (!Filter
->Descriptor
->Dispatch
->Process
)
1964 /* invalid device request */
1965 DPRINT("Filter Centric Processing No Process Routine\n");
1966 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1967 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1968 return STATUS_UNSUCCESSFUL
;
1971 /* mark irp as pending */
1972 IoMarkIrpPending(Irp
);
1974 /* add irp to cancelable queue */
1975 KsAddIrpToCancelableQueue(&This
->IrpList
, &This
->IrpListLock
, Irp
, KsListEntryTail
, NULL
/* FIXME */);
1977 Status
= Filter
->Descriptor
->Dispatch
->Process(Filter
, ProcessPinIndex
);
1979 DPRINT("IKsPin_DispatchKsStream FilterCentric: Status %lx \n", Status
);
1988 IKsPin_DispatchDeviceIoControl(
1989 IN PDEVICE_OBJECT DeviceObject
,
1992 PIO_STACK_LOCATION IoStack
;
1993 PKSIOBJECT_HEADER ObjectHeader
;
1996 UNICODE_STRING GuidString
;
1997 PKSPROPERTY Property
;
2000 /* get current irp stack */
2001 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2004 ASSERT(IoStack
->FileObject
);
2005 ASSERT(IoStack
->FileObject
->FsContext2
);
2007 /* get the object header */
2008 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
2010 /* locate ks pin implemention from KSPIN offset */
2011 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
2013 /* current irp stack */
2014 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2016 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_READ_STREAM
||
2017 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_WRITE_STREAM
)
2019 /* handle ks stream packets */
2020 return IKsPin_DispatchKsStream(DeviceObject
, Irp
, This
);
2023 /* get property from input buffer */
2024 Property
= (PKSPROPERTY
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
2027 ASSERT(IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
>= sizeof(KSIDENTIFIER
));
2028 ASSERT(This
->Pin
.Descriptor
->AutomationTable
);
2030 RtlStringFromGUID(&Property
->Set
, &GuidString
);
2031 DPRINT("IKsPin_DispatchDeviceIoControl property Set |%S| Id %u Flags %x\n", GuidString
.Buffer
, Property
->Id
, Property
->Flags
);
2032 RtlFreeUnicodeString(&GuidString
);
2035 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_METHOD
)
2037 const KSMETHOD_SET
*MethodSet
= NULL
;
2038 ULONG MethodItemSize
= 0;
2040 /* check if the driver supports method sets */
2041 if (This
->Pin
.Descriptor
->AutomationTable
->MethodSetsCount
)
2043 SetCount
= This
->Pin
.Descriptor
->AutomationTable
->MethodSetsCount
;
2044 MethodSet
= This
->Pin
.Descriptor
->AutomationTable
->MethodSets
;
2045 MethodItemSize
= This
->Pin
.Descriptor
->AutomationTable
->MethodItemSize
;
2048 /* call method set handler */
2049 Status
= KspMethodHandlerWithAllocator(Irp
, SetCount
, MethodSet
, NULL
, MethodItemSize
);
2051 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_PROPERTY
)
2053 const KSPROPERTY_SET
*PropertySet
= NULL
;
2054 ULONG PropertyItemSize
= 0;
2056 /* check if the driver supports method sets */
2057 if (This
->Pin
.Descriptor
->AutomationTable
->PropertySetsCount
)
2059 SetCount
= This
->Pin
.Descriptor
->AutomationTable
->PropertySetsCount
;
2060 PropertySet
= This
->Pin
.Descriptor
->AutomationTable
->PropertySets
;
2061 PropertyItemSize
= This
->Pin
.Descriptor
->AutomationTable
->PropertyItemSize
;
2064 /* needed for our property handlers */
2065 KSPROPERTY_ITEM_IRP_STORAGE(Irp
) = (KSPROPERTY_ITEM
*)This
;
2067 /* call property handler */
2068 Status
= KspPropertyHandler(Irp
, SetCount
, PropertySet
, NULL
, PropertyItemSize
);
2073 ASSERT(IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_ENABLE_EVENT
||
2074 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_DISABLE_EVENT
);
2076 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_ENABLE_EVENT
)
2078 /* call enable event handlers */
2079 Status
= KspEnableEvent(Irp
,
2080 This
->Pin
.Descriptor
->AutomationTable
->EventSetsCount
,
2081 (PKSEVENT_SET
)This
->Pin
.Descriptor
->AutomationTable
->EventSets
,
2082 &This
->BasicHeader
.EventList
,
2084 (PVOID
)&This
->BasicHeader
.EventListLock
,
2086 This
->Pin
.Descriptor
->AutomationTable
->EventItemSize
);
2090 /* disable event handler */
2091 Status
= KsDisableEvent(Irp
, &This
->BasicHeader
.EventList
, KSEVENTS_SPINLOCK
, &This
->BasicHeader
.EventListLock
);
2095 RtlStringFromGUID(&Property
->Set
, &GuidString
);
2096 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
);
2097 RtlFreeUnicodeString(&GuidString
);
2099 if (Status
!= STATUS_PENDING
)
2101 Irp
->IoStatus
.Status
= Status
;
2102 CompleteRequest(Irp
, IO_NO_INCREMENT
);
2112 IN PDEVICE_OBJECT DeviceObject
,
2115 PIO_STACK_LOCATION IoStack
;
2116 PKSIOBJECT_HEADER ObjectHeader
;
2118 NTSTATUS Status
= STATUS_SUCCESS
;
2120 /* get current irp stack */
2121 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2124 ASSERT(IoStack
->FileObject
);
2125 ASSERT(IoStack
->FileObject
->FsContext2
);
2127 /* get the object header */
2128 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
2130 /* locate ks pin implemention fro KSPIN offset */
2131 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
2133 if (This
->Pin
.Descriptor
->Dispatch
->Close
)
2135 /* call pin close routine */
2136 Status
= This
->Pin
.Descriptor
->Dispatch
->Close(&This
->Pin
, Irp
);
2138 if (!NT_SUCCESS(Status
))
2141 Irp
->IoStatus
.Status
= Status
;
2142 CompleteRequest(Irp
, IO_NO_INCREMENT
);
2146 /* remove pin from filter pin list and decrement reference count */
2147 IKsFilter_RemovePin(This
->Filter
->lpVtbl
->GetStruct(This
->Filter
), &This
->Pin
);
2149 if (Status
!= STATUS_PENDING
)
2151 Irp
->IoStatus
.Status
= Status
;
2152 CompleteRequest(Irp
, IO_NO_INCREMENT
);
2162 IKsPin_DispatchCreateAllocator(
2163 IN PDEVICE_OBJECT DeviceObject
,
2168 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
2169 CompleteRequest(Irp
, IO_NO_INCREMENT
);
2170 return STATUS_NOT_IMPLEMENTED
;
2175 IKsPin_DispatchCreateClock(
2176 IN PDEVICE_OBJECT DeviceObject
,
2180 NTSTATUS Status
= STATUS_SUCCESS
;
2182 KSRESOLUTION Resolution
;
2183 PKSRESOLUTION pResolution
= NULL
;
2184 PKSOBJECT_CREATE_ITEM CreateItem
;
2186 DPRINT("IKsPin_DispatchCreateClock\n");
2188 /* get the create item */
2189 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
2194 /* get the pin object */
2195 Pin
= (PKSPIN
)CreateItem
->Context
;
2200 /* locate ks pin implemention fro KSPIN offset */
2201 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
2204 ASSERT(This
->BasicHeader
.Type
== KsObjectTypePin
);
2205 ASSERT(This
->BasicHeader
.ControlMutex
);
2207 /* acquire control mutex */
2208 KsAcquireControl(Pin
);
2210 if ((This
->Pin
.Descriptor
->PinDescriptor
.Communication
!= KSPIN_COMMUNICATION_NONE
&&
2211 This
->Pin
.Descriptor
->Dispatch
) ||
2212 (This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_IMPLEMENT_CLOCK
))
2214 if (!This
->DefaultClock
)
2216 if (This
->Pin
.Descriptor
->Dispatch
&& This
->Pin
.Descriptor
->Dispatch
->Clock
)
2218 if (This
->Pin
.Descriptor
->Dispatch
->Clock
->Resolution
)
2220 This
->Pin
.Descriptor
->Dispatch
->Clock
->Resolution(&This
->Pin
, &Resolution
);
2221 pResolution
= &Resolution
;
2224 Status
= KsAllocateDefaultClockEx(&This
->DefaultClock
,
2226 (PFNKSSETTIMER
)This
->Pin
.Descriptor
->Dispatch
->Clock
->SetTimer
,
2227 (PFNKSCANCELTIMER
)This
->Pin
.Descriptor
->Dispatch
->Clock
->CancelTimer
,
2228 (PFNKSCORRELATEDTIME
)This
->Pin
.Descriptor
->Dispatch
->Clock
->CorrelatedTime
,
2234 Status
= KsAllocateDefaultClockEx(&This
->DefaultClock
, (PVOID
)&This
->Pin
, NULL
, NULL
, NULL
, NULL
, 0);
2238 if (NT_SUCCESS(Status
))
2240 Status
= KsCreateDefaultClock(Irp
, This
->DefaultClock
);
2244 DPRINT("IKsPin_DispatchCreateClock %lx\n", Status
);
2246 /* release control mutex */
2247 KsReleaseControl(Pin
);
2250 Irp
->IoStatus
.Status
= Status
;
2251 CompleteRequest(Irp
, IO_NO_INCREMENT
);
2257 IKsPin_DispatchCreateNode(
2258 IN PDEVICE_OBJECT DeviceObject
,
2263 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
2264 CompleteRequest(Irp
, IO_NO_INCREMENT
);
2265 return STATUS_NOT_IMPLEMENTED
;
2268 static KSDISPATCH_TABLE PinDispatchTable
=
2270 IKsPin_DispatchDeviceIoControl
,
2271 KsDispatchInvalidDeviceRequest
,
2272 KsDispatchInvalidDeviceRequest
,
2273 KsDispatchInvalidDeviceRequest
,
2275 KsDispatchQuerySecurity
,
2276 KsDispatchSetSecurity
,
2277 KsDispatchFastIoDeviceControlFailure
,
2278 KsDispatchFastReadFailure
,
2279 KsDispatchFastReadFailure
2284 IN PDEVICE_OBJECT DeviceObject
,
2286 IN PKSDEVICE KsDevice
,
2287 IN IKsFilterFactory
* FilterFactory
,
2288 IN IKsFilter
* Filter
,
2289 IN PKSPIN_CONNECT Connect
,
2290 IN KSPIN_DESCRIPTOR_EX
* Descriptor
)
2293 PIO_STACK_LOCATION IoStack
;
2295 PDEVICE_EXTENSION DeviceExtension
;
2296 PKSOBJECT_CREATE_ITEM CreateItem
;
2298 PKSDATAFORMAT DataFormat
;
2299 PKSBASIC_HEADER BasicHeader
;
2301 ULONG FrameSize
= 0;
2302 ULONG NumFrames
= 0;
2303 KSAUTOMATION_TABLE AutomationTable
;
2306 ASSERT(Descriptor
->Dispatch
);
2308 DPRINT("KspCreatePin PinId %lu Flags %x\n", Connect
->PinId
, Descriptor
->Flags
);
2310 //Output Pin: KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY
2311 //Input Pin: KSPIN_FLAG_FIXED_FORMAT|KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT|KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING
2313 DPRINT("KspCreatePin Dataflow %lu\n", Descriptor
->PinDescriptor
.DataFlow
);
2314 DPRINT("KspCreatePin Communication %lu\n", Descriptor
->PinDescriptor
.Communication
);
2315 if (Descriptor
->AllocatorFraming
)
2317 DPRINT("KspCreatePin CountItems %lu\n", Descriptor
->AllocatorFraming
->CountItems
);
2318 DPRINT("KspCreatePin PinFlags %lx\n", Descriptor
->AllocatorFraming
->PinFlags
);
2319 DPRINT("KspCreatePin OutputCompression RatioNumerator %lu RatioDenominator %lu RatioConstantMargin %lu\n", Descriptor
->AllocatorFraming
->OutputCompression
.RatioNumerator
,
2320 Descriptor
->AllocatorFraming
->OutputCompression
.RatioDenominator
, Descriptor
->AllocatorFraming
->OutputCompression
.RatioConstantMargin
);
2321 DPRINT("KspCreatePin PinWeight %lx\n", Descriptor
->AllocatorFraming
->PinWeight
);
2323 for(Index
= 0; Index
< Descriptor
->AllocatorFraming
->CountItems
; Index
++)
2325 DPRINT("KspCreatePin Index %lu MemoryFlags %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].MemoryFlags
);
2326 DPRINT("KspCreatePin Index %lu BusFlags %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].BusFlags
);
2327 DPRINT("KspCreatePin Index %lu Flags %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].Flags
);
2328 DPRINT("KspCreatePin Index %lu Frames %lu\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].Frames
);
2329 DPRINT("KspCreatePin Index %lu FileAlignment %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].FileAlignment
);
2330 DPRINT("KspCreatePin Index %lu MemoryTypeWeight %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].MemoryTypeWeight
);
2331 DPRINT("KspCreatePin Index %lu PhysicalRange MinFrameSize %lu MaxFrameSize %lu Stepping %lu\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].PhysicalRange
.MinFrameSize
,
2332 Descriptor
->AllocatorFraming
->FramingItem
[Index
].PhysicalRange
.MaxFrameSize
,
2333 Descriptor
->AllocatorFraming
->FramingItem
[Index
].PhysicalRange
.Stepping
);
2335 DPRINT("KspCreatePin Index %lu FramingRange MinFrameSize %lu MaxFrameSize %lu Stepping %lu InPlaceWeight %lu NotInPlaceWeight %lu\n",
2337 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.Range
.MinFrameSize
,
2338 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.Range
.MaxFrameSize
,
2339 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.Range
.Stepping
,
2340 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.InPlaceWeight
,
2341 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.NotInPlaceWeight
);
2343 FrameSize
= Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.Range
.MaxFrameSize
;
2344 NumFrames
= Descriptor
->AllocatorFraming
->FramingItem
[Index
].Frames
;
2348 for (Index
= 0; Index
< Descriptor
->PinDescriptor
.DataRangesCount
; Index
++)
2350 UNICODE_STRING GuidString
;
2351 /* convert the guid to string */
2352 RtlStringFromGUID(&Descriptor
->PinDescriptor
.DataRanges
[Index
]->MajorFormat
, &GuidString
);
2353 DPRINT("Index %lu MajorFormat %S\n", Index
, GuidString
.Buffer
);
2354 RtlStringFromGUID(&Descriptor
->PinDescriptor
.DataRanges
[Index
]->SubFormat
, &GuidString
);
2355 DPRINT("Index %lu SubFormat %S\n", Index
, GuidString
.Buffer
);
2356 RtlStringFromGUID(&Descriptor
->PinDescriptor
.DataRanges
[Index
]->Specifier
, &GuidString
);
2357 DPRINT("Index %lu Specifier %S\n", Index
, GuidString
.Buffer
);
2358 RtlStringFromGUID(&Descriptor
->PinDescriptor
.DataRanges
[Index
]->Specifier
, &GuidString
);
2359 DPRINT("Index %lu FormatSize %lu Flags %lu SampleSize %lu Reserved %lu KSDATAFORMAT %lu\n", Index
,
2360 Descriptor
->PinDescriptor
.DataRanges
[Index
]->FormatSize
, Descriptor
->PinDescriptor
.DataRanges
[Index
]->Flags
, Descriptor
->PinDescriptor
.DataRanges
[Index
]->SampleSize
, Descriptor
->PinDescriptor
.DataRanges
[Index
]->Reserved
, sizeof(KSDATAFORMAT
));
2362 if (IsEqualGUIDAligned(&Descriptor
->PinDescriptor
.DataRanges
[Index
]->SubFormat
, &KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT
))
2364 PKS_DATARANGE_BDA_TRANSPORT Transport
= (PKS_DATARANGE_BDA_TRANSPORT
)&Descriptor
->PinDescriptor
.DataRanges
[Index
];
2365 DPRINT("KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT AvgTimePerFrame %I64u ulcbPhyiscalFrame %lu ulcbPhyiscalFrameAlignment %lu ulcbPhyiscalPacket %lu\n", Transport
->BdaTransportInfo
.AvgTimePerFrame
, Transport
->BdaTransportInfo
.ulcbPhyiscalFrame
,
2366 Transport
->BdaTransportInfo
.ulcbPhyiscalFrameAlignment
, Transport
->BdaTransportInfo
.ulcbPhyiscalPacket
);
2371 /* default to 50 * 188 (MPEG2 TS packet size) */
2380 /* get current irp stack */
2381 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2383 /* get device extension */
2384 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
2386 /* get ks device interface */
2387 Device
= (IKsDevice
*)&DeviceExtension
->DeviceHeader
->BasicHeader
.OuterUnknown
;
2389 /* first allocate pin ctx */
2390 This
= AllocateItem(NonPagedPool
, sizeof(IKsPinImpl
));
2393 /* not enough memory */
2394 return STATUS_INSUFFICIENT_RESOURCES
;
2397 /* allocate create item */
2398 CreateItem
= AllocateItem(NonPagedPool
, sizeof(KSOBJECT_CREATE_ITEM
) * 3);
2401 /* not enough memory */
2403 DPRINT("KspCreatePin OutOfMemory\n");
2404 return STATUS_INSUFFICIENT_RESOURCES
;
2407 /* initialize basic header */
2408 This
->BasicHeader
.KsDevice
= KsDevice
;
2409 This
->BasicHeader
.Type
= KsObjectTypePin
;
2410 This
->BasicHeader
.Parent
.KsFilter
= Filter
->lpVtbl
->GetStruct(Filter
);
2411 This
->BasicHeader
.OuterUnknown
= (PUNKNOWN
)&vt_IKsPin
;
2412 InitializeListHead(&This
->BasicHeader
.EventList
);
2413 KeInitializeSpinLock(&This
->BasicHeader
.EventListLock
);
2415 ASSERT(This
->BasicHeader
.Parent
.KsFilter
);
2417 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)This
->BasicHeader
.Parent
.KsFilter
- sizeof(KSBASIC_HEADER
));
2419 This
->BasicHeader
.ControlMutex
= BasicHeader
->ControlMutex
;
2420 ASSERT(This
->BasicHeader
.ControlMutex
);
2422 InitializeListHead(&This
->BasicHeader
.EventList
);
2423 KeInitializeSpinLock(&This
->BasicHeader
.EventListLock
);
2425 /* initialize pin */
2426 This
->FrameSize
= FrameSize
;
2427 This
->NumFrames
= NumFrames
;
2428 This
->lpVtblReferenceClock
= &vt_ReferenceClock
;
2430 This
->FileObject
= IoStack
->FileObject
;
2431 This
->Filter
= Filter
;
2432 KeInitializeMutex(&This
->ProcessingMutex
, 0);
2433 InitializeListHead(&This
->IrpList
);
2434 KeInitializeSpinLock(&This
->IrpListLock
);
2436 /* allocate object bag */
2437 This
->Pin
.Bag
= AllocateItem(NonPagedPool
, sizeof(KSIOBJECT_BAG
));
2440 /* not enough memory */
2442 FreeItem(CreateItem
);
2443 return STATUS_INSUFFICIENT_RESOURCES
;
2446 /* initialize object bag */
2447 Device
->lpVtbl
->InitializeObjectBag(Device
, This
->Pin
.Bag
, NULL
);
2449 /* allocate pin descriptor */
2450 This
->Pin
.Descriptor
= AllocateItem(NonPagedPool
, sizeof(KSPIN_DESCRIPTOR_EX
));
2451 if (!This
->Pin
.Descriptor
)
2453 /* not enough memory */
2454 KsFreeObjectBag(This
->Pin
.Bag
);
2456 FreeItem(CreateItem
);
2457 return STATUS_INSUFFICIENT_RESOURCES
;
2460 /* copy pin descriptor */
2461 RtlMoveMemory((PVOID
)This
->Pin
.Descriptor
, Descriptor
, sizeof(KSPIN_DESCRIPTOR_EX
));
2463 /* initialize automation table */
2464 RtlZeroMemory(&AutomationTable
, sizeof(KSAUTOMATION_TABLE
));
2466 AutomationTable
.PropertyItemSize
= sizeof(KSPROPERTY_ITEM
);
2467 AutomationTable
.PropertySets
= PinPropertySet
;
2468 AutomationTable
.PropertySetsCount
= sizeof(PinPropertySet
) / sizeof(KSPROPERTY_SET
);
2470 /* merge in pin property sets */
2471 Status
= KsMergeAutomationTables((PKSAUTOMATION_TABLE
*)&This
->Pin
.Descriptor
->AutomationTable
, (PKSAUTOMATION_TABLE
)Descriptor
->AutomationTable
, &AutomationTable
, This
->Pin
.Bag
);
2473 if (!NT_SUCCESS(Status
))
2475 /* not enough memory */
2476 KsFreeObjectBag(This
->Pin
.Bag
);
2478 FreeItem(CreateItem
);
2483 DataFormat
= (PKSDATAFORMAT
)(Connect
+ 1);
2485 /* initialize pin descriptor */
2486 This
->Pin
.Context
= NULL
;
2487 This
->Pin
.Id
= Connect
->PinId
;
2488 This
->Pin
.Communication
= Descriptor
->PinDescriptor
.Communication
;
2489 This
->Pin
.ConnectionIsExternal
= FALSE
; //FIXME
2490 RtlMoveMemory(&This
->Pin
.ConnectionInterface
, &Connect
->Interface
, sizeof(KSPIN_INTERFACE
));
2491 RtlMoveMemory(&This
->Pin
.ConnectionMedium
, &Connect
->Medium
, sizeof(KSPIN_MEDIUM
));
2492 RtlMoveMemory(&This
->Pin
.ConnectionPriority
, &Connect
->Priority
, sizeof(KSPRIORITY
));
2494 /* allocate format */
2495 Status
= _KsEdit(This
->Pin
.Bag
, (PVOID
*)&This
->Pin
.ConnectionFormat
, DataFormat
->FormatSize
, DataFormat
->FormatSize
, 0);
2496 if (!NT_SUCCESS(Status
))
2498 /* failed to allocate format */
2499 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2501 FreeItem(CreateItem
);
2502 return STATUS_INSUFFICIENT_RESOURCES
;
2506 RtlMoveMemory((PVOID
)This
->Pin
.ConnectionFormat
, DataFormat
, DataFormat
->FormatSize
);
2508 This
->Pin
.AttributeList
= NULL
; //FIXME
2509 This
->Pin
.StreamHeaderSize
= sizeof(KSSTREAM_HEADER
);
2510 This
->Pin
.DataFlow
= Descriptor
->PinDescriptor
.DataFlow
;
2511 This
->Pin
.DeviceState
= KSSTATE_STOP
;
2512 This
->Pin
.ResetState
= KSRESET_END
;
2513 This
->Pin
.ClientState
= KSSTATE_STOP
;
2515 /* intialize allocator create item */
2516 CreateItem
[0].Context
= (PVOID
)&This
->Pin
;
2517 CreateItem
[0].Create
= IKsPin_DispatchCreateAllocator
;
2518 CreateItem
[0].Flags
= KSCREATE_ITEM_FREEONSTOP
;
2519 RtlInitUnicodeString(&CreateItem
[0].ObjectClass
, KSSTRING_Allocator
);
2521 /* intialize clock create item */
2522 CreateItem
[1].Context
= (PVOID
)&This
->Pin
;
2523 CreateItem
[1].Create
= IKsPin_DispatchCreateClock
;
2524 CreateItem
[1].Flags
= KSCREATE_ITEM_FREEONSTOP
;
2525 RtlInitUnicodeString(&CreateItem
[1].ObjectClass
, KSSTRING_Clock
);
2527 /* intialize topology node create item */
2528 CreateItem
[2].Context
= (PVOID
)&This
->Pin
;
2529 CreateItem
[2].Create
= IKsPin_DispatchCreateNode
;
2530 CreateItem
[2].Flags
= KSCREATE_ITEM_FREEONSTOP
;
2531 RtlInitUnicodeString(&CreateItem
[2].ObjectClass
, KSSTRING_TopologyNode
);
2533 /* now allocate object header */
2534 Status
= KsAllocateObjectHeader((KSOBJECT_HEADER
*)&This
->ObjectHeader
, 3, CreateItem
, Irp
, &PinDispatchTable
);
2535 if (!NT_SUCCESS(Status
))
2537 /* failed to create object header */
2538 DPRINT("KspCreatePin KsAllocateObjectHeader failed %lx\n", Status
);
2539 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2541 FreeItem(CreateItem
);
2543 /* return failure code */
2547 /* add extra info to object header */
2548 This
->ObjectHeader
->Type
= KsObjectTypePin
;
2549 This
->ObjectHeader
->Unknown
= (PUNKNOWN
)&This
->BasicHeader
.OuterUnknown
;
2550 This
->ObjectHeader
->ObjectType
= (PVOID
)&This
->Pin
;
2552 if (!Descriptor
->Dispatch
|| !Descriptor
->Dispatch
->Process
)
2554 /* the pin is part of filter-centric processing filter
2555 * add process pin to filter
2557 This
->ProcessPin
.BytesAvailable
= 0;
2558 This
->ProcessPin
.BytesUsed
= 0;
2559 This
->ProcessPin
.CopySource
= NULL
;
2560 This
->ProcessPin
.Data
= NULL
;
2561 This
->ProcessPin
.DelegateBranch
= NULL
;
2562 This
->ProcessPin
.Flags
= 0;
2563 This
->ProcessPin
.InPlaceCounterpart
= NULL
;
2564 This
->ProcessPin
.Pin
= &This
->Pin
;
2565 This
->ProcessPin
.StreamPointer
= (PKSSTREAM_POINTER
)&This
->LeadingEdgeStreamPointer
.StreamPointer
;
2566 This
->ProcessPin
.Terminate
= FALSE
;
2568 Status
= Filter
->lpVtbl
->AddProcessPin(Filter
, &This
->ProcessPin
);
2569 DPRINT("KspCreatePin AddProcessPin %lx\n", Status
);
2571 if (!NT_SUCCESS(Status
))
2573 /* failed to add process pin */
2574 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2575 KsFreeObjectHeader(&This
->ObjectHeader
);
2577 FreeItem(CreateItem
);
2578 /* return failure code */
2582 else if (Descriptor
->Dispatch
&& Descriptor
->Dispatch
->Process
)
2584 /* pin centric processing filter */
2586 /* initialize work item */
2587 ExInitializeWorkItem(&This
->PinWorkQueueItem
, IKsPin_PinCentricWorker
, (PVOID
)This
);
2589 /* allocate counted work item */
2590 Status
= KsRegisterCountedWorker(HyperCriticalWorkQueue
, &This
->PinWorkQueueItem
, &This
->PinWorker
);
2592 if (!NT_SUCCESS(Status
))
2594 DPRINT("Failed to register Worker %lx\n", Status
);
2595 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2596 KsFreeObjectHeader(&This
->ObjectHeader
);
2598 FreeItem(CreateItem
);
2602 if (This
->Pin
.Descriptor
->PinDescriptor
.DataFlow
== KSPIN_DATAFLOW_IN
)
2603 This
->LeadingEdgeStreamPointer
.StreamPointer
.Offset
= &This
->LeadingEdgeStreamPointer
.StreamPointer
.OffsetIn
;
2605 This
->LeadingEdgeStreamPointer
.StreamPointer
.Offset
= &This
->LeadingEdgeStreamPointer
.StreamPointer
.OffsetOut
;
2608 KeInitializeEvent(&This
->FrameComplete
, NotificationEvent
, FALSE
);
2612 /* FIXME add pin instance to filter instance */
2613 IKsFilter_AddPin(Filter
->lpVtbl
->GetStruct(Filter
), &This
->Pin
);
2615 if (Descriptor
->Dispatch
&& Descriptor
->Dispatch
->SetDataFormat
)
2617 Status
= Descriptor
->Dispatch
->SetDataFormat(&This
->Pin
, NULL
, NULL
, This
->Pin
.ConnectionFormat
, NULL
);
2618 DPRINT("KspCreatePin SetDataFormat %lx\n", Status
);
2622 /* does the driver have a pin dispatch */
2623 if (Descriptor
->Dispatch
&& Descriptor
->Dispatch
->Create
)
2625 /* now inform the driver to create a new pin */
2626 Status
= Descriptor
->Dispatch
->Create(&This
->Pin
, Irp
);
2627 DPRINT("KspCreatePin DispatchCreate %lx\n", Status
);
2631 DPRINT("KspCreatePin Status %lx KsDevice %p\n", Status
, KsDevice
);
2633 if (!NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
)
2635 /* failed to create pin, release resources */
2636 IKsFilter_RemovePin(Filter
->lpVtbl
->GetStruct(Filter
), &This
->Pin
);
2637 KsFreeObjectHeader((KSOBJECT_HEADER
)This
->ObjectHeader
);
2638 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2641 /* return failure code */