1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 Module Name: 6 7 FxDeviceApi.cpp 8 9 Abstract: 10 11 This module exposes the "C" interface to the FxDevice object. 12 13 Author: 14 15 16 17 Environment: 18 19 Both kernel and user mode 20 21 Revision History: 22 23 --*/ 24 25 #include "coreprivshared.hpp" 26 #include "fxiotarget.hpp" 27 28 extern "C" { 29 // #include "FxDeviceApi.tmh" 30 } 31 32 struct FxOffsetAndName { 33 __nullterminated PCHAR Name; 34 UCHAR Offset; 35 }; 36 37 #define OFFSET_AND_NAME(type, offset) { #offset, FIELD_OFFSET(type, offset) } 38 39 // 40 // extern "C" the entire file 41 // 42 extern "C" { 43 44 __drv_maxIRQL(DISPATCH_LEVEL) 45 WDFDRIVER 46 STDCALL 47 WDFEXPORT(WdfDeviceGetDriver)( 48 __in 49 PWDF_DRIVER_GLOBALS DriverGlobals, 50 __in 51 WDFDEVICE Device 52 ) 53 /*++ 54 55 Routine Description: 56 57 Given a Device Handle, return a Handle to the Driver object 58 containing this device. 59 60 Arguments: 61 Device - WDF Device handle. 62 63 Returns: 64 WDF Driver handle. 65 66 --*/ 67 68 { 69 DDI_ENTRY(); 70 71 FxDevice* pDevice; 72 73 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 74 Device, 75 FX_TYPE_DEVICE, 76 (PVOID*) &pDevice); 77 78 // 79 // No need to ref count the driver handle b/c it will be around as long 80 // as the device handle is. 81 // 82 return pDevice->GetDriver()->GetHandle(); 83 } 84 85 __drv_maxIRQL(DISPATCH_LEVEL) 86 WDFIOTARGET 87 STDCALL 88 WDFEXPORT(WdfDeviceGetIoTarget)( 89 __in 90 PWDF_DRIVER_GLOBALS DriverGlobals, 91 __in 92 WDFDEVICE Device 93 ) 94 { 95 DDI_ENTRY(); 96 97 FxIoTarget* pTarget; 98 FxDeviceBase *pDeviceBase; 99 100 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 101 Device, 102 FX_TYPE_DEVICE_BASE, 103 (PVOID*) &pDeviceBase); 104 105 pTarget = pDeviceBase->GetDefaultIoTarget(); 106 107 if (pTarget != NULL) { 108 return pTarget->GetHandle(); 109 } 110 111 return NULL; 112 } 113 114 _IRQL_requires_max_(DISPATCH_LEVEL) 115 WDFIOTARGET 116 STDCALL 117 WDFEXPORT(WdfDeviceGetSelfIoTarget)( 118 _In_ 119 PWDF_DRIVER_GLOBALS DriverGlobals, 120 _In_ 121 WDFDEVICE Device 122 ) 123 124 /*++ 125 126 Routine Description: 127 128 Return the handle to the Self IO target for the device. A Self 129 IO target is only created if the client opted for it by calling 130 WdfDeviceInitAllowSelfTarget 131 132 Arguments: 133 134 Device - Handle to the Device Object for which Self IO target is needed 135 136 Returns: 137 138 WDFIOTARGET handle to the Self IO Target. NULL is returned in case the 139 device does not have an Self IO target. 140 141 --*/ 142 143 { 144 DDI_ENTRY(); 145 146 FxIoTargetSelf* pTarget; 147 FxDevice *pDevice; 148 149 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 150 Device, 151 FX_TYPE_DEVICE, 152 (PVOID*) &pDevice); 153 154 pTarget = pDevice->GetSelfIoTarget(); 155 156 if (pTarget != NULL) { 157 return pTarget->GetHandle(); 158 } 159 160 return NULL; 161 } 162 163 _Must_inspect_result_ 164 __drv_maxIRQL(PASSIVE_LEVEL) 165 NTSTATUS 166 STDCALL 167 WDFEXPORT(WdfDeviceRetrieveDeviceName)( 168 __in 169 PWDF_DRIVER_GLOBALS DriverGlobals, 170 __in 171 WDFDEVICE Device, 172 __in 173 WDFSTRING String 174 ) 175 { 176 DDI_ENTRY(); 177 178 PFX_DRIVER_GLOBALS pFxDriverGlobals; 179 FxDevice *pDevice; 180 FxString* pString; 181 NTSTATUS status; 182 183 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 184 Device, 185 FX_TYPE_DEVICE, 186 (PVOID *) &pDevice, 187 &pFxDriverGlobals); 188 189 status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL); 190 if (!NT_SUCCESS(status)) { 191 return status; 192 } 193 194 FxObjectHandleGetPtr(pFxDriverGlobals, 195 String, 196 FX_TYPE_STRING, 197 (PVOID*) &pString); 198 199 if (pDevice->m_DeviceName.Buffer != NULL) { 200 status = pString->Assign(&pDevice->m_DeviceName); 201 } 202 else { 203 status = STATUS_INVALID_PARAMETER; 204 DoTraceLevelMessage( 205 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP, 206 "Device name for WDFDEVICE 0x%p is NULL. Possibly incorrect " 207 "device handle was passed, %!STATUS!", Device, status); 208 } 209 210 return status; 211 } 212 213 __drv_maxIRQL(DISPATCH_LEVEL) 214 VOID 215 STDCALL 216 WDFEXPORT(WdfDeviceSetCharacteristics)( 217 __in 218 PWDF_DRIVER_GLOBALS DriverGlobals, 219 __in 220 WDFDEVICE Device, 221 __in 222 ULONG DeviceCharacteristics 223 ) 224 { 225 DDI_ENTRY(); 226 227 FxDevice *pDevice; 228 MxDeviceObject deviceObject; 229 230 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 231 Device, 232 FX_TYPE_DEVICE, 233 (PVOID*) &pDevice); 234 235 deviceObject.SetObject(pDevice->GetDeviceObject()); 236 deviceObject.SetCharacteristics(DeviceCharacteristics | 237 FILE_DEVICE_SECURE_OPEN); 238 } 239 240 __drv_maxIRQL(DISPATCH_LEVEL) 241 ULONG 242 STDCALL 243 WDFEXPORT(WdfDeviceGetCharacteristics)( 244 __in 245 PWDF_DRIVER_GLOBALS DriverGlobals, 246 __in 247 WDFDEVICE Device 248 ) 249 { 250 DDI_ENTRY(); 251 252 FxDevice *pDevice; 253 MxDeviceObject deviceObject; 254 255 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 256 Device, 257 FX_TYPE_DEVICE, 258 (PVOID*) &pDevice); 259 260 deviceObject.SetObject(pDevice->GetDeviceObject()); 261 262 return deviceObject.GetCharacteristics(); 263 } 264 265 __drv_maxIRQL(DISPATCH_LEVEL) 266 ULONG 267 STDCALL 268 WDFEXPORT(WdfDeviceGetAlignmentRequirement)( 269 __in 270 PWDF_DRIVER_GLOBALS DriverGlobals, 271 __in 272 WDFDEVICE Device 273 ) 274 { 275 DDI_ENTRY(); 276 277 FxDeviceBase* pDeviceBase; 278 MxDeviceObject deviceObject; 279 280 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 281 Device, 282 FX_TYPE_DEVICE_BASE, 283 (PVOID*) &pDeviceBase); 284 285 deviceObject.SetObject(pDeviceBase->GetDeviceObject()); 286 287 return deviceObject.GetAlignmentRequirement(); 288 } 289 290 __drv_maxIRQL(DISPATCH_LEVEL) 291 VOID 292 STDCALL 293 WDFEXPORT(WdfDeviceSetAlignmentRequirement)( 294 __in 295 PWDF_DRIVER_GLOBALS DriverGlobals, 296 __in 297 WDFDEVICE Device, 298 __in 299 ULONG AlignmentRequirement 300 ) 301 { 302 DDI_ENTRY(); 303 304 FxDeviceBase* pDeviceBase; 305 MxDeviceObject deviceObject; 306 307 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 308 Device, 309 FX_TYPE_DEVICE_BASE, 310 (PVOID*) &pDeviceBase); 311 312 deviceObject.SetObject(pDeviceBase->GetDeviceObject()); 313 314 deviceObject.SetAlignmentRequirement(AlignmentRequirement); 315 } 316 317 __drv_maxIRQL(DISPATCH_LEVEL) 318 WDF_DEVICE_PNP_STATE 319 STDCALL 320 WDFEXPORT(WdfDeviceGetDevicePnpState)( 321 __in 322 PWDF_DRIVER_GLOBALS DriverGlobals, 323 __in 324 WDFDEVICE Device 325 ) 326 { 327 DDI_ENTRY(); 328 329 FxDevice *pDevice; 330 331 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 332 Device, 333 FX_TYPE_DEVICE, 334 (PVOID*) &pDevice); 335 336 return pDevice->GetDevicePnpState(); 337 } 338 339 __drv_maxIRQL(DISPATCH_LEVEL) 340 WDF_DEVICE_POWER_STATE 341 STDCALL 342 WDFEXPORT(WdfDeviceGetDevicePowerState)( 343 __in 344 PWDF_DRIVER_GLOBALS DriverGlobals, 345 __in 346 WDFDEVICE Device 347 ) 348 { 349 DDI_ENTRY(); 350 351 FxDevice *pDevice; 352 353 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 354 Device, 355 FX_TYPE_DEVICE, 356 (PVOID*) &pDevice); 357 358 return pDevice->GetDevicePowerState(); 359 } 360 361 __drv_maxIRQL(DISPATCH_LEVEL) 362 WDF_DEVICE_POWER_POLICY_STATE 363 STDCALL 364 WDFEXPORT(WdfDeviceGetDevicePowerPolicyState)( 365 __in 366 PWDF_DRIVER_GLOBALS DriverGlobals, 367 __in 368 WDFDEVICE Device 369 ) 370 { 371 DDI_ENTRY(); 372 373 FxDevice *pDevice; 374 375 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 376 Device, 377 FX_TYPE_DEVICE, 378 (PVOID*) &pDevice); 379 380 return pDevice->GetDevicePowerPolicyState(); 381 } 382 383 _Must_inspect_result_ 384 __drv_maxIRQL(DISPATCH_LEVEL) 385 NTSTATUS 386 STDCALL 387 WDFEXPORT(WdfDeviceAssignS0IdleSettings)( 388 __in 389 PWDF_DRIVER_GLOBALS DriverGlobals, 390 __in 391 WDFDEVICE Device, 392 __in 393 PWDF_DEVICE_POWER_POLICY_IDLE_SETTINGS Settings 394 ) 395 { 396 DDI_ENTRY(); 397 398 PFX_DRIVER_GLOBALS pFxDriverGlobals; 399 NTSTATUS status; 400 FxDevice* pDevice; 401 402 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 403 Device, 404 FX_TYPE_DEVICE, 405 (PVOID *) &pDevice, 406 &pFxDriverGlobals); 407 408 FxPointerNotNull(pFxDriverGlobals, Settings); 409 410 if (pDevice->m_PkgPnp->IsPowerPolicyOwner() == FALSE) { 411 status = STATUS_INVALID_DEVICE_REQUEST; 412 413 DoTraceLevelMessage( 414 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP, 415 "Device 0x%p is not the power policy owner, caller cannot set S0" 416 " idle settings %!STATUS!", Device, status); 417 418 return status; 419 } 420 421 // 422 // Validate the Settings parameter 423 // 424 if (Settings->Size != sizeof(WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS) && 425 Settings->Size != sizeof(WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_V1_9) && 426 Settings->Size != sizeof(WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_V1_7)) { 427 status = STATUS_INFO_LENGTH_MISMATCH; 428 DoTraceLevelMessage( 429 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 430 "Expected Settings Size %d, got %d, %!STATUS!", 431 sizeof(WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS), Settings->Size, 432 status); 433 return status; 434 } 435 else if (Settings->DxState < PowerDeviceD1 || 436 Settings->DxState > PowerDeviceMaximum || 437 Settings->IdleCaps < IdleCannotWakeFromS0 || 438 Settings->IdleCaps > IdleUsbSelectiveSuspend || 439 Settings->UserControlOfIdleSettings < IdleDoNotAllowUserControl || 440 Settings->UserControlOfIdleSettings > IdleAllowUserControl || 441 Settings->Enabled < WdfFalse || 442 Settings->Enabled > WdfUseDefault) { 443 444 status = STATUS_INVALID_PARAMETER; 445 DoTraceLevelMessage( 446 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 447 "a field (DxState, IdleCaps, Enabled, or UserControlOfIdleSettings)" 448 " is out range, %!STATUS!", status); 449 return status; 450 } 451 452 // 453 // PowerUpIdleDeviceOnSystemWake is available only on > 1.7 and can be set to true 454 // only when IdleCaps is IdleCannotWakeFromS0 455 // 456 if (Settings->Size > sizeof(WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_V1_7)) { 457 if (Settings->PowerUpIdleDeviceOnSystemWake < WdfFalse || 458 Settings->PowerUpIdleDeviceOnSystemWake > WdfUseDefault) { 459 460 status = STATUS_INVALID_PARAMETER; 461 DoTraceLevelMessage( 462 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 463 "value of field PowerUpIdleDeviceOnSystemWake is out of range," 464 " %!STATUS!", status); 465 return status; 466 } 467 else if (Settings->IdleCaps != IdleCannotWakeFromS0 && 468 Settings->PowerUpIdleDeviceOnSystemWake != WdfUseDefault) { 469 470 status = STATUS_INVALID_PARAMETER; 471 DoTraceLevelMessage( 472 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 473 "value of field PowerUpIdleDeviceOnSystemWake should be set only when" 474 " IdleCaps is IdleCannotWakeFromS0, %!STATUS!", status); 475 return status; 476 } 477 } 478 479 // 480 // IdleTimeoutType is available only on > 1.9 481 // 482 if (Settings->Size > sizeof(WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_V1_9)) { 483 if (Settings->IdleTimeoutType > SystemManagedIdleTimeoutWithHint) { 484 status = STATUS_INVALID_PARAMETER; 485 DoTraceLevelMessage( 486 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 487 "WDFDEVICE %p, value of field IdleTimeoutType is out of range," 488 " %!STATUS!", Device, status); 489 return status; 490 } 491 } 492 493 return pDevice->m_PkgPnp->PowerPolicySetS0IdleSettings(Settings); 494 } 495 496 _Must_inspect_result_ 497 __drv_maxIRQL(DISPATCH_LEVEL) 498 NTSTATUS 499 STDCALL 500 WDFEXPORT(WdfDeviceAssignSxWakeSettings)( 501 __in 502 PWDF_DRIVER_GLOBALS DriverGlobals, 503 __in 504 WDFDEVICE Device, 505 __in 506 PWDF_DEVICE_POWER_POLICY_WAKE_SETTINGS Settings 507 ) 508 { 509 DDI_ENTRY(); 510 511 NTSTATUS status; 512 FxDevice* pDevice; 513 PFX_DRIVER_GLOBALS pFxDriverGlobals; 514 BOOLEAN armForWakeIfChildrenAreArmedForWake; 515 BOOLEAN indicateChildWakeOnParentWake; 516 517 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 518 Device, 519 FX_TYPE_DEVICE, 520 (PVOID *) &pDevice, 521 &pFxDriverGlobals); 522 523 FxPointerNotNull(pFxDriverGlobals, Settings); 524 525 if (pDevice->m_PkgPnp->IsPowerPolicyOwner() == FALSE) { 526 status = STATUS_INVALID_DEVICE_REQUEST; 527 528 DoTraceLevelMessage( 529 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP, 530 "Device 0x%p is not the power policy owner, caller cannot set Sx" 531 " wake settings %!STATUS!", Device, status); 532 533 return status; 534 } 535 536 // 537 // Validate the Settings parameter 538 // 539 if (Settings->Size != sizeof(WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS) && 540 Settings->Size != sizeof(WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS_V1_5)) { 541 status = STATUS_INFO_LENGTH_MISMATCH; 542 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 543 "Expected Settings Size %x, got %x, %!STATUS!", 544 sizeof(WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS), 545 Settings->Size, 546 status); 547 return status; 548 } 549 else if (Settings->DxState < PowerDeviceD1 || 550 Settings->DxState > PowerDeviceMaximum || 551 Settings->UserControlOfWakeSettings < WakeDoNotAllowUserControl || 552 Settings->UserControlOfWakeSettings > WakeAllowUserControl || 553 Settings->Enabled < WdfFalse || 554 Settings->Enabled > WdfUseDefault) { 555 556 status = STATUS_INVALID_PARAMETER; 557 DoTraceLevelMessage( 558 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 559 "a field (DxState, Enabled, or UserControlOfIdleSettings) is out " 560 "range, %!STATUS!", status); 561 return status; 562 } 563 564 // 565 // Extract the values from the structure for all the parameters that were 566 // added after v1.5. Since the size of the structure can only grow, get 567 // the values only if we are using a version of the struct after v1.5 568 // 569 570 // 571 // ArmForWakeIfChildrenAreArmedForWake added after v1.5 572 // 573 armForWakeIfChildrenAreArmedForWake = 574 (Settings->Size > sizeof(WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS_V1_5)) ? 575 Settings->ArmForWakeIfChildrenAreArmedForWake : 576 FALSE; 577 578 // 579 // IndicateChildWakeOnParentWake added after v1.5 580 // 581 indicateChildWakeOnParentWake = 582 (Settings->Size > sizeof(WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS_V1_5)) ? 583 Settings->IndicateChildWakeOnParentWake : 584 FALSE; 585 586 return pDevice->m_PkgPnp->PowerPolicySetSxWakeSettings( 587 Settings, 588 armForWakeIfChildrenAreArmedForWake, 589 indicateChildWakeOnParentWake); 590 } 591 592 _Must_inspect_result_ 593 __drv_maxIRQL(PASSIVE_LEVEL) 594 NTSTATUS 595 STDCALL 596 WDFEXPORT(WdfDeviceOpenRegistryKey)( 597 __in 598 PWDF_DRIVER_GLOBALS DriverGlobals, 599 __in 600 WDFDEVICE Device, 601 __in 602 ULONG DeviceInstanceKeyType, 603 __in 604 ACCESS_MASK DesiredAccess, 605 __in_opt 606 PWDF_OBJECT_ATTRIBUTES KeyAttributes, 607 __out 608 WDFKEY* Key 609 ) 610 { 611 DDI_ENTRY(); 612 613 NTSTATUS status; 614 FxDevice* pDevice; 615 PFX_DRIVER_GLOBALS pFxDriverGlobals; 616 617 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 618 Device, 619 FX_TYPE_DEVICE, 620 (PVOID *) &pDevice, 621 &pFxDriverGlobals); 622 623 FxPointerNotNull(pFxDriverGlobals, Key); 624 625 *Key = NULL; 626 627 status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL); 628 if (!NT_SUCCESS(status)) { 629 FxVerifierDbgBreakPoint(pFxDriverGlobals); 630 return status; 631 } 632 633 status = FxValidateObjectAttributes(pFxDriverGlobals, KeyAttributes, 634 FX_VALIDATE_OPTION_PARENT_NOT_ALLOWED); 635 if (!NT_SUCCESS(status)) { 636 637 return status; 638 } 639 640 return FxDevice::_OpenKey(pDevice->GetDriverGlobals(), 641 NULL, 642 pDevice, 643 DeviceInstanceKeyType, 644 DesiredAccess, 645 KeyAttributes, 646 Key); 647 } 648 649 _Must_inspect_result_ 650 _IRQL_requires_max_(PASSIVE_LEVEL) 651 NTSTATUS 652 STDCALL 653 WDFEXPORT(WdfDeviceOpenDevicemapKey) ( 654 _In_ 655 PWDF_DRIVER_GLOBALS DriverGlobals, 656 _In_ 657 WDFDEVICE Device, 658 _In_ 659 PCUNICODE_STRING KeyName, 660 _In_ 661 ACCESS_MASK DesiredAccess, 662 _In_opt_ 663 PWDF_OBJECT_ATTRIBUTES KeyAttributes, 664 _Out_ 665 WDFKEY* Key 666 ) 667 { 668 DDI_ENTRY(); 669 670 NTSTATUS status; 671 FxDevice* pDevice; 672 PFX_DRIVER_GLOBALS pFxDriverGlobals; 673 FxRegKey* pKey = NULL; 674 WDFKEY keyHandle; 675 676 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 677 Device, 678 FX_TYPE_DEVICE, 679 (PVOID *) &pDevice, 680 &pFxDriverGlobals); 681 682 FxPointerNotNull(pFxDriverGlobals, Key); 683 684 *Key = NULL; 685 686 status = FxValidateUnicodeString(pFxDriverGlobals, KeyName); 687 if (!NT_SUCCESS(status)) { 688 return status; 689 } 690 691 if (KeyName->Length == 0) { 692 status = STATUS_INVALID_PARAMETER; 693 DoTraceLevelMessage( 694 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 695 "The subkey cannot be of length zero, %!STATUS!", status); 696 return status; 697 } 698 699 status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL); 700 if (!NT_SUCCESS(status)) { 701 FxVerifierDbgBreakPoint(pFxDriverGlobals); 702 return status; 703 } 704 705 status = FxValidateObjectAttributes(pFxDriverGlobals, KeyAttributes, 706 FX_VALIDATE_OPTION_PARENT_NOT_ALLOWED); 707 if (!NT_SUCCESS(status)) { 708 return status; 709 } 710 711 pKey = new(pFxDriverGlobals, KeyAttributes) FxRegKey(pFxDriverGlobals); 712 713 if (pKey == NULL) { 714 status = STATUS_INSUFFICIENT_RESOURCES; 715 DoTraceLevelMessage( 716 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 717 "Unable to allocate memory for WDFKEY object, %!STATUS!", status); 718 return status; 719 } 720 721 pKey->SetDeviceBase(pDevice); 722 723 status = pKey->Commit(KeyAttributes, (WDFOBJECT*)&keyHandle); 724 if (NT_SUCCESS(status)) { 725 726 status = pDevice->OpenDevicemapKeyWorker(pFxDriverGlobals, 727 KeyName, 728 DesiredAccess, 729 pKey); 730 if (NT_SUCCESS(status)) { 731 *Key = keyHandle; 732 } 733 } 734 735 if (!NT_SUCCESS(status)) { 736 pKey->DeleteFromFailedCreate(); 737 pKey = NULL; 738 } 739 740 return status; 741 } 742 743 __drv_maxIRQL(DISPATCH_LEVEL) 744 VOID 745 STDCALL 746 WDFEXPORT(WdfDeviceGetDeviceState)( 747 __in 748 PWDF_DRIVER_GLOBALS DriverGlobals, 749 __in 750 WDFDEVICE Device, 751 __out 752 PWDF_DEVICE_STATE DeviceState 753 ) 754 { 755 DDI_ENTRY(); 756 757 FxDevice *pDevice; 758 PFX_DRIVER_GLOBALS pFxDriverGlobals; 759 760 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 761 Device, 762 FX_TYPE_DEVICE, 763 (PVOID *) &pDevice, 764 &pFxDriverGlobals); 765 766 FxPointerNotNull(pFxDriverGlobals, DeviceState); 767 768 if (DeviceState->Size != sizeof(WDF_DEVICE_STATE)) { 769 DoTraceLevelMessage( 770 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 771 "WDFDEVICE 0x%p DeviceState Size %d, expected %d", 772 Device, DeviceState->Size, sizeof(WDF_DEVICE_STATE)); 773 774 FxVerifierDbgBreakPoint(pFxDriverGlobals); 775 776 return; // STATUS_INFO_LENGTH_MISMATCH; 777 } 778 779 pDevice->m_PkgPnp->GetPnpState(DeviceState); 780 } 781 782 __drv_maxIRQL(DISPATCH_LEVEL) 783 VOID 784 STDCALL 785 WDFEXPORT(WdfDeviceSetDeviceState)( 786 __in 787 PWDF_DRIVER_GLOBALS DriverGlobals, 788 __in 789 WDFDEVICE Device, 790 __in 791 PWDF_DEVICE_STATE DeviceState 792 ) 793 { 794 DDI_ENTRY(); 795 796 FxDevice *pDevice; 797 PFX_DRIVER_GLOBALS pFxDriverGlobals; 798 ULONG i; 799 800 const static FxOffsetAndName offsets[] = { 801 OFFSET_AND_NAME(WDF_DEVICE_STATE, Disabled), 802 OFFSET_AND_NAME(WDF_DEVICE_STATE, DontDisplayInUI), 803 OFFSET_AND_NAME(WDF_DEVICE_STATE, Failed), 804 OFFSET_AND_NAME(WDF_DEVICE_STATE, NotDisableable), 805 OFFSET_AND_NAME(WDF_DEVICE_STATE, Removed), 806 OFFSET_AND_NAME(WDF_DEVICE_STATE, ResourcesChanged), 807 }; 808 809 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 810 Device, 811 FX_TYPE_DEVICE, 812 (PVOID *) &pDevice, 813 &pFxDriverGlobals); 814 815 FxPointerNotNull(pFxDriverGlobals, DeviceState); 816 817 if (DeviceState->Size != sizeof(WDF_DEVICE_STATE)) { 818 DoTraceLevelMessage( 819 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 820 "WDFDEVICE 0x%p, DeviceState Size %d, expected %d", 821 Device, DeviceState->Size, sizeof(WDF_DEVICE_STATE)); 822 823 FxVerifierDbgBreakPoint(pFxDriverGlobals); 824 return; // STATUS_INFO_LENGTH_MISMATCH; 825 } 826 827 for (i = 0; i < ARRAY_SIZE(offsets); i++) { 828 WDF_TRI_STATE value; 829 830 // 831 // This check makes prefast happy 832 // 833 if (offsets[i].Offset + sizeof(WDF_TRI_STATE) > sizeof(*DeviceState)) { 834 return; 835 } 836 837 value = *(WDF_TRI_STATE*) WDF_PTR_ADD_OFFSET(DeviceState, 838 offsets[i].Offset); 839 840 switch (value) { 841 case WdfFalse: 842 case WdfTrue: 843 case WdfUseDefault: 844 break; 845 846 default: 847 DoTraceLevelMessage( 848 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 849 "WDFDEVICE 0x%p DeviceState WDF_TRI_STATE %s value out of range, " 850 "value is %d", Device, offsets[i].Name, value); 851 FxVerifierDbgBreakPoint(pFxDriverGlobals); 852 853 return; // STATUS_INVALID_PARAMETER 854 } 855 } 856 857 pDevice->m_PkgPnp->SetPnpState(DeviceState); 858 859 pDevice->InvalidateDeviceState(); 860 } 861 862 863 _Must_inspect_result_ 864 __drv_maxIRQL(PASSIVE_LEVEL) 865 NTSTATUS 866 STDCALL 867 WDFEXPORT(WdfDeviceCreate)( 868 __in 869 PWDF_DRIVER_GLOBALS DriverGlobals, 870 871 872 __inout 873 874 PWDFDEVICE_INIT* DeviceInit, 875 __in_opt 876 PWDF_OBJECT_ATTRIBUTES DeviceAttributes, 877 __out 878 WDFDEVICE* Device 879 ) 880 { 881 DDI_ENTRY(); 882 883 FxDevice* pDevice; 884 NTSTATUS status; 885 PFX_DRIVER_GLOBALS pFxDriverGlobals; 886 887 pFxDriverGlobals = GetFxDriverGlobals(DriverGlobals); 888 889 FxPointerNotNull(pFxDriverGlobals, DeviceInit); 890 FxPointerNotNull(pFxDriverGlobals, *DeviceInit); 891 FxPointerNotNull(pFxDriverGlobals, Device); 892 893 // 894 // Use the object's globals, not the caller's globals 895 // 896 pFxDriverGlobals = (*DeviceInit)->DriverGlobals; 897 898 *Device = NULL; 899 900 status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL); 901 if (!NT_SUCCESS(status)) { 902 return status; 903 } 904 905 // 906 // Make sure the device attributes is initialized properly if passed in 907 // 908 status = FxValidateObjectAttributes(pFxDriverGlobals, 909 DeviceAttributes, 910 (FX_VALIDATE_OPTION_PARENT_NOT_ALLOWED | 911 FX_VALIDATE_OPTION_EXECUTION_LEVEL_ALLOWED | 912 FX_VALIDATE_OPTION_SYNCHRONIZATION_SCOPE_ALLOWED)); 913 914 if (!NT_SUCCESS(status)) { 915 return status; 916 } 917 918 if ((*DeviceInit)->CreatedDevice != NULL) { 919 // 920 // Already created the device! 921 // 922 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 923 "WDFDEVICE 0x%p already created" 924 "STATUS_INVALID_DEVICE_STATE", 925 Device); 926 927 return STATUS_INVALID_DEVICE_STATE; 928 } 929 930 // 931 // If security is specified, then the device being created *must* have a 932 // name to apply that security too. 933 // 934 if ((*DeviceInit)->Security.Sddl != NULL || (*DeviceInit)->Security.DeviceClassSet) { 935 if ((*DeviceInit)->HasName()) { 936 // 937 // Driver writer specified a name, all is good 938 // 939 DO_NOTHING(); 940 } 941 else { 942 status = STATUS_INVALID_SECURITY_DESCR; 943 944 DoTraceLevelMessage( 945 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 946 "Device init: has device class or SDDL set, but does not have " 947 "a name, %!STATUS!", status); 948 949 return status; 950 } 951 } 952 953 if ((*DeviceInit)->RequiresSelfIoTarget) { 954 if ((*DeviceInit)->InitType != FxDeviceInitTypeFdo) { 955 status = STATUS_INVALID_DEVICE_REQUEST; 956 DoTraceLevelMessage( 957 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 958 "Client called WdfDeviceInitAllowSelfTarget. Self " 959 "IO Targets are supported only for FDOs, %!STATUS!", status); 960 return status; 961 } 962 } 963 964 status = FxDevice::_Create(pFxDriverGlobals, 965 DeviceInit, 966 DeviceAttributes, 967 &pDevice); 968 if (NT_SUCCESS(status)) { 969 *Device = pDevice->GetHandle(); 970 } 971 972 return status; 973 } 974 975 _Must_inspect_result_ 976 __drv_maxIRQL(PASSIVE_LEVEL) 977 NTSTATUS 978 STDCALL 979 WDFEXPORT(WdfDeviceCreateSymbolicLink)( 980 __in 981 PWDF_DRIVER_GLOBALS DriverGlobals, 982 __in 983 WDFDEVICE Device, 984 __in 985 PCUNICODE_STRING SymbolicLinkName 986 ) 987 { 988 DDI_ENTRY(); 989 990 PFX_DRIVER_GLOBALS pFxDriverGlobals; 991 FxAutoString pdoName; 992 FxDevice* pDevice; 993 NTSTATUS status; 994 995 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 996 Device, 997 FX_TYPE_DEVICE, 998 (PVOID *) &pDevice, 999 &pFxDriverGlobals); 1000 1001 FxPointerNotNull(pFxDriverGlobals, SymbolicLinkName); 1002 1003 if (SymbolicLinkName->Length == 0) { 1004 status = STATUS_INVALID_DEVICE_REQUEST; 1005 1006 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 1007 "WDFDEVICE %p, SymbolicLinkName has no length, %!STATUS!", 1008 Device, status); 1009 1010 return status; 1011 } 1012 1013 status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL); 1014 if (!NT_SUCCESS(status)) { 1015 return status; 1016 } 1017 1018 status = FxValidateUnicodeString(pFxDriverGlobals, SymbolicLinkName); 1019 if (!NT_SUCCESS(status)) { 1020 return status; 1021 } 1022 1023 if (pDevice->m_SymbolicLinkName.Buffer != NULL) { 1024 status = STATUS_INVALID_DEVICE_REQUEST; 1025 1026 DoTraceLevelMessage( 1027 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 1028 "WDFDEVICE %p already has a symbolic link associated with it, %!STATUS!", 1029 Device, status); 1030 1031 return status; 1032 } 1033 1034 status = pDevice->CreateSymbolicLink(pFxDriverGlobals, SymbolicLinkName); 1035 1036 return status; 1037 } 1038 1039 _Must_inspect_result_ 1040 __drv_maxIRQL(PASSIVE_LEVEL) 1041 NTSTATUS 1042 STDCALL 1043 WDFEXPORT(WdfDeviceQueryProperty)( 1044 __in 1045 PWDF_DRIVER_GLOBALS DriverGlobals, 1046 __in 1047 WDFDEVICE Device, 1048 __in 1049 DEVICE_REGISTRY_PROPERTY DeviceProperty, 1050 __in 1051 ULONG BufferLength, 1052 __out_bcount_full(BufferLength) 1053 PVOID PropertyBuffer, 1054 __out 1055 PULONG ResultLength 1056 ) 1057 /*++ 1058 1059 Routine Description: 1060 Retrieves the requested device property for the given device 1061 1062 Arguments: 1063 Device - the device whose PDO whose will be queried 1064 1065 DeviceProperty - the property being queried 1066 1067 BufferLength - length of PropertyBuffer in bytes 1068 1069 PropertyBuffer - Buffer which will receive the property being queried 1070 1071 ResultLength - if STATUS_BUFFER_TOO_SMALL is returned, then this will contain 1072 the required length 1073 1074 Return Value: 1075 NTSTATUS 1076 1077 --*/ 1078 { 1079 DDI_ENTRY(); 1080 1081 PFX_DRIVER_GLOBALS pFxDriverGlobals; 1082 FxDevice* pDevice; 1083 NTSTATUS status; 1084 1085 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 1086 Device, 1087 FX_TYPE_DEVICE, 1088 (PVOID *) &pDevice, 1089 &pFxDriverGlobals); 1090 1091 FxPointerNotNull(pFxDriverGlobals, ResultLength); 1092 if (BufferLength > 0) { 1093 FxPointerNotNull(pFxDriverGlobals, PropertyBuffer); 1094 } 1095 1096 status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL); 1097 if (!NT_SUCCESS(status)) { 1098 return status; 1099 } 1100 1101 if (pDevice->IsLegacy()) { 1102 status = STATUS_INVALID_DEVICE_REQUEST; 1103 1104 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 1105 "WDFDEVICE 0x%p is not a PnP device %!STATUS!", 1106 Device, status); 1107 1108 return status; 1109 } 1110 1111 status = FxDevice::_QueryProperty(pFxDriverGlobals, 1112 NULL, 1113 pDevice, 1114 NULL, 1115 DeviceProperty, 1116 BufferLength, 1117 PropertyBuffer, 1118 ResultLength); 1119 1120 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGDEVICE, 1121 "exit WDFDEVICE %p, Property %d, %!STATUS!", 1122 Device, DeviceProperty, status); 1123 1124 return status; 1125 } 1126 1127 _Must_inspect_result_ 1128 __drv_maxIRQL(PASSIVE_LEVEL) 1129 NTSTATUS 1130 STDCALL 1131 WDFEXPORT(WdfDeviceAllocAndQueryProperty)( 1132 __in 1133 PWDF_DRIVER_GLOBALS DriverGlobals, 1134 __in 1135 WDFDEVICE Device, 1136 __in 1137 DEVICE_REGISTRY_PROPERTY DeviceProperty, 1138 __in 1139 __drv_strictTypeMatch(__drv_typeExpr) 1140 POOL_TYPE PoolType, 1141 __in_opt 1142 PWDF_OBJECT_ATTRIBUTES PropertyMemoryAttributes, 1143 __out 1144 WDFMEMORY* PropertyMemory 1145 ) 1146 /*++ 1147 1148 Routine Description: 1149 Allocates and retrieves the requested device property for the given device 1150 1151 Arguments: 1152 Device - the pnp device whose PDO whose will be queried 1153 1154 DeviceProperty - the property being queried 1155 1156 PoolType - what type of pool to allocate 1157 1158 PropertyMemoryAttributes - attributes to associate with PropertyMemory 1159 1160 PropertyMemory - handle which will receive the property buffer 1161 1162 Return Value: 1163 NTSTATUS 1164 1165 --*/ 1166 { 1167 DDI_ENTRY(); 1168 1169 PFX_DRIVER_GLOBALS pFxDriverGlobals; 1170 FxDevice* pDevice; 1171 NTSTATUS status; 1172 1173 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 1174 Device, 1175 FX_TYPE_DEVICE, 1176 (PVOID *) &pDevice, 1177 &pFxDriverGlobals); 1178 1179 FxPointerNotNull(pFxDriverGlobals, PropertyMemory); 1180 1181 *PropertyMemory = NULL; 1182 1183 status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL); 1184 if (!NT_SUCCESS(status)) { 1185 return status; 1186 } 1187 1188 FxVerifierCheckNxPoolType(pFxDriverGlobals, PoolType, pFxDriverGlobals->Tag); 1189 1190 status = FxValidateObjectAttributes(pFxDriverGlobals, PropertyMemoryAttributes); 1191 if (!NT_SUCCESS(status)) { 1192 return status; 1193 } 1194 1195 if (pDevice->IsLegacy()) { 1196 status = STATUS_INVALID_DEVICE_REQUEST; 1197 1198 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 1199 "WDFDEVICE %p is not a PnP device, %!STATUS!", 1200 Device, status); 1201 1202 return status; 1203 } 1204 1205 status = FxDevice::_AllocAndQueryProperty(pFxDriverGlobals, 1206 NULL, 1207 pDevice, 1208 NULL, 1209 DeviceProperty, 1210 PoolType, 1211 PropertyMemoryAttributes, 1212 PropertyMemory); 1213 1214 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGDEVICE, 1215 "exit WDFDEVICE %p, Property %d, %!STATUS!", 1216 Device, DeviceProperty, status); 1217 1218 return status; 1219 } 1220 1221 __drv_maxIRQL(DISPATCH_LEVEL) 1222 VOID 1223 STDCALL 1224 WDFEXPORT(WdfDeviceSetStaticStopRemove)( 1225 __in 1226 PWDF_DRIVER_GLOBALS DriverGlobals, 1227 __in 1228 WDFDEVICE Device, 1229 __in 1230 BOOLEAN Stoppable 1231 ) 1232 { 1233 DDI_ENTRY(); 1234 1235 FxDevice *pDevice; 1236 1237 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 1238 Device, 1239 FX_TYPE_DEVICE, 1240 (PVOID*) &pDevice); 1241 1242 if (Stoppable) { 1243 // 1244 // Stoppable means that query stop / query remove can succeed. 1245 // This means m_DeviceStopCount == 0 (eventually if there are nested 1246 // calls to this function). 1247 // 1248 ASSERT(pDevice->m_PkgPnp->m_DeviceStopCount > 0); 1249 InterlockedDecrement((PLONG) &pDevice->m_PkgPnp->m_DeviceStopCount); 1250 } 1251 else { 1252 InterlockedIncrement((PLONG) &pDevice->m_PkgPnp->m_DeviceStopCount); 1253 } 1254 1255 return; 1256 } 1257 1258 __drv_maxIRQL(DISPATCH_LEVEL) 1259 VOID 1260 STDCALL 1261 WDFEXPORT(WdfDeviceSetFailed)( 1262 __in 1263 PWDF_DRIVER_GLOBALS DriverGlobals, 1264 __in 1265 WDFDEVICE Device, 1266 __in 1267 WDF_DEVICE_FAILED_ACTION FailedAction 1268 ) 1269 { 1270 DDI_ENTRY(); 1271 1272 PFX_DRIVER_GLOBALS pFxDriverGlobals; 1273 FxDevice *pDevice; 1274 1275 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 1276 Device, 1277 FX_TYPE_DEVICE, 1278 (PVOID *) &pDevice, 1279 &pFxDriverGlobals); 1280 1281 if (FailedAction < WdfDeviceFailedAttemptRestart || 1282 FailedAction > WdfDeviceFailedNoRestart) { 1283 DoTraceLevelMessage( 1284 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 1285 "Invalid FailedAction %d", FailedAction); 1286 FxVerifierDbgBreakPoint(pDevice->GetDriverGlobals()); 1287 return; 1288 } 1289 1290 DoTraceLevelMessage( 1291 pFxDriverGlobals, TRACE_LEVEL_INFORMATION, TRACINGDEVICE, 1292 "WDFDEVICE %p, !devobj %p SetFailed %!WDF_DEVICE_FAILED_ACTION!", 1293 Device, pDevice->GetDeviceObject(), FailedAction); 1294 1295 pDevice->m_PkgPnp->SetDeviceFailed(FailedAction); 1296 } 1297 1298 __inline 1299 NTSTATUS 1300 StopIdleWorker( 1301 __in 1302 PWDF_DRIVER_GLOBALS DriverGlobals, 1303 __in 1304 WDFDEVICE Device, 1305 __in 1306 BOOLEAN WaitForD0, 1307 __in 1308 PVOID Tag, 1309 __in 1310 LONG Line, 1311 __in 1312 PSTR File 1313 ) 1314 { 1315 PFX_DRIVER_GLOBALS pFxDriverGlobals; 1316 NTSTATUS status; 1317 FxDevice *pDevice; 1318 1319 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 1320 Device, 1321 FX_TYPE_DEVICE, 1322 (PVOID *) &pDevice, 1323 &pFxDriverGlobals); 1324 1325 if (WaitForD0) { 1326 status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, 1327 PASSIVE_LEVEL); 1328 if (!NT_SUCCESS(status)) { 1329 return status; 1330 } 1331 } 1332 1333 1334 if (pDevice->m_PkgPnp->IsPowerPolicyOwner() == FALSE) { 1335 status = STATUS_INVALID_DEVICE_STATE; 1336 DoTraceLevelMessage( 1337 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 1338 "WDFDEVICE %p WdfDeviceStopIdle does nothing if you are not the power " 1339 "policy owner for the stack, %!STATUS!", Device, status); 1340 return status; 1341 } 1342 1343 status = pDevice->m_PkgPnp->PowerReference(WaitForD0, Tag, Line, File); 1344 1345 DoTraceLevelMessage( 1346 pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGDEVICE, 1347 "WDFDEVICE %p WdfDeviceStopIdle, WaitForD0 %d %!STATUS!", 1348 Device, WaitForD0, status); 1349 1350 return status; 1351 } 1352 1353 __inline 1354 VOID 1355 ResumeIdleWorker( 1356 __in 1357 PWDF_DRIVER_GLOBALS DriverGlobals, 1358 __in 1359 WDFDEVICE Device, 1360 __in 1361 PVOID Tag, 1362 __in 1363 LONG Line, 1364 __in 1365 PSTR File 1366 ) 1367 { 1368 PFX_DRIVER_GLOBALS pFxDriverGlobals; 1369 FxDevice *pDevice; 1370 1371 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 1372 Device, 1373 FX_TYPE_DEVICE, 1374 (PVOID *) &pDevice, 1375 &pFxDriverGlobals); 1376 1377 if (pDevice->m_PkgPnp->IsPowerPolicyOwner() == FALSE) { 1378 DoTraceLevelMessage( 1379 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 1380 "WdfDeviceResumeIdle does nothing if you are not the power " 1381 "policy owner for the stack"); 1382 return; 1383 } 1384 1385 pDevice->m_PkgPnp->PowerDereference(Tag, Line, File); 1386 } 1387 1388 _Must_inspect_result_ 1389 __drv_when(WaitForD0 == 0, __drv_maxIRQL(DISPATCH_LEVEL)) 1390 __drv_when(WaitForD0 != 0, __drv_maxIRQL(PASSIVE_LEVEL)) 1391 NTSTATUS 1392 STDCALL 1393 WDFEXPORT(WdfDeviceStopIdleNoTrack)( 1394 __in 1395 PWDF_DRIVER_GLOBALS DriverGlobals, 1396 __in 1397 WDFDEVICE Device, 1398 __in 1399 BOOLEAN WaitForD0 1400 ) 1401 { 1402 DDI_ENTRY(); 1403 1404 NTSTATUS status; 1405 1406 status = StopIdleWorker(DriverGlobals, 1407 Device, 1408 WaitForD0, 1409 NULL, 1410 0, 1411 NULL); 1412 1413 return status; 1414 } 1415 1416 _Must_inspect_result_ 1417 __drv_when(WaitForD0 == 0, __drv_maxIRQL(DISPATCH_LEVEL)) 1418 __drv_when(WaitForD0 != 0, __drv_maxIRQL(PASSIVE_LEVEL)) 1419 NTSTATUS 1420 STDCALL 1421 WDFEXPORT(WdfDeviceStopIdleActual)( 1422 __in 1423 PWDF_DRIVER_GLOBALS DriverGlobals, 1424 __in 1425 WDFDEVICE Device, 1426 __in 1427 BOOLEAN WaitForD0, 1428 __in_opt 1429 PVOID Tag, 1430 __in 1431 LONG Line, 1432 __in 1433 PSTR File 1434 ) 1435 { 1436 DDI_ENTRY(); 1437 1438 NTSTATUS status; 1439 1440 status = StopIdleWorker(DriverGlobals, 1441 Device, 1442 WaitForD0, 1443 Tag, 1444 Line, 1445 File); 1446 1447 return status; 1448 } 1449 1450 __drv_maxIRQL(DISPATCH_LEVEL) 1451 VOID 1452 STDCALL 1453 WDFEXPORT(WdfDeviceResumeIdleNoTrack)( 1454 __in 1455 PWDF_DRIVER_GLOBALS DriverGlobals, 1456 __in 1457 WDFDEVICE Device 1458 ) 1459 { 1460 DDI_ENTRY(); 1461 1462 ResumeIdleWorker(DriverGlobals, 1463 Device, 1464 NULL, 1465 0, 1466 NULL); 1467 } 1468 1469 __drv_maxIRQL(DISPATCH_LEVEL) 1470 VOID 1471 STDCALL 1472 WDFEXPORT(WdfDeviceResumeIdleActual)( 1473 __in 1474 PWDF_DRIVER_GLOBALS DriverGlobals, 1475 __in 1476 WDFDEVICE Device, 1477 __in_opt 1478 PVOID Tag, 1479 __in 1480 LONG Line, 1481 __in 1482 PSTR File 1483 ) 1484 { 1485 DDI_ENTRY(); 1486 1487 ResumeIdleWorker(DriverGlobals, 1488 Device, 1489 Tag, 1490 Line, 1491 File); 1492 } 1493 1494 __drv_maxIRQL(DISPATCH_LEVEL) 1495 VOID 1496 STDCALL 1497 WDFEXPORT(WdfDeviceSetPnpCapabilities)( 1498 __in 1499 PWDF_DRIVER_GLOBALS DriverGlobals, 1500 __in 1501 WDFDEVICE Device, 1502 __in 1503 PWDF_DEVICE_PNP_CAPABILITIES PnpCapabilities 1504 ) 1505 /*++ 1506 1507 Routine Description: 1508 Sets the pnp capabilities of the device. This function is usually called 1509 during AddDevice or EvtDevicePrepareHardware since these values are queried 1510 by the stack and pnp during start device processing or immediately afterwards. 1511 1512 Arguments: 1513 Device - Device being set 1514 1515 PnpCapabilities - Caps being set 1516 1517 Return Value: 1518 None 1519 1520 --*/ 1521 { 1522 DDI_ENTRY(); 1523 1524 PFX_DRIVER_GLOBALS pFxDriverGlobals; 1525 FxDevice* pDevice; 1526 ULONG i; 1527 1528 const static FxOffsetAndName offsets[] = { 1529 OFFSET_AND_NAME(WDF_DEVICE_PNP_CAPABILITIES, LockSupported), 1530 OFFSET_AND_NAME(WDF_DEVICE_PNP_CAPABILITIES, EjectSupported), 1531 OFFSET_AND_NAME(WDF_DEVICE_PNP_CAPABILITIES, Removable), 1532 OFFSET_AND_NAME(WDF_DEVICE_PNP_CAPABILITIES, DockDevice), 1533 OFFSET_AND_NAME(WDF_DEVICE_PNP_CAPABILITIES, UniqueID), 1534 OFFSET_AND_NAME(WDF_DEVICE_PNP_CAPABILITIES, SilentInstall), 1535 OFFSET_AND_NAME(WDF_DEVICE_PNP_CAPABILITIES, SurpriseRemovalOK), 1536 OFFSET_AND_NAME(WDF_DEVICE_PNP_CAPABILITIES, HardwareDisabled), 1537 OFFSET_AND_NAME(WDF_DEVICE_PNP_CAPABILITIES, NoDisplayInUI), 1538 }; 1539 1540 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 1541 Device, 1542 FX_TYPE_DEVICE, 1543 (PVOID *) &pDevice, 1544 &pFxDriverGlobals); 1545 1546 FxPointerNotNull(pFxDriverGlobals, PnpCapabilities); 1547 1548 if (PnpCapabilities->Size != sizeof(WDF_DEVICE_PNP_CAPABILITIES)) { 1549 DoTraceLevelMessage( 1550 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 1551 "WDFDEVICE 0x%p PnpCapabilities Size %d, expected %d", 1552 Device, PnpCapabilities->Size, sizeof(WDF_DEVICE_PNP_CAPABILITIES)); 1553 FxVerifierDbgBreakPoint(pFxDriverGlobals); 1554 1555 return; // STATUS_INFO_LENGTH_MISMATCH; 1556 } 1557 else { 1558 for (i = 0; i < ARRAY_SIZE(offsets); i++) { 1559 WDF_TRI_STATE value; 1560 1561 // 1562 // This check makes prefast happy 1563 // 1564 if (offsets[i].Offset + sizeof(WDF_TRI_STATE) > 1565 sizeof(*PnpCapabilities)) { 1566 return; 1567 } 1568 1569 value = *(WDF_TRI_STATE*) WDF_PTR_ADD_OFFSET(PnpCapabilities, 1570 offsets[i].Offset); 1571 switch (value) { 1572 case WdfFalse: 1573 case WdfTrue: 1574 case WdfUseDefault: 1575 break; 1576 1577 default: 1578 DoTraceLevelMessage( 1579 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 1580 "WDFDEVICE 0x%p PnpCapabilities WDF_TRI_STATE %s value out " 1581 "of range, value is %d", Device, offsets[i].Name, value); 1582 FxVerifierDbgBreakPoint(pFxDriverGlobals); 1583 1584 return; // STATUS_INVALID_PARAMETER 1585 } 1586 } 1587 } 1588 1589 pDevice->m_PkgPnp->SetPnpCaps(PnpCapabilities); 1590 } 1591 1592 __drv_maxIRQL(DISPATCH_LEVEL) 1593 VOID 1594 STDCALL 1595 WDFEXPORT(WdfDeviceSetPowerCapabilities)( 1596 __in 1597 PWDF_DRIVER_GLOBALS DriverGlobals, 1598 __in 1599 WDFDEVICE Device, 1600 __in 1601 PWDF_DEVICE_POWER_CAPABILITIES PowerCapabilities 1602 ) 1603 /*++ 1604 1605 Routine Description: 1606 Sets the power capabilities of the device. This function is usually called 1607 during AddDevice or EvtDevicePrepareHardware since these values are queried 1608 by the stack and power during start device processing or immediately afterwards. 1609 1610 Arguments: 1611 Device - Device being set 1612 1613 PowerCapabilities - Caps being set 1614 1615 Return Value: 1616 None 1617 1618 --*/ 1619 { 1620 DDI_ENTRY(); 1621 1622 FxDevice* pDevice; 1623 ULONG i; 1624 PFX_DRIVER_GLOBALS pFxDriverGlobals; 1625 1626 const static FxOffsetAndName offsets[] = { 1627 OFFSET_AND_NAME(WDF_DEVICE_POWER_CAPABILITIES, DeviceD1), 1628 OFFSET_AND_NAME(WDF_DEVICE_POWER_CAPABILITIES, DeviceD2), 1629 OFFSET_AND_NAME(WDF_DEVICE_POWER_CAPABILITIES, WakeFromD0), 1630 OFFSET_AND_NAME(WDF_DEVICE_POWER_CAPABILITIES, WakeFromD1), 1631 OFFSET_AND_NAME(WDF_DEVICE_POWER_CAPABILITIES, WakeFromD2), 1632 OFFSET_AND_NAME(WDF_DEVICE_POWER_CAPABILITIES, WakeFromD3), 1633 }; 1634 1635 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 1636 Device, 1637 FX_TYPE_DEVICE, 1638 (PVOID *) &pDevice, 1639 &pFxDriverGlobals); 1640 1641 FxPointerNotNull(pFxDriverGlobals, PowerCapabilities); 1642 1643 if (PowerCapabilities->Size != sizeof(WDF_DEVICE_POWER_CAPABILITIES)) { 1644 1645 DoTraceLevelMessage( 1646 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 1647 "WDFDEVICE 0x%p PowerCapabilities Size %d, expected %d", 1648 Device, PowerCapabilities->Size, 1649 sizeof(WDF_DEVICE_POWER_CAPABILITIES)); 1650 1651 FxVerifierDbgBreakPoint(pFxDriverGlobals); 1652 1653 return; // STATUS_INFO_LENGTH_MISMATCH; 1654 } 1655 else { 1656 for (i = 0; i < ARRAY_SIZE(offsets); i++) { 1657 WDF_TRI_STATE value; 1658 1659 // 1660 // This check makes prefast happy 1661 // 1662 if (offsets[i].Offset + sizeof(WDF_TRI_STATE) > 1663 sizeof(*PowerCapabilities)) { 1664 return; 1665 } 1666 1667 value = *(WDF_TRI_STATE*) WDF_PTR_ADD_OFFSET(PowerCapabilities, 1668 offsets[i].Offset); 1669 switch (value) { 1670 case WdfFalse: 1671 case WdfTrue: 1672 case WdfUseDefault: 1673 break; 1674 1675 default: 1676 DoTraceLevelMessage( 1677 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 1678 "WDFDEVICE 0x%p PowerCapabilities WDF_TRI_STATE %s value out " 1679 "of range, value is %d", 1680 Device, offsets[i].Name, value); 1681 FxVerifierDbgBreakPoint(pFxDriverGlobals); 1682 1683 return; // STATUS_INVALID_PARAMETER 1684 } 1685 } 1686 1687 for (i = 0; i < ARRAY_SIZE(PowerCapabilities->DeviceState); i++) { 1688 if (PowerCapabilities->DeviceState[i] < PowerDeviceUnspecified || 1689 PowerCapabilities->DeviceState[i] > PowerDeviceMaximum) { 1690 1691 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 1692 "WDFDEVICE 0x%p PowerCapabilities DeviceState is invalid", 1693 Device); 1694 1695 FxVerifierDbgBreakPoint(pFxDriverGlobals); 1696 1697 return; // STATUS_INVALID_PARAMETER; 1698 } 1699 } 1700 1701 if (PowerCapabilities->DeviceWake < PowerDeviceUnspecified || 1702 PowerCapabilities->DeviceWake > PowerDeviceMaximum) { 1703 1704 DoTraceLevelMessage( 1705 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 1706 "WDFDEVICE 0x%p PowerCapabilities DeviceWake %d is out of range", 1707 Device, PowerCapabilities->DeviceWake); 1708 1709 FxVerifierDbgBreakPoint(pFxDriverGlobals); 1710 1711 return; // STATUS_INVALID_PARAMETER; 1712 } 1713 1714 if (PowerCapabilities->SystemWake < PowerSystemUnspecified || 1715 PowerCapabilities->SystemWake > PowerSystemMaximum) { 1716 1717 DoTraceLevelMessage( 1718 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 1719 "WDFDEVICE 0x%p PowerCapabilities SystemWake %d is out of range", 1720 Device, PowerCapabilities->SystemWake); 1721 1722 FxVerifierDbgBreakPoint(pFxDriverGlobals); 1723 1724 return; // STATUS_INVALID_PARAMETER; 1725 } 1726 1727 if (pDevice->m_PkgPnp->IsPowerPolicyOwner() == FALSE && 1728 PowerCapabilities->IdealDxStateForSx != PowerDeviceMaximum) { 1729 DoTraceLevelMessage( 1730 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 1731 "WDFDEVICE 0x%p PowerCapabilities IdealDxStateForSx %d can only" 1732 " be set by the power policy owner", 1733 Device, PowerCapabilities->IdealDxStateForSx); 1734 1735 FxVerifierDbgBreakPoint(pFxDriverGlobals); 1736 1737 return; // STATUS_INVALID_PARAMETER; 1738 } 1739 1740 // 1741 // D0 is not allowed as an ideal Dx state 1742 // 1743 if (PowerCapabilities->IdealDxStateForSx < PowerDeviceD1 || 1744 PowerCapabilities->IdealDxStateForSx > PowerDeviceMaximum) { 1745 1746 DoTraceLevelMessage( 1747 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 1748 "WDFDEVICE 0x%p PowerCapabilities IdealDxStateForSx %d is out " 1749 "of range", Device, PowerCapabilities->IdealDxStateForSx); 1750 1751 FxVerifierDbgBreakPoint(pFxDriverGlobals); 1752 1753 return; // STATUS_INVALID_PARAMETER; 1754 } 1755 } 1756 1757 1758 pDevice->m_PkgPnp->SetPowerCaps(PowerCapabilities); 1759 } 1760 1761 _Must_inspect_result_ 1762 __drv_maxIRQL(DISPATCH_LEVEL) 1763 NTSTATUS 1764 STDCALL 1765 WDFEXPORT(WdfDeviceConfigureRequestDispatching)( 1766 __in 1767 PWDF_DRIVER_GLOBALS DriverGlobals, 1768 __in 1769 WDFDEVICE Device, 1770 __in 1771 WDFQUEUE Queue, 1772 __in 1773 __drv_strictTypeMatch(__drv_typeCond) 1774 WDF_REQUEST_TYPE RequestType 1775 ) 1776 1777 /*++ 1778 1779 Routine Description: 1780 1781 Configure which IRP_MJ_* requests are automatically 1782 forwarded by the I/O package to the specified Queue. 1783 1784 By default the I/O package sends all requests to the 1785 devices default queue. This API allows certain requests 1786 to be specified to their own queues under driver control. 1787 1788 Arguments: 1789 1790 Device - The device which is handling the IO. 1791 1792 Queue - I/O Queue object to forward specified request to. 1793 1794 RequestType - WDF Request type to be forwarded to the queue 1795 1796 Returns: 1797 1798 NTSTATUS 1799 1800 --*/ 1801 1802 { 1803 DDI_ENTRY(); 1804 1805 PFX_DRIVER_GLOBALS pFxDriverGlobals; 1806 NTSTATUS status; 1807 FxDevice* pDevice; 1808 FxIoQueue* pFxIoQueue; 1809 1810 pDevice = NULL; 1811 pFxIoQueue = NULL; 1812 1813 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 1814 Device, 1815 FX_TYPE_DEVICE, 1816 (PVOID *) &pDevice, 1817 &pFxDriverGlobals); 1818 1819 if (RequestType != WdfRequestTypeCreate && 1820 RequestType != WdfRequestTypeRead && 1821 RequestType != WdfRequestTypeWrite && 1822 RequestType != WdfRequestTypeDeviceControl && 1823 RequestType != WdfRequestTypeDeviceControlInternal) { 1824 status = STATUS_INVALID_PARAMETER; 1825 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIO, 1826 "Invalid RequestType %!WDF_REQUEST_TYPE!, %!STATUS!", 1827 RequestType, status); 1828 return status; 1829 } 1830 1831 // 1832 // Validate the Queue handle 1833 // 1834 FxObjectHandleGetPtr(pFxDriverGlobals, 1835 Queue, 1836 FX_TYPE_QUEUE, 1837 (PVOID*)&pFxIoQueue); 1838 1839 if (pDevice != pFxIoQueue->GetDevice()) { 1840 status = STATUS_INVALID_DEVICE_REQUEST; 1841 1842 DoTraceLevelMessage( 1843 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIO, 1844 "Input WDFQUEUE 0x%p doesn't belong to the WDFDEVICE 0x%p, %!STATUS!", 1845 Queue, Device, status); 1846 1847 return status; 1848 } 1849 1850 if (pDevice->IsLegacy()) { 1851 // 1852 // This is a controldevice. Make sure the create is called after the device 1853 // is initialized and ready to accept I/O. 1854 // 1855 MxDeviceObject deviceObject(pDevice->GetDeviceObject()); 1856 if ((deviceObject.GetFlags() & DO_DEVICE_INITIALIZING) == 0x0) { 1857 1858 status = STATUS_INVALID_DEVICE_STATE; 1859 DoTraceLevelMessage( 1860 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP, 1861 "Queue cannot be configured for automatic dispatching" 1862 " after WdfControlDeviceFinishInitializing" 1863 "is called on the WDFDEVICE %p is called %!STATUS!", 1864 Device, 1865 status); 1866 return status; 1867 } 1868 } 1869 else { 1870 // 1871 // This is either FDO or PDO. Make sure it's not started yet. 1872 // 1873 if (pDevice->GetDevicePnpState() != WdfDevStatePnpInit) { 1874 status = STATUS_INVALID_DEVICE_STATE; 1875 DoTraceLevelMessage( 1876 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP, 1877 "Queue cannot be configured for automatic dispatching" 1878 "after the WDFDEVICE %p is started, %!STATUS!", 1879 Device, status); 1880 return status; 1881 } 1882 } 1883 1884 if (RequestType == WdfRequestTypeCreate) { 1885 status = pDevice->m_PkgGeneral->ConfigureForwarding(pFxIoQueue); 1886 } 1887 else { 1888 status = pDevice->m_PkgIo->ConfigureForwarding(pFxIoQueue, RequestType); 1889 } 1890 1891 return status; 1892 } 1893 1894 __drv_maxIRQL(DISPATCH_LEVEL) 1895 WDFQUEUE 1896 STDCALL 1897 WDFEXPORT(WdfDeviceGetDefaultQueue)( 1898 __in 1899 PWDF_DRIVER_GLOBALS DriverGlobals, 1900 __in 1901 WDFDEVICE Device 1902 ) 1903 1904 /*++ 1905 1906 Routine Description: 1907 1908 Return the handle to the default queue for the device. 1909 1910 Arguments: 1911 1912 Device - Handle to the Device Object 1913 1914 Returns: 1915 1916 WDFQUEUE 1917 1918 --*/ 1919 1920 { 1921 DDI_ENTRY(); 1922 1923 FxPkgIo* pPkgIo;; 1924 FxIoQueue* pFxIoQueue;; 1925 FxDevice * pFxDevice; 1926 PFX_DRIVER_GLOBALS pFxDriverGlobals; 1927 1928 pPkgIo = NULL; 1929 pFxIoQueue = NULL; 1930 1931 // 1932 // Validate the I/O Package handle, and get the FxPkgIo* 1933 // 1934 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 1935 Device, 1936 FX_TYPE_DEVICE, 1937 (PVOID *) &pFxDevice, 1938 &pFxDriverGlobals); 1939 1940 pPkgIo = (FxPkgIo *) pFxDevice->m_PkgIo; 1941 pFxIoQueue = pPkgIo->GetDefaultQueue(); 1942 1943 // 1944 // A default queue is optional 1945 // 1946 if (pFxIoQueue == NULL) { 1947 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_WARNING, TRACINGIO, 1948 "No default Queue configured " 1949 "for Device 0x%p", Device); 1950 return NULL; 1951 } 1952 1953 return (WDFQUEUE)pFxIoQueue->GetObjectHandle();; 1954 } 1955 1956 _Must_inspect_result_ 1957 __drv_maxIRQL(DISPATCH_LEVEL) 1958 NTSTATUS 1959 STDCALL 1960 WDFEXPORT(WdfDeviceEnqueueRequest)( 1961 __in 1962 PWDF_DRIVER_GLOBALS DriverGlobals, 1963 __in 1964 WDFDEVICE Device, 1965 __in 1966 WDFREQUEST Request 1967 ) 1968 1969 /*++ 1970 1971 Routine Description: 1972 1973 Inserts a request into the I/O Package processing pipeline. 1974 1975 The given request is processed by the I/O package, forwarding 1976 it to its configured destination or the default queue. 1977 1978 If an EvtIoInCallerContext is callback is registered, it is not called. 1979 1980 Arguments: 1981 1982 Device - Handle to the Device Object 1983 1984 Request - Request to insert in the processing pipeline 1985 1986 Return Value: 1987 1988 STATUS_SUCCESS - Request has been inserted into the I/O processing pipeline 1989 1990 !NT_SUCCESS(status) 1991 STATUS_WDF_BUSY - Device is not accepting requests, the driver still owns the 1992 the request and must complete it, or correct the conditions. 1993 1994 --*/ 1995 1996 { 1997 DDI_ENTRY(); 1998 1999 PFX_DRIVER_GLOBALS pFxDriverGlobals; 2000 FxDevice *pDevice; 2001 FxRequest* pRequest; 2002 2003 // 2004 // Validate the device object handle 2005 // 2006 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 2007 Device, 2008 FX_TYPE_DEVICE, 2009 (PVOID *) &pDevice, 2010 &pFxDriverGlobals); 2011 // 2012 // Validate Device object handle 2013 // 2014 FxObjectHandleGetPtr(pFxDriverGlobals, 2015 Device, 2016 FX_TYPE_DEVICE, 2017 (PVOID *) &pDevice); 2018 2019 // 2020 // Validate the request object handle 2021 // 2022 FxObjectHandleGetPtr(pFxDriverGlobals, 2023 Request, 2024 FX_TYPE_REQUEST, 2025 (PVOID *) &pRequest); 2026 2027 // 2028 // Dispatch it to the Io Package object 2029 // 2030 return pDevice->m_PkgIo->EnqueueRequest(pDevice, pRequest); 2031 } 2032 2033 __drv_maxIRQL(DISPATCH_LEVEL) 2034 POWER_ACTION 2035 STDCALL 2036 WDFEXPORT(WdfDeviceGetSystemPowerAction)( 2037 __in 2038 PWDF_DRIVER_GLOBALS DriverGlobals, 2039 __in 2040 WDFDEVICE Device 2041 ) 2042 2043 /*++ 2044 2045 Routine Description: 2046 2047 This DDI returns the System power action. 2048 2049 If the DDI is called in the power down path of a device, it will return the 2050 current system power transition type because of which the device is powering 2051 down. If the DDI is called in the power up path of a device, it will return 2052 the system power transition type which initially put the device into a lower 2053 power state. If the DDI is called during the normal functioning of a device 2054 that is not undergoing a power state transition, or if the device is powering 2055 up as part of the system start up, the DDI will return the PowerActionNone 2056 value. 2057 2058 Arguments: 2059 2060 Device - Handle to the Device Object 2061 2062 Return Value: 2063 2064 Returns a POWER_ACTION enum value that represents the current system power 2065 action with regards to any system power transition underway. 2066 2067 --*/ 2068 2069 { 2070 DDI_ENTRY(); 2071 2072 FxDevice *pDevice; 2073 2074 // 2075 // Validate Device object handle 2076 // 2077 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 2078 Device, 2079 FX_TYPE_DEVICE, 2080 (PVOID*) &pDevice); 2081 2082 return pDevice->m_PkgPnp->GetSystemPowerAction(); 2083 } 2084 2085 _Must_inspect_result_ 2086 _IRQL_requires_max_(APC_LEVEL) 2087 WDFAPI 2088 NTSTATUS 2089 STDCALL 2090 WDFEXPORT(WdfDeviceQueryPropertyEx)( 2091 _In_ 2092 PWDF_DRIVER_GLOBALS DriverGlobals, 2093 _In_ 2094 WDFDEVICE Device, 2095 _In_ 2096 PWDF_DEVICE_PROPERTY_DATA DeviceProperty, 2097 _In_ 2098 ULONG BufferLength, 2099 _Out_ 2100 PVOID PropertyBuffer, 2101 _Out_ 2102 PULONG RequiredSize, 2103 _Out_ 2104 PDEVPROPTYPE Type 2105 ) 2106 /*++ 2107 2108 Routine Description: 2109 2110 This routine queries interface property. 2111 2112 Arguments: 2113 2114 DriverGlobals - DriverGlobals pointer 2115 2116 Device - WDF Device handle. 2117 2118 DeviceProperty - A pointer to WDF_DEVICE_PROPERTY_ DATA structure. 2119 2120 BufferLength - The size, in bytes, of the buffer that is pointed to by 2121 PropertyBuffer. 2122 2123 PropertyBuffer - A caller-supplied pointer to a caller-allocated buffer that 2124 receives the requested information. The pointer can be NULL 2125 if the BufferLength parameter is zero. 2126 2127 ResultLength - A caller-supplied location that, on return, contains the 2128 size, in bytes, of the information that the method stored in 2129 PropertyBuffer. If the function's return value is 2130 STATUS_BUFFER_TOO_SMALL, this location receives the required 2131 buffer size. 2132 2133 Type - A pointer to a DEVPROPTYPE variable. If method successfully retrieves 2134 the property data, the routine writes the property type value 2135 to this variable. This value indicates the type of property 2136 data that is in the Data buffer. 2137 2138 Return Value: 2139 2140 Method returns an NTSTATUS value. This routine might return one of the 2141 following values. 2142 2143 STATUS_BUFFER_TOO_SMALL - The supplied buffer is too small to receive the 2144 information. The ResultLength member receives the 2145 size of buffer required. 2146 STATUS_SUCCESS - The operation succeeded. 2147 STATUS_INVALID_PARAMETER - One of the parameters is incorrect. 2148 2149 The method might return other NTSTATUS values. 2150 2151 --*/ 2152 2153 { 2154 DDI_ENTRY(); 2155 2156 PFX_DRIVER_GLOBALS pFxDriverGlobals; 2157 FxDevice* pDevice; 2158 NTSTATUS status; 2159 2160 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 2161 Device, 2162 FX_TYPE_DEVICE, 2163 (PVOID *) &pDevice, 2164 &pFxDriverGlobals); 2165 2166 FxPointerNotNull(pFxDriverGlobals, DeviceProperty); 2167 2168 // 2169 // Validate PropertyData 2170 // 2171 if (DeviceProperty->Size != sizeof(WDF_DEVICE_PROPERTY_DATA)) { 2172 status = STATUS_INFO_LENGTH_MISMATCH; 2173 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP, 2174 "PropertyData size (%d) incorrect, expected %d, %!STATUS!", 2175 DeviceProperty->Size, 2176 sizeof(WDF_DEVICE_PROPERTY_DATA), status); 2177 return status; 2178 } 2179 2180 status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, APC_LEVEL); 2181 if (!NT_SUCCESS(status)) { 2182 FxVerifierDbgBreakPoint(pFxDriverGlobals); 2183 return status; 2184 } 2185 2186 FxPointerNotNull(pFxDriverGlobals, RequiredSize); 2187 FxPointerNotNull(pFxDriverGlobals, Type); 2188 2189 if (BufferLength != 0 && PropertyBuffer == NULL) { 2190 status = STATUS_INVALID_PARAMETER; 2191 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 2192 "Property buffer size is non-zero, while the buffer is NULL" 2193 ", %!STATUS!", status); 2194 return status; 2195 } 2196 2197 if (BufferLength == 0 && PropertyBuffer != NULL) { 2198 status = STATUS_INVALID_PARAMETER; 2199 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 2200 "Property buffer size is zero, while the buffer is non-NULL" 2201 ", %!STATUS!", status); 2202 return status; 2203 } 2204 2205 status = FxDevice::_QueryPropertyEx(pFxDriverGlobals, 2206 NULL, 2207 pDevice, 2208 DeviceProperty, 2209 FxDeviceProperty, 2210 BufferLength, 2211 PropertyBuffer, 2212 RequiredSize, 2213 Type); 2214 return status; 2215 } 2216 2217 _Must_inspect_result_ 2218 _IRQL_requires_max_(APC_LEVEL) 2219 WDFAPI 2220 NTSTATUS 2221 STDCALL 2222 WDFEXPORT(WdfDeviceAllocAndQueryPropertyEx)( 2223 _In_ 2224 PWDF_DRIVER_GLOBALS DriverGlobals, 2225 _In_ 2226 WDFDEVICE Device, 2227 _In_ 2228 PWDF_DEVICE_PROPERTY_DATA DeviceProperty, 2229 _In_ 2230 _Strict_type_match_ 2231 POOL_TYPE PoolType, 2232 _In_opt_ 2233 PWDF_OBJECT_ATTRIBUTES PropertyMemoryAttributes, 2234 _Out_ 2235 WDFMEMORY* PropertyMemory, 2236 _Out_ 2237 PDEVPROPTYPE Type 2238 ) 2239 /*++ 2240 2241 Routine Description: 2242 2243 This routine queries device property. 2244 2245 Arguments: 2246 2247 DriverGlobals - DriverGlobals pointer 2248 2249 Device - WDF Device handle. 2250 2251 PropertyData - A pointer to WDF_DEVICE_PROPERTY_ DATA structure. 2252 2253 PoolType - A POOL_TYPE-typed enumerator that specifies the type of memory 2254 to be allocated. 2255 2256 PropertyMemoryAttributes - optional, A pointer to a caller-allocated 2257 WDF_OBJECT_ATTRIBUTES structure that describes object attributes 2258 for the memory object that the function will allocate. This 2259 parameter is optional and can be WDF_NO_OBJECT_ATTRIBUTES. 2260 2261 PropertyMemory - A pointer to a WDFMEMORY-typed location that receives a 2262 handle to a framework memory object. 2263 2264 Type - A pointer to a DEVPROPTYPE variable. If method successfully retrieves 2265 the property data, the routine writes the property type value to 2266 this variable. This value indicates the type of property data 2267 that is in the Data buffer. 2268 2269 Return Value: 2270 2271 Method returns an NTSTATUS value. This routine might return one of the 2272 following values. It might return other NTSTATUS-codes as well. 2273 2274 STATUS_SUCCESS The operation succeeded. 2275 STATUS_INVALID_PARAMETER One of the parameters is incorrect. 2276 2277 --*/ 2278 { 2279 DDI_ENTRY(); 2280 2281 PFX_DRIVER_GLOBALS pFxDriverGlobals; 2282 FxDevice* pDevice; 2283 NTSTATUS status; 2284 2285 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 2286 Device, 2287 FX_TYPE_DEVICE, 2288 (PVOID *) &pDevice, 2289 &pFxDriverGlobals); 2290 2291 FxPointerNotNull(pFxDriverGlobals, DeviceProperty); 2292 2293 // 2294 // Validate PropertyData 2295 // 2296 if (DeviceProperty->Size != sizeof(WDF_DEVICE_PROPERTY_DATA)) { 2297 status = STATUS_INFO_LENGTH_MISMATCH; 2298 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP, 2299 "PropertyData size (%d) incorrect, expected %d, %!STATUS!", 2300 DeviceProperty->Size, 2301 sizeof(WDF_DEVICE_PROPERTY_DATA), status); 2302 return status; 2303 } 2304 2305 status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, APC_LEVEL); 2306 if (!NT_SUCCESS(status)) { 2307 FxVerifierDbgBreakPoint(pFxDriverGlobals); 2308 return status; 2309 } 2310 2311 FxVerifierCheckNxPoolType(pFxDriverGlobals, PoolType, pFxDriverGlobals->Tag); 2312 2313 FxPointerNotNull(pFxDriverGlobals, PropertyMemory); 2314 FxPointerNotNull(pFxDriverGlobals, Type); 2315 2316 *PropertyMemory = NULL; 2317 2318 status = FxValidateObjectAttributes(pFxDriverGlobals, PropertyMemoryAttributes); 2319 if (!NT_SUCCESS(status)) { 2320 return status; 2321 } 2322 2323 status = FxDevice::_AllocAndQueryPropertyEx(pFxDriverGlobals, 2324 NULL, 2325 pDevice, 2326 DeviceProperty, 2327 FxDeviceProperty, 2328 PoolType, 2329 PropertyMemoryAttributes, 2330 PropertyMemory, 2331 Type); 2332 return status; 2333 } 2334 2335 _Must_inspect_result_ 2336 _IRQL_requires_max_(APC_LEVEL) 2337 WDFAPI 2338 NTSTATUS 2339 STDCALL 2340 WDFEXPORT(WdfDeviceAssignProperty)( 2341 _In_ 2342 PWDF_DRIVER_GLOBALS DriverGlobals, 2343 _In_ 2344 WDFDEVICE Device, 2345 _In_ 2346 PWDF_DEVICE_PROPERTY_DATA DeviceProperty, 2347 _In_ 2348 DEVPROPTYPE Type, 2349 _In_ 2350 ULONG BufferLength, 2351 _In_opt_ 2352 PVOID PropertyBuffer 2353 ) 2354 /*++ 2355 2356 Routine Description: 2357 2358 This routine assigns interface property. 2359 2360 Arguments: 2361 2362 DriverGlobals - DriverGlobals pointer 2363 2364 Device - WDF Device handle. 2365 2366 PropertyData - A pointer to WDF_DEVICE_PROPERTY_ DATA structure. 2367 2368 Type - Set this parameter to the DEVPROPTYPE value that specifies the type 2369 of the data that is supplied in the Data buffer. 2370 2371 BufferLength - Specifies the length, in bytes, of the buffer that 2372 PropertyBuffer points to. 2373 2374 PropertyBuffer - optional, A pointer to the device interface property data. 2375 Set this parameter to NULL to delete the specified property. 2376 2377 Return Value: 2378 2379 Mthod returns an NTSTATUS value. This routine might return one of the 2380 following values. It might return other NTSTATUS-codes as well. 2381 2382 STATUS_SUCCESS - The operation succeeded. 2383 STATUS_INVALID_PARAMETER - One of the parameters is incorrect. 2384 2385 --*/ 2386 2387 { 2388 DDI_ENTRY(); 2389 2390 PFX_DRIVER_GLOBALS pFxDriverGlobals; 2391 FxDevice *pDevice; 2392 NTSTATUS status; 2393 2394 // 2395 // Validate the Device object handle and get its FxDevice. Also get the 2396 // driver globals pointer. 2397 // 2398 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 2399 Device, 2400 FX_TYPE_DEVICE, 2401 (PVOID *) &pDevice, 2402 &pFxDriverGlobals); 2403 2404 FxPointerNotNull(pFxDriverGlobals, DeviceProperty); 2405 2406 // 2407 // Validate PropertyData 2408 // 2409 if (DeviceProperty->Size != sizeof(WDF_DEVICE_PROPERTY_DATA)) { 2410 status = STATUS_INFO_LENGTH_MISMATCH; 2411 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP, 2412 "PropertyData size (%d) incorrect, expected %d, %!STATUS!", 2413 DeviceProperty->Size, 2414 sizeof(WDF_DEVICE_PROPERTY_DATA), status); 2415 return status; 2416 } 2417 2418 status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, APC_LEVEL); 2419 if (!NT_SUCCESS(status)) { 2420 FxVerifierDbgBreakPoint(pFxDriverGlobals); 2421 return status; 2422 } 2423 2424 if (BufferLength == 0 && PropertyBuffer != NULL) { 2425 status = STATUS_INVALID_PARAMETER; 2426 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 2427 "Property buffer size is zero, while the buffer is non-NULL" 2428 ", %!STATUS!", status); 2429 return status; 2430 } 2431 2432 status = pDevice->AssignProperty(DeviceProperty, 2433 FxDeviceProperty, 2434 Type, 2435 BufferLength, 2436 PropertyBuffer 2437 ); 2438 return status; 2439 } 2440 2441 _Must_inspect_result_ 2442 __drv_maxIRQL(DISPATCH_LEVEL) 2443 WDFAPI 2444 NTSTATUS 2445 STDCALL 2446 WDFEXPORT(WdfDeviceConfigureWdmIrpDispatchCallback)( 2447 _In_ 2448 PWDF_DRIVER_GLOBALS DriverGlobals, 2449 _In_ 2450 WDFDEVICE Device, 2451 _In_opt_ 2452 WDFDRIVER Driver, 2453 _In_ 2454 UCHAR MajorFunction, 2455 _In_ 2456 PFN_WDFDEVICE_WDM_IRP_DISPATCH EvtDeviceWdmIrpDispatch, 2457 _In_opt_ 2458 WDFCONTEXT DriverContext 2459 ) 2460 2461 /*++ 2462 2463 Routine Description: 2464 2465 Configure callbacks for IRP_MJ_READ, IRP_MJ_WRITE, IRP_MJ_DEVICE_CONTROL, and 2466 IRP_MJ_INTERNAL_DEVICE_CONTROL (KMDF only). By default the I/O package sends all requests to 2467 a device's default queue, or to the queues configured with 2468 WdfDeviceConfigureRequestDisaptching. This DDI allows a driver specified 2469 callback to select a different queue dynamically during runtime. 2470 2471 Arguments: 2472 2473 Device - The device which is handling the I/O. 2474 2475 Driver - An optional driver handle. Used to associate the 2476 callback with a specific class extension. 2477 2478 MajorFunction - IRP major function type to be forwarded to the callback 2479 2480 EvtDeviceWdmIrpDispatch - Callback invoked when encountering the given major function. 2481 2482 DriverContext - An optional untyped driver specified context. 2483 2484 Returns: 2485 2486 STATUS_SUCCESS on success 2487 STATUS_INVALID_PARAMETER if an incorrect MajorFunction was provided 2488 STATUS_INSUFFICIENT_RESOURCES if insufficient memory was available 2489 STATUS_INVALID_DEVICE_STATE if this DDI was called at an improper time 2490 2491 --*/ 2492 { 2493 PFX_DRIVER_GLOBALS pFxDriverGlobals; 2494 NTSTATUS status; 2495 FxDevice* pDevice; 2496 FxCxDeviceInfo* pCxDeviceInfo; 2497 ULONG deviceFlags; 2498 2499 pDevice = NULL; 2500 pCxDeviceInfo = NULL; 2501 2502 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 2503 Device, 2504 FX_TYPE_DEVICE, 2505 (PVOID *) &pDevice, 2506 &pFxDriverGlobals); 2507 2508 // 2509 // Validate the MajorFunction provided. Note that 2510 // IRP_MJ_INTERNAL_DEVICE_CONTROL is KMDF only. 2511 // 2512 switch (MajorFunction) { 2513 case IRP_MJ_WRITE: 2514 case IRP_MJ_READ: 2515 case IRP_MJ_DEVICE_CONTROL: 2516 #if (FX_CORE_MODE == FX_CORE_KERNEL_MODE) 2517 case IRP_MJ_INTERNAL_DEVICE_CONTROL: 2518 #endif 2519 break; 2520 default: 2521 status = STATUS_INVALID_PARAMETER; 2522 DoTraceLevelMessage( 2523 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP, 2524 "Invalid MajorFunction provided %!IRPMJ!, %!STATUS!", 2525 MajorFunction, status); 2526 goto exit; 2527 } 2528 2529 // 2530 // Validate the driver handle and get (if present) the associated cx info. 2531 // 2532 if (Driver != NULL) { 2533 FxDriver* pDriver; 2534 2535 FxObjectHandleGetPtr(pFxDriverGlobals, 2536 Driver, 2537 FX_TYPE_DRIVER, 2538 (PVOID*)&pDriver); 2539 2540 // 2541 // Find the driver's cx info if it's not the main driver for this device. 2542 // cx struct info can be NULL if cx acts as client driver. 2543 // 2544 pCxDeviceInfo = pDevice->GetCxDeviceInfo(pDriver); 2545 } 2546 2547 // 2548 // Make sure callback is not null. 2549 // 2550 FxPointerNotNull(pFxDriverGlobals, EvtDeviceWdmIrpDispatch); 2551 2552 // 2553 // This callback can only be called during initialization. 2554 // 2555 if (pDevice->IsLegacy()) { 2556 2557 // 2558 // Extract the device flags from the device object 2559 // 2560 #if (FX_CORE_MODE == FX_CORE_KERNEL_MODE) 2561 deviceFlags = pDevice->GetDeviceObject()->Flags; 2562 #else 2563 deviceFlags = pDevice->GetDeviceObject()->GetDeviceObjectWdmFlags(); 2564 #endif 2565 2566 // 2567 // This is a controldevice. Make sure the create is called after the device 2568 // is initialized and ready to accept I/O. 2569 // 2570 if ((deviceFlags & DO_DEVICE_INITIALIZING) == 0x0) { 2571 status = STATUS_INVALID_DEVICE_STATE; 2572 DoTraceLevelMessage( 2573 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP, 2574 "Driver cannot set IRP dispatch callback " 2575 "after WdfControlDeviceFinishInitializing " 2576 "is called on the WDFDEVICE %p, %!STATUS!", 2577 pDevice, status); 2578 goto exit; 2579 } 2580 } else { 2581 // 2582 // This is either FDO or PDO. Make sure it's not started yet. 2583 // 2584 if (pDevice->GetDevicePnpState() != WdfDevStatePnpInit) { 2585 status = STATUS_INVALID_DEVICE_STATE; 2586 DoTraceLevelMessage( 2587 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP, 2588 "Driver cannot set IRP dispatch callback " 2589 "after the WDFDEVICE %p is started, %!STATUS!", 2590 pDevice, status); 2591 goto exit; 2592 } 2593 } 2594 2595 // 2596 // Let I/O package do the rest. 2597 // 2598 status = pDevice->m_PkgIo->ConfigureDynamicDispatching(MajorFunction, 2599 pCxDeviceInfo, 2600 EvtDeviceWdmIrpDispatch, 2601 DriverContext); 2602 exit: 2603 return status; 2604 } 2605 2606 _Must_inspect_result_ 2607 NTSTATUS 2608 FX_VF_FUNCTION(VerifyWdfDeviceWdmDispatchIrpToIoQueue) ( 2609 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals, 2610 _In_ FxDevice* device, 2611 _In_ MdIrp Irp, 2612 _In_ FxIoQueue* queue, 2613 _In_ ULONG Flags 2614 ) 2615 { 2616 NTSTATUS status = STATUS_SUCCESS; 2617 UCHAR majorFunction, minorFunction; 2618 FxIrp fxIrp(Irp); 2619 2620 PAGED_CODE_LOCKED(); 2621 2622 majorFunction = fxIrp.GetMajorFunction(); 2623 minorFunction = fxIrp.GetMinorFunction(); 2624 2625 DoTraceLevelMessage( 2626 FxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIO, 2627 "WDFDEVICE 0x%p !devobj 0x%p %!IRPMJ!, IRP_MN %x, IRP 0x%p", 2628 device->GetHandle(), device->GetDeviceObject(), 2629 majorFunction, minorFunction, Irp); 2630 2631 // 2632 // Validate Flags. For UMDF, this field is reserved and must be zero. 2633 // 2634 #if (FX_CORE_MODE == FX_CORE_KERNEL_MODE) 2635 if (Flags & ~FX_DISPATCH_IRP_TO_IO_QUEUE_FLAGS_MASK) { 2636 #else 2637 if (Flags != WDF_DISPATCH_IRP_TO_IO_QUEUE_NO_FLAGS) { 2638 #endif 2639 status = STATUS_INVALID_PARAMETER; 2640 DoTraceLevelMessage( 2641 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIO, 2642 "Flags 0x%x are invalid, %!STATUS!", 2643 Flags, status); 2644 FxVerifierDbgBreakPoint(FxDriverGlobals); 2645 goto Done; 2646 } 2647 2648 // 2649 // Only read/writes/ctrls/internal_ctrls IRPs are allowed, i.e., the I/O request set. 2650 // 2651 if (device->GetDispatchPackage(majorFunction) != device->m_PkgIo) { 2652 status = STATUS_INVALID_PARAMETER; 2653 DoTraceLevelMessage( 2654 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIO, 2655 "Only Read/Write/Control/Internal-Control IRPs can be " 2656 "forwarded to I/O Queue 0x%p, Irp 0x%p, %!IRPMJ!, " 2657 "IRP_MN %x, Device 0x%p, %!STATUS!", 2658 queue->GetHandle(), Irp, majorFunction, minorFunction, 2659 device->GetObjectHandle(), status); 2660 FxVerifierDbgBreakPoint(FxDriverGlobals); 2661 goto Done; 2662 } 2663 2664 // 2665 // Make sure queue can handle the request. 2666 // 2667 if (FALSE == queue->IsIoEventHandlerRegistered( 2668 (WDF_REQUEST_TYPE)majorFunction)) { 2669 2670 status = STATUS_INVALID_PARAMETER; 2671 DoTraceLevelMessage( 2672 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIO, 2673 "I/O Queue 0x%p cannot handle Irp 0x%p, %!IRPMJ!, " 2674 "IRP_MN %x, Device 0x%p, %!STATUS!", 2675 queue->GetHandle(), Irp, majorFunction, minorFunction, 2676 device->GetObjectHandle(), status); 2677 FxVerifierDbgBreakPoint(FxDriverGlobals); 2678 goto Done; 2679 } 2680 2681 if (device->m_ParentDevice == queue->GetDevice()) { 2682 // 2683 // Send to parent device's queue validation. 2684 // 2685 if (device->m_ParentDevice == NULL) { 2686 status = STATUS_INVALID_PARAMETER; 2687 DoTraceLevelMessage( 2688 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIO, 2689 "No parent device for Device 0x%p, %!STATUS!", 2690 device->GetObjectHandle(), status); 2691 FxVerifierDbgBreakPoint(FxDriverGlobals); 2692 goto Done; 2693 } 2694 2695 // 2696 // Make sure the child device is a PDO 2697 // 2698 ASSERT(device->IsPdo()); 2699 2700 // 2701 // Check if the WdfPdoInitSetForwardRequestToParent was called to 2702 // increase the StackSize of the child Device to include the stack 2703 // size of the parent Device 2704 // 2705 if (device->IsPnp() && 2706 device->GetPdoPkg()->m_AllowForwardRequestToParent == FALSE) { 2707 status = STATUS_INVALID_DEVICE_REQUEST; 2708 DoTraceLevelMessage( 2709 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIO, 2710 "WdfPdoInitSetForwardRequestToParent not called on " 2711 "Device 0x%p, %!STATUS!", 2712 device->GetObjectHandle(), status); 2713 FxVerifierDbgBreakPoint(FxDriverGlobals); 2714 goto Done; 2715 } 2716 } 2717 else { 2718 // 2719 // Send to current device's queue validation. 2720 // 2721 if (device != queue->GetDevice()) { 2722 status = STATUS_INVALID_PARAMETER; 2723 DoTraceLevelMessage( 2724 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIO, 2725 "Cannot forward a request to " 2726 "a different Device 0x%p, %!STATUS!", 2727 queue->GetDevice()->GetObjectHandle(), status); 2728 FxVerifierDbgBreakPoint(FxDriverGlobals); 2729 goto Done; 2730 } 2731 } 2732 2733 Done: 2734 return status; 2735 } 2736 2737 } // extern "C" 2738