mirror of
https://github.com/reactos/reactos.git
synced 2025-05-11 13:27:47 +00:00
1336 lines
30 KiB
C++
1336 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"
|