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

  1. //----------------------------------------------------------------------------
  2. //
  3. // SCRNSAVE.C -- skeleton for screen saver application
  4. //
  5. // 4/5/94 francish merged NT and Win4 saver code, folded in SCRNSAVE.SCR
  6. //
  7. //----------------------------------------------------------------------------
  8. #define WIN31
  9. #include <windows.h>
  10. #include <windowsx.h>
  11. #include "scrnsave.h"
  12. #include <regstr.h>
  13. #include <commctrl.h>
  14. #include <imm.h>
  15. #define DBG_MSGS 0
  16. const TCHAR szScreenSaverKey[] = REGSTR_PATH_SCREENSAVE;
  17. TCHAR szPasswordActiveValue[] = REGSTR_VALUE_USESCRPASSWORD;
  18. const TCHAR szPasswordValue[] = REGSTR_VALUE_SCRPASSWORD;
  19. TCHAR szPwdDLL[] = TEXT("PASSWORD.CPL");
  20. CHAR szFnName[] = "VerifyScreenSavePwd"; // Proc name, must be ANSI
  21. TCHAR szImmDLL[] = TEXT("IMM32.DLL");
  22. CHAR szImmFnc[] = "ImmAssociateContext"; // Proc name, must be ANSI
  23. #if 0
  24. TCHAR szCoolSaverHacks[] = REGSTR_PATH_SETUP TEXT("\\Screen Savers");
  25. TCHAR szMouseThreshold[] = TEXT("Mouse Threshold");
  26. TCHAR szPasswordDelay[] = TEXT("Password Delay");
  27. #endif
  28. typedef BOOL (FAR PASCAL * VERIFYPWDPROC) (HWND);
  29. typedef HIMC (FAR PASCAL * IMMASSOCPROC) (HWND,HIMC);
  30. //----------------------------------------------------------------------------
  31. // variables declared in SCRNSAVE.H
  32. HINSTANCE hMainInstance = 0;
  33. HWND hMainWindow = 0;
  34. BOOL fChildPreview = FALSE;
  35. //----------------------------------------------------------------------------
  36. // other globals
  37. POINT ptMouse;
  38. BOOL fClosing = FALSE;
  39. BOOL fCheckingPassword = FALSE;
  40. HINSTANCE hInstPwdDLL = NULL;
  41. VERIFYPWDPROC VerifyPassword = NULL;
  42. static BOOL preview_like_fullscreen = FALSE;
  43. static UINT uShellAutoPlayQueryMessage = 0;
  44. HINSTANCE hInstImm = NULL;
  45. IMMASSOCPROC ImmFnc = NULL;
  46. HIMC hPrevImc = (HIMC)0L;
  47. static BOOL fOnWin95 = FALSE; //TRUE if on Chicago, FALSE if on Cairo
  48. //----------------------------------------------------------------------------
  49. // random junk
  50. DWORD dwWakeThreshold = 4; //default to slight movement
  51. DWORD dwPasswordDelay = 0;
  52. DWORD dwBlankTime = 0;
  53. #define MAX_PASSWORD_DELAY_IN_SECONDS (60)
  54. BYTE bACLineStatus = AC_LINE_UNKNOWN; // Last state of AC line
  55. //----------------------------------------------------------------------------
  56. // forward declarations of internal fns
  57. static INT_PTR DoScreenSave( HWND hParent );
  58. static INT_PTR DoSaverPreview( LPCTSTR szUINTHandle );
  59. static INT_PTR DoConfigBox( HWND hParent );
  60. static INT_PTR DoChangePw( LPCTSTR szUINTHandle );
  61. static BOOL DoPasswordCheck( HWND hParent );
  62. VOID LoadPwdDLL(VOID);
  63. VOID UnloadPwdDLL(VOID);
  64. //----------------------------------------------------------------------------
  65. // helper for time
  66. static DWORD
  67. GetElapsedTime(DWORD from, DWORD to)
  68. {
  69. return (to >= from)? (to - from) : (1 + to + (((DWORD)-1) - from));
  70. }
  71. //----------------------------------------------------------------------------
  72. // helper to convert text to unsigned int
  73. static UINT_PTR
  74. atoui( LPCTSTR szUINT )
  75. {
  76. UINT_PTR uValue = 0;
  77. while( ( *szUINT >= TEXT('0') ) && ( *szUINT <= TEXT('9') ) )
  78. uValue = ( ( uValue * 10 ) + ( *szUINT++ - TEXT('0') ) );
  79. return uValue;
  80. }
  81. //----------------------------------------------------------------------------
  82. // Local reboot and hotkey control (on Win95)
  83. static void
  84. HogMachine( BOOL value )
  85. {
  86. BOOL dummy;
  87. //
  88. // NT is always secure, therefore we don't need to call this on Cairo/NT
  89. //
  90. if (fOnWin95) {
  91. SystemParametersInfo( SPI_SCREENSAVERRUNNING, value, &dummy, 0 );
  92. }
  93. }
  94. //----------------------------------------------------------------------------
  95. // entry point (duh)
  96. INT_PTR PASCAL
  97. WinMainN( HINSTANCE hInst, HINSTANCE hPrev, LPTSTR szCmdLine, int nCmdShow )
  98. {
  99. LPCTSTR pch = szCmdLine;
  100. HWND hParent = 0;
  101. OSVERSIONINFO osvi;
  102. INITCOMMONCONTROLSEX icce = {0};
  103. ZeroMemory(&icce, sizeof(icce));
  104. icce.dwSize = sizeof(icce);
  105. icce.dwICC = ICC_TAB_CLASSES;
  106. InitCommonControlsEx(&icce);
  107. hMainInstance = hInst;
  108. osvi.dwOSVersionInfoSize = sizeof(osvi);
  109. fOnWin95 = (GetVersionEx(&osvi) &&
  110. osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
  111. _try
  112. {
  113. for(;;) switch( *pch )
  114. {
  115. case TEXT('S'):
  116. case TEXT('s'):
  117. return DoScreenSave( NULL );
  118. case TEXT('L'):
  119. case TEXT('l'):
  120. // special switch for tests such as WinBench
  121. // this is NOT a hack to make bechmarks look good
  122. // it's a hack to allow you to benchmark a screen saver
  123. // many bechmarking apps require the whole screen in foreground
  124. // which makes it hard to measure how a screensaver adds CPU load
  125. // you must provide a parent window (just like preview mode)
  126. preview_like_fullscreen = TRUE;
  127. case TEXT('P'):
  128. case TEXT('p'):
  129. do pch++; while( *pch == TEXT(' ') ); // skip to the good stuff
  130. return DoSaverPreview( pch );
  131. case TEXT('A'):
  132. case TEXT('a'):
  133. if (!fOnWin95)
  134. return -1;
  135. do pch++; while( *pch == TEXT(' ') ); // skip to the good stuff
  136. return DoChangePw( pch );
  137. case TEXT('C'):
  138. case TEXT('c'): {
  139. HWND hwndParent = NULL
  140. ;
  141. // Look for optional parent window after the "C",
  142. // syntax is "C:hwnd_value"
  143. if (*(++pch) == TEXT(':')) {
  144. hwndParent = (HWND)atoui( ++pch );
  145. }
  146. if (hwndParent == NULL || !IsWindow(hwndParent))
  147. hwndParent = GetForegroundWindow();
  148. return DoConfigBox( hwndParent );
  149. }
  150. case TEXT('\0'):
  151. return DoConfigBox( NULL );
  152. case TEXT(' '):
  153. case TEXT('-'):
  154. case TEXT('/'):
  155. pch++; // skip spaces and common switch prefixes
  156. break;
  157. default:
  158. return -1;
  159. }
  160. }
  161. _except(UnhandledExceptionFilter(GetExceptionInformation()))
  162. {
  163. // don't leave local reboot and hotkeys disabled on Win95
  164. HogMachine( FALSE );
  165. }
  166. return -1;
  167. }
  168. //----------------------------------------------------------------------------
  169. // default screen-saver proc, declared in SCRNSAVE.H
  170. // intended to be called by the consumer's ScreenSaverProc where
  171. // DefWindowProc would normally be called
  172. LRESULT WINAPI
  173. DefScreenSaverProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  174. {
  175. #if DBG_MSGS
  176. TCHAR szBuff[1025];
  177. // safe to call wsprintf with > 1024 buffer
  178. wsprintf( szBuff, TEXT("*** DefSSP received:\t0x%04lx 0x%08lx 0x%08lx\n"), uMsg, wParam, lParam );
  179. OutputDebugString(szBuff);
  180. #endif
  181. SYSTEM_POWER_STATUS sps;
  182. BYTE bCurrentLineStatus;
  183. if( !fChildPreview && !fClosing )
  184. {
  185. switch( uMsg )
  186. {
  187. case WM_CLOSE:
  188. //
  189. // Only do password check if on Windows 95. WinNT (Cairo) has
  190. // the password check built into the security desktop for
  191. // C2 compliance.
  192. //
  193. if (fOnWin95) {
  194. if( !DoPasswordCheck( hWnd ) )
  195. {
  196. GetCursorPos( &ptMouse ); // re-establish
  197. return FALSE;
  198. }
  199. }
  200. break;
  201. case SCRM_VERIFYPW:
  202. if (fOnWin95)
  203. return ( VerifyPassword? (LRESULT)VerifyPassword( hWnd ) : 1L );
  204. break;
  205. default:
  206. {
  207. POINT ptMove, ptCheck;
  208. if( fCheckingPassword )
  209. break;
  210. switch( uMsg )
  211. {
  212. case WM_SHOWWINDOW:
  213. if( (BOOL)wParam )
  214. SetCursor( NULL );
  215. break;
  216. case WM_SETCURSOR:
  217. SetCursor( NULL );
  218. return TRUE;
  219. case WM_MOUSEMOVE:
  220. GetCursorPos( &ptCheck );
  221. if( ( ptMove.x = ptCheck.x - ptMouse.x ) && ( ptMove.x < 0 ) )
  222. ptMove.x *= -1;
  223. if( ( ptMove.y = ptCheck.y - ptMouse.y ) && ( ptMove.y < 0 ) )
  224. ptMove.y *= -1;
  225. if( ((DWORD)ptMove.x + (DWORD)ptMove.y) > dwWakeThreshold )
  226. {
  227. PostMessage( hWnd, WM_CLOSE, 0, 0l );
  228. ptMouse = ptCheck;
  229. }
  230. break;
  231. //
  232. // Handle Power Management event
  233. //
  234. case WM_POWERBROADCAST:
  235. switch (wParam)
  236. {
  237. case PBT_APMPOWERSTATUSCHANGE:
  238. if (GetSystemPowerStatus(&sps)) {
  239. bCurrentLineStatus = sps.ACLineStatus;
  240. }
  241. else {
  242. // we can't determine the power status, use default
  243. bCurrentLineStatus = AC_LINE_UNKNOWN;
  244. }
  245. // If the current line status differs from the previous
  246. // exit the screen saver, otherwise just keep running
  247. if (bCurrentLineStatus != bACLineStatus) {
  248. bACLineStatus = bCurrentLineStatus;
  249. goto PostClose;
  250. }
  251. else {
  252. bACLineStatus = bCurrentLineStatus;
  253. }
  254. break;
  255. case PBT_APMRESUMECRITICAL:
  256. case PBT_APMRESUMESUSPEND:
  257. case PBT_APMRESUMESTANDBY:
  258. case PBT_APMRESUMEAUTOMATIC:
  259. // If the system is resuming from a real suspend
  260. // (as opposed to a failed suspend) deactivate
  261. // the screensaver.
  262. if ((lParam & PBTF_APMRESUMEFROMFAILURE) == 0)
  263. {
  264. goto PostClose;
  265. }
  266. break;
  267. default:
  268. {
  269. goto PostClose;
  270. }
  271. }
  272. break;
  273. case WM_POWER:
  274. //
  275. // a critical resume does not generate a WM_POWERBROADCAST
  276. // to windows for some reason, but it does generate an old
  277. // WM_POWER message.
  278. //
  279. if (wParam == PWR_CRITICALRESUME)
  280. goto PostClose;
  281. break;
  282. case WM_ACTIVATEAPP:
  283. if( wParam ) break;
  284. case WM_LBUTTONDOWN:
  285. case WM_MBUTTONDOWN:
  286. case WM_RBUTTONDOWN:
  287. case WM_KEYDOWN:
  288. case WM_SYSKEYDOWN:
  289. PostClose:
  290. PostMessage( hWnd, WM_CLOSE, 0, 0l );
  291. break;
  292. }
  293. }
  294. }
  295. }
  296. //
  297. // the shell sends this message to the foreground window before running an
  298. // AutoPlay app. On Win95, we return 1 to cancel autoplay if we are password protected
  299. //
  300. // On WinNT, secure screen savers run on a secure separate desktop, and will never see
  301. // this message, therefore, this code will never get executed.
  302. //
  303. //
  304. // APPCOMPAT -
  305. // On NT we don't want to take down the screen saver unless it is running
  306. // on the same desktop as the autoplay shell. There is code in the
  307. // NT autoplay shell that looks for this and does not run the app if
  308. // that is the case; however, I not positive that the uShellAutoPlayQueryMessage
  309. // will not go between desktops. (BradG assures me that it will not, but you
  310. // never know.) If secure screensavers on NT randomly close when you put
  311. // an autoplay cd in the drive, then this code should be examined closely.
  312. //
  313. if ((uMsg == uShellAutoPlayQueryMessage) && uMsg)
  314. {
  315. PostMessage(hWnd, WM_CLOSE, 0, 0L);
  316. return (VerifyPassword != NULL);
  317. }
  318. return DefWindowProc( hWnd, uMsg, wParam, lParam );
  319. }
  320. //----------------------------------------------------------------------------
  321. // This window procedure takes care of important stuff before calling the
  322. // consumer's ScreenSaverProc. This helps to prevent us from getting hosed
  323. // by wacky consumer code.
  324. LRESULT WINAPI
  325. RealScreenSaverProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  326. {
  327. switch( uMsg )
  328. {
  329. case WM_CREATE:
  330. // screen saver does not need the IME
  331. if ((hInstImm = GetModuleHandle(szImmDLL)) &&
  332. (ImmFnc = (IMMASSOCPROC)GetProcAddress(hInstImm,szImmFnc)))
  333. hPrevImc = ImmFnc(hWnd, (HIMC)0);
  334. // establish the mouse position
  335. GetCursorPos( &ptMouse );
  336. if( !fChildPreview )
  337. SetCursor( NULL );
  338. break;
  339. case WM_DESTROY:
  340. // screen saver does not need the IME
  341. if( hInstImm && ImmFnc && hPrevImc )
  342. ImmFnc(hWnd, hPrevImc);
  343. PostQuitMessage( 0 );
  344. break;
  345. case WM_SETTEXT:
  346. // don't let some fool change our title
  347. // we need to be able to use FindWindow() to find running instances
  348. // of full-screen windows screen savers
  349. // NOTE: USER slams our title in during WM_NCCREATE by calling the
  350. // defproc for WM_SETTEXT directly, so the initial title will get
  351. // there. If this ever changes, we can simply set a bypass flag
  352. // during WM_NCCREATE processing.
  353. return FALSE;
  354. case WM_SYSCOMMAND:
  355. if (!fChildPreview)
  356. {
  357. switch (wParam)
  358. {
  359. case SC_NEXTWINDOW: // no Alt-tabs
  360. case SC_PREVWINDOW: // no shift-alt-tabs
  361. case SC_SCREENSAVE: // no more screensavers
  362. return FALSE;
  363. break;
  364. case SC_MONITORPOWER:
  365. //
  366. // The monitor is shutting down. Tell our client that he needs to
  367. // cleanup and exit.
  368. //
  369. PostMessage( hWnd, WM_CLOSE, 0, 0l );
  370. break;
  371. }
  372. }
  373. break;
  374. case WM_HELP:
  375. case WM_CONTEXTMENU:
  376. if( fChildPreview )
  377. {
  378. // if we're in preview mode, pump the help stuff to our owner
  379. HWND hParent = GetParent( hWnd );
  380. if( hParent && IsWindow( hParent ) )
  381. PostMessage( hParent, uMsg, (WPARAM)hParent, lParam );
  382. return TRUE;
  383. }
  384. break;
  385. case WM_TIMER:
  386. if( fClosing )
  387. return FALSE;
  388. Sleep( 0 );
  389. break;
  390. case WM_MOUSEMOVE:
  391. case WM_LBUTTONDOWN:
  392. case WM_MBUTTONDOWN:
  393. case WM_RBUTTONDOWN:
  394. case WM_KEYDOWN:
  395. case WM_SYSKEYDOWN:
  396. if( fClosing )
  397. return DefWindowProc( hWnd, uMsg, wParam, lParam );
  398. break;
  399. case WM_PAINT:
  400. if( fClosing )
  401. return DefWindowProc( hWnd, uMsg, wParam, lParam );
  402. if( !fChildPreview )
  403. SetCursor( NULL );
  404. break;
  405. }
  406. return ScreenSaverProc( hWnd, uMsg, wParam, lParam );
  407. }
  408. static void
  409. InitRealScreenSave()
  410. {
  411. LoadPwdDLL();
  412. }
  413. //----------------------------------------------------------------------------
  414. static INT_PTR
  415. DoScreenSave( HWND hParent )
  416. {
  417. LPCTSTR pszWindowClass = TEXT("WindowsScreenSaverClass");
  418. LPCTSTR pszWindowTitle;
  419. WNDCLASS cls;
  420. MSG msg;
  421. UINT uStyle;
  422. UINT uExStyle;
  423. int ncx, ncy;
  424. int nx, ny;
  425. SYSTEM_POWER_STATUS sps;
  426. cls.hCursor = NULL;
  427. cls.hIcon = LoadIcon( hMainInstance, MAKEINTATOM( ID_APP ) );
  428. cls.lpszMenuName = NULL;
  429. cls.lpszClassName = pszWindowClass;
  430. cls.hbrBackground = GetStockObject( BLACK_BRUSH );
  431. cls.hInstance = hMainInstance;
  432. cls.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_OWNDC;
  433. cls.lpfnWndProc = RealScreenSaverProc;
  434. cls.cbWndExtra = 0;
  435. cls.cbClsExtra = 0;
  436. if( hParent )
  437. {
  438. RECT rcParent;
  439. GetClientRect( hParent, &rcParent );
  440. ncx = rcParent.right;
  441. ncy = rcParent.bottom;
  442. nx = 0;
  443. ny = 0;
  444. uStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN;
  445. uExStyle = 0;
  446. fChildPreview = TRUE;
  447. pszWindowTitle = TEXT("Preview"); // MUST differ from full screen
  448. }
  449. else
  450. {
  451. HWND hOther;
  452. #ifdef SM_CXVIRTUALSCREEN
  453. nx = GetSystemMetrics( SM_XVIRTUALSCREEN );
  454. ny = GetSystemMetrics( SM_YVIRTUALSCREEN );
  455. ncx = GetSystemMetrics( SM_CXVIRTUALSCREEN );
  456. ncy = GetSystemMetrics( SM_CYVIRTUALSCREEN );
  457. if (ncx == 0 || ncy == 0)
  458. #endif
  459. {
  460. RECT rc;
  461. HDC hdc = GetDC(NULL);
  462. GetClipBox(hdc, &rc);
  463. ReleaseDC(NULL, hdc);
  464. nx = rc.left;
  465. ny = rc.top;
  466. ncx = rc.right - rc.left;
  467. ncy = rc.bottom - rc.top;
  468. }
  469. uStyle = WS_POPUP | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
  470. uExStyle = WS_EX_TOPMOST;
  471. pszWindowTitle = TEXT("Screen Saver"); // MUST differ from preview
  472. // if there is another NORMAL screen save instance, switch to it
  473. hOther = FindWindow( pszWindowClass, pszWindowTitle );
  474. if( hOther && IsWindow( hOther ) )
  475. {
  476. SetForegroundWindow( hOther );
  477. return 0;
  478. }
  479. // Get current system power status and store it
  480. if (GetSystemPowerStatus(&sps)) {
  481. bACLineStatus = sps.ACLineStatus;
  482. }
  483. else {
  484. // we can't determine the power status, use default
  485. bACLineStatus = AC_LINE_UNKNOWN;
  486. }
  487. InitRealScreenSave();
  488. }
  489. //
  490. // the shell sends this message to the foreground window before running an
  491. // AutoPlay app. we return 1 to cancel autoplay if we are password protected
  492. //
  493. if (fOnWin95) {
  494. uShellAutoPlayQueryMessage = RegisterWindowMessage(TEXT("QueryCancelAutoPlay"));
  495. } else {
  496. uShellAutoPlayQueryMessage = 0;
  497. }
  498. if( RegisterClass( &cls ) )
  499. {
  500. hMainWindow = CreateWindowEx( uExStyle, pszWindowClass, pszWindowTitle,
  501. uStyle, nx, ny, ncx, ncy, hParent, (HMENU)NULL,
  502. hMainInstance, (LPVOID)NULL );
  503. }
  504. msg.wParam = 0;
  505. if( hMainWindow )
  506. {
  507. if( !fChildPreview )
  508. SetForegroundWindow( hMainWindow );
  509. while( GetMessage( &msg, NULL, 0, 0 ) )
  510. {
  511. TranslateMessage( &msg );
  512. DispatchMessage( &msg );
  513. }
  514. }
  515. // free password-handling DLL if loaded
  516. UnloadPwdDLL();
  517. return msg.wParam;
  518. }
  519. //----------------------------------------------------------------------------
  520. static INT_PTR
  521. DoSaverPreview( LPCTSTR szUINTHandle )
  522. {
  523. // get parent handle from string
  524. HWND hParent = (HWND)atoui( szUINTHandle );
  525. // only preview on a valid parent window (NOT full screen)
  526. return ( (hParent && IsWindow( hParent ))? DoScreenSave( hParent ) : -1 );
  527. }
  528. //----------------------------------------------------------------------------
  529. static INT_PTR
  530. DoConfigBox( HWND hParent )
  531. {
  532. // let the consumer register any special controls for the dialog
  533. if( !RegisterDialogClasses( hMainInstance ) )
  534. return FALSE;
  535. return DialogBox( hMainInstance, MAKEINTRESOURCE( DLG_SCRNSAVECONFIGURE ),
  536. hParent, (WNDPROC)ScreenSaverConfigureDialog );
  537. }
  538. //----------------------------------------------------------------------------
  539. static INT_PTR
  540. DoChangePw( LPCTSTR szUINTHandle )
  541. {
  542. // get parent handle from string
  543. HWND hParent = (HWND)atoui( szUINTHandle );
  544. if( !hParent || !IsWindow( hParent ) )
  545. hParent = GetForegroundWindow();
  546. // allow the library to be hooked
  547. ScreenSaverChangePassword( hParent );
  548. return 0;
  549. }
  550. static const TCHAR szMprDll[] = TEXT("MPR.DLL"); // not to be localized
  551. static const TCHAR szProviderName[] = TEXT("SCRSAVE"); // not to be localized
  552. #ifdef UNICODE
  553. static const CHAR szPwdChangePW[] = "PwdChangePasswordW"; // not to be localized
  554. #else
  555. static const CHAR szPwdChangePW[] = "PwdChangePasswordA"; // not to be localized
  556. #endif
  557. // bogus prototype
  558. typedef DWORD (FAR PASCAL *PWCHGPROC)( LPCTSTR, HWND, DWORD, LPVOID );
  559. void WINAPI
  560. ScreenSaverChangePassword( HWND hParent )
  561. {
  562. HINSTANCE mpr = LoadLibrary( szMprDll );
  563. if( mpr )
  564. {
  565. // netland hasn't cracked MNRENTRY yet
  566. PWCHGPROC pwd = (PWCHGPROC)GetProcAddress( mpr, szPwdChangePW );
  567. if( pwd )
  568. pwd( szProviderName, hParent, 0, NULL );
  569. FreeLibrary( mpr );
  570. }
  571. }
  572. //----------------------------------------------------------------------------
  573. static BOOL
  574. DoPasswordCheck( HWND hParent )
  575. {
  576. // don't reenter and don't check when we've already decided
  577. if( fCheckingPassword || fClosing )
  578. return FALSE;
  579. if( VerifyPassword )
  580. {
  581. static DWORD lastcheck = (DWORD)-1;
  582. DWORD curtime = GetTickCount();
  583. MSG msg;
  584. if (dwPasswordDelay &&
  585. (GetElapsedTime(dwBlankTime, curtime) < dwPasswordDelay))
  586. {
  587. fClosing = TRUE;
  588. goto _didcheck;
  589. }
  590. // no rapid checking...
  591. if ((lastcheck != (DWORD)-1) &&
  592. (GetElapsedTime(lastcheck, curtime) < 200))
  593. {
  594. goto _didcheck;
  595. }
  596. // do the check
  597. fCheckingPassword = TRUE;
  598. // flush WM_TIMER messages before putting up the dialog
  599. PeekMessage( &msg, hParent, WM_TIMER, WM_TIMER, PM_REMOVE | PM_NOYIELD );
  600. PeekMessage( &msg, hParent, WM_TIMER, WM_TIMER, PM_REMOVE | PM_NOYIELD );
  601. // call the password verify proc
  602. fClosing = (BOOL)SendMessage( hParent, SCRM_VERIFYPW, 0, 0L );
  603. fCheckingPassword = FALSE;
  604. if (!fClosing)
  605. SetCursor(NULL);
  606. // curtime may be outdated by now
  607. lastcheck = GetTickCount();
  608. }
  609. else
  610. {
  611. // passwords disabled or unable to load handler DLL, always allow exit
  612. fClosing = TRUE;
  613. }
  614. _didcheck:
  615. return fClosing;
  616. }
  617. //----------------------------------------------------------------------------
  618. // stolen from the CRT, used to shirink our code
  619. int _stdcall
  620. DummyEntry( void )
  621. {
  622. int i;
  623. STARTUPINFO si;
  624. LPTSTR pszCmdLine = GetCommandLine();
  625. if ( *pszCmdLine == TEXT('\"')) {
  626. /*
  627. * Scan, and skip over, subsequent characters until
  628. * another double-quote or a null is encountered.
  629. */
  630. while (*(pszCmdLine = CharNext(pszCmdLine)) &&
  631. (*pszCmdLine != TEXT('\"')) );
  632. /*
  633. * If we stopped on a double-quote (usual case), skip
  634. * over it.
  635. */
  636. if ( *pszCmdLine == TEXT('\"') )
  637. pszCmdLine++;
  638. }
  639. else {
  640. while ((UINT)*pszCmdLine > (UINT)TEXT(' '))
  641. pszCmdLine = CharNext(pszCmdLine);
  642. }
  643. /*
  644. * Skip past any white space preceeding the second token.
  645. */
  646. while (*pszCmdLine && ((UINT)*pszCmdLine <= (UINT)TEXT(' '))) {
  647. pszCmdLine = CharNext(pszCmdLine);
  648. }
  649. si.dwFlags = 0;
  650. GetStartupInfo(&si);
  651. i = (int)WinMainN(GetModuleHandle(NULL), NULL, pszCmdLine,
  652. si.dwFlags & STARTF_USESHOWWINDOW ? si.wShowWindow : SW_SHOWDEFAULT);
  653. ExitProcess(i);
  654. return i; // We never comes here.
  655. }
  656. //----------------------------------------------------------------------------
  657. // main() entry point to satisfy old NT screen savers
  658. void _cdecl main( int argc, char *argv[] ) {
  659. DummyEntry();
  660. }
  661. //----------------------------------------------------------------------------
  662. // WinMain() entry point to satisfy old NT screen savers
  663. int PASCAL WinMain( HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int nCmdShow ) {
  664. DummyEntry();
  665. return 0;
  666. // reference unreferenced parameters
  667. (void)hInst;
  668. (void)hPrev;
  669. (void)szCmdLine;
  670. (void)nCmdShow;
  671. }
  672. VOID LoadPwdDLL(VOID)
  673. {
  674. HKEY hKey;
  675. if (!fOnWin95)
  676. return;
  677. if (hInstPwdDLL)
  678. UnloadPwdDLL();
  679. // look in registry to see if password turned on, otherwise don't
  680. // bother to load password handler DLL
  681. if (RegOpenKeyEx(HKEY_CURRENT_USER,szScreenSaverKey,0, KEY_QUERY_VALUE, &hKey) ==
  682. ERROR_SUCCESS)
  683. {
  684. DWORD dwVal,dwSize=sizeof(dwVal);
  685. if ((RegQueryValueEx(hKey,szPasswordActiveValue,
  686. NULL,NULL,(BYTE *) &dwVal,&dwSize) == ERROR_SUCCESS)
  687. && dwVal)
  688. {
  689. // try to load the DLL that contains password proc.
  690. hInstPwdDLL = LoadLibrary(szPwdDLL);
  691. if (hInstPwdDLL)
  692. {
  693. VerifyPassword = (VERIFYPWDPROC) GetProcAddress(hInstPwdDLL,
  694. szFnName);
  695. if( VerifyPassword )
  696. HogMachine( TRUE );
  697. else
  698. UnloadPwdDLL();
  699. }
  700. }
  701. RegCloseKey(hKey);
  702. }
  703. }
  704. VOID UnloadPwdDLL(VOID)
  705. {
  706. if (!fOnWin95)
  707. return;
  708. if (hInstPwdDLL)
  709. {
  710. FreeLibrary(hInstPwdDLL);
  711. hInstPwdDLL = NULL;
  712. if( VerifyPassword )
  713. {
  714. VerifyPassword = NULL;
  715. HogMachine( FALSE );
  716. }
  717. }
  718. }
  719. //----------------------------------------------------------------------------
  720. // compatbility stuff (to make porting easier)
  721. TCHAR szAppName[ APPNAMEBUFFERLEN ];
  722. TCHAR szName[ TITLEBARNAMELEN ];
  723. TCHAR szIniFile[ MAXFILELEN ];
  724. TCHAR szScreenSaver[ 22 ];
  725. TCHAR szHelpFile[ MAXFILELEN ];
  726. TCHAR szNoHelpMemory[ BUFFLEN ];
  727. // Quick fix for old screen savers that don't know about context
  728. // sensitive help
  729. UINT MyHelpMessage = WM_HELP;