Geoff Chappell - Software Analyst
The WIN32_POWERSTATE_PARAMETERS (formally _WIN32_POWERSTATE_PARAMETERS) is a structure that the kernel passes to WIN32K.SYS (or, if only in principle, whoever else registered instead) to provide for notification of significant events in the kernel’s changing of power state.
Microsoft is known (see below for sources) to define the pointer type PKWIN32_POWERSTATE_PARAMETERS. Note the K, presumaby for kernel.
Even among undocumented structures, the WIN32_POWERSTATE_PARAMETERS is unusually obscure. Except for what looks to be known from leaked source code and then recirculated as research, Microsoft’s name for this enumeration, let alone for any of its members, was unknown for decades—and then Microsoft disclosed the whole of it twice.
First is a C-language definition in the NTOSP.H which Microsoft published with the Windows Driver Kit (WDK) for the original and 1511 releases of Windows 10. Publication of this header was apparently an oversight. Though it is chock full of previously undisclosed definitions for kernel-mode programming, it is supplied in a subdirectory (named “minwin”) of a directory named “um” as if to suggest user-mode programming. Mistake or not, this disclosure has not been repeated in later kits.
The second disclosure is in type information from symbol files for a driver named NetAdapterCx.sys. Starting with the 1803 release of Windows 10, the symbol files for this driver, as made available by Microsoft at its public symbol server, are private symbol files. They have type information for the WIN32_POWERSTATE_PARAMETERS from the driver’s inclusion of NTOSP.H.
That the WIN32_POWERSTATE_PARAMETERS are shared between separate executable modules might lend stability, but the intended modules are very much tied to the Windows version, one by definition, being the kernel, and the other for being so important to Windows in real-world use that its use with a mismatched kernel is all but unthinkable. The PsEstablishWin32Callouts function that registers the routines for the kernel to call has frequently changed its prototype, and so it should not surprise that what’s shared through this interface changes too.
That said, the structure is small: the only changes have been that one member has been removed and another appended. Moreover, all members are simple enough that the structure is the same for both 32-bit and 64-bit Windows.
Version | Size |
---|---|
5.1 to 5.2 | 0x18 |
6.0 to 6.3 | 0x14 |
10.0 and higher | 0x18 |
Microsoft’s names for the WIN32_POWERSTATE_PARAMETERS and for its members are known with certainty only for some versions of Windows 10, as described above.
Offset | Definition | Versions |
---|---|---|
0x00 |
BOOLEAN Promotion; |
5.1 and higher |
0x04 |
POWER_ACTION SystemAction; |
5.1 and higher |
0x08 |
SYSTEM_POWER_STATE MinSystemState; |
5.1 and higher |
0x0C |
ULONG Flags; |
5.1 and higher |
0x10 (5.1 to 5.2) | unknown BOOLEAN | 5.1 to 5.2 |
0x14 (5.1 to 5.2); 0x10 |
POWERSTATETASK PowerStateTask; |
5.1 and higher |
0x14 |
POWER_MONITOR_REQUEST_REASON RequestReason; |
10.0 and higher |
The Flags in this structure are the same as for the documented POWER_ACTION_POLICY. They take their values from the documented set of macro definitions such as POWER_ACTION_QUERY_ALLOWED through to POWER_ACTION_CRITICAL.
The byte at offset 0x10 in the early versions is provided for output when the PowerStateTask was set to 2 for input. In these versions, this value for the PowerStateTask directs the called routine to query applications and services for permission to proceed with suspending power. A non-zero byte at offset 0x10 on output means that permission has been refused.
It is here thought that the called routine is not permitted to change any members, except as noted in the preceding paragraph. When the kernel progresses through multiple calls for different values of the PowerStateTask, it does not reload any of the other members.