"Modern" standby and power off the display(s)

Windows 8 introduced a new power saving mode called connected standby. In Windows 10, this was extended and re-named “modern” standby. Some Microsoft documents refer to it as “S0 low-power idle mode” or “Always On / Always Connected”. The new mode was initially used on the Microsoft Surface range and subsequently seems to be becoming more common on other high-end laptop such as the Dell XPS.

Behind the scenes, the new power mode works differently to the normal S1-S4 power states. Power saving starts when the display turns off and is transparent to applications.

Traditionally, usermode apps could use the SetSuspendState() API to suspend (S1-S3) or hibernate (S4) the PC. However, this no longer works and attempting to suspend will fail with ERROR_NOT_SUPPORTED. A workaround is to turn off the display directly. Usermode apps do this with:

SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM) 2);

A problem with this approach is that it can only be used by applications that have access to the display. It won’t work for services running in session 0 due to session 0 isolation.

In the past, the display could be powered down directly with:

IOCTL_VIDEO_SET_OUTPUT_DEVICE_POWER_STATE - Not available in Vista and later

IOCTL_VIDEO_SET_POWER_MANAGEMENT - Not available in Win2000 and later

The only other alternative I can find is to write a video filter and use DxgkDdiSetPowerState. This seems like massive overkill.

Please, is there a simpler way to turn off the display?

Jim

is there a simpler way to turn off the display

No. And as I understand it this is by design.

The issue of display blanking is larger than, and only tangentially related to, Modern Standby.

Check this thread from 2018, where we talk about the issue of display blanking in detail.

Peter

ETA: I qualified my statement to clarify that I do not have definitive knowledge that the ability to turn-off the display has been eliminated “by design”… rather, this is what I understand to be the case from discussions with various folks over the years.

Thank you.

I never really liked the idea of turning off the display as a proxy to get to the “modern” standby state anyway. It seems strange Microsoft didn’t provide a better alternative?

May be I missed something? There must be a better way to standby such a system, even if I need to write a small driver?

NB: On further investigation, the Microsoft PwrTest tool seems to achieve this by installing a virtual button driver and then pressing the virtual “sleep” button.

Jim

It’d probably be best if you told us what you’re ACTUALLY trying to achieve. Your first post specifically asked about turning off the display. That’s the question I answered. Turning off the display is absolutely, positively, not the same thing as Modern Standby. And turning off the display won’t GET you to Modern Standby.

So… What is it that you’re trying to achieve? And if you say “put the system into Standby” I’m going to ask you (a) why, and (b) what you mean by that, in relation to Modern Standby, in which the system’s not going to leave S0 in any case.

Peter

Why would any UM or KM component that any of use might develop have a legitimate use for changing the power state of the machine contrary to the policies established by the user who owns it?

What is the best way to trigger “modern” standby from user mode (or failing that, from kernel mode)? Explanation: Systems that support modern standby don’t support S1-S3. This means that if software wants to save power it is forced to use S4 instead. This is undesirable because S4 has a long resume time and frankly defeats the point of modern standby. In the absence of a better method, turning off the display certainly does seem to trigger modern standby (it takes a few seconds for the system state to change). This is imperfect but works. Unfortunately, services running in session 0 cannot even do this because they are isolated from the display. Why would software want to do this? There are lots of scenarios where it is desirable to have finer control over sleep/wake than provided by the built in power management engine. This used to be easily achieved via SetSuspendState() but that doesn’t work now for the reasons above. Intriguingly, the POWER_ACTION enum in the SDK/DDK has a new PowerActionDisplayOff value. This isn’t documented. However, so far, all attempts to get this to work via NtInitiatePowerAction() have failed. Jim

As a user of a computer, I’m not sure that I would agree that there are lots of scenarios where I don’t want my machine to behave in the way that I configured it. Do you have an example?

Please remember, the user must install any software too. The user (or owner) is still in ultimate charge. Examples: PC functioning as remote data logger, IoT device, large corporate IT user who wants finer control of power management than available with built in power engine.

I do no doubt that you have a legit need to do this.

Like you, I’m not sure how you DO it these days. When the system is configured for connect standby, even the option on the power menu is gone. Hmmmmm…

Perhaps the solution lies in configuring the system power profile(s) to do what you want “automatically”? Like, for example, switching the system to an ultra-short wait, even when on AC power?

In case you’re not aware: Display on/Display off is/was a proxy for user presence while the whole “user presence” detection stuff was being sorted out on Windows. And as we noted before, there are numerous ramifications to arbitrarily blanking the display.

I like the “virtual button” idea, too…. There’s got to be a way to do this via ACPI.

So if I want my PC to shut things down quickly to save power, I configure it to do so;
And if I want my PC to stay on all of the time and to waste all of the power it can, I configure it to do so;
And if I want something in between in install your software? I don’t mean to be flippant, but what kind of finer grained control are your thinking about? The inbox policies have just about all of the granularity that anyone could wish for - which is why they had to create the simplified power policies

I think you need to think beyond the standard office PC user scenario. The built-in power management engine is fine when the user is present and in control of their own PC. However, it only goes so far - for example, consider a Windows PC configured for some periodic task where it must automatically wake-up (on time), perform some fixed length task and then suspend again (to save power). This cannot be done with the built-in policies because they a based on the concept of the user being present/idle. Previously, this could be easily achieved using a combination of SetWaitableTimer() and SetSuspendState(). However, SetSuspendState() is broken on a “modern” standby system and can no longer sleep the PC.

After much research, I can find two methods to trigger a “modern” system to standby:

  1. Simulate a sleep button action - requires a fake HID device
  2. Turn off the display - Difficult from session 0

Neither of these methods is ideal because, unlike SetSuspendState() they don’t directly confirm success and a secondary method must be used to determine if the operation actually succeeded.

To my mind, the root cause of this problem is that MS decided to treat “modern” standby as a new special case that is distinct from traditional sleep/hibernate. As such, SetSuspendState() doesn’t work and traditional methods to detect suspend/resume don’t work either. We must now use new API’s such as PowerRegisterSuspendResumeNotification() or RegisterSuspendResumeNotification() instead. In other words, traditional apps are oblivious to “modern” standby unless the use the new APIs.

At this point, the most reliable approach I have found to trigger standby when nobody is logged on is to launch a process into the Winlogon desktop and use this to turn off the display. This works but has potential security concerns and is a really poor substitute for the original and very simple SetSuspendState() method. It seems crazy to me that such a convoluted method is required.

I would be very grateful for any other ideas on how to reliably trigger “modern” standby.

The most detailed explanation I can find for this is in the following MS document. Regrettably, this is no longer available on their website. This is what led me to the conclusion that turning off the display was a legit route to trigger “modern” standby. My experiments have confirmed this:

https://web.archive.org/web/20121012045029/http://msdn.microsoft.com/en-us/library/windows/hardware/jj248729.aspx

Jim

Thanks for explaining further. I’m still confused though. Even on desktop Windows SKUs, it is possible to configure the machine to wake to perform a scheduled task or service action without any special software. usually, the display does not even turn on when this happens, and the hardware that does power on will power down shortly after the work is complete.

This is much more obvious on server SKUs where the display (if there is one) is usually powered down

It is certainly true that the task scheduler can be used to wake-up and perform a task at a regular or known interval. However, there are several drawbacks to this: Firstly, in automatic wake-up the screen does not turn on. This solution is therefore unsuitable for PCs that display an information dashboard or similar. Secondly, automatic wake-up will (by default) automatically return to the previous (sleep) state after a default timeout. This is 2 minutes by default. This can be changed but is another complication. Lastly, the task scheduler approach isn’t very flexible if frequent wake-up is required on an indeterminate basis - for example, a lab sequencer that must perform a sequence of operations at intervals which depend on the stage in the sequence. Of course, these are specific examples, but all were previously easy using a combination of SetSuspendState() and SetWaitableTimer().

Now, on systems with “modern” standby we must go around the houses to achieve the same thing.

… don’t even get me started on what this means for services running in session 0. The Desktop Activity Moderator (DAM) component suspends desktop applications during “modern” standby and heavily throttles services. Services do not receive notification that the system is going into “modern” standby (via SERVICE_ACCEPT_POWEREVENT) and thus cannot change their behavior during this time. Some sources suggest using PowerRegisterSuspendResumeNotification() instead. This works fine for desktop applications but doesn’t work for services. A careful reading of the DAM documentation confirms this is because “strictly” the service is not being suspended, so the OS doesn’t notify it. For now, it seems services cannot find out if the PC is entering/resuming from “modern” standby.

The whole situation around idling in S0 (“Modern Standby”) is very much a work in progress:

“Please use F-States”… “Wait, F-States don’t really get you anything on ‘ordinary’ systems, so never mind”, “What’s more important is to control the power consumption when a device is active, so please use P-States”, “Wait, not THOSE (ACPI) P-States… OUR P-States”, “Yeah, never mind, just idle your device when it’s not in use… we’ve got a cool name for that now, it’s RTD3”, “Wait… what you should REALLY do is opt-in for DFX and we’ll send you D-IRPs, without any S-IRP being involved”, “Wait… we changed the default, so you don’t have to opt-in to DFX anymore, but you DO have to opt-out”…

I’m not saying the problem is easy to solve, nor am I saying the work isn’t evolving in a useful direction; It’s not (easy to solve), and it is (evolving in a useful direction). I’m just saying that, as has become traditional over the past many years, the communication with the driver development community has been much less than good. In fact, it’s downright sucked. So, it’s really, really, hard for folks to know what’s today’s best practice or what “the right thing to do” is this week… and the fullness of the architecture/concept (including such little details as to how to transition the system into the all-new-and-improved equivalent of S3 or how services or desktop apps interact with this new state) is… shall we say… “unclear” at best.

Maybe there’ll be a presentation in Chinese on this topic at the next WinHEC, that’ll be held in ShenZhen I’m sure.

Peter