mirror of
https://github.com/reactos/reactos.git
synced 2025-08-07 03:03:13 +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
739
sdk/lib/drivers/wdf/shared/support/fxresourcecollection.cpp
Normal file
739
sdk/lib/drivers/wdf/shared/support/fxresourcecollection.cpp
Normal file
|
@ -0,0 +1,739 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
FxResourceCollection.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
This module implements a base object for derived collection classes and
|
||||
the derived collection classes.
|
||||
|
||||
Author:
|
||||
|
||||
|
||||
|
||||
Environment:
|
||||
|
||||
Both kernel and user mode
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#include "FxSupportPch.hpp"
|
||||
|
||||
extern "C" {
|
||||
#if defined(EVENT_TRACING)
|
||||
#include "FxResourceCollection.tmh"
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
FxResourceCollection::RemoveAndDelete(
|
||||
__in ULONG Index
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Removes an entry from the collection and then deletes it if found. The
|
||||
caller must have removal permissions to perform this action.
|
||||
|
||||
Arguments:
|
||||
Index - zero based index into the collection at which to perform the removal
|
||||
|
||||
Return Value:
|
||||
TRUE if the item was found and deleted, FALSE otherwise
|
||||
|
||||
--*/
|
||||
{
|
||||
FxObject* pObject;
|
||||
FxCollectionEntry* pEntry;
|
||||
KIRQL irql;
|
||||
|
||||
if (IsRemoveAllowed() == FALSE) {
|
||||
DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
|
||||
"Removes not allowed on handle %p, remove at index %d"
|
||||
"failed", GetObjectHandle(), Index);
|
||||
|
||||
FxVerifierDbgBreakPoint(GetDriverGlobals());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pObject = NULL;
|
||||
|
||||
Lock(&irql);
|
||||
|
||||
pEntry = FindEntry(Index);
|
||||
if (pEntry != NULL) {
|
||||
|
||||
//
|
||||
// Mark the list as changed so when we go to create a WDM resource list we
|
||||
// know if a new list is needed.
|
||||
//
|
||||
MarkChanged();
|
||||
|
||||
pObject = pEntry->m_Object;
|
||||
|
||||
//
|
||||
// Remove the entry
|
||||
//
|
||||
RemoveEntry(pEntry);
|
||||
}
|
||||
Unlock(irql);
|
||||
|
||||
if (pObject != NULL) {
|
||||
//
|
||||
// Delete the object since we created it
|
||||
//
|
||||
pObject->DeleteObject();
|
||||
pObject = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
_Must_inspect_result_
|
||||
NTSTATUS
|
||||
FxResourceCollection::AddAt(
|
||||
__in ULONG Index,
|
||||
__in FxObject* Object
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Adds an object into the collection at the specified index.
|
||||
|
||||
Arguments:
|
||||
Index - zero baesd index in which to insert into the list. WDF_INSERT_AT_END
|
||||
is a special value which indicates that the insertion is an append.
|
||||
|
||||
Object - object to add
|
||||
|
||||
Return Value:
|
||||
NTSTATUS
|
||||
|
||||
--*/
|
||||
{
|
||||
FxCollectionEntry *pNew;
|
||||
PLIST_ENTRY ple;
|
||||
NTSTATUS status;
|
||||
KIRQL irql;
|
||||
|
||||
if (IsAddAllowed() == FALSE) {
|
||||
DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
|
||||
"Adds not allowed on handle %p, add at index %d"
|
||||
"failed", GetObjectHandle(), Index);
|
||||
|
||||
FxVerifierDbgBreakPoint(GetDriverGlobals());
|
||||
|
||||
return STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
Lock(&irql);
|
||||
|
||||
ple = NULL;
|
||||
status = STATUS_SUCCESS;
|
||||
|
||||
pNew = AllocateEntry(GetDriverGlobals());
|
||||
|
||||
if (pNew != NULL) {
|
||||
//
|
||||
// Inserting at the current count (i.e. one past the end) is the same
|
||||
// as append.
|
||||
//
|
||||
if (Index == WDF_INSERT_AT_END || Index == Count()) {
|
||||
ple = &m_ListHead;
|
||||
}
|
||||
else {
|
||||
FxCollectionEntry* cur, *end;
|
||||
ULONG i;
|
||||
|
||||
for (cur = Start(), end = End(), i = 0;
|
||||
cur != end;
|
||||
cur = cur->Next(), i++) {
|
||||
if (i == Index) {
|
||||
ple = &cur->m_ListEntry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ple == NULL) {
|
||||
delete pNew;
|
||||
status = STATUS_ARRAY_BOUNDS_EXCEEDED;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
PLIST_ENTRY blink;
|
||||
|
||||
// ple now points to the list entry which we will insert our node
|
||||
// *before*
|
||||
|
||||
blink = ple->Blink;
|
||||
|
||||
// Link the previous with the new entry
|
||||
blink->Flink = &pNew->m_ListEntry;
|
||||
pNew->m_ListEntry.Blink = blink;
|
||||
|
||||
// Link the current with the new entry
|
||||
pNew->m_ListEntry.Flink = ple;
|
||||
ple->Blink = &pNew->m_ListEntry;
|
||||
|
||||
AddEntry(pNew, Object);
|
||||
|
||||
//
|
||||
// Mark the list as changed so when we go to create a WDM resource list
|
||||
// we know if a new list is needed.
|
||||
//
|
||||
MarkChanged();
|
||||
}
|
||||
|
||||
Unlock(irql);
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
Object->DeleteFromFailedCreate();
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
_Must_inspect_result_
|
||||
NTSTATUS
|
||||
FxIoResList::BuildFromWdmList(
|
||||
__deref_in PIO_RESOURCE_LIST* WdmResourceList
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Builds up the collection with FxResourceIo objects based on the passed in
|
||||
WDM io resource list
|
||||
|
||||
Arguments:
|
||||
WdmResourceList - list which specifies the io resource objects to create
|
||||
|
||||
Return Value:
|
||||
NTSTATUS
|
||||
|
||||
--*/
|
||||
{
|
||||
PIO_RESOURCE_DESCRIPTOR pWdmDescriptor;
|
||||
ULONG i, count;
|
||||
NTSTATUS status;
|
||||
|
||||
pWdmDescriptor = &(*WdmResourceList)->Descriptors[0];
|
||||
count = (*WdmResourceList)->Count;
|
||||
status = STATUS_SUCCESS;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
//
|
||||
// Now create a new resource object for each resource
|
||||
// in our list.
|
||||
//
|
||||
FxResourceIo *pResource;
|
||||
|
||||
pResource = new(GetDriverGlobals())
|
||||
FxResourceIo(GetDriverGlobals(), pWdmDescriptor);
|
||||
|
||||
if (pResource == NULL) {
|
||||
//
|
||||
// We failed, clean up, and exit. Since we are only
|
||||
// keeping references on the master collection, if
|
||||
// we free this, everything else will go away too.
|
||||
//
|
||||
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
status = pResource->AssignParentObject(this);
|
||||
|
||||
//
|
||||
// See notes in previous AssignParentObject as to why
|
||||
// we are asserting.
|
||||
//
|
||||
ASSERT(NT_SUCCESS(status));
|
||||
UNREFERENCED_PARAMETER(status);
|
||||
|
||||
status = Add(pResource) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
pWdmDescriptor++;
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
status = m_OwningList->Add(this) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
*WdmResourceList = (PIO_RESOURCE_LIST) pWdmDescriptor;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
_Must_inspect_result_
|
||||
NTSTATUS
|
||||
FxCmResList::BuildFromWdmList(
|
||||
__in PCM_RESOURCE_LIST WdmResourceList,
|
||||
__in UCHAR AccessFlags
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Builds up the collection with FxResourceCm objects based on the passed in
|
||||
WDM io resource list.
|
||||
|
||||
Arguments:
|
||||
WdmResourceList - list which specifies the io resource objects to create
|
||||
|
||||
AccessFlags - permissions to be associated with the list
|
||||
|
||||
Return Value:
|
||||
NTSTATUS
|
||||
|
||||
--*/
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
//
|
||||
// Predispose to success
|
||||
//
|
||||
status = STATUS_SUCCESS;
|
||||
|
||||
Clear();
|
||||
|
||||
m_AccessFlags = AccessFlags;
|
||||
|
||||
if (WdmResourceList != NULL) {
|
||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR pDescriptor;
|
||||
ULONG count, i;
|
||||
|
||||
//
|
||||
// We only expect to see one full resource descriptor.
|
||||
//
|
||||
ASSERT(WdmResourceList->Count == 1);
|
||||
|
||||
count = WdmResourceList->List[0].PartialResourceList.Count;
|
||||
pDescriptor = WdmResourceList->List[0].PartialResourceList.PartialDescriptors;
|
||||
|
||||
for(i = 0; i < count; i++, pDescriptor++) {
|
||||
FxResourceCm *pResource;
|
||||
|
||||
pResource = new(GetDriverGlobals())
|
||||
FxResourceCm(GetDriverGlobals(), pDescriptor);
|
||||
|
||||
if (pResource == NULL) {
|
||||
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
status = pResource->AssignParentObject(this);
|
||||
|
||||
//
|
||||
// Since we control our own lifetime here, the assign should
|
||||
// always work.
|
||||
//
|
||||
ASSERT(NT_SUCCESS(status));
|
||||
|
||||
status = Add(pResource) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
Clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
_Must_inspect_result_
|
||||
PCM_RESOURCE_LIST
|
||||
FxCmResList::CreateWdmList(
|
||||
__in __drv_strictTypeMatch(__drv_typeExpr) POOL_TYPE PoolType
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Allocates and initializes a WDM CM resource list based off of the current
|
||||
contents of this collection.
|
||||
|
||||
Arguments:
|
||||
PoolType - the pool type from which to allocate the resource list
|
||||
|
||||
Return Value:
|
||||
a new resource list upon success, NULL upon failure
|
||||
|
||||
--*/
|
||||
{
|
||||
PCM_RESOURCE_LIST pWdmResourceList;
|
||||
ULONG size;
|
||||
PFX_DRIVER_GLOBALS pFxDriverGlobals;
|
||||
|
||||
pWdmResourceList = NULL;
|
||||
pFxDriverGlobals = GetDriverGlobals();
|
||||
|
||||
if (Count()) {
|
||||
//
|
||||
// NOTE: This function assumes all resources are on the same bus
|
||||
// and therefore there is only one FULL_RESOURCE_DESCRIPTOR.
|
||||
//
|
||||
size = sizeof(CM_RESOURCE_LIST) +
|
||||
(sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * (Count() - 1));
|
||||
|
||||
pWdmResourceList = (PCM_RESOURCE_LIST)
|
||||
MxMemory::MxAllocatePoolWithTag(PoolType, size, pFxDriverGlobals->Tag);
|
||||
|
||||
if (pWdmResourceList != NULL) {
|
||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR pDescriptor;
|
||||
FxCollectionEntry *cur, *end;
|
||||
|
||||
RtlZeroMemory(pWdmResourceList, size);
|
||||
|
||||
pWdmResourceList->Count = 1; // We only return one full descriptor
|
||||
|
||||
pWdmResourceList->List[0].PartialResourceList.Version = 1;
|
||||
pWdmResourceList->List[0].PartialResourceList.Revision = 1;
|
||||
pWdmResourceList->List[0].PartialResourceList.Count = Count();
|
||||
|
||||
pDescriptor =
|
||||
pWdmResourceList->List[0].PartialResourceList.PartialDescriptors;
|
||||
|
||||
end = End();
|
||||
for (cur = Start(); cur != end; cur = cur->Next()) {
|
||||
FxResourceCm *pResource;
|
||||
|
||||
pResource = (FxResourceCm*) cur->m_Object;
|
||||
|
||||
RtlCopyMemory(pDescriptor,
|
||||
&pResource->m_Descriptor,
|
||||
sizeof(pResource->m_Descriptor));
|
||||
pDescriptor++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pWdmResourceList;
|
||||
}
|
||||
|
||||
ULONG
|
||||
FxCmResList::GetCount(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
ULONG count;
|
||||
KIRQL irql;
|
||||
|
||||
Lock(&irql);
|
||||
count = Count();
|
||||
Unlock(irql);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR
|
||||
FxCmResList::GetDescriptor(
|
||||
__in ULONG Index
|
||||
)
|
||||
{
|
||||
FxResourceCm* pObject;
|
||||
KIRQL irql;
|
||||
|
||||
Lock(&irql);
|
||||
pObject = (FxResourceCm*) GetItem(Index);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
_Must_inspect_result_
|
||||
FxIoResReqList*
|
||||
FxIoResReqList::_CreateFromWdmList(
|
||||
__in PFX_DRIVER_GLOBALS FxDriverGlobals,
|
||||
__in PIO_RESOURCE_REQUIREMENTS_LIST WdmRequirementsList,
|
||||
__in UCHAR AccessFlags
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Allocates and populates an FxIoResReqList based on the WDM resource
|
||||
requirements list.
|
||||
|
||||
Arguments:
|
||||
WdmRequirementsList - a list of IO_RESOURCE_LISTs which will indicate how
|
||||
to fill in the returned collection object
|
||||
|
||||
AccessFlags - permissions to associate with the newly created object
|
||||
|
||||
Return Value:
|
||||
a new object upon success, NULL upon failure
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
FxIoResReqList* pIoResReqList;
|
||||
ULONG i;
|
||||
|
||||
pIoResReqList = new(FxDriverGlobals, WDF_NO_OBJECT_ATTRIBUTES)
|
||||
FxIoResReqList(FxDriverGlobals, AccessFlags);
|
||||
|
||||
if (pIoResReqList != NULL) {
|
||||
PIO_RESOURCE_LIST pWdmResourceList;
|
||||
NTSTATUS status;
|
||||
|
||||
if (WdmRequirementsList == NULL) {
|
||||
return pIoResReqList;
|
||||
}
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
pWdmResourceList = &WdmRequirementsList->List[0];
|
||||
|
||||
pIoResReqList->m_InterfaceType = WdmRequirementsList->InterfaceType;
|
||||
pIoResReqList->m_SlotNumber = WdmRequirementsList->SlotNumber;
|
||||
|
||||
for (i = 0; i < WdmRequirementsList->AlternativeLists; i++) {
|
||||
FxIoResList *pResList;
|
||||
|
||||
pResList = new(FxDriverGlobals, WDF_NO_OBJECT_ATTRIBUTES)
|
||||
FxIoResList(FxDriverGlobals, pIoResReqList);
|
||||
|
||||
if (pResList != NULL) {
|
||||
status = pResList->AssignParentObject(pIoResReqList);
|
||||
|
||||
//
|
||||
// Since we control our own lifetime, assigning the parent should
|
||||
// never fail.
|
||||
//
|
||||
ASSERT(NT_SUCCESS(status));
|
||||
|
||||
status = pResList->BuildFromWdmList(&pWdmResourceList);
|
||||
}
|
||||
else {
|
||||
//
|
||||
// We failed to allocate a child collection. Clean up
|
||||
// and break out of the loop.
|
||||
//
|
||||
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
//
|
||||
// Cleanup and return a NULL object
|
||||
//
|
||||
pIoResReqList->DeleteObject();
|
||||
pIoResReqList = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pIoResReqList;
|
||||
}
|
||||
|
||||
_Must_inspect_result_
|
||||
PIO_RESOURCE_REQUIREMENTS_LIST
|
||||
FxIoResReqList::CreateWdmList(
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Creates a WDM io resource requirements list based off of the current
|
||||
contents of the collection
|
||||
|
||||
Arguments:
|
||||
None
|
||||
|
||||
Return Value:
|
||||
new WDM io resource requirements list allocated out of paged pool upon success,
|
||||
NULL upon failure or an empty list
|
||||
|
||||
--*/
|
||||
{
|
||||
PIO_RESOURCE_REQUIREMENTS_LIST pRequirementsList;
|
||||
FxCollectionEntry *cur, *end;
|
||||
NTSTATUS status;
|
||||
ULONG totalDescriptors;
|
||||
ULONG size;
|
||||
ULONG count;
|
||||
ULONG tmp;
|
||||
PFX_DRIVER_GLOBALS pFxDriverGlobals;
|
||||
|
||||
totalDescriptors = 0;
|
||||
pRequirementsList = NULL;
|
||||
|
||||
count = Count();
|
||||
pFxDriverGlobals = GetDriverGlobals();
|
||||
|
||||
if (count > 0) {
|
||||
//
|
||||
// The collection object should contain a set of child collections
|
||||
// with each of the various requirement lists. Use the number of
|
||||
// these collections to determine the size of our requirements
|
||||
// list.
|
||||
//
|
||||
end = End();
|
||||
for (cur = Start(); cur != end; cur = cur->Next()) {
|
||||
status = RtlULongAdd(totalDescriptors,
|
||||
((FxIoResList *) cur->m_Object)->Count(),
|
||||
&totalDescriptors);
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
goto Overflow;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// We now have enough information to determine how much memory we
|
||||
// need to allocate for our requirements list.
|
||||
//
|
||||
// size = sizeof(IO_RESOURCE_REQUIREMENTS_LIST) +
|
||||
// (sizeof(IO_RESOURCE_LIST) * (count - 1)) +
|
||||
// (sizeof(IO_RESOURCE_DESCRIPTOR) * totalDescriptors) -
|
||||
// (sizeof(IO_RESOURCE_DESCRIPTOR) * count);
|
||||
//
|
||||
// sizeof(IO_RESOURCE_DESCRIPTOR) * count is subtracted off because
|
||||
// each IO_RESOURCE_LIST has an embedded IO_RESOURCE_DESCRIPTOR in it
|
||||
// and we don't want to overallocated.
|
||||
//
|
||||
|
||||
//
|
||||
// To handle overflow each mathematical operation is split out into an
|
||||
// overflow safe call.
|
||||
//
|
||||
size = sizeof(IO_RESOURCE_REQUIREMENTS_LIST);
|
||||
|
||||
// sizeof(IO_RESOURCE_LIST) * (count - 1)
|
||||
status = RtlULongMult(sizeof(IO_RESOURCE_LIST), count - 1, &tmp);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
goto Overflow;
|
||||
}
|
||||
|
||||
status = RtlULongAdd(size, tmp, &size);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
goto Overflow;
|
||||
}
|
||||
|
||||
// (sizeof(IO_RESOURCE_DESCRIPTOR) * totalDescriptors)
|
||||
status = RtlULongMult(sizeof(IO_RESOURCE_DESCRIPTOR),
|
||||
totalDescriptors,
|
||||
&tmp);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
goto Overflow;
|
||||
}
|
||||
|
||||
status = RtlULongAdd(size, tmp, &size);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
goto Overflow;
|
||||
}
|
||||
|
||||
// - sizeof(IO_RESOURCE_DESCRIPTOR) * Count() (note the subtraction!)
|
||||
status = RtlULongMult(sizeof(IO_RESOURCE_DESCRIPTOR), count, &tmp);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
goto Overflow;
|
||||
}
|
||||
|
||||
// Sub, not Add!
|
||||
status = RtlULongSub(size, tmp, &size);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
goto Overflow;
|
||||
}
|
||||
|
||||
pRequirementsList = (PIO_RESOURCE_REQUIREMENTS_LIST)
|
||||
MxMemory::MxAllocatePoolWithTag(PagedPool, size, pFxDriverGlobals->Tag);
|
||||
|
||||
if (pRequirementsList != NULL) {
|
||||
PIO_RESOURCE_LIST pList;
|
||||
FxResourceIo *pResource;
|
||||
|
||||
pList = pRequirementsList->List;
|
||||
|
||||
//
|
||||
// Start by zero initializing our structure
|
||||
//
|
||||
RtlZeroMemory(pRequirementsList, size);
|
||||
|
||||
//
|
||||
// InterfaceType and BusNumber are unused for WDM, but InterfaceType
|
||||
// is used by the arbiters.
|
||||
//
|
||||
pRequirementsList->InterfaceType = m_InterfaceType;
|
||||
|
||||
pRequirementsList->SlotNumber = m_SlotNumber;
|
||||
|
||||
//
|
||||
// Now populate the requirements list with the resources from
|
||||
// our collections.
|
||||
//
|
||||
pRequirementsList->ListSize = size;
|
||||
pRequirementsList->AlternativeLists = Count();
|
||||
|
||||
end = End();
|
||||
for (cur = Start(); cur != end; cur = cur->Next()) {
|
||||
FxIoResList* pIoResList;
|
||||
PIO_RESOURCE_DESCRIPTOR pDescriptor;
|
||||
FxCollectionEntry *pIoResCur, *pIoResEnd;
|
||||
|
||||
pIoResList = (FxIoResList*) cur->m_Object;
|
||||
|
||||
pList->Version = 1;
|
||||
pList->Revision = 1;
|
||||
pList->Count = pIoResList->Count();
|
||||
|
||||
pDescriptor = pList->Descriptors;
|
||||
|
||||
pIoResEnd = pIoResList->End();
|
||||
for (pIoResCur = pIoResList->Start();
|
||||
pIoResCur != pIoResEnd;
|
||||
pIoResCur = pIoResCur->Next()) {
|
||||
|
||||
pResource = (FxResourceIo *) pIoResCur->m_Object;
|
||||
RtlCopyMemory(pDescriptor,
|
||||
&pResource->m_Descriptor,
|
||||
sizeof(pResource->m_Descriptor));
|
||||
pDescriptor++;
|
||||
}
|
||||
|
||||
pList = (PIO_RESOURCE_LIST) pDescriptor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pRequirementsList;
|
||||
|
||||
Overflow:
|
||||
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP,
|
||||
"Integer overflow occured when computing size of "
|
||||
"IO_RESOURCE_REQUIREMENTS_LIST");
|
||||
|
||||
return NULL;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue