Source code of Windows XP (NT5)
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.

397 lines
11 KiB

  1. #include "stdafx.h"
  2. #include "DXSvr.h"
  3. #include <regstr.h>
  4. //***************************************************************************************
  5. // Globals
  6. HINSTANCE g_hMainInstance; // Main instance handle
  7. BOOL g_bIsTest; // Is in test mode?
  8. BOOL g_bIsPreview; // Is in preview mode?
  9. HWND g_hWnd; // Handle of the rendering window
  10. HWND g_hRefWindow; // Reference window (for preview mode)
  11. LPSTR g_szCommandLine; // Command line
  12. BOOL g_bCheckingPassword;
  13. BOOL g_bShuttingDown;
  14. ID3DXContext* g_pXContext; // X-Library context
  15. IDirect3DDevice7* g_pDevice; // D3D Device
  16. //***************************************************************************************
  17. BOOL g_bIsWin9x;
  18. BOOL g_bWait;
  19. DWORD g_dwMouseMoveCount;
  20. BOOL InitD3D(HWND hWnd);
  21. void KillD3D();
  22. //***************************************************************************************
  23. // Password stuff
  24. const TCHAR szScreenSaverKey[] = REGSTR_PATH_SCREENSAVE;
  25. TCHAR szPasswordActiveValue[] = REGSTR_VALUE_USESCRPASSWORD;
  26. const TCHAR szPasswordValue[] = REGSTR_VALUE_SCRPASSWORD;
  27. TCHAR szPwdDLL[] = TEXT("PASSWORD.CPL");
  28. char szFnName[] = "VerifyScreenSavePwd";
  29. typedef BOOL (FAR PASCAL * VERIFYPWDPROC) (HWND);
  30. VERIFYPWDPROC VerifyPassword = NULL;
  31. HINSTANCE hInstPwdDLL = NULL;
  32. static LPTSTR szMprDll = TEXT("MPR.DLL");
  33. static LPTSTR szProviderName = TEXT("SCRSAVE");
  34. static const char szPwdChangePW[] = "PwdChangePasswordA";
  35. typedef DWORD (FAR PASCAL *PWCHGPROC)(LPCTSTR, HWND, DWORD, LPVOID);
  36. //***************************************************************************************
  37. void ScreenSaverChangePassword(HWND hParent)
  38. {
  39. HINSTANCE mpr = LoadLibrary(szMprDll);
  40. if (mpr)
  41. {
  42. PWCHGPROC pwd = (PWCHGPROC)GetProcAddress(mpr, szPwdChangePW);
  43. if (pwd)
  44. pwd(szProviderName, hParent, 0, NULL);
  45. FreeLibrary(mpr);
  46. }
  47. }
  48. //***************************************************************************************
  49. void LoadPwdDLL()
  50. {
  51. // Don't bother unless we're on 9x
  52. if (!g_bIsWin9x)
  53. return;
  54. // look in registry to see if password turned on, otherwise don't
  55. // bother to load password handler DLL
  56. HKEY hKey;
  57. if (RegOpenKey(HKEY_CURRENT_USER,szScreenSaverKey,&hKey) ==
  58. ERROR_SUCCESS)
  59. {
  60. DWORD dwVal,dwSize=sizeof(dwVal);
  61. if ((RegQueryValueEx(hKey,szPasswordActiveValue,
  62. NULL,NULL,(BYTE *) &dwVal,&dwSize) == ERROR_SUCCESS)
  63. && dwVal)
  64. {
  65. // try to load the DLL that contains password proc.
  66. hInstPwdDLL = LoadLibrary(szPwdDLL);
  67. if (hInstPwdDLL)
  68. {
  69. VerifyPassword = (VERIFYPWDPROC) GetProcAddress(hInstPwdDLL, szFnName);
  70. }
  71. }
  72. RegCloseKey(hKey);
  73. }
  74. }
  75. //***************************************************************************************
  76. int DXSvrMain(HINSTANCE hInstance, HINSTANCE hInstPrev, LPSTR pszCmdLine, int)
  77. {
  78. // Store our instance handle for later use
  79. g_hMainInstance = hInstance;
  80. // Figure out if we're on 9x or NT (password stuff is different)
  81. OSVERSIONINFO osvi;
  82. osvi.dwOSVersionInfoSize = sizeof(osvi);
  83. GetVersionEx(&osvi);
  84. g_bIsWin9x = (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
  85. // Load the password DLL
  86. LoadPwdDLL();
  87. // Parse the command line
  88. g_szCommandLine = pszCmdLine;
  89. LPCSTR pszSwitch = StrChrA(pszCmdLine, '/');
  90. if (pszSwitch == NULL)
  91. {
  92. return ScreenSaverDoConfig();
  93. }
  94. else
  95. {
  96. pszSwitch++; // Skip past the '/'.
  97. switch (*pszSwitch)
  98. {
  99. case 't':
  100. case 'T':
  101. g_bIsTest = TRUE;
  102. break;
  103. case 'p':
  104. case 'P':
  105. while (*pszSwitch && !isdigit(*pszSwitch))
  106. pszSwitch++;
  107. if (isdigit(*pszSwitch))
  108. {
  109. LONGLONG llSize;
  110. if (StrToInt64ExA(pszSwitch, 0, &llSize))
  111. {
  112. g_hRefWindow = HWND(llSize);
  113. }
  114. if (g_hRefWindow != NULL)
  115. g_bIsPreview = TRUE;
  116. }
  117. break;
  118. case 'a':
  119. case 'A':
  120. while (*pszSwitch && !isdigit(*pszSwitch))
  121. pszSwitch++;
  122. if (isdigit(*pszSwitch))
  123. {
  124. LONGLONG llSize;
  125. if (StrToInt64ExA(pszSwitch, 0, &llSize))
  126. {
  127. g_hRefWindow = HWND(llSize);
  128. }
  129. }
  130. ScreenSaverChangePassword(g_hRefWindow);
  131. return 0;
  132. case 'c':
  133. case 'C':
  134. return ScreenSaverDoConfig();
  135. }
  136. }
  137. // Register the window class
  138. WNDCLASS cls;
  139. cls.hCursor = NULL;
  140. cls.hIcon = NULL;
  141. cls.lpszMenuName = NULL;
  142. cls.lpszClassName = TEXT("DXSvrWindow");
  143. cls.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
  144. cls.hInstance = g_hMainInstance;
  145. cls.style = CS_VREDRAW|CS_HREDRAW|CS_SAVEBITS|CS_DBLCLKS;
  146. cls.lpfnWndProc = ScreenSaverProc;
  147. cls.cbWndExtra = 0;
  148. cls.cbClsExtra = 0;
  149. RegisterClass(&cls);
  150. g_bWait = TRUE;
  151. // Create the window
  152. RECT rect;
  153. if (g_bIsTest)
  154. {
  155. rect.left = rect.top = 40;
  156. rect.right = rect.left+640;
  157. rect.bottom = rect.top+480;
  158. AdjustWindowRect(&rect , WS_VISIBLE|WS_OVERLAPPED|WS_CAPTION|WS_POPUP , FALSE);
  159. g_hWnd = CreateWindow(TEXT("DXSvrWindow"), TEXT("ScreenSaverTest"),
  160. WS_VISIBLE|WS_OVERLAPPED|WS_CAPTION|WS_POPUP , rect.left , rect.top ,
  161. rect.right-rect.left , rect.bottom-rect.top , NULL ,
  162. NULL , g_hMainInstance , NULL);
  163. }
  164. else if (g_bIsPreview)
  165. {
  166. GetClientRect(g_hRefWindow , &rect);
  167. ClientToScreen(g_hRefWindow , (POINT*)(&rect));
  168. rect.right += rect.left; rect.bottom += rect.top;
  169. AdjustWindowRect(&rect , WS_VISIBLE|WS_CHILD , FALSE);
  170. g_hWnd = CreateWindow(TEXT("DXSvrWindow"), TEXT("ScreenSaverPreview"),
  171. WS_VISIBLE|WS_CHILD , rect.left , rect.top ,
  172. rect.right-rect.left , rect.bottom-rect.top , g_hRefWindow ,
  173. NULL , g_hMainInstance , NULL);
  174. }
  175. else
  176. {
  177. g_hWnd = CreateWindowEx(WS_EX_TOPMOST , TEXT("DXSvrWindow"), TEXT("ScreenSaver"),
  178. WS_MAXIMIZE|WS_VISIBLE|WS_POPUP , 0 , 0 , 640 , 480 , NULL ,
  179. NULL , g_hMainInstance , NULL);
  180. }
  181. if (g_hWnd == NULL)
  182. return 0;
  183. // Prevent task switching if we're on 9x
  184. BOOL dummy;
  185. if (!g_bIsTest && !g_bIsPreview && g_bIsWin9x)
  186. SystemParametersInfo(SPI_SCREENSAVERRUNNING, TRUE, &dummy, 0);
  187. // Pump messages
  188. MSG msg;
  189. msg.message = 0;
  190. while (msg.message != WM_QUIT)
  191. {
  192. if (g_bWait)
  193. {
  194. GetMessage(&msg , NULL , 0 , 0);
  195. TranslateMessage(&msg);
  196. DispatchMessage(&msg);
  197. g_bWait = FALSE;
  198. }
  199. else
  200. {
  201. if (PeekMessage(&msg , NULL , 0 , 0 , PM_REMOVE))
  202. {
  203. TranslateMessage(&msg);
  204. DispatchMessage(&msg);
  205. }
  206. else
  207. ScreenSaverDrawFrame();
  208. }
  209. }
  210. // Allow task switching if we disabled it
  211. if (!g_bIsTest && !g_bIsPreview && g_bIsWin9x)
  212. SystemParametersInfo(SPI_SCREENSAVERRUNNING, FALSE, &dummy, 0);
  213. // Unload the password DLL
  214. if (hInstPwdDLL)
  215. FreeLibrary(hInstPwdDLL);
  216. // Done
  217. return 0;
  218. }
  219. void _stdcall ModuleEntry(void)
  220. {
  221. CHAR szCmdLine[MAX_PATH];
  222. LPCTSTR pszCmdLine = GetCommandLine();
  223. SHTCharToAnsi(pszCmdLine, szCmdLine, ARRAYSIZE(szCmdLine));
  224. int nReturn = DXSvrMain(GetModuleHandle(NULL), NULL, szCmdLine, SW_SHOWDEFAULT);
  225. ExitProcess(nReturn);
  226. }
  227. //***************************************************************************************
  228. BOOL DoPasswordCheck(HWND hWnd)
  229. {
  230. // Don't check if we're already checking or being shut down
  231. if (g_bCheckingPassword || g_bShuttingDown)
  232. return FALSE;
  233. // If no VerifyPassword function, then no password is set or we're on NT. Either way just
  234. // say the password was okay.
  235. if (VerifyPassword == NULL)
  236. return TRUE;
  237. g_bCheckingPassword = TRUE;
  238. if (g_pXContext != NULL)
  239. {
  240. IDirectDraw7* dd = g_pXContext->GetDD();
  241. if (dd != NULL)
  242. {
  243. dd->FlipToGDISurface();
  244. dd->Release();
  245. }
  246. }
  247. BOOL password_okay = VerifyPassword(hWnd);
  248. g_bCheckingPassword = FALSE;
  249. if (!password_okay)
  250. SetCursor(NULL);
  251. g_dwMouseMoveCount = 0;
  252. return password_okay;
  253. }
  254. //***************************************************************************************
  255. LONG DefDXScreenSaverProc(HWND hWnd , UINT message , WPARAM wParam , LPARAM lParam)
  256. {
  257. switch (message)
  258. {
  259. case WM_CREATE:
  260. if (!InitD3D(hWnd))
  261. return -1;
  262. if (!ScreenSaverInit())
  263. return -1;
  264. g_bWait = FALSE;
  265. break;
  266. case WM_DESTROY:
  267. ScreenSaverShutdown();
  268. KillD3D();
  269. PostQuitMessage(0);
  270. g_bWait = TRUE;
  271. break;
  272. case WM_SETCURSOR:
  273. SetCursor(NULL);
  274. return TRUE;
  275. case WM_CHAR:
  276. if (g_bIsTest)
  277. DestroyWindow(hWnd);
  278. else if (!g_bIsPreview)
  279. PostMessage(hWnd , WM_CLOSE , 0 , 0);
  280. break;
  281. case WM_PAINT:
  282. {
  283. PAINTSTRUCT ps;
  284. BeginPaint(hWnd , &ps);
  285. EndPaint(hWnd , &ps);
  286. return 0;
  287. }
  288. case WM_ERASEBKGND:
  289. return TRUE;
  290. case WM_MOUSEMOVE:
  291. if (!g_bIsTest && !g_bIsPreview)
  292. {
  293. g_dwMouseMoveCount++;
  294. if (g_dwMouseMoveCount >= 3)
  295. PostMessage(hWnd , WM_CLOSE , 0 , 0);
  296. }
  297. break;
  298. case WM_LBUTTONDOWN:
  299. case WM_RBUTTONDOWN:
  300. case WM_MBUTTONDOWN:
  301. if (!g_bIsTest && !g_bIsPreview)
  302. PostMessage(hWnd , WM_CLOSE , 0 , 0);
  303. break;
  304. case WM_CLOSE:
  305. if (g_bIsWin9x && !g_bIsPreview)
  306. {
  307. if (!DoPasswordCheck(hWnd))
  308. return FALSE;
  309. }
  310. break;
  311. case WM_SYSCOMMAND:
  312. if (!g_bIsPreview && !g_bIsTest)
  313. {
  314. switch (wParam)
  315. {
  316. case SC_NEXTWINDOW:
  317. case SC_PREVWINDOW:
  318. case SC_SCREENSAVE:
  319. return FALSE;
  320. };
  321. }
  322. break;
  323. }
  324. return DefWindowProc(hWnd , message , wParam , lParam);
  325. }