mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 16:12:58 +00:00
[WDF] Add Windows Driver Framework files
Takern from Microsoft GitHub repo:
d9c6040fe9
Licensed under MIT
This commit is contained in:
parent
545df81502
commit
8a978a179f
475 changed files with 285099 additions and 0 deletions
285
sdk/lib/drivers/wdf/shared/support/fxcollection.cpp
Normal file
285
sdk/lib/drivers/wdf/shared/support/fxcollection.cpp
Normal file
|
@ -0,0 +1,285 @@
|
|||
/*++
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
VOID
|
||||
FxCollectionInternal::Clear(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
while (!IsListEmpty(&m_ListHead)) {
|
||||
Remove(0);
|
||||
}
|
||||
}
|
||||
|
||||
ULONG
|
||||
FxCollectionInternal::Count(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return m_Count;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
FxCollectionInternal::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;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
FxCollectionInternal::Remove(
|
||||
__in ULONG Index
|
||||
)
|
||||
{
|
||||
FxCollectionEntry *pNode;
|
||||
|
||||
pNode = FindEntry(Index);
|
||||
|
||||
if (pNode != NULL) {
|
||||
return RemoveEntry(pNode);
|
||||
}
|
||||
else {
|
||||
return STATUS_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
_Must_inspect_result_
|
||||
NTSTATUS
|
||||
FxCollectionInternal::RemoveItem(
|
||||
__in FxObject* Item
|
||||
)
|
||||
{
|
||||
FxCollectionEntry* pNode;
|
||||
|
||||
pNode = FindEntryByObject(Item);
|
||||
|
||||
if (pNode != NULL) {
|
||||
return RemoveEntry(pNode);
|
||||
}
|
||||
|
||||
return STATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
VOID
|
||||
FxCollectionInternal::CleanupEntry(
|
||||
__in FxCollectionEntry* Entry
|
||||
)
|
||||
{
|
||||
RemoveEntryList(&Entry->m_ListEntry);
|
||||
delete Entry;
|
||||
|
||||
m_Count--;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
FxCollectionInternal::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();
|
||||
}
|
||||
|
||||
VOID
|
||||
FxCollection::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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue