diff --git a/checkin_notes b/checkin_notes index 0e7f637c52..d97f02e85d 100755 --- a/checkin_notes +++ b/checkin_notes @@ -3763,3 +3763,9 @@ Eric K 12 Apr 2006 diagnostics.[Ch] configure.ac +Rom 12 Apr 2006 + - Bug Fix: Fix a crash on Win9x when leaving the screensaver and + password protection is enabled. + + client/win/ + win_screensaver.cpp, .h diff --git a/client/win/win_screensaver.cpp b/client/win/win_screensaver.cpp index b97109c818..22892177a7 100755 --- a/client/win/win_screensaver.cpp +++ b/client/win/win_screensaver.cpp @@ -45,13 +45,15 @@ #endif +static HMODULE gshUser32 = NULL; +static HMODULE gshPasswordCPL = NULL; +static VERIFYPWDPROC gspfnMyVerifyPwdProc = NULL; static MYGETLASTINPUTINFO gspfnMyGetLastInputInfo = NULL; static MYISHUNGAPPWINDOW gspfnMyIsHungAppWindow = NULL; static MYBROADCASTSYSTEMMESSAGE gspfnMyBroadcastSystemMessage = NULL; static CScreensaver* gspScreensaver = NULL; -static HMODULE gshUser32 = NULL; -const UINT WM_BOINCSFW = RegisterWindowMessage(TEXT("BOINCSetForegroundWindow")); +const UINT WM_BOINCSFW = RegisterWindowMessage(TEXT("BOINCSetForegroundWindow")); INT WINAPI WinMain( @@ -62,6 +64,11 @@ INT WINAPI WinMain( int retval; WSADATA wsdata; BOOL bIs95 = FALSE; + BOOL bIs9x = FALSE; + DWORD dwVal; + DWORD dwSize = sizeof(dwVal); + HKEY hKey; + #ifdef _DEBUG // Initialize Diagnostics when compiled for debug @@ -85,11 +92,15 @@ INT WINAPI WinMain( OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof(osvi); GetVersionEx(&osvi); + bIs9x = osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS; bIs95 = (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) && ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion == 0)); // Load dynamically linked modules gshUser32 = LoadLibrary(_T("USER32.DLL")); + if (bIs9x) { + gshPasswordCPL = LoadLibrary(_T("PASSWORD.CPL")); + } // Map function pointers if (gshUser32) { @@ -101,6 +112,14 @@ INT WINAPI WinMain( gspfnMyBroadcastSystemMessage = (MYBROADCASTSYSTEMMESSAGE) GetProcAddress(gshUser32, _T("BroadcastSystemMessageA")); } } + if (gshPasswordCPL) { + if (RegOpenKey(HKEY_CURRENT_USER , REGSTR_PATH_SCREENSAVE , &hKey) == ERROR_SUCCESS) { + if ((RegQueryValueEx(hKey, REGSTR_VALUE_USESCRPASSWORD, NULL, NULL, (BYTE *)&dwVal, &dwSize) == ERROR_SUCCESS) && dwVal) { + gspfnMyVerifyPwdProc = (VERIFYPWDPROC)GetProcAddress(gshPasswordCPL, _T("VerifyScreenSavePwd")); + RegCloseKey(hKey); + } + } + } retval = WSAStartup(MAKEWORD(1, 1), &wsdata); if (retval) { @@ -122,9 +141,14 @@ INT WINAPI WinMain( gspfnMyGetLastInputInfo = NULL; gspfnMyIsHungAppWindow = NULL; gspfnMyBroadcastSystemMessage = NULL; + gspfnMyVerifyPwdProc = NULL; // Free modules FreeLibrary(gshUser32); + if (gshPasswordCPL) { + FreeLibrary(gshPasswordCPL); + gshPasswordCPL = NULL; + } return retval; } @@ -138,8 +162,6 @@ CScreensaver::CScreensaver() { m_dwSaverMouseMoveCount = 0; m_hWnd = NULL; m_hWndParent = NULL; - m_hPasswordDLL = NULL; - m_VerifySaverPassword = NULL; m_bAllScreensSame = FALSE; m_bWindowed = FALSE; @@ -622,10 +644,6 @@ int CScreensaver::UtilGetRegStartupStr(LPCTSTR name, LPTSTR str) { // Determine if BOINC is configured to automatically start at logon/startup. // - -// Define dynamically linked to function -typedef HRESULT (STDAPICALLTYPE* MYSHGETFOLDERPATH)(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags, LPSTR pszPath); - BOOL CScreensaver::IsConfigStartupBOINC() { BOOL bRetVal; BOOL bCheckFileExists; @@ -736,6 +754,9 @@ BOOL CScreensaver::IsConfigStartupBOINC() { return bRetVal; } + + + // Desc: Create the infrastructure for thread safe acccess to the infrastructure // layer of the screen saver. // @@ -748,6 +769,9 @@ BOOL CScreensaver::CreateInfrastructureMutexes() { return TRUE; } + + + // Provide a thread-safe implementation for retrieving the current // error condition. // @@ -827,6 +851,8 @@ BOOL CScreensaver::SetError(BOOL bErrorMode, HRESULT hrError) { return bRetVal; } + + // Update the error message // VOID CScreensaver::UpdateErrorBoxText() { @@ -871,6 +897,8 @@ VOID CScreensaver::UpdateErrorBoxText() { } + + // Translate an HRESULT error code into a string that can be displayed // to explain the error. A class derived from CD3DScreensaver can // provide its own version of this function that provides app-specific @@ -955,6 +983,8 @@ BOOL CScreensaver::DestoryDataManagementThread() { } + + // Do what needs to be done to update the text that is displayed // to the user // @@ -1013,6 +1043,7 @@ DWORD WINAPI CScreensaver::DataManagementProc() { SetError(TRUE, SCRAPPERR_BOINCNOTDETECTEDSTARTUP); } } + } else { SetError(FALSE, 0); if (m_bCoreNotified) { @@ -1045,7 +1076,6 @@ DWORD WINAPI CScreensaver::DataManagementProc() { NULL ); } - } } else { // Science application has focus, and is visible. @@ -1138,6 +1168,8 @@ DWORD WINAPI CScreensaver::DataManagementProc() { } + + // This function forwards to DataManagementProc, which has access to the // "this" pointer. // @@ -1146,6 +1178,8 @@ DWORD WINAPI CScreensaver::DataManagementProcStub(LPVOID UNUSED(lpParam)) { } + + // Notifies BOINC that it has to start the screensaver in full screen mode. // VOID CScreensaver::StartupBOINC() { @@ -1328,26 +1362,6 @@ HRESULT CScreensaver::CreateSaverWindow() { // Run the screensaver graphics - may be preview, test or full-on mode // HRESULT CScreensaver::DoSaver() { - // If we're in full on mode, and on 9x, then need to load the password DLL - if (m_SaverMode == sm_full && m_bIs9x) { - // Only do this if the password is set - check registry: - HKEY hKey; - if (RegOpenKey(HKEY_CURRENT_USER , REGSTR_PATH_SCREENSAVE , &hKey) == ERROR_SUCCESS) { - DWORD dwVal; - DWORD dwSize = sizeof(dwVal); - - if ((RegQueryValueEx( - hKey, REGSTR_VALUE_USESCRPASSWORD, NULL, NULL, - (BYTE *)&dwVal, &dwSize) == ERROR_SUCCESS) && dwVal - ) { - m_hPasswordDLL = LoadLibrary(_T("PASSWORD.CPL")); - if (m_hPasswordDLL) - m_VerifySaverPassword = (VERIFYPWDPROC)GetProcAddress(m_hPasswordDLL, _T("VerifyScreenSavePwd")); - RegCloseKey(hKey); - } - } - } - // Flag as screensaver running if in full on mode if (m_SaverMode == sm_full) { BOOL bUnused; @@ -1505,7 +1519,7 @@ LRESULT CScreensaver::SaverProc( break; case WM_POWERBROADCAST: - if (wParam == PBT_APMQUERYSUSPEND && m_VerifySaverPassword == NULL) + if (wParam == PBT_APMQUERYSUSPEND && gspfnMyVerifyPwdProc == NULL) InterruptSaver(); break; } @@ -1590,12 +1604,6 @@ VOID CScreensaver::ShutdownSaver() { SystemParametersInfo(SPI_SCREENSAVERRUNNING, FALSE, &bUnused, 0); } - // Unload the password DLL (if we loaded it) - if (m_hPasswordDLL != NULL) { - FreeLibrary(m_hPasswordDLL); - m_hPasswordDLL = NULL; - } - ShutdownBOINC(); // Post message to drop out of message loop @@ -1617,16 +1625,14 @@ VOID CScreensaver::ShutdownSaver() { VOID CScreensaver::InterruptSaver() { BOOL bPasswordOkay = FALSE; - if (m_SaverMode == sm_test || - m_SaverMode == sm_full && !m_bCheckingSaverPassword - ) { + if (m_SaverMode == sm_test || m_SaverMode == sm_full && !m_bCheckingSaverPassword) { if (m_bIs9x && m_SaverMode == sm_full) { // If no VerifyPassword function, then no password is set // or we're not on 9x. - if (m_VerifySaverPassword != NULL) { + if (gspfnMyVerifyPwdProc != NULL) { m_bCheckingSaverPassword = TRUE; - bPasswordOkay = m_VerifySaverPassword(m_hWnd); + bPasswordOkay = gspfnMyVerifyPwdProc(m_hWnd); m_bCheckingSaverPassword = FALSE; @@ -1634,7 +1640,6 @@ VOID CScreensaver::InterruptSaver() { // Back to screen saving... SetCursor(NULL); m_dwSaverMouseMoveCount = 0; - return; } } diff --git a/client/win/win_screensaver.h b/client/win/win_screensaver.h index 3fdb963adc..506ceb2563 100644 --- a/client/win/win_screensaver.h +++ b/client/win/win_screensaver.h @@ -102,7 +102,7 @@ struct DISPLAY_DEVICE_FULL // Prototype for VerifyScreenSavePwd() in password.cpl, used on Win9x -typedef BOOL (PASCAL * VERIFYPWDPROC)(HWND); +typedef BOOL (WINAPI *VERIFYPWDPROC)(HWND); // Prototype for GetLastInputInto() in user32.dll, used on Win2k or better. typedef BOOL (WINAPI *MYGETLASTINPUTINFO)(PLASTINPUTINFO); @@ -113,6 +113,9 @@ typedef BOOL (WINAPI *MYISHUNGAPPWINDOW)(HWND hWnd); // Prototype for BroadcastSystemMessage() in user32.dll. typedef long (WINAPI *MYBROADCASTSYSTEMMESSAGE)(DWORD dwFlags, LPDWORD lpdwRecipients, UINT uiMessage, WPARAM wParam, LPARAM lParam); +// Prototype for SHGetFolderPath() in shlwapi.dll. +typedef HRESULT (WINAPI *MYSHGETFOLDERPATH)(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags, LPSTR pszPath); + //----------------------------------------------------------------------------- // Name: class CScreensaver @@ -215,8 +218,6 @@ protected: BOOL m_bWaitForInputIdle; // Used to pause when preview starts DWORD m_dwSaverMouseMoveCount; BOOL m_bIs9x; - HINSTANCE m_hPasswordDLL; - VERIFYPWDPROC m_VerifySaverPassword; BOOL m_bCheckingSaverPassword; BOOL m_bWindowed;