Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Stop Windows shutdown from a service

Posted on 2003-03-23
5
Medium Priority
?
1,414 Views
Last Modified: 2012-05-04
Hi all experts,

I have a C application that runs as service in Windows XP. I want to be able to warn the user before the computer is being shut down and halt the shutdown if the user chooses to. FYI, the program was developed using Visual C++ using the Win32 Console Application option. I just added some codes found on the Net to make it a service and it's not an ATL COM service or anything fancy.

I know 'normal' program can use message maps to catch the WM_QUERYENDSESSION and return a false answer (not really sure though) to prevent shutdown. How can I do that with a service because services due to their nature are supposed to run silently in the background. The best I can do now (and it's really lame) is pop up a message box using the MB_SERVICE_NOTIFICATION by putting some codes under the ServiceHandler SERVICE_CONTROL_SHUTDOWN case but this hardly suffice as I can't prevent the shutdown and there's no option for the user to click Yes or No.

Is there anyway I can do this at all? Is the WM_QUERYENDSESSION message sent to services at all? Please provide source codes if possible. Points will be increased if I feel the accepted answer is thorough and, of course, solves my problem as soon as possible.
0
Comment
Question by:js_cheng
  • 3
5 Comments
 

Accepted Solution

by:
vadimtsarik earned 450 total points
ID: 8192536
The way I see the solution of the problem is as follows:

1. Your service should be setupped to be able to interact with desktop ('Allow service to interact with desktop' checkbox should be checked).

2. Your service creates a hidden normal window (to trap WM_QUERYENDSESSION) in the required desktop (there may be more the one desktops in Win2000\XP). You may probably need to use function EnumDesktops() for that.

3. Your service calls SetConsoleCtrlHandler to trap logoff events (to gracefully close hidden windows, created by the service)

This way you will be able to trap WM_QUERYENDSESSION and query for user confirmation. These are just guidelines, but I hope the idea is clear.
0
 

Author Comment

by:js_cheng
ID: 8195331
Vadimtsarik,

Thank you for your comment but it still seems a bit general there. I'm not entirely sure but I think SetConsoleCtrlHandler can't stop a shutdown from happening. It can only intercept CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, and CTRL_SHUTDOWN_EVENT to do some clean up before shutdown, something that is similar to ServiceHandler's SERVICE_CONTROL_SHUTDOWN case option.

The idea about creating a hidden windows sounds interesting though. Maybe you can explain more I can go on about doing that? I'm not very experienced when it comes to programming for Windows.

Is there anyway I can add message maps to a console program. Normal Win32 program can handle these messages and event easily thorugh message maps but I don't know how to do it in my program. Any ideas?

Thank you again.
0
 

Author Comment

by:js_cheng
ID: 8258331
I've added codes for creating a window in the service program and run it as a local system account with 'Allow service to interact with the desktop' checked. The Window Procedure funtion for this window is created to handle WM_QUERYENDSESSION and pops up a message box asking for user confirmation before returning a boolean value. Unfortunately, when opened up through the service, the window will receive the message but Windows XP does not wait for the reply. The window and message box is closed if the user does not click a button immediately. The usual not responding and end task message doesn't even appear. Why is this happening?

Please help. Thank you.
0
 
LVL 49

Assisted Solution

by:DanRollins
DanRollins earned 300 total points
ID: 8259538
>>Why is this happening?

That is exactly what is supposed to happen.  If you give it any thought at all, you would realize that.  

If no user responds to the popup, then the system must continue with the shutdown process.  And that means forceably killing the stubborn process.

Have you tried simply returning FALSE?

I can't find out if the system treats Services different in this regard, but I would not be surprised if they were treated as second-class citizens and either give a *very short* time to respond or simply closed.  Here is a reasonable explanation of why:  Imagine a standard service that cannot interact with the desktop.  If it waited for user input, it would wait forever and never let the system shutdown.  That means users who are angry at Microsoft and at your company because "the system inexplicably hangs when I try to shut down" It also means that automatic procedures such as rebooting after a critical system update would fail.  And it also means a hard reset or forced power off ... which is bad bad bad.

=-=-=-=-=-=-=-=-=-
Finally, look at the ExitWindowsEx API.... notice that it is possible to call this function and specify EWX_FORCE or EWX_FORCE or EWX_FORCEIFHUNG and that effectively overrides any WM_QUERYENDSESSION handling.... It just gives each process a chance to do immediate final cleanup.

And one last thing:  WHY ON EARTH DO YOU WNAT TO PREVENT SHUTDOWN?  This can only cause problems for anyone who uses your software.

-- Dan
0
 

Author Comment

by:js_cheng
ID: 8587379
Hi and sorry for the late response. Been busy lately.

Anyway, I've done the shoutdown thing successfully by creating a window from the service and writing my own Winproc function. Contary to Dan's remarks, it does work (to a certain extent) except that on certain machines some other programs will somehow interfere.

And Dan is right about preventing shutdown being bad bad bad. Anyone reading this should be aware that it is just bad programming practice to mess around with users computers this way (unless you want user to come after you with baseball bats :-)

Anyhow, I wanted to do it because the organization I work for requires it and we have problems with ID10T users shutting down the PC while it is doing something important. However, as a saving grace for my disruptive program, I have, as a good measure, put in a messagebox informing the user of what the PC is doing and telling the about the abortion of shutdown.

Thanks for all the useful comments. I think I'll just split the point between the two of you. A bit more to vadimtsarik for his comments about desktop (although actually there's no need for enumdesktop as there is another way of getting the current desktop).
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this post we will learn how to make Android Gesture Tutorial and give different functionality whenever a user Touch or Scroll android screen.
Although it can be difficult to imagine, someday your child will have a career of his or her own. He or she will likely start a family, buy a home and start having their own children. So, while being a kid is still extremely important, it’s also …
Starting up a Project
Loops Section Overview

579 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question