// If we don't want a message to be processed by Qt, return true and set result to // the value that the window procedure should return. Otherwise return false. bool WinShutdownMonitor::nativeEventFilter(const QByteArray& eventType, void* pMessage, long* pnResult) { Q_UNUSED(eventType); MSG* pMsg = static_cast<MSG*>(pMessage); // Seed OpenSSL PRNG with Windows event data (e.g. mouse movements and other user interactions) if (RAND_event(pMsg->message, pMsg->wParam, pMsg->lParam) == 0) { // Warn only once as this is performance-critical static bool warned = false; if (!warned) { LogPrint("%s: OpenSSL RAND_event() failed to seed OpenSSL PRNG with enough data.\n", __func__); warned = true; } } switch (pMsg->message) { case WM_QUERYENDSESSION: { // Initiate a client shutdown after receiving a WM_QUERYENDSESSION and block // Windows session end until we have finished client shutdown. StartShutdown(); *pnResult = FALSE; return true; } case WM_ENDSESSION: { *pnResult = FALSE; return true; } } return false; }
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; RECT rect; static int seeded = 0; switch (iMsg) { case WM_PAINT: hdc = BeginPaint(hwnd, &ps); GetClientRect(hwnd, &rect); DrawText(hdc, "Seeding the PRNG. Please move the mouse!", -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); EndPaint(hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } if (RAND_event(iMsg, wParam, lParam) == 1 && seeded == 0) { seeded = 1; if (RAND_write_file(filename) <= 0) MessageBox(hwnd, "Couldn't write random file!", "OpenSSL", MB_OK | MB_ICONERROR); PostQuitMessage(0); } return DefWindowProc(hwnd, iMsg, wParam, lParam); }