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?…
==============================================================================
--- 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?…
==============================================================================
--- 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/filter…
==============================================================================
--- 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/ksifac…
==============================================================================
--- 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/kstype…
==============================================================================
--- 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
{