Windows2000/private/windows/opengl/scrsave/common/scrnsave.cxx
2020-09-30 17:12:32 +02:00

794 lines
23 KiB
C++

// SCRNSAVE.C -- skeleton for screen saver application
// 4/5/94 francish merged NT and Win4 saver code, folded in SCRNSAVE.SCR
// - 3/14/96: marcfo Pulled this file in from shell\control\scrnsave\common.
// All changes marked with GL_SCRNSAVE.
#define GL_SCRNSAVE 1
#define WIN31
#include <windows.h>
#include <windowsx.h>
#include "scrnsave.h"
#include <regstr.h>
#include <imm.h>
#ifdef GL_SCRNSAVE
#include "glscrnsv.h"
#endif
#define DBG_MSGS 0
const TCHAR szScreenSaverKey[] = REGSTR_PATH_SCREENSAVE;
TCHAR szPasswordActiveValue[] = REGSTR_VALUE_USESCRPASSWORD;
const TCHAR szPasswordValue[] = REGSTR_VALUE_SCRPASSWORD;
TCHAR szPwdDLL[] = TEXT("PASSWORD.CPL");
CHAR szFnName[] = "VerifyScreenSavePwd"; // Proc name, must be ANSI
TCHAR szImmDLL[] = TEXT("IMM32.DLL");
CHAR szImmFnc[] = "ImmAssociateContext"; // Proc name, must be ANSI
#if 0
TCHAR szCoolSaverHacks[] = REGSTR_PATH_SETUP TEXT("\\Screen Savers");
TCHAR szMouseThreshold[] = TEXT("Mouse Threshold");
TCHAR szPasswordDelay[] = TEXT("Password Delay");
#endif
typedef BOOL(FAR PASCAL* VERIFYPWDPROC) (HWND);
typedef HIMC(FAR PASCAL* IMMASSOCPROC) (HWND, HIMC);
// variables declared in SCRNSAVE.H
HINSTANCE hMainInstance = 0;
HWND hMainWindow = 0;
BOOL fChildPreview = FALSE;
// other globals
POINT ptMouse;
BOOL fClosing = FALSE;
BOOL fCheckingPassword = FALSE;
HINSTANCE hInstPwdDLL = NULL;
VERIFYPWDPROC VerifyPassword = NULL;
static BOOL preview_like_fullscreen = FALSE;
static UINT uShellAutoPlayQueryMessage = 0;
HINSTANCE hInstImm = NULL;
IMMASSOCPROC ImmFnc = NULL;
HIMC hPrevImc = (HIMC)0L;
static BOOL fOnWin95 = FALSE; //TRUE if on Chicago, FALSE if on Cairo
// random junk
DWORD dwWakeThreshold = 4; //default to slight movement
DWORD dwPasswordDelay = 0;
DWORD dwBlankTime = 0;
#define MAX_PASSWORD_DELAY_IN_SECONDS (60)
// forward declarations of internal fns
#ifndef GL_SCRNSAVE
// These are hooked out to glscrnsv.cxx
static INT_PTR DoScreenSave(HWND hParent);
static INT_PTR DoConfigBox(HWND hParent);
#endif
static INT_PTR DoSaverPreview(LPCTSTR szUINTHandle);
static INT_PTR DoChangePw(LPCTSTR szUINTHandle);
static BOOL DoPasswordCheck(HWND hParent);
VOID LoadPwdDLL(VOID);
VOID UnloadPwdDLL(VOID);
// helper for time
static DWORD GetElapsedTime(DWORD from, DWORD to)
{
return (to >= from) ? (to - from) : (1 + to + (((DWORD)-1) - from));
}
// helper to convert text to unsigned int
static UINT_PTR
atoui(LPCTSTR szUINT)
{
UINT_PTR uValue = 0;
while ((*szUINT >= TEXT('0')) && (*szUINT <= TEXT('9')))
uValue = ((uValue * 10) + (*szUINT++ - TEXT('0')));
return uValue;
}
// Local reboot and hotkey control (on Win95)
static void
HogMachine(BOOL value)
{
BOOL dummy;
// NT is always secure, therefore we don't need to call this on Cairo/NT
if (fOnWin95) {
SystemParametersInfo(SPI_SCREENSAVERRUNNING, value, &dummy, 0);
}
}
// entry point (duh)
INT_PTR PASCAL
WinMainN(HINSTANCE hInst, HINSTANCE hPrev, LPTSTR szCmdLine, int nCmdShow)
{
LPCTSTR pch = szCmdLine;
HWND hParent = 0;
OSVERSIONINFO osvi;
hMainInstance = hInst;
osvi.dwOSVersionInfoSize = sizeof(osvi);
fOnWin95 = (GetVersionEx(&osvi) && osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
#ifdef GL_SCRNSAVE
// the shell sends this message to the foreground window before running an
// AutoPlay app. we return 1 to cancel autoplay if we are password protected
if (fOnWin95) {
uShellAutoPlayQueryMessage = RegisterWindowMessage(TEXT("QueryCancelAutoPlay"));
} else {
uShellAutoPlayQueryMessage = 0;
}
#endif
_try
{
for (;;) switch (*pch) {
case TEXT('S'):
case TEXT('s'):
return DoScreenSave(NULL);
#ifdef GL_SCRNSAVE
case TEXT('W'):
case TEXT('w'):
do pch++; while (*pch == TEXT(' ')); // size parameters
return DoWindowedScreenSave(pch);
#endif
case TEXT('L'):
case TEXT('l'):
// special switch for tests such as WinBench
// this is NOT a hack to make bechmarks look good
// it's a hack to allow you to benchmark a screen saver
// many bechmarking apps require the whole screen in foreground
// which makes it hard to measure how a screensaver adds CPU load
// you must provide a parent window (just like preview mode)
preview_like_fullscreen = TRUE;
case TEXT('P'):
case TEXT('p'):
do pch++; while (*pch == TEXT(' ')); // skip to the good stuff
return DoSaverPreview(pch);
case TEXT('A'):
case TEXT('a'):
if (!fOnWin95)
return -1;
do pch++; while (*pch == TEXT(' ')); // skip to the good stuff
return DoChangePw(pch);
case TEXT('C'):
case TEXT('c'):
{
HWND hwndParent = NULL
;
// Look for optional parent window after the "C",
// syntax is "C:hwnd_value"
if (*(++pch) == TEXT(':')) {
hwndParent = (HWND)atoui(++pch);
}
if (hwndParent == NULL || !IsWindow(hwndParent))
hwndParent = GetForegroundWindow();
return DoConfigBox(hwndParent);
}
case TEXT('\0'):
return DoConfigBox(NULL);
case TEXT(' '):
case TEXT('-'):
case TEXT('/'):
pch++; // skip spaces and common switch prefixes
break;
default:
return -1;
}
}
_except(UnhandledExceptionFilter(GetExceptionInformation()))
{
// don't leave local reboot and hotkeys disabled on Win95
HogMachine(FALSE);
}
}
// default screen-saver proc, declared in SCRNSAVE.H
// intended to be called by the consumer's ScreenSaverProc where
// DefWindowProc would normally be called
LRESULT WINAPI
DefScreenSaverProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
#if DBG_MSGS
TCHAR szBuff[80];
wsprintf(szBuff, TEXT("** DefSSP received:\t0x%04lx 0x%08lx 0x%08lx\n"), uMsg, wParam, lParam);
OutputDebugString(szBuff);
#endif
if (!fChildPreview && !fClosing) {
switch (uMsg) {
case WM_CLOSE:
// Only do password check if on Windows 95. WinNT (Cairo) has
// the password check built into the security desktop for
// C2 compliance.
if (fOnWin95) {
if (!DoPasswordCheck(hWnd)) {
GetCursorPos(&ptMouse); // re-establish
return FALSE;
}
}
#ifdef GL_SCRNSAVE
// We need to know when we're being terminated, so we can do
// various clean-up stuff
SendMessage(hWnd, SS_WM_CLOSING, 0, 0);
#endif
break;
case SCRM_VERIFYPW:
if (fOnWin95)
return (VerifyPassword ? (LRESULT)VerifyPassword(hWnd) : 1L);
break;
default:
{
POINT ptMove, ptCheck;
if (fCheckingPassword)
break;
switch (uMsg) {
case WM_SHOWWINDOW:
if ((BOOL)wParam)
SetCursor(NULL);
break;
case WM_SETCURSOR:
SetCursor(NULL);
return TRUE;
case WM_MOUSEMOVE:
GetCursorPos(&ptCheck);
if ((ptMove.x = ptCheck.x - ptMouse.x) && (ptMove.x < 0))
ptMove.x *= -1;
if ((ptMove.y = ptCheck.y - ptMouse.y) && (ptMove.y < 0))
ptMove.y *= -1;
if (((DWORD)ptMove.x + (DWORD)ptMove.y) > dwWakeThreshold) {
PostMessage(hWnd, WM_CLOSE, 0, 0l);
ptMouse = ptCheck;
}
break;
case WM_POWERBROADCAST:
switch (wParam) {
case PBT_APMRESUMECRITICAL:
case PBT_APMRESUMESUSPEND:
case PBT_APMRESUMESTANDBY:
case PBT_APMRESUMEAUTOMATIC:
// If the system is resuming from a real suspend
// (as opposed to a failed suspend) deactivate the screensaver.
if ((lParam & PBTF_APMRESUMEFROMFAILURE) == 0)
goto PostClose;
break;
default:
// The standard screensaver code shuts down on
// all power broadcast messages. This doesn't
// make much sense, but match the behavior so
// that all screensavers operate the same way.
goto PostClose;
}
break;
case WM_POWER:
// a critical resume does not generate a WM_POWERBROADCAST
// to windows for some reason, but it does generate an old WM_POWER message.
if (wParam == PWR_CRITICALRESUME)
goto PostClose;
break;
case WM_ACTIVATEAPP:
if (wParam) break;
case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
PostClose:
PostMessage(hWnd, WM_CLOSE, 0, 0l);
break;
}
}
}
}
// the shell sends this message to the foreground window before running an
// AutoPlay app. On Win95, we return 1 to cancel autoplay if we are password protected
// On WinNT, secure screen savers run on a secure separate desktop, and will never see
// this message, therefore, this code will never get executed.
// BUGBUG -
// On NT we don't want to take down the screen saver unless it is running
// on the same desktop as the autoplay shell. There is code in the
// NT autoplay shell that looks for this and does not run the app if
// that is the case; however, I not positive that the uShellAutoPlayQueryMessage
// will not go between desktops. (BradG assures me that it will not, but you
// never know.) If secure screensavers on NT randomly close when you put
// an autoplay cd in the drive, then this code should be examined closely.
if ((uMsg == uShellAutoPlayQueryMessage) && uMsg) {
PostMessage(hWnd, WM_CLOSE, 0, 0L);
return (VerifyPassword != NULL);
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
// This window procedure takes care of important stuff before calling the
// consumer's ScreenSaverProc. This helps to prevent us from getting hosed by wacky consumer code.
LRESULT WINAPI RealScreenSaverProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg) {
case WM_CREATE:
// screen saver does not need the IME
if ((hInstImm = GetModuleHandle(szImmDLL)) && (ImmFnc = (IMMASSOCPROC)GetProcAddress(hInstImm, szImmFnc)))
hPrevImc = ImmFnc(hWnd, (HIMC)0);
GetCursorPos(&ptMouse);// establish the mouse position
if (!fChildPreview)
SetCursor(NULL);
break;
case WM_DESTROY:
// screen saver does not need the IME
if (hInstImm && ImmFnc && hPrevImc)
ImmFnc(hWnd, hPrevImc);
PostQuitMessage(0);
break;
case WM_SETTEXT:
// don't let some fool change our title
// we need to be able to use FindWindow() to find running instances
// of full-screen windows screen savers
// NOTE: USER slams our title in during WM_NCCREATE by calling the
// defproc for WM_SETTEXT directly, so the initial title will get
// there. If this ever changes, we can simply set a bypass flag
// during WM_NCCREATE processing.
return FALSE;
case WM_SYSCOMMAND:
if (!fChildPreview) {
switch (wParam) {
case SC_NEXTWINDOW: // no Alt-tabs
case SC_PREVWINDOW: // no shift-alt-tabs
case SC_SCREENSAVE: // no more screensavers
return FALSE;
}
}
break;
case WM_HELP:
case WM_CONTEXTMENU:
if (fChildPreview) {
// if we're in preview mode, pump the help stuff to our owner
HWND hParent = GetParent(hWnd);
if (hParent && IsWindow(hParent))
PostMessage(hParent, uMsg, (WPARAM)hParent, lParam);
return TRUE;
}
break;
case WM_TIMER:
if (fClosing)
return FALSE;
Sleep(0);
break;
case WM_IME_NOTIFY:
// Eat IMN_OPENSTATUSWINDOW so that the status window
// isn't displayed.
if (wParam == IMN_OPENSTATUSWINDOW) {
return 0;
}
break;
case WM_MOUSEMOVE:
case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
if (fClosing)
return DefWindowProc(hWnd, uMsg, wParam, lParam);
break;
case WM_PAINT:
if (fClosing)
return DefWindowProc(hWnd, uMsg, wParam, lParam);
if (!fChildPreview)
SetCursor(NULL);
break;
}
return ScreenSaverProc(hWnd, uMsg, wParam, lParam);
}
#ifdef GL_SCRNSAVE
void
#else
static void
#endif
InitRealScreenSave()
{
#if 0
HKEY hkey;
if (RegOpenKey(HKEY_CURRENT_USER, szCoolSaverHacks, &hkey) == ERROR_SUCCESS) {
DWORD data, len, type;
len = sizeof(data);
if ((RegQueryValueEx(hkey, szMouseThreshold, NULL, &type,
(LPBYTE)&data, &len) == ERROR_SUCCESS) && (type == REG_DWORD)) {
dwWakeThreshold = max(dwWakeThreshold, data);
}
len = sizeof(data);
if ((RegQueryValueEx(hkey, szPasswordDelay, NULL, &type,
(LPBYTE)&data, &len) == ERROR_SUCCESS) && (type == REG_DWORD) && data) {
data = min(MAX_PASSWORD_DELAY_IN_SECONDS, data);
dwPasswordDelay = data * 1000;
dwBlankTime = GetTickCount();
}
}
#endif
LoadPwdDLL();
}
#ifndef GL_SCRNSAVE
static INT_PTR
DoScreenSave(HWND hParent)
{
LPCTSTR pszWindowClass = TEXT("WindowsScreenSaverClass");
LPCTSTR pszWindowTitle;
WNDCLASS cls;
MSG msg;
UINT uStyle;
UINT uExStyle;
int ncx, ncy;
int nx, ny;
cls.hCursor = NULL;
cls.hIcon = LoadIcon(hMainInstance, MAKEINTATOM(ID_APP));
cls.lpszMenuName = NULL;
cls.lpszClassName = pszWindowClass;
cls.hbrBackground = GetStockObject(BLACK_BRUSH);
cls.hInstance = hMainInstance;
cls.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_OWNDC;
cls.lpfnWndProc = RealScreenSaverProc;
cls.cbWndExtra = 0;
cls.cbClsExtra = 0;
if (hParent) {
RECT rcParent;
GetClientRect(hParent, &rcParent);
ncx = rcParent.right;
ncy = rcParent.bottom;
nx = 0;
ny = 0;
uStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN;
uExStyle = 0;
fChildPreview = TRUE;
pszWindowTitle = TEXT("Preview"); // MUST differ from full screen
} else {
HWND hOther;
#ifdef SM_CXVIRTUALSCREEN
nx = GetSystemMetrics(SM_XVIRTUALSCREEN);
ny = GetSystemMetrics(SM_YVIRTUALSCREEN);
ncx = GetSystemMetrics(SM_CXVIRTUALSCREEN);
ncy = GetSystemMetrics(SM_CYVIRTUALSCREEN);
if (ncx == 0 || ncy == 0)
#endif
{
RECT rc;
HDC hdc = GetDC(NULL);
GetClipBox(hdc, &rc);
ReleaseDC(NULL, hdc);
nx = rc.left;
ny = rc.top;
ncx = rc.right - rc.left;
ncy = rc.bottom - rc.top;
}
uStyle = WS_POPUP | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
uExStyle = WS_EX_TOPMOST;
pszWindowTitle = TEXT("Screen Saver"); // MUST differ from preview
// if there is another NORMAL screen save instance, switch to it
hOther = FindWindow(pszWindowClass, pszWindowTitle);
if (hOther && IsWindow(hOther)) {
SetForegroundWindow(hOther);
return 0;
}
InitRealScreenSave();
}
// the shell sends this message to the foreground window before running an
// AutoPlay app. we return 1 to cancel autoplay if we are password protected
if (fOnWin95) {
uShellAutoPlayQueryMessage = RegisterWindowMessage(TEXT("QueryCancelAutoPlay"));
} else {
uShellAutoPlayQueryMessage = 0;
}
if (RegisterClass(&cls)) {
hMainWindow = CreateWindowEx(uExStyle, pszWindowClass, pszWindowTitle,
uStyle, nx, ny, ncx, ncy, hParent, (HMENU)NULL,
hMainInstance, (LPVOID)NULL);
}
if (hMainWindow) {
if (!fChildPreview)
SetForegroundWindow(hMainWindow);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
UnloadPwdDLL();// free password-handling DLL if loaded
return msg.wParam;
}
#endif
static INT_PTR DoSaverPreview(LPCTSTR szUINTHandle)
{
HWND hParent = (HWND)atoui(szUINTHandle);// get parent handle from string
// only preview on a valid parent window (NOT full screen)
return ((hParent && IsWindow(hParent)) ? DoScreenSave(hParent) : -1);
}
#ifndef GL_SCRNSAVE
static INT_PTR DoConfigBox(HWND hParent)
{
// let the consumer register any special controls for the dialog
if (!RegisterDialogClasses(hMainInstance))
return FALSE;
return DialogBox(hMainInstance, MAKEINTRESOURCE(DLG_SCRNSAVECONFIGURE),
hParent, (DLGPROC)ScreenSaverConfigureDialog);
}
#endif
static INT_PTR DoChangePw(LPCTSTR szUINTHandle)
{
// get parent handle from string
HWND hParent = (HWND)atoui(szUINTHandle);
if (!hParent || !IsWindow(hParent))
hParent = GetForegroundWindow();
ScreenSaverChangePassword(hParent);// allow the library to be hooked
return 0;
}
static const TCHAR szMprDll[] = TEXT("MPR.DLL"); // not to be localized
static const TCHAR szProviderName[] = TEXT("SCRSAVE"); // not to be localized
#ifdef UNICODE
static const CHAR szPwdChangePW[] = "PwdChangePasswordW"; // not to be localized
#else
static const CHAR szPwdChangePW[] = "PwdChangePasswordA"; // not to be localized
#endif
// bogus prototype
typedef DWORD(FAR PASCAL* PWCHGPROC)(LPCTSTR, HWND, DWORD, LPVOID);
void WINAPI ScreenSaverChangePassword(HWND hParent)
{
HINSTANCE mpr = LoadLibrary(szMprDll);
if (mpr) {
// netland hasn't cracked MNRENTRY yet
PWCHGPROC pwd = (PWCHGPROC)GetProcAddress(mpr, szPwdChangePW);
if (pwd)
pwd(szProviderName, hParent, 0, NULL);
FreeLibrary(mpr);
}
}
static BOOL DoPasswordCheck(HWND hParent)
{
// don't reenter and don't check when we've already decided
if (fCheckingPassword || fClosing)
return FALSE;
if (VerifyPassword) {
static DWORD lastcheck = (DWORD)-1;
DWORD curtime = GetTickCount();
MSG msg;
if (dwPasswordDelay && (GetElapsedTime(dwBlankTime, curtime) < dwPasswordDelay)) {
fClosing = TRUE;
goto _didcheck;
}
// no rapid checking...
if ((lastcheck != (DWORD)-1) && (GetElapsedTime(lastcheck, curtime) < 200)) {
goto _didcheck;
}
fCheckingPassword = TRUE;// do the check
#ifdef GL_SCRNSAVE
// Put ss in idle mode during password dialog processing
SendMessage(hParent, SS_WM_IDLE, SS_IDLE_ON, 0L);
#endif
// flush WM_TIMER messages before putting up the dialog
PeekMessage(&msg, hParent, WM_TIMER, WM_TIMER, PM_REMOVE | PM_NOYIELD);
PeekMessage(&msg, hParent, WM_TIMER, WM_TIMER, PM_REMOVE | PM_NOYIELD);
// call the password verify proc
fClosing = (BOOL)SendMessage(hParent, SCRM_VERIFYPW, 0, 0L);
fCheckingPassword = FALSE;
#ifdef GL_SCRNSAVE
SendMessage(hParent, SS_WM_IDLE, SS_IDLE_OFF, 0L);// Restore normal display mode
#endif
if (!fClosing)
SetCursor(NULL);
lastcheck = GetTickCount();// curtime may be outdated by now
} else {
// passwords disabled or unable to load handler DLL, always allow exit
fClosing = TRUE;
}
_didcheck:
return fClosing;
}
// stolen from the CRT, used to shirink our code
int _stdcall DummyEntry(void)
{
int i;
STARTUPINFO si;
LPTSTR pszCmdLine = GetCommandLine();
if (*pszCmdLine == TEXT('\"')) {
/*
* Scan, and skip over, subsequent characters until another double-quote or a null is encountered.
*/
while (*(pszCmdLine = CharNext(pszCmdLine)) && (*pszCmdLine != TEXT('\"')));
/*
* If we stopped on a double-quote (usual case), skip over it.
*/
if (*pszCmdLine == TEXT('\"'))
pszCmdLine++;
} else {
while ((UINT)*pszCmdLine > (UINT)TEXT(' '))
pszCmdLine = CharNext(pszCmdLine);
}
/*
* Skip past any white space preceeding the second token.
*/
while (*pszCmdLine && ((UINT)*pszCmdLine <= (UINT)TEXT(' '))) {
pszCmdLine = CharNext(pszCmdLine);
}
si.dwFlags = 0;
GetStartupInfo(&si);
i = (int)WinMainN(GetModuleHandle(NULL), NULL, pszCmdLine,
si.dwFlags & STARTF_USESHOWWINDOW ? si.wShowWindow : SW_SHOWDEFAULT);
ExitProcess(i);
return i;// We never comes here.
}
// main() entry point to satisfy old NT screen savers
void _cdecl main(int argc, char* argv[]) {
DummyEntry();
}
// WinMain() entry point to satisfy old NT screen savers
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int nCmdShow) {
DummyEntry();
return 0;
// reference unreferenced parameters
(void)hInst;
(void)hPrev;
(void)szCmdLine;
(void)nCmdShow;
}
VOID LoadPwdDLL(VOID)
{
HKEY hKey;
if (!fOnWin95)
return;
if (hInstPwdDLL)
UnloadPwdDLL();
// look in registry to see if password turned on, otherwise don't
// bother to load password handler DLL
if (RegOpenKey(HKEY_CURRENT_USER, szScreenSaverKey, &hKey) == ERROR_SUCCESS) {
DWORD dwVal, dwSize = sizeof(dwVal);
if ((RegQueryValueEx(hKey, szPasswordActiveValue, NULL, NULL, (BYTE*)&dwVal, &dwSize) == ERROR_SUCCESS)
&& dwVal) {
// try to load the DLL that contains password proc.
hInstPwdDLL = LoadLibrary(szPwdDLL);
if (hInstPwdDLL) {
VerifyPassword = (VERIFYPWDPROC)GetProcAddress(hInstPwdDLL, szFnName);
if (VerifyPassword)
HogMachine(TRUE);
else
UnloadPwdDLL();
}
}
RegCloseKey(hKey);
}
}
VOID UnloadPwdDLL(VOID)
{
if (!fOnWin95)
return;
if (hInstPwdDLL) {
FreeLibrary(hInstPwdDLL);
hInstPwdDLL = NULL;
if (VerifyPassword) {
VerifyPassword = NULL;
HogMachine(FALSE);
}
}
}
// compatbility stuff (to make porting easier)
TCHAR szAppName[APPNAMEBUFFERLEN];
TCHAR szName[TITLEBARNAMELEN];
TCHAR szIniFile[MAXFILELEN];
TCHAR szScreenSaver[22];
TCHAR szHelpFile[MAXFILELEN];
TCHAR szNoHelpMemory[BUFFLEN];
// Quick fix for old screen savers that don't know about context sensitive help
UINT MyHelpMessage = WM_HELP;