Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

883 lines
26 KiB

//----------------------------------------------------------------------------
//
// SCRNSAVE.C -- skeleton for screen saver application
//
// 4/5/94 francish merged NT and Win4 saver code, folded in SCRNSAVE.SCR
//
//----------------------------------------------------------------------------
#define WIN31
#include <windows.h>
#include <windowsx.h>
#include "scrnsave.h"
#include <regstr.h>
#include <commctrl.h>
#include <imm.h>
#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)
BYTE bACLineStatus = AC_LINE_UNKNOWN; // Last state of AC line
//----------------------------------------------------------------------------
// forward declarations of internal fns
static INT_PTR DoScreenSave( HWND hParent );
static INT_PTR DoSaverPreview( LPCTSTR szUINTHandle );
static INT_PTR DoConfigBox( HWND hParent );
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;
INITCOMMONCONTROLSEX icce = {0};
ZeroMemory(&icce, sizeof(icce));
icce.dwSize = sizeof(icce);
icce.dwICC = ICC_TAB_CLASSES;
InitCommonControlsEx(&icce);
hMainInstance = hInst;
osvi.dwOSVersionInfoSize = sizeof(osvi);
fOnWin95 = (GetVersionEx(&osvi) &&
osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
_try
{
for(;;) switch( *pch )
{
case TEXT('S'):
case TEXT('s'):
return DoScreenSave( NULL );
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 );
}
return -1;
}
//----------------------------------------------------------------------------
// 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[1025];
// safe to call wsprintf with > 1024 buffer
wsprintf( szBuff, TEXT("*** DefSSP received:\t0x%04lx 0x%08lx 0x%08lx\n"), uMsg, wParam, lParam );
OutputDebugString(szBuff);
#endif
SYSTEM_POWER_STATUS sps;
BYTE bCurrentLineStatus;
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;
}
}
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;
//
// Handle Power Management event
//
case WM_POWERBROADCAST:
switch (wParam)
{
case PBT_APMPOWERSTATUSCHANGE:
if (GetSystemPowerStatus(&sps)) {
bCurrentLineStatus = sps.ACLineStatus;
}
else {
// we can't determine the power status, use default
bCurrentLineStatus = AC_LINE_UNKNOWN;
}
// If the current line status differs from the previous
// exit the screen saver, otherwise just keep running
if (bCurrentLineStatus != bACLineStatus) {
bACLineStatus = bCurrentLineStatus;
goto PostClose;
}
else {
bACLineStatus = bCurrentLineStatus;
}
break;
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:
{
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.
//
//
// APPCOMPAT -
// 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);
// establish the mouse position
GetCursorPos( &ptMouse );
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 SC_MONITORPOWER:
//
// The monitor is shutting down. Tell our client that he needs to
// cleanup and exit.
//
PostMessage( hWnd, WM_CLOSE, 0, 0l );
break;
}
}
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_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 );
}
static void
InitRealScreenSave()
{
LoadPwdDLL();
}
//----------------------------------------------------------------------------
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;
SYSTEM_POWER_STATUS sps;
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;
}
// Get current system power status and store it
if (GetSystemPowerStatus(&sps)) {
bACLineStatus = sps.ACLineStatus;
}
else {
// we can't determine the power status, use default
bACLineStatus = AC_LINE_UNKNOWN;
}
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 );
}
msg.wParam = 0;
if( hMainWindow )
{
if( !fChildPreview )
SetForegroundWindow( hMainWindow );
while( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
// free password-handling DLL if loaded
UnloadPwdDLL();
return msg.wParam;
}
//----------------------------------------------------------------------------
static INT_PTR
DoSaverPreview( LPCTSTR szUINTHandle )
{
// get parent handle from string
HWND hParent = (HWND)atoui( szUINTHandle );
// only preview on a valid parent window (NOT full screen)
return ( (hParent && IsWindow( hParent ))? DoScreenSave( hParent ) : -1 );
}
//----------------------------------------------------------------------------
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, (WNDPROC)ScreenSaverConfigureDialog );
}
//----------------------------------------------------------------------------
static INT_PTR
DoChangePw( LPCTSTR szUINTHandle )
{
// get parent handle from string
HWND hParent = (HWND)atoui( szUINTHandle );
if( !hParent || !IsWindow( hParent ) )
hParent = GetForegroundWindow();
// allow the library to be hooked
ScreenSaverChangePassword( hParent );
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;
}
// do the check
fCheckingPassword = TRUE;
// 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;
if (!fClosing)
SetCursor(NULL);
// curtime may be outdated by now
lastcheck = GetTickCount();
}
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 (RegOpenKeyEx(HKEY_CURRENT_USER,szScreenSaverKey,0, KEY_QUERY_VALUE, &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;