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
;
1336 StreamPointer
->StreamPointer
.Offset
->Alignment
= 0;
1338 StreamPointer
->StreamPointer
.Offset
->Count
= 0;
1339 StreamPointer
->StreamPointer
.Offset
->Data
= NULL
;
1340 StreamPointer
->StreamPointer
.Offset
->Remaining
= 0;
1342 ASSERT(StreamPointer
->StreamPointer
.Offset
->Remaining
== 0);
1344 //StreamPointer->Offset += StreamPointer->StreamPointer.Offset->Count;
1346 ASSERT(StreamPointer
->Length
> StreamPointer
->Offset
);
1347 ASSERT(StreamPointer
->StreamPointer
.StreamHeader
);
1348 ASSERT(This
->FrameSize
);
1350 /* calculate length */
1351 /* TODO split into frames */
1352 Length
= StreamPointer
->Length
;
1358 StreamPointer
->StreamPointer
.Offset
->Alignment
= 0;
1360 StreamPointer
->StreamPointer
.Context
= NULL
;
1361 StreamPointer
->StreamPointer
.Pin
= &This
->Pin
;
1362 StreamPointer
->StreamPointer
.Offset
->Count
= Length
;
1363 StreamPointer
->StreamPointer
.Offset
->Remaining
= Length
;
1364 StreamPointer
->StreamPointer
.Offset
->Data
= (PVOID
)((ULONG_PTR
)StreamPointer
->Data
+ StreamPointer
->Offset
);
1365 StreamPointer
->StreamPointer
.StreamHeader
->FrameExtent
= Length
;
1366 if (StreamPointer
->StreamPointer
.StreamHeader
->DataUsed
)
1367 StreamPointer
->StreamPointer
.StreamHeader
->DataUsed
= Length
;
1369 StreamPointer
->StreamPointer
.StreamHeader
->Data
= StreamPointer
->StreamPointer
.Offset
->Data
;
1371 return STATUS_SUCCESS
;
1381 KsPinGetLeadingEdgeStreamPointer(
1383 IN KSSTREAM_POINTER_STATE State
)
1388 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1390 DPRINT("KsPinGetLeadingEdgeStreamPointer Pin %p State %x Count %lu Remaining %lu\n", Pin
, State
,
1391 This
->LeadingEdgeStreamPointer
.Length
,
1392 This
->LeadingEdgeStreamPointer
.Offset
);
1395 ASSERT(State
== KSSTREAM_POINTER_STATE_LOCKED
);
1397 if (State
== KSSTREAM_POINTER_STATE_LOCKED
)
1399 if (!This
->LeadingEdgeStreamPointer
.Irp
|| This
->LeadingEdgeStreamPointer
.StreamPointer
.Offset
->Remaining
== 0)
1401 Status
= IKsPin_PrepareStreamHeader(This
, &This
->LeadingEdgeStreamPointer
);
1402 if (!NT_SUCCESS(Status
))
1406 DPRINT("KsPinGetLeadingEdgeStreamPointer NewOffset %lu TotalLength %lu\n", This
->LeadingEdgeStreamPointer
.Offset
, This
->LeadingEdgeStreamPointer
.Length
);
1409 return &This
->LeadingEdgeStreamPointer
.StreamPointer
;
1418 KsPinGetTrailingEdgeStreamPointer(
1420 IN KSSTREAM_POINTER_STATE State
)
1432 KsStreamPointerSetStatusCode(
1433 IN PKSSTREAM_POINTER StreamPointer
,
1437 return STATUS_UNSUCCESSFUL
;
1446 KsStreamPointerLock(
1447 IN PKSSTREAM_POINTER StreamPointer
)
1450 return STATUS_UNSUCCESSFUL
;
1459 KsStreamPointerUnlock(
1460 IN PKSSTREAM_POINTER StreamPointer
,
1463 PKSISTREAM_POINTER Pointer
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1465 DPRINT("KsStreamPointerUnlock StreamPointer %pEject %lu\n", StreamPointer
, Eject
);
1467 Pointer
->Irp
= NULL
;
1476 KsStreamPointerAdvanceOffsetsAndUnlock(
1477 IN PKSSTREAM_POINTER StreamPointer
,
1482 DPRINT("KsStreamPointerAdvanceOffsets InUsed %lu OutUsed %lu Eject %lu\n", InUsed
, OutUsed
, Eject
);
1493 KsStreamPointerDelete(
1494 IN PKSSTREAM_POINTER StreamPointer
)
1497 PKSISTREAM_POINTER Cur
, Last
;
1498 PKSISTREAM_POINTER Pointer
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1500 DPRINT("KsStreamPointerDelete %p\n", Pointer
);
1502 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pointer
->StreamPointer
.Pin
, IKsPinImpl
, Pin
);
1504 /* point to first stream pointer */
1506 Cur
= This
->ClonedStreamPointer
;
1508 while(Cur
!= Pointer
&& Cur
)
1511 /* iterate to next cloned pointer */
1517 /* you naughty driver */
1523 /* remove first cloned pointer */
1524 This
->ClonedStreamPointer
= Pointer
->Next
;
1528 Last
->Next
= Pointer
->Next
;
1531 /* FIXME make sure no timeouts are pending */
1541 KsStreamPointerClone(
1542 IN PKSSTREAM_POINTER StreamPointer
,
1543 IN PFNKSSTREAMPOINTER CancelCallback OPTIONAL
,
1544 IN ULONG ContextSize
,
1545 OUT PKSSTREAM_POINTER
* CloneStreamPointer
)
1548 PKSISTREAM_POINTER CurFrame
;
1549 PKSISTREAM_POINTER NewFrame
;
1554 DPRINT("KsStreamPointerClone StreamPointer %p CancelCallback %p ContextSize %p CloneStreamPointer %p\n", StreamPointer
, CancelCallback
, ContextSize
, CloneStreamPointer
);
1556 /* get stream pointer */
1557 CurFrame
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1559 /* calculate context size */
1560 Size
= sizeof(KSISTREAM_POINTER
) + ContextSize
;
1562 /* allocate new stream pointer */
1563 NewFrame
= (PKSISTREAM_POINTER
)AllocateItem(NonPagedPool
, Size
);
1566 return STATUS_INSUFFICIENT_RESOURCES
;
1568 /* get current irp stack location */
1569 RefCount
= (ULONG_PTR
)CurFrame
->Irp
->Tail
.Overlay
.DriverContext
[0];
1571 /* increment reference count */
1573 CurFrame
->Irp
->Tail
.Overlay
.DriverContext
[0] = (PVOID
)RefCount
;
1575 /* copy stream pointer */
1576 RtlMoveMemory(NewFrame
, CurFrame
, sizeof(KSISTREAM_POINTER
));
1579 This
= (IKsPinImpl
*)CONTAINING_RECORD(CurFrame
->Pin
, IKsPinImpl
, Pin
);
1581 /* prepare stream header in case required */
1582 if (CurFrame
->StreamPointer
.Offset
->Remaining
== 0)
1584 Status
= IKsPin_PrepareStreamHeader(This
, NewFrame
);
1585 if (!NT_SUCCESS(Status
))
1588 return STATUS_DEVICE_NOT_READY
;
1593 NewFrame
->StreamPointer
.Context
= (NewFrame
+ 1);
1596 if (This
->Pin
.Descriptor
->PinDescriptor
.DataFlow
== KSPIN_DATAFLOW_IN
)
1597 NewFrame
->StreamPointer
.Offset
= &NewFrame
->StreamPointer
.OffsetIn
;
1599 NewFrame
->StreamPointer
.Offset
= &NewFrame
->StreamPointer
.OffsetOut
;
1603 NewFrame
->StreamPointer
.Pin
= &This
->Pin
;
1605 ASSERT(NewFrame
->StreamPointer
.Pin
);
1606 ASSERT(NewFrame
->StreamPointer
.Context
);
1607 ASSERT(NewFrame
->StreamPointer
.Offset
);
1608 ASSERT(NewFrame
->StreamPointer
.StreamHeader
);
1611 *CloneStreamPointer
= &NewFrame
->StreamPointer
;
1613 DPRINT("KsStreamPointerClone CloneStreamPointer %p\n", *CloneStreamPointer
);
1615 return STATUS_SUCCESS
;
1624 KsStreamPointerAdvanceOffsets(
1625 IN PKSSTREAM_POINTER StreamPointer
,
1630 PKSISTREAM_POINTER CurFrame
;
1634 DPRINT("KsStreamPointerAdvanceOffsets StreamPointer %p InUsed %lu OutUsed %lu Eject %lu\n", StreamPointer
, InUsed
, OutUsed
, Eject
);
1636 /* get stream pointer */
1637 CurFrame
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1640 This
= (IKsPinImpl
*)CONTAINING_RECORD(CurFrame
->Pin
, IKsPinImpl
, Pin
);
1643 ASSERT(InUsed
== 0);
1647 DPRINT("KsStreamPointerAdvanceOffsets Offset %lu Length %lu NewOffset %lu Remaining %lu LeadingEdge %p DataUsed %lu\n", CurFrame
->Offset
, CurFrame
->Length
, CurFrame
->Offset
+ OutUsed
,
1648 CurFrame
->StreamPointer
.OffsetOut
.Remaining
, &This
->LeadingEdgeStreamPointer
.StreamPointer
, CurFrame
->StreamPointer
.StreamHeader
->DataUsed
);
1651 if (This
->Pin
.Descriptor
->PinDescriptor
.DataFlow
== KSPIN_DATAFLOW_IN
)
1653 ASSERT(CurFrame
->StreamPointer
.OffsetIn
.Remaining
>= InUsed
);
1654 CurFrame
->StreamPointer
.OffsetIn
.Remaining
-= InUsed
;
1655 CurFrame
->StreamPointer
.OffsetIn
.Data
= (PVOID
)((ULONG_PTR
)CurFrame
->StreamPointer
.OffsetIn
.Data
+ InUsed
);
1659 if (!CurFrame
->StreamPointer
.OffsetOut
.Remaining
)
1661 Status
= IKsPin_PrepareStreamHeader(This
, CurFrame
);
1662 if (!NT_SUCCESS(Status
))
1664 return STATUS_DEVICE_NOT_READY
;
1669 ASSERT(CurFrame
->StreamPointer
.OffsetOut
.Remaining
>= OutUsed
);
1670 CurFrame
->StreamPointer
.OffsetOut
.Remaining
-= OutUsed
;
1671 CurFrame
->StreamPointer
.OffsetOut
.Data
= (PVOID
)((ULONG_PTR
)CurFrame
->StreamPointer
.OffsetOut
.Data
+ OutUsed
);
1675 return STATUS_SUCCESS
;
1684 KsStreamPointerAdvance(
1685 IN PKSSTREAM_POINTER StreamPointer
)
1689 return STATUS_NOT_IMPLEMENTED
;
1698 KsStreamPointerGetMdl(
1699 IN PKSSTREAM_POINTER StreamPointer
)
1711 KsStreamPointerGetIrp(
1712 IN PKSSTREAM_POINTER StreamPointer
,
1713 OUT PBOOLEAN FirstFrameInIrp OPTIONAL
,
1714 OUT PBOOLEAN LastFrameInIrp OPTIONAL
)
1726 KsStreamPointerScheduleTimeout(
1727 IN PKSSTREAM_POINTER StreamPointer
,
1728 IN PFNKSSTREAMPOINTER Callback
,
1729 IN ULONGLONG Interval
)
1731 LARGE_INTEGER DueTime
;
1732 PKSISTREAM_POINTER Pointer
;
1734 /* get stream pointer */
1735 Pointer
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1737 /* setup timer callback */
1738 Pointer
->Callback
= Callback
;
1740 /* setup expiration */
1741 DueTime
.QuadPart
= (LONGLONG
)Interval
;
1743 /* setup the timer */
1744 KeSetTimer(&Pointer
->Timer
, DueTime
, &Pointer
->TimerDpc
);
1754 KsStreamPointerCancelTimeout(
1755 IN PKSSTREAM_POINTER StreamPointer
)
1757 PKSISTREAM_POINTER Pointer
;
1759 /* get stream pointer */
1760 Pointer
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1762 KeCancelTimer(&Pointer
->Timer
);
1772 KsPinGetFirstCloneStreamPointer(
1777 DPRINT("KsPinGetFirstCloneStreamPointer %p\n", Pin
);
1779 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1781 if (!This
->ClonedStreamPointer
)
1784 /* return first cloned stream pointer */
1785 return &This
->ClonedStreamPointer
->StreamPointer
;
1794 KsStreamPointerGetNextClone(
1795 IN PKSSTREAM_POINTER StreamPointer
)
1797 PKSISTREAM_POINTER Pointer
;
1799 DPRINT("KsStreamPointerGetNextClone\n");
1801 /* get stream pointer */
1802 Pointer
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1804 /* is there a another cloned stream pointer */
1808 /* return next stream pointer */
1809 return &Pointer
->Next
->StreamPointer
;
1814 IKsPin_PinCentricWorker(
1818 IKsPinImpl
* This
= (IKsPinImpl
*)Parameter
;
1820 DPRINT("IKsPin_PinCentricWorker\n");
1824 ASSERT(This
->Pin
.Descriptor
);
1825 ASSERT(This
->Pin
.Descriptor
->Dispatch
);
1826 ASSERT(This
->Pin
.Descriptor
->Dispatch
->Process
);
1827 ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL
);
1828 ASSERT(!(This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_DISPATCH_LEVEL_PROCESSING
));
1829 ASSERT(!(This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_GENERATE_MAPPINGS
));
1833 DPRINT("IKsPin_PinCentricWorker calling Pin Process Routine\n");
1835 Status
= This
->Pin
.Descriptor
->Dispatch
->Process(&This
->Pin
);
1836 DPRINT("IKsPin_PinCentricWorker Status %lx, Offset %lu Length %lu\n", Status
,
1837 This
->LeadingEdgeStreamPointer
.Offset
,
1838 This
->LeadingEdgeStreamPointer
.Length
);
1841 }while(This
->IrpCount
);
1847 IKsPin_DispatchKsStream(
1848 PDEVICE_OBJECT DeviceObject
,
1852 PKSPROCESSPIN_INDEXENTRY ProcessPinIndex
;
1853 PKSSTREAM_HEADER Header
;
1856 PIO_STACK_LOCATION IoStack
;
1857 NTSTATUS Status
= STATUS_SUCCESS
;
1859 DPRINT("IKsPin_DispatchKsStream\n");
1861 /* FIXME handle reset states */
1862 ASSERT(This
->Pin
.ResetState
== KSRESET_END
);
1864 /* get current stack location */
1865 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1867 /* probe stream pointer */
1868 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_WRITE_STREAM
)
1869 Status
= KsProbeStreamIrp(Irp
, KSSTREAM_WRITE
| KSPROBE_ALLOCATEMDL
| KSPROBE_PROBEANDLOCK
| KSPROBE_SYSTEMADDRESS
, This
->Pin
.StreamHeaderSize
);
1871 Status
= KsProbeStreamIrp(Irp
, KSSTREAM_READ
| KSPROBE_ALLOCATEMDL
| KSPROBE_PROBEANDLOCK
| KSPROBE_SYSTEMADDRESS
, This
->Pin
.StreamHeaderSize
);
1873 if (!NT_SUCCESS(Status
))
1875 DPRINT1("KsProbeStreamIrp failed with %x\n", Status
);
1877 Irp
->IoStatus
.Status
= Status
;
1878 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1882 if (Irp
->RequestorMode
== UserMode
)
1883 Header
= (PKSSTREAM_HEADER
)Irp
->AssociatedIrp
.SystemBuffer
;
1885 Header
= (PKSSTREAM_HEADER
)Irp
->UserBuffer
;
1889 DPRINT("NoHeader Canceling Irp %p\n", Irp
);
1890 Irp
->IoStatus
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
1891 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1895 /* calculate num headers */
1896 NumHeaders
= IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
/ Header
->Size
;
1898 /* assume headers of same length */
1899 ASSERT(IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
% Header
->Size
== 0);
1901 /* FIXME support multiple stream headers */
1902 ASSERT(NumHeaders
== 1);
1904 if (Irp
->RequestorMode
== UserMode
)
1906 /* prepare header */
1907 ASSERT(Irp
->MdlAddress
);
1908 Header
->Data
= MmGetSystemAddressForMdlSafe(Irp
->MdlAddress
, NormalPagePriority
);
1912 DPRINT("NoHeader->Data Canceling Irp %p\n", Irp
);
1913 Irp
->IoStatus
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
1914 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1922 if (This
->Pin
.Descriptor
->Dispatch
->Process
)
1924 /* it is a pin centric avstream */
1926 /* mark irp as pending */
1927 IoMarkIrpPending(Irp
);
1929 /* add irp to cancelable queue */
1930 KsAddIrpToCancelableQueue(&This
->IrpList
, &This
->IrpListLock
, Irp
, KsListEntryTail
, NULL
/* FIXME */);
1933 ASSERT(!(This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_DISPATCH_LEVEL_PROCESSING
));
1934 ASSERT(This
->PinWorker
);
1936 InterlockedIncrement(&This
->IrpCount
);
1938 DPRINT("IKsPin_DispatchKsStream IrpCount %lu\n", This
->IrpCount
);
1940 /* start the processing loop */
1941 KsIncrementCountedWorker(This
->PinWorker
);
1943 Status
= STATUS_PENDING
;
1947 /* filter-centric avstream */
1948 ASSERT(This
->Filter
);
1950 ProcessPinIndex
= This
->Filter
->lpVtbl
->GetProcessDispatch(This
->Filter
);
1951 Filter
= This
->Filter
->lpVtbl
->GetStruct(This
->Filter
);
1953 ASSERT(ProcessPinIndex
);
1955 ASSERT(Filter
->Descriptor
);
1956 ASSERT(Filter
->Descriptor
->Dispatch
);
1958 if (!Filter
->Descriptor
->Dispatch
->Process
)
1960 /* invalid device request */
1961 DPRINT("Filter Centric Processing No Process Routine\n");
1962 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1963 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1964 return STATUS_UNSUCCESSFUL
;
1967 /* mark irp as pending */
1968 IoMarkIrpPending(Irp
);
1970 /* add irp to cancelable queue */
1971 KsAddIrpToCancelableQueue(&This
->IrpList
, &This
->IrpListLock
, Irp
, KsListEntryTail
, NULL
/* FIXME */);
1973 Status
= Filter
->Descriptor
->Dispatch
->Process(Filter
, ProcessPinIndex
);
1975 DPRINT("IKsPin_DispatchKsStream FilterCentric: Status %lx \n", Status
);
1984 IKsPin_DispatchDeviceIoControl(
1985 IN PDEVICE_OBJECT DeviceObject
,
1988 PIO_STACK_LOCATION IoStack
;
1989 PKSIOBJECT_HEADER ObjectHeader
;
1992 UNICODE_STRING GuidString
;
1993 PKSPROPERTY Property
;
1996 /* get current irp stack */
1997 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2000 ASSERT(IoStack
->FileObject
);
2001 ASSERT(IoStack
->FileObject
->FsContext2
);
2003 /* get the object header */
2004 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
2006 /* locate ks pin implemention from KSPIN offset */
2007 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
2009 /* current irp stack */
2010 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2012 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_READ_STREAM
||
2013 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_WRITE_STREAM
)
2015 /* handle ks stream packets */
2016 return IKsPin_DispatchKsStream(DeviceObject
, Irp
, This
);
2019 /* get property from input buffer */
2020 Property
= (PKSPROPERTY
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
2023 ASSERT(IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
>= sizeof(KSIDENTIFIER
));
2024 ASSERT(This
->Pin
.Descriptor
->AutomationTable
);
2026 RtlStringFromGUID(&Property
->Set
, &GuidString
);
2027 DPRINT("IKsPin_DispatchDeviceIoControl property Set |%S| Id %u Flags %x\n", GuidString
.Buffer
, Property
->Id
, Property
->Flags
);
2028 RtlFreeUnicodeString(&GuidString
);
2031 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_METHOD
)
2033 const KSMETHOD_SET
*MethodSet
= NULL
;
2034 ULONG MethodItemSize
= 0;
2036 /* check if the driver supports method sets */
2037 if (This
->Pin
.Descriptor
->AutomationTable
->MethodSetsCount
)
2039 SetCount
= This
->Pin
.Descriptor
->AutomationTable
->MethodSetsCount
;
2040 MethodSet
= This
->Pin
.Descriptor
->AutomationTable
->MethodSets
;
2041 MethodItemSize
= This
->Pin
.Descriptor
->AutomationTable
->MethodItemSize
;
2044 /* call method set handler */
2045 Status
= KspMethodHandlerWithAllocator(Irp
, SetCount
, MethodSet
, NULL
, MethodItemSize
);
2047 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_PROPERTY
)
2049 const KSPROPERTY_SET
*PropertySet
= NULL
;
2050 ULONG PropertyItemSize
= 0;
2052 /* check if the driver supports method sets */
2053 if (This
->Pin
.Descriptor
->AutomationTable
->PropertySetsCount
)
2055 SetCount
= This
->Pin
.Descriptor
->AutomationTable
->PropertySetsCount
;
2056 PropertySet
= This
->Pin
.Descriptor
->AutomationTable
->PropertySets
;
2057 PropertyItemSize
= This
->Pin
.Descriptor
->AutomationTable
->PropertyItemSize
;
2060 /* needed for our property handlers */
2061 KSPROPERTY_ITEM_IRP_STORAGE(Irp
) = (KSPROPERTY_ITEM
*)This
;
2063 /* call property handler */
2064 Status
= KspPropertyHandler(Irp
, SetCount
, PropertySet
, NULL
, PropertyItemSize
);
2069 ASSERT(IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_ENABLE_EVENT
||
2070 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_DISABLE_EVENT
);
2072 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_ENABLE_EVENT
)
2074 /* call enable event handlers */
2075 Status
= KspEnableEvent(Irp
,
2076 This
->Pin
.Descriptor
->AutomationTable
->EventSetsCount
,
2077 (PKSEVENT_SET
)This
->Pin
.Descriptor
->AutomationTable
->EventSets
,
2078 &This
->BasicHeader
.EventList
,
2080 (PVOID
)&This
->BasicHeader
.EventListLock
,
2082 This
->Pin
.Descriptor
->AutomationTable
->EventItemSize
);
2086 /* disable event handler */
2087 Status
= KsDisableEvent(Irp
, &This
->BasicHeader
.EventList
, KSEVENTS_SPINLOCK
, &This
->BasicHeader
.EventListLock
);
2091 RtlStringFromGUID(&Property
->Set
, &GuidString
);
2092 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
);
2093 RtlFreeUnicodeString(&GuidString
);
2095 if (Status
!= STATUS_PENDING
)
2097 Irp
->IoStatus
.Status
= Status
;
2098 CompleteRequest(Irp
, IO_NO_INCREMENT
);
2108 IN PDEVICE_OBJECT DeviceObject
,
2111 PIO_STACK_LOCATION IoStack
;
2112 PKSIOBJECT_HEADER ObjectHeader
;
2114 NTSTATUS Status
= STATUS_SUCCESS
;
2116 /* get current irp stack */
2117 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2120 ASSERT(IoStack
->FileObject
);
2121 ASSERT(IoStack
->FileObject
->FsContext2
);
2123 /* get the object header */
2124 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
2126 /* locate ks pin implemention fro KSPIN offset */
2127 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
2129 if (This
->Pin
.Descriptor
->Dispatch
->Close
)
2131 /* call pin close routine */
2132 Status
= This
->Pin
.Descriptor
->Dispatch
->Close(&This
->Pin
, Irp
);
2134 if (!NT_SUCCESS(Status
))
2137 Irp
->IoStatus
.Status
= Status
;
2138 CompleteRequest(Irp
, IO_NO_INCREMENT
);
2142 /* remove pin from filter pin list and decrement reference count */
2143 IKsFilter_RemovePin(This
->Filter
->lpVtbl
->GetStruct(This
->Filter
), &This
->Pin
);
2145 if (Status
!= STATUS_PENDING
)
2147 Irp
->IoStatus
.Status
= Status
;
2148 CompleteRequest(Irp
, IO_NO_INCREMENT
);
2158 IKsPin_DispatchCreateAllocator(
2159 IN PDEVICE_OBJECT DeviceObject
,
2164 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
2165 CompleteRequest(Irp
, IO_NO_INCREMENT
);
2166 return STATUS_NOT_IMPLEMENTED
;
2171 IKsPin_DispatchCreateClock(
2172 IN PDEVICE_OBJECT DeviceObject
,
2176 NTSTATUS Status
= STATUS_SUCCESS
;
2178 KSRESOLUTION Resolution
;
2179 PKSRESOLUTION pResolution
= NULL
;
2180 PKSOBJECT_CREATE_ITEM CreateItem
;
2182 DPRINT("IKsPin_DispatchCreateClock\n");
2184 /* get the create item */
2185 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
2190 /* get the pin object */
2191 Pin
= (PKSPIN
)CreateItem
->Context
;
2196 /* locate ks pin implemention fro KSPIN offset */
2197 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
2200 ASSERT(This
->BasicHeader
.Type
== KsObjectTypePin
);
2201 ASSERT(This
->BasicHeader
.ControlMutex
);
2203 /* acquire control mutex */
2204 KsAcquireControl(Pin
);
2206 if ((This
->Pin
.Descriptor
->PinDescriptor
.Communication
!= KSPIN_COMMUNICATION_NONE
&&
2207 This
->Pin
.Descriptor
->Dispatch
) ||
2208 (This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_IMPLEMENT_CLOCK
))
2210 if (!This
->DefaultClock
)
2212 if (This
->Pin
.Descriptor
->Dispatch
&& This
->Pin
.Descriptor
->Dispatch
->Clock
)
2214 if (This
->Pin
.Descriptor
->Dispatch
->Clock
->Resolution
)
2216 This
->Pin
.Descriptor
->Dispatch
->Clock
->Resolution(&This
->Pin
, &Resolution
);
2217 pResolution
= &Resolution
;
2220 Status
= KsAllocateDefaultClockEx(&This
->DefaultClock
,
2222 (PFNKSSETTIMER
)This
->Pin
.Descriptor
->Dispatch
->Clock
->SetTimer
,
2223 (PFNKSCANCELTIMER
)This
->Pin
.Descriptor
->Dispatch
->Clock
->CancelTimer
,
2224 (PFNKSCORRELATEDTIME
)This
->Pin
.Descriptor
->Dispatch
->Clock
->CorrelatedTime
,
2230 Status
= KsAllocateDefaultClockEx(&This
->DefaultClock
, (PVOID
)&This
->Pin
, NULL
, NULL
, NULL
, NULL
, 0);
2234 if (NT_SUCCESS(Status
))
2236 Status
= KsCreateDefaultClock(Irp
, This
->DefaultClock
);
2240 DPRINT("IKsPin_DispatchCreateClock %lx\n", Status
);
2242 /* release control mutex */
2243 KsReleaseControl(Pin
);
2246 Irp
->IoStatus
.Status
= Status
;
2247 CompleteRequest(Irp
, IO_NO_INCREMENT
);
2253 IKsPin_DispatchCreateNode(
2254 IN PDEVICE_OBJECT DeviceObject
,
2259 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
2260 CompleteRequest(Irp
, IO_NO_INCREMENT
);
2261 return STATUS_NOT_IMPLEMENTED
;
2264 static KSDISPATCH_TABLE PinDispatchTable
=
2266 IKsPin_DispatchDeviceIoControl
,
2267 KsDispatchInvalidDeviceRequest
,
2268 KsDispatchInvalidDeviceRequest
,
2269 KsDispatchInvalidDeviceRequest
,
2271 KsDispatchQuerySecurity
,
2272 KsDispatchSetSecurity
,
2273 KsDispatchFastIoDeviceControlFailure
,
2274 KsDispatchFastReadFailure
,
2275 KsDispatchFastReadFailure
2280 IN PDEVICE_OBJECT DeviceObject
,
2282 IN PKSDEVICE KsDevice
,
2283 IN IKsFilterFactory
* FilterFactory
,
2284 IN IKsFilter
* Filter
,
2285 IN PKSPIN_CONNECT Connect
,
2286 IN KSPIN_DESCRIPTOR_EX
* Descriptor
)
2289 PIO_STACK_LOCATION IoStack
;
2291 PDEVICE_EXTENSION DeviceExtension
;
2292 PKSOBJECT_CREATE_ITEM CreateItem
;
2294 PKSDATAFORMAT DataFormat
;
2295 PKSBASIC_HEADER BasicHeader
;
2297 ULONG FrameSize
= 0;
2298 ULONG NumFrames
= 0;
2299 KSAUTOMATION_TABLE AutomationTable
;
2302 ASSERT(Descriptor
->Dispatch
);
2304 DPRINT("KspCreatePin PinId %lu Flags %x\n", Connect
->PinId
, Descriptor
->Flags
);
2306 //Output Pin: KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY
2307 //Input Pin: KSPIN_FLAG_FIXED_FORMAT|KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT|KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING
2309 DPRINT("KspCreatePin Dataflow %lu\n", Descriptor
->PinDescriptor
.DataFlow
);
2310 DPRINT("KspCreatePin Communication %lu\n", Descriptor
->PinDescriptor
.Communication
);
2311 if (Descriptor
->AllocatorFraming
)
2313 DPRINT("KspCreatePin CountItems %lu\n", Descriptor
->AllocatorFraming
->CountItems
);
2314 DPRINT("KspCreatePin PinFlags %lx\n", Descriptor
->AllocatorFraming
->PinFlags
);
2315 DPRINT("KspCreatePin OutputCompression RatioNumerator %lu RatioDenominator %lu RatioConstantMargin %lu\n", Descriptor
->AllocatorFraming
->OutputCompression
.RatioNumerator
,
2316 Descriptor
->AllocatorFraming
->OutputCompression
.RatioDenominator
, Descriptor
->AllocatorFraming
->OutputCompression
.RatioConstantMargin
);
2317 DPRINT("KspCreatePin PinWeight %lx\n", Descriptor
->AllocatorFraming
->PinWeight
);
2319 for(Index
= 0; Index
< Descriptor
->AllocatorFraming
->CountItems
; Index
++)
2321 DPRINT("KspCreatePin Index %lu MemoryFlags %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].MemoryFlags
);
2322 DPRINT("KspCreatePin Index %lu BusFlags %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].BusFlags
);
2323 DPRINT("KspCreatePin Index %lu Flags %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].Flags
);
2324 DPRINT("KspCreatePin Index %lu Frames %lu\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].Frames
);
2325 DPRINT("KspCreatePin Index %lu FileAlignment %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].FileAlignment
);
2326 DPRINT("KspCreatePin Index %lu MemoryTypeWeight %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].MemoryTypeWeight
);
2327 DPRINT("KspCreatePin Index %lu PhysicalRange MinFrameSize %lu MaxFrameSize %lu Stepping %lu\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].PhysicalRange
.MinFrameSize
,
2328 Descriptor
->AllocatorFraming
->FramingItem
[Index
].PhysicalRange
.MaxFrameSize
,
2329 Descriptor
->AllocatorFraming
->FramingItem
[Index
].PhysicalRange
.Stepping
);
2331 DPRINT("KspCreatePin Index %lu FramingRange MinFrameSize %lu MaxFrameSize %lu Stepping %lu InPlaceWeight %lu NotInPlaceWeight %lu\n",
2333 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.Range
.MinFrameSize
,
2334 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.Range
.MaxFrameSize
,
2335 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.Range
.Stepping
,
2336 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.InPlaceWeight
,
2337 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.NotInPlaceWeight
);
2339 FrameSize
= Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.Range
.MaxFrameSize
;
2340 NumFrames
= Descriptor
->AllocatorFraming
->FramingItem
[Index
].Frames
;
2344 for (Index
= 0; Index
< Descriptor
->PinDescriptor
.DataRangesCount
; Index
++)
2346 UNICODE_STRING GuidString
;
2347 /* convert the guid to string */
2348 RtlStringFromGUID(&Descriptor
->PinDescriptor
.DataRanges
[Index
]->MajorFormat
, &GuidString
);
2349 DPRINT("Index %lu MajorFormat %S\n", Index
, GuidString
.Buffer
);
2350 RtlStringFromGUID(&Descriptor
->PinDescriptor
.DataRanges
[Index
]->SubFormat
, &GuidString
);
2351 DPRINT("Index %lu SubFormat %S\n", Index
, GuidString
.Buffer
);
2352 RtlStringFromGUID(&Descriptor
->PinDescriptor
.DataRanges
[Index
]->Specifier
, &GuidString
);
2353 DPRINT("Index %lu Specifier %S\n", Index
, GuidString
.Buffer
);
2354 RtlStringFromGUID(&Descriptor
->PinDescriptor
.DataRanges
[Index
]->Specifier
, &GuidString
);
2355 DPRINT("Index %lu FormatSize %lu Flags %lu SampleSize %lu Reserved %lu KSDATAFORMAT %lu\n", Index
,
2356 Descriptor
->PinDescriptor
.DataRanges
[Index
]->FormatSize
, Descriptor
->PinDescriptor
.DataRanges
[Index
]->Flags
, Descriptor
->PinDescriptor
.DataRanges
[Index
]->SampleSize
, Descriptor
->PinDescriptor
.DataRanges
[Index
]->Reserved
, sizeof(KSDATAFORMAT
));
2358 if (IsEqualGUIDAligned(&Descriptor
->PinDescriptor
.DataRanges
[Index
]->SubFormat
, &KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT
))
2360 PKS_DATARANGE_BDA_TRANSPORT Transport
= (PKS_DATARANGE_BDA_TRANSPORT
)&Descriptor
->PinDescriptor
.DataRanges
[Index
];
2361 DPRINT("KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT AvgTimePerFrame %I64u ulcbPhyiscalFrame %lu ulcbPhyiscalFrameAlignment %lu ulcbPhyiscalPacket %lu\n", Transport
->BdaTransportInfo
.AvgTimePerFrame
, Transport
->BdaTransportInfo
.ulcbPhyiscalFrame
,
2362 Transport
->BdaTransportInfo
.ulcbPhyiscalFrameAlignment
, Transport
->BdaTransportInfo
.ulcbPhyiscalPacket
);
2367 /* default to 50 * 188 (MPEG2 TS packet size) */
2376 /* get current irp stack */
2377 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2379 /* get device extension */
2380 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
2382 /* get ks device interface */
2383 Device
= (IKsDevice
*)&DeviceExtension
->DeviceHeader
->BasicHeader
.OuterUnknown
;
2385 /* first allocate pin ctx */
2386 This
= AllocateItem(NonPagedPool
, sizeof(IKsPinImpl
));
2389 /* not enough memory */
2390 return STATUS_INSUFFICIENT_RESOURCES
;
2393 /* allocate create item */
2394 CreateItem
= AllocateItem(NonPagedPool
, sizeof(KSOBJECT_CREATE_ITEM
) * 3);
2397 /* not enough memory */
2399 DPRINT("KspCreatePin OutOfMemory\n");
2400 return STATUS_INSUFFICIENT_RESOURCES
;
2403 /* initialize basic header */
2404 This
->BasicHeader
.KsDevice
= KsDevice
;
2405 This
->BasicHeader
.Type
= KsObjectTypePin
;
2406 This
->BasicHeader
.Parent
.KsFilter
= Filter
->lpVtbl
->GetStruct(Filter
);
2407 This
->BasicHeader
.OuterUnknown
= (PUNKNOWN
)&vt_IKsPin
;
2408 InitializeListHead(&This
->BasicHeader
.EventList
);
2409 KeInitializeSpinLock(&This
->BasicHeader
.EventListLock
);
2411 ASSERT(This
->BasicHeader
.Parent
.KsFilter
);
2413 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)This
->BasicHeader
.Parent
.KsFilter
- sizeof(KSBASIC_HEADER
));
2415 This
->BasicHeader
.ControlMutex
= BasicHeader
->ControlMutex
;
2416 ASSERT(This
->BasicHeader
.ControlMutex
);
2418 InitializeListHead(&This
->BasicHeader
.EventList
);
2419 KeInitializeSpinLock(&This
->BasicHeader
.EventListLock
);
2421 /* initialize pin */
2422 This
->FrameSize
= FrameSize
;
2423 This
->NumFrames
= NumFrames
;
2424 This
->lpVtblReferenceClock
= &vt_ReferenceClock
;
2426 This
->FileObject
= IoStack
->FileObject
;
2427 This
->Filter
= Filter
;
2428 KeInitializeMutex(&This
->ProcessingMutex
, 0);
2429 InitializeListHead(&This
->IrpList
);
2430 KeInitializeSpinLock(&This
->IrpListLock
);
2432 /* allocate object bag */
2433 This
->Pin
.Bag
= AllocateItem(NonPagedPool
, sizeof(KSIOBJECT_BAG
));
2436 /* not enough memory */
2438 FreeItem(CreateItem
);
2439 return STATUS_INSUFFICIENT_RESOURCES
;
2442 /* initialize object bag */
2443 Device
->lpVtbl
->InitializeObjectBag(Device
, This
->Pin
.Bag
, NULL
);
2445 /* allocate pin descriptor */
2446 This
->Pin
.Descriptor
= AllocateItem(NonPagedPool
, sizeof(KSPIN_DESCRIPTOR_EX
));
2447 if (!This
->Pin
.Descriptor
)
2449 /* not enough memory */
2450 KsFreeObjectBag(This
->Pin
.Bag
);
2452 FreeItem(CreateItem
);
2453 return STATUS_INSUFFICIENT_RESOURCES
;
2456 /* copy pin descriptor */
2457 RtlMoveMemory((PVOID
)This
->Pin
.Descriptor
, Descriptor
, sizeof(KSPIN_DESCRIPTOR_EX
));
2459 /* initialize automation table */
2460 RtlZeroMemory(&AutomationTable
, sizeof(KSAUTOMATION_TABLE
));
2462 AutomationTable
.PropertyItemSize
= sizeof(KSPROPERTY_ITEM
);
2463 AutomationTable
.PropertySets
= PinPropertySet
;
2464 AutomationTable
.PropertySetsCount
= sizeof(PinPropertySet
) / sizeof(KSPROPERTY_SET
);
2466 /* merge in pin property sets */
2467 Status
= KsMergeAutomationTables((PKSAUTOMATION_TABLE
*)&This
->Pin
.Descriptor
->AutomationTable
, (PKSAUTOMATION_TABLE
)Descriptor
->AutomationTable
, &AutomationTable
, This
->Pin
.Bag
);
2469 if (!NT_SUCCESS(Status
))
2471 /* not enough memory */
2472 KsFreeObjectBag(This
->Pin
.Bag
);
2474 FreeItem(CreateItem
);
2479 DataFormat
= (PKSDATAFORMAT
)(Connect
+ 1);
2481 /* initialize pin descriptor */
2482 This
->Pin
.Context
= NULL
;
2483 This
->Pin
.Id
= Connect
->PinId
;
2484 This
->Pin
.Communication
= Descriptor
->PinDescriptor
.Communication
;
2485 This
->Pin
.ConnectionIsExternal
= FALSE
; //FIXME
2486 RtlMoveMemory(&This
->Pin
.ConnectionInterface
, &Connect
->Interface
, sizeof(KSPIN_INTERFACE
));
2487 RtlMoveMemory(&This
->Pin
.ConnectionMedium
, &Connect
->Medium
, sizeof(KSPIN_MEDIUM
));
2488 RtlMoveMemory(&This
->Pin
.ConnectionPriority
, &Connect
->Priority
, sizeof(KSPRIORITY
));
2490 /* allocate format */
2491 Status
= _KsEdit(This
->Pin
.Bag
, (PVOID
*)&This
->Pin
.ConnectionFormat
, DataFormat
->FormatSize
, DataFormat
->FormatSize
, 0);
2492 if (!NT_SUCCESS(Status
))
2494 /* failed to allocate format */
2495 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2497 FreeItem(CreateItem
);
2498 return STATUS_INSUFFICIENT_RESOURCES
;
2502 RtlMoveMemory((PVOID
)This
->Pin
.ConnectionFormat
, DataFormat
, DataFormat
->FormatSize
);
2504 This
->Pin
.AttributeList
= NULL
; //FIXME
2505 This
->Pin
.StreamHeaderSize
= sizeof(KSSTREAM_HEADER
);
2506 This
->Pin
.DataFlow
= Descriptor
->PinDescriptor
.DataFlow
;
2507 This
->Pin
.DeviceState
= KSSTATE_STOP
;
2508 This
->Pin
.ResetState
= KSRESET_END
;
2509 This
->Pin
.ClientState
= KSSTATE_STOP
;
2511 /* intialize allocator create item */
2512 CreateItem
[0].Context
= (PVOID
)&This
->Pin
;
2513 CreateItem
[0].Create
= IKsPin_DispatchCreateAllocator
;
2514 CreateItem
[0].Flags
= KSCREATE_ITEM_FREEONSTOP
;
2515 RtlInitUnicodeString(&CreateItem
[0].ObjectClass
, KSSTRING_Allocator
);
2517 /* intialize clock create item */
2518 CreateItem
[1].Context
= (PVOID
)&This
->Pin
;
2519 CreateItem
[1].Create
= IKsPin_DispatchCreateClock
;
2520 CreateItem
[1].Flags
= KSCREATE_ITEM_FREEONSTOP
;
2521 RtlInitUnicodeString(&CreateItem
[1].ObjectClass
, KSSTRING_Clock
);
2523 /* intialize topology node create item */
2524 CreateItem
[2].Context
= (PVOID
)&This
->Pin
;
2525 CreateItem
[2].Create
= IKsPin_DispatchCreateNode
;
2526 CreateItem
[2].Flags
= KSCREATE_ITEM_FREEONSTOP
;
2527 RtlInitUnicodeString(&CreateItem
[2].ObjectClass
, KSSTRING_TopologyNode
);
2529 /* now allocate object header */
2530 Status
= KsAllocateObjectHeader((KSOBJECT_HEADER
*)&This
->ObjectHeader
, 3, CreateItem
, Irp
, &PinDispatchTable
);
2531 if (!NT_SUCCESS(Status
))
2533 /* failed to create object header */
2534 DPRINT("KspCreatePin KsAllocateObjectHeader failed %lx\n", Status
);
2535 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2537 FreeItem(CreateItem
);
2539 /* return failure code */
2543 /* add extra info to object header */
2544 This
->ObjectHeader
->Type
= KsObjectTypePin
;
2545 This
->ObjectHeader
->Unknown
= (PUNKNOWN
)&This
->BasicHeader
.OuterUnknown
;
2546 This
->ObjectHeader
->ObjectType
= (PVOID
)&This
->Pin
;
2548 if (!Descriptor
->Dispatch
|| !Descriptor
->Dispatch
->Process
)
2550 /* the pin is part of filter-centric processing filter
2551 * add process pin to filter
2553 This
->ProcessPin
.BytesAvailable
= 0;
2554 This
->ProcessPin
.BytesUsed
= 0;
2555 This
->ProcessPin
.CopySource
= NULL
;
2556 This
->ProcessPin
.Data
= NULL
;
2557 This
->ProcessPin
.DelegateBranch
= NULL
;
2558 This
->ProcessPin
.Flags
= 0;
2559 This
->ProcessPin
.InPlaceCounterpart
= NULL
;
2560 This
->ProcessPin
.Pin
= &This
->Pin
;
2561 This
->ProcessPin
.StreamPointer
= (PKSSTREAM_POINTER
)&This
->LeadingEdgeStreamPointer
.StreamPointer
;
2562 This
->ProcessPin
.Terminate
= FALSE
;
2564 Status
= Filter
->lpVtbl
->AddProcessPin(Filter
, &This
->ProcessPin
);
2565 DPRINT("KspCreatePin AddProcessPin %lx\n", Status
);
2567 if (!NT_SUCCESS(Status
))
2569 /* failed to add process pin */
2570 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2571 KsFreeObjectHeader(&This
->ObjectHeader
);
2573 FreeItem(CreateItem
);
2574 /* return failure code */
2578 else if (Descriptor
->Dispatch
&& Descriptor
->Dispatch
->Process
)
2580 /* pin centric processing filter */
2582 /* initialize work item */
2583 ExInitializeWorkItem(&This
->PinWorkQueueItem
, IKsPin_PinCentricWorker
, (PVOID
)This
);
2585 /* allocate counted work item */
2586 Status
= KsRegisterCountedWorker(HyperCriticalWorkQueue
, &This
->PinWorkQueueItem
, &This
->PinWorker
);
2588 if (!NT_SUCCESS(Status
))
2590 DPRINT("Failed to register Worker %lx\n", Status
);
2591 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2592 KsFreeObjectHeader(&This
->ObjectHeader
);
2594 FreeItem(CreateItem
);
2598 if (This
->Pin
.Descriptor
->PinDescriptor
.DataFlow
== KSPIN_DATAFLOW_IN
)
2599 This
->LeadingEdgeStreamPointer
.StreamPointer
.Offset
= &This
->LeadingEdgeStreamPointer
.StreamPointer
.OffsetIn
;
2601 This
->LeadingEdgeStreamPointer
.StreamPointer
.Offset
= &This
->LeadingEdgeStreamPointer
.StreamPointer
.OffsetOut
;
2604 KeInitializeEvent(&This
->FrameComplete
, NotificationEvent
, FALSE
);
2608 /* FIXME add pin instance to filter instance */
2609 IKsFilter_AddPin(Filter
->lpVtbl
->GetStruct(Filter
), &This
->Pin
);
2611 if (Descriptor
->Dispatch
&& Descriptor
->Dispatch
->SetDataFormat
)
2613 Status
= Descriptor
->Dispatch
->SetDataFormat(&This
->Pin
, NULL
, NULL
, This
->Pin
.ConnectionFormat
, NULL
);
2614 DPRINT("KspCreatePin SetDataFormat %lx\n", Status
);
2618 /* does the driver have a pin dispatch */
2619 if (Descriptor
->Dispatch
&& Descriptor
->Dispatch
->Create
)
2621 /* now inform the driver to create a new pin */
2622 Status
= Descriptor
->Dispatch
->Create(&This
->Pin
, Irp
);
2623 DPRINT("KspCreatePin DispatchCreate %lx\n", Status
);
2627 DPRINT("KspCreatePin Status %lx KsDevice %p\n", Status
, KsDevice
);
2629 if (!NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
)
2631 /* failed to create pin, release resources */
2632 IKsFilter_RemovePin(Filter
->lpVtbl
->GetStruct(Filter
), &This
->Pin
);
2633 KsFreeObjectHeader((KSOBJECT_HEADER
)This
->ObjectHeader
);
2634 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2637 /* return failure code */