1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 Module Name: 6 7 FxResourceAPI.cpp 8 9 Abstract: 10 11 This module implements the resource class. 12 13 Author: 14 15 16 17 18 Environment: 19 20 Both kernel and user mode 21 22 Revision History: 23 24 --*/ 25 #include "fxsupportpch.hpp" 26 27 extern "C" { 28 // #include "FxResourceAPI.tmh" 29 } 30 31 // 32 // Extern "C" the entire file 33 // 34 extern "C" { 35 36 __drv_maxIRQL(DISPATCH_LEVEL) 37 VOID 38 WDFEXPORT(WdfIoResourceRequirementsListSetSlotNumber)( 39 __in 40 PWDF_DRIVER_GLOBALS DriverGlobals, 41 __in 42 WDFIORESREQLIST RequirementsList, 43 __in 44 ULONG SlotNumber 45 ) 46 /*++ 47 48 Routine Description: 49 Sets the slot number for a given resource requirements list 50 51 Arguments: 52 RequirementsList - list to be modified 53 54 SlotNumber - slot value to assign 55 56 Return Value: 57 None 58 59 --*/ 60 { 61 FxIoResReqList* pIoResReqList; 62 63 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 64 RequirementsList, 65 FX_TYPE_IO_RES_REQ_LIST, 66 (PVOID*) &pIoResReqList); 67 68 if (pIoResReqList->m_SlotNumber != SlotNumber) { 69 pIoResReqList->MarkChanged(); 70 } 71 pIoResReqList->m_SlotNumber = SlotNumber; 72 } 73 74 __drv_maxIRQL(DISPATCH_LEVEL) 75 VOID 76 WDFEXPORT(WdfIoResourceRequirementsListSetInterfaceType)( 77 __in 78 PWDF_DRIVER_GLOBALS DriverGlobals, 79 __in 80 WDFIORESREQLIST RequirementsList, 81 __in 82 __drv_strictTypeMatch(__drv_typeCond) 83 INTERFACE_TYPE InterfaceType 84 ) 85 /*++ 86 87 Routine Description: 88 Sets the InterfaceType for a given resource requirements list 89 90 Arguments: 91 RequirementsList - list to be modified 92 93 InterfaceType - interface type to assign 94 95 Return Value: 96 None 97 98 --*/ 99 { 100 FxIoResReqList* pIoResReqList; 101 102 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 103 RequirementsList, 104 FX_TYPE_IO_RES_REQ_LIST, 105 (PVOID*) &pIoResReqList); 106 107 if (pIoResReqList->m_InterfaceType != InterfaceType) { 108 pIoResReqList->MarkChanged(); 109 } 110 111 pIoResReqList->m_InterfaceType = InterfaceType; 112 } 113 114 _Must_inspect_result_ 115 __drv_maxIRQL(DISPATCH_LEVEL) 116 NTSTATUS 117 FxIoResourceRequirementsListInsertIoResList( 118 __in 119 PWDF_DRIVER_GLOBALS DriverGlobals, 120 __in 121 WDFIORESREQLIST RequirementsList, 122 __in 123 WDFIORESLIST IoResList, 124 ULONG Index 125 ) 126 /*++ 127 128 Routine Description: 129 Inserts a resource list into a requirements list at a particular index. 130 131 Arguments: 132 RequirementsList - list to be modified 133 134 IoResList - resource list to add 135 136 Index - zero based index to insert at 137 138 Return Value: 139 NTSTATUS 140 141 --*/ 142 { 143 PFX_DRIVER_GLOBALS pFxDriverGlobals; 144 FxIoResReqList* pIoResReqList; 145 FxIoResList* pIoResList; 146 NTSTATUS status; 147 148 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 149 RequirementsList, 150 FX_TYPE_IO_RES_REQ_LIST, 151 (PVOID*) &pIoResReqList, 152 &pFxDriverGlobals); 153 154 FxObjectHandleGetPtr(pFxDriverGlobals, 155 IoResList, 156 FX_TYPE_IO_RES_LIST, 157 (PVOID*) &pIoResList); 158 159 if (pIoResList->m_OwningList != pIoResReqList) { 160 return STATUS_INVALID_DEVICE_REQUEST; 161 } 162 163 status = pIoResReqList->AddAt(Index, pIoResList); 164 165 if (NT_SUCCESS(status)) { 166 // 167 // Mirror the access flags as well. 168 // 169 pIoResList->m_AccessFlags = pIoResReqList->m_AccessFlags; 170 pIoResList->m_OwningList = pIoResReqList; 171 } 172 173 return status; 174 } 175 176 177 _Must_inspect_result_ 178 __drv_maxIRQL(DISPATCH_LEVEL) 179 NTSTATUS 180 WDFEXPORT(WdfIoResourceRequirementsListInsertIoResList)( 181 __in 182 PWDF_DRIVER_GLOBALS DriverGlobals, 183 __in 184 WDFIORESREQLIST RequirementsList, 185 __in 186 WDFIORESLIST IoResList, 187 __in 188 ULONG Index 189 ) 190 /*++ 191 192 Routine Description: 193 Inserts a resource list into a requirements list at a particular index. 194 195 Arguments: 196 RequirementsList - list to be modified 197 198 IoResList - resource list to add 199 200 Index - zero based index to insert at 201 202 Return Value: 203 NTSTATUS 204 205 --*/ 206 { 207 return FxIoResourceRequirementsListInsertIoResList(DriverGlobals, 208 RequirementsList, 209 IoResList, 210 Index); 211 } 212 213 _Must_inspect_result_ 214 __drv_maxIRQL(DISPATCH_LEVEL) 215 NTSTATUS 216 WDFEXPORT(WdfIoResourceRequirementsListAppendIoResList)( 217 __in 218 PWDF_DRIVER_GLOBALS DriverGlobals, 219 __in 220 WDFIORESREQLIST RequirementsList, 221 __in 222 WDFIORESLIST IoResList 223 ) 224 /*++ 225 226 Routine Description: 227 Appends a resource list to a resource requirements list 228 229 Arguments: 230 RequirementsList - list to be modified 231 232 IoResList - resource list to append 233 234 Return Value: 235 NTSTATUS 236 237 --*/ 238 239 { 240 return FxIoResourceRequirementsListInsertIoResList(DriverGlobals, 241 RequirementsList, 242 IoResList, 243 WDF_INSERT_AT_END); 244 } 245 246 247 __drv_maxIRQL(DISPATCH_LEVEL) 248 ULONG 249 WDFEXPORT(WdfIoResourceRequirementsListGetCount)( 250 __in 251 PWDF_DRIVER_GLOBALS DriverGlobals, 252 __in 253 WDFIORESREQLIST RequirementsList 254 ) 255 /*++ 256 257 Routine Description: 258 Returns the number of resource lists in the requirements list 259 260 261 Arguments: 262 RequirementsList - requirements list whose count will be returned 263 264 Return Value: 265 number of elements in the list 266 267 --*/ 268 269 { 270 FxIoResReqList* pList; 271 ULONG count; 272 KIRQL irql; 273 274 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 275 RequirementsList, 276 FX_TYPE_IO_RES_REQ_LIST, 277 (PVOID*) &pList); 278 279 pList->Lock(&irql); 280 count = pList->Count(); 281 pList->Unlock(irql); 282 283 return count; 284 } 285 286 __drv_maxIRQL(DISPATCH_LEVEL) 287 WDFIORESLIST 288 WDFEXPORT(WdfIoResourceRequirementsListGetIoResList)( 289 __in 290 PWDF_DRIVER_GLOBALS DriverGlobals, 291 __in 292 WDFIORESREQLIST RequirementsList, 293 __in 294 ULONG Index 295 ) 296 /*++ 297 298 Routine Description: 299 Retrieves a resource list from the requirements list at a given index. 300 301 Arguments: 302 RequirementsList - list to retrieve the resource list from 303 304 Index - zero based index from which to retrieve the list 305 306 Return Value: 307 resource list handle or NULL 308 309 --*/ 310 { 311 FxIoResReqList* pIoResReqList; 312 FxObject* pObject; 313 KIRQL irql; 314 315 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 316 RequirementsList, 317 FX_TYPE_IO_RES_REQ_LIST, 318 (PVOID*) &pIoResReqList); 319 320 pIoResReqList->Lock(&irql); 321 pObject = pIoResReqList->GetItem(Index); 322 pIoResReqList->Unlock(irql); 323 324 if (pObject == NULL) { 325 return NULL; 326 } 327 else { 328 return (WDFIORESLIST) pObject->GetObjectHandle(); 329 } 330 } 331 332 __drv_maxIRQL(DISPATCH_LEVEL) 333 VOID 334 WDFEXPORT(WdfIoResourceRequirementsListRemove)( 335 __in 336 PWDF_DRIVER_GLOBALS DriverGlobals, 337 __in 338 WDFIORESREQLIST RequirementsList, 339 __in 340 ULONG Index 341 ) 342 /*++ 343 344 Routine Description: 345 Removes a resource list from the requirements list at a given index 346 347 Arguments: 348 RequirementsList - list of resource requirements which will be modified 349 350 Index - zero based index which indictes location in the list to find the 351 resource list 352 353 Return Value: 354 None 355 356 --*/ 357 { 358 PFX_DRIVER_GLOBALS pFxDriverGlobals; 359 FxIoResReqList* pList; 360 361 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 362 RequirementsList, 363 FX_TYPE_IO_RES_REQ_LIST, 364 (PVOID*) &pList, 365 &pFxDriverGlobals); 366 367 if (pList->RemoveAndDelete(Index) == FALSE) { 368 DoTraceLevelMessage( 369 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP, 370 "WDFIORESLIST %p, could not remove list at index %d (not found), " 371 "list item count is %d", RequirementsList, Index, pList->Count()); 372 373 FxVerifierDbgBreakPoint(pFxDriverGlobals); 374 } 375 } 376 377 __drv_maxIRQL(DISPATCH_LEVEL) 378 VOID 379 WDFEXPORT(WdfIoResourceRequirementsListRemoveByIoResList)( 380 __in 381 PWDF_DRIVER_GLOBALS DriverGlobals, 382 __in 383 WDFIORESREQLIST RequirementsList, 384 __in 385 WDFIORESLIST IoResList 386 ) 387 /*++ 388 389 Routine Description: 390 Removes a resource list from the requirements list based on the resource list's 391 handle 392 393 Arguments: 394 RequirementsList - resource requirements list being modified 395 396 IoResList - resource list to be removed 397 398 Return Value: 399 None 400 401 --*/ 402 { 403 PFX_DRIVER_GLOBALS pFxDriverGlobals; 404 FxCollectionEntry* cur, *end; 405 FxIoResReqList* pList; 406 FxIoResList* pResList; 407 KIRQL irql; 408 BOOLEAN listFound; 409 410 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 411 RequirementsList, 412 FX_TYPE_IO_RES_REQ_LIST, 413 (PVOID*) &pList, 414 &pFxDriverGlobals); 415 416 if (pList->IsRemoveAllowed() == FALSE) { 417 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP, 418 "WDFIORESREQLIST %p: Removes not allowed", 419 RequirementsList); 420 421 FxVerifierDbgBreakPoint(pFxDriverGlobals); 422 return; 423 } 424 425 FxObjectHandleGetPtr(pFxDriverGlobals, 426 IoResList, 427 FX_TYPE_IO_RES_LIST, 428 (PVOID*) &pResList); 429 430 pList->Lock(&irql); 431 432 cur = pList->Start(); 433 end = pList->End(); 434 listFound = FALSE; 435 436 while (cur != end) { 437 if (cur->m_Object == pResList) { 438 pList->MarkChanged(); 439 440 pList->RemoveEntry(cur); 441 listFound = TRUE; 442 break; 443 } 444 445 cur = cur->Next(); 446 } 447 448 pList->Unlock(irql); 449 450 if (listFound) { 451 pResList->DeleteObject(); 452 pResList = NULL; 453 } 454 } 455 456 _Must_inspect_result_ 457 __drv_maxIRQL(DISPATCH_LEVEL) 458 NTSTATUS 459 WDFEXPORT(WdfIoResourceListCreate)( 460 __in 461 PWDF_DRIVER_GLOBALS DriverGlobals, 462 __in 463 WDFIORESREQLIST RequirementsList, 464 __in_opt 465 PWDF_OBJECT_ATTRIBUTES Attributes, 466 __out 467 WDFIORESLIST* ResourceList 468 ) 469 /*++ 470 471 Routine Description: 472 Creates a resource list. 473 474 Arguments: 475 RequirementsList - the resource requirements list that the resource list will 476 be associated with 477 478 Attributes - generic object attributes for the new resource list 479 480 ResourceList - pointer which will receive the new object handle 481 482 Return Value: 483 NTSTATUS 484 485 --*/ 486 { 487 PFX_DRIVER_GLOBALS pFxDriverGlobals; 488 FxIoResReqList* pIoResReqList; 489 FxIoResList* pIoResList; 490 NTSTATUS status; 491 492 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 493 RequirementsList, 494 FX_TYPE_IO_RES_REQ_LIST, 495 (PVOID*) &pIoResReqList, 496 &pFxDriverGlobals); 497 498 FxPointerNotNull(pFxDriverGlobals, ResourceList); 499 *ResourceList = NULL; 500 501 status = FxValidateObjectAttributes(pFxDriverGlobals, 502 Attributes, 503 FX_VALIDATE_OPTION_PARENT_NOT_ALLOWED); 504 505 if (!NT_SUCCESS(status)) { 506 return status; 507 } 508 509 pIoResList = new (pFxDriverGlobals, Attributes) FxIoResList( 510 pFxDriverGlobals, pIoResReqList); 511 512 if (pIoResList == NULL) { 513 return STATUS_INSUFFICIENT_RESOURCES; 514 } 515 516 status = pIoResList->Commit(Attributes, 517 (WDFOBJECT*) ResourceList, 518 pIoResReqList); 519 520 if (!NT_SUCCESS(status)) { 521 pIoResList->DeleteFromFailedCreate(); 522 } 523 524 return status; 525 } 526 527 _Must_inspect_result_ 528 __drv_maxIRQL(DISPATCH_LEVEL) 529 NTSTATUS 530 FxIoResourceListInsertDescriptor( 531 __in 532 PWDF_DRIVER_GLOBALS DriverGlobals, 533 __in 534 WDFIORESLIST ResourceList, 535 __in 536 PIO_RESOURCE_DESCRIPTOR Descriptor, 537 ULONG Index 538 ) 539 /*++ 540 541 Routine Description: 542 Inserts a descriptor into a resource list at a particular index. 543 544 Arguments: 545 ResourceList - list to be modified 546 547 Descriptor - descriptor to insert 548 549 Index - zero based index to insert at 550 551 Return Value: 552 NTSTATUS 553 554 --*/ 555 { 556 PFX_DRIVER_GLOBALS pFxDriverGlobals; 557 FxIoResList* pList; 558 FxResourceIo* pObject; 559 NTSTATUS status; 560 561 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 562 ResourceList, 563 FX_TYPE_IO_RES_LIST, 564 (PVOID*) &pList, 565 &pFxDriverGlobals); 566 567 FxPointerNotNull(pFxDriverGlobals, Descriptor); 568 569 if (pList->m_OwningList->IsAddAllowed() == FALSE) { 570 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP, 571 "Removes not allowed on WDFIORESLIST %p", 572 ResourceList); 573 FxVerifierDbgBreakPoint(pFxDriverGlobals); 574 return STATUS_ACCESS_DENIED; 575 } 576 577 pObject = new(pFxDriverGlobals) 578 FxResourceIo(pFxDriverGlobals, Descriptor); 579 580 if (pObject == NULL) { 581 return STATUS_INSUFFICIENT_RESOURCES; 582 } 583 584 status = pObject->AssignParentObject(pList); 585 if (!NT_SUCCESS(status)) { 586 pObject->DeleteObject(); 587 return status; 588 } 589 590 status = pList->AddAt(Index, pObject); 591 592 // 593 // Mark both this list and its owning list as changed so when it comes 594 // time to evaluate the entire requirements list for changes, we do not 595 // have to iterate over all the resource lists. 596 // 597 if (NT_SUCCESS(status)) { 598 pList->m_OwningList->MarkChanged(); 599 } 600 601 return status; 602 } 603 604 _Must_inspect_result_ 605 __drv_maxIRQL(DISPATCH_LEVEL) 606 NTSTATUS 607 WDFEXPORT(WdfIoResourceListInsertDescriptor)( 608 __in 609 PWDF_DRIVER_GLOBALS DriverGlobals, 610 __in 611 WDFIORESLIST ResourceList, 612 __in 613 PIO_RESOURCE_DESCRIPTOR Descriptor, 614 __in 615 ULONG Index 616 ) 617 /*++ 618 619 Routine Description: 620 Inserts a descriptor into a resource list at a particular index. 621 622 Arguments: 623 ResourceList - list to be modified 624 625 Descriptor - descriptor to insert 626 627 Index - zero based index to insert at 628 629 Return Value: 630 NTSTATUS 631 632 --*/ 633 { 634 return FxIoResourceListInsertDescriptor(DriverGlobals, 635 ResourceList, 636 Descriptor, 637 Index); 638 } 639 640 _Must_inspect_result_ 641 __drv_maxIRQL(DISPATCH_LEVEL) 642 NTSTATUS 643 WDFEXPORT(WdfIoResourceListAppendDescriptor)( 644 __in 645 PWDF_DRIVER_GLOBALS DriverGlobals, 646 __in 647 WDFIORESLIST ResourceList, 648 __in 649 PIO_RESOURCE_DESCRIPTOR Descriptor 650 ) 651 /*++ 652 653 Routine Description: 654 Appends a descriptor to a resource list 655 656 Arguments: 657 ResourceList - list to be modified 658 659 Descriptor - item to be appended 660 661 Return Value: 662 NTSTATUS 663 664 --*/ 665 { 666 return FxIoResourceListInsertDescriptor(DriverGlobals, 667 ResourceList, 668 Descriptor, 669 WDF_INSERT_AT_END); 670 } 671 672 __drv_maxIRQL(DISPATCH_LEVEL) 673 VOID 674 WDFEXPORT(WdfIoResourceListUpdateDescriptor)( 675 __in 676 PWDF_DRIVER_GLOBALS DriverGlobals, 677 __in 678 WDFIORESLIST ResourceList, 679 __in 680 PIO_RESOURCE_DESCRIPTOR Descriptor, 681 __in 682 ULONG Index 683 ) 684 /*++ 685 686 Routine Description: 687 Updates resource requirement in place in the list. 688 689 Arguments: 690 ResourceList - list to be modified 691 692 Descriptor - Pointer to descriptor whic contains the updated value 693 694 Index - zero based location in the list to update 695 696 Return Value: 697 None 698 699 --*/ 700 { 701 PFX_DRIVER_GLOBALS pFxDriverGlobals; 702 FxIoResList* pList; 703 FxResourceIo* pObject; 704 KIRQL irql; 705 706 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 707 ResourceList, 708 FX_TYPE_IO_RES_LIST, 709 (PVOID*) &pList, 710 &pFxDriverGlobals); 711 712 FxPointerNotNull(pFxDriverGlobals, Descriptor); 713 714 pList->Lock(&irql); 715 pObject = (FxResourceIo*) pList->GetItem(Index); 716 pList->Unlock(irql); 717 718 if (pObject != NULL) { 719 // 720 // We don't check for add or remove access because we don't know what 721 // the update is actually doing (ie widening a range, shortening it, etc). 722 // For this operation we have to trust the driver that it is doing the 723 // right thing at the right time. 724 // 725 RtlCopyMemory(&pObject->m_Descriptor, 726 Descriptor, 727 sizeof(pObject->m_Descriptor)); 728 729 // 730 // Mark both this list and its owning list as changed so when it comes 731 // time to evaluate the entire requirements list for changes, we do not 732 // have to iterate over all the resource lists. 733 // 734 pList->MarkChanged(); 735 pList->m_OwningList->MarkChanged(); 736 } 737 else { 738 DoTraceLevelMessage( 739 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP, 740 "WDFIORESREQLIST %p, cannot update item at index %d, item not found," 741 " list item count is %d", ResourceList, Index, pList->Count()); 742 743 FxVerifierDbgBreakPoint(pFxDriverGlobals); 744 } 745 } 746 747 __drv_maxIRQL(DISPATCH_LEVEL) 748 ULONG 749 WDFEXPORT(WdfIoResourceListGetCount)( 750 __in 751 PWDF_DRIVER_GLOBALS DriverGlobals, 752 __in 753 WDFIORESLIST ResourceList 754 ) 755 /*++ 756 757 Routine Description: 758 Returns the number of descriptors in the resource list 759 760 Arguments: 761 ResourceList - resource list whose count will be returned 762 763 Return Value: 764 number of elements in the list 765 766 --*/ 767 { 768 FxIoResList* pList; 769 ULONG count; 770 KIRQL irql; 771 772 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 773 ResourceList, 774 FX_TYPE_IO_RES_LIST, 775 (PVOID*) &pList); 776 777 pList->Lock(&irql); 778 count = pList->Count(); 779 pList->Unlock(irql); 780 781 return count; 782 } 783 784 785 __drv_maxIRQL(DISPATCH_LEVEL) 786 PIO_RESOURCE_DESCRIPTOR 787 WDFEXPORT(WdfIoResourceListGetDescriptor)( 788 __in 789 PWDF_DRIVER_GLOBALS DriverGlobals, 790 __in 791 WDFIORESLIST ResourceList, 792 __in 793 ULONG Index 794 ) 795 /*++ 796 797 Routine Description: 798 Retrieves an io resource desciptor for a given index in the resource list 799 800 Arguments: 801 ResourceList - list being looked up 802 803 Index - zero based index into the list to find the value of 804 805 Return Value: 806 pointer to an io resource descriptor upon success, NULL upon error 807 808 --*/ 809 810 { 811 FxIoResList* pList; 812 FxResourceIo* pObject; 813 KIRQL irql; 814 815 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 816 ResourceList, 817 FX_TYPE_IO_RES_LIST, 818 (PVOID*) &pList); 819 820 pList->Lock(&irql); 821 pObject = (FxResourceIo*) pList->GetItem(Index); 822 pList->Unlock(irql); 823 824 if (pObject == NULL) { 825 return NULL; 826 } 827 else { 828 // 829 // Copy the current descriptor to the clone and return it 830 // 831 RtlCopyMemory(&pObject->m_DescriptorClone, 832 &pObject->m_Descriptor, 833 sizeof(pObject->m_Descriptor)); 834 835 return &pObject->m_DescriptorClone; 836 } 837 } 838 839 __drv_maxIRQL(DISPATCH_LEVEL) 840 VOID 841 WDFEXPORT(WdfIoResourceListRemove)( 842 __in 843 PWDF_DRIVER_GLOBALS DriverGlobals, 844 __in 845 WDFIORESLIST ResourceList, 846 __in 847 ULONG Index 848 ) 849 /*++ 850 851 Routine Description: 852 Removes a descriptor in an io resource list 853 854 Arguments: 855 ResourceList - resource list to modify 856 857 Index - zero based index into the list in which to remove the descriptor 858 859 Return Value: 860 None 861 862 --*/ 863 { 864 PFX_DRIVER_GLOBALS pFxDriverGlobals; 865 FxIoResList* pList; 866 867 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 868 ResourceList, 869 FX_TYPE_IO_RES_LIST, 870 (PVOID*) &pList, 871 &pFxDriverGlobals); 872 873 if (pList->RemoveAndDelete(Index)) { 874 // 875 // Mark this list's owning list as changed so when it comes 876 // time to evaluate the entire requirements list for changes, we do not 877 // have to iterate over all the resource lists. 878 // 879 // RemoveAndDelete marked pList as changed already 880 // 881 pList->m_OwningList->MarkChanged(); 882 } 883 else { 884 DoTraceLevelMessage( 885 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP, 886 "WDFIORESLIST %p, could not remove item at index %d (not found), " 887 "list item count is %d", ResourceList, Index, pList->Count()); 888 889 FxVerifierDbgBreakPoint(pFxDriverGlobals); 890 } 891 } 892 893 __drv_maxIRQL(DISPATCH_LEVEL) 894 VOID 895 WDFEXPORT(WdfIoResourceListRemoveByDescriptor)( 896 __in 897 PWDF_DRIVER_GLOBALS DriverGlobals, 898 __in 899 WDFIORESLIST ResourceList, 900 __in 901 PIO_RESOURCE_DESCRIPTOR Descriptor 902 ) 903 /*++ 904 905 Routine Description: 906 Removes a descriptor by value in a given io resource list. Equality is 907 determined by RtlCompareMemory. 908 909 Arguments: 910 ResourceList - the io resource list to modify 911 912 Descriptor - pointer to a descriptor to remove. 913 914 Return Value: 915 None 916 917 --*/ 918 { 919 PFX_DRIVER_GLOBALS pFxDriverGlobals; 920 FxCollectionEntry* cur, *end; 921 FxIoResList* pList; 922 FxResourceIo* pObject; 923 KIRQL irql; 924 925 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 926 ResourceList, 927 FX_TYPE_IO_RES_LIST, 928 (PVOID*) &pList, 929 &pFxDriverGlobals); 930 931 FxPointerNotNull(pFxDriverGlobals, Descriptor); 932 933 if (pList->IsRemoveAllowed() == FALSE) { 934 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP, 935 "Removes not allowed on WDFIORESLIST %p", 936 ResourceList); 937 938 FxVerifierDbgBreakPoint(pFxDriverGlobals); 939 return; 940 } 941 942 pList->Lock(&irql); 943 944 cur = pList->Start(); 945 end = pList->End(); 946 pObject = NULL; 947 948 while (cur != end) { 949 pObject = (FxResourceIo*) cur->m_Object; 950 951 if (RtlCompareMemory(&pObject->m_Descriptor, 952 Descriptor, 953 sizeof(*Descriptor)) == sizeof(*Descriptor)) { 954 // 955 // Mark both this list and its owning list as changed so when it 956 // comes time to evaluate the entire requirements list for 957 // changes, we do not have to iterate over all the resource lists. 958 // 959 pList->MarkChanged(); 960 pList->m_OwningList->MarkChanged(); 961 962 pList->RemoveEntry(cur); 963 break; 964 } 965 966 // 967 // Set to NULL so that we do not delete it if this is the last item in 968 // the list. 969 // 970 pObject = NULL; 971 972 cur = cur->Next(); 973 } 974 975 pList->Unlock(irql); 976 977 if (pObject != NULL) { 978 pObject->DeleteObject(); 979 } 980 } 981 982 _Must_inspect_result_ 983 __drv_maxIRQL(DISPATCH_LEVEL) 984 NTSTATUS 985 FxCmResourceListInsertDescriptor( 986 __in 987 PWDF_DRIVER_GLOBALS DriverGlobals, 988 __in 989 WDFCMRESLIST List, 990 __in 991 PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor, 992 __in 993 ULONG Index 994 ) 995 /*++ 996 997 Routine Description: 998 Inserts a descriptor into a cm resource list at a particular index. 999 1000 Arguments: 1001 ResourceList - list to be modified 1002 1003 Descriptor - descriptor to insert 1004 1005 Index - zero based index to insert at 1006 1007 Return Value: 1008 NTSTATUS 1009 1010 --*/ 1011 { 1012 PFX_DRIVER_GLOBALS pFxDriverGlobals; 1013 FxCmResList* pList; 1014 FxResourceCm* pObject; 1015 NTSTATUS status; 1016 1017 pFxDriverGlobals = GetFxDriverGlobals(DriverGlobals); 1018 1019 FxPointerNotNull(pFxDriverGlobals, Descriptor); 1020 1021 FxObjectHandleGetPtr(pFxDriverGlobals, 1022 List, 1023 FX_TYPE_CM_RES_LIST, 1024 (PVOID*) &pList); 1025 1026 pObject = new(pFxDriverGlobals) FxResourceCm(pFxDriverGlobals, Descriptor); 1027 1028 if (pObject == NULL) { 1029 return STATUS_INSUFFICIENT_RESOURCES; 1030 } 1031 1032 status = pObject->AssignParentObject(pList); 1033 if (!NT_SUCCESS(status)) { 1034 pObject->DeleteObject(); 1035 return status; 1036 } 1037 1038 return pList->AddAt(Index, pObject); 1039 } 1040 1041 _Must_inspect_result_ 1042 __drv_maxIRQL(DISPATCH_LEVEL) 1043 NTSTATUS 1044 WDFEXPORT(WdfCmResourceListInsertDescriptor)( 1045 __in 1046 PWDF_DRIVER_GLOBALS DriverGlobals, 1047 __in 1048 WDFCMRESLIST List, 1049 __in 1050 PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor, 1051 __in 1052 ULONG Index 1053 ) 1054 /*++ 1055 1056 Routine Description: 1057 Inserts a descriptor into a cm resource list at a particular index. 1058 1059 Arguments: 1060 ResourceList - list to be modified 1061 1062 Descriptor - descriptor to insert 1063 1064 Index - zero based index to insert at 1065 1066 Return Value: 1067 NTSTATUS 1068 1069 --*/ 1070 { 1071 DDI_ENTRY(); 1072 1073 return FxCmResourceListInsertDescriptor(DriverGlobals, 1074 List, 1075 Descriptor, 1076 Index); 1077 } 1078 1079 _Must_inspect_result_ 1080 __drv_maxIRQL(DISPATCH_LEVEL) 1081 NTSTATUS 1082 WDFEXPORT(WdfCmResourceListAppendDescriptor)( 1083 __in 1084 PWDF_DRIVER_GLOBALS DriverGlobals, 1085 __in 1086 WDFCMRESLIST List, 1087 __in 1088 PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor 1089 ) 1090 /*++ 1091 1092 Routine Description: 1093 Appends a descriptor to a cm resource list 1094 1095 Arguments: 1096 ResourceList - list to be modified 1097 1098 Descriptor - item to be appended 1099 1100 Return Value: 1101 NTSTATUS 1102 1103 --*/ 1104 { 1105 DDI_ENTRY(); 1106 1107 return FxCmResourceListInsertDescriptor(DriverGlobals, 1108 List, 1109 Descriptor, 1110 WDF_INSERT_AT_END); 1111 } 1112 1113 __drv_maxIRQL(DISPATCH_LEVEL) 1114 ULONG 1115 WDFEXPORT(WdfCmResourceListGetCount)( 1116 __in 1117 PWDF_DRIVER_GLOBALS DriverGlobals, 1118 __in 1119 WDFCMRESLIST List 1120 ) 1121 /*++ 1122 1123 Routine Description: 1124 Returns the number of cm descriptors in the resource list 1125 1126 Arguments: 1127 ResourceList - resource list whose count will be returned 1128 1129 Return Value: 1130 number of elements in the list 1131 1132 --*/ 1133 { 1134 FxCmResList* pList; 1135 1136 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 1137 List, 1138 FX_TYPE_CM_RES_LIST, 1139 (PVOID*) &pList); 1140 1141 return pList->GetCount(); 1142 } 1143 1144 1145 __drv_maxIRQL(DISPATCH_LEVEL) 1146 PCM_PARTIAL_RESOURCE_DESCRIPTOR 1147 WDFEXPORT(WdfCmResourceListGetDescriptor)( 1148 __in 1149 PWDF_DRIVER_GLOBALS DriverGlobals, 1150 __in 1151 WDFCMRESLIST List, 1152 __in 1153 ULONG Index 1154 ) 1155 /*++ 1156 1157 Routine Description: 1158 Retrieves a cm resource desciptor for a given index in the resource list 1159 1160 Arguments: 1161 ResourceList - list being looked up 1162 1163 Index - zero based index into the list to find the value of 1164 1165 Return Value: 1166 pointer to a cm resource descriptor upon success, NULL upon error 1167 1168 --*/ 1169 { 1170 DDI_ENTRY(); 1171 1172 FxCmResList* pList; 1173 1174 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 1175 List, 1176 FX_TYPE_CM_RES_LIST, 1177 (PVOID*) &pList); 1178 1179 return pList->GetDescriptor(Index); 1180 } 1181 1182 __drv_maxIRQL(DISPATCH_LEVEL) 1183 VOID 1184 WDFEXPORT(WdfCmResourceListRemove)( 1185 __in 1186 PWDF_DRIVER_GLOBALS DriverGlobals, 1187 __in 1188 WDFCMRESLIST List, 1189 __in 1190 ULONG Index 1191 ) 1192 /*++ 1193 1194 Routine Description: 1195 Removes a descriptor in an cm resource list 1196 1197 Arguments: 1198 ResourceList - resource list to modify 1199 1200 Index - zero based index into the list in which to remove the descriptor 1201 1202 Return Value: 1203 None 1204 1205 --*/ 1206 { 1207 DDI_ENTRY(); 1208 1209 PFX_DRIVER_GLOBALS pFxDriverGlobals; 1210 FxCmResList* pList; 1211 1212 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 1213 List, 1214 FX_TYPE_CM_RES_LIST, 1215 (PVOID*) &pList, 1216 &pFxDriverGlobals); 1217 1218 if (pList->RemoveAndDelete(Index) == FALSE) { 1219 DoTraceLevelMessage( 1220 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP, 1221 "WDFCMRESLIST %p, could not remove list at index %d (not found), " 1222 "list item count is %d", List, Index, pList->Count()); 1223 1224 FxVerifierDbgBreakPoint(pFxDriverGlobals); 1225 } 1226 } 1227 1228 __drv_maxIRQL(DISPATCH_LEVEL) 1229 VOID 1230 WDFEXPORT(WdfCmResourceListRemoveByDescriptor)( 1231 __in 1232 PWDF_DRIVER_GLOBALS DriverGlobals, 1233 __in 1234 WDFCMRESLIST List, 1235 __in 1236 PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor 1237 ) 1238 /*++ 1239 1240 Routine Description: 1241 Removes a descriptor by value in a given cm resource list. Equality is 1242 determined by RtlCompareMemory. 1243 1244 Arguments: 1245 ResourceList - the io resource list to modify 1246 1247 Descriptor - pointer to a descriptor to remove. 1248 1249 Return Value: 1250 None 1251 1252 --*/ 1253 { 1254 DDI_ENTRY(); 1255 1256 PFX_DRIVER_GLOBALS pFxDriverGlobals; 1257 FxCollectionEntry* cur; 1258 FxCollectionEntry* end; 1259 FxCmResList* pList; 1260 FxResourceCm* pObject; 1261 KIRQL irql; 1262 1263 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 1264 List, 1265 FX_TYPE_CM_RES_LIST, 1266 (PVOID*) &pList, 1267 &pFxDriverGlobals); 1268 1269 FxPointerNotNull(pFxDriverGlobals, Descriptor); 1270 1271 if (pList->IsRemoveAllowed() == FALSE) { 1272 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP, 1273 "Removes not allowed on WDFCMRESLIST %p", List); 1274 1275 FxVerifierDbgBreakPoint(pFxDriverGlobals); 1276 return; 1277 } 1278 1279 pList->Lock(&irql); 1280 1281 cur = pList->Start(); 1282 end = pList->End(); 1283 pObject = NULL; 1284 1285 while (cur != end) { 1286 pObject = (FxResourceCm*) cur->m_Object; 1287 1288 if (RtlCompareMemory(&pObject->m_Descriptor, 1289 Descriptor, 1290 sizeof(*Descriptor)) == sizeof(*Descriptor)) { 1291 pList->MarkChanged(); 1292 1293 pList->RemoveEntry(cur); 1294 break; 1295 } 1296 1297 // 1298 // Set to NULL so that we do not delete it if this is the last item in 1299 // the list. 1300 // 1301 pObject = NULL; 1302 1303 cur = cur->Next(); 1304 } 1305 1306 pList->Unlock(irql); 1307 1308 if (pObject != NULL) { 1309 pObject->DeleteObject(); 1310 pObject = NULL; 1311 } 1312 } 1313 1314 } // extern "C" 1315