How does Windows close a program when shutting down the computer? - c++

My application throws some strange errors if you shut down the computer while my application is running.
Sometimes the message is (address) memory can not be "read", sometimes can not be "write".
Shutting down the application in the normal way doesn't generate such messages.
How can I simulate the "windows shutdown" so that I can debug my application? How can I find out what the application is trying to do that it cannot?

When Windows wants to shutdown, it sends a series of events to the application; such as WM_ENDSESSION and WM_QUIT. You can process these in the message handler you are using; in general the application will need to respond appropriately and quickly to these messages else the OS will just terminate the application anyway. I'm not sure what default processing wxwidgets offers in this regard. Hooking into these would help in diagnosing the application error itself.
There are a few things you could attempt to do;
The shutdown sequence will not be easy to simulate (if at all) - a lot happens during shutdown; the exact state and situation is difficult to simulate in it's entirety.
In terms of diagnosing the state of the application just before shutdown, you could try to process the WM_QUERYENDSESSION and respond with a FALSE to prevent it from shutting down (with newer versions of Windows you can no longer prevent the shutdown, so it may not work depending on the platform you are on).
You could also try to test the application's immediate response to WM_ENDSESSION message by sending it the WM_ENDSESSION (e.g. via a PostMessage) with the appropriate data as detailed on MSDN.
For terminal based applications;
You can also hook in the signals (SIGKILL I believe) if required. See this Microsoft reference for more detail. You can also the the SetConsoleCtrlHandler hook. But since you using a toolkit, it would be better to use the messages sent to the application already.

Related

how to handle your windows application being force closed?

if a user decides to force close my application(like through the task manager) is there a way i can quickly execute some clean up code before the application closes? i'm coding in c++ btw
It depends on how the process is instructed to close. It is possible to do this upon graceful exit, but not for anything forcefully closed.
If the process is closed via TerminateProcess or ExitProcess, you won't be able to perform any graceful cleanup. TerminateProcess is how Task Manager and utilities like Sysinternals pskill end a target process. ExitProcess is called within a process but is not typically used to exit.
If the process has a message pump on one thread (typically the first thread in the process) and no other threads running that are running code whose lifetimes are independent of activity in that thread, then a WM_QUIT message will signal that the process should close (semantically, that the app should close, your process might conceivably stick around for a while for other reasons), and you can run cleanup code upon receiving the message. Depending on your needs, in a windowed app you might consider performing cleanup operations as early as WM_CLOSE or WM_DESTROY.
If you have written code in a DLL, there are notifications that you can handle in DllMain that will allow you to perform last-chance cleanup (DLL_PROCESS_DETACH), which can potentially cover the case of a process exiting without having a message pump. However, this is not a great way to perform cleanup for code that strictly relies on any C/C++ runtime (or any other DLL), as the runtime might be unloaded first.
Last, for any graceful close where you control what runs in WinMain or main, you can always do whatever cleanup you need to do before either function returns, sending control back to the windows subsystem. This is preferred and usually safest for most application needs.
If you are using a message pump, handle the WM_QUIT message.
Also: What is the difference between WM_QUIT, WM_CLOSE, and WM_DESTROY in a windows program?
EDIT
Im sorry, I read over the fact that you want to handle termination, eg by the task manager.
This might help you though: How to catch event when Task manager kill your C++ application

Interaction with Windows rebooting/shutdown

For example we have a Win32 application which on close of main window hides to tray.
When user reboot or shutdown OS applications were closed in some way.
How to handle properly this closing event?
This is documented over on MSDN: Shutting Down.
Essentially you need a top-level window that listens for either WM_QUERYENDSESSION or WM_ENDSESSION or possibly both. You get an opportunity to perform shutdown related tasks when these messages arrive.
Applications with a window and message queue receive shutdown notifications through the WM_QUERYENDSESSION and WM_ENDSESSION messages. These applications should return TRUE to indicate that they can be terminated. Applications should not block system shutdown unless it is absolutely necessary. Applications should perform any required cleanup while processing WM_ENDSESSION. Applications that have unsaved data could save the data to a temporary location and restore it the next time the application starts. It is recommended that applications save their data and state frequently; for example, automatically save data between save operations initiated by the user to reduce the amount of data to be saved at shutdown.
If you wish to show UI during shutdown, perhaps because your app is performing critical actions that cannot survive interruption, then you can use ShutdownBlockReasonCreate.
If an application must block a potential system shutdown, it can call the ShutdownBlockReasonCreate function. The caller provides a reason string that will be displayed to the user. The reason string should be short and clear, providing the user with the information necessary to decide whether to continue shutting down the system.
Note that this process was changed dramatically from Vista. If you need to support XP then you may need code that behaves differently under XP. That topic is also covered on MSDN: Application Shutdown Changes in Windows Vista.
You should handle the System Shutdown Messages WM_QUERYENDSESSION and WM_ENDSESSION.
Shuting down should cause a SIGTERM or SIGINT be sent to you program.
You can handle this via .
Ref: http://www.cplusplus.com/reference/csignal/signal/
void my_handler (int param)
{
// clean up here
}
int main ()
{
signal(SIGINT my_handler); // try also SIGTERM
}

Working with a shut-down state of a user session on Windows?

Say, if I open a Notepad, type something in it and don't save it, then call the following API from the same user session:
ExitWindowsEx(EWX_LOGOFF, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED);
That user session will enter a "shut-down state", where OS will show an overlay window displaying a message that Notepad prevents system from logging off a user. This overlay will not go away until a user clicks "Cancel" or "Force Quit" buttons.
So two part question:
Is there any way to know which processes blocked logging-off/shut-down process?
Is there any way to cancel this user-session "shut-down state" programmatically?
PS. This state can be detected by calling GetSystemMetrics(SM_SHUTTINGDOWN);
EDIT: Contrary to the answer below, I am not trying to stop system from shutting down, nor that any user-mode process is "hung."
EDIT2: Here's a screenshot of the overlay I'm trying to cancel/close:
Question 2: "Is there any way to cancel this shut-down state programmatically?"
The short is answer is not really. And neither should you want to really stop shutdown programatically UNLESS: shutting down will result in serious data loss or significantly affect the user experience on a subsequent system start up. But to mention just one example: imagine a computer is overheating - stopping shutdown programmatically could result in a fried system (and a very irate user).
System shutdown is also not the only thing you need to monitor. There's also hibernate and suspend events (have a look at WM_POWERBROADCAST message).
That said, Windows provides a plethora of mechanisms for detecting system shutdown. For instance:
If your application has a message pump you can choose to return FALSE when Windows polls running applications to vote on WM_QUERYENDSESSION , however Windows from Vista onwards will still force a shutdown after a time-out. From Vista onwards you can (and need to) ShutdownBlockReasonCreate after returning false to WM_QUERYENDSESSION.
If your application is running as a service you can use RegisterServiceCtrHandlerEx and then SetServiceStatus to get a 3 minute shutdown extension grace by setting SERVICE_ACCEPT_PRESHUTDOWN which will get you a SERVICE_CONTROL_PRESHUTDOWN notification. Naturally, you won't receive logoff notification because a service is not affected by logoff. Pre-Vista you can register for SERVICE_CONTROL_SHUTDOWN notification.
Console applications (and gui apps as well but it does not make sense) can use SetConsoleCtrlHandler to be notified of CTRL_LOGOFF and CTRL_SHUTDOWN_EVENT.
At a much lower level one can try hooking API functions such as NTShutdown or even NtSetSystemPowerState which apparently is "the last thing called during ANY type of reboot". But I would strongly suggest not to attempt this.
That said there are ways to really strongly insist that the system should not be shutdown.
Consider the following:
1.) Try to register your application to be first in line to receive Shutdown notification. Something like:
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms686227(v=vs.85).aspx
if(!SetProcessShutdownParameters(0x4ff, 0)) // greedy highest documented System reserved FirstShutdown
{
// Fallback
if(!SetProcessShutdownParameters(0x3ff, 0)) // highest notification range for applications
{
// shouldn't happen
}
}
2.) Return FALSE on WM_QUERYENDSESSION
From Vista onwards call ShutdownBlockReasonCreate() after returning false on WM_QUERYENDSESSION.
3.) Tell Windows that you need the system to stay up and available. Have a look at
http://msdn.microsoft.com/en-us/library/windows/desktop/aa373208(v=vs.85).aspx
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED);
4.) Clean up, call ShutdownBlockReasonDestroy() on Vista onwards, and THEN shutdown the system cleanly.
You could also try the undocumented function (at least it's not on MSDN anymore) CancelShutdown in "user32.dll" which at some point (still may) used to function very much like calling shutdown.exe with the abort flag.
Your mileage may vary.
Following your edit which makes your question clearer:
If you monitor WM_QUERYENDSESSION and respond FALSE to it you can poll from your still running process for a predetermined period of time and then issue an ExitWindowsEx call with flag EWX_FORCEIFHUNG, for example on WM_ENDSESSION. Or you could actually call this pre-emptively on receiving WM_QUERYENDSESSION - the problem is: what if forcing the shutdown results in serious data loss? You're not doing the user of the system any good at that point.
Update following your comments:
How about this:
To find out blocking application:
Register your app with SetProcessShutdownParameters to be first in
line to get WM_QUERYENDSESSION.
Respond FALSE to WM_QUERYENDSESSION and on Vista onwards call
ShutdownBlockReasonCreate to buy yourself the time.
Get the first window in the chain HWND top = GetTopWindow(NULL)
Get the process ThreadId from hwnd GetWindowThreadProcessId() (compare it with your running app's ;) )
Use SendMessageTimeOut with a message to the hWnd - if you receive
no response (timeout) you may have found the blocking window. Go to step 6.
If not skip to 7.
Use OpenProcess() with the handle returned from
GetWindowThreadProcessId to get a process handle and call
GetModuleBaseName() to get the name of the hung process.
If you haven't found the hung window, enumerate the next Window with
GetNextWindow() and go back to step 4.
You can also try using the enumerate window handle technique above to find out if you can get a handle to the "hung window" overlay. Having this might give you a chance to do a send key to cancel the state. My bet is that you won't be able to access it but I haven't tried :)
Again your mileage may vary :)

Prevent Windows shutdown with custom message

VMWare Workstation does something quite cool when I try to shutdown Windows while a Virtual Machine is running:
Normally, we'd see a "This program is preventing Windows from shutting down" message instead of the new "1 Virtual Machine is in use".
How does VMWare do this? I haven't been able to find any APIs about it on Google.
You can read all about the changes introduced in Vista here. You really should read that article very carefully.
The APIs you are looking for are ShutdownBlockReasonCreate, ShutdownBlockReasonDestroy and ShutdownBlockReasonQuery. Remember that these APIs are only available on Vista/2008 server up. You'll have to implement fall back behaviour on 2000/XP.
If you need to block shutdown you call ShutdownBlockReasonCreate passing the handle to your main window and the reason as a string. This string is what is displayed in the shutdown blocked dialog, i.e. "1 virtual machine is in use" in your screenshot.
If the operation that blocks shutdown completes then you call ShutdownBlockReasonDestroy.
Note that you must still implement WM_QUERYENDSESSION to make all the pieces fit together. This is the part that actually blocks the shutdown.
On XP you should also respond to WM_ENDSESSION and if your app blocked shutdown it is polite to show a message indicating why. If you don't do so then the user is left scratching his/her head as to why the computer is ignoring the instruction to shutdown.

xmlrpc server in dll, sending signal to myself?

I'm writing some dll (on windows in MSVC++2008) which provides some functionality as xmlrpc server. To implement xmlrpc server I'm using xmlrpc-c library.
I can start xmlrpc server in some diffrent ways. More intresting are:
run method - This will run xmlrpc server forever so dll can't control until server is not terminated.
runOnce method - This will run xmlrpc server only to process one RPC. And if there is no request it will wait for that.
I can't keep control in dll for long time. I need to process some RPCs and give back control to program which is using dll. And process next RPCs when dll will get back control again.
runOnce looks ok. But there is possibility that there will be no RPCs to process and it will be waiting for one. That is unacceptable.
There is also one exception:
runOnce aborts waiting for a
connection request and returns
immediately if the process receives a
signal. Note that unless you have a
handler for that signal, the signal
will probably kill the whole process,
so set up a signal handler — even one
that does nothing — if you want to
exploit this. But before Xmlrpc-c 1.06
(June 2006), signals have no effect —
there is no way to make runOnce abort
the wait and return.
Can I use it as workaround go get back control to dll? Is it possible to send signal from dll to themself? How it works on windows?
Or maybe there is some better solution of this issue?
Signals (of the kind that makes an Xmlrpc-c library call abort early) don't exist in Windows.
Best solution is to create new thread for server.