Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286/*++
Copyright (c) Microsoft Corporation
Module Name:
FxCollection.cpp
Abstract:
This module implements a simple collection class to operate on objects derived from FxObject.
Author:
Environment:
Both kernel and user mode
Revision History:
--*/
#include "fxsupportpch.hpp"
FxCollectionInternal::FxCollectionInternal( VOID ){ m_Count = 0; InitializeListHead(&m_ListHead);}
FxCollectionInternal::~FxCollectionInternal( VOID ){ Clear();}
VOIDFxCollectionInternal::Clear( VOID ){ while (!IsListEmpty(&m_ListHead)) { Remove(0); }}
ULONGFxCollectionInternal::Count( VOID ){ return m_Count;}
BOOLEANFxCollectionInternal::Add( __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObject *Item ){ FxCollectionEntry *pNode;
pNode = AllocateEntry(FxDriverGlobals);
if (pNode != NULL) { InsertTailList(&m_ListHead, &pNode->m_ListEntry);
AddEntry(pNode, Item); }
return pNode != NULL;}
_Must_inspect_result_FxCollectionEntry*FxCollectionInternal::FindEntry( __in ULONG Index ){ PLIST_ENTRY ple; ULONG i;
if (Index >= m_Count) { return NULL; }
for (i = 0, ple = m_ListHead.Flink; ple != &m_ListHead; ple = ple->Flink, i++) { if (i != Index) { continue; }
return CONTAINING_RECORD(ple, FxCollectionEntry, m_ListEntry); }
return NULL;}
_Must_inspect_result_FxCollectionEntry*FxCollectionInternal::FindEntryByObject( __in FxObject* Object ){ PLIST_ENTRY ple;
for (ple = m_ListHead.Flink; ple != &m_ListHead; ple = ple->Flink) { FxCollectionEntry* pNode;
pNode = CONTAINING_RECORD(ple, FxCollectionEntry, m_ListEntry); if (pNode->m_Object == Object) { return pNode; } }
return NULL;}
NTSTATUSFxCollectionInternal::Remove( __in ULONG Index ){ FxCollectionEntry *pNode;
pNode = FindEntry(Index);
if (pNode != NULL) { return RemoveEntry(pNode); } else { return STATUS_NOT_FOUND; }}
_Must_inspect_result_NTSTATUSFxCollectionInternal::RemoveItem( __in FxObject* Item ){ FxCollectionEntry* pNode;
pNode = FindEntryByObject(Item);
if (pNode != NULL) { return RemoveEntry(pNode); }
return STATUS_NOT_FOUND;}
VOIDFxCollectionInternal::CleanupEntry( __in FxCollectionEntry* Entry ){ RemoveEntryList(&Entry->m_ListEntry); delete Entry;
m_Count--;}
NTSTATUSFxCollectionInternal::RemoveEntry( __in FxCollectionEntry* Entry ){ CleanupEntryObject(Entry->m_Object); CleanupEntry(Entry);
return STATUS_SUCCESS;}
_Must_inspect_result_FxObject*FxCollectionInternal::GetItem( __in ULONG Index )
{ FxCollectionEntry* pNode;
pNode = FindEntry(Index); if (pNode != NULL) { return pNode->m_Object; } else { return NULL; }}
_Must_inspect_result_FxObject*FxCollectionInternal::GetFirstItem( VOID ){ if (IsListEmpty(&m_ListHead)) { return NULL; } else { return CONTAINING_RECORD(m_ListHead.Flink, FxCollectionEntry, m_ListEntry)->m_Object; }}
_Must_inspect_result_FxObject*FxCollectionInternal::GetLastItem( VOID ){ if (IsListEmpty(&m_ListHead)) { return NULL; } else { return CONTAINING_RECORD(m_ListHead.Blink, FxCollectionEntry, m_ListEntry)->m_Object; }}
FxCollection::FxCollection( __in PFX_DRIVER_GLOBALS FxDriverGlobals ) : FxNonPagedObject(FX_TYPE_COLLECTION, sizeof(FxCollection), FxDriverGlobals){}
FxCollection::FxCollection( __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in WDFTYPE Type, __in USHORT Size ) : FxNonPagedObject(Type, Size, FxDriverGlobals){}
FxCollection::~FxCollection( VOID ){ Clear();}
VOIDFxCollection::StealCollection( __in FxCollection* Collection ){ PLIST_ENTRY ple;
m_Count = Collection->m_Count; Collection->m_Count = 0;
while (!IsListEmpty(&Collection->m_ListHead)) { FxCollectionEntry* pEntry;
ple = RemoveHeadList(&Collection->m_ListHead); pEntry = CONTAINING_RECORD(ple, FxCollectionEntry, m_ListEntry);
// // When we are tracking reference tags, the tag associated with the // reference matters. When we added the object to Collection, we used // that pointer as the tag. We must remove that tag and readd the // reference using the this value as a tag. // // Obviously, order is important here. Add the reference first so that // we know the relese will make the object go away. // pEntry->m_Object->ADDREF(this); pEntry->m_Object->RELEASE(Collection);
InsertTailList(&m_ListHead, ple); }}