| ... | ... | @@ -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 | | } |