Author: janderwald Date: Tue Jul 28 18:18:05 2009 New Revision: 42275
URL: http://svn.reactos.org/svn/reactos?rev=42275&view=rev Log: - Implement KsGetObjectFromFileObject, KsGetObjectFromFileObject, KsGetObjectTypeFromIrp, KsGetParent - Create object bag for IKsFilter, IKsFilterFactory and IKsDevice
Modified: trunk/reactos/drivers/ksfilter/ks/api.c trunk/reactos/drivers/ksfilter/ks/bag.c trunk/reactos/drivers/ksfilter/ks/device.c trunk/reactos/drivers/ksfilter/ks/filter.c trunk/reactos/drivers/ksfilter/ks/filterfactory.c trunk/reactos/drivers/ksfilter/ks/ksiface.h trunk/reactos/drivers/ksfilter/ks/kstypes.h
Modified: trunk/reactos/drivers/ksfilter/ks/api.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/api.c?r... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/api.c [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/api.c [iso-8859-1] Tue Jul 28 18:18:05 2009 @@ -509,6 +509,8 @@ InitializeListHead(&Header->TargetDeviceList); /* initialize power dispatch list */ InitializeListHead(&Header->PowerDispatchList); + /* initialize object bag lists */ + InitializeListHead(&Header->ObjectBags);
/* initialize create item list */ InitializeListHead(&Header->ItemList);
Modified: trunk/reactos/drivers/ksfilter/ks/bag.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/bag.c?r... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/bag.c [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/bag.c [iso-8859-1] Tue Jul 28 18:18:05 2009 @@ -9,8 +9,17 @@
#include "priv.h"
-/* - @unimplemented +typedef struct +{ + LIST_ENTRY Entry; + PVOID Item; + PFNKSFREE Free; + ULONG References; +}KSIOBJECT_BAG_ENTRY, *PKSIOBJECT_BAG_ENTRY; + + +/* + @implemented */ KSDDKAPI NTSTATUS @@ -19,12 +28,56 @@ IN PKSDEVICE Device, OUT KSOBJECT_BAG* ObjectBag) { - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; -} - -/* - @unimplemented + PKSIDEVICE_HEADER DeviceHeader; + PKSIOBJECT_BAG Bag; + IKsDevice *KsDevice; + + /* get real device header */ + DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice); + + /* allocate a object bag ctx */ + Bag = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_BAG)); + if (!Bag) + return STATUS_INSUFFICIENT_RESOURCES; + + /* get device interface */ + KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice; + + /* initialize object bag */ + return KsDevice->lpVtbl->InitializeObjectBag(KsDevice, Bag, NULL); +} + +PKSIOBJECT_BAG_ENTRY +KspFindObjectBagItem( + IN PLIST_ENTRY ObjectList, + IN PVOID Item) +{ + PLIST_ENTRY Entry; + PKSIOBJECT_BAG_ENTRY BagEntry; + + /* point to first item */ + Entry = ObjectList->Flink; + /* first scan the list if the item is already inserted */ + while(Entry != ObjectList) + { + /* get bag entry */ + BagEntry = (PKSIOBJECT_BAG_ENTRY)CONTAINING_RECORD(Entry, KSIOBJECT_BAG_ENTRY, Entry); + + if (BagEntry->Item == Item) + { + /* found entry */ + return BagEntry; + } + /* move to next entry */ + Entry = Entry->Flink; + } + /* item not in this object bag */ + return NULL; +} + + +/* + @implemented */ NTSTATUS NTAPI @@ -33,12 +86,88 @@ IN PVOID Item, IN PFNKSFREE Free OPTIONAL) { - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; -} - -/* - @unimplemented + PKSIOBJECT_BAG Bag; + PKSIOBJECT_BAG_ENTRY BagEntry; + + /* get real object bag */ + Bag = (PKSIOBJECT_BAG)ObjectBag; + + /* acquire bag mutex */ + KeWaitForSingleObject(Bag->BagMutex, Executive, KernelMode, FALSE, NULL); + + /* is the item already present in this object bag */ + BagEntry = KspFindObjectBagItem(&Bag->ObjectList, Item); + + if (BagEntry) + { + /* is is, update reference count */ + InterlockedIncrement((PLONG)&BagEntry->References); + /* release mutex */ + KeReleaseMutex(Bag->BagMutex, FALSE); + /* return result */ + return STATUS_SUCCESS; + } + + /* item is new, allocate entry */ + BagEntry = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_BAG_ENTRY)); + if (!BagEntry) + { + /* no memory */ + KeReleaseMutex(Bag->BagMutex, FALSE); + /* return result */ + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* initialize bag entry */ + BagEntry->References = 1; + BagEntry->Item = Item; + if (Free) + BagEntry->Free = Free; + else + BagEntry->Free = ExFreePool; + + /* insert item */ + InsertTailList(&Bag->ObjectList, &Bag->Entry); + + /* release mutex */ + KeReleaseMutex(Bag->BagMutex, FALSE); + + /* done */ + return STATUS_SUCCESS; +} + +ULONG +KspGetObjectItemReferenceCount( + IN PKSIDEVICE_HEADER DeviceHeader, + IN PVOID Item) +{ + PLIST_ENTRY Entry; + PKSIOBJECT_BAG OtherBag; + PKSIOBJECT_BAG_ENTRY OtherBagEntry; + ULONG TotalRefs = 0; + + /* scan all object bags and see if item is present there */ + Entry = DeviceHeader->ObjectBags.Flink; + while(Entry != &DeviceHeader->ObjectBags) + { + /* get other bag */ + OtherBag = (PKSIOBJECT_BAG)CONTAINING_RECORD(Entry, KSIOBJECT_BAG, Entry); + + /* is the item present there */ + OtherBagEntry = KspFindObjectBagItem(&OtherBag->ObjectList, Item); + + if (OtherBagEntry) + TotalRefs++; + + /* move to next item */ + Entry = Entry->Flink; + } + + return TotalRefs; +} + +/* + @implemented */ KSDDKAPI ULONG @@ -48,8 +177,61 @@ IN PVOID Item, IN BOOLEAN Free) { - UNIMPLEMENTED - return 0; + PKSIOBJECT_BAG Bag; + PKSIOBJECT_BAG_ENTRY BagEntry; + ULONG TotalRefs; + + /* get real object bag */ + Bag = (PKSIOBJECT_BAG)ObjectBag; + + /* acquire bag mutex */ + KeWaitForSingleObject(Bag->BagMutex, Executive, KernelMode, FALSE, NULL); + + /* is the item already present in this object bag */ + BagEntry = KspFindObjectBagItem(&Bag->ObjectList, Item); + + if (!BagEntry) + { + /* item was not in this object bag */ + KeReleaseMutex(Bag->BagMutex, FALSE); + return 0; + } + + /* set current refs count */ + TotalRefs = BagEntry->References; + + /* get total refs count */ + TotalRefs += KspGetObjectItemReferenceCount((PKSIDEVICE_HEADER)Bag->DeviceHeader, Item); + + /* decrease reference count */ + InterlockedDecrement((PLONG)&BagEntry->References); + + if (BagEntry->References == 0) + { + /* remove the entry */ + RemoveEntryList(&BagEntry->Entry); + } + + if (TotalRefs == 1) + { + /* does the caller want to free the item */ + if (Free) + { + /* free the item */ + BagEntry->Free(BagEntry->Item); + } + } + if (BagEntry->References == 0) + { + /* free bag item entry */ + FreeItem(BagEntry); + } + + /* release mutex */ + KeReleaseMutex(Bag->BagMutex, FALSE); + + + return TotalRefs; }
/* @@ -66,14 +248,55 @@ return STATUS_NOT_IMPLEMENTED; }
+/* + @implemented +*/ KSDDKAPI VOID NTAPI KsFreeObjectBag( IN KSOBJECT_BAG ObjectBag) { - UNIMPLEMENTED -} - - - + PLIST_ENTRY Entry; + PKSIOBJECT_BAG Bag; + PKSIOBJECT_BAG_ENTRY BagEntry; + ULONG TotalRefs; + + /* get real object bag */ + Bag = (PKSIOBJECT_BAG)ObjectBag; + + /* acquire bag mutex */ + KeWaitForSingleObject(Bag->BagMutex, Executive, KernelMode, FALSE, NULL); + + while(!IsListEmpty(&Bag->ObjectList)) + { + /* get an bag entry */ + Entry = RemoveHeadList(&Bag->ObjectList); + /* access bag entry item */ + BagEntry = (PKSIOBJECT_BAG_ENTRY)CONTAINING_RECORD(Entry, KSIOBJECT_BAG, Entry); + + /* check if the item is present in some other bag */ + TotalRefs = KspGetObjectItemReferenceCount((PKSIDEVICE_HEADER)Bag->DeviceHeader, &BagEntry->Item); + + if (TotalRefs == 0) + { + /* item is ready to be freed */ + BagEntry->Free(BagEntry->Item); + } + + /* free bag entry item */ + FreeItem(BagEntry); + } + + /* remove bag entry from device object list */ + RemoveEntryList(&Bag->Entry); + + /* release bag mutex */ + KeReleaseMutex(Bag->BagMutex, FALSE); + + /* now free object bag */ + FreeItem(Bag); +} + + +
Modified: trunk/reactos/drivers/ksfilter/ks/device.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/device.... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/device.c [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/device.c [iso-8859-1] Tue Jul 28 18:18:05 2009 @@ -66,13 +66,26 @@ NTAPI IKsDevice_fnInitializeObjectBag( IN IKsDevice * iface, - IN struct KSIOBJECTBAG *Bag, - IN KMUTANT * Mutant) -{ - //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); - - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; + IN PKSIOBJECT_BAG Bag, + IN PRKMUTEX Mutex) +{ + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + + if (!Mutex) + { + /* use device mutex */ + Mutex = &This->DeviceMutex; + } + + /* initialize object bag */ + Bag->BagMutex = Mutex; + Bag->DeviceHeader = (PKSIDEVICE_HEADER)This; + InitializeListHead(&Bag->ObjectList); + + /* insert bag into device list */ + InsertTailList(&This->ObjectBags, &Bag->Entry); + + return STATUS_SUCCESS; }
NTSTATUS @@ -627,6 +640,7 @@ PDEVICE_EXTENSION DeviceExtension; PKSIDEVICE_HEADER Header; ULONG Index; + IKsDevice * KsDevice; NTSTATUS Status = STATUS_SUCCESS;
/* get device extension */ @@ -644,6 +658,23 @@ DPRINT1("Failed to allocate device header with %x\n", Status); return Status; } + + /* initialize IKsDevice interface */ + Header->lpVtblIKsDevice = &vt_IKsDevice; + Header->ref = 1; + + /* initialize object bag */ + Header->KsDevice.Bag = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_BAG)); + if (!Header->KsDevice.Bag) + { + /* no memory */ + KsFreeDeviceHeader((KSDEVICE_HEADER*)&DeviceExtension->DeviceHeader); + return STATUS_INSUFFICIENT_RESOURCES; + } + + KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice; + KsDevice->lpVtbl->InitializeObjectBag(KsDevice, Header->KsDevice.Bag, NULL); +
/* initialize device header */ Header->KsDevice.FunctionalDeviceObject = FunctionalDeviceObject; @@ -651,9 +682,7 @@ Header->KsDevice.NextDeviceObject = NextDeviceObject; Header->KsDevice.Descriptor = Descriptor; KsSetDevicePnpAndBaseObject(Header, PhysicalDeviceObject, NextDeviceObject); - /* initialize IKsDevice interface */ - Header->lpVtblIKsDevice = &vt_IKsDevice; - Header->ref = 1; +
/* FIXME Power state */
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] Tue Jul 28 18:18:05 2009 @@ -831,6 +831,7 @@ IN IKsFilterFactory *iface) { IKsFilterImpl * This; + IKsDevice *KsDevice; PKSFILTERFACTORY Factory; PIO_STACK_LOCATION IoStack; PDEVICE_EXTENSION DeviceExtension; @@ -856,10 +857,24 @@ /* get current irp stack */ IoStack = IoGetCurrentIrpStackLocation(Irp);
+ + /* initialize object bag */ + This->Filter.Bag = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_BAG)); + if (!This->Filter.Bag) + { + /* no memory */ + FreeItem(This); + return STATUS_INSUFFICIENT_RESOURCES; + } + + KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice; + KsDevice->lpVtbl->InitializeObjectBag(KsDevice, (PKSIOBJECT_BAG)This->Filter.Bag, NULL); + /* initialize filter instance */ This->ref = 1; This->lpVtbl = &vt_IKsFilter; This->lpVtblKsControl = &vt_IKsControl; + This->Filter.Descriptor = Factory->FilterDescriptor; This->Factory = Factory; This->FilterFactory = iface;
Modified: trunk/reactos/drivers/ksfilter/ks/filterfactory.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/filterf... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/filterfactory.c [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/filterfactory.c [iso-8859-1] Tue Jul 28 18:18:05 2009 @@ -173,6 +173,7 @@ PDEVICE_EXTENSION DeviceExtension; KSOBJECT_CREATE_ITEM CreateItem; BOOL FreeString = FALSE; + IKsDevice * KsDevice;
IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
@@ -253,7 +254,14 @@ /* return filterfactory */ *FilterFactory = &This->FilterFactory;
- /*FIXME create object bag */ + /* create a object bag for the filter factory */ + This->FilterFactory.Bag = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_BAG)); + if (This->FilterFactory.Bag) + { + /* initialize object bag */ + KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice; + KsDevice->lpVtbl->InitializeObjectBag(KsDevice, (PKSIOBJECT_BAG)This->FilterFactory.Bag, NULL); + } }
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] Tue Jul 28 18:18:05 2009 @@ -13,6 +13,15 @@ STDMETHOD_(ULONG,AddRef)(THIS) PURE; \ STDMETHOD_(ULONG,Release)(THIS) PURE; #endif + +typedef struct +{ + LIST_ENTRY Entry; + LIST_ENTRY ObjectList; + PRKMUTEX BagMutex; + PVOID DeviceHeader; +}KSIOBJECT_BAG, *PKSIOBJECT_BAG; +
/***************************************************************************** * IKsAllocator @@ -199,7 +208,6 @@ #undef INTERFACE #define INTERFACE IKsDevice
-struct KSIOBJECTBAG; struct KSPOWER_ENTRY;
DECLARE_INTERFACE_(IKsDevice, IUnknown) @@ -209,8 +217,8 @@ STDMETHOD_(KSDEVICE*,GetStruct)(THIS) PURE;
STDMETHOD_(NTSTATUS, InitializeObjectBag)(THIS_ - IN struct KSIOBJECTBAG *Bag, - IN KMUTANT * Mutant) PURE; + IN PKSIOBJECT_BAG Bag, + IN PRKMUTEX Mutex) PURE;
STDMETHOD_(NTSTATUS,AcquireDevice)(THIS) PURE; STDMETHOD_(NTSTATUS,ReleaseDevice)(THIS) PURE;
Modified: trunk/reactos/drivers/ksfilter/ks/kstypes.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/kstypes... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/kstypes.h [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/kstypes.h [iso-8859-1] Tue Jul 28 18:18:05 2009 @@ -1,5 +1,8 @@ #ifndef KSTYPES_H__ #define KSTYPES_H__ + +#include <ntddk.h> +#include <ks.h>
typedef struct { @@ -87,9 +90,9 @@ KSDEVICE_DESCRIPTOR* Descriptor;
LIST_ENTRY PowerDispatchList; + LIST_ENTRY ObjectBags;
}KSIDEVICE_HEADER, *PKSIDEVICE_HEADER; -
typedef struct {