reactos/sdk/lib/drivers/wdf/shared/support/fxcollectionapi.cpp

390 lines
8.8 KiB
C++
Raw Normal View History

/*++
Copyright (c) Microsoft Corporation
Module Name:
FxCollectionApi.cpp
Abstract:
This module implements the "C" interface to the collection object.
Author:
Environment:
Both kernel and user mode
Revision History:
--*/
#include "fxsupportpch.hpp"
extern "C" {
// #include "FxCollectionApi.tmh"
}
//
// Extern the entire file
//
extern "C" {
_Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)
NTSTATUS
STDCALL
WDFEXPORT(WdfCollectionCreate)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in_opt
PWDF_OBJECT_ATTRIBUTES CollectionAttributes,
__out
WDFCOLLECTION *Collection
)
{
DDI_ENTRY();
PFX_DRIVER_GLOBALS pFxDriverGlobals;
NTSTATUS status;
FxCollection *pCollection;
WDFCOLLECTION hCol;
pFxDriverGlobals = GetFxDriverGlobals(DriverGlobals);
//
// Get the parent's globals if it is present
//
if (NT_SUCCESS(FxValidateObjectAttributesForParentHandle(
pFxDriverGlobals, CollectionAttributes))) {
FxObject* pParent;
FxObjectHandleGetPtrAndGlobals(pFxDriverGlobals,
CollectionAttributes->ParentObject,
FX_TYPE_OBJECT,
(PVOID*)&pParent,
&pFxDriverGlobals);
}
FxPointerNotNull(pFxDriverGlobals, Collection);
*Collection = NULL;
status = FxValidateObjectAttributes(pFxDriverGlobals, CollectionAttributes);
if (!NT_SUCCESS(status)) {
return status;
}
pCollection = new (pFxDriverGlobals, CollectionAttributes)
FxCollection(pFxDriverGlobals);
if (pCollection != NULL) {
status = pCollection->Commit(CollectionAttributes, (WDFOBJECT*)&hCol);
if (NT_SUCCESS(status)) {
*Collection = hCol;
}
else {
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGERROR,
"Could not create collection object: %!STATUS!",
status);
pCollection->DeleteFromFailedCreate();
}
}
else {
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGERROR,
"Could not create collection object: "
"STATUS_INSUFFICIENT_RESOURCES" );
status = STATUS_INSUFFICIENT_RESOURCES;
}
return status;
}
__drv_maxIRQL(DISPATCH_LEVEL)
ULONG
STDCALL
WDFEXPORT(WdfCollectionGetCount)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFCOLLECTION Collection
)
{
DDI_ENTRY();
FxCollection *pCollection;
KIRQL irql;
ULONG count;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
Collection,
FX_TYPE_COLLECTION,
(PVOID *)&pCollection);
pCollection->Lock(&irql);
count = pCollection->Count();
pCollection->Unlock(irql);
return count;
}
_Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)
NTSTATUS
STDCALL
WDFEXPORT(WdfCollectionAdd)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFCOLLECTION Collection,
__in
WDFOBJECT Object
)
{
DDI_ENTRY();
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxCollection *pCollection;
FxObject *pObject;
NTSTATUS status;
KIRQL irql;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
Collection,
FX_TYPE_COLLECTION,
(PVOID*) &pCollection,
&pFxDriverGlobals);
FxObjectHandleGetPtr(pFxDriverGlobals,
Object,
FX_TYPE_OBJECT,
(PVOID*) &pObject);
pCollection->Lock(&irql);
status = pCollection->Add(pObject) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
pCollection->Unlock(irql);
return status;
}
__drv_maxIRQL(DISPATCH_LEVEL)
VOID
STDCALL
WDFEXPORT(WdfCollectionRemoveItem)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFCOLLECTION Collection,
__in
ULONG Index
)
{
DDI_ENTRY();
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxCollection* pCollection;
FxCollectionEntry* pEntry;
FxObject* pObject;
NTSTATUS status;
KIRQL irql;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
Collection,
FX_TYPE_COLLECTION,
(PVOID*) &pCollection,
&pFxDriverGlobals);
pCollection->Lock(&irql);
pEntry = pCollection->FindEntry(Index);
if (pEntry != NULL) {
pObject = pEntry->m_Object;
pCollection->CleanupEntry(pEntry);
status = STATUS_SUCCESS;
}
else {
pObject = NULL;
status = STATUS_NOT_FOUND;
}
pCollection->Unlock(irql);
if (pObject != NULL) {
pCollection->CleanupEntryObject(pObject);
}
if (!NT_SUCCESS(status)) {
DoTraceLevelMessage(
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGERROR,
"Index %d is not valid in WDFCOLLECTION %p (count is %d), %!STATUS!",
Index, Collection, pCollection->Count(), status);
FxVerifierDbgBreakPoint(pFxDriverGlobals);
}
}
__drv_maxIRQL(DISPATCH_LEVEL)
VOID
STDCALL
WDFEXPORT(WdfCollectionRemove)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFCOLLECTION Collection,
__in
WDFOBJECT Item
)
{
DDI_ENTRY();
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxCollection *pCollection;
FxCollectionEntry *pEntry;
FxObject* pObject;
NTSTATUS status;
KIRQL irql;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
Collection,
FX_TYPE_COLLECTION,
(PVOID*) &pCollection,
&pFxDriverGlobals);
FxObjectHandleGetPtr(pFxDriverGlobals,
Item,
FX_TYPE_OBJECT,
(PVOID*) &pObject);
pCollection->Lock(&irql);
pEntry = pCollection->FindEntryByObject(pObject);
if (pEntry != NULL) {
pCollection->CleanupEntry(pEntry);
status = STATUS_SUCCESS;
}
else {
pObject = NULL;
status = STATUS_NOT_FOUND;
}
pCollection->Unlock(irql);
if (pObject != NULL) {
pCollection->CleanupEntryObject(pObject);
}
if (!NT_SUCCESS(status)) {
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGERROR,
"WDFOBJECT %p not in WDFCOLLECTION %p, %!STATUS!",
Item, Collection, status);
FxVerifierDbgBreakPoint(pFxDriverGlobals);
}
}
__drv_maxIRQL(DISPATCH_LEVEL)
WDFOBJECT
STDCALL
WDFEXPORT(WdfCollectionGetItem)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFCOLLECTION Collection,
__in
ULONG Index
)
{
DDI_ENTRY();
FxCollection *pCollection;
FxObject *pObject;
KIRQL irql;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
Collection,
FX_TYPE_COLLECTION,
(PVOID*) &pCollection);
pCollection->Lock(&irql);
pObject = pCollection->GetItem(Index);
pCollection->Unlock(irql);
if (pObject == NULL) {
return NULL;
}
return pObject->GetObjectHandle();
}
__drv_maxIRQL(DISPATCH_LEVEL)
WDFOBJECT
STDCALL
WDFEXPORT(WdfCollectionGetFirstItem)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFCOLLECTION Collection
)
{
DDI_ENTRY();
FxCollection *pCollection;
FxObject* pObject;
KIRQL irql;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
Collection,
FX_TYPE_COLLECTION,
(PVOID*) &pCollection);
pCollection->Lock(&irql);
pObject = pCollection->GetFirstItem();
pCollection->Unlock(irql);
if (pObject != NULL) {
return pObject->GetObjectHandle();
}
else {
return NULL;
}
}
__drv_maxIRQL(DISPATCH_LEVEL)
WDFOBJECT
STDCALL
WDFEXPORT(WdfCollectionGetLastItem)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFCOLLECTION Collection
)
{
DDI_ENTRY();
FxCollection *pCollection;
FxObject* pObject;
KIRQL irql;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
Collection,
FX_TYPE_COLLECTION,
(PVOID*) &pCollection);
pCollection->Lock(&irql);
pObject = pCollection->GetLastItem();
pCollection->Unlock(irql);
if (pObject != NULL) {
return pObject->GetObjectHandle();
}
else {
return NULL;
}
}
} // extern "C" of entire file