[ros-diffs] [janderwald] 42275: - Implement KsGetObjectFromFileObject, KsGetObjectFromFileObject, KsGetObjectTypeFromIrp, KsGetParent - Create object bag for IKsFilter, IKsFilterFactory and IKsDevice

janderwald at svn.reactos.org janderwald at svn.reactos.org
Tue Jul 28 18:18:05 CEST 2009


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?rev=42275&r1=42274&r2=42275&view=diff
==============================================================================
--- 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?rev=42275&r1=42274&r2=42275&view=diff
==============================================================================
--- 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.c?rev=42275&r1=42274&r2=42275&view=diff
==============================================================================
--- 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.c?rev=42275&r1=42274&r2=42275&view=diff
==============================================================================
--- 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/filterfactory.c?rev=42275&r1=42274&r2=42275&view=diff
==============================================================================
--- 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.h?rev=42275&r1=42274&r2=42275&view=diff
==============================================================================
--- 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.h?rev=42275&r1=42274&r2=42275&view=diff
==============================================================================
--- 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
 {




More information about the Ros-diffs mailing list