Debugging Stop 0x10D - WDF_VIOLATION

x BlueRobot

Administrator
Staff member
Joined
May 7, 2013
Posts
10,400
A Stop 0x10D, also known as a Windows driver framework violation, is a bugcheck which is produced when the framework detects one of the rules has been broken. You can think of this bugcheck as akin to a Stop 0xC4 or any other Driver Verifier produced bugcheck. There is a number of variations of this bugcheck and therefore you will need to examine the parameters for each crash, otherwise the call stack will have no context.

The Windows Driver Framework is an open-source framework used to allow driver developers to develop software more efficiently and with less errors, by allowing the framework to handle many of the common tasks which the Windows Driver Model would expose to the developer. As a general debugging tip, if you notice any Wdf1000!* calls on a call stack, then it would be advisable to load wdfkd.dll and start investigating.

Let’s examine the first parameter of the bugcheck.

Rich (BB code):
WDF_VIOLATION (10d)
The Kernel-Mode Driver Framework was notified that Windows detected an error
in a framework-based driver. In general, the dump file will yield additional
information about the driver that caused this bug check.
Arguments:
Arg1: 000000000000000d, A power irp was received for the device but the irp was not
    requested by the device (the power policy owner). Possibly there
    are multiple power policy owners. Only one driver in the stack can
    be the power policy owner. A KMDF driver can change power policy
    ownership by calling the DDI WdfDeviceInitSetPowerPolicyOwnership.
Arg2: ffff9888d3710a70, Device object pointer.
Arg3: ffff9888d4753010, Power Irp.
Arg4: ffff9888d37e2a20, Reserved. << Pointer to PFX_DRIVER_GLOBALS

It states that a power IRP was received by a device which did not request the IRP to be sent. That is to say, the device in question is the power policy owner, however, it never requested the power operation. You may be wondering what is a power policy owner? The bugcheck description states that there should only be one power policy owner per a device stack, yet there is the possibility of there being multiple power policy owners on the same device stack. Let’s explore what a power policy owner is and how it is used.

For each device stack, one of the device objects must be assigned as the power policy owner. It is the responsibility of the power policy owner to manage the power state of the device, and generate power requests for when the device power state should be changed. It is then the responsibility of the framework itself to ensure that the device state is changed by requesting the bus driver of the device to change the power state. Remember, only bus drivers are able to complete power-related IRPs, thus why the framework is reliant upon the device’s bus driver. It may be useful to think of the framework as the middle-man between the device’s function driver and the device’s bus driver.

Moreover, it is possible for the power policy owner of a device to be changed, and in order to do so, the driver must call WdfDeviceInitSetPowerPolicyOwnership. The function takes two parameters: a pointer to the WDFDEVICE_INIT structure which is essentially the device object and a boolean which represents if the driver is the power policy owner. For the power policy owner to be successfully changed, then two drivers must call the above function; the default power policy owner must set the boolean value to false to state that it's no longer the owner, on the other hand, the device which will become the owner must call the function with the boolean set to true.

This leads to two possible reasons for the bugcheck: a driver hasn’t stated that it is no longer the power policy owner, therefore leading to two power policy owners in the same device stack. Secondly, the developer hasn’t realised that the framework will automatically set the power policy owner to the function driver, unless other stated, thereby again, leading to two possible power policy owners. We can use the second parameter which contains the address of the device object which received the power IRP to find the device stack.

Rich (BB code):
3: kd> !devstack ffff9888d3710a70
  !DevObj           !DrvObj            !DevExt           ObjectName
  ffff9888d37e9dd0  \Driver\WudfRd     ffff9888d37e9f20
> ffff9888d3710a70  \Driver\esif_lf    ffff9888d3721c20  esif_lf
  ffff9888d37e2c60  \Driver\dptf_cpu   ffff9888d210ba20
  ffff9888c465ddc0  \Driver\ACPI       ffff9888c46b3010
  ffff9888c67ef360  \Driver\pci        ffff9888c67ef4b0  NTPNP_PCI0002
!DevNode ffff9888c6817ca0 :
  DeviceInst is "PCI\VEN_8086&DEV_1903&SUBSYS_22B117AA&REV_0C\3&11583659&0&20"
  ServiceName is "dptf_cpu"

As we can see, there are two third-party drivers involved in this stack, both of which are related to Intel Thermal Power Management framework. The third parameter of the bugcheck contains the address of the power IRP which was sent to the power policy owner.

Rich (BB code):
3: kd> !irp ffff9888`d4753010
Irp is active with 6 stacks 4 is current (= 0xffff9888d47531b8)
 No Mdl: No System Buffer: Thread 00000000:  Irp stack trace.
     cmd  flg cl Device   File     Completion-Context
 [N/A(0), N/A(0)]
            0  0 00000000 00000000 00000000-00000000

            Args: 00000000 00000000 00000000 00000000
 [N/A(0), N/A(0)]
            0  0 00000000 00000000 00000000-00000000

            Args: 00000000 00000000 00000000 00000000
 [N/A(0), N/A(0)]
            0  0 00000000 00000000 00000000-00000000

            Args: 00000000 00000000 00000000 00000000
>[IRP_MJ_POWER(16), IRP_MN_SET_POWER(2)]
            0  0 ffff9888d3710a70 00000000 00000000-00000000
           \Driver\esif_lf
            Args: 00016600 00000001 00000004 00000005
 [IRP_MJ_POWER(16), IRP_MN_SET_POWER(2)]
            0 e1 ffff9888d37e9dd0 00000000 fffff80410b77bc0-ffff9888d39fc380 Success Error Cancel pending
           \Driver\WudfRd    nt!PopRequestCompletion
            Args: 00016600 00000001 00000004 00000005
 [N/A(0), N/A(0)]
            0  0 00000000 00000000 00000000-ffff9888d39fc380

            Args: 00000000 00000000 00000000 00000000

If we look closely, the current I/O stack location for the power request is associated to one of the Intel drivers. Notice how the framework driver has a completion routine set to complete the IRP? Remember it is the responsibility of the framework to inform the bus driver of the requested power state change.

We’ve gained some understanding behind what has possibly happened and why the bugcheck is called. Let’s begin to examine the call stack and see where we crash.

Rich (BB code):
3: kd> knL
 # Child-SP          RetAddr           Call Site
00 ffff870c`e7172658 fffff804`15b08920 nt!KeBugCheckEx
01 (Inline Function) --------`-------- Wdf01000!Mx::MxBugCheckEx+0x19
02 ffff870c`e7172660 fffff804`15ad1842 Wdf01000!FxVerifierBugCheckWorker+0x24
03 ffff870c`e71726a0 fffff804`15ac10b5 Wdf01000!FxPkgFdo::DispatchDeviceSetPower+0x10782 << Crash here!
04 ffff870c`e71726f0 fffff804`15abcc60 Wdf01000!FxPkgFdo::_DispatchSetPower+0x25
05 ffff870c`e7172720 fffff804`15aba867 Wdf01000!FxPkgPnp::Dispatch+0xb0 << Called by framework
06 (Inline Function) --------`-------- Wdf01000!DispatchWorker+0x6b
07 (Inline Function) --------`-------- Wdf01000!FxDevice::Dispatch+0x89
08 ffff870c`e7172790 fffff804`10b9516f Wdf01000!FxDevice::DispatchWithLock+0x157
09 ffff870c`e71727f0 fffff804`10a52f6d nt!IopPoHandleIrp+0x3b
0a ffff870c`e7172820 fffff804`10b973f9 nt!IofCallDriver+0x6d
0b ffff870c`e7172860 fffff804`1b777efe nt!IoCallDriver+0x9
0c ffff870c`e7172890 fffff804`1b777be4 WUDFRd!RdPnpTracker::RdPnpProcessor+0x47e
0d ffff870c`e7172930 fffff804`1b777a61 WUDFRd!RdPnpTracker::RdPnpProcessor+0x164
0e ffff870c`e71729d0 fffff804`10b5a4c5 WUDFRd!RdPnpTracker::RdPnpCallbackAtPassiveInSystemProcess+0x11
0f ffff870c`e7172a00 fffff804`10a25975 nt!IopProcessWorkItem+0x135
10 ffff870c`e7172a70 fffff804`10b17e85 nt!ExpWorkerThread+0x105
11 ffff870c`e7172b10 fffff804`10bfd2a8 nt!PspSystemThreadStartup+0x55
12 ffff870c`e7172b60 00000000`00000000 nt!KiStartSystemThread+0x28

The function in which we appear to have crashed at is DispatchDeviceSetPower, this dispatches the bugcheck exception if the device in question is the power policy owner and has not requested for a power state change. This can be seen in the following code excerpt:

Rich (BB code):
if (IsPowerPolicyOwner()) {
        if (m_PowerPolicyMachine.m_Owner->m_RequestedPowerUpIrp == FALSE &&
            m_PowerPolicyMachine.m_Owner->m_RequestedPowerDownIrp == FALSE) {
            //
            // A power irp arrived, but we did not request it.  log and bugcheck
            //
            DoTraceLevelMessage(
                GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
                "Received set device power irp 0x%p on WDFDEVICE 0x%p !devobj 0x%p, "
                "but the irp was not requested by the device (the power policy owner)",
                Irp->GetIrp(), m_Device->GetHandle(),
                m_Device->GetDeviceObject());

            FxVerifierBugCheck(GetDriverGlobals(),  // globals
                   WDF_POWER_MULTIPLE_PPO, // specific type
                   (ULONG_PTR)m_Device->GetDeviceObject(), //parm 2
                   (ULONG_PTR)Irp->GetIrp());  // parm 3

            /* NOTREACHED */
}

The power policy owner is determined by checking if the m_Owner field for the FxPowerPolicyMachine object is null, if it isn’t, then the device is said to be the power policy owner of the device stack. The power policy machine object is a property of a larger object called FxPkgFdo. The function then checks if the device requested the power state change by checking two fields within the FxPowerPolicySettings object (m_owner), if both of these are false then the framework will throw the bugcheck shown at the beginning of this post.

Rich (BB code):
3: kd> dt FxPkgFdo -y m_PowerPolicyMachine ffff9888d37e5600
Wdf01000!FxPkgFdo
   +0x2b8 m_PowerPolicyMachine : FxPowerPolicyMachine

Rich (BB code):
3: kd> dt FxPowerPolicyMachine -y m_Owner ffff9888`d37e58b8
Wdf01000!FxPowerPolicyMachine
   +0x0c0 m_Owner : 0xffff9888`d37d9a30 FxPowerPolicyOwnerSettings

Rich (BB code):
3: kd> dt FxPowerPolicyOwnerSettings ffff9888`d37d9a30
Wdf01000!FxPowerPolicyOwnerSettings
   +0x000 m_PowerIdleMachine : FxPowerIdleMachine
   +0x128 m_PoxInterface   : FxPoxInterface
   +0x168 m_DeviceArmWakeFromS0 : FxPowerDeviceArmWakeFromS0
   +0x190 m_DeviceArmWakeFromSx : FxPowerDeviceArmWakeFromSx
   +0x1c8 m_DeviceDisarmWakeFromS0 : FxPowerDeviceDisarmWakeFromS0
   +0x1f0 m_DeviceDisarmWakeFromSx : FxPowerDeviceDisarmWakeFromSx
   +0x218 m_DeviceWakeFromS0Triggered : FxPowerDeviceWakeFromS0Triggered
   +0x240 m_DeviceWakeFromSxTriggered : FxPowerDeviceWakeFromSxTriggered
   +0x268 m_UsbIdle        : (null)
   +0x270 m_PkgPnp         : 0xffff9888`d37e5600 FxPkgPnp
   +0x278 m_WakeSettings   : WakePolicySettings
   +0x298 m_IdleSettings   : IdlePolicySettings
   +0x2d0 m_DevicePowerIrpTracker : FxDevicePowerIrpTracker
   +0x360 m_SystemToDeviceStateMap : 0x4440010
   +0x364 m_ChildrenPoweredOnCount : 0
   +0x368 m_ChildrenArmedCount : 0n0
   +0x36c m_WaitWakeStatus : 0n-1073741637
   +0x370 m_IdealDxStateForSx : 0x4 ''
   +0x371 m_RequestedPowerUpIrp : 0 '' << FALSE
   +0x372 m_RequestedPowerDownIrp : 0 '' << FALSE
   +0x373 m_RequestedWaitWakeIrp : 0 ''
   +0x374 m_WakeCompletionEventDropped : 0 ''
   +0x375 m_PowerFailed    : 0 ''
   +0x376 m_CanSaveState   : 0 ''
   +0x377 m_ChildrenCanPowerUp : 0x1 ''
   +0x378 m_SystemWakeSource : 0 ''
   +0x380 m_PowerCallbackObject : 0xffff9888`c46a1780 _CALLBACK_OBJECT
   +0x388 m_PowerCallbackRegistration : 0xffff9888`d3758b10 Void
   +0x390 m_WaitWakeCancelCompletionOwnership : 0n0

The address of the FxPkgFdo object can be found from the FxPkgPnp's Dispatch function as the first parameter.

Rich (BB code):
3: kd> !stack -p
Call Stack : 16 frames
## Stack-Pointer    Return-Address   Call-Site
00 ffff870ce7172658 fffff80415b08920 nt!KeBugCheckEx+0
    Parameter[0] = 000000000000010d
    Parameter[1] = 000000000000000d
    Parameter[2] = ffff9888d3710a70
    Parameter[3] = ffff9888d4753010
01 ffff870ce7172660 fffff80415ad1842 Wdf01000!FxVerifierBugCheckWorker+24
    Parameter[0] = ffff9888d37e2a20
    Parameter[1] = 000000000000000d
    Parameter[2] = (unknown)
    Parameter[3] = (unknown)
02 ffff870ce71726a0 fffff80415ac10b5 Wdf01000!FxPkgFdo::DispatchDeviceSetPower+10782 (perf)
    Parameter[0] = ffff9888d37e5600 <<FxPkgFdo
    Parameter[1] = ffff870ce7172790 << FxIrp
    Parameter[2] = (unknown)
    Parameter[3] = (unknown)
03 ffff870ce71726f0 fffff80415abcc60 Wdf01000!FxPkgFdo::_DispatchSetPower+25
    Parameter[0] = (unknown)
    Parameter[1] = ffff870ce7172790
    Parameter[2] = (unknown)
    Parameter[3] = (unknown)
04 ffff870ce7172720 fffff80415aba867 Wdf01000!FxPkgPnp::Dispatch+b0 (perf)
    Parameter[0] = ffff9888d37e5600 << FxPkgFdo
    Parameter[1] = ffff9888d4753010 << IRP
    Parameter[2] = (unknown)
    Parameter[3] = (unknown)
05 ffff870ce7172790 fffff80410b9516f Wdf01000!FxDevice::DispatchWithLock+157 (perf)
    Parameter[0] = 0000000000000002
    Parameter[1] = ffff9888d4753010
    Parameter[2] = (unknown)
    Parameter[3] = (unknown)
[...]

You may also notice that the function logs the error message into the WDF IFR log for the driver and dispatches the bugcheck exception by calling FxVerifierBugCheckWorker which is wrapper function for the standard KeBugcheckEx function.

Rich (BB code):
VOID
__declspec(noreturn)
FxVerifierBugCheckWorker(
    __in PFX_DRIVER_GLOBALS FxDriverGlobals,
    __in WDF_BUGCHECK_CODES WdfBugCheckCode,
    __in_opt ULONG_PTR BugCheckParameter2,
    __in_opt ULONG_PTR BugCheckParameter3
)

The second parameter for FxVerifierBugcheckWorker is actually an enumeration called WDF_BUGCHECK_CODES. This enumeration contains all the possible reasons for the crash; in our case, it appears to be due to multiple power policy owners within the same device stack as mentioned earlier.

Rich (BB code):
3: kd> dt WDF_BUGCHECK_CODES
Wdf01000!WDF_BUGCHECK_CODES
   WDF_POWER_ROUTINE_TIMED_OUT = 0n1
   WDF_RECURSIVE_LOCK = 0n2
   WDF_VERIFIER_FATAL_ERROR = 0n3
   WDF_REQUIRED_PARAMETER_IS_NULL = 0n4
   WDF_INVALID_HANDLE = 0n5
   WDF_REQUEST_FATAL_ERROR = 0n6
   WDF_OBJECT_ERROR = 0n7
   WDF_DMA_FATAL_ERROR = 0n8
   WDF_INVALID_INTERRUPT = 0n9
   WDF_QUEUE_FATAL_ERROR = 0n10
   WDF_INVALID_LOCK_OPERATION = 0n11
   WDF_PNP_FATAL_ERROR = 0n12
   WDF_POWER_MULTIPLE_PPO = 0n13
   WDF_VERIFIER_IRQL_MISMATCH = 0n14
   WDF_VERIFIER_CRITICAL_REGION_MISMATCH = 0n15
   WDF_API_UNAVAILABLE = 0n16

So, we understand why the bugcheck was caused and the bugcheck description suggests that there may be two power policy owners in the same device stack. However, let's confirm this fact, by dumping the IFR logs for both drivers and their subsequent WDF device objects.

Rich (BB code):
3: kd> !wdflogdump esif_lf
Trace searchpath is:

Trace format prefix is: %7!u!: %!FUNC! -
Trying to extract TMF information from - C:\ProgramData\dbg\sym\Wdf01000.pdb\6D6E9C327875C47856AC7DA750AB1C5E1\Wdf01000.pdb
Gather log: Please wait, this may take a moment (reading 4024 bytes).
% read so far ... 10, 20, 30, 40, 50, 60, 70, 100
There are 58 log entries
--- start of log ---
1: FxIFRStart - FxIFR logging started
2: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 entering PnP State WdfDevStatePnpInit from WdfDevStatePnpObjectCreated
3: FxPkgPnp::Dispatch - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70, IRP_MJ_PNP, 0x00000000(IRP_MN_START_DEVICE) IRP 0xFFFF9888CF6A5AF0
4: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 entering PnP State WdfDevStatePnpInitStarting from WdfDevStatePnpInit
5: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 entering PnP State WdfDevStatePnpHardwareAvailable from WdfDevStatePnpInitStarting
6: FxPkgPnp::PnpMatchResources - Not enough interrupt objects created by WDFDEVICE 0x000067772C8DE6C8
7: FxPkgPnp::PowerPolicyEnterNewState - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 entering power policy state WdfDevStatePwrPolStarting from WdfDevStatePwrPolObjectCreated
8: FxPowerIdleMachine::ProcessEventLocked - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 entering power idle state FxIdleStarted from FxIdleStopped
9: FxPkgPnp::PowerEnterNewState - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 entering Power State WdfDevStatePowerStartingCheckDeviceType from WdfDevStatePowerObjectCreated
10: FxPkgPnp::PowerEnterNewState - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 entering Power State WdfDevStatePowerD0Starting from WdfDevStatePowerStartingCheckDeviceType
11: FxPkgPnp::PowerEnterNewState - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 entering Power State WdfDevStatePowerD0StartingConnectInterrupt from WdfDevStatePowerD0Starting
12: FxPkgPnp::PowerEnterNewState - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 entering Power State WdfDevStatePowerD0StartingDmaEnable from WdfDevStatePowerD0StartingConnectInterrupt
13: FxPkgPnp::PowerEnterNewState - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 entering Power State WdfDevStatePowerD0StartingPostHardwareEnabled from WdfDevStatePowerD0StartingDmaEnable
14: FxPkgPnp::PowerEnterNewState - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 entering Power State WdfDevStatePowerD0StartingStartSelfManagedIo from WdfDevStatePowerD0StartingPostHardwareEnabled
15: FxPkgIo::ResumeProcessingForPower - Power resume all queues of WDFDEVICE 0x000067772C8DE6C8
16: FxSelfManagedIoMachine::ProcessEvent - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 entering self managed io state FxSelfManagedIoInit from FxSelfManagedIoCreated
17: FxIoTargetRemote::OpenTargetHandle - ZwCreateFile for WDFIOTARGET 000067772C667368 returned status STATUS_SUCCESS, info 0x0
18: FxIoTargetRemote::ClearTargetPointers - WDFIOTARGET 000067772C667368 cleared pointers FFFF870CE7181B30 state WdfIoTargetClosed, open state 1, pdo FFFF9888D0B396F0, fileobj FFFF9888D384F1E0, handle FFFFFFFF80000F9C
19: FxIoTargetRemote::Close - WDFIOTARGET 000067772C667368 derefing PDO FFFF9888D0B396F0 on close
20: FxIoTargetRemote::Close - WDFIOTARGET 000067772C667368 derefing FileObj FFFF9888D384F1E0 on close
21: FxIoTargetRemote::Close - WDFIOTARGET 000067772C667368 closing handle FFFFFFFF80000F9C on close
22: FxIoTargetRemote::ClearTargetPointers - WDFIOTARGET 000067772C667368 cleared pointers FFFF870CE7181A40 state WdfIoTargetDeleted, open state 1, pdo 0000000000000000, fileobj 0000000000000000, handle 0000000000000000
23: FxIoTarget::WaitForDisposeEvent - WDFIOTARGET 000067772C667368, Waiting on Dispose event FFFF870CE71819B0
24: FxIoTargetRemote::OpenTargetHandle - ZwCreateFile for WDFIOTARGET 000067772C47A748 returned status STATUS_SUCCESS, info 0x0
25: FxSelfManagedIoMachine::ProcessEvent - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 entering self managed io state FxSelfManagedIoStarted from FxSelfManagedIoInit
26: FxPowerIdleMachine::ProcessEventLocked - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 entering power idle state FxIdleStartedPowerUp from FxIdleStarted
27: FxPowerIdleMachine::ProcessEventLocked - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 entering power idle state FxIdleDisabled from FxIdleStartedPowerUp
28: FxPkgPnp::PowerEnterNewState - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 entering Power State WdfDevStatePowerDecideD0State from WdfDevStatePowerD0StartingStartSelfManagedIo
29: FxPkgPnp::PowerEnterNewState - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 entering Power State WdfDevStatePowerD0 from WdfDevStatePowerDecideD0State
30: FxPkgPnp::PowerPolicyEnterNewState - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 entering power policy state WdfDevStatePwrPolStartingPoweredUp from WdfDevStatePwrPolStarting
31: FxPkgPnp::PowerPolicyEnterNewState - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 entering power policy state WdfDevStatePwrPolStartingSucceeded from WdfDevStatePwrPolStartingPoweredUp
32: FxPkgPnp::PowerPolicyEnterNewState - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 entering power policy state WdfDevStatePwrPolStartingDecideS0Wake from WdfDevStatePwrPolStartingSucceeded
33: FxPkgPnp::PowerPolicyEnterNewState - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 entering power policy state WdfDevStatePwrPolStarted from WdfDevStatePwrPolStartingDecideS0Wake
34: FxPowerIdleMachine::ProcessEventLocked - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 entering power idle state FxIdleDisabled from FxIdleDisabled
35: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 entering PnP State WdfDevStatePnpEnableInterfaces from WdfDevStatePnpHardwareAvailable
36: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 entering PnP State WdfDevStatePnpStarted from WdfDevStatePnpEnableInterfaces
37: FxPkgPnp::Dispatch - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70, IRP_MJ_PNP, 0x00000007(IRP_MN_QUERY_DEVICE_RELATIONS) type TargetDeviceRelation IRP 0xFFFF9888D2F20A20
38: FxPkgPnp::Dispatch - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70, IRP_MJ_PNP, 0x00000007(IRP_MN_QUERY_DEVICE_RELATIONS) type TargetDeviceRelation IRP 0xFFFF9888D2F20A20
39: FxPkgPnp::Dispatch - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70, IRP_MJ_PNP, 0x00000014(IRP_MN_QUERY_PNP_DEVICE_STATE) IRP 0xFFFF9888D2DE7B70
40: FxPkgFdo::HandleQueryPnpDeviceStateCompletion - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 returning PNP_DEVICE_STATE 0x32 IRP 0xFFFF9888D2DE7B70
41: FxPkgPnp::Dispatch - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70, IRP_MJ_PNP, 0x00000007(IRP_MN_QUERY_DEVICE_RELATIONS) type BusRelations IRP 0xFFFF9888CF6F3940
42: FxPkgPnp::Dispatch - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70, IRP_MJ_PNP, 0x00000007(IRP_MN_QUERY_DEVICE_RELATIONS) type TargetDeviceRelation IRP 0xFFFF9888CF6F3940
43: FxPkgPnp::Dispatch - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70, IRP_MJ_PNP, 0x00000007(IRP_MN_QUERY_DEVICE_RELATIONS) type TargetDeviceRelation IRP 0xFFFF9888D2DE7B70
44: FxPkgPnp::Dispatch - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70, IRP_MJ_PNP, 0x00000007(IRP_MN_QUERY_DEVICE_RELATIONS) type TargetDeviceRelation IRP 0xFFFF9888D2DE7B70
45: FxPkgPnp::Dispatch - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70, IRP_MJ_PNP, 0x00000007(IRP_MN_QUERY_DEVICE_RELATIONS) type TargetDeviceRelation IRP 0xFFFF9888CBF59460
46: FxPkgPnp::Dispatch - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70, IRP_MJ_PNP, 0x00000007(IRP_MN_QUERY_DEVICE_RELATIONS) type TargetDeviceRelation IRP 0xFFFF9888CBF59460
47: FxPkgPnp::Dispatch - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70, IRP_MJ_PNP, 0x00000007(IRP_MN_QUERY_DEVICE_RELATIONS) type TargetDeviceRelation IRP 0xFFFF9888CBF59460
48: FxPkgPnp::Dispatch - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70, IRP_MJ_PNP, 0x00000007(IRP_MN_QUERY_DEVICE_RELATIONS) type TargetDeviceRelation IRP 0xFFFF9888D2F21A20
49: FxPkgPnp::Dispatch - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70, IRP_MJ_PNP, 0x00000007(IRP_MN_QUERY_DEVICE_RELATIONS) type TargetDeviceRelation IRP 0xFFFF9888D2F21A20
50: FxPkgPnp::Dispatch - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70, IRP_MJ_PNP, 0x00000007(IRP_MN_QUERY_DEVICE_RELATIONS) type TargetDeviceRelation IRP 0xFFFF9888D2F21A20
51: FxPkgPnp::Dispatch - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70, IRP_MJ_PNP, 0x00000007(IRP_MN_QUERY_DEVICE_RELATIONS) type TargetDeviceRelation IRP 0xFFFF9888D0ED55E0
52: FxPkgPnp::Dispatch - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70, IRP_MJ_PNP, 0x00000007(IRP_MN_QUERY_DEVICE_RELATIONS) type TargetDeviceRelation IRP 0xFFFF9888CBF59460
53: FxIoTargetRemote::OpenTargetHandle - ZwCreateFile for WDFIOTARGET 000067772C245458 returned status STATUS_SUCCESS, info 0x0
54: FxPkgPnp::Dispatch - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70, IRP_MJ_PNP, 0x00000007(IRP_MN_QUERY_DEVICE_RELATIONS) type TargetDeviceRelation IRP 0xFFFF9888D2EFAA20
55: FxPkgPnp::Dispatch - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70, IRP_MJ_PNP, 0x00000007(IRP_MN_QUERY_DEVICE_RELATIONS) type TargetDeviceRelation IRP 0xFFFF9888D2EFAA20
56: FxPkgPnp::Dispatch - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 IRP_MJ_POWER, 0x00000002(IRP_MN_SET_POWER) IRP 0xFFFF9888DCD99560 for PowerSystemShutdown (S5)
57: FxPkgPnp::Dispatch - WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70 IRP_MJ_POWER, 0x00000002(IRP_MN_SET_POWER) IRP 0xFFFF9888D4753010 for PowerDeviceD3
58: FxPkgFdo::DispatchDeviceSetPower - Received set device power irp 0xFFFF9888D4753010 on WDFDEVICE 0x000067772C8DE6C8 !devobj 0xFFFF9888D3710A70, but the irp was not requested by the device (the power policy owner)

Notice the same logging statement from the code sample shown earlier?

Rich (BB code):
3: kd> !wdfdevice 0x000067772C8DE6C8
Treating handle as a KMDF handle!

Dumping WDFDEVICE 0x000067772c8de6c8
=================================

WDM PDEVICE_OBJECTs:  self ffff9888d3710a70, attached ffff9888d37e2c60, pdo ffff9888c67ef360

Pnp state:  119 ( WdfDevStatePnpStarted )
Power state:  307 ( WdfDevStatePowerD0 )
Power Pol state:  565 ( WdfDevStatePwrPolStarted )

Default WDFIOTARGET: 000067772d0742c8

Device is the power policy owner for the stack
No pended pnp, wait-wake irps
Pended system power !irp 0xffff9888dcd99560 (S5)

We'll dump the other driver which was in the device stack by dumping the IFR log and then using handle address for the WDF Device object.

Rich (BB code):
3: kd> !wdfdevice 0x000067772DEF48C8
Treating handle as a KMDF handle!

Dumping WDFDEVICE 0x000067772def48c8
=================================

WDM PDEVICE_OBJECTs:  self ffff9888d37e2c60, attached ffff9888c465ddc0, pdo ffff9888c67ef360

Pnp state:  119 ( WdfDevStatePnpStarted )
Power state:  307 ( WdfDevStatePowerD0 )
Power Pol state:  527 ( WdfDevStatePwrPolSleepingNoWakePowerDown )

Default WDFIOTARGET: 000067772d074628

Device is the power policy owner for the stack
No pended pnp, wait-wake irps
Pended system power !irp 0xffff9888dcd99560 (S5)

Ah! It seems that we do in fact have two power policy owners in the same device stack, hence why the system crashes with the bugcheck. Although, how do we confirm that dptf_cpu.sys is the correct power policy owner for the stack? In order to do so, we need to obtain the address of the FxDevice object and to do that, we can use the !wdfhandle command along with the address of the WDF device handle we obtained from the IFR log.

Rich (BB code):
3: kd> !wdfhandle 0x000067772DEF48C8
Treating handle as a KMDF handle!

Dumping WDFHANDLE 0x000067772def48c8
=============================
Handle type is WDFDEVICE
Refcount: 2
Contexts:
    context:  dt 0xffff9888d210ba20 DEVICE_EXTENSION (size is 0x130 bytes)
    EvtCleanupCallback fffff8041c1e4670 dptf_cpu

Parent: !wdfhandle 0x000067772f521958, type is WDFDRIVER
Owning device: !wdfdevice 0x000067772def48c8

!wdfobject 0xffff9888d210b730 << FxDevice

Rich (BB code):
3: kd> dt FxDevice -y m_PkgPnp ffff9888d210b730
Wdf01000!FxDevice
   +0x288 m_PkgPnp : 0xffff9888`d3720840 FxPkgPnp

The FxPkgPnp object contains a reference to the power policy settings object mentioned earlier.

Rich (BB code):
3: kd> dt FxPkgPnp -y m_PowerPolicyMachine ffff9888`d3720840
Wdf01000!FxPkgPnp
   +0x2b8 m_PowerPolicyMachine : FxPowerPolicyMachine

Rich (BB code):
3: kd> dt FxPowerPolicyMachine -y m_Owner ffff9888`d3720af8
Wdf01000!FxPowerPolicyMachine
   +0x0c0 m_Owner : 0xffff9888`d37e3a30 FxPowerPolicyOwnerSettings

Rich (BB code):
3: kd> dt FxPowerPolicyOwnerSettings 0xffff9888`d37e3a30
Wdf01000!FxPowerPolicyOwnerSettings
   +0x000 m_PowerIdleMachine : FxPowerIdleMachine
   +0x128 m_PoxInterface   : FxPoxInterface
   +0x168 m_DeviceArmWakeFromS0 : FxPowerDeviceArmWakeFromS0
   +0x190 m_DeviceArmWakeFromSx : FxPowerDeviceArmWakeFromSx
   +0x1c8 m_DeviceDisarmWakeFromS0 : FxPowerDeviceDisarmWakeFromS0
   +0x1f0 m_DeviceDisarmWakeFromSx : FxPowerDeviceDisarmWakeFromSx
   +0x218 m_DeviceWakeFromS0Triggered : FxPowerDeviceWakeFromS0Triggered
   +0x240 m_DeviceWakeFromSxTriggered : FxPowerDeviceWakeFromSxTriggered
   +0x268 m_UsbIdle        : (null)
   +0x270 m_PkgPnp         : 0xffff9888`d3720840 FxPkgPnp
   +0x278 m_WakeSettings   : WakePolicySettings
   +0x298 m_IdleSettings   : IdlePolicySettings
   +0x2d0 m_DevicePowerIrpTracker : FxDevicePowerIrpTracker
   +0x360 m_SystemToDeviceStateMap : 0x4440010
   +0x364 m_ChildrenPoweredOnCount : 0
   +0x368 m_ChildrenArmedCount : 0n0
   +0x36c m_WaitWakeStatus : 0n-1073741637
   +0x370 m_IdealDxStateForSx : 0x4 ''
   +0x371 m_RequestedPowerUpIrp : 0 ''
   +0x372 m_RequestedPowerDownIrp : 0x1 '' << True
   +0x373 m_RequestedWaitWakeIrp : 0 ''
   +0x374 m_WakeCompletionEventDropped : 0 ''
   +0x375 m_PowerFailed    : 0 ''
   +0x376 m_CanSaveState   : 0 ''
   +0x377 m_ChildrenCanPowerUp : 0 ''
   +0x378 m_SystemWakeSource : 0 ''
   +0x380 m_PowerCallbackObject : 0xffff9888`c46a1780 _CALLBACK_OBJECT
   +0x388 m_PowerCallbackRegistration : 0xffff9888`d3758f90 Void
   +0x390 m_WaitWakeCancelCompletionOwnership : 0n0

As we can see, it was dptf_cpu.sys which requested the device to be powered down and is the legitimate power policy owner for the device stack. It would seem that esif_lf.sys would need to be updated or the source code be investigated, especially since both drivers are part of the same package which is the Intel thermal management software. As explained earlier, if we have multiple power policy owners in the same device stack; if the illegitimate power policy owner is higher up in the stack, it will receive the power IRP before the legitimate power policy owner, thus leading to the framework throwing the bugcheck exception.

Rich (BB code):
3: kd> lmvm esif_lf
Browse full module list
start             end                 module name
fffff804`1c9d0000 fffff804`1ca2f000   esif_lf    (deferred)          
    Image path: \SystemRoot\System32\drivers\esif_lf.sys
    Image name: esif_lf.sys
    Browse all global symbols  functions  data
    Timestamp:        Thu Nov  2 21:28:12 2017 (59FB8DEC)
    CheckSum:         00068C4F
    ImageSize:        0005F000
    Translations:     0000.04b0 0000.04e4 0409.04b0 0409.04e4
    Information from resource tables:


References:

microsoft/Windows-Driver-Frameworks
microsoft/Windows-Driver-Frameworks
microsoft/Windows-Driver-Frameworks
One Reference to WDFDEVICE
Power Policy Ownership - Windows drivers
 
Rich (BB code):
WDF_VIOLATION (10d)
The Kernel-Mode Driver Framework was notified that Windows detected an error
in a framework-based driver. In general, the dump file will yield additional
information about the driver that caused this BugCheck.
Arguments:
Arg1: 0000000000000007, A driver attempted to delete a framework object incorrectly
by calling WdfObjectDereference to delete a handle instead
of calling WdfObjectDelete.
Arg2: 000019fc10bf48a8, Reserved. << Handle to the object being deleted
Arg3: ffffe603ef40b750, Reserved. << The FxDevice object being deleted
Arg4: ffffe603edcf4de0, Reserved. << Pointer to PFX_DRIVER_GLOBALS

This is another example of a driver framework violation error but for a slightly different reason this time. The issue here is that a driver has attempted to close a handle to a WDF object using the wrong API. This is given in the first parameter. The bugcheck is actually raised when an object is being destroyed, here is the destructor for all FxObjects:

Rich (BB code):
FxObject::~FxObject()
{
    FxTagTracker *pTagTracker;
    pTagTracker = GetTagTracker();
 
    if (pTagTracker != NULL) {
        delete pTagTracker;
    }
 
    ASSERT(m_DisposeSingleEntry.Next == NULL);
 
    //
    // We need to ensure there are no leaked child objects, or
    // parent associations.
    //
    // This can occur if someone calls the C++ operator delete,
    // or Release() to destroy the object.
    //
    // This is generally invalid in the framework, though certain
    // objects may understand the underlying contract, but must
    // make sure there are no left over un-Disposed associations.
    //
    // Embedded FxObject's also don't have delete called on them,
    // and have to manually manage any child associations when
    // their parent object disposes by calling PerformEarlyDispose.
    //
    // They don't have an associated lifetime parent since they
    // are embedded.
    //
    if (m_ParentObject != NULL ||
        !IsListEmpty(&m_ChildListHead) || !IsListEmpty(&m_ChildEntry)) {
        PCSTR pHandleName;
 
        pHandleName = FxObjectTypeToHandleName(m_Type);
        if (pHandleName == NULL) {
            pHandleName = "WDFOBJECT";
        }
 
        ASSERTMSG(
            "Object was freed using WdfObjectDereference, not WdfObjectDelete\n",
            m_ParentObject == NULL &&
            IsListEmpty(&m_ChildEntry) &&
            IsListEmpty(&m_ChildListHead)
            );
 
        DoTraceLevelMessage(
            GetDriverGlobals(), TRACE_LEVEL_FATAL, TRACINGOBJECT,
            "Handle %s %p (raw object %p) was freed using "
            "WdfObjectDereference(), not WdfObjectDelete()",
            pHandleName, GetObjectHandleUnchecked(), this);
 
        FxVerifierBugCheck(GetDriverGlobals(),
                           WDF_OBJECT_ERROR,
                           (ULONG_PTR) GetObjectHandleUnchecked(),
                           (ULONG_PTR) this);
    }
 
    //
    // This is called when the reference count goes to zero
    //
    SetObjectStateLocked(FxObjectStateDestroyed);
}

The documentation clearly states that all drivers must dispose of any resources using WdfObjectDelete, since the WdfObjectDereference function only decrements the reference count on the object. While this is permissible for framework managed objects – they will be automatically disposed of when the reference count reaches 0 – not all objects may be disposed of by the framework when their reference count reaches 0 and therefore there is a risk of undisposed objects, which in turn can lead to memory leaks.

If we examine the second parameter, we’ll see that it is a handle to the WDF object being disposed of.

Rich (BB code):
15: kd> !wdfhandle 000019fc10bf48a8
Treating handle as a KMDF handle!

Dumping WDFHANDLE 0x000019fc10bf48a8
=============================
Handle type is WDFDEVICE
Refcount: 0
Contexts:
    <no associated attribute callbacks>
Owning device: !wdfdevice 0x000019fc10bf48a8

!wdfobject 0xffffe603ef40b750

The handle belongs to a WDF device object and by using the !wdfobject command with the object address, we’ll be able to gather the address of the FxDevice.

Rich (BB code):
15: kd> !wdfobject 0xffffe603ef40b750

The type for object 0xffffe603ef40b750 is FxDevice
State: FxObjectStateDisposingDisposeChildren (0x4)
!wdfhandle 0x000019fc10bf48a8

dt Wdf01000!FxDevice 0xffffe603ef40b750

Notice that the object state is disposing? You can dump the FxDevice object itself and then examine the RegistryPath field to see which driver the object belongs to. In this case, it was dc1-controller.sys which is a WDF driver for Xbox controllers.

Rich (BB code):
15: kd> dt FxDevice ffffe603ef40b750
Wdf01000!FxDevice
   +0x000 __VFN_table : 0xfffff805`63c637e0 
   +0x008 m_Type           : 0x1002
   +0x00a m_ObjectSize     : 0x2c0
   +0x00c m_Refcnt         : 0n0
   +0x010 m_Globals        : 0xffffe603`edcf4de0 _FX_DRIVER_GLOBALS
   +0x018 m_ObjectFlags    : 0xd1a
   +0x018 m_ObjectFlagsByName : FxObject::<anonymous-tag>::<unnamed-type-m_ObjectFlagsByName>
   +0x01a m_ObjectState    : 4
   +0x020 m_ChildListHead  : _LIST_ENTRY [ 0xffffe603`f706ac98 - 0xffffe603`ee3baf28 ]
   +0x030 m_SpinLock       : MxLock
   +0x040 m_ParentObject   : (null) 
   +0x048 m_ChildEntry     : _LIST_ENTRY [ 0xffffe603`ef40b798 - 0xffffe603`ef40b798 ]
   +0x058 m_DisposeSingleEntry : _SINGLE_LIST_ENTRY
   +0x060 m_DeviceBase     : 0xffffe603`ef40b750 FxDeviceBase
   +0x060 m_Device         : 0xffffe603`ef40b750 FxDevice
   +0x068 m_NPLock         : MxLock
   +0x078 __VFN_table : 0xfffff805`63c673d8 
   +0x080 m_DisposeList    : (null) 
   +0x088 m_Driver         : 0xffffe603`fb646af0 FxDriver
   +0x090 m_DeviceObject   : MxDeviceObject

Rich (BB code):
15: kd> dt FxDriver ffffe603`fb646af0 -y m_RegistryPath
Wdf01000!FxDriver
   +0x088 m_RegistryPath : _UNICODE_STRING "\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\dc1-controller"

Since Xbox drivers are notorious for causing bugchecks on Windows 10 and Windows 11 systems, the best course of action would be to remove the driver completely using pnputil and then delete the associated services if needs be.

For those interested, here is the call stack leading up to the bugcheck, notice the destructor being called?

Rich (BB code):
15: kd> !load cmkd; !stack -p
Call Stack : 44 frames
## Stack-Pointer    Return-Address   Call-Site       
00 fffffd030ed466e8 fffff80563c2927c nt!KeBugCheckEx+0 
    Parameter[0] = 000000000000010d
    Parameter[1] = 0000000000000007
    Parameter[2] = 000019fc10bf48a8
    Parameter[3] = ffffe603ef40b750
01 fffffd030ed466f0 fffff80563bf58bc Wdf01000!FxVerifierBugCheckWorker+24 
    Parameter[0] = ffffe603edcf4de0
    Parameter[1] = 0000000000000007
    Parameter[2] = 000019fc10bf48a8
    Parameter[3] = ffffe603ef40b750
02 fffffd030ed46730 fffff80563be425a Wdf01000!FxObject::~FxObject+1df1c (perf)
    Parameter[0] = ffffe603ef40b750
    Parameter[1] = (unknown)       
    Parameter[2] = (unknown)       
    Parameter[3] = (unknown)       
03 fffffd030ed46790 fffff80563c1d574 Wdf01000!FxNonPagedObject::~FxNonPagedObject+2a 
    Parameter[0] = ffffe603ef40b750
    Parameter[1] = (unknown)       
    Parameter[2] = (unknown)       
    Parameter[3] = (unknown)       
04 fffffd030ed467c0 fffff80563c216bc Wdf01000!FxDeviceBase::~FxDeviceBase+6c 
    Parameter[0] = ffffe603ef40b750
    Parameter[1] = (unknown)       
    Parameter[2] = (unknown)       
    Parameter[3] = (unknown)       
05 fffffd030ed467f0 fffff80563c216f4 Wdf01000!FxDevice::~FxDevice+29c 
    Parameter[0] = ffffe603ef40b750
    Parameter[1] = (unknown)       
    Parameter[2] = (unknown)       
    Parameter[3] = (unknown)       
06 fffffd030ed46850 fffff80563bd40cb Wdf01000!FxDevice::`scalar deleting destructor'+14 
    Parameter[0] = ffffe603ef40b750
    Parameter[1] = 0000000000000001
    Parameter[2] = (unknown)       
    Parameter[3] = (unknown)       
07 fffffd030ed46880 fffff80563bd2a46 Wdf01000!FxObject::SelfDestruct+1b 
    Parameter[0] = (unknown)       
    Parameter[1] = (unknown)       
    Parameter[2] = (unknown)       
    Parameter[3] = (unknown)       
08 fffffd030ed468b0 fffff80563be3b02 Wdf01000!FxObject::Release+106 (perf)
    Parameter[0] = ffffe603ef40b750
    Parameter[1] = ffffe603ee3baee0
    Parameter[2] = 00000000000001d5
    Parameter[3] = fffff80563c68e00

References:

WdfObjectDelete function (wdfobject.h) - Windows drivers

WdfObjectDereference macro - Windows drivers

Framework Object Life Cycle - Windows drivers

/src/framework/shared/object/fxobject.cpp – GitHub
 

Has Sysnative Forums helped you? Please consider donating to help us support the site!

Back
Top