- May 7, 2013
- 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.
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.
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.
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.
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:
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.
The address of the FxPkgFdo object can be found from the FxPkgPnp's Dispatch function as the first parameter.
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.
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.
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.
Notice the same logging statement from the code sample shown earlier?
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.
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.
The FxPkgPnp object contains a reference to the power policy settings object mentioned earlier.
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.
References:
microsoft/Windows-Driver-Frameworks
microsoft/Windows-Driver-Frameworks
microsoft/Windows-Driver-Frameworks
One Reference to WDFDEVICE
Power Policy Ownership - Windows drivers
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