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
;
33 KMUTEX ProcessingMutex
;
34 PFILE_OBJECT FileObject
;
40 KSPIN_LOCK IrpListLock
;
42 PKSISTREAM_POINTER ClonedStreamPointer
;
43 PKSISTREAM_POINTER LeadingEdgeStreamPointer
;
44 PKSISTREAM_POINTER TrailingStreamPointer
;
48 PFNKSPINHANDSHAKE Handshake
;
49 PFNKSPINFRAMERETURN FrameReturn
;
50 PFNKSPINIRPCOMPLETION IrpCompletion
;
56 IKsPin_fnQueryInterface(
61 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtbl
);
63 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
))
65 *Output
= &This
->lpVtbl
;
66 _InterlockedIncrement(&This
->ref
);
67 return STATUS_SUCCESS
;
69 return STATUS_UNSUCCESSFUL
;
77 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtbl
);
79 return InterlockedIncrement(&This
->ref
);
87 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(iface
, IKsPinImpl
, lpVtbl
);
89 InterlockedDecrement(&This
->ref
);
96 /* Return new reference count */
102 IKsPin_fnTransferKsIrp(
105 IN IKsTransport
**OutTransport
)
108 return STATUS_NOT_IMPLEMENTED
;
113 IKsPin_fnDiscardKsIrp(
116 IN IKsTransport
* *OutTransport
)
126 IN IKsTransport
* TransportIn
,
127 OUT IKsTransport
** OutTransportIn
,
128 OUT IKsTransport
* *OutTransportOut
,
129 IN KSPIN_DATAFLOW DataFlow
)
132 return STATUS_NOT_IMPLEMENTED
;
137 IKsPin_fnSetDeviceState(
141 IN IKsTransport
* *OutTransport
)
144 return STATUS_NOT_IMPLEMENTED
;
149 IKsPin_fnSetResetState(
151 IN KSRESET ResetState
,
152 OUT IKsTransport
* * OutTransportOut
)
159 IKsPin_fnGetTransportConfig(
161 IN
struct KSPTRANSPORTCONFIG
* TransportConfig
,
162 OUT IKsTransport
** OutTransportIn
,
163 OUT IKsTransport
** OutTransportOut
)
166 return STATUS_NOT_IMPLEMENTED
;
171 IKsPin_fnSetTransportConfig(
173 IN
struct KSPTRANSPORTCONFIG
const * TransportConfig
,
174 OUT IKsTransport
** OutTransportIn
,
175 OUT IKsTransport
** OutTransportOut
)
178 return STATUS_NOT_IMPLEMENTED
;
183 IKsPin_fnResetTransportConfig(
185 OUT IKsTransport
** OutTransportIn
,
186 OUT IKsTransport
** OutTransportOut
)
189 return STATUS_NOT_IMPLEMENTED
;
203 IKsPin_fnGetProcessPin(
212 IKsPin_fnAttemptBypass(
216 return STATUS_NOT_IMPLEMENTED
;
221 IKsPin_fnAttemptUnbypass(
225 return STATUS_NOT_IMPLEMENTED
;
230 IKsPin_fnGenerateConnectionEvents(
239 IKsPin_fnClientSetDeviceState(
245 return STATUS_NOT_IMPLEMENTED
;
248 static IKsPinVtbl vt_IKsPin
=
250 IKsPin_fnQueryInterface
,
253 IKsPin_fnTransferKsIrp
,
254 IKsPin_fnDiscardKsIrp
,
256 IKsPin_fnSetDeviceState
,
257 IKsPin_fnSetResetState
,
258 IKsPin_fnGetTransportConfig
,
259 IKsPin_fnSetTransportConfig
,
260 IKsPin_fnResetTransportConfig
,
262 IKsPin_fnGetProcessPin
,
263 IKsPin_fnAttemptBypass
,
264 IKsPin_fnAttemptUnbypass
,
265 IKsPin_fnGenerateConnectionEvents
,
266 IKsPin_fnClientSetDeviceState
270 //==============================================================
277 KsPinAcquireProcessingMutex(
280 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
282 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
292 IN PKSGATE AndGate OPTIONAL
)
294 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
296 /* FIXME attach to filter's and gate (filter-centric processing) */
298 This
->AttachedGate
= AndGate
;
299 This
->OrGate
= FALSE
;
309 IN PKSGATE OrGate OPTIONAL
)
311 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
313 /* FIXME attach to filter's and gate (filter-centric processing) */
315 This
->AttachedGate
= OrGate
;
327 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
329 return This
->AttachedGate
;
337 KsPinAttemptProcessing(
339 IN BOOLEAN Asynchronous
)
349 KsPinGetAvailableByteCount(
351 OUT PLONG InputDataBytes OPTIONAL
,
352 OUT PLONG OutputBufferBytes OPTIONAL
)
355 return STATUS_NOT_IMPLEMENTED
;
363 KsPinGetConnectedFilterInterface(
365 IN
const GUID
* InterfaceId
,
366 OUT PVOID
* Interface
)
369 return STATUS_NOT_IMPLEMENTED
;
377 KsPinGetConnectedPinDeviceObject(
380 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
382 /* return related file object */
383 return IoGetRelatedDeviceObject(This
->FileObject
);
391 KsPinGetConnectedPinFileObject(
402 KsPinGetConnectedPinInterface(
404 IN
const GUID
* InterfaceId
,
405 OUT PVOID
* Interface
)
408 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
410 /* get pin interface */
411 KsPin
= (IKsPin
*)&This
->lpVtbl
;
413 /* query pin interface for the requested interface */
414 return KsPin
->lpVtbl
->QueryInterface(KsPin
, InterfaceId
, Interface
);
422 KsPinGetCopyRelationships(
424 OUT PKSPIN
* CopySource
,
425 OUT PKSPIN
* DelegateBranch
)
435 KsPinGetNextSiblingPin(
438 return KsGetNextSibling((PVOID
)Pin
);
446 KsPinGetParentFilter(
449 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
451 /* return parent filter */
452 return This
->BasicHeader
.Parent
.KsFilter
;
460 KsPinGetReferenceClockInterface(
462 OUT PIKSREFERENCECLOCK
* Interface
)
465 return STATUS_UNSUCCESSFUL
;
473 KsPinRegisterFrameReturnCallback(
475 IN PFNKSPINFRAMERETURN FrameReturn
)
477 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
479 /* register frame return callback */
480 This
->FrameReturn
= FrameReturn
;
488 KsPinRegisterHandshakeCallback(
490 IN PFNKSPINHANDSHAKE Handshake
)
492 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
494 /* register private protocol handshake callback */
495 This
->Handshake
= Handshake
;
503 KsPinRegisterIrpCompletionCallback(
505 IN PFNKSPINIRPCOMPLETION IrpCompletion
)
507 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
509 /* register irp completion callback */
510 This
->IrpCompletion
= IrpCompletion
;
518 KsPinRegisterPowerCallbacks(
520 IN PFNKSPINPOWER Sleep OPTIONAL
,
521 IN PFNKSPINPOWER Wake OPTIONAL
)
523 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
525 /* register power callbacks */
535 KsPinReleaseProcessingMutex(
538 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
540 /* release processing mutex */
541 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
553 PKSIOBJECT_HEADER ObjectHeader
;
554 PIO_STACK_LOCATION IoStack
= IoGetCurrentIrpStackLocation(Irp
);
556 /* get object header */
557 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext
;
558 /* return object type */
559 return (PKSPIN
)ObjectHeader
->ObjectType
;
570 KsPinSetPinClockTime(
584 IN PVOID Data OPTIONAL
,
585 IN ULONG Size OPTIONAL
,
586 IN PKSSTREAM_HEADER StreamHeader OPTIONAL
,
587 IN PVOID Context OPTIONAL
)
590 return STATUS_UNSUCCESSFUL
;
601 IN PMDL Mdl OPTIONAL
,
602 IN PKSSTREAM_HEADER StreamHeader OPTIONAL
,
603 IN PVOID Context OPTIONAL
)
606 return STATUS_UNSUCCESSFUL
;
616 IN PKSPROCESSPIN ProcessPin
)
628 KsPinGetLeadingEdgeStreamPointer(
630 IN KSSTREAM_POINTER_STATE State
)
642 KsPinGetTrailingEdgeStreamPointer(
644 IN KSSTREAM_POINTER_STATE State
)
656 KsStreamPointerSetStatusCode(
657 IN PKSSTREAM_POINTER StreamPointer
,
661 return STATUS_UNSUCCESSFUL
;
671 IN PKSSTREAM_POINTER StreamPointer
)
674 return STATUS_UNSUCCESSFUL
;
683 KsStreamPointerUnlock(
684 IN PKSSTREAM_POINTER StreamPointer
,
696 KsStreamPointerAdvanceOffsetsAndUnlock(
697 IN PKSSTREAM_POINTER StreamPointer
,
711 KsStreamPointerDelete(
712 IN PKSSTREAM_POINTER StreamPointer
)
715 PKSISTREAM_POINTER Cur
, Last
;
716 PKSISTREAM_POINTER Pointer
= (PKSISTREAM_POINTER
)StreamPointer
;
718 This
= (IKsPinImpl
*)CONTAINING_RECORD(Pointer
->StreamPointer
.Pin
, IKsPinImpl
, Pin
);
720 /* point to first stream pointer */
722 Cur
= This
->ClonedStreamPointer
;
724 while(Cur
!= Pointer
&& Cur
)
727 /* iterate to next cloned pointer */
733 /* you naughty driver */
739 /* remove first cloned pointer */
740 This
->ClonedStreamPointer
= Pointer
->Next
;
744 Last
->Next
= Pointer
->Next
;
747 /* FIXME make sure no timeouts are pending */
757 KsStreamPointerClone(
758 IN PKSSTREAM_POINTER StreamPointer
,
759 IN PFNKSSTREAMPOINTER CancelCallback OPTIONAL
,
760 IN ULONG ContextSize
,
761 OUT PKSSTREAM_POINTER
* CloneStreamPointer
)
764 return STATUS_NOT_IMPLEMENTED
;
773 KsStreamPointerAdvanceOffsets(
774 IN PKSSTREAM_POINTER StreamPointer
,
780 return STATUS_NOT_IMPLEMENTED
;
789 KsStreamPointerAdvance(
790 IN PKSSTREAM_POINTER StreamPointer
)
793 return STATUS_NOT_IMPLEMENTED
;
802 KsStreamPointerGetMdl(
803 IN PKSSTREAM_POINTER StreamPointer
)
815 KsStreamPointerGetIrp(
816 IN PKSSTREAM_POINTER StreamPointer
,
817 OUT PBOOLEAN FirstFrameInIrp OPTIONAL
,
818 OUT PBOOLEAN LastFrameInIrp OPTIONAL
)
830 KsStreamPointerScheduleTimeout(
831 IN PKSSTREAM_POINTER StreamPointer
,
832 IN PFNKSSTREAMPOINTER Callback
,
833 IN ULONGLONG Interval
)
835 LARGE_INTEGER DueTime
;
836 PKSISTREAM_POINTER Pointer
= (PKSISTREAM_POINTER
)StreamPointer
;
838 /* setup timer callback */
839 Pointer
->Callback
= Callback
;
841 /* setup expiration */
842 DueTime
.QuadPart
= (LONGLONG
)Interval
;
844 /* setup the timer */
845 KeSetTimer(&Pointer
->Timer
, DueTime
, &Pointer
->TimerDpc
);
855 KsStreamPointerCancelTimeout(
856 IN PKSSTREAM_POINTER StreamPointer
)
858 PKSISTREAM_POINTER Pointer
= (PKSISTREAM_POINTER
)StreamPointer
;
860 KeCancelTimer(&Pointer
->Timer
);
870 KsPinGetFirstCloneStreamPointer(
873 IKsPinImpl
* This
= (IKsPinImpl
*)CONTAINING_RECORD(Pin
, IKsPinImpl
, Pin
);
874 /* return first cloned stream pointer */
875 return &This
->ClonedStreamPointer
->StreamPointer
;
884 KsStreamPointerGetNextClone(
885 IN PKSSTREAM_POINTER StreamPointer
)
887 PKSISTREAM_POINTER Pointer
= (PKSISTREAM_POINTER
)StreamPointer
;
889 /* is there a another cloned stream pointer */
893 /* return next stream pointer */
894 return &Pointer
->Next
->StreamPointer
;
899 IKsPin_DispatchDeviceIoControl(
900 IN PDEVICE_OBJECT DeviceObject
,
903 PIO_STACK_LOCATION IoStack
;
904 PKSIOBJECT_HEADER ObjectHeader
;
906 NTSTATUS Status
= STATUS_SUCCESS
;
908 /* get current irp stack */
909 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
912 ASSERT(IoStack
->FileObject
);
913 ASSERT(IoStack
->FileObject
->FsContext
);
915 /* get the object header */
916 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext
;
918 /* locate ks pin implemention fro KSPIN offset */
919 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
921 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_WRITE_STREAM
&& IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_READ_STREAM
)
924 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
925 Irp
->IoStatus
.Information
= 0;
926 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
927 return STATUS_NOT_IMPLEMENTED
;
930 /* mark irp as pending */
931 IoMarkIrpPending(Irp
);
933 /* add irp to cancelable queue */
934 KsAddIrpToCancelableQueue(&This
->IrpList
, &This
->IrpListLock
, Irp
, KsListEntryTail
, NULL
/* FIXME */);
936 if (This
->Pin
.Descriptor
->Dispatch
->Process
)
938 /* it is a pin centric avstream */
939 Status
= This
->Pin
.Descriptor
->Dispatch
->Process(&This
->Pin
);
946 * filter-centric avstream
957 IN PDEVICE_OBJECT DeviceObject
,
960 PIO_STACK_LOCATION IoStack
;
961 PKSIOBJECT_HEADER ObjectHeader
;
963 NTSTATUS Status
= STATUS_SUCCESS
;
965 /* get current irp stack */
966 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
969 ASSERT(IoStack
->FileObject
);
970 ASSERT(IoStack
->FileObject
->FsContext
);
972 /* get the object header */
973 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext
;
975 /* locate ks pin implemention fro KSPIN offset */
976 This
= (IKsPinImpl
*)CONTAINING_RECORD(ObjectHeader
->ObjectType
, IKsPinImpl
, Pin
);
978 /* acquire filter control mutex */
979 KsFilterAcquireControl(This
->BasicHeader
.Parent
.KsFilter
);
981 if (This
->Pin
.Descriptor
->Dispatch
->Close
)
983 /* call pin close routine */
984 Status
= This
->Pin
.Descriptor
->Dispatch
->Close(&This
->Pin
, Irp
);
986 if (!NT_SUCCESS(Status
))
989 Irp
->IoStatus
.Status
= Status
;
990 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
994 /* FIXME remove pin from filter pin list and decrement reference count */
996 if (Status
!= STATUS_PENDING
)
998 Irp
->IoStatus
.Status
= Status
;
999 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1009 IKsPin_DispatchCreateAllocator(
1010 IN PDEVICE_OBJECT DeviceObject
,
1015 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
1016 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1017 return STATUS_NOT_IMPLEMENTED
;
1022 IKsPin_DispatchCreateClock(
1023 IN PDEVICE_OBJECT DeviceObject
,
1028 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
1029 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1030 return STATUS_NOT_IMPLEMENTED
;
1035 IKsPin_DispatchCreateNode(
1036 IN PDEVICE_OBJECT DeviceObject
,
1041 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
1042 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1043 return STATUS_NOT_IMPLEMENTED
;
1046 static KSDISPATCH_TABLE PinDispatchTable
=
1048 IKsPin_DispatchDeviceIoControl
,
1049 KsDispatchInvalidDeviceRequest
,
1050 KsDispatchInvalidDeviceRequest
,
1051 KsDispatchInvalidDeviceRequest
,
1053 KsDispatchQuerySecurity
,
1054 KsDispatchSetSecurity
,
1055 KsDispatchFastIoDeviceControlFailure
,
1056 KsDispatchFastReadFailure
,
1057 KsDispatchFastReadFailure
1062 IN PDEVICE_OBJECT DeviceObject
,
1064 IN PKSDEVICE KsDevice
,
1065 IN IKsFilterFactory
* FilterFactory
,
1066 IN IKsFilter
* Filter
,
1067 IN PKSPIN_CONNECT Connect
,
1068 IN KSPIN_DESCRIPTOR_EX
* Descriptor
)
1071 PIO_STACK_LOCATION IoStack
;
1073 PDEVICE_EXTENSION DeviceExtension
;
1074 PKSOBJECT_CREATE_ITEM CreateItem
;
1078 ASSERT(Descriptor
->Dispatch
);
1079 ASSERT(Descriptor
->Dispatch
->Create
);
1081 /* get current irp stack */
1082 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1084 /* get device extension */
1085 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1087 /* get ks device interface */
1088 Device
= (IKsDevice
*)&DeviceExtension
->DeviceHeader
->lpVtblIKsDevice
;
1090 /* first allocate pin ctx */
1091 This
= AllocateItem(NonPagedPool
, sizeof(IKsPinImpl
));
1094 /* not enough memory */
1095 return STATUS_INSUFFICIENT_RESOURCES
;
1098 /* allocate create item */
1099 CreateItem
= AllocateItem(NonPagedPool
, sizeof(KSOBJECT_CREATE_ITEM
) * 3);
1102 /* not enough memory */
1104 return STATUS_INSUFFICIENT_RESOURCES
;
1107 /* initialize basic header */
1108 This
->BasicHeader
.KsDevice
= KsDevice
;
1109 This
->BasicHeader
.Type
= KsObjectTypePin
;
1110 This
->BasicHeader
.Parent
.KsFilter
= Filter
->lpVtbl
->GetStruct(Filter
);
1111 KeInitializeMutex(&This
->BasicHeader
.ControlMutex
, 0);
1112 InitializeListHead(&This
->BasicHeader
.EventList
);
1113 KeInitializeSpinLock(&This
->BasicHeader
.EventListLock
);
1115 /* initialize pin */
1116 This
->lpVtbl
= &vt_IKsPin
;
1118 This
->FileObject
= IoStack
->FileObject
;
1119 KeInitializeMutex(&This
->ProcessingMutex
, 0);
1120 InitializeListHead(&This
->IrpList
);
1121 KeInitializeSpinLock(&This
->IrpListLock
);
1123 /* initialize ks pin descriptor */
1124 This
->Pin
.Descriptor
= Descriptor
;
1125 This
->Pin
.Id
= Connect
->PinId
;
1127 /* allocate object bag */
1128 This
->Pin
.Bag
= AllocateItem(NonPagedPool
, sizeof(KSIOBJECT_BAG
));
1131 /* not enough memory */
1133 FreeItem(CreateItem
);
1134 return STATUS_INSUFFICIENT_RESOURCES
;
1137 /* initialize object bag */
1138 Device
->lpVtbl
->InitializeObjectBag(Device
, This
->Pin
.Bag
, &This
->BasicHeader
.ControlMutex
); /* is using control mutex right? */
1140 This
->Pin
.Communication
= Descriptor
->PinDescriptor
.Communication
;
1141 This
->Pin
.ConnectionIsExternal
= FALSE
; /* FIXME */
1142 //FIXME This->Pin.ConnectionInterface = Descriptor->PinDescriptor.Interfaces;
1143 //FIXME This->Pin.ConnectionMedium = Descriptor->PinDescriptor.Mediums;
1144 //FIXME This->Pin.ConnectionPriority = KSPRIORITY_NORMAL;
1145 This
->Pin
.ConnectionFormat
= (PKSDATAFORMAT
) (Connect
+ 1);
1146 This
->Pin
.AttributeList
= NULL
; //FIXME
1147 This
->Pin
.StreamHeaderSize
= sizeof(KSSTREAM_HEADER
);
1148 This
->Pin
.DataFlow
= Descriptor
->PinDescriptor
.DataFlow
;
1149 This
->Pin
.DeviceState
= KSSTATE_STOP
;
1150 This
->Pin
.ResetState
= KSRESET_END
;
1151 This
->Pin
.ClientState
= KSSTATE_STOP
;
1153 /* intialize allocator create item */
1154 CreateItem
[0].Context
= (PVOID
)This
;
1155 CreateItem
[0].Create
= IKsPin_DispatchCreateAllocator
;
1156 CreateItem
[0].Flags
= KSCREATE_ITEM_FREEONSTOP
;
1157 RtlInitUnicodeString(&CreateItem
[0].ObjectClass
, KSSTRING_Allocator
);
1159 /* intialize clock create item */
1160 CreateItem
[1].Context
= (PVOID
)This
;
1161 CreateItem
[1].Create
= IKsPin_DispatchCreateClock
;
1162 CreateItem
[1].Flags
= KSCREATE_ITEM_FREEONSTOP
;
1163 RtlInitUnicodeString(&CreateItem
[1].ObjectClass
, KSSTRING_Clock
);
1165 /* intialize topology node create item */
1166 CreateItem
[2].Context
= (PVOID
)This
;
1167 CreateItem
[2].Create
= IKsPin_DispatchCreateNode
;
1168 CreateItem
[2].Flags
= KSCREATE_ITEM_FREEONSTOP
;
1169 RtlInitUnicodeString(&CreateItem
[2].ObjectClass
, KSSTRING_TopologyNode
);
1171 /* now allocate object header */
1172 Status
= KsAllocateObjectHeader((KSOBJECT_HEADER
*)&This
->ObjectHeader
, 3, CreateItem
, Irp
, &PinDispatchTable
);
1173 if (!NT_SUCCESS(Status
))
1175 /* failed to create object header */
1176 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
1178 FreeItem(CreateItem
);
1180 /* return failure code */
1184 /* add extra info to object header */
1185 This
->ObjectHeader
->Type
= KsObjectTypePin
;
1186 This
->ObjectHeader
->Unknown
= (PUNKNOWN
)&This
->lpVtbl
;
1187 This
->ObjectHeader
->ObjectType
= (PVOID
)&This
->Pin
;
1189 /* does the driver have a pin dispatch */
1190 if (Descriptor
->Dispatch
&& Descriptor
->Dispatch
->Create
)
1192 /* now inform the driver to create a new pin */
1193 Status
= Descriptor
->Dispatch
->Create(&This
->Pin
, Irp
);
1196 if (!NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
)
1198 /* failed to create pin, release resources */
1199 KsFreeObjectHeader((KSOBJECT_HEADER
)This
->ObjectHeader
);
1200 KsFreeObjectBag((KSOBJECT_BAG
)This
->Pin
.Bag
);
1203 /* return failure code */
1207 /* FIXME add pin instance to filter instance */