SP2 & PowerButton

  • Thread starter Thread starter Georges Berenger
  • Start date Start date
G

Georges Berenger

Hi there!

Some of you may remember that I long lamented the fact that with SP1
(with no patches), when you pressed the power button, the system
wouldn't shutdown.

Much later, Slobodan helped: with a properly set up message filter and a
proper configuration, you actually got a PBT_APMQUERYSUSPEND message
that you could react on as you wanted. All was good.

But now, with SP2, things have been "fixed". Fixed so well that I have a
problem that happens both with SP2 & XP Pro. (I guess some will tell me
then that this issue should go to an other group. I'd reply that this
issue is particularly important when building appliances, if not only
with appliances, therefore, the issue is mostly an XPe issue).

I see two (main) ways to configure the action of the power button. One
is to set it to "PowerActionNone", the other is to set it to
"PowerActionShutdown".
When you set the action to "PowerActionNone", that's what you get:
nothing. I don't even know that the button was pressed.
When you set the action to "PowerActionShutdown", that's what you get: a
shutdown. Always. And that's the issue: I can't stop the shutdown.
Wether I return BROADCAST_QUERY_DENY or not in my message filter, the
shutdown happens.

What I really want to do is detect that the button has been pressed in
some way (I don't really care how), and then, show the user a dialog.
Depending on the user's action, I then request a shutdown or not.

SP1 used to send the PBT_APMQUERYSUSPEND, and then do nothing. Which
gave me a chance to do what I wanted. Now, I either get nothing or all,
and this is not what I need.

Does anyone know either:
- how to detect that the power button has been pressed without having a
shutdown sequence started
-or-
- how to cancel a shutdown sequence.

BTW: I have configured the power management with:

SYSTEM_POWER_POLICY policy;
::CallNtPowerInformation(SystemPowerPolicyAc, NULL, 0, &policy,
sizeof(policy);
policy.PowerButton.Action = PowerActionShutdown;
policy.PowerButton.Flags = POWER_ACTION_QUERY_ALLOWED |
POWER_ACTION_UI_ALLOWED;
policy.PowerButton.EventCode = POWER_USER_NOTIFY_BUTTON;
::CallNtPowerInformation(SystemPowerPolicyAc, &policy, sizeof(policy),
&policy, sizeof(policy));

(yes, that works: if I change PowerActionShutdown to PowerActionNone, I
do not get a shutdown anymore).

Any clue?

Thanks,
-georges
 
I guess I need to stress a part of my original post: I am not sure that
the behavior I see now is buggy. I just do not know if it is:
- a bug shared between XP Pro SP2 & XPe SP2 (and possibly previous
releases of XP Pro, previous releases of XPe/MinLogin being known to be
buggy)
- a bug in my code: I would not be doing something right, and I was just
using an XPe SP1 bug to get things to work as I wanted
- a design issue: what I am trying to do shouldn't be done the way I am
trying to.

So maybe I should rephrase my post:
I want to be able to find out that the power button has been pressed, so
that I can offer the user to shutdown or not using my own GUI. Unless
the user agrees first, shutdown should not be performed (no app should
quit).
Right now, using the CallNtPowerInformation API, I am able to either get
the power button to do nothing, or to shutdown the system right away,
with no found way to stop it.

In other words, how would you detect that the power button has been
pressed to take your own customized action, without having the system
shutdown?

Thanks,
-georges
 
Hi Georges,

Some other process get and handle this message before your process receive it.
You will have to follow it trough debugger like I did long time ago and to see who snatches this message before you do. Then you can
try to circumvent this behavior in specified process. (Like Explorer).

Regards,
Slobodan
 
Slobodan said:
Hi Georges,

Some other process get and handle this message before your process receive it.
You will have to follow it trough debugger like I did long time ago and to see who snatches this message before you do. Then you can
try to circumvent this behavior in specified process. (Like Explorer).

What I see is that I get a PBT_APMQUERYSUSPEND message, followed by a
PBT_APMSUSPEND even if I returned BROADCAST_QUERY_DENY to the query
message(s). So by "this message" you mean the PBT_APMQUERYSUSPEND
message, then my app gets it. It just can't act usefully on it (that is,
cancel the shutdown).

If "this message" means some kind of lower level system message
signaling that the power button has been pressed, then it would mean
that your suggestion is to hack MinLogon itself to snatch the message.

It looks more and more that SP2 is not usable for us. :-(

-georges
 
But then Georges wouldn't receive notification?

Sorry, I'm new to this game, but I actually do not receive any notification
of any kind when the power button is pushed with SP2 (latest patches as
well). I only receive notifcation when 'standby' is chosen from the 'start'
menu. When I click 'standby' from the menu, I am able to deny it. I don't
see why hitting the power button is any different.

Just like George, I'm trying to provide a solution that will allow the user
to click 'yes' or 'no' to going into sleep, standy, hibernate, of whatever it
may be. As an additional constraint, I can't use any solutions that require
that the user running my app has admin privledges.

-Craig

ps: I noticed that DevStudio must receive some sort of notifcation when the
power button is pushed because it prompts me if I want to stop debugging my
app. If I click 'Yes' the whole computer shuts-off. If I click 'no', nothing
happens.
 
Craig said:
But then Georges wouldn't receive notification?

Sorry, I'm new to this game, but I actually do not receive any notification
of any kind when the power button is pushed with SP2 (latest patches as
well). I only receive notifcation when 'standby' is chosen from the 'start'
menu. When I click 'standby' from the menu, I am able to deny it. I don't
see why hitting the power button is any different.

Just like George, I'm trying to provide a solution that will allow the user
to click 'yes' or 'no' to going into sleep, standy, hibernate, of whatever it
may be. As an additional constraint, I can't use any solutions that require
that the user running my app has admin privledges.

-Craig

ps: I noticed that DevStudio must receive some sort of notifcation when the
power button is pushed because it prompts me if I want to stop debugging my
app. If I click 'Yes' the whole computer shuts-off. If I click 'no', nothing
happens.

My experience is that XP Pro SP2 & XPe SP2 behave differently.
The first thing you must do to get XPe or XP Pro to react, is make sure
that pressing the power button will trigger a shutdown. I do not know of
any other non-kernel level hooks/hacks that would otherwise give us the
info (directly or not) that the power button has been pressed. I would
*love* to have such a method! On XP Pro, you can use the Power Options
control panel. On XPe, you can use it too if you have included it in
your image, or you can use the code snipet of my initial post.

Then with the exact same app and the same config, I get different
messages. On XP Pro, I get a WM_QUERYENDSESSION, and later a
WM_ENDSESSION. That's most probably the messages DevStudio reacts to in
your experiments.

On XPe, I do only get WM_POWERBROADCAST + PBT_APMQUERYSUSPEND, followed
by a WM_POWERBROADCAST + PBT_APMSUSPEND.
So the action triggered when the power button press is detected is
different, and you can debug the code on XP Pro, as things will be
significantly different on XPe here. BTW, this type of differences is
very sad as it kills one of the great strengths of XPe...

Unfortunately, I can't stop the XPe shutdown process, while I am pretty
sure I could stop the XP Pro sequence, just like VisualStudio or NotePad
can.

-georges
 
Craig,
But then Georges wouldn't receive notification?

Does it need to?
I asked if he only wants to prevent the system from suspeding. If that is what he wants to, he can have the control over it using
the API.
To turn off the prevention, he can call the same API without the ES_CONTINUE falg set to reset the idle timer.
Sorry, I'm new to this game, but I actually do not receive any notification
of any kind when the power button is pushed with SP2 (latest patches as
well). I only receive notifcation when 'standby' is chosen from the 'start'
menu. When I click 'standby' from the menu, I am able to deny it. I don't
see why hitting the power button is any different.

What's your image HAL supported?
Just like George, I'm trying to provide a solution that will allow the user
to click 'yes' or 'no' to going into sleep, standy, hibernate, of whatever it
may be. As an additional constraint, I can't use any solutions that require
that the user running my app has admin privledges.

You can always have a service running with the admin priviledges to monitor anything in the system.
 
KM said:
Craig,




Does it need to?

Yes, that's precisely the point of the thread! I want the notification,
and nothing else! Please re-read the initial post...

If I set the config one way, nothing happens when the power button is
pressed. If I set the config the other way, I get a notification, and I
can't prevent the shutdown. I want the notification, so that I can do
what ever I want with it.
I asked if he only wants to prevent the system from suspeding. If that is what he wants to, he can have the control over it using
the API.
To turn off the prevention, he can call the same API without the ES_CONTINUE falg set to reset the idle timer.

Unfortunately, it doesn't work... :-(

-georges
 
Hi Georges,
Then with the exact same app and the same config, I get different
messages. On XP Pro, I get a WM_QUERYENDSESSION, and later a
WM_ENDSESSION. That's most probably the messages DevStudio reacts to in
your experiments.

On XPe, I do only get WM_POWERBROADCAST + PBT_APMQUERYSUSPEND, followed
by a WM_POWERBROADCAST + PBT_APMSUSPEND.

First on XPe with winlogon you should also get WM_QUERYENDSESSION as you hope for.
Secondly on XPP you can also catch these messages. It is just a question which "application/service" will handle and remove this
message first.

Perhaps you can see events here from debugger and figure out something based on this?
win32k!QueuePowerRequest -> win32k!xxxUserPowerCalloutWorker

Regards,
Slobodan
 
Hi Slobodan,
First on XPe with winlogon you should also get WM_QUERYENDSESSION as
you hope for.

I think the key here is "WinLogon". I have a minlogon image and do not get
WM_QUERYENDSESSION.

I have solved this problem in my case easily as I have a microcontroller that
communicates with my software and also controls the APCI power button.
This means I simply send a message to my software when the user presses the
power button on the remote control.

-Mike
 
Mike,

Just out of curiosity..
Have you tried highering (or lowering) the shutdown order range for your application?
E.g., use SetProcessShutdownParameters(3FF,0) (or even try SetProcessShutdownParameters(4FF,0) ;-) ).
http://msdn.microsoft.com/library/d...dllproc/base/setprocessshutdownparameters.asp

According to MSDN documentation: "Applications running in the system security context do not get shut down by the operating system.
They get notified of shutdown or logoff through the callback function installable via SetConsoleCtrlHandler. They also get notified
in the order specified by the dwLevel parameter."
 
Slobodan said:
Hi Georges,




First on XPe with winlogon you should also get WM_QUERYENDSESSION as you hope for.
Secondly on XPP you can also catch these messages. It is just a question which "application/service" will handle and remove this
message first.

I haven't repeated that part in my last message: I use MinLogon.
Perhaps you can see events here from debugger and figure out something based on this?
win32k!QueuePowerRequest -> win32k!xxxUserPowerCalloutWorker

? Could you elaborate?
Thanks,
-georges
 
Hi Georges,
? Could you elaborate?

No really :-(
I just think that these internal functions are called by kernel to make WM_POWERBROADCAST request to all user mode applications.
Perhaps you can intercept this from debugger and figure something out what happen next.

Regards,
Slobodan
 
KM said:
Mike,

Just out of curiosity..
Have you tried highering (or lowering) the shutdown order range for your application?
E.g., use SetProcessShutdownParameters(3FF,0) (or even try SetProcessShutdownParameters(4FF,0) ;-) ).
http://msdn.microsoft.com/library/d...dllproc/base/setprocessshutdownparameters.asp

Yes. I am currently using 0x3FF.
According to MSDN documentation: "Applications running in the system security context do not get shut down by the operating system.
They get notified of shutdown or logoff through the callback function installable via SetConsoleCtrlHandler. They also get notified
in the order specified by the dwLevel parameter."

That's true for console apps I believe, not for Win32 apps. Our shell
app is a win32 app, as if it was a console app, it would show it's ugly
console face (when I tried to use a console app as a shell app, I
couldn't get it to run without showing the console window. But that
issue is long past and we now rely on the shell app being a win32 app).

When a console app runs, it indeeds receives a message in its callback
function.

-georges
 
Georges,
That's true for console apps I believe, not for Win32 apps. Our shell
app is a win32 app, as if it was a console app, it would show it's ugly
console face (when I tried to use a console app as a shell app, I
couldn't get it to run without showing the console window. But that
issue is long past and we now rely on the shell app being a win32 app).

When a console app runs, it indeeds receives a message in its callback function.

Well.. Console apps are not a question. Although, btw, you may want to use a console app to have more control over the process.

But I think it may be true that any app running in the system security context can get notified of shutdown via
SetConsoleCtrlHandler.
Have you tried to set a callback in your shell app using the API and see if you get the notification? (I believe your shell app is
not console)
 
Back
Top