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