So, without further ado, here is the code for using SetConsoleCtrlHandler in Windows for handling console control signals.
There are a few caveats you need to think about though when implementing control handlers. For some events, there may be other handlers already registered, so your's may not get called. This happens, for instance, when using a debugger. Processes with a window message pump will also get some events through the pump that are not synchronized the process signal handler.
There are a few caveats you need to think about though when implementing control handlers. For some events, there may be other handlers already registered, so your's may not get called. This happens, for instance, when using a debugger. Processes with a window message pump will also get some events through the pump that are not synchronized the process signal handler.
/*--
User mode only.
--*/
#include "precomp.h"
HANDLE g_hControlEvent = NULL;
///// ctl event handling
BOOL WINAPI ControlHandlerCallback(
_In_ DWORD dwCtrlType)
{
HRESULT hr = S_OK;
BOOL bControlEventHandled = FALSE;
wprintf(L"got event %i\n", dwCtrlType);
switch (dwCtrlType) {
case CTRL_C_EVENT:
case CTRL_BREAK_EVENT:
if (!SetEvent(g_hControlEvent)) {
hr = HRESULT_FROM_WIN32(GetLastError());
NT_ASSERT(hr == S_OK);
}
if (S_OK == hr) {
bControlEventHandled = TRUE;
}
break;
CTRL_CLOSE_EVENT:
CTRL_LOGOFF_EVENT:
CTRL_SHUTDOWN_EVENT:
default:
break;
}
return bControlEventHandled;
} // ControlHandlerCallback
HRESULT RegisterControlHandler()
{
HRESULT hr = S_OK;
g_hControlEvent = NULL;
g_hControlEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!g_hControlEvent) {
hr = HRESULT_FROM_WIN32(GetLastError());
goto exit;
}
if (!SetConsoleCtrlHandler(ControlHandlerCallback, TRUE)) {
hr = HRESULT_FROM_WIN32(GetLastError());
goto exit;
}
wprintf(L"press ctrl+c to stop\n");
exit:
return hr;
} // RegisterControlHandler
HRESULT UnregisterControlHandler()
{
HRESULT hr = S_OK;
if (!SetConsoleCtrlHandler(ControlHandlerCallback, FALSE)) {
hr = HRESULT_FROM_WIN32(GetLastError());
goto exit;
}
if (!CloseHandle(g_hControlEvent)) {
hr = HRESULT_FROM_WIN32(GetLastError());
}
g_hControlEvent = NULL;
exit:
return hr;
} // UnregisterControlHandler
HRESULT WaitForControlEvent()
{
HRESULT hr = S_OK;
if (!g_hControlEvent) {
// called before registring
hr = E_UNEXPECTED;
goto exit;
}
if (WAIT_OBJECT_0 != WaitForSingleObject(g_hControlEvent, INFINITE)) {
hr = E_FAIL;
goto exit;
}
exit:
return hr;
} // WaitForControlEvent

No comments:
Post a Comment