408 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			408 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|   Screen saver library by Anders Norlander <anorland@hem2.passagen.se>
 | |
| 
 | |
|   This library is (hopefully) compatible with Microsoft's
 | |
|   screen saver library.
 | |
| 
 | |
|   This is public domain software.
 | |
| 
 | |
|  */
 | |
| #include <windows.h>
 | |
| #include <scrnsave.h>
 | |
| #include <regstr.h>
 | |
| 
 | |
| /* screen saver window class */
 | |
| #define CLASS_SCRNSAVE TEXT("WindowsScreenSaverClass")
 | |
| 
 | |
| /* globals */
 | |
| HWND		hMainWindow = NULL;
 | |
| BOOL		fChildPreview = FALSE;
 | |
| HINSTANCE	hMainInstance;
 | |
| TCHAR		szName[TITLEBARNAMELEN];
 | |
| TCHAR		szAppName[APPNAMEBUFFERLEN];
 | |
| TCHAR		szIniFile[MAXFILELEN];
 | |
| TCHAR		szScreenSaver[22];
 | |
| TCHAR		szHelpFile[MAXFILELEN];
 | |
| TCHAR		szNoHelpMemory[BUFFLEN];
 | |
| UINT		MyHelpMessage;
 | |
| 
 | |
| /* local house keeping */
 | |
| static HINSTANCE hPwdLib = NULL;
 | |
| static POINT pt_orig;
 | |
| static BOOL checking_pwd = FALSE;
 | |
| static BOOL closing = FALSE;
 | |
| static BOOL w95 = FALSE;
 | |
| 
 | |
| typedef BOOL (WINAPI *VERIFYPWDPROC)(HWND);
 | |
| typedef DWORD (WINAPI *CHPWDPROC)(LPCTSTR, HWND, DWORD, PVOID);
 | |
| static VERIFYPWDPROC VerifyScreenSavePwd = NULL;
 | |
| 
 | |
| /* function names */
 | |
| #define szVerifyPassword "VerifyScreenSavePwd"
 | |
| 
 | |
| #ifdef UNICODE
 | |
| #define szPwdChangePassword "PwdChangePasswordW"
 | |
| #else
 | |
| #define szPwdChangePassword "PwdChangePasswordA"
 | |
| #endif
 | |
| 
 | |
| static void TerminateScreenSaver(HWND hWnd);
 | |
| static BOOL RegisterClasses(void);
 | |
| static LRESULT WINAPI SysScreenSaverProc(HWND,UINT,WPARAM,LPARAM);
 | |
| static int LaunchScreenSaver(HWND hParent);
 | |
| static void LaunchConfig(void);
 | |
| 
 | |
| static int ISSPACE(char c)
 | |
| {
 | |
|   return (c == ' ' || c == '\t');
 | |
| }
 | |
| 
 | |
| #define ISNUM(c) ((c) >= '0' && c <= '9')
 | |
| static unsigned long
 | |
| _toul(const char *s)
 | |
| {
 | |
|   unsigned long res;
 | |
|   unsigned long n;
 | |
|   const char *p;
 | |
|   for (p = s; *p; p++)
 | |
|     if (!ISNUM(*p)) break;
 | |
|   p--;
 | |
|   res = 0;
 | |
|   for (n = 1; p >= s; p--, n *= 10)
 | |
|     res += (*p - '0') * n;
 | |
|   return res;
 | |
| }
 | |
| 
 | |
| /* screen saver entry point */
 | |
| int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
 | |
|                      LPSTR CmdLine, int nCmdShow)
 | |
| {
 | |
|   LPSTR p;
 | |
|   OSVERSIONINFO vi;
 | |
| 
 | |
|   /* initialize */
 | |
|   hMainInstance = hInst;
 | |
| 
 | |
|   vi.dwOSVersionInfoSize = sizeof(vi);
 | |
|   GetVersionEx(&vi);
 | |
|   /* check if we are going to check for passwords */
 | |
|   if (vi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
 | |
|     {
 | |
|       HKEY hKey;
 | |
|       /* we are using windows 95 */
 | |
|       w95 = TRUE;
 | |
|       if (RegOpenKey(HKEY_CURRENT_USER, REGSTR_PATH_SCREENSAVE ,&hKey) ==
 | |
|           ERROR_SUCCESS)
 | |
|         {
 | |
|           DWORD check_pwd;
 | |
|           DWORD size = sizeof(DWORD);
 | |
|           DWORD type;
 | |
|           LONG res;
 | |
|           res = RegQueryValueEx(hKey, REGSTR_VALUE_USESCRPASSWORD,
 | |
|                                 NULL, &type, (PBYTE) &check_pwd, &size);
 | |
|           if (check_pwd && res == ERROR_SUCCESS)
 | |
|             {
 | |
|               hPwdLib = LoadLibrary(TEXT("PASSWORD.CPL"));
 | |
|               if (hPwdLib)
 | |
|                 VerifyScreenSavePwd = GetProcAddress(hPwdLib, szVerifyPassword);
 | |
|             }
 | |
|           RegCloseKey(hKey);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|   /* parse arguments */
 | |
|   for (p = CmdLine; *p; p++)
 | |
|     {
 | |
|       switch (*p)
 | |
|         {
 | |
|         case 'S':
 | |
|         case 's':
 | |
|           /* start screen saver */
 | |
|           return LaunchScreenSaver(NULL);
 | |
|           
 | |
|         case 'P':
 | |
|         case 'p':
 | |
|           {
 | |
|             /* start screen saver in preview window */
 | |
|             HWND hParent;
 | |
|             fChildPreview = TRUE;
 | |
|             while (ISSPACE(*++p));
 | |
|             hParent = (HWND) _toul(p);
 | |
|             if (hParent && IsWindow(hParent))
 | |
|               return LaunchScreenSaver(hParent);
 | |
|           }
 | |
|           return 0;
 | |
| 
 | |
|         case 'C':
 | |
|         case 'c':
 | |
|           /* display configure dialog */
 | |
|           LaunchConfig();
 | |
|           return 0;
 | |
| 
 | |
|         case 'A':
 | |
|         case 'a':
 | |
|           {
 | |
|             /* change screen saver password */
 | |
|             HWND hParent;
 | |
|             while (ISSPACE(*++p));
 | |
|             hParent = (HWND) _toul(p);
 | |
|             if (!hParent || !IsWindow(hParent))
 | |
|               hParent = GetForegroundWindow();
 | |
|             ScreenSaverChangePassword(hParent);
 | |
|           }
 | |
|           return 0;
 | |
| 
 | |
|         case '-':
 | |
|         case '/':
 | |
|         case ' ':
 | |
|         default: 
 | |
| 	  break;
 | |
|         }
 | |
|     }
 | |
|   LaunchConfig();
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| static void LaunchConfig(void)
 | |
| {
 | |
|   /* FIXME: should this be called */
 | |
|   RegisterDialogClasses(hMainInstance);
 | |
|   /* display configure dialog */
 | |
|   DialogBox(hMainInstance, MAKEINTRESOURCE(DLG_SCRNSAVECONFIGURE),
 | |
|             GetForegroundWindow(), (DLGPROC) ScreenSaverConfigureDialog);
 | |
| }
 | |
| 
 | |
| 
 | |
| static int LaunchScreenSaver(HWND hParent)
 | |
| {
 | |
|   BOOL foo;
 | |
|   UINT style;
 | |
|   RECT rc;
 | |
|   MSG msg;
 | |
| 
 | |
|   /* don't allow other tasks to get into the foreground */
 | |
|   if (w95 && !fChildPreview)
 | |
|     SystemParametersInfo(SPI_SCREENSAVERRUNNING, TRUE, &foo, 0);
 | |
| 
 | |
|   msg.wParam = 0;
 | |
| 
 | |
|   /* register classes, both user defined and classes used by screen saver
 | |
|      library */
 | |
|   if (!RegisterClasses())
 | |
|     {
 | |
|       MessageBox(NULL, TEXT("RegisterClasses() failed"), NULL, MB_ICONHAND);
 | |
|       goto restore;
 | |
|     }
 | |
| 
 | |
|   /* a slightly different approach needs to be used when displaying
 | |
|      in a preview window */
 | |
|   if (hParent)
 | |
|     {
 | |
|       style = WS_CHILD;
 | |
|       GetClientRect(hParent, &rc);
 | |
|     }
 | |
|   else
 | |
|     {
 | |
|       style = WS_POPUP;
 | |
|       rc.right = GetSystemMetrics(SM_CXSCREEN);
 | |
|       rc.bottom = GetSystemMetrics(SM_CYSCREEN);
 | |
|       style |= WS_VISIBLE;
 | |
|     }
 | |
| 
 | |
|   /* create main screen saver window */
 | |
|   hMainWindow = CreateWindowEx(hParent ? 0 : WS_EX_TOPMOST, CLASS_SCRNSAVE,
 | |
|                                TEXT("SCREENSAVER"), style,
 | |
|                                0, 0, rc.right, rc.bottom, hParent, NULL,
 | |
|                                hMainInstance, NULL);
 | |
| 
 | |
|   /* display window and start pumping messages */
 | |
|   if (hMainWindow)
 | |
|     {
 | |
|       UpdateWindow(hMainWindow);
 | |
|       ShowWindow(hMainWindow, SW_SHOW);
 | |
| 
 | |
|       while (GetMessage(&msg, NULL, 0, 0) == TRUE)
 | |
|         {
 | |
|           TranslateMessage(&msg);
 | |
|           DispatchMessage(&msg);
 | |
|         }
 | |
|     }
 | |
| 
 | |
| restore:
 | |
|   /* restore system */
 | |
|   if (w95 && !fChildPreview)
 | |
|     SystemParametersInfo(SPI_SCREENSAVERRUNNING, FALSE, &foo, 0);
 | |
|   FreeLibrary(hPwdLib);
 | |
|   return msg.wParam;
 | |
| }
 | |
| 
 | |
| /* this function takes care of *must* do tasks, like terminating
 | |
|    screen saver */
 | |
| static LRESULT WINAPI SysScreenSaverProc(HWND hWnd, UINT msg,
 | |
|                                   WPARAM wParam, LPARAM lParam)
 | |
| {
 | |
|   switch (msg)
 | |
|     {
 | |
|     case WM_CREATE:
 | |
|       if (!fChildPreview)
 | |
|         SetCursor(NULL);
 | |
|       /* mouse is not supposed to move from this position */
 | |
|       GetCursorPos(&pt_orig);
 | |
|       break;
 | |
|     case WM_DESTROY:
 | |
|       PostQuitMessage(0);
 | |
|       break;
 | |
|     case WM_TIMER:
 | |
|       if (closing)
 | |
|         return 0;
 | |
|       break;
 | |
|     case WM_PAINT:
 | |
|       if (closing)
 | |
|         return DefWindowProc(hWnd, msg, wParam, lParam);
 | |
|       break;
 | |
|     case WM_SYSCOMMAND:
 | |
|       if (!fChildPreview)
 | |
|         switch (wParam)
 | |
|           {
 | |
|           case SC_CLOSE:
 | |
|           case SC_SCREENSAVE:
 | |
|           case SC_NEXTWINDOW:
 | |
|           case SC_PREVWINDOW:
 | |
|             return FALSE;
 | |
|           }
 | |
|       break;
 | |
|     case WM_MOUSEMOVE:
 | |
|     case WM_LBUTTONDOWN:
 | |
|     case WM_RBUTTONDOWN:
 | |
|     case WM_MBUTTONDOWN:
 | |
|     case WM_KEYDOWN:
 | |
|     case WM_SYSKEYDOWN:
 | |
|     case WM_NCACTIVATE:
 | |
|     case WM_ACTIVATE:
 | |
|     case WM_ACTIVATEAPP:
 | |
|       if (closing)
 | |
|         return DefWindowProc(hWnd, msg, wParam, lParam);
 | |
|       break;
 | |
|     }
 | |
|   return ScreenSaverProc(hWnd, msg, wParam, lParam);
 | |
| }
 | |
| 
 | |
| LONG WINAPI DefScreenSaverProc(HWND hWnd, UINT msg,
 | |
|                                WPARAM wParam, LPARAM lParam)
 | |
| {
 | |
|   /* don't do any special processing when in preview mode */
 | |
|   if (fChildPreview || closing)
 | |
|     return DefWindowProc(hWnd, msg, wParam, lParam);
 | |
| 
 | |
|   switch (msg)
 | |
|     {
 | |
|     case WM_CLOSE:
 | |
|       TerminateScreenSaver(hWnd);
 | |
|       /* do NOT pass this to DefWindowProc; it will terminate even if
 | |
|          an invalid password was given.
 | |
|        */
 | |
|       return 0;
 | |
|     case SCRM_VERIFYPW: 
 | |
|       /* verify password or return TRUE if password checking is turned off */
 | |
|       if (VerifyScreenSavePwd) 
 | |
|         return VerifyScreenSavePwd(hWnd);
 | |
|       else
 | |
|         return TRUE;
 | |
|     case WM_SETCURSOR:
 | |
|       if (checking_pwd)
 | |
|         break;
 | |
|       SetCursor(NULL);
 | |
|       return TRUE;
 | |
|     case WM_NCACTIVATE:
 | |
|     case WM_ACTIVATE:
 | |
|     case WM_ACTIVATEAPP:
 | |
|       if (wParam != FALSE)
 | |
|         break;
 | |
|     case WM_MOUSEMOVE:
 | |
|       {
 | |
|         POINT pt;
 | |
|         GetCursorPos(&pt);
 | |
|         if (pt.x == pt_orig.x && pt.y == pt_orig.y)
 | |
|           break;
 | |
|       }
 | |
|     case WM_LBUTTONDOWN:
 | |
|     case WM_RBUTTONDOWN:
 | |
|     case WM_MBUTTONDOWN:
 | |
|     case WM_KEYDOWN:
 | |
|     case WM_SYSKEYDOWN:
 | |
|       /* try to terminate screen saver */
 | |
|       if (!checking_pwd)
 | |
|         PostMessage(hWnd, WM_CLOSE, 0, 0);
 | |
|       break;
 | |
|     }
 | |
|   return DefWindowProc(hWnd, msg, wParam, lParam);
 | |
| }
 | |
| 
 | |
| static void TerminateScreenSaver(HWND hWnd)
 | |
| {
 | |
|   /* don't allow recursion */
 | |
|   if (checking_pwd || closing)
 | |
|     return;
 | |
| 
 | |
|   /* verify password */
 | |
|   if (VerifyScreenSavePwd)
 | |
|     {
 | |
|       checking_pwd = TRUE;
 | |
|       closing = SendMessage(hWnd, SCRM_VERIFYPW, 0, 0);
 | |
|       checking_pwd = FALSE;
 | |
|     }
 | |
|   else
 | |
|     closing = TRUE;
 | |
| 
 | |
|   /* are we closing? */
 | |
|   if (closing)
 | |
|     {
 | |
|       DestroyWindow(hWnd);
 | |
|     }
 | |
|   else
 | |
|     GetCursorPos(&pt_orig); /* if not: get new mouse position */
 | |
| }
 | |
| 
 | |
| /*
 | |
|   Register screen saver window class and call user
 | |
|   supplied hook.
 | |
|  */
 | |
| static BOOL RegisterClasses(void)
 | |
| {
 | |
|   WNDCLASS cls;
 | |
|   
 | |
|   cls.hCursor = NULL; 
 | |
|   cls.hIcon = LoadIcon(hMainInstance, MAKEINTATOM(ID_APP)); 
 | |
|   cls.lpszMenuName = NULL;
 | |
|   cls.lpszClassName = CLASS_SCRNSAVE;
 | |
|   cls.hbrBackground = GetStockObject(BLACK_BRUSH);
 | |
|   cls.hInstance = hMainInstance;
 | |
|   cls.style = CS_VREDRAW | CS_HREDRAW | CS_SAVEBITS | CS_PARENTDC;
 | |
|   cls.lpfnWndProc = (WNDPROC) SysScreenSaverProc;
 | |
|   cls.cbWndExtra = 0;
 | |
|   cls.cbClsExtra = 0;
 | |
|   
 | |
|   if (!RegisterClass(&cls))
 | |
|     return FALSE;
 | |
| 
 | |
|   return RegisterDialogClasses(hMainInstance);
 | |
| }
 | |
| 
 | |
| void WINAPI ScreenSaverChangePassword(HWND hParent)
 | |
| {
 | |
|   /* load Master Password Router (MPR) */
 | |
|   HINSTANCE hMpr = LoadLibrary(TEXT("MPR.DLL"));
 | |
|   
 | |
|   if (hMpr)
 | |
|     {
 | |
|       CHPWDPROC ChangePassword;
 | |
|       ChangePassword = (CHPWDPROC) GetProcAddress(hMpr, szPwdChangePassword);
 | |
| 
 | |
|       /* change password for screen saver provider */
 | |
|       if (ChangePassword)
 | |
|         ChangePassword(TEXT("SCRSAVE"), hParent, 0, NULL);
 | |
| 
 | |
|       FreeLibrary(hMpr);
 | |
|     }
 | |
| }
 |