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
;
38 KMUTEX ProcessingMutex
;
39 PFILE_OBJECT FileObject
;
45 KSPIN_LOCK IrpListLock
;
46 volatile LONG IrpCount
;
48 PKSISTREAM_POINTER ClonedStreamPointer
;
49 KSISTREAM_POINTER LeadingEdgeStreamPointer
;
50 KSISTREAM_POINTER TrailingStreamPointer
;
54 PFNKSPINHANDSHAKE Handshake
;
55 PFNKSPINFRAMERETURN FrameReturn
;
56 PFNKSPINIRPCOMPLETION IrpCompletion
;
58 KSCLOCK_FUNCTIONTABLE ClockTable
;
59 PFILE_OBJECT ClockFileObject
;
60 IKsReferenceClockVtbl
* lpVtblReferenceClock
;
61 PKSDEFAULTCLOCK DefaultClock
;
64 WORK_QUEUE_ITEM PinWorkQueueItem
;
73 NTSTATUS NTAPI
IKsPin_PinStatePropertyHandler(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
74 NTSTATUS NTAPI
IKsPin_PinDataFormatPropertyHandler(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
75 NTSTATUS NTAPI
IKsPin_PinAllocatorFramingPropertyHandler(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
76 NTSTATUS NTAPI
IKsPin_PinStreamAllocator(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
77 NTSTATUS NTAPI
IKsPin_PinMasterClock(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
78 NTSTATUS NTAPI
IKsPin_PinPipeId(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
82 DEFINE_KSPROPERTY_CONNECTIONSET(PinConnectionSet
, IKsPin_PinStatePropertyHandler
, IKsPin_PinDataFormatPropertyHandler
, IKsPin_PinAllocatorFramingPropertyHandler
);
83 DEFINE_KSPROPERTY_STREAMSET(PinStreamSet
, IKsPin_PinStreamAllocator
, IKsPin_PinMasterClock
, IKsPin_PinPipeId
);
86 // KSPROPSETID_Connection
87 // KSPROPERTY_CONNECTION_ACQUIREORDERING
88 // KSPROPSETID_StreamInterface
89 // KSPROPERTY_STREAMINTERFACE_HEADERSIZE
91 KSPROPERTY_SET PinPropertySet
[] =
94 &KSPROPSETID_Connection
,
95 sizeof(PinConnectionSet
) / sizeof(KSPROPERTY_ITEM
),
96 (const KSPROPERTY_ITEM
*)&PinConnectionSet
,
102 sizeof(PinStreamSet
) / sizeof(KSPROPERTY_ITEM
),
103 (const KSPROPERTY_ITEM
*)&PinStreamSet
,
109 const GUID KSPROPSETID_Connection
= {0x1D58C920L
, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
110 const GUID KSPROPSETID_Stream
= {0x65aaba60L
, 0x98ae, 0x11cf, {0xa1, 0x0d, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4}};
111 const GUID KSPROPSETID_Clock
= {0xDF12A4C0L
, 0xAC17, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
115 IKsPin_PinStreamAllocator(
117 IN PKSIDENTIFIER Request
,
121 return STATUS_NOT_IMPLEMENTED
;
126 IKsPin_PinMasterClock(
128 IN PKSIDENTIFIER Request
,
131 PIO_STACK_LOCATION IoStack
;
132 PKSIOBJECT_HEADER ObjectHeader
;
134 NTSTATUS Status
= STATUS_SUCCESS
;
136 PFILE_OBJECT FileObject
;
137 KPROCESSOR_MODE Mode
;
141 /* get current irp stack */
142 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
144 DPRINT("IKsPin_PinMasterClock\n");
147 ASSERT(IoStack
->FileObject
);
148 ASSERT(IoStack
->FileObject
->FsContext2
);
150 /* get the object header */
151 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
154 ASSERT(ObjectHeader
);
156 /* locate ks pin implemention from KSPIN offset */
157 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
162 Handle
= (PHANDLE
)Data
;
164 if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
166 if (This
->Pin
.Descriptor
->PinDescriptor
.Communication
!= KSPIN_COMMUNICATION_NONE
&&
167 This
->Pin
.Descriptor
->Dispatch
&&
168 (This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_IMPLEMENT_CLOCK
))
171 Status
= STATUS_SUCCESS
;
175 /* no clock available */
176 Status
= STATUS_UNSUCCESSFUL
;
179 else if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
181 if (This
->Pin
.ClientState
!= KSSTATE_STOP
)
183 /* can only set in stopped state */
184 Status
= STATUS_INVALID_DEVICE_STATE
;
190 Mode
= ExGetPreviousMode();
192 Status
= ObReferenceObjectByHandle(*Handle
, SYNCHRONIZE
| DIRECTORY_QUERY
, IoFileObjectType
, Mode
, (PVOID
*)&FileObject
, NULL
);
194 DPRINT("IKsPin_PinMasterClock ObReferenceObjectByHandle %lx\n", Status
);
195 if (NT_SUCCESS(Status
))
197 Property
.Set
= KSPROPSETID_Clock
;
198 Property
.Id
= KSPROPERTY_CLOCK_FUNCTIONTABLE
;
199 Property
.Flags
= KSPROPERTY_TYPE_GET
;
201 Status
= KsSynchronousIoControlDevice(FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, &Property
, sizeof(KSPROPERTY
), &This
->ClockTable
, sizeof(KSCLOCK_FUNCTIONTABLE
), &BytesReturned
);
203 DPRINT("IKsPin_PinMasterClock KSPROPERTY_CLOCK_FUNCTIONTABLE %lx\n", Status
);
205 if (NT_SUCCESS(Status
))
207 This
->ClockFileObject
= FileObject
;
211 ObDereferenceObject(FileObject
);
217 /* zeroing clock handle */
218 RtlZeroMemory(&This
->ClockTable
, sizeof(KSCLOCK_FUNCTIONTABLE
));
219 Status
= STATUS_SUCCESS
;
220 if (This
->ClockFileObject
)
222 FileObject
= This
->ClockFileObject
;
223 This
->ClockFileObject
= NULL
;
225 ObDereferenceObject(This
->ClockFileObject
);
231 DPRINT("IKsPin_PinMasterClock Status %lx\n", Status
);
241 IN PKSIDENTIFIER Request
,
245 return STATUS_NOT_IMPLEMENTED
;
251 IKsPin_PinStatePropertyHandler(
253 IN PKSIDENTIFIER Request
,
256 PIO_STACK_LOCATION IoStack
;
257 PKSIOBJECT_HEADER ObjectHeader
;
259 NTSTATUS Status
= STATUS_SUCCESS
;
263 /* get current irp stack */
264 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
266 DPRINT("IKsPin_PinStatePropertyHandler\n");
269 ASSERT(IoStack
->FileObject
);
270 ASSERT(IoStack
->FileObject
->FsContext2
);
272 /* get the object header */
273 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
275 /* locate ks pin implemention from KSPIN offset */
276 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
278 /* acquire control mutex */
279 KeWaitForSingleObject(This
->BasicHeader
.ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
282 NewState
= (PKSSTATE
)Data
;
284 if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
286 *NewState
= This
->Pin
.DeviceState
;
287 Irp
->IoStatus
.Information
= sizeof(KSSTATE
);
289 else if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
291 if (This
->Pin
.Descriptor
->Dispatch
->SetDeviceState
)
293 /* backup old state */
294 OldState
= This
->Pin
.ClientState
;
297 This
->Pin
.ClientState
= *NewState
;
298 This
->Pin
.DeviceState
= KSSTATE_RUN
;
300 /* check if it supported */
301 Status
= This
->Pin
.Descriptor
->Dispatch
->SetDeviceState(&This
->Pin
, *NewState
, OldState
);
303 DPRINT("IKsPin_PinStatePropertyHandler NewState %lu Result %lx\n", *NewState
, Status
);
305 if (!NT_SUCCESS(Status
))
307 /* revert to old state */
308 This
->Pin
.ClientState
= OldState
;
309 This
->Pin
.DeviceState
= OldState
;
310 DPRINT("IKsPin_PinStatePropertyHandler failed to set state %lx Result %lx\n", *NewState
, Status
);
315 /* update device state */
316 This
->Pin
.DeviceState
= *NewState
;
321 /* just set new state */
322 This
->Pin
.DeviceState
= *NewState
;
323 This
->Pin
.ClientState
= *NewState
;
327 /* release processing mutex */
328 KeReleaseMutex(This
->BasicHeader
.ControlMutex
, FALSE
);
330 DPRINT("IKsPin_PinStatePropertyHandler Status %lx\n", Status
);
336 IKsPin_PinAllocatorFramingPropertyHandler(
338 IN PKSIDENTIFIER Request
,
341 PIO_STACK_LOCATION IoStack
;
342 PKSIOBJECT_HEADER ObjectHeader
;
345 NTSTATUS Status
= STATUS_SUCCESS
;
347 /* get current irp stack */
348 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
351 ASSERT(IoStack
->FileObject
);
352 ASSERT(IoStack
->FileObject
->FsContext2
);
354 /* get the object header */
355 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
357 /* locate ks pin implemention from KSPIN offset */
358 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
360 /* setting allocator flags is not supported */
361 ASSERT(!(Request
->Flags
& KSPROPERTY_TYPE_SET
));
363 /* acquire control mutex */
364 KeWaitForSingleObject(This
->BasicHeader
.ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
366 if (This
->Pin
.Descriptor
->AllocatorFraming
)
369 Size
= FIELD_OFFSET(KSALLOCATOR_FRAMING_EX
, FramingItem
[0]) + This
->Pin
.Descriptor
->AllocatorFraming
->CountItems
* sizeof(KS_FRAMING_ITEM
);
371 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== 0)
374 Status
= STATUS_BUFFER_OVERFLOW
;
376 else if (Size
> IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
)
378 /* buffer too small */
379 Status
= STATUS_BUFFER_TOO_SMALL
;
384 RtlMoveMemory(Data
, This
->Pin
.Descriptor
->AllocatorFraming
, Size
);
388 Irp
->IoStatus
.Information
= Size
;
392 /* no allocator framing details */
393 Status
= STATUS_NOT_FOUND
;
396 /* release processing mutex */
397 KeReleaseMutex(This
->BasicHeader
.ControlMutex
, FALSE
);
399 DPRINT("IKsPin_PinAllocatorFramingPropertyHandler Status %lx\n", Status
);
406 IKsPin_PinDataFormatPropertyHandler(
408 IN PKSPROPERTY Request
,
411 PIO_STACK_LOCATION IoStack
;
412 PKSIOBJECT_HEADER ObjectHeader
;
414 NTSTATUS Status
= STATUS_SUCCESS
;
416 /* get current irp stack */
417 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
419 DPRINT("IKsPin_PinDataFormatPropertyHandler\n");
422 ASSERT(IoStack
->FileObject
);
423 ASSERT(IoStack
->FileObject
->FsContext2
);
425 /* get the object header */
426 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
428 /* locate ks pin implemention from KSPIN offset */
429 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
431 /* acquire control mutex */
432 KeWaitForSingleObject(This
->BasicHeader
.ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
434 if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
436 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< This
->Pin
.ConnectionFormat
->FormatSize
)
438 /* buffer too small */
439 Irp
->IoStatus
.Information
= This
->Pin
.ConnectionFormat
->FormatSize
;
440 Status
= STATUS_BUFFER_TOO_SMALL
;
445 RtlMoveMemory(Data
, This
->Pin
.ConnectionFormat
, This
->Pin
.ConnectionFormat
->FormatSize
);
448 else if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
451 if (This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_FIXED_FORMAT
)
453 /* format cannot be changed */
454 Status
= STATUS_INVALID_DEVICE_REQUEST
;
458 /* FIXME check if the format is supported */
459 Status
= _KsEdit(This
->Pin
.Bag
, (PVOID
*)&This
->Pin
.ConnectionFormat
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, This
->Pin
.ConnectionFormat
->FormatSize
, 0);
461 if (NT_SUCCESS(Status
))
463 /* store new format */
464 RtlMoveMemory(This
->Pin
.ConnectionFormat
, Data
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
);
469 /* release processing mutex */
470 KeReleaseMutex(This
->BasicHeader
.ControlMutex
, FALSE
);
472 DPRINT("IKsPin_PinDataFormatPropertyHandler Status %lx\n", Status
);
479 IKsPin_fnQueryInterface(
485 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, BasicHeader
.OuterUnknown
);
487 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
))
489 *Output
= &This
->BasicHeader
.OuterUnknown
;
490 _InterlockedIncrement(&This
->ref
);
491 return STATUS_SUCCESS
;
495 if (This
->BasicHeader
.ClientAggregate
)
497 /* using client aggregate */
498 Status
= This
->BasicHeader
.ClientAggregate
->lpVtbl
->QueryInterface(This
->BasicHeader
.ClientAggregate
, refiid
, Output
);
500 if (NT_SUCCESS(Status
))
502 /* client aggregate supports interface */
507 DPRINT("IKsPin_fnQueryInterface no interface\n");
508 return STATUS_NOT_SUPPORTED
;
516 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, BasicHeader
.OuterUnknown
);
518 return InterlockedIncrement(&This
->ref
);
526 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, BasicHeader
.OuterUnknown
);
528 InterlockedDecrement(&This
->ref
);
535 /* Return new reference count */
541 IKsPin_fnTransferKsIrp(
544 IN IKsTransport
**OutTransport
)
547 return STATUS_NOT_IMPLEMENTED
;
552 IKsPin_fnDiscardKsIrp(
555 IN IKsTransport
* *OutTransport
)
565 IN IKsTransport
* TransportIn
,
566 OUT IKsTransport
** OutTransportIn
,
567 OUT IKsTransport
* *OutTransportOut
,
568 IN KSPIN_DATAFLOW DataFlow
)
571 return STATUS_NOT_IMPLEMENTED
;
576 IKsPin_fnSetDeviceState(
580 IN IKsTransport
* *OutTransport
)
583 return STATUS_NOT_IMPLEMENTED
;
588 IKsPin_fnSetResetState(
590 IN KSRESET ResetState
,
591 OUT IKsTransport
* * OutTransportOut
)
598 IKsPin_fnGetTransportConfig(
600 IN
struct KSPTRANSPORTCONFIG
* TransportConfig
,
601 OUT IKsTransport
** OutTransportIn
,
602 OUT IKsTransport
** OutTransportOut
)
605 return STATUS_NOT_IMPLEMENTED
;
610 IKsPin_fnSetTransportConfig(
612 IN
struct KSPTRANSPORTCONFIG
const * TransportConfig
,
613 OUT IKsTransport
** OutTransportIn
,
614 OUT IKsTransport
** OutTransportOut
)
617 return STATUS_NOT_IMPLEMENTED
;
622 IKsPin_fnResetTransportConfig(
624 OUT IKsTransport
** OutTransportIn
,
625 OUT IKsTransport
** OutTransportOut
)
628 return STATUS_NOT_IMPLEMENTED
;
642 IKsPin_fnGetProcessPin(
651 IKsPin_fnAttemptBypass(
655 return STATUS_NOT_IMPLEMENTED
;
660 IKsPin_fnAttemptUnbypass(
664 return STATUS_NOT_IMPLEMENTED
;
669 IKsPin_fnGenerateConnectionEvents(
678 IKsPin_fnClientSetDeviceState(
684 return STATUS_NOT_IMPLEMENTED
;
687 static IKsPinVtbl vt_IKsPin
=
689 IKsPin_fnQueryInterface
,
692 IKsPin_fnTransferKsIrp
,
693 IKsPin_fnDiscardKsIrp
,
695 IKsPin_fnSetDeviceState
,
696 IKsPin_fnSetResetState
,
697 IKsPin_fnGetTransportConfig
,
698 IKsPin_fnSetTransportConfig
,
699 IKsPin_fnResetTransportConfig
,
701 IKsPin_fnGetProcessPin
,
702 IKsPin_fnAttemptBypass
,
703 IKsPin_fnAttemptUnbypass
,
704 IKsPin_fnGenerateConnectionEvents
,
705 IKsPin_fnClientSetDeviceState
709 //==============================================================
713 IKsReferenceClock_fnQueryInterface(
714 IKsReferenceClock
* iface
,
718 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
720 return IKsPin_fnQueryInterface((IKsPin
*)&This
->BasicHeader
.OuterUnknown
, refiid
, Output
);
725 IKsReferenceClock_fnAddRef(
726 IKsReferenceClock
* iface
)
728 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
730 return IKsPin_fnAddRef((IKsPin
*)&This
->BasicHeader
.OuterUnknown
);
735 IKsReferenceClock_fnRelease(
736 IKsReferenceClock
* iface
)
738 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
740 return IKsPin_fnRelease((IKsPin
*)&This
->BasicHeader
.OuterUnknown
);
745 IKsReferenceClock_fnGetTime(
746 IKsReferenceClock
* iface
)
750 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
753 DPRINT1("IKsReferenceClock_fnGetTime\n");
755 if (!This
->ClockFileObject
|| !This
->ClockTable
.GetTime
)
761 Result
= This
->ClockTable
.GetTime(This
->ClockFileObject
);
769 IKsReferenceClock_fnGetPhysicalTime(
770 IKsReferenceClock
* iface
)
774 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
776 DPRINT1("IKsReferenceClock_fnGetPhysicalTime\n");
779 if (!This
->ClockFileObject
|| !This
->ClockTable
.GetPhysicalTime
)
785 Result
= This
->ClockTable
.GetPhysicalTime(This
->ClockFileObject
);
794 IKsReferenceClock_fnGetCorrelatedTime(
795 IKsReferenceClock
* iface
,
796 OUT PLONGLONG SystemTime
)
800 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
802 DPRINT1("IKsReferenceClock_fnGetCorrelatedTime\n");
804 if (!This
->ClockFileObject
|| !This
->ClockTable
.GetCorrelatedTime
)
810 Result
= This
->ClockTable
.GetCorrelatedTime(This
->ClockFileObject
, SystemTime
);
819 IKsReferenceClock_fnGetCorrelatedPhysicalTime(
820 IKsReferenceClock
* iface
,
821 OUT PLONGLONG SystemTime
)
825 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
827 DPRINT1("IKsReferenceClock_fnGetCorrelatedPhysicalTime\n");
829 if (!This
->ClockFileObject
|| !This
->ClockTable
.GetCorrelatedPhysicalTime
)
835 Result
= This
->ClockTable
.GetCorrelatedPhysicalTime(This
->ClockFileObject
, SystemTime
);
843 IKsReferenceClock_fnGetResolution(
844 IKsReferenceClock
* iface
,
845 OUT PKSRESOLUTION Resolution
)
850 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
852 DPRINT1("IKsReferenceClock_fnGetResolution\n");
854 if (!This
->ClockFileObject
)
856 Resolution
->Error
= 0;
857 Resolution
->Granularity
= 1;
858 DPRINT1("IKsReferenceClock_fnGetResolution Using HACK\n");
859 return STATUS_SUCCESS
;
863 if (!This
->ClockFileObject
)
864 return STATUS_DEVICE_NOT_READY
;
867 Property
.Set
= KSPROPSETID_Clock
;
868 Property
.Id
= KSPROPERTY_CLOCK_RESOLUTION
;
869 Property
.Flags
= KSPROPERTY_TYPE_GET
;
871 return KsSynchronousIoControlDevice(This
->ClockFileObject
, KernelMode
, IOCTL_KS_PROPERTY
, &Property
, sizeof(KSPROPERTY
), Resolution
, sizeof(KSRESOLUTION
), &BytesReturned
);
877 IKsReferenceClock_fnGetState(
878 IKsReferenceClock
* iface
,
884 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
886 DPRINT1("IKsReferenceClock_fnGetState\n");
888 if (!This
->ClockFileObject
)
890 *State
= This
->Pin
.ClientState
;
891 DPRINT1("IKsReferenceClock_fnGetState Using HACK\n");
892 return STATUS_SUCCESS
;
896 if (!This
->ClockFileObject
)
897 return STATUS_DEVICE_NOT_READY
;
900 Property
.Set
= KSPROPSETID_Clock
;
901 Property
.Id
= KSPROPERTY_CLOCK_RESOLUTION
;
902 Property
.Flags
= KSPROPERTY_TYPE_GET
;
904 return KsSynchronousIoControlDevice(This
->ClockFileObject
, KernelMode
, IOCTL_KS_PROPERTY
, &Property
, sizeof(KSPROPERTY
), State
, sizeof(KSSTATE
), &BytesReturned
);
907 static IKsReferenceClockVtbl vt_ReferenceClock
=
909 IKsReferenceClock_fnQueryInterface
,
910 IKsReferenceClock_fnAddRef
,
911 IKsReferenceClock_fnRelease
,
912 IKsReferenceClock_fnGetTime
,
913 IKsReferenceClock_fnGetPhysicalTime
,
914 IKsReferenceClock_fnGetCorrelatedTime
,
915 IKsReferenceClock_fnGetCorrelatedPhysicalTime
,
916 IKsReferenceClock_fnGetResolution
,
917 IKsReferenceClock_fnGetState
921 //==============================================================
929 KsPinAcquireProcessingMutex(
932 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
934 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
944 IN PKSGATE AndGate OPTIONAL
)
946 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
948 /* FIXME attach to filter's and gate (filter-centric processing) */
950 This
->AttachedGate
= AndGate
;
951 This
->OrGate
= FALSE
;
961 IN PKSGATE OrGate OPTIONAL
)
963 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
965 /* FIXME attach to filter's and gate (filter-centric processing) */
967 This
->AttachedGate
= OrGate
;
979 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
981 return This
->AttachedGate
;
989 KsPinAttemptProcessing(
991 IN BOOLEAN Asynchronous
)
993 DPRINT("KsPinAttemptProcessing\n");
1003 KsPinGetAvailableByteCount(
1005 OUT PLONG InputDataBytes OPTIONAL
,
1006 OUT PLONG OutputBufferBytes OPTIONAL
)
1009 return STATUS_NOT_IMPLEMENTED
;
1017 KsPinGetConnectedFilterInterface(
1019 IN
const GUID
* InterfaceId
,
1020 OUT PVOID
* Interface
)
1023 return STATUS_NOT_IMPLEMENTED
;
1031 KsPinGetConnectedPinDeviceObject(
1043 KsPinGetConnectedPinFileObject(
1055 KsPinGetConnectedPinInterface(
1057 IN
const GUID
* InterfaceId
,
1058 OUT PVOID
* Interface
)
1061 return STATUS_NOT_IMPLEMENTED
;
1069 KsPinGetCopyRelationships(
1071 OUT PKSPIN
* CopySource
,
1072 OUT PKSPIN
* DelegateBranch
)
1082 KsPinGetNextSiblingPin(
1085 return KsGetNextSibling((PVOID
)Pin
);
1093 KsPinGetParentFilter(
1096 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1098 /* return parent filter */
1099 return This
->BasicHeader
.Parent
.KsFilter
;
1107 KsPinGetReferenceClockInterface(
1109 OUT PIKSREFERENCECLOCK
* Interface
)
1111 NTSTATUS Status
= STATUS_DEVICE_NOT_READY
;
1112 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1114 if (This
->ClockFileObject
)
1116 /* clock is available */
1117 *Interface
= (PIKSREFERENCECLOCK
)&This
->lpVtblReferenceClock
;
1118 Status
= STATUS_SUCCESS
;
1121 DPRINT("KsPinGetReferenceClockInterface Pin %p Interface %p Status %x\n", Pin
, Interface
, Status
);
1130 KsPinRegisterFrameReturnCallback(
1132 IN PFNKSPINFRAMERETURN FrameReturn
)
1134 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1136 /* register frame return callback */
1137 This
->FrameReturn
= FrameReturn
;
1145 KsPinRegisterHandshakeCallback(
1147 IN PFNKSPINHANDSHAKE Handshake
)
1149 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1151 /* register private protocol handshake callback */
1152 This
->Handshake
= Handshake
;
1160 KsPinRegisterIrpCompletionCallback(
1162 IN PFNKSPINIRPCOMPLETION IrpCompletion
)
1164 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1166 /* register irp completion callback */
1167 This
->IrpCompletion
= IrpCompletion
;
1175 KsPinRegisterPowerCallbacks(
1177 IN PFNKSPINPOWER Sleep OPTIONAL
,
1178 IN PFNKSPINPOWER Wake OPTIONAL
)
1180 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1182 /* register power callbacks */
1183 This
->Sleep
= Sleep
;
1192 KsPinReleaseProcessingMutex(
1195 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1197 /* release processing mutex */
1198 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
1210 PKSIOBJECT_HEADER ObjectHeader
;
1212 PKSBASIC_HEADER Header
;
1213 PIO_STACK_LOCATION IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1215 DPRINT("KsGetPinFromIrp\n");
1217 /* get object header */
1218 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
1223 Pin
= (PKSPIN
)ObjectHeader
->ObjectType
;
1224 Header
= (PKSBASIC_HEADER
)((ULONG_PTR
)Pin
- sizeof(KSBASIC_HEADER
));
1227 ASSERT(Header
->Type
== KsObjectTypePin
);
1229 /* return object type */
1240 KsPinSetPinClockTime(
1254 IN PVOID Data OPTIONAL
,
1255 IN ULONG Size OPTIONAL
,
1256 IN PKSSTREAM_HEADER StreamHeader OPTIONAL
,
1257 IN PVOID Context OPTIONAL
)
1260 return STATUS_UNSUCCESSFUL
;
1269 KsPinSubmitFrameMdl(
1271 IN PMDL Mdl OPTIONAL
,
1272 IN PKSSTREAM_HEADER StreamHeader OPTIONAL
,
1273 IN PVOID Context OPTIONAL
)
1276 return STATUS_UNSUCCESSFUL
;
1286 IN PKSPROCESSPIN ProcessPin
)
1293 IKsPin_PrepareStreamHeader(
1294 IN IKsPinImpl
* This
,
1295 IN PKSISTREAM_POINTER StreamPointer
)
1297 PKSSTREAM_HEADER Header
;
1301 StreamPointer
->Irp
= KsRemoveIrpFromCancelableQueue(&This
->IrpList
, &This
->IrpListLock
, KsListEntryHead
, KsAcquireAndRemoveOnlySingleItem
);
1302 if (!StreamPointer
->Irp
)
1304 /* run out of mappings */
1305 DPRINT("OutOfMappings\n");
1306 return STATUS_DEVICE_NOT_READY
;
1309 InterlockedDecrement(&This
->IrpCount
);
1310 KsDecrementCountedWorker(This
->PinWorker
);
1312 /* get stream header */
1313 if (StreamPointer
->Irp
->RequestorMode
== UserMode
)
1314 Header
= (PKSSTREAM_HEADER
)StreamPointer
->Irp
->AssociatedIrp
.SystemBuffer
;
1316 Header
= (PKSSTREAM_HEADER
)StreamPointer
->Irp
->UserBuffer
;
1318 /* initialize stream pointer */
1319 StreamPointer
->Callback
= NULL
;
1320 StreamPointer
->Length
= max(Header
->DataUsed
, Header
->FrameExtent
);
1321 StreamPointer
->Next
= NULL
;
1322 StreamPointer
->Offset
= 0;
1323 StreamPointer
->Pin
= &This
->Pin
;
1324 StreamPointer
->Data
= Header
->Data
;
1326 StreamPointer
->StreamPointer
.Context
= NULL
;
1327 StreamPointer
->StreamPointer
.Pin
= &This
->Pin
;
1328 StreamPointer
->StreamPointer
.StreamHeader
= Header
;
1330 if (This
->Pin
.Descriptor
->PinDescriptor
.DataFlow
== KSPIN_DATAFLOW_IN
)
1331 StreamPointer
->StreamPointer
.Offset
= &StreamPointer
->StreamPointer
.OffsetIn
;
1333 StreamPointer
->StreamPointer
.Offset
= &StreamPointer
->StreamPointer
.OffsetOut
;
1335 StreamPointer
->StreamPointer
.Offset
->Alignment
= 0;
1336 StreamPointer
->StreamPointer
.Offset
->Count
= 0;
1337 StreamPointer
->StreamPointer
.Offset
->Data
= NULL
;
1338 StreamPointer
->StreamPointer
.Offset
->Remaining
= 0;
1340 ASSERT(StreamPointer
->StreamPointer
.Offset
->Remaining
== 0);
1342 //StreamPointer->Offset += StreamPointer->StreamPointer.Offset->Count;
1344 ASSERT(StreamPointer
->Length
> StreamPointer
->Offset
);
1345 ASSERT(StreamPointer
->StreamPointer
.StreamHeader
);
1346 ASSERT(This
->FrameSize
);
1348 /* calculate length */
1349 /* TODO split into frames */
1350 Length
= StreamPointer
->Length
;
1355 StreamPointer
->StreamPointer
.Offset
->Alignment
= 0;
1356 StreamPointer
->StreamPointer
.Context
= NULL
;
1357 StreamPointer
->StreamPointer
.Pin
= &This
->Pin
;
1358 StreamPointer
->StreamPointer
.Offset
->Count
= Length
;
1359 StreamPointer
->StreamPointer
.Offset
->Remaining
= Length
;
1360 StreamPointer
->StreamPointer
.Offset
->Data
= (PVOID
)((ULONG_PTR
)StreamPointer
->Data
+ StreamPointer
->Offset
);
1361 StreamPointer
->StreamPointer
.StreamHeader
->FrameExtent
= Length
;
1362 if (StreamPointer
->StreamPointer
.StreamHeader
->DataUsed
)
1363 StreamPointer
->StreamPointer
.StreamHeader
->DataUsed
= Length
;
1365 StreamPointer
->StreamPointer
.StreamHeader
->Data
= StreamPointer
->StreamPointer
.Offset
->Data
;
1367 return STATUS_SUCCESS
;
1377 KsPinGetLeadingEdgeStreamPointer(
1379 IN KSSTREAM_POINTER_STATE State
)
1384 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1386 DPRINT("KsPinGetLeadingEdgeStreamPointer Pin %p State %x Count %lu Remaining %lu\n", Pin
, State
,
1387 This
->LeadingEdgeStreamPointer
.Length
,
1388 This
->LeadingEdgeStreamPointer
.Offset
);
1391 ASSERT(State
== KSSTREAM_POINTER_STATE_LOCKED
);
1393 if (State
== KSSTREAM_POINTER_STATE_LOCKED
)
1395 if (!This
->LeadingEdgeStreamPointer
.Irp
|| This
->LeadingEdgeStreamPointer
.StreamPointer
.Offset
->Remaining
== 0)
1397 Status
= IKsPin_PrepareStreamHeader(This
, &This
->LeadingEdgeStreamPointer
);
1398 if (!NT_SUCCESS(Status
))
1402 DPRINT("KsPinGetLeadingEdgeStreamPointer NewOffset %lu TotalLength %lu\n", This
->LeadingEdgeStreamPointer
.Offset
, This
->LeadingEdgeStreamPointer
.Length
);
1405 return &This
->LeadingEdgeStreamPointer
.StreamPointer
;
1414 KsPinGetTrailingEdgeStreamPointer(
1416 IN KSSTREAM_POINTER_STATE State
)
1428 KsStreamPointerSetStatusCode(
1429 IN PKSSTREAM_POINTER StreamPointer
,
1433 return STATUS_UNSUCCESSFUL
;
1442 KsStreamPointerLock(
1443 IN PKSSTREAM_POINTER StreamPointer
)
1446 return STATUS_UNSUCCESSFUL
;
1455 KsStreamPointerUnlock(
1456 IN PKSSTREAM_POINTER StreamPointer
,
1459 PKSISTREAM_POINTER Pointer
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1461 DPRINT("KsStreamPointerUnlock StreamPointer %pEject %lu\n", StreamPointer
, Eject
);
1463 Pointer
->Irp
= NULL
;
1472 KsStreamPointerAdvanceOffsetsAndUnlock(
1473 IN PKSSTREAM_POINTER StreamPointer
,
1478 DPRINT("KsStreamPointerAdvanceOffsets InUsed %lu OutUsed %lu Eject %lu\n", InUsed
, OutUsed
, Eject
);
1489 KsStreamPointerDelete(
1490 IN PKSSTREAM_POINTER StreamPointer
)
1493 PKSISTREAM_POINTER Cur
, Last
;
1494 PKSISTREAM_POINTER Pointer
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1496 DPRINT("KsStreamPointerDelete %p\n", Pointer
);
1498 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pointer
->StreamPointer
.Pin
, IKsPinImpl
, Pin
);
1500 /* point to first stream pointer */
1502 Cur
= This
->ClonedStreamPointer
;
1504 while(Cur
!= Pointer
&& Cur
)
1507 /* iterate to next cloned pointer */
1513 /* you naughty driver */
1519 /* remove first cloned pointer */
1520 This
->ClonedStreamPointer
= Pointer
->Next
;
1524 Last
->Next
= Pointer
->Next
;
1527 /* FIXME make sure no timeouts are pending */
1537 KsStreamPointerClone(
1538 IN PKSSTREAM_POINTER StreamPointer
,
1539 IN PFNKSSTREAMPOINTER CancelCallback OPTIONAL
,
1540 IN ULONG ContextSize
,
1541 OUT PKSSTREAM_POINTER
* CloneStreamPointer
)
1544 PKSISTREAM_POINTER CurFrame
;
1545 PKSISTREAM_POINTER NewFrame
;
1550 DPRINT("KsStreamPointerClone StreamPointer %p CancelCallback %p ContextSize %p CloneStreamPointer %p\n", StreamPointer
, CancelCallback
, ContextSize
, CloneStreamPointer
);
1552 /* get stream pointer */
1553 CurFrame
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1555 /* calculate context size */
1556 Size
= sizeof(KSISTREAM_POINTER
) + ContextSize
;
1558 /* allocate new stream pointer */
1559 NewFrame
= (PKSISTREAM_POINTER
)ExAllocatePool(NonPagedPool
, Size
);
1562 return STATUS_INSUFFICIENT_RESOURCES
;
1564 /* get current irp stack location */
1565 RefCount
= (ULONG
)CurFrame
->Irp
->Tail
.Overlay
.DriverContext
[0];
1567 /* increment reference count */
1569 CurFrame
->Irp
->Tail
.Overlay
.DriverContext
[0] = (PVOID
)RefCount
;
1571 /* copy stream pointer */
1572 RtlMoveMemory(NewFrame
, CurFrame
, sizeof(KSISTREAM_POINTER
));
1575 This
= (IKsPinImpl
*)CONTAINING_RECORD(CurFrame
->Pin
, IKsPinImpl
, Pin
);
1577 /* prepare stream header in case required */
1578 if (CurFrame
->StreamPointer
.Offset
->Remaining
== 0)
1580 Status
= IKsPin_PrepareStreamHeader(This
, NewFrame
);
1581 if (!NT_SUCCESS(Status
))
1584 return STATUS_DEVICE_NOT_READY
;
1589 NewFrame
->StreamPointer
.Context
= (NewFrame
+ 1);
1592 if (This
->Pin
.Descriptor
->PinDescriptor
.DataFlow
== KSPIN_DATAFLOW_IN
)
1593 NewFrame
->StreamPointer
.Offset
= &NewFrame
->StreamPointer
.OffsetIn
;
1595 NewFrame
->StreamPointer
.Offset
= &NewFrame
->StreamPointer
.OffsetOut
;
1599 NewFrame
->StreamPointer
.Pin
= &This
->Pin
;
1601 ASSERT(NewFrame
->StreamPointer
.Pin
);
1602 ASSERT(NewFrame
->StreamPointer
.Context
);
1603 ASSERT(NewFrame
->StreamPointer
.Offset
);
1604 ASSERT(NewFrame
->StreamPointer
.StreamHeader
);
1607 *CloneStreamPointer
= &NewFrame
->StreamPointer
;
1609 DPRINT("KsStreamPointerClone CloneStreamPointer %p\n", *CloneStreamPointer
);
1611 return STATUS_SUCCESS
;
1620 KsStreamPointerAdvanceOffsets(
1621 IN PKSSTREAM_POINTER StreamPointer
,
1626 PKSISTREAM_POINTER CurFrame
;
1630 DPRINT("KsStreamPointerAdvanceOffsets StreamPointer %p InUsed %lu OutUsed %lu Eject %lu\n", StreamPointer
, InUsed
, OutUsed
, Eject
);
1632 /* get stream pointer */
1633 CurFrame
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1636 This
= (IKsPinImpl
*)CONTAINING_RECORD(CurFrame
->Pin
, IKsPinImpl
, Pin
);
1639 ASSERT(InUsed
== 0);
1643 DPRINT("KsStreamPointerAdvanceOffsets Offset %lu Length %lu NewOffset %lu Remaining %lu LeadingEdge %p DataUsed %lu\n", CurFrame
->Offset
, CurFrame
->Length
, CurFrame
->Offset
+ OutUsed
,
1644 CurFrame
->StreamPointer
.OffsetOut
.Remaining
, &This
->LeadingEdgeStreamPointer
.StreamPointer
, CurFrame
->StreamPointer
.StreamHeader
->DataUsed
);
1647 if (This
->Pin
.Descriptor
->PinDescriptor
.DataFlow
== KSPIN_DATAFLOW_IN
)
1649 ASSERT(CurFrame
->StreamPointer
.OffsetIn
.Remaining
>= InUsed
);
1650 CurFrame
->StreamPointer
.OffsetIn
.Remaining
-= InUsed
;
1651 CurFrame
->StreamPointer
.OffsetIn
.Data
= (PVOID
)((ULONG_PTR
)CurFrame
->StreamPointer
.OffsetIn
.Data
+ InUsed
);
1655 if (!CurFrame
->StreamPointer
.OffsetOut
.Remaining
)
1657 Status
= IKsPin_PrepareStreamHeader(This
, CurFrame
);
1658 if (!NT_SUCCESS(Status
))
1660 return STATUS_DEVICE_NOT_READY
;
1665 ASSERT(CurFrame
->StreamPointer
.OffsetOut
.Remaining
>= OutUsed
);
1666 CurFrame
->StreamPointer
.OffsetOut
.Remaining
-= OutUsed
;
1667 CurFrame
->StreamPointer
.OffsetOut
.Data
= (PVOID
)((ULONG_PTR
)CurFrame
->StreamPointer
.OffsetOut
.Data
+ OutUsed
);
1671 return STATUS_SUCCESS
;
1680 KsStreamPointerAdvance(
1681 IN PKSSTREAM_POINTER StreamPointer
)
1685 return STATUS_NOT_IMPLEMENTED
;
1694 KsStreamPointerGetMdl(
1695 IN PKSSTREAM_POINTER StreamPointer
)
1707 KsStreamPointerGetIrp(
1708 IN PKSSTREAM_POINTER StreamPointer
,
1709 OUT PBOOLEAN FirstFrameInIrp OPTIONAL
,
1710 OUT PBOOLEAN LastFrameInIrp OPTIONAL
)
1722 KsStreamPointerScheduleTimeout(
1723 IN PKSSTREAM_POINTER StreamPointer
,
1724 IN PFNKSSTREAMPOINTER Callback
,
1725 IN ULONGLONG Interval
)
1727 LARGE_INTEGER DueTime
;
1728 PKSISTREAM_POINTER Pointer
;
1730 /* get stream pointer */
1731 Pointer
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1733 /* setup timer callback */
1734 Pointer
->Callback
= Callback
;
1736 /* setup expiration */
1737 DueTime
.QuadPart
= (LONGLONG
)Interval
;
1739 /* setup the timer */
1740 KeSetTimer(&Pointer
->Timer
, DueTime
, &Pointer
->TimerDpc
);
1750 KsStreamPointerCancelTimeout(
1751 IN PKSSTREAM_POINTER StreamPointer
)
1753 PKSISTREAM_POINTER Pointer
;
1755 /* get stream pointer */
1756 Pointer
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1758 KeCancelTimer(&Pointer
->Timer
);
1768 KsPinGetFirstCloneStreamPointer(
1773 DPRINT("KsPinGetFirstCloneStreamPointer %p\n", Pin
);
1775 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1777 if (!This
->ClonedStreamPointer
)
1780 /* return first cloned stream pointer */
1781 return &This
->ClonedStreamPointer
->StreamPointer
;
1790 KsStreamPointerGetNextClone(
1791 IN PKSSTREAM_POINTER StreamPointer
)
1793 PKSISTREAM_POINTER Pointer
;
1795 DPRINT("KsStreamPointerGetNextClone\n");
1797 /* get stream pointer */
1798 Pointer
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1800 /* is there a another cloned stream pointer */
1804 /* return next stream pointer */
1805 return &Pointer
->Next
->StreamPointer
;
1810 IKsPin_PinCentricWorker(
1814 IKsPinImpl
* This
= (IKsPinImpl
*)Parameter
;
1816 DPRINT("IKsPin_PinCentricWorker\n");
1820 ASSERT(This
->Pin
.Descriptor
);
1821 ASSERT(This
->Pin
.Descriptor
->Dispatch
);
1822 ASSERT(This
->Pin
.Descriptor
->Dispatch
->Process
);
1823 ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL
);
1824 ASSERT(!(This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_DISPATCH_LEVEL_PROCESSING
));
1825 ASSERT(!(This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_GENERATE_MAPPINGS
));
1829 DPRINT("IKsPin_PinCentricWorker calling Pin Process Routine\n");
1831 Status
= This
->Pin
.Descriptor
->Dispatch
->Process(&This
->Pin
);
1832 DPRINT("IKsPin_PinCentricWorker Status %lx, Offset %lu Length %lu\n", Status
,
1833 This
->LeadingEdgeStreamPointer
.Offset
,
1834 This
->LeadingEdgeStreamPointer
.Length
);
1837 }while(This
->IrpCount
);
1843 IKsPin_DispatchKsStream(
1844 PDEVICE_OBJECT DeviceObject
,
1848 PKSPROCESSPIN_INDEXENTRY ProcessPinIndex
;
1849 PKSSTREAM_HEADER Header
;
1852 PIO_STACK_LOCATION IoStack
;
1853 NTSTATUS Status
= STATUS_SUCCESS
;
1855 DPRINT("IKsPin_DispatchKsStream\n");
1857 /* FIXME handle reset states */
1858 ASSERT(This
->Pin
.ResetState
== KSRESET_END
);
1860 /* get current stack location */
1861 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1863 /* probe stream pointer */
1864 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_WRITE_STREAM
)
1865 Status
= KsProbeStreamIrp(Irp
, KSSTREAM_WRITE
| KSPROBE_ALLOCATEMDL
| KSPROBE_PROBEANDLOCK
| KSPROBE_SYSTEMADDRESS
, This
->Pin
.StreamHeaderSize
);
1867 Status
= KsProbeStreamIrp(Irp
, KSSTREAM_READ
| KSPROBE_ALLOCATEMDL
| KSPROBE_PROBEANDLOCK
| KSPROBE_SYSTEMADDRESS
, This
->Pin
.StreamHeaderSize
);
1869 if (!NT_SUCCESS(Status
))
1871 DPRINT1("KsProbeStreamIrp failed with %x\n", Status
);
1873 Irp
->IoStatus
.Status
= Status
;
1874 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1878 if (Irp
->RequestorMode
== UserMode
)
1879 Header
= (PKSSTREAM_HEADER
)Irp
->AssociatedIrp
.SystemBuffer
;
1881 Header
= (PKSSTREAM_HEADER
)Irp
->UserBuffer
;
1885 DPRINT("NoHeader Canceling Irp %p\n", Irp
);
1886 Irp
->IoStatus
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
1887 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1891 /* calculate num headers */
1892 NumHeaders
= IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
/ Header
->Size
;
1894 /* assume headers of same length */
1895 ASSERT(IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
% Header
->Size
== 0);
1897 /* FIXME support multiple stream headers */
1898 ASSERT(NumHeaders
== 1);
1900 if (Irp
->RequestorMode
== UserMode
)
1902 /* prepare header */
1903 ASSERT(Irp
->MdlAddress
);
1904 Header
->Data
= MmGetSystemAddressForMdlSafe(Irp
->MdlAddress
, NormalPagePriority
);
1908 DPRINT("NoHeader->Data Canceling Irp %p\n", Irp
);
1909 Irp
->IoStatus
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
1910 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1918 if (This
->Pin
.Descriptor
->Dispatch
->Process
)
1920 /* it is a pin centric avstream */
1922 /* mark irp as pending */
1923 IoMarkIrpPending(Irp
);
1925 /* add irp to cancelable queue */
1926 KsAddIrpToCancelableQueue(&This
->IrpList
, &This
->IrpListLock
, Irp
, KsListEntryTail
, NULL
/* FIXME */);
1929 ASSERT(!(This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_DISPATCH_LEVEL_PROCESSING
));
1930 ASSERT(This
->PinWorker
);
1932 InterlockedIncrement(&This
->IrpCount
);
1934 DPRINT("IKsPin_DispatchKsStream IrpCount %lu\n", This
->IrpCount
);
1936 /* start the processing loop */
1937 KsIncrementCountedWorker(This
->PinWorker
);
1939 Status
= STATUS_PENDING
;
1943 /* filter-centric avstream */
1944 ASSERT(This
->Filter
);
1946 ProcessPinIndex
= This
->Filter
->lpVtbl
->GetProcessDispatch(This
->Filter
);
1947 Filter
= This
->Filter
->lpVtbl
->GetStruct(This
->Filter
);
1949 ASSERT(ProcessPinIndex
);
1951 ASSERT(Filter
->Descriptor
);
1952 ASSERT(Filter
->Descriptor
->Dispatch
);
1954 if (!Filter
->Descriptor
->Dispatch
->Process
)
1956 /* invalid device request */
1957 DPRINT("Filter Centric Processing No Process Routine\n");
1958 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1959 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1960 return STATUS_UNSUCCESSFUL
;
1963 /* mark irp as pending */
1964 IoMarkIrpPending(Irp
);
1966 /* add irp to cancelable queue */
1967 KsAddIrpToCancelableQueue(&This
->IrpList
, &This
->IrpListLock
, Irp
, KsListEntryTail
, NULL
/* FIXME */);
1969 Status
= Filter
->Descriptor
->Dispatch
->Process(Filter
, ProcessPinIndex
);
1971 DPRINT("IKsPin_DispatchKsStream FilterCentric: Status %lx \n", Status
);
1980 IKsPin_DispatchDeviceIoControl(
1981 IN PDEVICE_OBJECT DeviceObject
,
1984 PIO_STACK_LOCATION IoStack
;
1985 PKSIOBJECT_HEADER ObjectHeader
;
1988 UNICODE_STRING GuidString
;
1989 PKSPROPERTY Property
;
1992 /* get current irp stack */
1993 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1996 ASSERT(IoStack
->FileObject
);
1997 ASSERT(IoStack
->FileObject
->FsContext2
);
1999 /* get the object header */
2000 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
2002 /* locate ks pin implemention from KSPIN offset */
2003 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
2005 /* current irp stack */
2006 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2008 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_READ_STREAM
||
2009 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_WRITE_STREAM
)
2011 /* handle ks stream packets */
2012 return IKsPin_DispatchKsStream(DeviceObject
, Irp
, This
);
2015 /* get property from input buffer */
2016 Property
= (PKSPROPERTY
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
2019 ASSERT(IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
>= sizeof(KSIDENTIFIER
));
2020 ASSERT(This
->Pin
.Descriptor
->AutomationTable
);
2022 RtlStringFromGUID(&Property
->Set
, &GuidString
);
2023 DPRINT("IKsPin_DispatchDeviceIoControl property Set |%S| Id %u Flags %x\n", GuidString
.Buffer
, Property
->Id
, Property
->Flags
);
2024 RtlFreeUnicodeString(&GuidString
);
2027 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_METHOD
)
2029 const KSMETHOD_SET
*MethodSet
= NULL
;
2030 ULONG MethodItemSize
= 0;
2032 /* check if the driver supports method sets */
2033 if (This
->Pin
.Descriptor
->AutomationTable
->MethodSetsCount
)
2035 SetCount
= This
->Pin
.Descriptor
->AutomationTable
->MethodSetsCount
;
2036 MethodSet
= This
->Pin
.Descriptor
->AutomationTable
->MethodSets
;
2037 MethodItemSize
= This
->Pin
.Descriptor
->AutomationTable
->MethodItemSize
;
2040 /* call method set handler */
2041 Status
= KspMethodHandlerWithAllocator(Irp
, SetCount
, MethodSet
, NULL
, MethodItemSize
);
2043 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_PROPERTY
)
2045 const KSPROPERTY_SET
*PropertySet
= NULL
;
2046 ULONG PropertyItemSize
= 0;
2048 /* check if the driver supports method sets */
2049 if (This
->Pin
.Descriptor
->AutomationTable
->PropertySetsCount
)
2051 SetCount
= This
->Pin
.Descriptor
->AutomationTable
->PropertySetsCount
;
2052 PropertySet
= This
->Pin
.Descriptor
->AutomationTable
->PropertySets
;
2053 PropertyItemSize
= This
->Pin
.Descriptor
->AutomationTable
->PropertyItemSize
;
2056 /* needed for our property handlers */
2057 KSPROPERTY_ITEM_IRP_STORAGE(Irp
) = (KSPROPERTY_ITEM
*)This
;
2059 /* call property handler */
2060 Status
= KspPropertyHandler(Irp
, SetCount
, PropertySet
, NULL
, PropertyItemSize
);
2065 ASSERT(IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_ENABLE_EVENT
||
2066 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_DISABLE_EVENT
);
2068 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_ENABLE_EVENT
)
2070 /* call enable event handlers */
2071 Status
= KspEnableEvent(Irp
,
2072 This
->Pin
.Descriptor
->AutomationTable
->EventSetsCount
,
2073 (PKSEVENT_SET
)This
->Pin
.Descriptor
->AutomationTable
->EventSets
,
2074 &This
->BasicHeader
.EventList
,
2076 (PVOID
)&This
->BasicHeader
.EventListLock
,
2078 This
->Pin
.Descriptor
->AutomationTable
->EventItemSize
);
2082 /* disable event handler */
2083 Status
= KsDisableEvent(Irp
, &This
->BasicHeader
.EventList
, KSEVENTS_SPINLOCK
, &This
->BasicHeader
.EventListLock
);
2087 RtlStringFromGUID(&Property
->Set
, &GuidString
);
2088 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
);
2089 RtlFreeUnicodeString(&GuidString
);
2091 if (Status
!= STATUS_PENDING
)
2093 Irp
->IoStatus
.Status
= Status
;
2094 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2104 IN PDEVICE_OBJECT DeviceObject
,
2107 PIO_STACK_LOCATION IoStack
;
2108 PKSIOBJECT_HEADER ObjectHeader
;
2110 NTSTATUS Status
= STATUS_SUCCESS
;
2112 /* get current irp stack */
2113 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2116 ASSERT(IoStack
->FileObject
);
2117 ASSERT(IoStack
->FileObject
->FsContext2
);
2119 /* get the object header */
2120 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
2122 /* locate ks pin implemention fro KSPIN offset */
2123 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
2125 if (This
->Pin
.Descriptor
->Dispatch
->Close
)
2127 /* call pin close routine */
2128 Status
= This
->Pin
.Descriptor
->Dispatch
->Close(&This
->Pin
, Irp
);
2130 if (!NT_SUCCESS(Status
))
2133 Irp
->IoStatus
.Status
= Status
;
2134 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2138 /* remove pin from filter pin list and decrement reference count */
2139 IKsFilter_RemovePin(This
->Filter
->lpVtbl
->GetStruct(This
->Filter
), &This
->Pin
);
2141 if (Status
!= STATUS_PENDING
)
2143 Irp
->IoStatus
.Status
= Status
;
2144 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2154 IKsPin_DispatchCreateAllocator(
2155 IN PDEVICE_OBJECT DeviceObject
,
2160 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
2161 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2162 return STATUS_NOT_IMPLEMENTED
;
2167 IKsPin_DispatchCreateClock(
2168 IN PDEVICE_OBJECT DeviceObject
,
2172 NTSTATUS Status
= STATUS_SUCCESS
;
2174 KSRESOLUTION Resolution
;
2175 PKSRESOLUTION pResolution
= NULL
;
2176 PKSOBJECT_CREATE_ITEM CreateItem
;
2178 DPRINT("IKsPin_DispatchCreateClock\n");
2180 /* get the create item */
2181 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
2186 /* get the pin object */
2187 Pin
= (PKSPIN
)CreateItem
->Context
;
2192 /* locate ks pin implemention fro KSPIN offset */
2193 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
2196 ASSERT(This
->BasicHeader
.Type
== KsObjectTypePin
);
2197 ASSERT(This
->BasicHeader
.ControlMutex
);
2199 /* acquire control mutex */
2200 KsAcquireControl(Pin
);
2202 if ((This
->Pin
.Descriptor
->PinDescriptor
.Communication
!= KSPIN_COMMUNICATION_NONE
&&
2203 This
->Pin
.Descriptor
->Dispatch
) ||
2204 (This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_IMPLEMENT_CLOCK
))
2206 if (!This
->DefaultClock
)
2208 if (This
->Pin
.Descriptor
->Dispatch
&& This
->Pin
.Descriptor
->Dispatch
->Clock
)
2210 if (This
->Pin
.Descriptor
->Dispatch
->Clock
->Resolution
)
2212 This
->Pin
.Descriptor
->Dispatch
->Clock
->Resolution(&This
->Pin
, &Resolution
);
2213 pResolution
= &Resolution
;
2216 Status
= KsAllocateDefaultClockEx(&This
->DefaultClock
,
2218 (PFNKSSETTIMER
)This
->Pin
.Descriptor
->Dispatch
->Clock
->SetTimer
,
2219 (PFNKSCANCELTIMER
)This
->Pin
.Descriptor
->Dispatch
->Clock
->CancelTimer
,
2220 (PFNKSCORRELATEDTIME
)This
->Pin
.Descriptor
->Dispatch
->Clock
->CorrelatedTime
,
2226 Status
= KsAllocateDefaultClockEx(&This
->DefaultClock
, (PVOID
)&This
->Pin
, NULL
, NULL
, NULL
, NULL
, 0);
2230 if (NT_SUCCESS(Status
))
2232 Status
= KsCreateDefaultClock(Irp
, This
->DefaultClock
);
2236 DPRINT("IKsPin_DispatchCreateClock %lx\n", Status
);
2238 /* release control mutex */
2239 KsReleaseControl(Pin
);
2242 Irp
->IoStatus
.Status
= Status
;
2243 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2249 IKsPin_DispatchCreateNode(
2250 IN PDEVICE_OBJECT DeviceObject
,
2255 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
2256 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2257 return STATUS_NOT_IMPLEMENTED
;
2260 static KSDISPATCH_TABLE PinDispatchTable
=
2262 IKsPin_DispatchDeviceIoControl
,
2263 KsDispatchInvalidDeviceRequest
,
2264 KsDispatchInvalidDeviceRequest
,
2265 KsDispatchInvalidDeviceRequest
,
2267 KsDispatchQuerySecurity
,
2268 KsDispatchSetSecurity
,
2269 KsDispatchFastIoDeviceControlFailure
,
2270 KsDispatchFastReadFailure
,
2271 KsDispatchFastReadFailure
2276 IN PDEVICE_OBJECT DeviceObject
,
2278 IN PKSDEVICE KsDevice
,
2279 IN IKsFilterFactory
* FilterFactory
,
2280 IN IKsFilter
* Filter
,
2281 IN PKSPIN_CONNECT Connect
,
2282 IN KSPIN_DESCRIPTOR_EX
* Descriptor
)
2285 PIO_STACK_LOCATION IoStack
;
2287 PDEVICE_EXTENSION DeviceExtension
;
2288 PKSOBJECT_CREATE_ITEM CreateItem
;
2290 PKSDATAFORMAT DataFormat
;
2291 PKSBASIC_HEADER BasicHeader
;
2293 ULONG FrameSize
= 0;
2294 ULONG NumFrames
= 0;
2295 KSAUTOMATION_TABLE AutomationTable
;
2298 ASSERT(Descriptor
->Dispatch
);
2300 DPRINT("KspCreatePin PinId %lu Flags %x\n", Connect
->PinId
, Descriptor
->Flags
);
2302 //Output Pin: KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY
2303 //Input Pin: KSPIN_FLAG_FIXED_FORMAT|KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT|KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING
2305 DPRINT("KspCreatePin Dataflow %lu\n", Descriptor
->PinDescriptor
.DataFlow
);
2306 DPRINT("KspCreatePin Communication %lu\n", Descriptor
->PinDescriptor
.Communication
);
2307 if (Descriptor
->AllocatorFraming
)
2309 DPRINT("KspCreatePin CountItems %lu\n", Descriptor
->AllocatorFraming
->CountItems
);
2310 DPRINT("KspCreatePin PinFlags %lx\n", Descriptor
->AllocatorFraming
->PinFlags
);
2311 DPRINT("KspCreatePin OutputCompression RatioNumerator %lu RatioDenominator %lu RatioConstantMargin %lu\n", Descriptor
->AllocatorFraming
->OutputCompression
.RatioNumerator
,
2312 Descriptor
->AllocatorFraming
->OutputCompression
.RatioDenominator
, Descriptor
->AllocatorFraming
->OutputCompression
.RatioConstantMargin
);
2313 DPRINT("KspCreatePin PinWeight %lx\n", Descriptor
->AllocatorFraming
->PinWeight
);
2315 for(Index
= 0; Index
< Descriptor
->AllocatorFraming
->CountItems
; Index
++)
2317 DPRINT("KspCreatePin Index %lu MemoryFlags %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].MemoryFlags
);
2318 DPRINT("KspCreatePin Index %lu BusFlags %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].BusFlags
);
2319 DPRINT("KspCreatePin Index %lu Flags %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].Flags
);
2320 DPRINT("KspCreatePin Index %lu Frames %lu\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].Frames
);
2321 DPRINT("KspCreatePin Index %lu FileAlignment %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].FileAlignment
);
2322 DPRINT("KspCreatePin Index %lu MemoryTypeWeight %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].MemoryTypeWeight
);
2323 DPRINT("KspCreatePin Index %lu PhysicalRange MinFrameSize %lu MaxFrameSize %lu Stepping %lu\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].PhysicalRange
.MinFrameSize
,
2324 Descriptor
->AllocatorFraming
->FramingItem
[Index
].PhysicalRange
.MaxFrameSize
,
2325 Descriptor
->AllocatorFraming
->FramingItem
[Index
].PhysicalRange
.Stepping
);
2327 DPRINT("KspCreatePin Index %lu FramingRange MinFrameSize %lu MaxFrameSize %lu Stepping %lu InPlaceWeight %lu NotInPlaceWeight %lu\n",
2329 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.Range
.MinFrameSize
,
2330 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.Range
.MaxFrameSize
,
2331 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.Range
.Stepping
,
2332 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.InPlaceWeight
,
2333 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.NotInPlaceWeight
);
2335 FrameSize
= Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.Range
.MaxFrameSize
;
2336 NumFrames
= Descriptor
->AllocatorFraming
->FramingItem
[Index
].Frames
;
2340 for (Index
= 0; Index
< Descriptor
->PinDescriptor
.DataRangesCount
; Index
++)
2342 UNICODE_STRING GuidString
;
2343 /* convert the guid to string */
2344 RtlStringFromGUID(&Descriptor
->PinDescriptor
.DataRanges
[Index
]->MajorFormat
, &GuidString
);
2345 DPRINT("Index %lu MajorFormat %S\n", Index
, GuidString
.Buffer
);
2346 RtlStringFromGUID(&Descriptor
->PinDescriptor
.DataRanges
[Index
]->SubFormat
, &GuidString
);
2347 DPRINT("Index %lu SubFormat %S\n", Index
, GuidString
.Buffer
);
2348 RtlStringFromGUID(&Descriptor
->PinDescriptor
.DataRanges
[Index
]->Specifier
, &GuidString
);
2349 DPRINT("Index %lu Specifier %S\n", Index
, GuidString
.Buffer
);
2350 RtlStringFromGUID(&Descriptor
->PinDescriptor
.DataRanges
[Index
]->Specifier
, &GuidString
);
2351 DPRINT("Index %lu FormatSize %lu Flags %lu SampleSize %lu Reserved %lu KSDATAFORMAT %lu\n", Index
,
2352 Descriptor
->PinDescriptor
.DataRanges
[Index
]->FormatSize
, Descriptor
->PinDescriptor
.DataRanges
[Index
]->Flags
, Descriptor
->PinDescriptor
.DataRanges
[Index
]->SampleSize
, Descriptor
->PinDescriptor
.DataRanges
[Index
]->Reserved
, sizeof(KSDATAFORMAT
));
2354 if (IsEqualGUIDAligned(&Descriptor
->PinDescriptor
.DataRanges
[Index
]->SubFormat
, &KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT
))
2356 PKS_DATARANGE_BDA_TRANSPORT Transport
= (PKS_DATARANGE_BDA_TRANSPORT
)&Descriptor
->PinDescriptor
.DataRanges
[Index
];
2357 DPRINT("KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT AvgTimePerFrame %I64u ulcbPhyiscalFrame %lu ulcbPhyiscalFrameAlignment %lu ulcbPhyiscalPacket %lu\n", Transport
->BdaTransportInfo
.AvgTimePerFrame
, Transport
->BdaTransportInfo
.ulcbPhyiscalFrame
,
2358 Transport
->BdaTransportInfo
.ulcbPhyiscalFrameAlignment
, Transport
->BdaTransportInfo
.ulcbPhyiscalPacket
);
2363 /* default to 50 * 188 (MPEG2 TS packet size) */
2372 /* get current irp stack */
2373 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2375 /* get device extension */
2376 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
2378 /* get ks device interface */
2379 Device
= (IKsDevice
*)&DeviceExtension
->DeviceHeader
->BasicHeader
.OuterUnknown
;
2381 /* first allocate pin ctx */
2382 This
= AllocateItem(NonPagedPool
, sizeof(IKsPinImpl
));
2385 /* not enough memory */
2386 return STATUS_INSUFFICIENT_RESOURCES
;
2389 /* allocate create item */
2390 CreateItem
= AllocateItem(NonPagedPool
, sizeof(KSOBJECT_CREATE_ITEM
) * 3);
2393 /* not enough memory */
2395 DPRINT("KspCreatePin OutOfMemory\n");
2396 return STATUS_INSUFFICIENT_RESOURCES
;
2399 /* initialize basic header */
2400 This
->BasicHeader
.KsDevice
= KsDevice
;
2401 This
->BasicHeader
.Type
= KsObjectTypePin
;
2402 This
->BasicHeader
.Parent
.KsFilter
= Filter
->lpVtbl
->GetStruct(Filter
);
2403 This
->BasicHeader
.OuterUnknown
= (PUNKNOWN
)&vt_IKsPin
;
2404 InitializeListHead(&This
->BasicHeader
.EventList
);
2405 KeInitializeSpinLock(&This
->BasicHeader
.EventListLock
);
2407 ASSERT(This
->BasicHeader
.Parent
.KsFilter
);
2409 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)This
->BasicHeader
.Parent
.KsFilter
- sizeof(KSBASIC_HEADER
));
2411 This
->BasicHeader
.ControlMutex
= BasicHeader
->ControlMutex
;
2412 ASSERT(This
->BasicHeader
.ControlMutex
);
2414 InitializeListHead(&This
->BasicHeader
.EventList
);
2415 KeInitializeSpinLock(&This
->BasicHeader
.EventListLock
);
2417 /* initialize pin */
2418 This
->FrameSize
= FrameSize
;
2419 This
->NumFrames
= NumFrames
;
2420 This
->lpVtblReferenceClock
= &vt_ReferenceClock
;
2422 This
->FileObject
= IoStack
->FileObject
;
2423 This
->Filter
= Filter
;
2424 KeInitializeMutex(&This
->ProcessingMutex
, 0);
2425 InitializeListHead(&This
->IrpList
);
2426 KeInitializeSpinLock(&This
->IrpListLock
);
2428 /* allocate object bag */
2429 This
->Pin
.Bag
= AllocateItem(NonPagedPool
, sizeof(KSIOBJECT_BAG
));
2432 /* not enough memory */
2434 FreeItem(CreateItem
);
2435 return STATUS_INSUFFICIENT_RESOURCES
;
2438 /* initialize object bag */
2439 Device
->lpVtbl
->InitializeObjectBag(Device
, This
->Pin
.Bag
, NULL
);
2441 /* allocate pin descriptor */
2442 This
->Pin
.Descriptor
= AllocateItem(NonPagedPool
, sizeof(KSPIN_DESCRIPTOR_EX
));
2443 if (!This
->Pin
.Descriptor
)
2445 /* not enough memory */
2446 KsFreeObjectBag(This
->Pin
.Bag
);
2448 FreeItem(CreateItem
);
2449 return STATUS_INSUFFICIENT_RESOURCES
;
2452 /* copy pin descriptor */
2453 RtlMoveMemory((PVOID
)This
->Pin
.Descriptor
, Descriptor
, sizeof(KSPIN_DESCRIPTOR_EX
));
2455 /* initialize automation table */
2456 RtlZeroMemory(&AutomationTable
, sizeof(KSAUTOMATION_TABLE
));
2458 AutomationTable
.PropertyItemSize
= sizeof(KSPROPERTY_ITEM
);
2459 AutomationTable
.PropertySets
= PinPropertySet
;
2460 AutomationTable
.PropertySetsCount
= sizeof(PinPropertySet
) / sizeof(KSPROPERTY_SET
);
2462 /* merge in pin property sets */
2463 Status
= KsMergeAutomationTables((PKSAUTOMATION_TABLE
*)&This
->Pin
.Descriptor
->AutomationTable
, (PKSAUTOMATION_TABLE
)Descriptor
->AutomationTable
, &AutomationTable
, This
->Pin
.Bag
);
2465 if (!NT_SUCCESS(Status
))
2467 /* not enough memory */
2468 KsFreeObjectBag(This
->Pin
.Bag
);
2470 FreeItem(CreateItem
);
2475 DataFormat
= (PKSDATAFORMAT
)(Connect
+ 1);
2477 /* initialize pin descriptor */
2478 This
->Pin
.Context
= NULL
;
2479 This
->Pin
.Id
= Connect
->PinId
;
2480 This
->Pin
.Communication
= Descriptor
->PinDescriptor
.Communication
;
2481 This
->Pin
.ConnectionIsExternal
= FALSE
; //FIXME
2482 RtlMoveMemory(&This
->Pin
.ConnectionInterface
, &Connect
->Interface
, sizeof(KSPIN_INTERFACE
));
2483 RtlMoveMemory(&This
->Pin
.ConnectionMedium
, &Connect
->Medium
, sizeof(KSPIN_MEDIUM
));
2484 RtlMoveMemory(&This
->Pin
.ConnectionPriority
, &Connect
->Priority
, sizeof(KSPRIORITY
));
2486 /* allocate format */
2487 Status
= _KsEdit(This
->Pin
.Bag
, (PVOID
*)&This
->Pin
.ConnectionFormat
, DataFormat
->FormatSize
, DataFormat
->FormatSize
, 0);
2488 if (!NT_SUCCESS(Status
))
2490 /* failed to allocate format */
2491 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2493 FreeItem(CreateItem
);
2494 return STATUS_INSUFFICIENT_RESOURCES
;
2498 RtlMoveMemory((PVOID
)This
->Pin
.ConnectionFormat
, DataFormat
, DataFormat
->FormatSize
);
2500 This
->Pin
.AttributeList
= NULL
; //FIXME
2501 This
->Pin
.StreamHeaderSize
= sizeof(KSSTREAM_HEADER
);
2502 This
->Pin
.DataFlow
= Descriptor
->PinDescriptor
.DataFlow
;
2503 This
->Pin
.DeviceState
= KSSTATE_STOP
;
2504 This
->Pin
.ResetState
= KSRESET_END
;
2505 This
->Pin
.ClientState
= KSSTATE_STOP
;
2507 /* intialize allocator create item */
2508 CreateItem
[0].Context
= (PVOID
)&This
->Pin
;
2509 CreateItem
[0].Create
= IKsPin_DispatchCreateAllocator
;
2510 CreateItem
[0].Flags
= KSCREATE_ITEM_FREEONSTOP
;
2511 RtlInitUnicodeString(&CreateItem
[0].ObjectClass
, KSSTRING_Allocator
);
2513 /* intialize clock create item */
2514 CreateItem
[1].Context
= (PVOID
)&This
->Pin
;
2515 CreateItem
[1].Create
= IKsPin_DispatchCreateClock
;
2516 CreateItem
[1].Flags
= KSCREATE_ITEM_FREEONSTOP
;
2517 RtlInitUnicodeString(&CreateItem
[1].ObjectClass
, KSSTRING_Clock
);
2519 /* intialize topology node create item */
2520 CreateItem
[2].Context
= (PVOID
)&This
->Pin
;
2521 CreateItem
[2].Create
= IKsPin_DispatchCreateNode
;
2522 CreateItem
[2].Flags
= KSCREATE_ITEM_FREEONSTOP
;
2523 RtlInitUnicodeString(&CreateItem
[2].ObjectClass
, KSSTRING_TopologyNode
);
2525 /* now allocate object header */
2526 Status
= KsAllocateObjectHeader((KSOBJECT_HEADER
*)&This
->ObjectHeader
, 3, CreateItem
, Irp
, &PinDispatchTable
);
2527 if (!NT_SUCCESS(Status
))
2529 /* failed to create object header */
2530 DPRINT("KspCreatePin KsAllocateObjectHeader failed %lx\n", Status
);
2531 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2533 FreeItem(CreateItem
);
2535 /* return failure code */
2539 /* add extra info to object header */
2540 This
->ObjectHeader
->Type
= KsObjectTypePin
;
2541 This
->ObjectHeader
->Unknown
= (PUNKNOWN
)&This
->BasicHeader
.OuterUnknown
;
2542 This
->ObjectHeader
->ObjectType
= (PVOID
)&This
->Pin
;
2544 if (!Descriptor
->Dispatch
|| !Descriptor
->Dispatch
->Process
)
2546 /* the pin is part of filter-centric processing filter
2547 * add process pin to filter
2549 This
->ProcessPin
.BytesAvailable
= 0;
2550 This
->ProcessPin
.BytesUsed
= 0;
2551 This
->ProcessPin
.CopySource
= NULL
;
2552 This
->ProcessPin
.Data
= NULL
;
2553 This
->ProcessPin
.DelegateBranch
= NULL
;
2554 This
->ProcessPin
.Flags
= 0;
2555 This
->ProcessPin
.InPlaceCounterpart
= NULL
;
2556 This
->ProcessPin
.Pin
= &This
->Pin
;
2557 This
->ProcessPin
.StreamPointer
= (PKSSTREAM_POINTER
)&This
->LeadingEdgeStreamPointer
.StreamPointer
;
2558 This
->ProcessPin
.Terminate
= FALSE
;
2560 Status
= Filter
->lpVtbl
->AddProcessPin(Filter
, &This
->ProcessPin
);
2561 DPRINT("KspCreatePin AddProcessPin %lx\n", Status
);
2563 if (!NT_SUCCESS(Status
))
2565 /* failed to add process pin */
2566 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2567 KsFreeObjectHeader(&This
->ObjectHeader
);
2569 FreeItem(CreateItem
);
2570 /* return failure code */
2574 else if (Descriptor
->Dispatch
&& Descriptor
->Dispatch
->Process
)
2576 /* pin centric processing filter */
2578 /* initialize work item */
2579 ExInitializeWorkItem(&This
->PinWorkQueueItem
, IKsPin_PinCentricWorker
, (PVOID
)This
);
2581 /* allocate counted work item */
2582 Status
= KsRegisterCountedWorker(HyperCriticalWorkQueue
, &This
->PinWorkQueueItem
, &This
->PinWorker
);
2584 if (!NT_SUCCESS(Status
))
2586 DPRINT("Failed to register Worker %lx\n", Status
);
2587 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2588 KsFreeObjectHeader(&This
->ObjectHeader
);
2590 FreeItem(CreateItem
);
2594 if (This
->Pin
.Descriptor
->PinDescriptor
.DataFlow
== KSPIN_DATAFLOW_IN
)
2595 This
->LeadingEdgeStreamPointer
.StreamPointer
.Offset
= &This
->LeadingEdgeStreamPointer
.StreamPointer
.OffsetIn
;
2597 This
->LeadingEdgeStreamPointer
.StreamPointer
.Offset
= &This
->LeadingEdgeStreamPointer
.StreamPointer
.OffsetOut
;
2600 KeInitializeEvent(&This
->FrameComplete
, NotificationEvent
, FALSE
);
2604 /* FIXME add pin instance to filter instance */
2605 IKsFilter_AddPin(Filter
->lpVtbl
->GetStruct(Filter
), &This
->Pin
);
2607 if (Descriptor
->Dispatch
&& Descriptor
->Dispatch
->SetDataFormat
)
2609 Status
= Descriptor
->Dispatch
->SetDataFormat(&This
->Pin
, NULL
, NULL
, This
->Pin
.ConnectionFormat
, NULL
);
2610 DPRINT("KspCreatePin SetDataFormat %lx\n", Status
);
2614 /* does the driver have a pin dispatch */
2615 if (Descriptor
->Dispatch
&& Descriptor
->Dispatch
->Create
)
2617 /* now inform the driver to create a new pin */
2618 Status
= Descriptor
->Dispatch
->Create(&This
->Pin
, Irp
);
2619 DPRINT("KspCreatePin DispatchCreate %lx\n", Status
);
2623 DPRINT("KspCreatePin Status %lx KsDevice %p\n", Status
, KsDevice
);
2625 if (!NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
)
2627 /* failed to create pin, release resources */
2628 IKsFilter_RemovePin(Filter
->lpVtbl
->GetStruct(Filter
), &This
->Pin
);
2629 KsFreeObjectHeader((KSOBJECT_HEADER
)This
->ObjectHeader
);
2630 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2633 /* return failure code */