reactos/sdk/lib/drivers/wdf/shared/support/fxresourceapi.cpp
2020-11-04 19:34:14 +03:00

1337 lines
30 KiB
C++

/*++
Copyright (c) Microsoft Corporation
Module Name:
FxResourceAPI.cpp
Abstract:
This module implements the resource class.
Author:
Environment:
Both kernel and user mode
Revision History:
--*/
#include "fxsupportpch.hpp"
extern "C" {
// #include "FxResourceAPI.tmh"
}
//
// Extern "C" the entire file
//
extern "C" {
__drv_maxIRQL(DISPATCH_LEVEL)
VOID
STDCALL
WDFEXPORT(WdfIoResourceRequirementsListSetSlotNumber)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFIORESREQLIST RequirementsList,
__in
ULONG SlotNumber
)
/*++
Routine Description:
Sets the slot number for a given resource requirements list
Arguments:
RequirementsList - list to be modified
SlotNumber - slot value to assign
Return Value:
None
--*/
{
FxIoResReqList* pIoResReqList;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
RequirementsList,
FX_TYPE_IO_RES_REQ_LIST,
(PVOID*) &pIoResReqList);
if (pIoResReqList->m_SlotNumber != SlotNumber) {
pIoResReqList->MarkChanged();
}
pIoResReqList->m_SlotNumber = SlotNumber;
}
__drv_maxIRQL(DISPATCH_LEVEL)
VOID
STDCALL
WDFEXPORT(WdfIoResourceRequirementsListSetInterfaceType)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFIORESREQLIST RequirementsList,
__in
__drv_strictTypeMatch(__drv_typeCond)
INTERFACE_TYPE InterfaceType
)
/*++
Routine Description:
Sets the InterfaceType for a given resource requirements list
Arguments:
RequirementsList - list to be modified
InterfaceType - interface type to assign
Return Value:
None
--*/
{
FxIoResReqList* pIoResReqList;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
RequirementsList,
FX_TYPE_IO_RES_REQ_LIST,
(PVOID*) &pIoResReqList);
if (pIoResReqList->m_InterfaceType != InterfaceType) {
pIoResReqList->MarkChanged();
}
pIoResReqList->m_InterfaceType = InterfaceType;
}
_Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)
NTSTATUS
FxIoResourceRequirementsListInsertIoResList(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFIORESREQLIST RequirementsList,
__in
WDFIORESLIST IoResList,
ULONG Index
)
/*++
Routine Description:
Inserts a resource list into a requirements list at a particular index.
Arguments:
RequirementsList - list to be modified
IoResList - resource list to add
Index - zero based index to insert at
Return Value:
NTSTATUS
--*/
{
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxIoResReqList* pIoResReqList;
FxIoResList* pIoResList;
NTSTATUS status;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
RequirementsList,
FX_TYPE_IO_RES_REQ_LIST,
(PVOID*) &pIoResReqList,
&pFxDriverGlobals);
FxObjectHandleGetPtr(pFxDriverGlobals,
IoResList,
FX_TYPE_IO_RES_LIST,
(PVOID*) &pIoResList);
if (pIoResList->m_OwningList != pIoResReqList) {
return STATUS_INVALID_DEVICE_REQUEST;
}
status = pIoResReqList->AddAt(Index, pIoResList);
if (NT_SUCCESS(status)) {
//
// Mirror the access flags as well.
//
pIoResList->m_AccessFlags = pIoResReqList->m_AccessFlags;
pIoResList->m_OwningList = pIoResReqList;
}
return status;
}
_Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)
NTSTATUS
STDCALL
WDFEXPORT(WdfIoResourceRequirementsListInsertIoResList)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFIORESREQLIST RequirementsList,
__in
WDFIORESLIST IoResList,
__in
ULONG Index
)
/*++
Routine Description:
Inserts a resource list into a requirements list at a particular index.
Arguments:
RequirementsList - list to be modified
IoResList - resource list to add
Index - zero based index to insert at
Return Value:
NTSTATUS
--*/
{
return FxIoResourceRequirementsListInsertIoResList(DriverGlobals,
RequirementsList,
IoResList,
Index);
}
_Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)
NTSTATUS
STDCALL
WDFEXPORT(WdfIoResourceRequirementsListAppendIoResList)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFIORESREQLIST RequirementsList,
__in
WDFIORESLIST IoResList
)
/*++
Routine Description:
Appends a resource list to a resource requirements list
Arguments:
RequirementsList - list to be modified
IoResList - resource list to append
Return Value:
NTSTATUS
--*/
{
return FxIoResourceRequirementsListInsertIoResList(DriverGlobals,
RequirementsList,
IoResList,
WDF_INSERT_AT_END);
}
__drv_maxIRQL(DISPATCH_LEVEL)
ULONG
STDCALL
WDFEXPORT(WdfIoResourceRequirementsListGetCount)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFIORESREQLIST RequirementsList
)
/*++
Routine Description:
Returns the number of resource lists in the requirements list
Arguments:
RequirementsList - requirements list whose count will be returned
Return Value:
number of elements in the list
--*/
{
FxIoResReqList* pList;
ULONG count;
KIRQL irql;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
RequirementsList,
FX_TYPE_IO_RES_REQ_LIST,
(PVOID*) &pList);
pList->Lock(&irql);
count = pList->Count();
pList->Unlock(irql);
return count;
}
__drv_maxIRQL(DISPATCH_LEVEL)
WDFIORESLIST
STDCALL
WDFEXPORT(WdfIoResourceRequirementsListGetIoResList)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFIORESREQLIST RequirementsList,
__in
ULONG Index
)
/*++
Routine Description:
Retrieves a resource list from the requirements list at a given index.
Arguments:
RequirementsList - list to retrieve the resource list from
Index - zero based index from which to retrieve the list
Return Value:
resource list handle or NULL
--*/
{
FxIoResReqList* pIoResReqList;
FxObject* pObject;
KIRQL irql;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
RequirementsList,
FX_TYPE_IO_RES_REQ_LIST,
(PVOID*) &pIoResReqList);
pIoResReqList->Lock(&irql);
pObject = pIoResReqList->GetItem(Index);
pIoResReqList->Unlock(irql);
if (pObject == NULL) {
return NULL;
}
else {
return (WDFIORESLIST) pObject->GetObjectHandle();
}
}
__drv_maxIRQL(DISPATCH_LEVEL)
VOID
STDCALL
WDFEXPORT(WdfIoResourceRequirementsListRemove)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFIORESREQLIST RequirementsList,
__in
ULONG Index
)
/*++
Routine Description:
Removes a resource list from the requirements list at a given index
Arguments:
RequirementsList - list of resource requirements which will be modified
Index - zero based index which indictes location in the list to find the
resource list
Return Value:
None
--*/
{
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxIoResReqList* pList;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
RequirementsList,
FX_TYPE_IO_RES_REQ_LIST,
(PVOID*) &pList,
&pFxDriverGlobals);
if (pList->RemoveAndDelete(Index) == FALSE) {
DoTraceLevelMessage(
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP,
"WDFIORESLIST %p, could not remove list at index %d (not found), "
"list item count is %d", RequirementsList, Index, pList->Count());
FxVerifierDbgBreakPoint(pFxDriverGlobals);
}
}
__drv_maxIRQL(DISPATCH_LEVEL)
VOID
STDCALL
WDFEXPORT(WdfIoResourceRequirementsListRemoveByIoResList)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFIORESREQLIST RequirementsList,
__in
WDFIORESLIST IoResList
)
/*++
Routine Description:
Removes a resource list from the requirements list based on the resource list's
handle
Arguments:
RequirementsList - resource requirements list being modified
IoResList - resource list to be removed
Return Value:
None
--*/
{
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxCollectionEntry* cur, *end;
FxIoResReqList* pList;
FxIoResList* pResList;
KIRQL irql;
BOOLEAN listFound;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
RequirementsList,
FX_TYPE_IO_RES_REQ_LIST,
(PVOID*) &pList,
&pFxDriverGlobals);
if (pList->IsRemoveAllowed() == FALSE) {
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP,
"WDFIORESREQLIST %p: Removes not allowed",
RequirementsList);
FxVerifierDbgBreakPoint(pFxDriverGlobals);
return;
}
FxObjectHandleGetPtr(pFxDriverGlobals,
IoResList,
FX_TYPE_IO_RES_LIST,
(PVOID*) &pResList);
pList->Lock(&irql);
cur = pList->Start();
end = pList->End();
listFound = FALSE;
while (cur != end) {
if (cur->m_Object == pResList) {
pList->MarkChanged();
pList->RemoveEntry(cur);
listFound = TRUE;
break;
}
cur = cur->Next();
}
pList->Unlock(irql);
if (listFound) {
pResList->DeleteObject();
pResList = NULL;
}
}
_Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)
NTSTATUS
STDCALL
WDFEXPORT(WdfIoResourceListCreate)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFIORESREQLIST RequirementsList,
__in_opt
PWDF_OBJECT_ATTRIBUTES Attributes,
__out
WDFIORESLIST* ResourceList
)
/*++
Routine Description:
Creates a resource list.
Arguments:
RequirementsList - the resource requirements list that the resource list will
be associated with
Attributes - generic object attributes for the new resource list
ResourceList - pointer which will receive the new object handle
Return Value:
NTSTATUS
--*/
{
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxIoResReqList* pIoResReqList;
FxIoResList* pIoResList;
NTSTATUS status;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
RequirementsList,
FX_TYPE_IO_RES_REQ_LIST,
(PVOID*) &pIoResReqList,
&pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, ResourceList);
*ResourceList = NULL;
status = FxValidateObjectAttributes(pFxDriverGlobals,
Attributes,
FX_VALIDATE_OPTION_PARENT_NOT_ALLOWED);
if (!NT_SUCCESS(status)) {
return status;
}
pIoResList = new (pFxDriverGlobals, Attributes) FxIoResList(
pFxDriverGlobals, pIoResReqList);
if (pIoResList == NULL) {
return STATUS_INSUFFICIENT_RESOURCES;
}
status = pIoResList->Commit(Attributes,
(WDFOBJECT*) ResourceList,
pIoResReqList);
if (!NT_SUCCESS(status)) {
pIoResList->DeleteFromFailedCreate();
}
return status;
}
_Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)
NTSTATUS
FxIoResourceListInsertDescriptor(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFIORESLIST ResourceList,
__in
PIO_RESOURCE_DESCRIPTOR Descriptor,
ULONG Index
)
/*++
Routine Description:
Inserts a descriptor into a resource list at a particular index.
Arguments:
ResourceList - list to be modified
Descriptor - descriptor to insert
Index - zero based index to insert at
Return Value:
NTSTATUS
--*/
{
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxIoResList* pList;
FxResourceIo* pObject;
NTSTATUS status;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
ResourceList,
FX_TYPE_IO_RES_LIST,
(PVOID*) &pList,
&pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, Descriptor);
if (pList->m_OwningList->IsAddAllowed() == FALSE) {
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP,
"Removes not allowed on WDFIORESLIST %p",
ResourceList);
FxVerifierDbgBreakPoint(pFxDriverGlobals);
return STATUS_ACCESS_DENIED;
}
pObject = new(pFxDriverGlobals)
FxResourceIo(pFxDriverGlobals, Descriptor);
if (pObject == NULL) {
return STATUS_INSUFFICIENT_RESOURCES;
}
status = pObject->AssignParentObject(pList);
if (!NT_SUCCESS(status)) {
pObject->DeleteObject();
return status;
}
status = pList->AddAt(Index, pObject);
//
// Mark both this list and its owning list as changed so when it comes
// time to evaluate the entire requirements list for changes, we do not
// have to iterate over all the resource lists.
//
if (NT_SUCCESS(status)) {
pList->m_OwningList->MarkChanged();
}
return status;
}
_Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)
NTSTATUS
STDCALL
WDFEXPORT(WdfIoResourceListInsertDescriptor)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFIORESLIST ResourceList,
__in
PIO_RESOURCE_DESCRIPTOR Descriptor,
__in
ULONG Index
)
/*++
Routine Description:
Inserts a descriptor into a resource list at a particular index.
Arguments:
ResourceList - list to be modified
Descriptor - descriptor to insert
Index - zero based index to insert at
Return Value:
NTSTATUS
--*/
{
return FxIoResourceListInsertDescriptor(DriverGlobals,
ResourceList,
Descriptor,
Index);
}
_Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)
NTSTATUS
STDCALL
WDFEXPORT(WdfIoResourceListAppendDescriptor)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFIORESLIST ResourceList,
__in
PIO_RESOURCE_DESCRIPTOR Descriptor
)
/*++
Routine Description:
Appends a descriptor to a resource list
Arguments:
ResourceList - list to be modified
Descriptor - item to be appended
Return Value:
NTSTATUS
--*/
{
return FxIoResourceListInsertDescriptor(DriverGlobals,
ResourceList,
Descriptor,
WDF_INSERT_AT_END);
}
__drv_maxIRQL(DISPATCH_LEVEL)
VOID
STDCALL
WDFEXPORT(WdfIoResourceListUpdateDescriptor)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFIORESLIST ResourceList,
__in
PIO_RESOURCE_DESCRIPTOR Descriptor,
__in
ULONG Index
)
/*++
Routine Description:
Updates resource requirement in place in the list.
Arguments:
ResourceList - list to be modified
Descriptor - Pointer to descriptor whic contains the updated value
Index - zero based location in the list to update
Return Value:
None
--*/
{
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxIoResList* pList;
FxResourceIo* pObject;
KIRQL irql;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
ResourceList,
FX_TYPE_IO_RES_LIST,
(PVOID*) &pList,
&pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, Descriptor);
pList->Lock(&irql);
pObject = (FxResourceIo*) pList->GetItem(Index);
pList->Unlock(irql);
if (pObject != NULL) {
//
// We don't check for add or remove access because we don't know what
// the update is actually doing (ie widening a range, shortening it, etc).
// For this operation we have to trust the driver that it is doing the
// right thing at the right time.
//
RtlCopyMemory(&pObject->m_Descriptor,
Descriptor,
sizeof(pObject->m_Descriptor));
//
// Mark both this list and its owning list as changed so when it comes
// time to evaluate the entire requirements list for changes, we do not
// have to iterate over all the resource lists.
//
pList->MarkChanged();
pList->m_OwningList->MarkChanged();
}
else {
DoTraceLevelMessage(
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP,
"WDFIORESREQLIST %p, cannot update item at index %d, item not found,"
" list item count is %d", ResourceList, Index, pList->Count());
FxVerifierDbgBreakPoint(pFxDriverGlobals);
}
}
__drv_maxIRQL(DISPATCH_LEVEL)
ULONG
STDCALL
WDFEXPORT(WdfIoResourceListGetCount)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFIORESLIST ResourceList
)
/*++
Routine Description:
Returns the number of descriptors in the resource list
Arguments:
ResourceList - resource list whose count will be returned
Return Value:
number of elements in the list
--*/
{
FxIoResList* pList;
ULONG count;
KIRQL irql;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
ResourceList,
FX_TYPE_IO_RES_LIST,
(PVOID*) &pList);
pList->Lock(&irql);
count = pList->Count();
pList->Unlock(irql);
return count;
}
__drv_maxIRQL(DISPATCH_LEVEL)
PIO_RESOURCE_DESCRIPTOR
STDCALL
WDFEXPORT(WdfIoResourceListGetDescriptor)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFIORESLIST ResourceList,
__in
ULONG Index
)
/*++
Routine Description:
Retrieves an io resource desciptor for a given index in the resource list
Arguments:
ResourceList - list being looked up
Index - zero based index into the list to find the value of
Return Value:
pointer to an io resource descriptor upon success, NULL upon error
--*/
{
FxIoResList* pList;
FxResourceIo* pObject;
KIRQL irql;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
ResourceList,
FX_TYPE_IO_RES_LIST,
(PVOID*) &pList);
pList->Lock(&irql);
pObject = (FxResourceIo*) pList->GetItem(Index);
pList->Unlock(irql);
if (pObject == NULL) {
return NULL;
}
else {
//
// Copy the current descriptor to the clone and return it
//
RtlCopyMemory(&pObject->m_DescriptorClone,
&pObject->m_Descriptor,
sizeof(pObject->m_Descriptor));
return &pObject->m_DescriptorClone;
}
}
__drv_maxIRQL(DISPATCH_LEVEL)
VOID
STDCALL
WDFEXPORT(WdfIoResourceListRemove)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFIORESLIST ResourceList,
__in
ULONG Index
)
/*++
Routine Description:
Removes a descriptor in an io resource list
Arguments:
ResourceList - resource list to modify
Index - zero based index into the list in which to remove the descriptor
Return Value:
None
--*/
{
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxIoResList* pList;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
ResourceList,
FX_TYPE_IO_RES_LIST,
(PVOID*) &pList,
&pFxDriverGlobals);
if (pList->RemoveAndDelete(Index)) {
//
// Mark this list's owning list as changed so when it comes
// time to evaluate the entire requirements list for changes, we do not
// have to iterate over all the resource lists.
//
// RemoveAndDelete marked pList as changed already
//
pList->m_OwningList->MarkChanged();
}
else {
DoTraceLevelMessage(
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP,
"WDFIORESLIST %p, could not remove item at index %d (not found), "
"list item count is %d", ResourceList, Index, pList->Count());
FxVerifierDbgBreakPoint(pFxDriverGlobals);
}
}
__drv_maxIRQL(DISPATCH_LEVEL)
VOID
STDCALL
WDFEXPORT(WdfIoResourceListRemoveByDescriptor)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFIORESLIST ResourceList,
__in
PIO_RESOURCE_DESCRIPTOR Descriptor
)
/*++
Routine Description:
Removes a descriptor by value in a given io resource list. Equality is
determined by RtlCompareMemory.
Arguments:
ResourceList - the io resource list to modify
Descriptor - pointer to a descriptor to remove.
Return Value:
None
--*/
{
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxCollectionEntry* cur, *end;
FxIoResList* pList;
FxResourceIo* pObject;
KIRQL irql;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
ResourceList,
FX_TYPE_IO_RES_LIST,
(PVOID*) &pList,
&pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, Descriptor);
if (pList->IsRemoveAllowed() == FALSE) {
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP,
"Removes not allowed on WDFIORESLIST %p",
ResourceList);
FxVerifierDbgBreakPoint(pFxDriverGlobals);
return;
}
pList->Lock(&irql);
cur = pList->Start();
end = pList->End();
pObject = NULL;
while (cur != end) {
pObject = (FxResourceIo*) cur->m_Object;
if (RtlCompareMemory(&pObject->m_Descriptor,
Descriptor,
sizeof(*Descriptor)) == sizeof(*Descriptor)) {
//
// Mark both this list and its owning list as changed so when it
// comes time to evaluate the entire requirements list for
// changes, we do not have to iterate over all the resource lists.
//
pList->MarkChanged();
pList->m_OwningList->MarkChanged();
pList->RemoveEntry(cur);
break;
}
//
// Set to NULL so that we do not delete it if this is the last item in
// the list.
//
pObject = NULL;
cur = cur->Next();
}
pList->Unlock(irql);
if (pObject != NULL) {
pObject->DeleteObject();
}
}
_Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)
NTSTATUS
FxCmResourceListInsertDescriptor(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFCMRESLIST List,
__in
PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor,
__in
ULONG Index
)
/*++
Routine Description:
Inserts a descriptor into a cm resource list at a particular index.
Arguments:
ResourceList - list to be modified
Descriptor - descriptor to insert
Index - zero based index to insert at
Return Value:
NTSTATUS
--*/
{
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxCmResList* pList;
FxResourceCm* pObject;
NTSTATUS status;
pFxDriverGlobals = GetFxDriverGlobals(DriverGlobals);
FxPointerNotNull(pFxDriverGlobals, Descriptor);
FxObjectHandleGetPtr(pFxDriverGlobals,
List,
FX_TYPE_CM_RES_LIST,
(PVOID*) &pList);
pObject = new(pFxDriverGlobals) FxResourceCm(pFxDriverGlobals, Descriptor);
if (pObject == NULL) {
return STATUS_INSUFFICIENT_RESOURCES;
}
status = pObject->AssignParentObject(pList);
if (!NT_SUCCESS(status)) {
pObject->DeleteObject();
return status;
}
return pList->AddAt(Index, pObject);
}
_Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)
NTSTATUS
STDCALL
WDFEXPORT(WdfCmResourceListInsertDescriptor)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFCMRESLIST List,
__in
PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor,
__in
ULONG Index
)
/*++
Routine Description:
Inserts a descriptor into a cm resource list at a particular index.
Arguments:
ResourceList - list to be modified
Descriptor - descriptor to insert
Index - zero based index to insert at
Return Value:
NTSTATUS
--*/
{
DDI_ENTRY();
return FxCmResourceListInsertDescriptor(DriverGlobals,
List,
Descriptor,
Index);
}
_Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)
NTSTATUS
STDCALL
WDFEXPORT(WdfCmResourceListAppendDescriptor)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFCMRESLIST List,
__in
PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
)
/*++
Routine Description:
Appends a descriptor to a cm resource list
Arguments:
ResourceList - list to be modified
Descriptor - item to be appended
Return Value:
NTSTATUS
--*/
{
DDI_ENTRY();
return FxCmResourceListInsertDescriptor(DriverGlobals,
List,
Descriptor,
WDF_INSERT_AT_END);
}
__drv_maxIRQL(DISPATCH_LEVEL)
ULONG
STDCALL
WDFEXPORT(WdfCmResourceListGetCount)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFCMRESLIST List
)
/*++
Routine Description:
Returns the number of cm descriptors in the resource list
Arguments:
ResourceList - resource list whose count will be returned
Return Value:
number of elements in the list
--*/
{
FxCmResList* pList;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
List,
FX_TYPE_CM_RES_LIST,
(PVOID*) &pList);
return pList->GetCount();
}
__drv_maxIRQL(DISPATCH_LEVEL)
PCM_PARTIAL_RESOURCE_DESCRIPTOR
STDCALL
WDFEXPORT(WdfCmResourceListGetDescriptor)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFCMRESLIST List,
__in
ULONG Index
)
/*++
Routine Description:
Retrieves a cm resource desciptor for a given index in the resource list
Arguments:
ResourceList - list being looked up
Index - zero based index into the list to find the value of
Return Value:
pointer to a cm resource descriptor upon success, NULL upon error
--*/
{
DDI_ENTRY();
FxCmResList* pList;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
List,
FX_TYPE_CM_RES_LIST,
(PVOID*) &pList);
return pList->GetDescriptor(Index);
}
__drv_maxIRQL(DISPATCH_LEVEL)
VOID
STDCALL
WDFEXPORT(WdfCmResourceListRemove)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFCMRESLIST List,
__in
ULONG Index
)
/*++
Routine Description:
Removes a descriptor in an cm resource list
Arguments:
ResourceList - resource list to modify
Index - zero based index into the list in which to remove the descriptor
Return Value:
None
--*/
{
DDI_ENTRY();
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxCmResList* pList;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
List,
FX_TYPE_CM_RES_LIST,
(PVOID*) &pList,
&pFxDriverGlobals);
if (pList->RemoveAndDelete(Index) == FALSE) {
DoTraceLevelMessage(
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP,
"WDFCMRESLIST %p, could not remove list at index %d (not found), "
"list item count is %d", List, Index, pList->Count());
FxVerifierDbgBreakPoint(pFxDriverGlobals);
}
}
__drv_maxIRQL(DISPATCH_LEVEL)
VOID
STDCALL
WDFEXPORT(WdfCmResourceListRemoveByDescriptor)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFCMRESLIST List,
__in
PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
)
/*++
Routine Description:
Removes a descriptor by value in a given cm resource list. Equality is
determined by RtlCompareMemory.
Arguments:
ResourceList - the io resource list to modify
Descriptor - pointer to a descriptor to remove.
Return Value:
None
--*/
{
DDI_ENTRY();
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxCollectionEntry* cur;
FxCollectionEntry* end;
FxCmResList* pList;
FxResourceCm* pObject;
KIRQL irql;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
List,
FX_TYPE_CM_RES_LIST,
(PVOID*) &pList,
&pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, Descriptor);
if (pList->IsRemoveAllowed() == FALSE) {
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP,
"Removes not allowed on WDFCMRESLIST %p", List);
FxVerifierDbgBreakPoint(pFxDriverGlobals);
return;
}
pList->Lock(&irql);
cur = pList->Start();
end = pList->End();
pObject = NULL;
while (cur != end) {
pObject = (FxResourceCm*) cur->m_Object;
if (RtlCompareMemory(&pObject->m_Descriptor,
Descriptor,
sizeof(*Descriptor)) == sizeof(*Descriptor)) {
pList->MarkChanged();
pList->RemoveEntry(cur);
break;
}
//
// Set to NULL so that we do not delete it if this is the last item in
// the list.
//
pObject = NULL;
cur = cur->Next();
}
pList->Unlock(irql);
if (pObject != NULL) {
pObject->DeleteObject();
pObject = NULL;
}
}
} // extern "C"