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 KSSTREAM_POINTER StreamPointer
;
15 PFNKSSTREAMPOINTER Callback
;
19 struct _KSISTREAM_POINTER
*Next
;
21 }KSISTREAM_POINTER
, *PKSISTREAM_POINTER
;
25 KSBASIC_HEADER BasicHeader
;
27 PKSIOBJECT_HEADER ObjectHeader
;
28 KSPROCESSPIN ProcessPin
;
34 KMUTEX ProcessingMutex
;
35 PFILE_OBJECT FileObject
;
41 KSPIN_LOCK IrpListLock
;
43 PKSISTREAM_POINTER ClonedStreamPointer
;
44 PKSISTREAM_POINTER LeadingEdgeStreamPointer
;
45 PKSISTREAM_POINTER TrailingStreamPointer
;
49 PFNKSPINHANDSHAKE Handshake
;
50 PFNKSPINFRAMERETURN FrameReturn
;
51 PFNKSPINIRPCOMPLETION IrpCompletion
;
57 IKsPin_fnQueryInterface(
62 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtbl
);
64 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
))
66 *Output
= &This
->lpVtbl
;
67 _InterlockedIncrement(&This
->ref
);
68 return STATUS_SUCCESS
;
70 return STATUS_UNSUCCESSFUL
;
78 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtbl
);
80 return InterlockedIncrement(&This
->ref
);
88 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtbl
);
90 InterlockedDecrement(&This
->ref
);
97 /* Return new reference count */
103 IKsPin_fnTransferKsIrp(
106 IN IKsTransport
**OutTransport
)
109 return STATUS_NOT_IMPLEMENTED
;
114 IKsPin_fnDiscardKsIrp(
117 IN IKsTransport
* *OutTransport
)
127 IN IKsTransport
* TransportIn
,
128 OUT IKsTransport
** OutTransportIn
,
129 OUT IKsTransport
* *OutTransportOut
,
130 IN KSPIN_DATAFLOW DataFlow
)
133 return STATUS_NOT_IMPLEMENTED
;
138 IKsPin_fnSetDeviceState(
142 IN IKsTransport
* *OutTransport
)
145 return STATUS_NOT_IMPLEMENTED
;
150 IKsPin_fnSetResetState(
152 IN KSRESET ResetState
,
153 OUT IKsTransport
* * OutTransportOut
)
160 IKsPin_fnGetTransportConfig(
162 IN
struct KSPTRANSPORTCONFIG
* TransportConfig
,
163 OUT IKsTransport
** OutTransportIn
,
164 OUT IKsTransport
** OutTransportOut
)
167 return STATUS_NOT_IMPLEMENTED
;
172 IKsPin_fnSetTransportConfig(
174 IN
struct KSPTRANSPORTCONFIG
const * TransportConfig
,
175 OUT IKsTransport
** OutTransportIn
,
176 OUT IKsTransport
** OutTransportOut
)
179 return STATUS_NOT_IMPLEMENTED
;
184 IKsPin_fnResetTransportConfig(
186 OUT IKsTransport
** OutTransportIn
,
187 OUT IKsTransport
** OutTransportOut
)
190 return STATUS_NOT_IMPLEMENTED
;
204 IKsPin_fnGetProcessPin(
213 IKsPin_fnAttemptBypass(
217 return STATUS_NOT_IMPLEMENTED
;
222 IKsPin_fnAttemptUnbypass(
226 return STATUS_NOT_IMPLEMENTED
;
231 IKsPin_fnGenerateConnectionEvents(
240 IKsPin_fnClientSetDeviceState(
246 return STATUS_NOT_IMPLEMENTED
;
249 static IKsPinVtbl vt_IKsPin
=
251 IKsPin_fnQueryInterface
,
254 IKsPin_fnTransferKsIrp
,
255 IKsPin_fnDiscardKsIrp
,
257 IKsPin_fnSetDeviceState
,
258 IKsPin_fnSetResetState
,
259 IKsPin_fnGetTransportConfig
,
260 IKsPin_fnSetTransportConfig
,
261 IKsPin_fnResetTransportConfig
,
263 IKsPin_fnGetProcessPin
,
264 IKsPin_fnAttemptBypass
,
265 IKsPin_fnAttemptUnbypass
,
266 IKsPin_fnGenerateConnectionEvents
,
267 IKsPin_fnClientSetDeviceState
271 //==============================================================
278 KsPinAcquireProcessingMutex(
281 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
283 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
293 IN PKSGATE AndGate OPTIONAL
)
295 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
297 /* FIXME attach to filter's and gate (filter-centric processing) */
299 This
->AttachedGate
= AndGate
;
300 This
->OrGate
= FALSE
;
310 IN PKSGATE OrGate OPTIONAL
)
312 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
314 /* FIXME attach to filter's and gate (filter-centric processing) */
316 This
->AttachedGate
= OrGate
;
328 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
330 return This
->AttachedGate
;
338 KsPinAttemptProcessing(
340 IN BOOLEAN Asynchronous
)
350 KsPinGetAvailableByteCount(
352 OUT PLONG InputDataBytes OPTIONAL
,
353 OUT PLONG OutputBufferBytes OPTIONAL
)
356 return STATUS_NOT_IMPLEMENTED
;
364 KsPinGetConnectedFilterInterface(
366 IN
const GUID
* InterfaceId
,
367 OUT PVOID
* Interface
)
370 return STATUS_NOT_IMPLEMENTED
;
378 KsPinGetConnectedPinDeviceObject(
390 KsPinGetConnectedPinFileObject(
402 KsPinGetConnectedPinInterface(
404 IN
const GUID
* InterfaceId
,
405 OUT PVOID
* Interface
)
408 return STATUS_NOT_IMPLEMENTED
;
416 KsPinGetCopyRelationships(
418 OUT PKSPIN
* CopySource
,
419 OUT PKSPIN
* DelegateBranch
)
429 KsPinGetNextSiblingPin(
432 return KsGetNextSibling((PVOID
)Pin
);
440 KsPinGetParentFilter(
443 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
445 /* return parent filter */
446 return This
->BasicHeader
.Parent
.KsFilter
;
454 KsPinGetReferenceClockInterface(
456 OUT PIKSREFERENCECLOCK
* Interface
)
459 return STATUS_UNSUCCESSFUL
;
467 KsPinRegisterFrameReturnCallback(
469 IN PFNKSPINFRAMERETURN FrameReturn
)
471 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
473 /* register frame return callback */
474 This
->FrameReturn
= FrameReturn
;
482 KsPinRegisterHandshakeCallback(
484 IN PFNKSPINHANDSHAKE Handshake
)
486 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
488 /* register private protocol handshake callback */
489 This
->Handshake
= Handshake
;
497 KsPinRegisterIrpCompletionCallback(
499 IN PFNKSPINIRPCOMPLETION IrpCompletion
)
501 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
503 /* register irp completion callback */
504 This
->IrpCompletion
= IrpCompletion
;
512 KsPinRegisterPowerCallbacks(
514 IN PFNKSPINPOWER Sleep OPTIONAL
,
515 IN PFNKSPINPOWER Wake OPTIONAL
)
517 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
519 /* register power callbacks */
529 KsPinReleaseProcessingMutex(
532 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
534 /* release processing mutex */
535 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
547 PKSIOBJECT_HEADER ObjectHeader
;
548 PIO_STACK_LOCATION IoStack
= IoGetCurrentIrpStackLocation(Irp
);
550 /* get object header */
551 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext
;
552 /* return object type */
553 return (PKSPIN
)ObjectHeader
->ObjectType
;
564 KsPinSetPinClockTime(
578 IN PVOID Data OPTIONAL
,
579 IN ULONG Size OPTIONAL
,
580 IN PKSSTREAM_HEADER StreamHeader OPTIONAL
,
581 IN PVOID Context OPTIONAL
)
584 return STATUS_UNSUCCESSFUL
;
595 IN PMDL Mdl OPTIONAL
,
596 IN PKSSTREAM_HEADER StreamHeader OPTIONAL
,
597 IN PVOID Context OPTIONAL
)
600 return STATUS_UNSUCCESSFUL
;
610 IN PKSPROCESSPIN ProcessPin
)
622 KsPinGetLeadingEdgeStreamPointer(
624 IN KSSTREAM_POINTER_STATE State
)
636 KsPinGetTrailingEdgeStreamPointer(
638 IN KSSTREAM_POINTER_STATE State
)
650 KsStreamPointerSetStatusCode(
651 IN PKSSTREAM_POINTER StreamPointer
,
655 return STATUS_UNSUCCESSFUL
;
665 IN PKSSTREAM_POINTER StreamPointer
)
668 return STATUS_UNSUCCESSFUL
;
677 KsStreamPointerUnlock(
678 IN PKSSTREAM_POINTER StreamPointer
,
690 KsStreamPointerAdvanceOffsetsAndUnlock(
691 IN PKSSTREAM_POINTER StreamPointer
,
705 KsStreamPointerDelete(
706 IN PKSSTREAM_POINTER StreamPointer
)
709 PKSISTREAM_POINTER Cur
, Last
;
710 PKSISTREAM_POINTER Pointer
= (PKSISTREAM_POINTER
)StreamPointer
;
712 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pointer
->StreamPointer
.Pin
, IKsPinImpl
, Pin
);
714 /* point to first stream pointer */
716 Cur
= This
->ClonedStreamPointer
;
718 while(Cur
!= Pointer
&& Cur
)
721 /* iterate to next cloned pointer */
727 /* you naughty driver */
733 /* remove first cloned pointer */
734 This
->ClonedStreamPointer
= Pointer
->Next
;
738 Last
->Next
= Pointer
->Next
;
741 /* FIXME make sure no timeouts are pending */
751 KsStreamPointerClone(
752 IN PKSSTREAM_POINTER StreamPointer
,
753 IN PFNKSSTREAMPOINTER CancelCallback OPTIONAL
,
754 IN ULONG ContextSize
,
755 OUT PKSSTREAM_POINTER
* CloneStreamPointer
)
758 return STATUS_NOT_IMPLEMENTED
;
767 KsStreamPointerAdvanceOffsets(
768 IN PKSSTREAM_POINTER StreamPointer
,
774 return STATUS_NOT_IMPLEMENTED
;
783 KsStreamPointerAdvance(
784 IN PKSSTREAM_POINTER StreamPointer
)
787 return STATUS_NOT_IMPLEMENTED
;
796 KsStreamPointerGetMdl(
797 IN PKSSTREAM_POINTER StreamPointer
)
809 KsStreamPointerGetIrp(
810 IN PKSSTREAM_POINTER StreamPointer
,
811 OUT PBOOLEAN FirstFrameInIrp OPTIONAL
,
812 OUT PBOOLEAN LastFrameInIrp OPTIONAL
)
824 KsStreamPointerScheduleTimeout(
825 IN PKSSTREAM_POINTER StreamPointer
,
826 IN PFNKSSTREAMPOINTER Callback
,
827 IN ULONGLONG Interval
)
829 LARGE_INTEGER DueTime
;
830 PKSISTREAM_POINTER Pointer
= (PKSISTREAM_POINTER
)StreamPointer
;
832 /* setup timer callback */
833 Pointer
->Callback
= Callback
;
835 /* setup expiration */
836 DueTime
.QuadPart
= (LONGLONG
)Interval
;
838 /* setup the timer */
839 KeSetTimer(&Pointer
->Timer
, DueTime
, &Pointer
->TimerDpc
);
849 KsStreamPointerCancelTimeout(
850 IN PKSSTREAM_POINTER StreamPointer
)
852 PKSISTREAM_POINTER Pointer
= (PKSISTREAM_POINTER
)StreamPointer
;
854 KeCancelTimer(&Pointer
->Timer
);
864 KsPinGetFirstCloneStreamPointer(
867 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
868 /* return first cloned stream pointer */
869 return &This
->ClonedStreamPointer
->StreamPointer
;
878 KsStreamPointerGetNextClone(
879 IN PKSSTREAM_POINTER StreamPointer
)
881 PKSISTREAM_POINTER Pointer
= (PKSISTREAM_POINTER
)StreamPointer
;
883 /* is there a another cloned stream pointer */
887 /* return next stream pointer */
888 return &Pointer
->Next
->StreamPointer
;
893 IKsPin_DispatchDeviceIoControl(
894 IN PDEVICE_OBJECT DeviceObject
,
897 PIO_STACK_LOCATION IoStack
;
898 PKSIOBJECT_HEADER ObjectHeader
;
900 NTSTATUS Status
= STATUS_SUCCESS
;
902 /* get current irp stack */
903 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
906 ASSERT(IoStack
->FileObject
);
907 ASSERT(IoStack
->FileObject
->FsContext
);
909 /* get the object header */
910 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext
;
912 /* locate ks pin implemention fro KSPIN offset */
913 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
915 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_WRITE_STREAM
&& IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_READ_STREAM
)
918 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
919 Irp
->IoStatus
.Information
= 0;
920 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
921 return STATUS_NOT_IMPLEMENTED
;
924 /* mark irp as pending */
925 IoMarkIrpPending(Irp
);
927 /* add irp to cancelable queue */
928 KsAddIrpToCancelableQueue(&This
->IrpList
, &This
->IrpListLock
, Irp
, KsListEntryTail
, NULL
/* FIXME */);
930 if (This
->Pin
.Descriptor
->Dispatch
->Process
)
932 /* it is a pin centric avstream */
933 Status
= This
->Pin
.Descriptor
->Dispatch
->Process(&This
->Pin
);
940 * filter-centric avstream
951 IN PDEVICE_OBJECT DeviceObject
,
954 PIO_STACK_LOCATION IoStack
;
955 PKSIOBJECT_HEADER ObjectHeader
;
957 NTSTATUS Status
= STATUS_SUCCESS
;
959 /* get current irp stack */
960 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
963 ASSERT(IoStack
->FileObject
);
964 ASSERT(IoStack
->FileObject
->FsContext
);
966 /* get the object header */
967 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext
;
969 /* locate ks pin implemention fro KSPIN offset */
970 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
972 /* acquire filter control mutex */
973 KsFilterAcquireControl(This
->BasicHeader
.Parent
.KsFilter
);
975 if (This
->Pin
.Descriptor
->Dispatch
->Close
)
977 /* call pin close routine */
978 Status
= This
->Pin
.Descriptor
->Dispatch
->Close(&This
->Pin
, Irp
);
980 if (!NT_SUCCESS(Status
))
983 Irp
->IoStatus
.Status
= Status
;
984 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
988 /* FIXME remove pin from filter pin list and decrement reference count */
990 if (Status
!= STATUS_PENDING
)
992 Irp
->IoStatus
.Status
= Status
;
993 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1003 IKsPin_DispatchCreateAllocator(
1004 IN PDEVICE_OBJECT DeviceObject
,
1009 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
1010 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1011 return STATUS_NOT_IMPLEMENTED
;
1016 IKsPin_DispatchCreateClock(
1017 IN PDEVICE_OBJECT DeviceObject
,
1022 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
1023 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1024 return STATUS_NOT_IMPLEMENTED
;
1029 IKsPin_DispatchCreateNode(
1030 IN PDEVICE_OBJECT DeviceObject
,
1035 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
1036 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1037 return STATUS_NOT_IMPLEMENTED
;
1040 static KSDISPATCH_TABLE PinDispatchTable
=
1042 IKsPin_DispatchDeviceIoControl
,
1043 KsDispatchInvalidDeviceRequest
,
1044 KsDispatchInvalidDeviceRequest
,
1045 KsDispatchInvalidDeviceRequest
,
1047 KsDispatchQuerySecurity
,
1048 KsDispatchSetSecurity
,
1049 KsDispatchFastIoDeviceControlFailure
,
1050 KsDispatchFastReadFailure
,
1051 KsDispatchFastReadFailure
1056 IN PDEVICE_OBJECT DeviceObject
,
1058 IN PKSDEVICE KsDevice
,
1059 IN IKsFilterFactory
* FilterFactory
,
1060 IN IKsFilter
* Filter
,
1061 IN PKSPIN_CONNECT Connect
,
1062 IN KSPIN_DESCRIPTOR_EX
* Descriptor
)
1065 PIO_STACK_LOCATION IoStack
;
1067 PDEVICE_EXTENSION DeviceExtension
;
1068 PKSOBJECT_CREATE_ITEM CreateItem
;
1072 ASSERT(Descriptor
->Dispatch
);
1073 ASSERT(Descriptor
->Dispatch
->Create
);
1075 /* get current irp stack */
1076 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1078 /* get device extension */
1079 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1081 /* get ks device interface */
1082 Device
= (IKsDevice
*)&DeviceExtension
->DeviceHeader
->lpVtblIKsDevice
;
1084 /* first allocate pin ctx */
1085 This
= AllocateItem(NonPagedPool
, sizeof(IKsPinImpl
));
1088 /* not enough memory */
1089 return STATUS_INSUFFICIENT_RESOURCES
;
1092 /* allocate create item */
1093 CreateItem
= AllocateItem(NonPagedPool
, sizeof(KSOBJECT_CREATE_ITEM
) * 3);
1096 /* not enough memory */
1098 return STATUS_INSUFFICIENT_RESOURCES
;
1101 /* initialize basic header */
1102 This
->BasicHeader
.KsDevice
= KsDevice
;
1103 This
->BasicHeader
.Type
= KsObjectTypePin
;
1104 This
->BasicHeader
.Parent
.KsFilter
= Filter
->lpVtbl
->GetStruct(Filter
);
1105 KeInitializeMutex(&This
->BasicHeader
.ControlMutex
, 0);
1106 InitializeListHead(&This
->BasicHeader
.EventList
);
1107 KeInitializeSpinLock(&This
->BasicHeader
.EventListLock
);
1109 /* initialize pin */
1110 This
->lpVtbl
= &vt_IKsPin
;
1112 This
->FileObject
= IoStack
->FileObject
;
1113 KeInitializeMutex(&This
->ProcessingMutex
, 0);
1114 InitializeListHead(&This
->IrpList
);
1115 KeInitializeSpinLock(&This
->IrpListLock
);
1117 /* initialize ks pin descriptor */
1118 This
->Pin
.Descriptor
= Descriptor
;
1119 This
->Pin
.Id
= Connect
->PinId
;
1121 /* allocate object bag */
1122 This
->Pin
.Bag
= AllocateItem(NonPagedPool
, sizeof(KSIOBJECT_BAG
));
1125 /* not enough memory */
1127 FreeItem(CreateItem
);
1128 return STATUS_INSUFFICIENT_RESOURCES
;
1131 /* initialize object bag */
1132 Device
->lpVtbl
->InitializeObjectBag(Device
, This
->Pin
.Bag
, &This
->BasicHeader
.ControlMutex
); /* is using control mutex right? */
1134 This
->Pin
.Communication
= Descriptor
->PinDescriptor
.Communication
;
1135 This
->Pin
.ConnectionIsExternal
= FALSE
; /* FIXME */
1136 //FIXME This->Pin.ConnectionInterface = Descriptor->PinDescriptor.Interfaces;
1137 //FIXME This->Pin.ConnectionMedium = Descriptor->PinDescriptor.Mediums;
1138 //FIXME This->Pin.ConnectionPriority = KSPRIORITY_NORMAL;
1139 This
->Pin
.ConnectionFormat
= (PKSDATAFORMAT
) (Connect
+ 1);
1140 This
->Pin
.AttributeList
= NULL
; //FIXME
1141 This
->Pin
.StreamHeaderSize
= sizeof(KSSTREAM_HEADER
);
1142 This
->Pin
.DataFlow
= Descriptor
->PinDescriptor
.DataFlow
;
1143 This
->Pin
.DeviceState
= KSSTATE_STOP
;
1144 This
->Pin
.ResetState
= KSRESET_END
;
1145 This
->Pin
.ClientState
= KSSTATE_STOP
;
1147 /* intialize allocator create item */
1148 CreateItem
[0].Context
= (PVOID
)This
;
1149 CreateItem
[0].Create
= IKsPin_DispatchCreateAllocator
;
1150 CreateItem
[0].Flags
= KSCREATE_ITEM_FREEONSTOP
;
1151 RtlInitUnicodeString(&CreateItem
[0].ObjectClass
, KSSTRING_Allocator
);
1153 /* intialize clock create item */
1154 CreateItem
[1].Context
= (PVOID
)This
;
1155 CreateItem
[1].Create
= IKsPin_DispatchCreateClock
;
1156 CreateItem
[1].Flags
= KSCREATE_ITEM_FREEONSTOP
;
1157 RtlInitUnicodeString(&CreateItem
[1].ObjectClass
, KSSTRING_Clock
);
1159 /* intialize topology node create item */
1160 CreateItem
[2].Context
= (PVOID
)This
;
1161 CreateItem
[2].Create
= IKsPin_DispatchCreateNode
;
1162 CreateItem
[2].Flags
= KSCREATE_ITEM_FREEONSTOP
;
1163 RtlInitUnicodeString(&CreateItem
[2].ObjectClass
, KSSTRING_TopologyNode
);
1165 /* now allocate object header */
1166 Status
= KsAllocateObjectHeader((KSOBJECT_HEADER
*)&This
->ObjectHeader
, 3, CreateItem
, Irp
, &PinDispatchTable
);
1167 if (!NT_SUCCESS(Status
))
1169 /* failed to create object header */
1170 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
1172 FreeItem(CreateItem
);
1174 /* return failure code */
1178 /* add extra info to object header */
1179 This
->ObjectHeader
->Type
= KsObjectTypePin
;
1180 This
->ObjectHeader
->Unknown
= (PUNKNOWN
)&This
->lpVtbl
;
1181 This
->ObjectHeader
->ObjectType
= (PVOID
)&This
->Pin
;
1183 /* setup process pin */
1184 This
->ProcessPin
.Pin
= &This
->Pin
;
1185 This
->ProcessPin
.StreamPointer
= (PKSSTREAM_POINTER
)This
->LeadingEdgeStreamPointer
;
1187 if (!Descriptor
->Dispatch
|| !Descriptor
->Dispatch
->Process
)
1189 /* the pin is part of filter-centric processing filter
1190 * add process pin to filter
1193 Status
= Filter
->lpVtbl
->AddProcessPin(Filter
, &This
->ProcessPin
);
1194 if (!NT_SUCCESS(Status
))
1196 /* failed to add process pin */
1197 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
1198 KsFreeObjectHeader(&This
->ObjectHeader
);
1200 /* return failure code */
1205 /* FIXME add pin instance to filter instance */
1207 /* does the driver have a pin dispatch */
1208 if (Descriptor
->Dispatch
&& Descriptor
->Dispatch
->Create
)
1210 /* now inform the driver to create a new pin */
1211 Status
= Descriptor
->Dispatch
->Create(&This
->Pin
, Irp
);
1214 if (!NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
)
1216 /* failed to create pin, release resources */
1217 KsFreeObjectHeader((KSOBJECT_HEADER
)This
->ObjectHeader
);
1218 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
1221 /* return failure code */