410 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			410 lines
		
	
	
		
			10 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_SETSCREENSAVERRUNNING, 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.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
 | 
						|
      rc.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
 | 
						|
      rc.right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
 | 
						|
      rc.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
 | 
						|
      style |= WS_VISIBLE;
 | 
						|
    }
 | 
						|
 | 
						|
  /* create main screen saver window */
 | 
						|
  hMainWindow = CreateWindowEx(hParent ? 0 : WS_EX_TOPMOST, CLASS_SCRNSAVE,
 | 
						|
                               TEXT("SCREENSAVER"), style,
 | 
						|
                               rc.left, rc.top, 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_SETSCREENSAVERRUNNING, 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);
 | 
						|
    }
 | 
						|
}
 |