reactos/sdk/lib/drivers/wdf/shared/inc/private/common/fxpowerpolicystatemachine.hpp
Victor Perevertkin 1f377076d7
[WDF] Fix KMDF so it can compile with ReactOS SDK
Not all files are included, but these are necessary to compile cdrom driver.
So far it can only be statically linked with drivers, a proper
implementation requires wdfldr helper driver
2020-11-03 00:06:27 +03:00

811 lines
24 KiB
C++

//
// Copyright (C) Microsoft. All rights reserved.
//
#ifndef _FXPOWERPOLICYSTATEMACHINE_H_
#define _FXPOWERPOLICYSTATEMACHINE_H_
#include "fxpoweridlestatemachine.hpp"
#include "fxpoxinterface.hpp"
// @@SMVERIFY_SPLIT_BEGIN
//
// Treat these values as a bit field when comparing for known dropped events in
// the current state and treat them as values when they known transition events
// from state to the next.
//
enum FxPowerPolicyEvent {
PwrPolInvalid = 0x00000000,
PwrPolStart = 0x00000001,
PwrPolStop = 0x00000002,
PwrPolSx = 0x00000004,
PwrPolS0 = 0x00000008,
PwrPolPowerDown = 0x00000010,
PwrPolPowerUp = 0x00000020,
PwrPolPowerDownIoStopped = 0x00000040,
PwrPolPowerUpHwStarted = 0x00000080,
PwrPolWakeArrived = 0x00000100,
PwrPolWakeSuccess = 0x00000200,
PwrPolWakeFailed = 0x00000400,
PwrPolIoPresent = 0x00000800,
PwrPolPowerTimeoutExpired = 0x00001000,
PwrPolS0IdlePolicyChanged = 0x00002000,
PwrPolSurpriseRemove = 0x00004000,
PwrPolUsbSelectiveSuspendCallback = 0x00008000,
PwrPolUsbSelectiveSuspendCompleted = 0x00010000,
PwrPolPowerDownFailed = 0x00020000,
PwrPolPowerUpFailed = 0x00040000,
PwrPolImplicitPowerDown = 0x00080000,
PwrPolImplicitPowerDownFailed = 0x00100000,
PwrPolPowerUpNotSeen = 0x00200000,
PwrPolDevicePowerNotRequired = 0x00400000,
PwrPolDevicePowerRequired = 0x00800000,
PwrPolRemove = 0x01000000,
PwrPolWakeInterruptFired = 0x02000000,
//
// Not a real event, just a value that indicates all of the events which
// goto the head of the queue and are always processed, even if the state is
// locked. This applies to the power policy owner state machine.
//
PwrPolPriorityEventsMask = PwrPolPowerUp |
PwrPolPowerDown |
PwrPolPowerUpFailed |
PwrPolPowerDownFailed |
PwrPolPowerDownIoStopped |
PwrPolPowerUpHwStarted |
PwrPolImplicitPowerDown |
PwrPolImplicitPowerDownFailed |
PwrPolWakeArrived |
PwrPolWakeSuccess |
PwrPolWakeFailed |
PwrPolPowerUpNotSeen |
PwrPolUsbSelectiveSuspendCompleted |
PwrPolWakeInterruptFired,
//
// Not a real event, just a value that indicates all of the events which
// goto the head of the queue and are always processed, even if the state is
// locked. This applies to the not power policy owner state machine.
//
PwrPolNotOwnerPriorityEventsMask = PwrPolPowerUp |
PwrPolPowerUpFailed |
PwrPolPowerDown |
PwrPolPowerDownFailed,
//
// Not a real event, just a value that indicate all of the events which
// should not be in the queue, if a similar event is already enqueued.
//
PowerPolSingularEventMask = PwrPolS0IdlePolicyChanged |
//
// A device could have multiple wake interrupts that could each fire
// this event.
//
PwrPolWakeInterruptFired,
PwrPolNull = 0xFFFFFFFF,
};
//
// Bit packed ULONG.
//
union FxPwrPolStateInfo {
struct {
//
// Indicates whether the state is open to all events
//
ULONG QueueOpen : 1;
//
// Bit of events we know we can drop in this state
//
ULONG KnownDroppedEvents : 31;
} Bits;
struct {
//
// Maps to the same bit location as QueueOpen. Since we start
// KnownDroppedEvents at the next bit, start our bits by at the next
// bit as well.
//
ULONG Reserved : 1;
//
// These are defined so that we can easily tell in the debugger what
// each set bit in KnownDroppedEvents maps to in the FxPowerPolicyEvent
// enum
//
ULONG PwrPolStartKnown : 1;
ULONG PwrPolStopKnown : 1;
ULONG PwrPolSxKnown : 1;
ULONG PwrPolS0Known : 1;
ULONG PwrPolPowerDownKnown : 1;
ULONG PwrPolPowerUpKnown : 1;
ULONG PwrPolPowerDownIoStoppedKnown : 1;
ULONG PwrPolPowerUpHwStartedKnown : 1;
ULONG PwrPolWakeArrivedKnown : 1;
ULONG PwrPolWakeSuccessKnown : 1;
ULONG PwrPolWakeFailedKnown : 1;
ULONG PwrPolIoPresentKnown : 1;
ULONG PwrPolPowerTimeoutExpiredKnown : 1;
ULONG PwrPolS0IdlePolicyChangedKnown : 1;
ULONG PwrPolSurpriseRemoveKnown : 1;
ULONG PwrPolUsbSelectiveSuspendCallbackKnown : 1;
ULONG PwrPolUsbSelectiveSuspendCompletedKnown : 1;
ULONG PwrPolPowerDownFailedKnown : 1;
ULONG PwrPolPowerUpFailedKnown : 1;
} BitsByName;
};
struct POWER_POLICY_EVENT_TARGET_STATE {
FxPowerPolicyEvent PowerPolicyEvent;
WDF_DEVICE_POWER_POLICY_STATE TargetState;
EVENT_TRAP_FIELD
};
typedef const POWER_POLICY_EVENT_TARGET_STATE* CPPOWER_POLICY_EVENT_TARGET_STATE;
typedef
WDF_DEVICE_POWER_POLICY_STATE
(*PFN_POWER_POLICY_STATE_ENTRY_FUNCTION)(
FxPkgPnp* This
);
typedef struct POWER_POLICY_STATE_TABLE {
//
// Framework internal function to handle the transition into this state
//
PFN_POWER_POLICY_STATE_ENTRY_FUNCTION StateFunc;
//
// First state transition out of this state
//
POWER_POLICY_EVENT_TARGET_STATE FirstTargetState;
//
// Other state transitions out of this state if FirstTargetState is not
// matched. This is an array where we expect the final element to be
// { PwrPolNull, WdfDevStatePwrPolNull }
//
CPPOWER_POLICY_EVENT_TARGET_STATE OtherTargetStates;
//
// Whether we allow transitions out of this state that are not D state
// related events, ie if this is a green dot state, TRUE, if this is a red
// dot state, FALSE. D state events (PwrPolPowerUp, PwrPolPowerDown)
// are never affected by the queue state and are always processed.
//
FxPwrPolStateInfo StateInfo;
} *PPOWER_POLICY_STATE_TABLE;
typedef const POWER_POLICY_STATE_TABLE* CPPOWER_POLICY_STATE_TABLE;
typedef
WDF_DEVICE_POWER_POLICY_STATE
(*PFN_NOT_POWER_POLICY_OWNER_STATE_ENTRY_FUNCTION)(
FxPkgPnp* This
);
typedef struct NOT_POWER_POLICY_OWNER_STATE_TABLE {
//
// The current power policy state that this entry applies to
//
WDF_DEVICE_POWER_POLICY_STATE CurrentTargetState;
//
// Framework internal function to handle the transition into this state
//
PFN_NOT_POWER_POLICY_OWNER_STATE_ENTRY_FUNCTION StateFunc;
//
// Only state transition out of this state
//
CPPOWER_POLICY_EVENT_TARGET_STATE TargetStates;
UCHAR TargetStatesCount;
BOOLEAN QueueOpen;
} *PNOT_POWER_POLICY_OWNER_STATE_TABLE;
typedef const NOT_POWER_POLICY_OWNER_STATE_TABLE* CPNOT_POWER_POLICY_OWNER_STATE_TABLE;
#if FX_STATE_MACHINE_VERIFY
#define MAX_PWR_POL_STATE_ENTRY_FN_RETURN_STATES (5)
struct PWR_POL_STATE_ENTRY_FUNCTION_TARGET_STATE {
//
// Return value from state entry function
//
WDF_DEVICE_POWER_POLICY_STATE State;
//
// type of device the returning state applies to
//
FxStateMachineDeviceType DeviceType;
//
// Info about the state transition
//
PSTR Comment;
};
struct PWR_POL_STATE_ENTRY_FN_RETURN_STATE_TABLE {
//
// array of state transitions caused by state entry function
//
PWR_POL_STATE_ENTRY_FUNCTION_TARGET_STATE TargetStates[MAX_PWR_POL_STATE_ENTRY_FN_RETURN_STATES];
};
typedef const PWR_POL_STATE_ENTRY_FN_RETURN_STATE_TABLE* CPPWR_POL_STATE_ENTRY_FN_RETURN_STATE_TABLE;
#endif // FX_STATE_MACHINE_VERIFY
// @@SMVERIFY_SPLIT_END
enum FxPowerPolicyConstants {
FxPowerPolicyNoTimeout = 0,
FxPowerPolicyDefaultTimeout = 5000, // Timeout in milliseconds
};
enum CancelIrpCompletionOwnership {
CancelOwnershipUnclaimed = 0,
CancelOwnershipClaimed = 1,
};
enum FxPowerPolicySxWakeSettingsFlags {
FxPowerPolicySxWakeDeviceEnabledFlag = 0x1,
FxPowerPolicySxWakeChildrenArmedFlag = 0x2,
};
struct PolicySettings {
PolicySettings()
{
WmiInstance = NULL;
DxState = PowerDeviceD3;
Enabled = Overridable = Set = Dirty = FALSE;
}
~PolicySettings();
//
// Dx state to put the device in when the policy is applied
//
DEVICE_POWER_STATE DxState;
FxWmiInstanceInternal* WmiInstance;
BOOLEAN Enabled;
BOOLEAN Overridable;
BOOLEAN Set;
BOOLEAN Dirty;
};
typedef struct _POX_SETTINGS {
PFN_WDFDEVICE_WDM_POST_PO_FX_REGISTER_DEVICE
EvtDeviceWdmPostPoFxRegisterDevice;
PFN_WDFDEVICE_WDM_PRE_PO_FX_UNREGISTER_DEVICE
EvtDeviceWdmPrePoFxUnregisterDevice;
PPO_FX_COMPONENT Component;
PPO_FX_COMPONENT_ACTIVE_CONDITION_CALLBACK ComponentActiveConditionCallback;
PPO_FX_COMPONENT_IDLE_CONDITION_CALLBACK ComponentIdleConditionCallback;
PPO_FX_COMPONENT_IDLE_STATE_CALLBACK ComponentIdleStateCallback;
PPO_FX_POWER_CONTROL_CALLBACK PowerControlCallback;
PVOID PoFxDeviceContext;
} POX_SETTINGS, *PPOX_SETTINGS;
class IdleTimeoutManagement {
private:
//
// This member is used to control whether or not the idle timeout is
// determined by the power manager when running on Windows 8 and above.
// The value of this member is some combination of the flags defined below.
//
LONG volatile m_IdleTimeoutStatus;
//
// Flags for the m_IdleTimeoutStatus member
//
// IdleTimeoutStatusFrozen - This flag implies that the decision on
// whether the power manager determines the idle timeout is "frozen"
// and can no longer be changed. The decision is frozen during start
// IRP completion processing, just before WDF registers with the
// power manager.
//
// IdleTimeoutSystemManaged - This flag implies that the power manager
// determines the idle timeout on Windows 8 and above. If this flag
// is not set, the idle timeout specified by the client driver is
// used.
//
// IdleTimeoutPoxSettingsSpecified - This flag implies that the client
// driver has already specified the settings that need to be used
// when registering with the power framework. This flag is used to
// track that the settings are not specified more than once.
//
enum IdleTimeoutStatusFlag {
IdleTimeoutStatusFrozen = 0x00000001,
IdleTimeoutSystemManaged = 0x00000002,
IdleTimeoutPoxSettingsSpecified = 0x00000004,
};
//
// Result returned by the UpdateIdleTimeoutStatus() method
//
enum IdleTimeoutStatusUpdateResult {
//
// Flags were sucessfully updated
//
IdleTimeoutStatusFlagsUpdated,
//
// The flag we were trying to set was already set
//
IdleTimeoutStatusFlagAlreadySet,
//
// It is too late to set the flag. The flags have already been frozen.
// Flags are frozen the first time a device is started.
//
IdleTimeoutStatusFlagsAlreadyFrozen,
//
// Flags are being set by multiple threads in parallel. This is not
// supported.
//
IdleTimeoutStatusFlagsUnexpected
};
//
// This member contains the client driver's settings that will be used when
// we register with the power manager on Windows 8 and above.
//
PPOX_SETTINGS m_PoxSettings;
private:
IdleTimeoutStatusUpdateResult
UpdateIdleTimeoutStatus(
__in IdleTimeoutStatusFlag Flag
);
CfxDevice *
GetDevice(
VOID
);
public:
IdleTimeoutManagement(
VOID
) : m_IdleTimeoutStatus(0),
m_PoxSettings(NULL)
{
}
~IdleTimeoutManagement(
VOID
)
{
BYTE * buffer = NULL;
ULONG poxSettingsOffset;
if (NULL != m_PoxSettings) {
buffer = (BYTE*) m_PoxSettings;
//
// In the function FxPkgPnp::AssignPowerFrameworkSettings, we had
// allocated a buffer which we need to free now. Note that
// m_PoxSettings does not necessarily point to the beginning of the
// buffer. It points to the POX_SETTINGS structure in the buffer,
// which may or may not be in the beginning. If it is not in the
// beginning, figure out where the beginning of the buffer is.
//
if (m_PoxSettings->Component != NULL) {
//
// The computation below won't overflow because we already
// performed this computation successfully using safeint
// functions in FxPkgPnp::AssignPowerFrameworkSettings.
//
poxSettingsOffset =
(sizeof(*(m_PoxSettings->Component->IdleStates)) *
(m_PoxSettings->Component->IdleStateCount)) +
(sizeof(*(m_PoxSettings->Component)));
}
else {
poxSettingsOffset = 0;
}
//
// Move to the beginning of the buffer
//
buffer = buffer - poxSettingsOffset;
//
// Free the buffer
//
MxMemory::MxFreePool(buffer);
}
}
static
BOOLEAN
_SystemManagedIdleTimeoutAvailable(
VOID
);
NTSTATUS
UseSystemManagedIdleTimeout(
__in PFX_DRIVER_GLOBALS DriverGlobals
);
VOID
FreezeIdleTimeoutManagementStatus(
__in PFX_DRIVER_GLOBALS DriverGlobals
);
BOOLEAN
UsingSystemManagedIdleTimeout(
VOID
);
NTSTATUS
CommitPowerFrameworkSettings(
__in PFX_DRIVER_GLOBALS DriverGlobals,
__in PPOX_SETTINGS PoxSettings
);
BOOLEAN
DriverSpecifiedPowerFrameworkSettings(
VOID
);
PPOX_SETTINGS
GetPowerFrameworkSettings(
VOID
)
{
return m_PoxSettings;
}
};
struct IdlePolicySettings : PolicySettings {
IdlePolicySettings(
VOID
) : PolicySettings()
{
WakeFromS0Capable = FALSE;
UsbSSCapable = FALSE;
PowerUpIdleDeviceOnSystemWake = FALSE;
UsbSSCapabilityKnown = FALSE;
}
//
// TRUE if the device capable of waking from S0
//
BOOLEAN WakeFromS0Capable;
//
// This member is meaningful only if the WakeFromS0Capable member (above) is
// TRUE. The WakeFromS0Capable member indicates whether or not wake-from-S0
// is currently enabled. If wake-from-S0 is currently enabled, the
// UsbSSCapable member indicates whether the wake-from-S0 support is generic
// or USB SS specific. If wake-from-S0 is not enabled, the UsbSSCapable
// member is ignored.
//
BOOLEAN UsbSSCapable;
//
// TRUE if we know whether the device supports generic wake or USB SS wake.
// This value is initialized to FALSE and remains FALSE until the first time
// that the driver specifies S0-idle settings with an idle capability value
// of IdleCanWakeFromS0 or IdleUsbSelectiveSuspend. When the driver
// specifies one of these idle capabilities, this value is set to TRUE and
// remains TRUE for the lifetime of the device.
//
BOOLEAN UsbSSCapabilityKnown;
//
// TRUE if idle enabled device should be powered up even when idle,
// when resuming from Sx
//
BOOLEAN PowerUpIdleDeviceOnSystemWake;
//
// Member to manage interactions with the power manager for S0-idle support
// on Win8 and above
//
IdleTimeoutManagement m_TimeoutMgmt;
};
struct WakePolicySettings : PolicySettings {
WakePolicySettings(
VOID
) : PolicySettings()
{
ArmForWakeIfChildrenAreArmedForWake = FALSE;
IndicateChildWakeOnParentWake = FALSE;
}
//
// TRUE if the device should arm for wake when one or more children are
// armed for wake.
//
BOOLEAN ArmForWakeIfChildrenAreArmedForWake;
//
// TRUE if the device should propagate the wake status to its children.
//
BOOLEAN IndicateChildWakeOnParentWake;
};
struct FxPowerPolicyOwnerSettings : public FxStump {
friend FxPowerPolicyMachine;
public:
FxPowerPolicyOwnerSettings(
__in FxPkgPnp* PkgPnp
);
~FxPowerPolicyOwnerSettings(
VOID
);
_Must_inspect_result_
NTSTATUS
Init(
VOID
);
VOID
CleanupPowerCallback(
VOID
);
VOID
IncrementChildrenArmedForWakeCount(
VOID
)
{
InterlockedIncrement(&m_ChildrenArmedCount);
}
VOID
DecrementChildrenArmedForWakeCount(
VOID
)
{
InterlockedDecrement(&m_ChildrenArmedCount);
}
protected:
static
MdCallbackFunctionType
_PowerStateCallback;
public:
FxPowerIdleMachine m_PowerIdleMachine;
FxPoxInterface m_PoxInterface;
FxPowerDeviceArmWakeFromS0 m_DeviceArmWakeFromS0;
FxPowerDeviceArmWakeFromSx m_DeviceArmWakeFromSx;
FxPowerDeviceDisarmWakeFromS0 m_DeviceDisarmWakeFromS0;
FxPowerDeviceDisarmWakeFromSx m_DeviceDisarmWakeFromSx;
FxPowerDeviceWakeFromS0Triggered m_DeviceWakeFromS0Triggered;
FxPowerDeviceWakeFromSxTriggered m_DeviceWakeFromSxTriggered;
FxUsbIdleInfo* m_UsbIdle;
FxPkgPnp* m_PkgPnp;
WakePolicySettings m_WakeSettings;
IdlePolicySettings m_IdleSettings;
//
// Nibble packed structure. Each D state is encoded 4 bits. The S state is
// used as the "index" within the ULONG. PowerSystemUnspecified is the
// first 4 bits of the first byte, etc. etc. ...
//
ULONG m_SystemToDeviceStateMap;
//
// The number of children who are in the D0 state. If this count is > 0,
// then this parent cannot idle out while in S0. Note that each child also
// has an explicit call to PowerReference against this device which is used
// to control the idle timer for this device.
//
ULONG m_ChildrenPoweredOnCount;
//
// The number of children who are currently armed for wake. This count
// can be used by the the wake owner to determine whether wake should be
// enabled or not for a parent stack if arming for wake depends on
// children being armed for wake.
//
LONG m_ChildrenArmedCount;
//
// The status of the last wait wake IRP to complete in the stack
//
NTSTATUS m_WaitWakeStatus;
//
// Dx state to put the device into when an Sx irp arrives and the device is
// not armed for wake from Sx. DEVICE_POWER_STATE values are used.
//
BYTE m_IdealDxStateForSx;
//
// Track power requests to assert if someone other than this driver sent it
// and to determine if this driver has received the requested irp (to catch
// someone above completing irp w/o sending to this driver)
//
BOOLEAN m_RequestedPowerUpIrp;
BOOLEAN m_RequestedPowerDownIrp;
BOOLEAN m_RequestedWaitWakeIrp;
//
// Tracks wake event being dropped
//
BOOLEAN m_WakeCompletionEventDropped;
BOOLEAN m_PowerFailed;
//
// Indicates whether we can cause paging I/O by writing to the registry
//
BOOLEAN m_CanSaveState;
//
// Guard to stop children from powering up while the parent is in Dx or
// about to transition into Dx.
//
BOOLEAN m_ChildrenCanPowerUp;
//
// TRUE if our device caused the machine to wake up. Access to this value
// is not synchronized between the parent and PDO. The parent sets it to
// TRUE upon successful completion of the WW irp and cleared after
// EvtDeviceDisarmWakeFromSx. If a PDO's WW IRP is completed within this
// window, the PDO's WW IRP will have PoSetSystemWake called on it. It is
// acceptable if the PDO's WW IRP completion races with the clearing of the
// value and is not set as a source of wake.
//
BOOLEAN m_SystemWakeSource;
protected:
PCALLBACK_OBJECT m_PowerCallbackObject;
PVOID m_PowerCallbackRegistration;
LONG m_WaitWakeCancelCompletionOwnership;
};
//
// This type of union is done so that we can
// 1) shrink the array element to the smallest size possible
// 2) keep types within the structure so we can dump it in the debugger
//
union FxPowerPolicyMachineStateHistory {
struct {
WDF_DEVICE_POWER_POLICY_STATE State1 : 16;
WDF_DEVICE_POWER_POLICY_STATE State2 : 16;
WDF_DEVICE_POWER_POLICY_STATE State3 : 16;
WDF_DEVICE_POWER_POLICY_STATE State4 : 16;
WDF_DEVICE_POWER_POLICY_STATE State5 : 16;
WDF_DEVICE_POWER_POLICY_STATE State6 : 16;
WDF_DEVICE_POWER_POLICY_STATE State7 : 16;
WDF_DEVICE_POWER_POLICY_STATE State8 : 16;
} S;
USHORT History[FxPowerPolicyEventQueueDepth];
};
struct FxPowerPolicyMachine : public FxThreadedEventQueue {
FxPowerPolicyMachine(
VOID
);
~FxPowerPolicyMachine(
VOID
);
VOID
UsbSSCallbackProcessingComplete(
VOID
);
_Must_inspect_result_
NTSTATUS
InitUsbSS(
VOID
);
VOID
SetWaitWakeUnclaimed(
VOID
)
{
m_Owner->m_WaitWakeCancelCompletionOwnership = CancelOwnershipUnclaimed;
}
BOOLEAN
CanCompleteWaitWakeIrp(
VOID
)
{
//
// We have 2 potential call sites racing on trying to complete the wait
// wake irp. The first is the cancelling call site. The other is the
// irp's completion routine. What we want is for the *2nd* (and last)
// call site to actually complete the irp. This is why we check to see
// if the result of the exchange is that the ownership is already claimed
// (and not unclaimed as one might first be led to think).
//
if (InterlockedExchange(&m_Owner->m_WaitWakeCancelCompletionOwnership,
CancelOwnershipClaimed) == CancelOwnershipClaimed) {
return TRUE;
}
else {
return FALSE;
}
}
public:
FxPowerPolicyEvent m_Queue[FxPowerPolicyEventQueueDepth];
FxPowerPolicyMachineStateHistory m_States;
FxPowerPolicyOwnerSettings* m_Owner;
union {
ULONG m_SingularEventsPresent;
union {
//
// These are defined so that we can easily tell in the debugger what
// each set bit in m_SingularEventsPresent maps to in the
// FxPowerPolicyEvent enum.
//
ULONG PwrPolStartKnown : 1;
ULONG PwrPolStopKnown : 1;
ULONG PwrPolSxKnown : 1;
ULONG PwrPolS0Known : 1;
ULONG PwrPolPowerDownKnown : 1;
ULONG PwrPolPowerUpKnown : 1;
ULONG PwrPolPowerDownIoStoppedKnown : 1;
ULONG PwrPolPowerUpHwStartedKnown : 1;
ULONG PwrPolWakeArrivedKnown : 1;
ULONG PwrPolWakeSuccessKnown : 1;
ULONG PwrPolWakeFailedKnown : 1;
ULONG PwrPolIoPresentKnown : 1;
ULONG PwrPolPowerTimeoutExpiredKnown : 1;
ULONG PwrPolS0IdlePolicyChangedKnown : 1;
ULONG PwrPolSurpriseRemoveKnown : 1;
ULONG PwrPolUsbSelectiveSuspendCallbackKnown : 1;
ULONG PwrPolUsbSelectiveSuspendCompletedKnown : 1;
ULONG PwrPolPowerDownFailedKnown : 1;
ULONG PwrPolPowerUpFailedKnown : 1;
} m_SingularEventsPresentByName;
};
};
#endif // _FXPOWERPOLICYSTATEMACHINE_H_