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
;
24 }KSISTREAM_POINTER
, *PKSISTREAM_POINTER
;
28 KSBASIC_HEADER BasicHeader
;
30 PKSIOBJECT_HEADER ObjectHeader
;
31 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
;
153 /* locate ks pin implemention from KSPIN offset */
154 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
156 /* acquire control mutex */
157 KeWaitForSingleObject(This
->BasicHeader
.ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
159 Handle
= (PHANDLE
)Data
;
161 if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
163 if (This
->Pin
.Descriptor
->PinDescriptor
.Communication
!= KSPIN_COMMUNICATION_NONE
&&
164 This
->Pin
.Descriptor
->Dispatch
&&
165 (This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_IMPLEMENT_CLOCK
))
168 Status
= STATUS_SUCCESS
;
172 /* no clock available */
173 Status
= STATUS_UNSUCCESSFUL
;
176 else if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
178 if (This
->Pin
.ClientState
!= KSSTATE_STOP
)
180 /* can only set in stopped state */
181 Status
= STATUS_INVALID_DEVICE_STATE
;
187 Mode
= ExGetPreviousMode();
189 Status
= ObReferenceObjectByHandle(*Handle
, SYNCHRONIZE
| DIRECTORY_QUERY
, IoFileObjectType
, Mode
, (PVOID
*)&FileObject
, NULL
);
191 DPRINT("IKsPin_PinMasterClock ObReferenceObjectByHandle %lx\n", Status
);
192 if (NT_SUCCESS(Status
))
194 Property
.Set
= KSPROPSETID_Clock
;
195 Property
.Id
= KSPROPERTY_CLOCK_FUNCTIONTABLE
;
196 Property
.Flags
= KSPROPERTY_TYPE_GET
;
198 Status
= KsSynchronousIoControlDevice(FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, &Property
, sizeof(KSPROPERTY
), &This
->ClockTable
, sizeof(KSCLOCK_FUNCTIONTABLE
), &BytesReturned
);
200 DPRINT("IKsPin_PinMasterClock KSPROPERTY_CLOCK_FUNCTIONTABLE %lx\n", Status
);
202 if (NT_SUCCESS(Status
))
204 This
->ClockFileObject
= FileObject
;
208 ObDereferenceObject(FileObject
);
214 /* zeroing clock handle */
215 RtlZeroMemory(&This
->ClockTable
, sizeof(KSCLOCK_FUNCTIONTABLE
));
216 Status
= STATUS_SUCCESS
;
217 if (This
->ClockFileObject
)
219 FileObject
= This
->ClockFileObject
;
220 This
->ClockFileObject
= NULL
;
222 ObDereferenceObject(This
->ClockFileObject
);
228 /* release processing mutex */
229 KeReleaseMutex(This
->BasicHeader
.ControlMutex
, FALSE
);
231 DPRINT("IKsPin_PinStatePropertyHandler 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
= *NewState
;
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
;
314 /* update device state */
315 This
->Pin
.DeviceState
= *NewState
;
320 /* just set new state */
321 This
->Pin
.DeviceState
= *NewState
;
322 This
->Pin
.ClientState
= *NewState
;
326 /* release processing mutex */
327 KeReleaseMutex(This
->BasicHeader
.ControlMutex
, FALSE
);
329 DPRINT("IKsPin_PinStatePropertyHandler Status %lx\n", Status
);
335 IKsPin_PinAllocatorFramingPropertyHandler(
337 IN PKSIDENTIFIER Request
,
341 return STATUS_NOT_IMPLEMENTED
;
346 IKsPin_PinDataFormatPropertyHandler(
348 IN PKSPROPERTY Request
,
351 PIO_STACK_LOCATION IoStack
;
352 PKSIOBJECT_HEADER ObjectHeader
;
354 NTSTATUS Status
= STATUS_SUCCESS
;
356 /* get current irp stack */
357 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
359 DPRINT("IKsPin_PinDataFormatPropertyHandler\n");
362 ASSERT(IoStack
->FileObject
);
363 ASSERT(IoStack
->FileObject
->FsContext2
);
365 /* get the object header */
366 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
368 /* locate ks pin implemention from KSPIN offset */
369 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
371 /* acquire control mutex */
372 KeWaitForSingleObject(This
->BasicHeader
.ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
374 if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
376 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< This
->Pin
.ConnectionFormat
->FormatSize
)
378 /* buffer too small */
379 Irp
->IoStatus
.Information
= This
->Pin
.ConnectionFormat
->FormatSize
;
380 Status
= STATUS_BUFFER_TOO_SMALL
;
385 RtlMoveMemory(Data
, This
->Pin
.ConnectionFormat
, This
->Pin
.ConnectionFormat
->FormatSize
);
388 else if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
391 if (This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_FIXED_FORMAT
)
393 /* format cannot be changed */
394 Status
= STATUS_INVALID_DEVICE_REQUEST
;
398 /* FIXME check if the format is supported */
399 Status
= _KsEdit(This
->Pin
.Bag
, (PVOID
*)&This
->Pin
.ConnectionFormat
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, This
->Pin
.ConnectionFormat
->FormatSize
, 0);
401 if (NT_SUCCESS(Status
))
403 /* store new format */
404 RtlMoveMemory(This
->Pin
.ConnectionFormat
, Data
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
);
409 /* release processing mutex */
410 KeReleaseMutex(This
->BasicHeader
.ControlMutex
, FALSE
);
412 DPRINT("IKsPin_PinDataFormatPropertyHandler Status %lx\n", Status
);
419 IKsPin_fnQueryInterface(
424 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtbl
);
426 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
))
428 *Output
= &This
->lpVtbl
;
429 _InterlockedIncrement(&This
->ref
);
430 return STATUS_SUCCESS
;
433 return STATUS_UNSUCCESSFUL
;
441 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtbl
);
443 return InterlockedIncrement(&This
->ref
);
451 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtbl
);
453 InterlockedDecrement(&This
->ref
);
460 /* Return new reference count */
466 IKsPin_fnTransferKsIrp(
469 IN IKsTransport
**OutTransport
)
472 return STATUS_NOT_IMPLEMENTED
;
477 IKsPin_fnDiscardKsIrp(
480 IN IKsTransport
* *OutTransport
)
490 IN IKsTransport
* TransportIn
,
491 OUT IKsTransport
** OutTransportIn
,
492 OUT IKsTransport
* *OutTransportOut
,
493 IN KSPIN_DATAFLOW DataFlow
)
496 return STATUS_NOT_IMPLEMENTED
;
501 IKsPin_fnSetDeviceState(
505 IN IKsTransport
* *OutTransport
)
508 return STATUS_NOT_IMPLEMENTED
;
513 IKsPin_fnSetResetState(
515 IN KSRESET ResetState
,
516 OUT IKsTransport
* * OutTransportOut
)
523 IKsPin_fnGetTransportConfig(
525 IN
struct KSPTRANSPORTCONFIG
* TransportConfig
,
526 OUT IKsTransport
** OutTransportIn
,
527 OUT IKsTransport
** OutTransportOut
)
530 return STATUS_NOT_IMPLEMENTED
;
535 IKsPin_fnSetTransportConfig(
537 IN
struct KSPTRANSPORTCONFIG
const * TransportConfig
,
538 OUT IKsTransport
** OutTransportIn
,
539 OUT IKsTransport
** OutTransportOut
)
542 return STATUS_NOT_IMPLEMENTED
;
547 IKsPin_fnResetTransportConfig(
549 OUT IKsTransport
** OutTransportIn
,
550 OUT IKsTransport
** OutTransportOut
)
553 return STATUS_NOT_IMPLEMENTED
;
567 IKsPin_fnGetProcessPin(
576 IKsPin_fnAttemptBypass(
580 return STATUS_NOT_IMPLEMENTED
;
585 IKsPin_fnAttemptUnbypass(
589 return STATUS_NOT_IMPLEMENTED
;
594 IKsPin_fnGenerateConnectionEvents(
603 IKsPin_fnClientSetDeviceState(
609 return STATUS_NOT_IMPLEMENTED
;
612 static IKsPinVtbl vt_IKsPin
=
614 IKsPin_fnQueryInterface
,
617 IKsPin_fnTransferKsIrp
,
618 IKsPin_fnDiscardKsIrp
,
620 IKsPin_fnSetDeviceState
,
621 IKsPin_fnSetResetState
,
622 IKsPin_fnGetTransportConfig
,
623 IKsPin_fnSetTransportConfig
,
624 IKsPin_fnResetTransportConfig
,
626 IKsPin_fnGetProcessPin
,
627 IKsPin_fnAttemptBypass
,
628 IKsPin_fnAttemptUnbypass
,
629 IKsPin_fnGenerateConnectionEvents
,
630 IKsPin_fnClientSetDeviceState
634 //==============================================================
638 IKsReferenceClock_fnQueryInterface(
639 IKsReferenceClock
* iface
,
643 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
645 return IKsPin_fnQueryInterface((IKsPin
*)&This
->lpVtbl
, refiid
, Output
);
650 IKsReferenceClock_fnAddRef(
651 IKsReferenceClock
* iface
)
653 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
655 return IKsPin_fnAddRef((IKsPin
*)&This
->lpVtbl
);
660 IKsReferenceClock_fnRelease(
661 IKsReferenceClock
* iface
)
663 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
665 return IKsPin_fnRelease((IKsPin
*)&This
->lpVtbl
);
670 IKsReferenceClock_fnGetTime(
671 IKsReferenceClock
* iface
)
675 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
677 if (!This
->ClockFileObject
|| !This
->ClockTable
.GetTime
)
683 Result
= This
->ClockTable
.GetTime(This
->ClockFileObject
);
691 IKsReferenceClock_fnGetPhysicalTime(
692 IKsReferenceClock
* iface
)
696 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
698 if (!This
->ClockFileObject
|| !This
->ClockTable
.GetPhysicalTime
)
704 Result
= This
->ClockTable
.GetPhysicalTime(This
->ClockFileObject
);
713 IKsReferenceClock_fnGetCorrelatedTime(
714 IKsReferenceClock
* iface
,
715 OUT PLONGLONG SystemTime
)
719 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
721 if (!This
->ClockFileObject
|| !This
->ClockTable
.GetCorrelatedTime
)
727 Result
= This
->ClockTable
.GetCorrelatedTime(This
->ClockFileObject
, SystemTime
);
736 IKsReferenceClock_fnGetCorrelatedPhysicalTime(
737 IKsReferenceClock
* iface
,
738 OUT PLONGLONG SystemTime
)
742 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
744 if (!This
->ClockFileObject
|| !This
->ClockTable
.GetCorrelatedPhysicalTime
)
750 Result
= This
->ClockTable
.GetCorrelatedPhysicalTime(This
->ClockFileObject
, SystemTime
);
758 IKsReferenceClock_fnGetResolution(
759 IKsReferenceClock
* iface
,
760 OUT PKSRESOLUTION Resolution
)
765 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
767 DPRINT1("IKsReferenceClock_fnGetResolution\n");
769 if (!This
->ClockFileObject
)
771 Resolution
->Error
= 0;
772 Resolution
->Granularity
= 1;
773 DPRINT1("IKsReferenceClock_fnGetResolution Using HACK\n");
774 return STATUS_SUCCESS
;
778 if (!This
->ClockFileObject
)
779 return STATUS_DEVICE_NOT_READY
;
782 Property
.Set
= KSPROPSETID_Clock
;
783 Property
.Id
= KSPROPERTY_CLOCK_RESOLUTION
;
784 Property
.Flags
= KSPROPERTY_TYPE_GET
;
786 return KsSynchronousIoControlDevice(This
->ClockFileObject
, KernelMode
, IOCTL_KS_PROPERTY
, &Property
, sizeof(KSPROPERTY
), Resolution
, sizeof(KSRESOLUTION
), &BytesReturned
);
792 IKsReferenceClock_fnGetState(
793 IKsReferenceClock
* iface
,
799 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtblReferenceClock
);
801 DPRINT1("IKsReferenceClock_fnGetState\n");
803 if (!This
->ClockFileObject
)
805 *State
= This
->Pin
.ClientState
;
806 DPRINT1("IKsReferenceClock_fnGetState Using HACK\n");
807 return STATUS_SUCCESS
;
811 if (!This
->ClockFileObject
)
812 return STATUS_DEVICE_NOT_READY
;
815 Property
.Set
= KSPROPSETID_Clock
;
816 Property
.Id
= KSPROPERTY_CLOCK_RESOLUTION
;
817 Property
.Flags
= KSPROPERTY_TYPE_GET
;
819 return KsSynchronousIoControlDevice(This
->ClockFileObject
, KernelMode
, IOCTL_KS_PROPERTY
, &Property
, sizeof(KSPROPERTY
), State
, sizeof(KSSTATE
), &BytesReturned
);
822 static IKsReferenceClockVtbl vt_ReferenceClock
=
824 IKsReferenceClock_fnQueryInterface
,
825 IKsReferenceClock_fnAddRef
,
826 IKsReferenceClock_fnRelease
,
827 IKsReferenceClock_fnGetTime
,
828 IKsReferenceClock_fnGetPhysicalTime
,
829 IKsReferenceClock_fnGetCorrelatedTime
,
830 IKsReferenceClock_fnGetCorrelatedPhysicalTime
,
831 IKsReferenceClock_fnGetResolution
,
832 IKsReferenceClock_fnGetState
836 //==============================================================
844 KsPinAcquireProcessingMutex(
847 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
849 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
859 IN PKSGATE AndGate OPTIONAL
)
861 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
863 /* FIXME attach to filter's and gate (filter-centric processing) */
865 This
->AttachedGate
= AndGate
;
866 This
->OrGate
= FALSE
;
876 IN PKSGATE OrGate OPTIONAL
)
878 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
880 /* FIXME attach to filter's and gate (filter-centric processing) */
882 This
->AttachedGate
= OrGate
;
894 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
896 return This
->AttachedGate
;
904 KsPinAttemptProcessing(
906 IN BOOLEAN Asynchronous
)
908 DPRINT("KsPinAttemptProcessing\n");
918 KsPinGetAvailableByteCount(
920 OUT PLONG InputDataBytes OPTIONAL
,
921 OUT PLONG OutputBufferBytes OPTIONAL
)
924 return STATUS_NOT_IMPLEMENTED
;
932 KsPinGetConnectedFilterInterface(
934 IN
const GUID
* InterfaceId
,
935 OUT PVOID
* Interface
)
938 return STATUS_NOT_IMPLEMENTED
;
946 KsPinGetConnectedPinDeviceObject(
958 KsPinGetConnectedPinFileObject(
970 KsPinGetConnectedPinInterface(
972 IN
const GUID
* InterfaceId
,
973 OUT PVOID
* Interface
)
976 return STATUS_NOT_IMPLEMENTED
;
984 KsPinGetCopyRelationships(
986 OUT PKSPIN
* CopySource
,
987 OUT PKSPIN
* DelegateBranch
)
997 KsPinGetNextSiblingPin(
1000 return KsGetNextSibling((PVOID
)Pin
);
1008 KsPinGetParentFilter(
1011 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1013 /* return parent filter */
1014 return This
->BasicHeader
.Parent
.KsFilter
;
1022 KsPinGetReferenceClockInterface(
1024 OUT PIKSREFERENCECLOCK
* Interface
)
1026 NTSTATUS Status
= STATUS_DEVICE_NOT_READY
;
1027 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1029 if (This
->ClockFileObject
)
1031 /* clock is available */
1032 *Interface
= (PIKSREFERENCECLOCK
)&This
->lpVtblReferenceClock
;
1033 Status
= STATUS_SUCCESS
;
1036 *Interface
= (PIKSREFERENCECLOCK
)&This
->lpVtblReferenceClock
;
1037 Status
= STATUS_SUCCESS
;
1039 DPRINT("KsPinGetReferenceClockInterface Pin %p Interface %p Status %x\n", Pin
, Interface
, Status
);
1049 KsPinRegisterFrameReturnCallback(
1051 IN PFNKSPINFRAMERETURN FrameReturn
)
1053 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1055 /* register frame return callback */
1056 This
->FrameReturn
= FrameReturn
;
1064 KsPinRegisterHandshakeCallback(
1066 IN PFNKSPINHANDSHAKE Handshake
)
1068 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1070 /* register private protocol handshake callback */
1071 This
->Handshake
= Handshake
;
1079 KsPinRegisterIrpCompletionCallback(
1081 IN PFNKSPINIRPCOMPLETION IrpCompletion
)
1083 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1085 /* register irp completion callback */
1086 This
->IrpCompletion
= IrpCompletion
;
1094 KsPinRegisterPowerCallbacks(
1096 IN PFNKSPINPOWER Sleep OPTIONAL
,
1097 IN PFNKSPINPOWER Wake OPTIONAL
)
1099 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1101 /* register power callbacks */
1102 This
->Sleep
= Sleep
;
1111 KsPinReleaseProcessingMutex(
1114 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1116 /* release processing mutex */
1117 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
1129 PKSIOBJECT_HEADER ObjectHeader
;
1131 PKSBASIC_HEADER Header
;
1132 PIO_STACK_LOCATION IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1134 DPRINT("KsGetPinFromIrp\n");
1136 /* get object header */
1137 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
1142 Pin
= (PKSPIN
)ObjectHeader
->ObjectType
;
1143 Header
= (PKSBASIC_HEADER
)((ULONG_PTR
)Pin
- sizeof(KSBASIC_HEADER
));
1146 ASSERT(Header
->Type
== KsObjectTypePin
);
1148 /* return object type */
1159 KsPinSetPinClockTime(
1173 IN PVOID Data OPTIONAL
,
1174 IN ULONG Size OPTIONAL
,
1175 IN PKSSTREAM_HEADER StreamHeader OPTIONAL
,
1176 IN PVOID Context OPTIONAL
)
1179 return STATUS_UNSUCCESSFUL
;
1188 KsPinSubmitFrameMdl(
1190 IN PMDL Mdl OPTIONAL
,
1191 IN PKSSTREAM_HEADER StreamHeader OPTIONAL
,
1192 IN PVOID Context OPTIONAL
)
1195 return STATUS_UNSUCCESSFUL
;
1205 IN PKSPROCESSPIN ProcessPin
)
1212 IKsPin_PrepareStreamHeader(
1213 IN IKsPinImpl
* This
,
1214 IN PKSISTREAM_POINTER StreamPointer
)
1216 PKSSTREAM_HEADER Header
;
1220 StreamPointer
->Irp
= KsRemoveIrpFromCancelableQueue(&This
->IrpList
, &This
->IrpListLock
, KsListEntryHead
, KsAcquireAndRemoveOnlySingleItem
);
1221 if (!StreamPointer
->Irp
)
1223 /* run out of mappings */
1224 DPRINT("OutOfMappings\n");
1225 return STATUS_DEVICE_NOT_READY
;
1228 InterlockedDecrement(&This
->IrpCount
);
1230 /* get stream header */
1231 if (StreamPointer
->Irp
->RequestorMode
== UserMode
)
1232 Header
= (PKSSTREAM_HEADER
)StreamPointer
->Irp
->AssociatedIrp
.SystemBuffer
;
1234 Header
= (PKSSTREAM_HEADER
)StreamPointer
->Irp
->UserBuffer
;
1236 /* initialize stream pointer */
1237 StreamPointer
->Callback
= NULL
;
1238 StreamPointer
->Length
= max(Header
->DataUsed
, Header
->FrameExtent
);
1239 StreamPointer
->Next
= NULL
;
1240 StreamPointer
->Offset
= 0;
1241 StreamPointer
->Pin
= &This
->Pin
;
1242 StreamPointer
->Data
= Header
->Data
;
1244 StreamPointer
->StreamPointer
.Context
= NULL
;
1245 StreamPointer
->StreamPointer
.Pin
= &This
->Pin
;
1246 StreamPointer
->StreamPointer
.StreamHeader
= Header
;
1248 if (This
->Pin
.Descriptor
->PinDescriptor
.DataFlow
== KSPIN_DATAFLOW_IN
)
1249 StreamPointer
->StreamPointer
.Offset
= &StreamPointer
->StreamPointer
.OffsetIn
;
1251 StreamPointer
->StreamPointer
.Offset
= &StreamPointer
->StreamPointer
.OffsetOut
;
1253 StreamPointer
->StreamPointer
.Offset
->Alignment
= 0;
1254 StreamPointer
->StreamPointer
.Offset
->Count
= 0;
1255 StreamPointer
->StreamPointer
.Offset
->Data
= NULL
;
1256 StreamPointer
->StreamPointer
.Offset
->Remaining
= 0;
1258 ASSERT(StreamPointer
->StreamPointer
.Offset
->Remaining
== 0);
1260 //StreamPointer->Offset += StreamPointer->StreamPointer.Offset->Count;
1262 ASSERT(StreamPointer
->Length
> StreamPointer
->Offset
);
1263 ASSERT(StreamPointer
->StreamPointer
.StreamHeader
);
1264 ASSERT(This
->FrameSize
);
1266 /* calculate length */
1267 /* TODO split into frames */
1268 Length
= StreamPointer
->Length
;
1273 StreamPointer
->StreamPointer
.Offset
->Alignment
= 0;
1274 StreamPointer
->StreamPointer
.Context
= NULL
;
1275 StreamPointer
->StreamPointer
.Pin
= &This
->Pin
;
1276 StreamPointer
->StreamPointer
.Offset
->Count
= Length
;
1277 StreamPointer
->StreamPointer
.Offset
->Remaining
= Length
;
1278 StreamPointer
->StreamPointer
.Offset
->Data
= (PVOID
)((ULONG_PTR
)StreamPointer
->Data
+ StreamPointer
->Offset
);
1279 StreamPointer
->StreamPointer
.StreamHeader
->FrameExtent
= Length
;
1280 if (StreamPointer
->StreamPointer
.StreamHeader
->DataUsed
)
1281 StreamPointer
->StreamPointer
.StreamHeader
->DataUsed
= Length
;
1283 StreamPointer
->StreamPointer
.StreamHeader
->Data
= StreamPointer
->StreamPointer
.Offset
->Data
;
1285 return STATUS_SUCCESS
;
1295 KsPinGetLeadingEdgeStreamPointer(
1297 IN KSSTREAM_POINTER_STATE State
)
1302 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1304 DPRINT("KsPinGetLeadingEdgeStreamPointer Pin %p State %x Count %lu Remaining %lu\n", Pin
, State
,
1305 This
->LeadingEdgeStreamPointer
.Length
,
1306 This
->LeadingEdgeStreamPointer
.Offset
);
1309 ASSERT(State
== KSSTREAM_POINTER_STATE_LOCKED
);
1311 if (State
== KSSTREAM_POINTER_STATE_LOCKED
)
1313 if (!This
->LeadingEdgeStreamPointer
.Irp
|| This
->LeadingEdgeStreamPointer
.StreamPointer
.Offset
->Remaining
== 0)
1315 Status
= IKsPin_PrepareStreamHeader(This
, &This
->LeadingEdgeStreamPointer
);
1316 if (!NT_SUCCESS(Status
))
1320 DPRINT("KsPinGetLeadingEdgeStreamPointer NewOffset %lu TotalLength %lu\n", This
->LeadingEdgeStreamPointer
.Offset
, This
->LeadingEdgeStreamPointer
.Length
);
1323 return &This
->LeadingEdgeStreamPointer
.StreamPointer
;
1332 KsPinGetTrailingEdgeStreamPointer(
1334 IN KSSTREAM_POINTER_STATE State
)
1346 KsStreamPointerSetStatusCode(
1347 IN PKSSTREAM_POINTER StreamPointer
,
1351 return STATUS_UNSUCCESSFUL
;
1360 KsStreamPointerLock(
1361 IN PKSSTREAM_POINTER StreamPointer
)
1364 return STATUS_UNSUCCESSFUL
;
1373 KsStreamPointerUnlock(
1374 IN PKSSTREAM_POINTER StreamPointer
,
1378 DPRINT("KsStreamPointerUnlock StreamPointer %pEject %lu\n", StreamPointer
, Eject
);
1388 KsStreamPointerAdvanceOffsetsAndUnlock(
1389 IN PKSSTREAM_POINTER StreamPointer
,
1394 DPRINT("KsStreamPointerAdvanceOffsets InUsed %lu OutUsed %lu Eject %lu\n", InUsed
, OutUsed
, Eject
);
1405 KsStreamPointerDelete(
1406 IN PKSSTREAM_POINTER StreamPointer
)
1409 PKSISTREAM_POINTER Cur
, Last
;
1410 PKSISTREAM_POINTER Pointer
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1412 DPRINT("KsStreamPointerDelete %p\n", Pointer
);
1414 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pointer
->StreamPointer
.Pin
, IKsPinImpl
, Pin
);
1416 /* point to first stream pointer */
1418 Cur
= This
->ClonedStreamPointer
;
1420 while(Cur
!= Pointer
&& Cur
)
1423 /* iterate to next cloned pointer */
1429 /* you naughty driver */
1435 /* remove first cloned pointer */
1436 This
->ClonedStreamPointer
= Pointer
->Next
;
1440 Last
->Next
= Pointer
->Next
;
1443 /* FIXME make sure no timeouts are pending */
1453 KsStreamPointerClone(
1454 IN PKSSTREAM_POINTER StreamPointer
,
1455 IN PFNKSSTREAMPOINTER CancelCallback OPTIONAL
,
1456 IN ULONG ContextSize
,
1457 OUT PKSSTREAM_POINTER
* CloneStreamPointer
)
1460 PKSISTREAM_POINTER CurFrame
;
1461 PKSISTREAM_POINTER NewFrame
;
1466 DPRINT("KsStreamPointerClone StreamPointer %p CancelCallback %p ContextSize %p CloneStreamPointer %p\n", StreamPointer
, CancelCallback
, ContextSize
, CloneStreamPointer
);
1468 /* get stream pointer */
1469 CurFrame
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1471 /* calculate context size */
1472 Size
= sizeof(KSISTREAM_POINTER
) + ContextSize
;
1474 /* allocate new stream pointer */
1475 NewFrame
= (PKSISTREAM_POINTER
)ExAllocatePool(NonPagedPool
, Size
);
1478 return STATUS_INSUFFICIENT_RESOURCES
;
1480 /* get current irp stack location */
1481 RefCount
= (ULONG
)CurFrame
->Irp
->Tail
.Overlay
.DriverContext
[0];
1483 /* increment reference count */
1485 CurFrame
->Irp
->Tail
.Overlay
.DriverContext
[0] = (PVOID
)RefCount
;
1487 /* copy stream pointer */
1488 RtlMoveMemory(NewFrame
, CurFrame
, sizeof(KSISTREAM_POINTER
));
1491 This
= (IKsPinImpl
*)CONTAINING_RECORD(CurFrame
->Pin
, IKsPinImpl
, Pin
);
1493 /* prepare stream header in case required */
1494 if (CurFrame
->StreamPointer
.Offset
->Remaining
== 0)
1496 Status
= IKsPin_PrepareStreamHeader(This
, NewFrame
);
1497 if (!NT_SUCCESS(Status
))
1500 return STATUS_DEVICE_NOT_READY
;
1505 NewFrame
->StreamPointer
.Context
= (NewFrame
+ 1);
1508 if (This
->Pin
.Descriptor
->PinDescriptor
.DataFlow
== KSPIN_DATAFLOW_IN
)
1509 NewFrame
->StreamPointer
.Offset
= &NewFrame
->StreamPointer
.OffsetIn
;
1511 NewFrame
->StreamPointer
.Offset
= &NewFrame
->StreamPointer
.OffsetOut
;
1515 NewFrame
->StreamPointer
.Pin
= &This
->Pin
;
1517 ASSERT(NewFrame
->StreamPointer
.Pin
);
1518 ASSERT(NewFrame
->StreamPointer
.Context
);
1519 ASSERT(NewFrame
->StreamPointer
.Offset
);
1520 ASSERT(NewFrame
->StreamPointer
.StreamHeader
);
1523 *CloneStreamPointer
= &NewFrame
->StreamPointer
;
1525 DPRINT("KsStreamPointerClone CloneStreamPointer %p\n", *CloneStreamPointer
);
1527 return STATUS_SUCCESS
;
1536 KsStreamPointerAdvanceOffsets(
1537 IN PKSSTREAM_POINTER StreamPointer
,
1542 PKSISTREAM_POINTER CurFrame
;
1546 DPRINT("KsStreamPointerAdvanceOffsets StreamPointer %p InUsed %lu OutUsed %lu Eject %lu\n", StreamPointer
, InUsed
, OutUsed
, Eject
);
1548 /* get stream pointer */
1549 CurFrame
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1552 This
= (IKsPinImpl
*)CONTAINING_RECORD(CurFrame
->Pin
, IKsPinImpl
, Pin
);
1555 ASSERT(InUsed
== 0);
1559 DPRINT("KsStreamPointerAdvanceOffsets Offset %lu Length %lu NewOffset %lu Remaining %lu LeadingEdge %p DataUsed %lu\n", CurFrame
->Offset
, CurFrame
->Length
, CurFrame
->Offset
+ OutUsed
,
1560 CurFrame
->StreamPointer
.OffsetOut
.Remaining
, &This
->LeadingEdgeStreamPointer
.StreamPointer
, CurFrame
->StreamPointer
.StreamHeader
->DataUsed
);
1563 if (This
->Pin
.Descriptor
->PinDescriptor
.DataFlow
== KSPIN_DATAFLOW_IN
)
1565 ASSERT(CurFrame
->StreamPointer
.OffsetIn
.Remaining
>= InUsed
);
1566 CurFrame
->StreamPointer
.OffsetIn
.Remaining
-= InUsed
;
1567 CurFrame
->StreamPointer
.OffsetIn
.Data
= (PVOID
)((ULONG_PTR
)CurFrame
->StreamPointer
.OffsetIn
.Data
+ InUsed
);
1571 if (!CurFrame
->StreamPointer
.OffsetOut
.Remaining
)
1573 Status
= IKsPin_PrepareStreamHeader(This
, CurFrame
);
1574 if (!NT_SUCCESS(Status
))
1576 return STATUS_DEVICE_NOT_READY
;
1581 ASSERT(CurFrame
->StreamPointer
.OffsetOut
.Remaining
>= OutUsed
);
1582 CurFrame
->StreamPointer
.OffsetOut
.Remaining
-= OutUsed
;
1583 CurFrame
->StreamPointer
.OffsetOut
.Data
= (PVOID
)((ULONG_PTR
)CurFrame
->StreamPointer
.OffsetOut
.Data
+ OutUsed
);
1587 return STATUS_SUCCESS
;
1596 KsStreamPointerAdvance(
1597 IN PKSSTREAM_POINTER StreamPointer
)
1601 return STATUS_NOT_IMPLEMENTED
;
1610 KsStreamPointerGetMdl(
1611 IN PKSSTREAM_POINTER StreamPointer
)
1623 KsStreamPointerGetIrp(
1624 IN PKSSTREAM_POINTER StreamPointer
,
1625 OUT PBOOLEAN FirstFrameInIrp OPTIONAL
,
1626 OUT PBOOLEAN LastFrameInIrp OPTIONAL
)
1638 KsStreamPointerScheduleTimeout(
1639 IN PKSSTREAM_POINTER StreamPointer
,
1640 IN PFNKSSTREAMPOINTER Callback
,
1641 IN ULONGLONG Interval
)
1643 LARGE_INTEGER DueTime
;
1644 PKSISTREAM_POINTER Pointer
;
1646 /* get stream pointer */
1647 Pointer
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1649 /* setup timer callback */
1650 Pointer
->Callback
= Callback
;
1652 /* setup expiration */
1653 DueTime
.QuadPart
= (LONGLONG
)Interval
;
1655 /* setup the timer */
1656 KeSetTimer(&Pointer
->Timer
, DueTime
, &Pointer
->TimerDpc
);
1666 KsStreamPointerCancelTimeout(
1667 IN PKSSTREAM_POINTER StreamPointer
)
1669 PKSISTREAM_POINTER Pointer
;
1671 /* get stream pointer */
1672 Pointer
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1674 KeCancelTimer(&Pointer
->Timer
);
1684 KsPinGetFirstCloneStreamPointer(
1689 DPRINT("KsPinGetFirstCloneStreamPointer %p\n", Pin
);
1691 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
1692 /* return first cloned stream pointer */
1693 return &This
->ClonedStreamPointer
->StreamPointer
;
1702 KsStreamPointerGetNextClone(
1703 IN PKSSTREAM_POINTER StreamPointer
)
1705 PKSISTREAM_POINTER Pointer
;
1707 DPRINT("KsStreamPointerGetNextClone\n");
1709 /* get stream pointer */
1710 Pointer
= (PKSISTREAM_POINTER
)CONTAINING_RECORD(StreamPointer
, KSISTREAM_POINTER
, StreamPointer
);
1713 /* is there a another cloned stream pointer */
1717 /* return next stream pointer */
1718 return &Pointer
->Next
->StreamPointer
;
1723 IKsPin_PinCentricWorker(
1727 IKsPinImpl
* This
= (IKsPinImpl
*)Parameter
;
1729 DPRINT("IKsPin_PinCentricWorker\n");
1733 ASSERT(This
->Pin
.Descriptor
);
1734 ASSERT(This
->Pin
.Descriptor
->Dispatch
);
1735 ASSERT(This
->Pin
.Descriptor
->Dispatch
->Process
);
1736 ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL
);
1737 ASSERT(!(This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_DISPATCH_LEVEL_PROCESSING
));
1738 ASSERT(!(This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_GENERATE_MAPPINGS
));
1742 DPRINT("IKsPin_PinCentricWorker calling Pin Process Routine\n");
1744 Status
= This
->Pin
.Descriptor
->Dispatch
->Process(&This
->Pin
);
1745 DPRINT("IKsPin_PinCentricWorker Status %lx, Offset %lu Length %lu\n", Status
,
1746 This
->LeadingEdgeStreamPointer
.Offset
,
1747 This
->LeadingEdgeStreamPointer
.Length
);
1750 }while(This
->IrpCount
);
1756 IKsPin_DispatchKsStream(
1757 PDEVICE_OBJECT DeviceObject
,
1761 PKSPROCESSPIN_INDEXENTRY ProcessPinIndex
;
1762 PKSSTREAM_HEADER Header
;
1765 PIO_STACK_LOCATION IoStack
;
1766 NTSTATUS Status
= STATUS_SUCCESS
;
1768 DPRINT("IKsPin_DispatchKsStream\n");
1770 /* FIXME handle reset states */
1771 ASSERT(This
->Pin
.ResetState
== KSRESET_END
);
1773 /* get current stack location */
1774 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1776 /* probe stream pointer */
1777 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_WRITE_STREAM
)
1778 Status
= KsProbeStreamIrp(Irp
, KSSTREAM_WRITE
| KSPROBE_ALLOCATEMDL
| KSPROBE_PROBEANDLOCK
| KSPROBE_SYSTEMADDRESS
, This
->Pin
.StreamHeaderSize
);
1780 Status
= KsProbeStreamIrp(Irp
, KSSTREAM_READ
| KSPROBE_ALLOCATEMDL
| KSPROBE_PROBEANDLOCK
| KSPROBE_SYSTEMADDRESS
, This
->Pin
.StreamHeaderSize
);
1782 if (!NT_SUCCESS(Status
))
1784 DPRINT1("KsProbeStreamIrp failed with %x\n", Status
);
1786 Irp
->IoStatus
.Status
= Status
;
1787 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1791 if (Irp
->RequestorMode
== UserMode
)
1792 Header
= (PKSSTREAM_HEADER
)Irp
->AssociatedIrp
.SystemBuffer
;
1794 Header
= (PKSSTREAM_HEADER
)Irp
->UserBuffer
;
1798 DPRINT("NoHeader Canceling Irp %p\n", Irp
);
1799 Irp
->IoStatus
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
1800 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1804 /* calculate num headers */
1805 NumHeaders
= IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
/ Header
->Size
;
1807 /* assume headers of same length */
1808 ASSERT(IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
% Header
->Size
== 0);
1810 /* FIXME support multiple stream headers */
1811 ASSERT(NumHeaders
== 1);
1813 if (Irp
->RequestorMode
== UserMode
)
1815 /* prepare header */
1816 ASSERT(Irp
->MdlAddress
);
1817 Header
->Data
= MmGetSystemAddressForMdlSafe(Irp
->MdlAddress
, NormalPagePriority
);
1821 DPRINT("NoHeader->Data Canceling Irp %p\n", Irp
);
1822 Irp
->IoStatus
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
1823 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1831 if (This
->Pin
.Descriptor
->Dispatch
->Process
)
1833 /* it is a pin centric avstream */
1835 /* mark irp as pending */
1836 IoMarkIrpPending(Irp
);
1838 /* add irp to cancelable queue */
1839 KsAddIrpToCancelableQueue(&This
->IrpList
, &This
->IrpListLock
, Irp
, KsListEntryTail
, NULL
/* FIXME */);
1842 ASSERT(!(This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_DISPATCH_LEVEL_PROCESSING
));
1843 ASSERT(This
->PinWorker
);
1845 InterlockedIncrement(&This
->IrpCount
);
1847 DPRINT("IKsPin_DispatchKsStream IrpCount %lu\n", This
->IrpCount
);
1849 /* start the processing loop */
1850 KsIncrementCountedWorker(This
->PinWorker
);
1852 Status
= STATUS_PENDING
;
1856 /* filter-centric avstream */
1857 ASSERT(This
->Filter
);
1859 ProcessPinIndex
= This
->Filter
->lpVtbl
->GetProcessDispatch(This
->Filter
);
1860 Filter
= This
->Filter
->lpVtbl
->GetStruct(This
->Filter
);
1862 ASSERT(ProcessPinIndex
);
1864 ASSERT(Filter
->Descriptor
);
1865 ASSERT(Filter
->Descriptor
->Dispatch
);
1867 if (!Filter
->Descriptor
->Dispatch
->Process
)
1869 /* invalid device request */
1870 DPRINT("Filter Centric Processing No Process Routine\n");
1871 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1872 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1873 return STATUS_UNSUCCESSFUL
;
1876 /* mark irp as pending */
1877 IoMarkIrpPending(Irp
);
1879 /* add irp to cancelable queue */
1880 KsAddIrpToCancelableQueue(&This
->IrpList
, &This
->IrpListLock
, Irp
, KsListEntryTail
, NULL
/* FIXME */);
1882 Status
= Filter
->Descriptor
->Dispatch
->Process(Filter
, ProcessPinIndex
);
1884 DPRINT("IKsPin_DispatchKsStream FilterCentric: Status %lx \n", Status
);
1893 IKsPin_DispatchKsProperty(
1894 PDEVICE_OBJECT DeviceObject
,
1899 PKSPROPERTY Property
;
1900 PIO_STACK_LOCATION IoStack
;
1901 UNICODE_STRING GuidString
;
1902 ULONG PropertySetsCount
= 0, PropertyItemSize
= 0;
1903 const KSPROPERTY_SET
* PropertySets
= NULL
;
1906 ASSERT(This
->Pin
.Descriptor
);
1908 /* get current irp stack */
1909 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1912 if (This
->Pin
.Descriptor
->AutomationTable
)
1914 /* use available driver property sets */
1915 PropertySetsCount
= This
->Pin
.Descriptor
->AutomationTable
->PropertySetsCount
;
1916 PropertySets
= This
->Pin
.Descriptor
->AutomationTable
->PropertySets
;
1917 PropertyItemSize
= This
->Pin
.Descriptor
->AutomationTable
->PropertyItemSize
;
1921 /* try driver provided property sets */
1922 Status
= KspPropertyHandler(Irp
,
1928 if (Status
!= STATUS_NOT_FOUND
)
1930 /* property was handled by driver */
1931 if (Status
!= STATUS_PENDING
)
1933 Irp
->IoStatus
.Status
= Status
;
1934 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1939 /* try our properties */
1940 Status
= KspPropertyHandler(Irp
,
1941 sizeof(PinPropertySet
) / sizeof(KSPROPERTY_SET
),
1946 if (Status
!= STATUS_NOT_FOUND
)
1948 /* property was handled by driver */
1949 if (Status
!= STATUS_PENDING
)
1951 Irp
->IoStatus
.Status
= Status
;
1952 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1957 /* property was not handled */
1958 Property
= (PKSPROPERTY
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1960 RtlStringFromGUID(&Property
->Set
, &GuidString
);
1961 DPRINT("IKsPin_DispatchKsProperty Unhandled property Set |%S| Id %u Flags %x\n", GuidString
.Buffer
, Property
->Id
, Property
->Flags
);
1962 RtlFreeUnicodeString(&GuidString
);
1964 Irp
->IoStatus
.Status
= STATUS_NOT_FOUND
;
1965 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1967 return STATUS_NOT_FOUND
;
1973 IKsPin_DispatchDeviceIoControl(
1974 IN PDEVICE_OBJECT DeviceObject
,
1977 PIO_STACK_LOCATION IoStack
;
1978 PKSIOBJECT_HEADER ObjectHeader
;
1981 /* get current irp stack */
1982 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1985 ASSERT(IoStack
->FileObject
);
1986 ASSERT(IoStack
->FileObject
->FsContext2
);
1988 /* get the object header */
1989 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
1991 /* locate ks pin implemention from KSPIN offset */
1992 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
1994 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_PROPERTY
)
1996 /* handle ks properties */
1997 return IKsPin_DispatchKsProperty(DeviceObject
, Irp
, This
);
2000 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_WRITE_STREAM
||
2001 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_READ_STREAM
)
2003 /* handle ks properties */
2004 return IKsPin_DispatchKsStream(DeviceObject
, Irp
, This
);
2008 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
2009 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2010 return STATUS_NOT_IMPLEMENTED
;
2016 IN PDEVICE_OBJECT DeviceObject
,
2019 PIO_STACK_LOCATION IoStack
;
2020 PKSIOBJECT_HEADER ObjectHeader
;
2022 NTSTATUS Status
= STATUS_SUCCESS
;
2024 /* get current irp stack */
2025 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2028 ASSERT(IoStack
->FileObject
);
2029 ASSERT(IoStack
->FileObject
->FsContext2
);
2031 /* get the object header */
2032 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
2034 /* locate ks pin implemention fro KSPIN offset */
2035 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
2037 /* acquire filter control mutex */
2038 KsFilterAcquireControl(&This
->Pin
);
2040 if (This
->Pin
.Descriptor
->Dispatch
->Close
)
2042 /* call pin close routine */
2043 Status
= This
->Pin
.Descriptor
->Dispatch
->Close(&This
->Pin
, Irp
);
2045 if (!NT_SUCCESS(Status
))
2048 Irp
->IoStatus
.Status
= Status
;
2049 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2053 /* FIXME remove pin from filter pin list and decrement reference count */
2055 if (Status
!= STATUS_PENDING
)
2057 Irp
->IoStatus
.Status
= Status
;
2058 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2063 /* release filter control mutex */
2064 KsFilterReleaseControl(&This
->Pin
);
2071 IKsPin_DispatchCreateAllocator(
2072 IN PDEVICE_OBJECT DeviceObject
,
2077 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
2078 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2079 return STATUS_NOT_IMPLEMENTED
;
2084 IKsPin_DispatchCreateClock(
2085 IN PDEVICE_OBJECT DeviceObject
,
2089 NTSTATUS Status
= STATUS_SUCCESS
;
2091 KSRESOLUTION Resolution
;
2092 PKSRESOLUTION pResolution
= NULL
;
2093 PKSOBJECT_CREATE_ITEM CreateItem
;
2095 DPRINT("IKsPin_DispatchCreateClock\n");
2097 /* get the create item */
2098 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
2103 /* get the pin object */
2104 Pin
= (PKSPIN
)CreateItem
->Context
;
2109 /* locate ks pin implemention fro KSPIN offset */
2110 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
2113 ASSERT(This
->BasicHeader
.Type
== KsObjectTypePin
);
2114 ASSERT(This
->BasicHeader
.ControlMutex
);
2116 /* acquire control mutex */
2117 KsAcquireControl(Pin
);
2119 if ((This
->Pin
.Descriptor
->PinDescriptor
.Communication
!= KSPIN_COMMUNICATION_NONE
&&
2120 This
->Pin
.Descriptor
->Dispatch
) ||
2121 (This
->Pin
.Descriptor
->Flags
& KSPIN_FLAG_IMPLEMENT_CLOCK
))
2123 if (!This
->DefaultClock
)
2125 if (This
->Pin
.Descriptor
->Dispatch
&& This
->Pin
.Descriptor
->Dispatch
->Clock
)
2127 if (This
->Pin
.Descriptor
->Dispatch
->Clock
->Resolution
)
2129 This
->Pin
.Descriptor
->Dispatch
->Clock
->Resolution(&This
->Pin
, &Resolution
);
2130 pResolution
= &Resolution
;
2133 Status
= KsAllocateDefaultClockEx(&This
->DefaultClock
,
2135 (PFNKSSETTIMER
)This
->Pin
.Descriptor
->Dispatch
->Clock
->SetTimer
,
2136 (PFNKSCANCELTIMER
)This
->Pin
.Descriptor
->Dispatch
->Clock
->CancelTimer
,
2137 (PFNKSCORRELATEDTIME
)This
->Pin
.Descriptor
->Dispatch
->Clock
->CorrelatedTime
,
2143 Status
= KsAllocateDefaultClockEx(&This
->DefaultClock
, (PVOID
)&This
->Pin
, NULL
, NULL
, NULL
, NULL
, 0);
2147 if (NT_SUCCESS(Status
))
2149 Status
= KsCreateDefaultClock(Irp
, This
->DefaultClock
);
2153 DPRINT("IKsPin_DispatchCreateClock %lx\n", Status
);
2155 /* release control mutex */
2156 KsReleaseControl(Pin
);
2159 Irp
->IoStatus
.Status
= Status
;
2160 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2166 IKsPin_DispatchCreateNode(
2167 IN PDEVICE_OBJECT DeviceObject
,
2172 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
2173 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2174 return STATUS_NOT_IMPLEMENTED
;
2177 static KSDISPATCH_TABLE PinDispatchTable
=
2179 IKsPin_DispatchDeviceIoControl
,
2180 KsDispatchInvalidDeviceRequest
,
2181 KsDispatchInvalidDeviceRequest
,
2182 KsDispatchInvalidDeviceRequest
,
2184 KsDispatchQuerySecurity
,
2185 KsDispatchSetSecurity
,
2186 KsDispatchFastIoDeviceControlFailure
,
2187 KsDispatchFastReadFailure
,
2188 KsDispatchFastReadFailure
2193 IN PDEVICE_OBJECT DeviceObject
,
2195 IN PKSDEVICE KsDevice
,
2196 IN IKsFilterFactory
* FilterFactory
,
2197 IN IKsFilter
* Filter
,
2198 IN PKSPIN_CONNECT Connect
,
2199 IN KSPIN_DESCRIPTOR_EX
* Descriptor
)
2202 PIO_STACK_LOCATION IoStack
;
2204 PDEVICE_EXTENSION DeviceExtension
;
2205 PKSOBJECT_CREATE_ITEM CreateItem
;
2207 PKSDATAFORMAT DataFormat
;
2208 PKSBASIC_HEADER BasicHeader
;
2210 ULONG FrameSize
= 0;
2211 ULONG NumFrames
= 0;
2214 ASSERT(Descriptor
->Dispatch
);
2216 DPRINT("KspCreatePin PinId %lu Flags %x\n", Connect
->PinId
, Descriptor
->Flags
);
2218 //Output Pin: KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY
2219 //Input Pin: KSPIN_FLAG_FIXED_FORMAT|KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT|KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING
2222 if (Descriptor
->AllocatorFraming
)
2224 DPRINT("KspCreatePin Dataflow %lu\n", Descriptor
->PinDescriptor
.DataFlow
);
2225 DPRINT("KspCreatePin CountItems %lu\n", Descriptor
->AllocatorFraming
->CountItems
);
2226 DPRINT("KspCreatePin PinFlags %lx\n", Descriptor
->AllocatorFraming
->PinFlags
);
2227 DPRINT("KspCreatePin OutputCompression RatioNumerator %lu RatioDenominator %lu RatioConstantMargin %lu\n", Descriptor
->AllocatorFraming
->OutputCompression
.RatioNumerator
,
2228 Descriptor
->AllocatorFraming
->OutputCompression
.RatioDenominator
, Descriptor
->AllocatorFraming
->OutputCompression
.RatioConstantMargin
);
2229 DPRINT("KspCreatePin PinWeight %lx\n", Descriptor
->AllocatorFraming
->PinWeight
);
2231 for(Index
= 0; Index
< Descriptor
->AllocatorFraming
->CountItems
; Index
++)
2233 DPRINT("KspCreatePin Index %lu MemoryFlags %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].MemoryFlags
);
2234 DPRINT("KspCreatePin Index %lu BusFlags %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].BusFlags
);
2235 DPRINT("KspCreatePin Index %lu Flags %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].Flags
);
2236 DPRINT("KspCreatePin Index %lu Frames %lu\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].Frames
);
2237 DPRINT("KspCreatePin Index %lu FileAlignment %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].FileAlignment
);
2238 DPRINT("KspCreatePin Index %lu MemoryTypeWeight %lx\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].MemoryTypeWeight
);
2239 DPRINT("KspCreatePin Index %lu PhysicalRange MinFrameSize %lu MaxFrameSize %lu Stepping %lu\n", Index
, Descriptor
->AllocatorFraming
->FramingItem
[Index
].PhysicalRange
.MinFrameSize
,
2240 Descriptor
->AllocatorFraming
->FramingItem
[Index
].PhysicalRange
.MaxFrameSize
,
2241 Descriptor
->AllocatorFraming
->FramingItem
[Index
].PhysicalRange
.Stepping
);
2243 DPRINT("KspCreatePin Index %lu FramingRange MinFrameSize %lu MaxFrameSize %lu Stepping %lu InPlaceWeight %lu NotInPlaceWeight %lu\n",
2245 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.Range
.MinFrameSize
,
2246 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.Range
.MaxFrameSize
,
2247 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.Range
.Stepping
,
2248 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.InPlaceWeight
,
2249 Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.NotInPlaceWeight
);
2251 FrameSize
= Descriptor
->AllocatorFraming
->FramingItem
[Index
].FramingRange
.Range
.MaxFrameSize
;
2252 NumFrames
= Descriptor
->AllocatorFraming
->FramingItem
[Index
].Frames
;
2258 /* default to 50 * 188 (MPEG2 TS packet size) */
2267 /* get current irp stack */
2268 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2270 /* get device extension */
2271 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
2273 /* get ks device interface */
2274 Device
= (IKsDevice
*)&DeviceExtension
->DeviceHeader
->lpVtblIKsDevice
;
2276 /* first allocate pin ctx */
2277 This
= AllocateItem(NonPagedPool
, sizeof(IKsPinImpl
));
2280 /* not enough memory */
2281 return STATUS_INSUFFICIENT_RESOURCES
;
2284 /* allocate create item */
2285 CreateItem
= AllocateItem(NonPagedPool
, sizeof(KSOBJECT_CREATE_ITEM
) * 3);
2288 /* not enough memory */
2290 DPRINT("KspCreatePin OutOfMemory\n");
2291 return STATUS_INSUFFICIENT_RESOURCES
;
2294 /* initialize basic header */
2295 This
->BasicHeader
.KsDevice
= KsDevice
;
2296 This
->BasicHeader
.Type
= KsObjectTypePin
;
2297 This
->BasicHeader
.Parent
.KsFilter
= Filter
->lpVtbl
->GetStruct(Filter
);
2299 ASSERT(This
->BasicHeader
.Parent
.KsFilter
);
2301 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)This
->BasicHeader
.Parent
.KsFilter
- sizeof(KSBASIC_HEADER
));
2303 This
->BasicHeader
.ControlMutex
= BasicHeader
->ControlMutex
;
2304 ASSERT(This
->BasicHeader
.ControlMutex
);
2306 InitializeListHead(&This
->BasicHeader
.EventList
);
2307 KeInitializeSpinLock(&This
->BasicHeader
.EventListLock
);
2309 /* initialize pin */
2310 This
->lpVtbl
= &vt_IKsPin
;
2311 This
->FrameSize
= FrameSize
;
2312 This
->NumFrames
= NumFrames
;
2313 This
->lpVtblReferenceClock
= &vt_ReferenceClock
;
2315 This
->FileObject
= IoStack
->FileObject
;
2316 This
->Filter
= Filter
;
2317 KeInitializeMutex(&This
->ProcessingMutex
, 0);
2318 InitializeListHead(&This
->IrpList
);
2319 KeInitializeSpinLock(&This
->IrpListLock
);
2321 /* allocate object bag */
2322 This
->Pin
.Bag
= AllocateItem(NonPagedPool
, sizeof(KSIOBJECT_BAG
));
2325 /* not enough memory */
2327 FreeItem(CreateItem
);
2328 return STATUS_INSUFFICIENT_RESOURCES
;
2331 /* initialize object bag */
2332 Device
->lpVtbl
->InitializeObjectBag(Device
, This
->Pin
.Bag
, NULL
);
2335 DataFormat
= (PKSDATAFORMAT
)(Connect
+ 1);
2337 /* initialize pin descriptor */
2338 This
->Pin
.Descriptor
= Descriptor
;
2339 This
->Pin
.Context
= NULL
;
2340 This
->Pin
.Id
= Connect
->PinId
;
2341 This
->Pin
.Communication
= Descriptor
->PinDescriptor
.Communication
;
2342 This
->Pin
.ConnectionIsExternal
= FALSE
; //FIXME
2343 RtlMoveMemory(&This
->Pin
.ConnectionInterface
, &Connect
->Interface
, sizeof(KSPIN_INTERFACE
));
2344 RtlMoveMemory(&This
->Pin
.ConnectionMedium
, &Connect
->Medium
, sizeof(KSPIN_MEDIUM
));
2345 RtlMoveMemory(&This
->Pin
.ConnectionPriority
, &Connect
->Priority
, sizeof(KSPRIORITY
));
2347 /* allocate format */
2348 Status
= _KsEdit(This
->Pin
.Bag
, (PVOID
*)&This
->Pin
.ConnectionFormat
, DataFormat
->FormatSize
, DataFormat
->FormatSize
, 0);
2349 if (!NT_SUCCESS(Status
))
2351 /* failed to allocate format */
2352 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2354 FreeItem(CreateItem
);
2355 return STATUS_INSUFFICIENT_RESOURCES
;
2359 RtlMoveMemory((PVOID
)This
->Pin
.ConnectionFormat
, DataFormat
, DataFormat
->FormatSize
);
2361 This
->Pin
.AttributeList
= NULL
; //FIXME
2362 This
->Pin
.StreamHeaderSize
= sizeof(KSSTREAM_HEADER
);
2363 This
->Pin
.DataFlow
= Descriptor
->PinDescriptor
.DataFlow
;
2364 This
->Pin
.DeviceState
= KSSTATE_STOP
;
2365 This
->Pin
.ResetState
= KSRESET_END
;
2366 This
->Pin
.ClientState
= KSSTATE_STOP
;
2368 /* intialize allocator create item */
2369 CreateItem
[0].Context
= (PVOID
)&This
->Pin
;
2370 CreateItem
[0].Create
= IKsPin_DispatchCreateAllocator
;
2371 CreateItem
[0].Flags
= KSCREATE_ITEM_FREEONSTOP
;
2372 RtlInitUnicodeString(&CreateItem
[0].ObjectClass
, KSSTRING_Allocator
);
2374 /* intialize clock create item */
2375 CreateItem
[1].Context
= (PVOID
)&This
->Pin
;
2376 CreateItem
[1].Create
= IKsPin_DispatchCreateClock
;
2377 CreateItem
[1].Flags
= KSCREATE_ITEM_FREEONSTOP
;
2378 RtlInitUnicodeString(&CreateItem
[1].ObjectClass
, KSSTRING_Clock
);
2380 /* intialize topology node create item */
2381 CreateItem
[2].Context
= (PVOID
)&This
->Pin
;
2382 CreateItem
[2].Create
= IKsPin_DispatchCreateNode
;
2383 CreateItem
[2].Flags
= KSCREATE_ITEM_FREEONSTOP
;
2384 RtlInitUnicodeString(&CreateItem
[2].ObjectClass
, KSSTRING_TopologyNode
);
2386 /* now allocate object header */
2387 Status
= KsAllocateObjectHeader((KSOBJECT_HEADER
*)&This
->ObjectHeader
, 3, CreateItem
, Irp
, &PinDispatchTable
);
2388 if (!NT_SUCCESS(Status
))
2390 /* failed to create object header */
2391 DPRINT("KspCreatePin KsAllocateObjectHeader failed %lx\n", Status
);
2392 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2394 FreeItem(CreateItem
);
2396 /* return failure code */
2400 /* add extra info to object header */
2401 This
->ObjectHeader
->Type
= KsObjectTypePin
;
2402 This
->ObjectHeader
->Unknown
= (PUNKNOWN
)&This
->lpVtbl
;
2403 This
->ObjectHeader
->ObjectType
= (PVOID
)&This
->Pin
;
2405 if (!Descriptor
->Dispatch
|| !Descriptor
->Dispatch
->Process
)
2407 /* the pin is part of filter-centric processing filter
2408 * add process pin to filter
2410 This
->ProcessPin
.BytesAvailable
= 0;
2411 This
->ProcessPin
.BytesUsed
= 0;
2412 This
->ProcessPin
.CopySource
= NULL
;
2413 This
->ProcessPin
.Data
= NULL
;
2414 This
->ProcessPin
.DelegateBranch
= NULL
;
2415 This
->ProcessPin
.Flags
= 0;
2416 This
->ProcessPin
.InPlaceCounterpart
= NULL
;
2417 This
->ProcessPin
.Pin
= &This
->Pin
;
2418 This
->ProcessPin
.StreamPointer
= (PKSSTREAM_POINTER
)&This
->LeadingEdgeStreamPointer
.StreamPointer
;
2419 This
->ProcessPin
.Terminate
= FALSE
;
2421 Status
= Filter
->lpVtbl
->AddProcessPin(Filter
, &This
->ProcessPin
);
2422 DPRINT("KspCreatePin AddProcessPin %lx\n", Status
);
2424 if (!NT_SUCCESS(Status
))
2426 /* failed to add process pin */
2427 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2428 KsFreeObjectHeader(&This
->ObjectHeader
);
2430 FreeItem(CreateItem
);
2431 /* return failure code */
2435 else if (Descriptor
->Dispatch
&& Descriptor
->Dispatch
->Process
)
2437 /* pin centric processing filter */
2439 /* initialize work item */
2440 ExInitializeWorkItem(&This
->PinWorkQueueItem
, IKsPin_PinCentricWorker
, (PVOID
)This
);
2442 /* allocate counted work item */
2443 Status
= KsRegisterCountedWorker(HyperCriticalWorkQueue
, &This
->PinWorkQueueItem
, &This
->PinWorker
);
2445 if (!NT_SUCCESS(Status
))
2447 DPRINT("Failed to register Worker %lx\n", Status
);
2448 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2449 KsFreeObjectHeader(&This
->ObjectHeader
);
2451 FreeItem(CreateItem
);
2455 if (This
->Pin
.Descriptor
->PinDescriptor
.DataFlow
== KSPIN_DATAFLOW_IN
)
2456 This
->LeadingEdgeStreamPointer
.StreamPointer
.Offset
= &This
->LeadingEdgeStreamPointer
.StreamPointer
.OffsetIn
;
2458 This
->LeadingEdgeStreamPointer
.StreamPointer
.Offset
= &This
->LeadingEdgeStreamPointer
.StreamPointer
.OffsetOut
;
2461 KeInitializeEvent(&This
->FrameComplete
, NotificationEvent
, FALSE
);
2465 /* FIXME add pin instance to filter instance */
2468 if (Descriptor
->Dispatch
&& Descriptor
->Dispatch
->SetDataFormat
)
2470 Status
= Descriptor
->Dispatch
->SetDataFormat(&This
->Pin
, NULL
, NULL
, This
->Pin
.ConnectionFormat
, NULL
);
2471 DPRINT("KspCreatePin SetDataFormat %lx\n", Status
);
2475 /* does the driver have a pin dispatch */
2476 if (Descriptor
->Dispatch
&& Descriptor
->Dispatch
->Create
)
2478 /* now inform the driver to create a new pin */
2479 Status
= Descriptor
->Dispatch
->Create(&This
->Pin
, Irp
);
2480 DPRINT("KspCreatePin DispatchCreate %lx\n", Status
);
2484 DPRINT("KspCreatePin Status %lx\n", Status
);
2486 if (!NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
)
2488 /* failed to create pin, release resources */
2489 KsFreeObjectHeader((KSOBJECT_HEADER
)This
->ObjectHeader
);
2490 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
2493 /* return failure code */