1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 Module Name: 6 7 FxIrp.hpp 8 9 Abstract: 10 11 This module implements a class for handling irps. 12 13 Author: 14 15 16 17 Environment: 18 19 Both kernel and user mode 20 21 Revision History: 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 // A function for when not assigning 88 89 MdIrp 90 GetIrp( 91 VOID 92 ); 93 94 95 VOID 96 CompleteRequest( 97 __in_opt CCHAR PriorityBoost=IO_NO_INCREMENT 98 ); 99 100 101 NTSTATUS 102 CallDriver( 103 __in MdDeviceObject DeviceObject 104 ); 105 106 107 108 109 110 111 112 NTSTATUS 113 PoCallDriver( 114 __in MdDeviceObject DeviceObject 115 ); 116 117 118 VOID 119 StartNextPowerIrp( 120 ); 121 122 MdCompletionRoutine 123 GetNextCompletionRoutine( 124 VOID 125 ); 126 127 VOID 128 SetCompletionRoutine( 129 __in MdCompletionRoutine CompletionRoutine, 130 __in PVOID Context, 131 __in BOOLEAN InvokeOnSuccess = TRUE, 132 __in BOOLEAN InvokeOnError = TRUE, 133 __in BOOLEAN InvokeOnCancel = TRUE 134 ); 135 136 VOID 137 SetCompletionRoutineEx( 138 __in MdDeviceObject DeviceObject, 139 __in MdCompletionRoutine CompletionRoutine, 140 __in PVOID Context, 141 __in BOOLEAN InvokeOnSuccess = TRUE, 142 __in BOOLEAN InvokeOnError = TRUE, 143 __in BOOLEAN InvokeOnCancel = TRUE 144 ); 145 146 MdCancelRoutine 147 SetCancelRoutine( 148 __in_opt MdCancelRoutine CancelRoutine 149 ); 150 151 // 152 // SendIrpSynchronously achieves synchronous behavior by waiting on an 153 // event after submitting the IRP. The event creation can fail in UM, but 154 // not in KM. Hence, in UM the return code could either indicate event 155 // creation failure or it could indicate the status set on the IRP by the 156 // lower driver. In KM, the return code only indicates the status set on 157 // the IRP by the lower lower, because event creation cannot fail. 158 // 159 CHECK_RETURN_IF_USER_MODE 160 NTSTATUS 161 SendIrpSynchronously( 162 __in MdDeviceObject DeviceObject 163 ); 164 165 166 VOID 167 CopyCurrentIrpStackLocationToNext( 168 VOID 169 ); 170 171 VOID 172 CopyToNextIrpStackLocation( 173 __in PIO_STACK_LOCATION Stack 174 ); 175 176 VOID 177 SetNextIrpStackLocation( 178 VOID 179 ); 180 181 UCHAR 182 GetMajorFunction( 183 VOID 184 ); 185 186 UCHAR 187 GetMinorFunction( 188 VOID 189 ); 190 191 UCHAR 192 GetCurrentStackFlags( 193 VOID 194 ); 195 196 MdFileObject 197 GetCurrentStackFileObject( 198 VOID 199 ); 200 201 KPROCESSOR_MODE 202 GetRequestorMode( 203 VOID 204 ); 205 206 VOID 207 SetContext( 208 __in ULONG Index, 209 __in PVOID Value 210 ); 211 212 VOID 213 SetSystemBuffer( 214 __in PVOID Value 215 ); 216 217 VOID 218 SetUserBuffer( 219 __in PVOID Value 220 ); 221 222 VOID 223 SetMdlAddress( 224 __in PMDL Value 225 ); 226 227 VOID 228 SetFlags( 229 __in ULONG Flags 230 ); 231 232 PVOID 233 GetContext( 234 __in ULONG Index 235 ); 236 237 ULONG 238 GetFlags( 239 VOID 240 ); 241 242 PIO_STACK_LOCATION 243 GetCurrentIrpStackLocation( 244 VOID 245 ); 246 247 248 PIO_STACK_LOCATION 249 GetNextIrpStackLocation( 250 VOID 251 ); 252 253 static 254 PIO_STACK_LOCATION 255 _GetAndClearNextStackLocation( 256 __in MdIrp Irp 257 ); 258 259 260 VOID 261 SkipCurrentIrpStackLocation( 262 VOID 263 ); 264 265 266 VOID 267 MarkIrpPending( 268 ); 269 270 271 BOOLEAN 272 PendingReturned( 273 ); 274 275 276 VOID 277 PropagatePendingReturned( 278 VOID 279 ); 280 281 282 VOID 283 SetStatus( 284 __in NTSTATUS Status 285 ); 286 287 288 NTSTATUS 289 GetStatus( 290 ); 291 292 293 BOOLEAN 294 Cancel( 295 VOID 296 ); 297 298 VOID 299 SetCancel( 300 __in BOOLEAN Cancel 301 ); 302 303 304 BOOLEAN 305 IsCanceled( 306 ); 307 308 309 KIRQL 310 GetCancelIrql( 311 ); 312 313 314 VOID 315 SetInformation( 316 __in ULONG_PTR Information 317 ); 318 319 320 ULONG_PTR 321 GetInformation( 322 ); 323 324 325 CCHAR 326 GetCurrentIrpStackLocationIndex( 327 ); 328 329 CCHAR 330 GetStackCount( 331 ); 332 333 PLIST_ENTRY 334 ListEntry( 335 ); 336 337 338 PVOID 339 GetSystemBuffer( 340 ); 341 342 PVOID 343 GetOutputBuffer( 344 ); 345 346 PMDL 347 GetMdl( 348 ); 349 350 PMDL* 351 GetMdlAddressPointer( 352 ); 353 354 PVOID 355 GetUserBuffer( 356 ); 357 358 VOID 359 Reuse( 360 __in NTSTATUS Status = STATUS_SUCCESS 361 ); 362 363 // 364 // Methods for IO_STACK_LOCATION members 365 // 366 367 VOID 368 SetMajorFunction( 369 __in UCHAR MajorFunction 370 ); 371 372 373 VOID 374 SetMinorFunction( 375 __in UCHAR MinorFunction 376 ); 377 378 // 379 // Get Methods for IO_STACK_LOCATION.Parameters.Power 380 // 381 382 SYSTEM_POWER_STATE_CONTEXT 383 GetParameterPowerSystemPowerStateContext( 384 ); 385 386 387 POWER_STATE_TYPE 388 GetParameterPowerType( 389 ); 390 391 POWER_STATE 392 GetParameterPowerState( 393 ); 394 395 396 DEVICE_POWER_STATE 397 GetParameterPowerStateDeviceState( 398 ); 399 400 401 SYSTEM_POWER_STATE 402 GetParameterPowerStateSystemState( 403 ); 404 405 406 POWER_ACTION 407 GetParameterPowerShutdownType( 408 ); 409 410 411 MdFileObject 412 GetFileObject( 413 VOID 414 ); 415 416 417 // 418 // Get/Set Method for IO_STACK_LOCATION.Parameters.QueryDeviceRelations 419 // 420 421 DEVICE_RELATION_TYPE 422 GetParameterQDRType( 423 ); 424 425 VOID 426 SetParameterQDRType( 427 __in DEVICE_RELATION_TYPE DeviceRelation 428 ); 429 430 // 431 // Get/Set Methods for IO_STACK_LOCATION.Parameters.DeviceCapabilities 432 // 433 434 PDEVICE_CAPABILITIES 435 GetParameterDeviceCapabilities( 436 ); 437 438 VOID 439 SetCurrentDeviceObject( 440 __in MdDeviceObject DeviceObject 441 ); 442 443 MdDeviceObject 444 GetDeviceObject( 445 VOID 446 ); 447 448 VOID 449 SetParameterDeviceCapabilities( 450 __in PDEVICE_CAPABILITIES DeviceCapabilities 451 ); 452 453 454 // 455 // Get/Set Methods for IO_STACK_LOCATION.Parameters.Write.ByteOffset.QuadPart 456 // 457 458 LONGLONG 459 GetParameterWriteByteOffsetQuadPart( 460 ); 461 462 463 VOID 464 SetNextParameterWriteByteOffsetQuadPart( 465 __in LONGLONG DeviceOffset 466 ); 467 468 // 469 // Get/Set Methods for IO_STACK_LOCATION.Parameters.Write.Length 470 // 471 472 ULONG 473 GetCurrentParameterWriteLength( 474 ); 475 476 VOID 477 SetNextParameterWriteLength( 478 __in ULONG IoLength 479 ); 480 481 PVOID* 482 GetNextStackParameterOthersArgument1Pointer( 483 ); 484 485 VOID 486 SetNextStackParameterOthersArgument1( 487 __in PVOID Argument1 488 ); 489 490 PVOID* 491 GetNextStackParameterOthersArgument2Pointer( 492 ); 493 494 PVOID* 495 GetNextStackParameterOthersArgument4Pointer( 496 ); 497 498 // 499 // Get/Set Methods for IO_STACK_LOCATION.Parameters.StartDevice 500 // 501 502 PCM_RESOURCE_LIST 503 GetParameterAllocatedResources( 504 ); 505 506 507 VOID 508 SetParameterAllocatedResources( 509 __in PCM_RESOURCE_LIST AllocatedResources 510 ); 511 512 513 PCM_RESOURCE_LIST 514 GetParameterAllocatedResourcesTranslated( 515 ); 516 517 518 VOID 519 SetParameterAllocatedResourcesTranslated( 520 __in PCM_RESOURCE_LIST AllocatedResourcesTranslated 521 ); 522 523 // 524 // Get Method for IO_STACK_LOCATION.Parameters.QueryDeviceText 525 // 526 527 LCID 528 GetParameterQueryDeviceTextLocaleId( 529 ); 530 531 532 DEVICE_TEXT_TYPE 533 GetParameterQueryDeviceTextType( 534 ); 535 536 // 537 // Get Method for IO_STACK_LOCATION.Parameters.SetLock 538 // 539 540 BOOLEAN 541 GetParameterSetLockLock( 542 ); 543 544 // 545 // Get Method for IO_STACK_LOCATION.Parameters.QueryId 546 // 547 548 BUS_QUERY_ID_TYPE 549 GetParameterQueryIdType( 550 ); 551 552 // 553 // Get/Set Methods for IO_STACK_LOCATION.Parameters.QueryInterface 554 // 555 556 PINTERFACE 557 GetParameterQueryInterfaceInterface( 558 ); 559 560 561 const GUID* 562 GetParameterQueryInterfaceType( 563 ); 564 565 566 USHORT 567 GetParameterQueryInterfaceVersion( 568 ); 569 570 571 USHORT 572 GetParameterQueryInterfaceSize( 573 ); 574 575 576 PVOID 577 GetParameterQueryInterfaceInterfaceSpecificData( 578 ); 579 580 VOID 581 SetParameterQueryInterfaceInterface( 582 __in PINTERFACE Interface 583 ); 584 585 VOID 586 SetParameterQueryInterfaceType( 587 __in const GUID* InterfaceType 588 ); 589 590 VOID 591 SetParameterQueryInterfaceVersion( 592 __in USHORT Version 593 ); 594 595 VOID 596 SetParameterQueryInterfaceSize( 597 __in USHORT Size 598 ); 599 600 VOID 601 SetParameterQueryInterfaceInterfaceSpecificData( 602 __in PVOID InterfaceSpecificData 603 ); 604 605 // 606 // Get Method for IO_STACK_LOCATION.Parameters.UsageNotification 607 // 608 609 DEVICE_USAGE_NOTIFICATION_TYPE 610 GetParameterUsageNotificationType( 611 ); 612 613 614 BOOLEAN 615 GetParameterUsageNotificationInPath( 616 ); 617 618 619 VOID 620 SetParameterUsageNotificationInPath( 621 __in BOOLEAN InPath 622 ); 623 624 625 BOOLEAN 626 GetNextStackParameterUsageNotificationInPath( 627 ); 628 629 ULONG 630 GetParameterIoctlCode( 631 VOID 632 ); 633 634 ULONG 635 GetParameterIoctlCodeBufferMethod( 636 VOID 637 ); 638 639 ULONG 640 GetParameterIoctlInputBufferLength( 641 VOID 642 ); 643 644 ULONG 645 GetParameterIoctlOutputBufferLength( 646 VOID 647 ); 648 649 PVOID 650 GetParameterIoctlType3InputBuffer( 651 VOID 652 ); 653 654 // 655 // Set Methods for IO_STACK_LOCATION.Parameters.DeviceControl members 656 // 657 658 VOID 659 SetParameterIoctlCode( 660 __in ULONG DeviceIoControlCode 661 ); 662 663 VOID 664 SetParameterIoctlInputBufferLength( 665 __in ULONG InputBufferLength 666 ); 667 668 VOID 669 SetParameterIoctlOutputBufferLength( 670 __in ULONG OutputBufferLength 671 ); 672 673 VOID 674 SetParameterIoctlType3InputBuffer( 675 __in PVOID Type3InputBuffer 676 ); 677 678 ULONG 679 GetParameterReadLength( 680 VOID 681 ); 682 683 ULONG 684 GetParameterWriteLength( 685 VOID 686 ); 687 688 VOID 689 SetNextStackFlags( 690 __in UCHAR Flags 691 ); 692 693 VOID 694 SetNextStackFileObject( 695 _In_ MdFileObject FileObject 696 ); 697 698 PVOID 699 GetCurrentParametersPointer( 700 VOID 701 ); 702 703 // 704 // Methods for IO_STACK_LOCATION 705 // 706 707 VOID 708 ClearNextStack( 709 VOID 710 ); 711 712 VOID 713 ClearNextStackLocation( 714 VOID 715 ); 716 717 VOID 718 InitNextStackUsingStack( 719 __in FxIrp* Irp 720 ); 721 722 ULONG 723 GetCurrentFlags( 724 VOID 725 ); 726 727 VOID 728 FreeIrp( 729 VOID 730 ); 731 732 MdEThread 733 GetThread( 734 VOID 735 ); 736 737 BOOLEAN 738 Is32bitProcess( 739 VOID 740 ); 741 742 private: 743 744 static 745 NTSTATUS 746 _IrpSynchronousCompletion( 747 __in MdDeviceObject DeviceObject, 748 __in MdIrp OriginalIrp, 749 __in PVOID Context 750 ); 751 752 public: 753 754 _Must_inspect_result_ 755 static 756 MdIrp 757 AllocateIrp( 758 _In_ CCHAR StackSize, 759 _In_opt_ FxDevice* Device = NULL 760 ); 761 762 static 763 MdIrp 764 GetIrpFromListEntry( 765 __in PLIST_ENTRY Ple 766 ); 767 768 _Must_inspect_result_ 769 static 770 NTSTATUS 771 RequestPowerIrp( 772 __in MdDeviceObject DeviceObject, 773 __in UCHAR MinorFunction, 774 __in POWER_STATE PowerState, 775 __in MdRequestPowerComplete CompletionFunction, 776 __in PVOID Context 777 ); 778 779 PIO_STATUS_BLOCK 780 GetStatusBlock( 781 VOID 782 ); 783 784 PVOID 785 GetDriverContext( 786 ); 787 788 ULONG 789 GetDriverContextSize( 790 ); 791 792 VOID 793 CopyParameters( 794 _Out_ PWDF_REQUEST_PARAMETERS Parameters 795 ); 796 797 VOID 798 CopyStatus( 799 _Out_ PIO_STATUS_BLOCK StatusBlock 800 ); 801 802 BOOLEAN 803 HasStack( 804 _In_ UCHAR StackCount 805 ); 806 807 BOOLEAN 808 IsCurrentIrpStackLocationValid( 809 VOID 810 ); 811 812 #if (FX_CORE_MODE == FX_CORE_USER_MODE) 813 814 IWudfIoIrp* 815 GetIoIrp( 816 VOID 817 ); 818 819 IWudfPnpIrp* 820 GetPnpIrp( 821 VOID 822 ); 823 #endif 824 825 }; 826 827 // 828 // FxAutoIrp adds value to FxIrp by automatically freeing the associated MdIrp 829 // when it goes out of scope 830 // 831 struct FxAutoIrp : public FxIrp { 832 833 FxAutoIrp( 834 __in_opt MdIrp Irp = NULL 835 ) : 836 FxIrp(Irp) 837 { 838 } 839 840 841 ~FxAutoIrp(); 842 }; 843 844 #endif // _FXIRP_H_ 845