Author: janderwald Date: Wed Jul 29 11:48:36 2009 New Revision: 42283
URL: http://svn.reactos.org/svn/reactos?rev=42283&view=rev Log: - Start Implementing IKsPin interface - Increment PinInstanceCount when a pin has succcessfully been created - Implement KsPinAcquireProcessingMutex, KsPinGetConnectedPinDeviceObject, KsPinGetConnectedFileObject, KsPinGetConnectedPinInterface, KsPinGetNextSiblingPin, KsPinGetParentFilter, KsPinRegisterFrameReturnCallback, KsPinRegisterHandshakeCallback, KsPinRegisterIrpCompletionCallback, KsPinRegisterPowerCallbacks, KsPinReleaseProcessingMutex - Initialize pin dispatch table - Add create items for allocator, clock, node create requests - AVStream clients should now be able to instantiated pins, streaming not yet supported
Modified: trunk/reactos/drivers/ksfilter/ks/filter.c trunk/reactos/drivers/ksfilter/ks/ksfunc.h trunk/reactos/drivers/ksfilter/ks/ksiface.h trunk/reactos/drivers/ksfilter/ks/pin.c
Modified: trunk/reactos/drivers/ksfilter/ks/filter.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/filter.... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/filter.c [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/filter.c [iso-8859-1] Wed Jul 29 11:48:36 2009 @@ -924,8 +924,22 @@
if (NT_SUCCESS(Status)) { - /* create the pin */ - Status = KspCreatePin(DeviceObject, Irp, This->Header.KsDevice, This->FilterFactory, (IKsFilter*)&This->lpVtbl, Connect); + if (This->PinInstanceCount[Connect->PinId] < This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible) + { + /* create the pin */ + Status = KspCreatePin(DeviceObject, Irp, This->Header.KsDevice, This->FilterFactory, (IKsFilter*)&This->lpVtbl, Connect, (KSPIN_DESCRIPTOR_EX*)&This->Filter.Descriptor->PinDescriptors[Connect->PinId]); + + if (NT_SUCCESS(Status)) + { + /* successfully created pin, increment pin instance count */ + This->PinInstanceCount[Connect->PinId]++; + } + } + else + { + /* maximum instance count reached, bye-bye */ + Status = STATUS_UNSUCCESSFUL; + } }
/* release control mutex */ @@ -1040,11 +1054,13 @@ This->Factory = Factory; This->FilterFactory = iface; This->FileObject = IoStack->FileObject; + KeInitializeMutex(&This->ProcessingMutex, 0); + /* initialize basic header */ This->Header.KsDevice = &DeviceExtension->DeviceHeader->KsDevice; This->Header.Parent.KsFilterFactory = iface->lpVtbl->GetStruct(iface); This->Header.Type = KsObjectTypeFilter; KeInitializeMutex(&This->Header.ControlMutex, 0); - KeInitializeMutex(&This->ProcessingMutex, 0); +
/* allocate the stream descriptors */ @@ -1095,9 +1111,7 @@ return Status; }
- /* initialize object header */ - This->Header.Type = KsObjectTypeFilter; - This->Header.KsDevice = &DeviceExtension->DeviceHeader->KsDevice; + /* initialize object header extra fields */ This->ObjectHeader->Type = KsObjectTypeFilter; This->ObjectHeader->Unknown = (PUNKNOWN)&This->lpVtbl; This->ObjectHeader->ObjectType = (PVOID)&This->Filter;
Modified: trunk/reactos/drivers/ksfilter/ks/ksfunc.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/ksfunc.... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/ksfunc.h [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/ksfunc.h [iso-8859-1] Wed Jul 29 11:48:36 2009 @@ -121,7 +121,8 @@ IN PKSDEVICE KsDevice, IN IKsFilterFactory * FilterFactory, IN IKsFilter* Filter, - IN PKSPIN_CONNECT Connect); + IN PKSPIN_CONNECT Connect, + IN KSPIN_DESCRIPTOR_EX* Descriptor);
#endif
Modified: trunk/reactos/drivers/ksfilter/ks/ksiface.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/ksiface... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/ksiface.h [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/ksiface.h [iso-8859-1] Wed Jul 29 11:48:36 2009 @@ -63,6 +63,20 @@ };
/***************************************************************************** + * IKsTransport + ***************************************************************************** + */ + +#undef INTERFACE +#define INTERFACE IKsTransport + +DECLARE_INTERFACE_(IKsTransport, IUnknown) +{ + DEFINE_ABSTRACT_UNKNOWN() +}; + + +/***************************************************************************** * IKsPin ***************************************************************************** */ @@ -70,9 +84,60 @@ #undef INTERFACE #define INTERFACE IKsPin
+struct KSPTRANSPORTCONFIG; + DECLARE_INTERFACE_(IKsPin, IUnknown) { DEFINE_ABSTRACT_UNKNOWN() + + STDMETHOD_(NTSTATUS, TransferKsIrp)(THIS_ + IN PIRP Irp, + IN IKsTransport **OutTransport) PURE; + + STDMETHOD_(VOID, DiscardKsIrp)(THIS_ + IN PIRP Irp, + IN IKsTransport * *OutTransport) PURE; + + STDMETHOD_(NTSTATUS, Connect)(THIS_ + IN IKsTransport * TransportIn, + OUT IKsTransport ** OutTransportIn, + OUT IKsTransport * *OutTransportOut, + IN KSPIN_DATAFLOW DataFlow) PURE; + + STDMETHOD_(NTSTATUS, SetDeviceState)(THIS_ + IN KSSTATE OldState, + IN KSSTATE NewState, + IN IKsTransport * *OutTransport) PURE; + + STDMETHOD_(VOID, SetResetState)(THIS_ + IN KSRESET ResetState, + OUT IKsTransport * * OutTransportOut) PURE; + + STDMETHOD_(NTSTATUS, GetTransportConfig)(THIS_ + IN struct KSPTRANSPORTCONFIG * TransportConfig, + OUT IKsTransport ** OutTransportIn, + OUT IKsTransport ** OutTransportOut) PURE; + + STDMETHOD_(NTSTATUS, SetTransportConfig)(THIS_ + IN struct KSPTRANSPORTCONFIG const * TransportConfig, + OUT IKsTransport ** OutTransportIn, + OUT IKsTransport ** OutTransportOut) PURE; + + STDMETHOD_(NTSTATUS, ResetTransportConfig)(THIS_ + OUT IKsTransport ** OutTransportIn, + OUT IKsTransport ** OutTransportOut) PURE; + + STDMETHOD_(PKSPIN, GetStruct)(THIS) PURE; + STDMETHOD_(PKSPROCESSPIN, GetProcessPin)(THIS) PURE; + STDMETHOD_(NTSTATUS, AttemptBypass)(THIS) PURE; + STDMETHOD_(NTSTATUS, AttemptUnbypass)(THIS) PURE; + + STDMETHOD_(VOID, GenerateConnectionEvents)(THIS_ + IN ULONG EventMask) PURE; + + STDMETHOD_(NTSTATUS, ClientSetDeviceState)(THIS_ + IN KSSTATE StateIn, + IN KSSTATE StateOut) PURE; };
/*****************************************************************************
Modified: trunk/reactos/drivers/ksfilter/ks/pin.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/pin.c?r... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/pin.c [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/pin.c [iso-8859-1] Wed Jul 29 11:48:36 2009 @@ -9,15 +9,256 @@
#include "priv.h"
-/* - @unimplemented +typedef struct +{ + KSBASIC_HEADER BasicHeader; + KSPIN Pin; + PKSIOBJECT_HEADER ObjectHeader; + LIST_ENTRY Entry; + + IKsPinVtbl *lpVtbl; + + LONG ref; + KMUTEX ProcessingMutex; + PFILE_OBJECT FileObject; + + PFNKSPINPOWER Sleep; + PFNKSPINPOWER Wake; + PFNKSPINHANDSHAKE Handshake; + PFNKSPINFRAMERETURN FrameReturn; + PFNKSPINIRPCOMPLETION IrpCompletion; + +}IKsPinImpl; + +NTSTATUS +NTAPI +IKsPin_fnQueryInterface( + IKsPin * iface, + IN REFIID refiid, + OUT PVOID* Output) +{ + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtbl); + + if (IsEqualGUIDAligned(refiid, &IID_IUnknown)) + { + *Output = &This->lpVtbl; + _InterlockedIncrement(&This->ref); + return STATUS_SUCCESS; + } + return STATUS_UNSUCCESSFUL; +} + +ULONG +NTAPI +IKsPin_fnAddRef( + IKsPin * iface) +{ + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtbl); + + return InterlockedIncrement(&This->ref); +} + +ULONG +NTAPI +IKsPin_fnRelease( + IKsPin * iface) +{ + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtbl); + + InterlockedDecrement(&This->ref); + + if (This->ref == 0) + { + FreeItem(This); + return 0; + } + /* Return new reference count */ + return This->ref; +} + +NTSTATUS +NTAPI +IKsPin_fnTransferKsIrp( + IN IKsPin *iface, + IN PIRP Irp, + IN IKsTransport **OutTransport) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + +VOID +NTAPI +IKsPin_fnDiscardKsIrp( + IN IKsPin *iface, + IN PIRP Irp, + IN IKsTransport * *OutTransport) +{ + UNIMPLEMENTED +} + + +NTSTATUS +NTAPI +IKsPin_fnConnect( + IN IKsPin *iface, + IN IKsTransport * TransportIn, + OUT IKsTransport ** OutTransportIn, + OUT IKsTransport * *OutTransportOut, + IN KSPIN_DATAFLOW DataFlow) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +IKsPin_fnSetDeviceState( + IN IKsPin *iface, + IN KSSTATE OldState, + IN KSSTATE NewState, + IN IKsTransport * *OutTransport) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + +VOID +NTAPI +IKsPin_fnSetResetState( + IN IKsPin *iface, + IN KSRESET ResetState, + OUT IKsTransport * * OutTransportOut) +{ + UNIMPLEMENTED +} + +NTSTATUS +NTAPI +IKsPin_fnGetTransportConfig( + IN IKsPin *iface, + IN struct KSPTRANSPORTCONFIG * TransportConfig, + OUT IKsTransport ** OutTransportIn, + OUT IKsTransport ** OutTransportOut) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +IKsPin_fnSetTransportConfig( + IN IKsPin *iface, + IN struct KSPTRANSPORTCONFIG const * TransportConfig, + OUT IKsTransport ** OutTransportIn, + OUT IKsTransport ** OutTransportOut) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +IKsPin_fnResetTransportConfig( + IN IKsPin *iface, + OUT IKsTransport ** OutTransportIn, + OUT IKsTransport ** OutTransportOut) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + +PKSPIN +NTAPI +IKsPin_fnGetStruct( + IN IKsPin *iface) +{ + UNIMPLEMENTED + return NULL; +} + +PKSPROCESSPIN +NTAPI +IKsPin_fnGetProcessPin( + IN IKsPin *iface) +{ + UNIMPLEMENTED + return NULL; +} + +NTSTATUS +NTAPI +IKsPin_fnAttemptBypass( + IN IKsPin *iface) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +IKsPin_fnAttemptUnbypass( + IN IKsPin *iface) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + +VOID +NTAPI +IKsPin_fnGenerateConnectionEvents( + IN IKsPin *iface, + IN ULONG EventMask) +{ + UNIMPLEMENTED +} + +NTSTATUS +NTAPI +IKsPin_fnClientSetDeviceState( + IN IKsPin *iface, + IN KSSTATE StateIn, + IN KSSTATE StateOut) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + +static IKsPinVtbl vt_IKsPin = +{ + IKsPin_fnQueryInterface, + IKsPin_fnAddRef, + IKsPin_fnRelease, + IKsPin_fnTransferKsIrp, + IKsPin_fnDiscardKsIrp, + IKsPin_fnConnect, + IKsPin_fnSetDeviceState, + IKsPin_fnSetResetState, + IKsPin_fnGetTransportConfig, + IKsPin_fnSetTransportConfig, + IKsPin_fnResetTransportConfig, + IKsPin_fnGetStruct, + IKsPin_fnGetProcessPin, + IKsPin_fnAttemptBypass, + IKsPin_fnAttemptUnbypass, + IKsPin_fnGenerateConnectionEvents, + IKsPin_fnClientSetDeviceState +}; + + +//============================================================== + +/* + @implemented */ VOID NTAPI KsPinAcquireProcessingMutex( IN PKSPIN Pin) { - UNIMPLEMENTED + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); + + KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL); }
/* @@ -96,31 +337,34 @@ }
/* - @unimplemented + @implemented */ PDEVICE_OBJECT NTAPI KsPinGetConnectedPinDeviceObject( IN PKSPIN Pin) { - UNIMPLEMENTED - return NULL; -} - -/* - @unimplemented + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); + + /* return related file object */ + return IoGetRelatedDeviceObject(This->FileObject); +} + +/* + @implemented */ PFILE_OBJECT NTAPI KsPinGetConnectedPinFileObject( IN PKSPIN Pin) { - UNIMPLEMENTED - return NULL; -} - -/* - @unimplemented + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); + + return This->FileObject; +} + +/* + @implemented */ NTSTATUS NTAPI @@ -129,8 +373,14 @@ IN const GUID* InterfaceId, OUT PVOID* Interface) { - UNIMPLEMENTED - return STATUS_UNSUCCESSFUL; + IKsPin * KsPin; + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); + + /* get pin interface */ + KsPin = (IKsPin*)&This->lpVtbl; + + /* query pin interface for the requested interface */ + return KsPin->lpVtbl->QueryInterface(KsPin, InterfaceId, Interface); }
/* @@ -147,27 +397,28 @@ }
/* - @unimplemented + @implemented */ PKSPIN NTAPI KsPinGetNextSiblingPin( IN PKSPIN Pin) { - UNIMPLEMENTED - return NULL; -} - -/* - @unimplemented + return KsGetNextSibling((PVOID)Pin); +} + +/* + @implemented */ PKSFILTER NTAPI KsPinGetParentFilter( IN PKSPIN Pin) { - UNIMPLEMENTED - return NULL; + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); + + /* return parent filter */ + return This->BasicHeader.Parent.KsFilter; }
/* @@ -184,7 +435,7 @@ }
/* - @unimplemented + @implemented */ VOID NTAPI @@ -192,11 +443,14 @@ IN PKSPIN Pin, IN PFNKSPINFRAMERETURN FrameReturn) { - UNIMPLEMENTED -} - -/* - @unimplemented + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); + + /* register frame return callback */ + This->FrameReturn = FrameReturn; +} + +/* + @implemented */ VOID NTAPI @@ -204,11 +458,14 @@ IN PKSPIN Pin, IN PFNKSPINHANDSHAKE Handshake) { - UNIMPLEMENTED -} - -/* - @unimplemented + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); + + /* register private protocol handshake callback */ + This->Handshake = Handshake; +} + +/* + @implemented */ VOID NTAPI @@ -216,11 +473,14 @@ IN PKSPIN Pin, IN PFNKSPINIRPCOMPLETION IrpCompletion) { - UNIMPLEMENTED -} - -/* - @unimplemented + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); + + /* register irp completion callback */ + This->IrpCompletion = IrpCompletion; +} + +/* + @implemented */ VOID NTAPI @@ -229,18 +489,25 @@ IN PFNKSPINPOWER Sleep OPTIONAL, IN PFNKSPINPOWER Wake OPTIONAL) { - UNIMPLEMENTED -} - -/* - @unimplemented + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); + + /* register power callbacks */ + This->Sleep = Sleep; + This->Wake = Wake; +} + +/* + @implemented */ VOID NTAPI KsPinReleaseProcessingMutex( IN PKSPIN Pin) { - UNIMPLEMENTED + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); + + /* release processing mutex */ + KeReleaseMutex(&This->ProcessingMutex, FALSE); }
/* @@ -521,15 +788,225 @@ }
NTSTATUS +NTAPI +IKsPin_DispatchDeviceIoControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED; + + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +IKsPin_Close( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED; + + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +IKsPin_DispatchCreateAllocator( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED; + + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +IKsPin_DispatchCreateClock( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED; + + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +IKsPin_DispatchCreateNode( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED; + + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_IMPLEMENTED; +} + +static KSDISPATCH_TABLE PinDispatchTable = +{ + IKsPin_DispatchDeviceIoControl, + KsDispatchInvalidDeviceRequest, + KsDispatchInvalidDeviceRequest, + KsDispatchInvalidDeviceRequest, + IKsPin_Close, + KsDispatchQuerySecurity, + KsDispatchSetSecurity, + KsDispatchFastIoDeviceControlFailure, + KsDispatchFastReadFailure, + KsDispatchFastReadFailure +}; + + +NTSTATUS KspCreatePin( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, - IN PKSDEVICE KsDevice, - IN IKsFilterFactory * FilterFactory, + IN PKSDEVICE KsDevice, + IN IKsFilterFactory * FilterFactory, IN IKsFilter* Filter, - IN PKSPIN_CONNECT Connect) -{ - - return STATUS_NOT_IMPLEMENTED; -} - + IN PKSPIN_CONNECT Connect, + IN KSPIN_DESCRIPTOR_EX* Descriptor) +{ + IKsPinImpl * This; + PIO_STACK_LOCATION IoStack; + IKsDevice * Device; + PDEVICE_EXTENSION DeviceExtension; + PKSOBJECT_CREATE_ITEM CreateItem; + NTSTATUS Status; + + /* sanity checks */ + ASSERT(Descriptor->Dispatch); + ASSERT(Descriptor->Dispatch->Create); + + /* get current irp stack */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* get device extension */ + DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; + + /* get ks device interface */ + Device = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice; + + /* first allocate pin ctx */ + This = AllocateItem(NonPagedPool, sizeof(IKsPinImpl)); + if (!This) + { + /* not enough memory */ + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* allocate create item */ + CreateItem = AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM) * 3); + if (!CreateItem) + { + /* not enough memory */ + FreeItem(This); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* initialize basic header */ + This->BasicHeader.KsDevice = KsDevice; + This->BasicHeader.Type = KsObjectTypePin; + This->BasicHeader.Parent.KsFilter = Filter->lpVtbl->GetStruct(Filter); + KeInitializeMutex(&This->BasicHeader.ControlMutex, 0); + + /* initialize pin */ + This->lpVtbl = &vt_IKsPin; + This->ref = 1; + This->FileObject = IoStack->FileObject; + KeInitializeMutex(&This->ProcessingMutex, 0); + + /* initialize ks pin descriptor */ + This->Pin.Descriptor = Descriptor; + This->Pin.Id = Connect->PinId; + + /* allocate object bag */ + This->Pin.Bag = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_BAG)); + if (!This->Pin.Bag) + { + /* not enough memory */ + FreeItem(This); + FreeItem(CreateItem); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* initialize object bag */ + Device->lpVtbl->InitializeObjectBag(Device, This->Pin.Bag, &This->BasicHeader.ControlMutex); /* is using control mutex right? */ + + This->Pin.Communication = Descriptor->PinDescriptor.Communication; + This->Pin.ConnectionIsExternal = FALSE; /* FIXME */ + //FIXME This->Pin.ConnectionInterface = Descriptor->PinDescriptor.Interfaces; + //FIXME This->Pin.ConnectionMedium = Descriptor->PinDescriptor.Mediums; + //FIXME This->Pin.ConnectionPriority = KSPRIORITY_NORMAL; + This->Pin.ConnectionFormat = (PKSDATAFORMAT) (Connect + 1); + This->Pin.AttributeList = NULL; //FIXME + This->Pin.StreamHeaderSize = sizeof(KSSTREAM_HEADER); + This->Pin.DataFlow = Descriptor->PinDescriptor.DataFlow; + This->Pin.DeviceState = KSSTATE_STOP; + This->Pin.ResetState = KSRESET_END; + This->Pin.ClientState = KSSTATE_STOP; + + /* intialize allocator create item */ + CreateItem[0].Context = (PVOID)This; + CreateItem[0].Create = IKsPin_DispatchCreateAllocator; + CreateItem[0].Flags = KSCREATE_ITEM_FREEONSTOP; + RtlInitUnicodeString(&CreateItem[0].ObjectClass, KSSTRING_Allocator); + + /* intialize clock create item */ + CreateItem[1].Context = (PVOID)This; + CreateItem[1].Create = IKsPin_DispatchCreateClock; + CreateItem[1].Flags = KSCREATE_ITEM_FREEONSTOP; + RtlInitUnicodeString(&CreateItem[1].ObjectClass, KSSTRING_Clock); + + /* intialize topology node create item */ + CreateItem[2].Context = (PVOID)This; + CreateItem[2].Create = IKsPin_DispatchCreateNode; + CreateItem[2].Flags = KSCREATE_ITEM_FREEONSTOP; + RtlInitUnicodeString(&CreateItem[2].ObjectClass, KSSTRING_TopologyNode); + + /* now allocate object header */ + Status = KsAllocateObjectHeader((KSOBJECT_HEADER*)&This->ObjectHeader, 3, CreateItem, Irp, &PinDispatchTable); + if (!NT_SUCCESS(Status)) + { + /* failed to create object header */ + KsFreeObjectBag((KSOBJECT_BAG)This->Pin.Bag); + FreeItem(This); + FreeItem(CreateItem); + + /* return failure code */ + return Status; + } + + /* add extra info to object header */ + This->ObjectHeader->Type = KsObjectTypePin; + This->ObjectHeader->Unknown = (PUNKNOWN)&This->lpVtbl; + This->ObjectHeader->ObjectType = (PVOID)&This->Pin; + + /* now inform the driver to create a new pin */ + Status = Descriptor->Dispatch->Create(&This->Pin, Irp); + + if (!NT_SUCCESS(Status) && Status != STATUS_PENDING) + { + /* failed to create pin, release resources */ + KsFreeObjectHeader((KSOBJECT_HEADER)This->ObjectHeader); + KsFreeObjectBag((KSOBJECT_BAG)This->Pin.Bag); + FreeItem(This); + + /* return failure code */ + return Status; + } + + /* FIXME add pin instance to filter instance */ + + return Status; +}