| ... | @@ -1,415 +0,0 @@ |
| 1 | /* |
| 2 | Screen saver library by Anders Norlander <anorland@hem2.passagen.se> |
| 3 | |
| 4 | This library is (hopefully) compatible with Microsoft's |
| 5 | screen saver library. |
| 6 | |
| 7 | This is public domain software. |
| 8 | |
| 9 | */ |
| 10 | #include <windows.h> |
| 11 | #include <scrnsave.h> |
| 12 | #include <regstr.h> |
| 13 | |
| 14 | /* screen saver window class */ |
| 15 | #define CLASS_SCRNSAVE TEXT("WindowsScreenSaverClass") |
| 16 | |
| 17 | /* globals */ |
| 18 | HWND		hMainWindow = NULL; |
| 19 | BOOL		fChildPreview = FALSE; |
| 20 | HINSTANCE	hMainInstance; |
| 21 | TCHAR		szName[TITLEBARNAMELEN]; |
| 22 | TCHAR		szAppName[APPNAMEBUFFERLEN]; |
| 23 | TCHAR		szIniFile[MAXFILELEN]; |
| 24 | TCHAR		szScreenSaver[22]; |
| 25 | TCHAR		szHelpFile[MAXFILELEN]; |
| 26 | TCHAR		szNoHelpMemory[BUFFLEN]; |
| 27 | UINT		MyHelpMessage; |
| 28 | |
| 29 | /* local house keeping */ |
| 30 | static HINSTANCE hPwdLib = NULL; |
| 31 | static POINT pt_orig; |
| 32 | static BOOL checking_pwd = FALSE; |
| 33 | static BOOL closing = FALSE; |
| 34 | static BOOL w95 = FALSE; |
| 35 | |
| 36 | typedef void (*PVFV)(void); |
| 37 | typedef BOOL (WINAPI *VERIFYPWDPROC)(HWND); |
| 38 | typedef DWORD (WINAPI *CHPWDPROC)(LPCTSTR, HWND, DWORD, PVOID); |
| 39 | static VERIFYPWDPROC VerifyScreenSavePwd = NULL; |
| 40 | |
| 41 | /* function names */ |
| 42 | #define szVerifyPassword "VerifyScreenSavePwd" |
| 43 | |
| 44 | #ifdef UNICODE |
| 45 | #define szPwdChangePassword "PwdChangePasswordW" |
| 46 | #else |
| 47 | #define szPwdChangePassword "PwdChangePasswordA" |
| 48 | #endif |
| 49 | |
| 50 | static void TerminateScreenSaver(HWND hWnd); |
| 51 | static BOOL RegisterClasses(void); |
| 52 | static LRESULT WINAPI SysScreenSaverProc(HWND,UINT,WPARAM,LPARAM); |
| 53 | static int LaunchScreenSaver(HWND hParent); |
| 54 | static void LaunchConfig(void); |
| 55 | |
| 56 | static int ISSPACE(char c) |
| 57 | { |
| 58 | return (c == ' ' || c == '\t'); |
| 59 | } |
| 60 | |
| 61 | static ULONG_PTR parse_ulptr(const char *s) |
| 62 | { |
| 63 | ULONG_PTR res, n; |
| 64 | const char *p; |
| 65 | for (p = s; *p; p++) |
| 66 | if (*p < '0' || *p > '9') |
| 67 | break; |
| 68 | p--; |
| 69 | res = 0; |
| 70 | for (n = 1; p >= s; p--, n *= 10) |
| 71 | res += (*p - '0') * n; |
| 72 | return res; |
| 73 | } |
| 74 | |
| 75 | /* screen saver entry point */ |
| 76 | int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, |
| 77 | LPSTR CmdLine, int nCmdShow) |
| 78 | { |
| 79 | LPSTR p; |
| 80 | OSVERSIONINFO vi; |
| 81 | |
| 82 | UNREFERENCED_PARAMETER(hPrevInst); |
| 83 | UNREFERENCED_PARAMETER(nCmdShow); |
| 84 | |
| 85 | /* initialize */ |
| 86 | hMainInstance = hInst; |
| 87 | |
| 88 | vi.dwOSVersionInfoSize = sizeof(vi); |
| 89 | GetVersionEx(&vi); |
| 90 | /* check if we are going to check for passwords */ |
| 91 | if (vi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) |
| 92 | { |
| 93 | HKEY hKey; |
| 94 | /* we are using windows 95 */ |
| 95 | w95 = TRUE; |
| 96 | if (RegOpenKey(HKEY_CURRENT_USER, REGSTR_PATH_SCREENSAVE ,&hKey) == |
| 97 | ERROR_SUCCESS) |
| 98 | { |
| 99 | DWORD check_pwd; |
| 100 | DWORD size = sizeof(DWORD); |
| 101 | DWORD type; |
| 102 | LONG res; |
| 103 | res = RegQueryValueEx(hKey, REGSTR_VALUE_USESCRPASSWORD, |
| 104 | NULL, &type, (PBYTE) &check_pwd, &size); |
| 105 | if (check_pwd && res == ERROR_SUCCESS) |
| 106 | { |
| 107 | hPwdLib = LoadLibrary(TEXT("PASSWORD.CPL")); |
| 108 | if (hPwdLib) |
| 109 | VerifyScreenSavePwd = (VERIFYPWDPROC)(PVFV) GetProcAddress(hPwdLib, szVerifyPassword); |
| 110 | } |
| 111 | RegCloseKey(hKey); |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | /* parse arguments */ |
| 116 | for (p = CmdLine; *p; p++) |
| 117 | { |
| 118 | switch (*p) |
| 119 | { |
| 120 | case 'S': |
| 121 | case 's': |
| 122 | /* start screen saver */ |
| 123 | return LaunchScreenSaver(NULL); |
| 124 | |
| 125 | case 'P': |
| 126 | case 'p': |
| 127 | { |
| 128 | /* start screen saver in preview window */ |
| 129 | HWND hParent; |
| 130 | fChildPreview = TRUE; |
| 131 | while (ISSPACE(*++p)); |
| 132 | hParent = (HWND) parse_ulptr(p); |
| 133 | if (hParent && IsWindow(hParent)) |
| 134 | return LaunchScreenSaver(hParent); |
| 135 | } |
| 136 | return 0; |
| 137 | |
| 138 | case 'C': |
| 139 | case 'c': |
| 140 | /* display configure dialog */ |
| 141 | LaunchConfig(); |
| 142 | return 0; |
| 143 | |
| 144 | case 'A': |
| 145 | case 'a': |
| 146 | { |
| 147 | /* change screen saver password */ |
| 148 | HWND hParent; |
| 149 | while (ISSPACE(*++p)); |
| 150 | hParent = (HWND) parse_ulptr(p); |
| 151 | if (!hParent || !IsWindow(hParent)) |
| 152 | hParent = GetForegroundWindow(); |
| 153 | ScreenSaverChangePassword(hParent); |
| 154 | } |
| 155 | return 0; |
| 156 | |
| 157 | case '-': |
| 158 | case '/': |
| 159 | case ' ': |
| 160 | default: |
| 161 | 	 break; |
| 162 | } |
| 163 | } |
| 164 | LaunchConfig(); |
| 165 | return 0; |
| 166 | } |
| 167 | |
| 168 | static void LaunchConfig(void) |
| 169 | { |
| 170 | /* FIXME: should this be called */ |
| 171 | RegisterDialogClasses(hMainInstance); |
| 172 | /* display configure dialog */ |
| 173 | DialogBox(hMainInstance, MAKEINTRESOURCE(DLG_SCRNSAVECONFIGURE), |
| 174 | GetForegroundWindow(), (DLGPROC)(PVFV) ScreenSaverConfigureDialog); |
| 175 | } |
| 176 | |
| 177 | |
| 178 | static int LaunchScreenSaver(HWND hParent) |
| 179 | { |
| 180 | BOOL foo; |
| 181 | UINT style; |
| 182 | RECT rc; |
| 183 | MSG msg; |
| 184 | |
| 185 | /* don't allow other tasks to get into the foreground */ |
| 186 | if (w95 && !fChildPreview) |
| 187 | SystemParametersInfo(SPI_SCREENSAVERRUNNING, TRUE, &foo, 0); |
| 188 | |
| 189 | msg.wParam = 0; |
| 190 | |
| 191 | /* register classes, both user defined and classes used by screen saver |
| 192 | library */ |
| 193 | if (!RegisterClasses()) |
| 194 | { |
| 195 | MessageBox(NULL, TEXT("RegisterClasses() failed"), NULL, MB_ICONHAND); |
| 196 | goto restore; |
| 197 | } |
| 198 | |
| 199 | /* a slightly different approach needs to be used when displaying |
| 200 | in a preview window */ |
| 201 | if (hParent) |
| 202 | { |
| 203 | style = WS_CHILD; |
| 204 | GetClientRect(hParent, &rc); |
| 205 | } |
| 206 | else |
| 207 | { |
| 208 | style = WS_POPUP; |
| 209 | rc.left = GetSystemMetrics(SM_XVIRTUALSCREEN); |
| 210 | rc.top = GetSystemMetrics(SM_YVIRTUALSCREEN); |
| 211 | rc.right = GetSystemMetrics(SM_CXVIRTUALSCREEN); |
| 212 | rc.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN); |
| 213 | style |= WS_VISIBLE; |
| 214 | } |
| 215 | |
| 216 | /* create main screen saver window */ |
| 217 | hMainWindow = CreateWindowEx(hParent ? 0 : WS_EX_TOPMOST, CLASS_SCRNSAVE, |
| 218 | TEXT("SCREENSAVER"), style, |
| 219 | rc.left, rc.top, rc.right, rc.bottom, hParent, NULL, |
| 220 | hMainInstance, NULL); |
| 221 | |
| 222 | /* display window and start pumping messages */ |
| 223 | if (hMainWindow) |
| 224 | { |
| 225 | UpdateWindow(hMainWindow); |
| 226 | ShowWindow(hMainWindow, SW_SHOW); |
| 227 | |
| 228 | while (GetMessage(&msg, NULL, 0, 0) == TRUE) |
| 229 | { |
| 230 | TranslateMessage(&msg); |
| 231 | DispatchMessage(&msg); |
| 232 | } |
| 233 | } |
| 234 | |
| 235 | restore: |
| 236 | /* restore system */ |
| 237 | if (w95 && !fChildPreview) |
| 238 | SystemParametersInfo(SPI_SCREENSAVERRUNNING, FALSE, &foo, 0); |
| 239 | FreeLibrary(hPwdLib); |
| 240 | return msg.wParam; |
| 241 | } |
| 242 | |
| 243 | /* this function takes care of *must* do tasks, like terminating |
| 244 | screen saver */ |
| 245 | static LRESULT WINAPI SysScreenSaverProc(HWND hWnd, UINT msg, |
| 246 | WPARAM wParam, LPARAM lParam) |
| 247 | { |
| 248 | switch (msg) |
| 249 | { |
| 250 | case WM_CREATE: |
| 251 | if (!fChildPreview) |
| 252 | SetCursor(NULL); |
| 253 | /* mouse is not supposed to move from this position */ |
| 254 | GetCursorPos(&pt_orig); |
| 255 | break; |
| 256 | case WM_DESTROY: |
| 257 | PostQuitMessage(0); |
| 258 | break; |
| 259 | case WM_TIMER: |
| 260 | if (closing) |
| 261 | return 0; |
| 262 | break; |
| 263 | case WM_PAINT: |
| 264 | if (closing) |
| 265 | return DefWindowProc(hWnd, msg, wParam, lParam); |
| 266 | break; |
| 267 | case WM_SYSCOMMAND: |
| 268 | if (!fChildPreview) |
| 269 | switch (wParam) |
| 270 | { |
| 271 | case SC_CLOSE: |
| 272 | case SC_SCREENSAVE: |
| 273 | case SC_NEXTWINDOW: |
| 274 | case SC_PREVWINDOW: |
| 275 | return FALSE; |
| 276 | } |
| 277 | break; |
| 278 | case WM_MOUSEMOVE: |
| 279 | case WM_LBUTTONDOWN: |
| 280 | case WM_RBUTTONDOWN: |
| 281 | case WM_MBUTTONDOWN: |
| 282 | case WM_KEYDOWN: |
| 283 | case WM_SYSKEYDOWN: |
| 284 | case WM_NCACTIVATE: |
| 285 | case WM_ACTIVATE: |
| 286 | case WM_ACTIVATEAPP: |
| 287 | if (closing) |
| 288 | return DefWindowProc(hWnd, msg, wParam, lParam); |
| 289 | break; |
| 290 | } |
| 291 | return ScreenSaverProc(hWnd, msg, wParam, lParam); |
| 292 | } |
| 293 | |
| 294 | LRESULT WINAPI DefScreenSaverProc(HWND hWnd, UINT msg, |
| 295 | WPARAM wParam, LPARAM lParam) |
| 296 | { |
| 297 | /* don't do any special processing when in preview mode */ |
| 298 | if (fChildPreview || closing) |
| 299 | return DefWindowProc(hWnd, msg, wParam, lParam); |
| 300 | |
| 301 | switch (msg) |
| 302 | { |
| 303 | case WM_CLOSE: |
| 304 | TerminateScreenSaver(hWnd); |
| 305 | /* do NOT pass this to DefWindowProc; it will terminate even if |
| 306 | an invalid password was given. |
| 307 | */ |
| 308 | return 0; |
| 309 | case SCRM_VERIFYPW: |
| 310 | /* verify password or return TRUE if password checking is turned off */ |
| 311 | if (VerifyScreenSavePwd) |
| 312 | return VerifyScreenSavePwd(hWnd); |
| 313 | else |
| 314 | return TRUE; |
| 315 | case WM_SETCURSOR: |
| 316 | if (checking_pwd) |
| 317 | break; |
| 318 | SetCursor(NULL); |
| 319 | return TRUE; |
| 320 | case WM_NCACTIVATE: |
| 321 | case WM_ACTIVATE: |
| 322 | case WM_ACTIVATEAPP: |
| 323 | /* if wParam is FALSE then I am losing focus */ |
| 324 | if (wParam == FALSE && !checking_pwd) |
| 325 | PostMessage(hWnd, WM_CLOSE, 0, 0); |
| 326 | break; |
| 327 | case WM_MOUSEMOVE: |
| 328 | { |
| 329 | POINT pt; |
| 330 | GetCursorPos(&pt); |
| 331 | if (pt.x == pt_orig.x && pt.y == pt_orig.y) |
| 332 | break; |
| 333 | /* mouse moved */ |
| 334 | } |
| 335 | /* fallthrough */ |
| 336 | case WM_LBUTTONDOWN: |
| 337 | case WM_RBUTTONDOWN: |
| 338 | case WM_MBUTTONDOWN: |
| 339 | case WM_KEYDOWN: |
| 340 | case WM_SYSKEYDOWN: |
| 341 | /* try to terminate screen saver */ |
| 342 | if (!checking_pwd) |
| 343 | PostMessage(hWnd, WM_CLOSE, 0, 0); |
| 344 | break; |
| 345 | } |
| 346 | return DefWindowProc(hWnd, msg, wParam, lParam); |
| 347 | } |
| 348 | |
| 349 | static void TerminateScreenSaver(HWND hWnd) |
| 350 | { |
| 351 | /* don't allow recursion */ |
| 352 | if (checking_pwd || closing) |
| 353 | return; |
| 354 | |
| 355 | /* verify password */ |
| 356 | if (VerifyScreenSavePwd) |
| 357 | { |
| 358 | checking_pwd = TRUE; |
| 359 | closing = SendMessage(hWnd, SCRM_VERIFYPW, 0, 0); |
| 360 | checking_pwd = FALSE; |
| 361 | } |
| 362 | else |
| 363 | closing = TRUE; |
| 364 | |
| 365 | /* are we closing? */ |
| 366 | if (closing) |
| 367 | { |
| 368 | DestroyWindow(hWnd); |
| 369 | } |
| 370 | else |
| 371 | GetCursorPos(&pt_orig); /* if not: get new mouse position */ |
| 372 | } |
| 373 | |
| 374 | /* |
| 375 | Register screen saver window class and call user |
| 376 | supplied hook. |
| 377 | */ |
| 378 | static BOOL RegisterClasses(void) |
| 379 | { |
| 380 | WNDCLASS cls; |
| 381 | |
| 382 | cls.hCursor = NULL; |
| 383 | cls.hIcon = LoadIcon(hMainInstance, MAKEINTATOM(ID_APP)); |
| 384 | cls.lpszMenuName = NULL; |
| 385 | cls.lpszClassName = CLASS_SCRNSAVE; |
| 386 | cls.hbrBackground = GetStockObject(BLACK_BRUSH); |
| 387 | cls.hInstance = hMainInstance; |
| 388 | cls.style = CS_VREDRAW | CS_HREDRAW | CS_SAVEBITS | CS_PARENTDC; |
| 389 | cls.lpfnWndProc = SysScreenSaverProc; |
| 390 | cls.cbWndExtra = 0; |
| 391 | cls.cbClsExtra = 0; |
| 392 | |
| 393 | if (!RegisterClass(&cls)) |
| 394 | return FALSE; |
| 395 | |
| 396 | return RegisterDialogClasses(hMainInstance); |
| 397 | } |
| 398 | |
| 399 | void WINAPI ScreenSaverChangePassword(HWND hParent) |
| 400 | { |
| 401 | /* load Master Password Router (MPR) */ |
| 402 | HINSTANCE hMpr = LoadLibrary(TEXT("MPR.DLL")); |
| 403 | |
| 404 | if (hMpr) |
| 405 | { |
| 406 | CHPWDPROC ChangePassword; |
| 407 | ChangePassword = (CHPWDPROC)(PVFV) GetProcAddress(hMpr, szPwdChangePassword); |
| 408 | |
| 409 | /* change password for screen saver provider */ |
| 410 | if (ChangePassword) |
| 411 | ChangePassword(TEXT("SCRSAVE"), hParent, 0, NULL); |
| 412 | |
| 413 | FreeLibrary(hMpr); |
| 414 | } |
| 415 | } |