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/ksifac…
==============================================================================
--- 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?…
==============================================================================
--- 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;
+}