mirror of
https://github.com/reactos/reactos.git
synced 2025-06-01 07:28:19 +00:00
- Implement KsGetObjectFromFileObject, KsGetObjectFromFileObject, KsGetObjectTypeFromIrp, KsGetParent
- Create object bag for IKsFilter, IKsFilterFactory and IKsDevice svn path=/trunk/; revision=42275
This commit is contained in:
parent
ca60ae56c0
commit
64fa3b028f
7 changed files with 311 additions and 23 deletions
|
@ -509,6 +509,8 @@ KsAllocateDeviceHeader(
|
|||
InitializeListHead(&Header->TargetDeviceList);
|
||||
/* initialize power dispatch list */
|
||||
InitializeListHead(&Header->PowerDispatchList);
|
||||
/* initialize object bag lists */
|
||||
InitializeListHead(&Header->ObjectBags);
|
||||
|
||||
/* initialize create item list */
|
||||
InitializeListHead(&Header->ItemList);
|
||||
|
|
|
@ -9,8 +9,17 @@
|
|||
|
||||
#include "priv.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LIST_ENTRY Entry;
|
||||
PVOID Item;
|
||||
PFNKSFREE Free;
|
||||
ULONG References;
|
||||
}KSIOBJECT_BAG_ENTRY, *PKSIOBJECT_BAG_ENTRY;
|
||||
|
||||
|
||||
/*
|
||||
@unimplemented
|
||||
@implemented
|
||||
*/
|
||||
KSDDKAPI
|
||||
NTSTATUS
|
||||
|
@ -19,12 +28,56 @@ KsAllocateObjectBag(
|
|||
IN PKSDEVICE Device,
|
||||
OUT KSOBJECT_BAG* ObjectBag)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@unimplemented
|
||||
@implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
|
@ -33,12 +86,88 @@ KsAddItemToObjectBag(
|
|||
IN PVOID Item,
|
||||
IN PFNKSFREE Free OPTIONAL)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
@unimplemented
|
||||
@implemented
|
||||
*/
|
||||
KSDDKAPI
|
||||
ULONG
|
||||
|
@ -48,8 +177,61 @@ KsRemoveItemFromObjectBag(
|
|||
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,13 +248,54 @@ KsCopyObjectBagItems(
|
|||
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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -66,13 +66,26 @@ NTSTATUS
|
|||
NTAPI
|
||||
IKsDevice_fnInitializeObjectBag(
|
||||
IN IKsDevice * iface,
|
||||
IN struct KSIOBJECTBAG *Bag,
|
||||
IN KMUTANT * Mutant)
|
||||
IN PKSIOBJECT_BAG Bag,
|
||||
IN PRKMUTEX Mutex)
|
||||
{
|
||||
//PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
|
||||
PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
|
||||
|
||||
UNIMPLEMENTED
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
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 @@ KsInitializeDevice(
|
|||
PDEVICE_EXTENSION DeviceExtension;
|
||||
PKSIDEVICE_HEADER Header;
|
||||
ULONG Index;
|
||||
IKsDevice * KsDevice;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
/* get device extension */
|
||||
|
@ -645,15 +659,30 @@ KsInitializeDevice(
|
|||
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;
|
||||
Header->KsDevice.PhysicalDeviceObject = PhysicalDeviceObject;
|
||||
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 */
|
||||
|
||||
|
|
|
@ -831,6 +831,7 @@ KspCreateFilter(
|
|||
IN IKsFilterFactory *iface)
|
||||
{
|
||||
IKsFilterImpl * This;
|
||||
IKsDevice *KsDevice;
|
||||
PKSFILTERFACTORY Factory;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PDEVICE_EXTENSION DeviceExtension;
|
||||
|
@ -856,10 +857,24 @@ KspCreateFilter(
|
|||
/* 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;
|
||||
|
|
|
@ -173,6 +173,7 @@ IKsFilterFactory_fnInitialize(
|
|||
PDEVICE_EXTENSION DeviceExtension;
|
||||
KSOBJECT_CREATE_ITEM CreateItem;
|
||||
BOOL FreeString = FALSE;
|
||||
IKsDevice * KsDevice;
|
||||
|
||||
IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
|
||||
|
||||
|
@ -253,7 +254,14 @@ IKsFilterFactory_fnInitialize(
|
|||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -14,6 +14,15 @@
|
|||
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 @@ DECLARE_INTERFACE_(IKsPowerNotify, IUnknown)
|
|||
#undef INTERFACE
|
||||
#define INTERFACE IKsDevice
|
||||
|
||||
struct KSIOBJECTBAG;
|
||||
struct KSPOWER_ENTRY;
|
||||
|
||||
DECLARE_INTERFACE_(IKsDevice, IUnknown)
|
||||
|
@ -209,8 +217,8 @@ DECLARE_INTERFACE_(IKsDevice, IUnknown)
|
|||
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;
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#ifndef KSTYPES_H__
|
||||
#define KSTYPES_H__
|
||||
|
||||
#include <ntddk.h>
|
||||
#include <ks.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
KoCreateObjectHandler CreateObjectHandler;
|
||||
|
@ -87,10 +90,10 @@ typedef struct
|
|||
KSDEVICE_DESCRIPTOR* Descriptor;
|
||||
|
||||
LIST_ENTRY PowerDispatchList;
|
||||
LIST_ENTRY ObjectBags;
|
||||
|
||||
}KSIDEVICE_HEADER, *PKSIDEVICE_HEADER;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PKSIDEVICE_HEADER DeviceHeader;
|
||||
|
|
Loading…
Reference in a new issue