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.

644 lines
14 KiB

  1. /*++
  2. Copyright (c) 2000, Microsoft Corporation
  3. Module Name:
  4. Abstract:
  5. Revision History:
  6. timmoore, sachins, May 19 2000, Created
  7. --*/
  8. #include "pcheapol.h"
  9. #pragma hdrstop
  10. LONG_PTR FAR PASCAL
  11. WndProc(
  12. HWND hWnd,
  13. unsigned message,
  14. WPARAM wParam,
  15. LPARAM lParam
  16. );
  17. #define TASK_BAR_CREATED L"TaskbarCreated"
  18. TCHAR EAPOLClassName[] = TEXT("EAPOLClass");
  19. UINT g_TaskbarCreated;
  20. HWND g_hWnd = 0;
  21. HINSTANCE g_hInstance;
  22. HANDLE g_UserToken;
  23. HWINSTA hWinStaUser = 0;
  24. HWINSTA hSaveWinSta = 0;
  25. HDESK hDeskUser = 0;
  26. HDESK hSaveDesk = 0;
  27. //
  28. // WindowInit
  29. //
  30. // Description:
  31. //
  32. // Function called create the taskbar used to detect user logon/logoff
  33. //
  34. // Arguments:
  35. //
  36. // Return values:
  37. // NO_ERROR - success
  38. // NON-zero - error
  39. //
  40. DWORD
  41. WindowInit ()
  42. {
  43. WNDCLASS Wc;
  44. DWORD dwRetCode = NO_ERROR;
  45. TRACE0 (ANY, "Came into WindowInit ========================\n");
  46. do
  47. {
  48. if ((g_TaskbarCreated = RegisterWindowMessage(TASK_BAR_CREATED))
  49. == 0)
  50. {
  51. dwRetCode = GetLastError ();
  52. TRACE1 (ANY, "WindowInit: RegisterWindowMessage failed with error %ld\n",
  53. dwRetCode);
  54. break;
  55. }
  56. TRACE1 (ANY, "WindowInit: TaskbarCreated id = %ld",
  57. g_TaskbarCreated);
  58. // save current desktop and window station
  59. // so that it can be restored when we shutdown
  60. if ((hSaveWinSta = GetProcessWindowStation()) == NULL)
  61. {
  62. dwRetCode = GetLastError ();
  63. TRACE1 (ANY, "WindowInit: GetProcessWindowStation failed with error %ld\n",
  64. dwRetCode);
  65. break;
  66. }
  67. if ((hSaveDesk = GetThreadDesktop(GetCurrentThreadId())) == NULL)
  68. {
  69. dwRetCode = GetLastError ();
  70. TRACE1 (ANY, "WindowInit: GetThreadDesktop failed with error %ld\n",
  71. dwRetCode);
  72. break;
  73. }
  74. // Open the current user's window station and desktop
  75. if ((hWinStaUser = OpenWindowStation(L"WinSta0", FALSE, MAXIMUM_ALLOWED)) == NULL)
  76. {
  77. dwRetCode = GetLastError ();
  78. TRACE1 (ANY, "WindowInit: OpenWindowStation failed with error %ld\n",
  79. dwRetCode);
  80. break;
  81. }
  82. if (!SetProcessWindowStation(hWinStaUser))
  83. {
  84. dwRetCode = GetLastError ();
  85. TRACE1 (ANY, "WindowInit: SetProcessWindowStation failed with error %ld\n",
  86. dwRetCode);
  87. break;
  88. }
  89. else
  90. {
  91. TRACE0 (ANY, "WindowInit: SetProcessWindowStation succeeded\n");
  92. }
  93. if ((hDeskUser = OpenDesktop(L"Default", 0 , FALSE, MAXIMUM_ALLOWED))
  94. == NULL)
  95. {
  96. dwRetCode = GetLastError ();
  97. TRACE1 (ANY, "WindowInit: OpenDesktop failed with error %ld\n",
  98. dwRetCode);
  99. break;
  100. }
  101. if (!SetThreadDesktop(hDeskUser))
  102. {
  103. dwRetCode = GetLastError ();
  104. TRACE1 (ANY, "WindowInit: SetThreadDesktop failed with error %ld\n",
  105. dwRetCode);
  106. break;
  107. }
  108. else
  109. {
  110. TRACE0 (ANY, "WindowInit: SetThreadDesktop succeeded\n");
  111. }
  112. //
  113. // Register the class for the window
  114. //
  115. Wc.style = CS_NOCLOSE;
  116. Wc.cbClsExtra = 0;
  117. Wc.cbWndExtra = 0;
  118. Wc.hInstance = g_hInstance;
  119. Wc.hIcon = NULL;
  120. Wc.hCursor = NULL;
  121. Wc.hbrBackground = NULL;
  122. Wc.lpszMenuName = NULL;
  123. Wc.lpfnWndProc = WndProc;
  124. Wc.lpszClassName = EAPOLClassName;
  125. if (!RegisterClass(&Wc))
  126. {
  127. dwRetCode = GetLastError ();
  128. TRACE1 (ANY, "WindowInit: RegisterClass failed with error %ld\n",
  129. dwRetCode);
  130. if (dwRetCode == ERROR_CLASS_ALREADY_EXISTS)
  131. {
  132. dwRetCode = NO_ERROR;
  133. }
  134. else
  135. {
  136. break;
  137. }
  138. }
  139. // Create the window that will receive the taskbar menu messages.
  140. // The window has to be created after opening the user's desktop
  141. if ((g_hWnd = CreateWindow(
  142. EAPOLClassName,
  143. L"EAPOLWindow",
  144. WS_OVERLAPPEDWINDOW,
  145. CW_USEDEFAULT,
  146. CW_USEDEFAULT,
  147. CW_USEDEFAULT,
  148. CW_USEDEFAULT,
  149. NULL,
  150. NULL,
  151. g_hInstance,
  152. NULL)) == NULL)
  153. {
  154. dwRetCode = GetLastError ();
  155. TRACE1 (ANY, "WindowInit: CreateWindow failed with error %ld\n",
  156. dwRetCode);
  157. break;
  158. }
  159. // We don't care about the return value, since we just want it to
  160. // be hidden and it will always succeed
  161. ShowWindow(g_hWnd, SW_HIDE);
  162. if (!UpdateWindow(g_hWnd))
  163. {
  164. dwRetCode = GetLastError ();
  165. TRACE1 (ANY, "WindowInit: UpdateWindow failed with error %ld\n",
  166. dwRetCode);
  167. break;
  168. }
  169. TRACE0 (ANY, "WindowInit: CreateWindow succeeded\n");
  170. } while (FALSE);
  171. return dwRetCode;
  172. }
  173. //
  174. // WindowShut
  175. //
  176. // Description:
  177. //
  178. // Function called to delete the task bar created to detect user logon/logoff
  179. //
  180. // Arguments:
  181. //
  182. // Return values:
  183. // NO_ERROR - success
  184. // NON-zero - error
  185. //
  186. DWORD
  187. WindowShut ()
  188. {
  189. DWORD dwRetCode = NO_ERROR;
  190. do
  191. {
  192. if (g_hWnd)
  193. {
  194. if (!DestroyWindow (g_hWnd))
  195. {
  196. dwRetCode = GetLastError ();
  197. TRACE1 (ANY, "WindowShut: DestroyWindow failed with error %ld\n",
  198. dwRetCode);
  199. // log
  200. }
  201. }
  202. if (g_hInstance)
  203. {
  204. if (!UnregisterClass (
  205. EAPOLClassName,
  206. g_hInstance))
  207. {
  208. dwRetCode = GetLastError ();
  209. TRACE1 (ANY, "WindowShut: UnregisterClass failed with error %ld\n",
  210. dwRetCode);
  211. // log
  212. }
  213. g_hInstance = NULL;
  214. }
  215. if (hDeskUser)
  216. {
  217. if (CloseDesktop(hDeskUser) == 0)
  218. {
  219. dwRetCode = GetLastError ();
  220. TRACE1 (ANY, "WindowShut: CloseDesktop-hDeskUser failed with error %ld\n",
  221. dwRetCode);
  222. // log
  223. }
  224. hDeskUser = 0;
  225. }
  226. if (hWinStaUser)
  227. {
  228. if (CloseWindowStation(hWinStaUser) == 0)
  229. {
  230. dwRetCode = GetLastError ();
  231. TRACE1 (ANY, "WindowShut: CloseWindowStation-hWinStaUser failed with error %ld\n",
  232. dwRetCode);
  233. // log
  234. }
  235. hWinStaUser = 0;
  236. }
  237. if (hSaveDesk)
  238. {
  239. if (!SetThreadDesktop(hSaveDesk))
  240. {
  241. dwRetCode = GetLastError ();
  242. TRACE1 (ANY, "WindowShut: SetThreadDesktop failed with error %ld\n",
  243. dwRetCode);
  244. // log
  245. }
  246. if (hSaveWinSta)
  247. {
  248. if (SetProcessWindowStation(hSaveWinSta) == 0)
  249. {
  250. TRACE1 (ANY, "WindowShut: SetProcessWindowStation failed with error %ld\n",
  251. dwRetCode);
  252. dwRetCode = GetLastError ();
  253. // log
  254. }
  255. }
  256. if (CloseDesktop(hSaveDesk) == 0)
  257. {
  258. dwRetCode = GetLastError ();
  259. TRACE1 (ANY, "WindowShut: CloseDesktop-hSaveDesk failed with error %ld\n",
  260. dwRetCode);
  261. // log
  262. }
  263. hSaveDesk = 0;
  264. if (hSaveWinSta)
  265. {
  266. if (CloseWindowStation(hSaveWinSta) == 0)
  267. {
  268. dwRetCode = GetLastError ();
  269. TRACE1 (ANY, "WindowShut: CloseWindowStation-hSaveWinSta failed with error %ld\n",
  270. dwRetCode);
  271. // log
  272. }
  273. hSaveWinSta = 0;
  274. }
  275. }
  276. } while (FALSE);
  277. return dwRetCode;
  278. }
  279. //
  280. // UserLogon
  281. //
  282. // Description:
  283. //
  284. // Function called to do processing when user logs on
  285. //
  286. // Arguments:
  287. //
  288. // Return values:
  289. // NO_ERROR - success
  290. // NON-zero - error
  291. //
  292. DWORD
  293. UserLogon ()
  294. {
  295. DWORD dwRetCode = NO_ERROR;
  296. TRACE0 (ANY, "Came into UserLogon ===================\n");
  297. do
  298. {
  299. ElUserLogonCallback (
  300. NULL,
  301. TRUE
  302. );
  303. TRACE0 (ANY, "UserLogon: ElUserLogonCallback completed");
  304. } while (FALSE);
  305. return dwRetCode;
  306. }
  307. //
  308. // UserLogoff
  309. //
  310. // Description:
  311. //
  312. // Function called to do processing when user logs off
  313. //
  314. // Arguments:
  315. //
  316. // Return values:
  317. // NO_ERROR - success
  318. // NON-zero - error
  319. //
  320. DWORD
  321. UserLogoff ()
  322. {
  323. DWORD dwRetCode = NO_ERROR;
  324. TRACE0 (ANY, "Came into UserLogoff ===================\n");
  325. do
  326. {
  327. ElUserLogoffCallback (
  328. NULL,
  329. TRUE
  330. );
  331. TRACE0 (ANY, "UserLogoff: ElUserLogoffCallback completed");
  332. } while (FALSE);
  333. return dwRetCode;
  334. }
  335. //
  336. // ElWaitOnEvent
  337. //
  338. // Description:
  339. //
  340. // Function called to wait on taskbar event changes
  341. //
  342. // Arguments:
  343. //
  344. // Return values:
  345. // NO_ERROR - success
  346. // NON-zero - error
  347. //
  348. DWORD
  349. ElWaitOnEvent ()
  350. {
  351. MSG Msg;
  352. HANDLE hEvents[1];
  353. BOOL fExitThread = FALSE;
  354. DWORD dwStatus = NO_ERROR;
  355. DWORD dwRetCode = NO_ERROR;
  356. // Check if 802.1X service has stopped
  357. // Exit if so
  358. if (( dwStatus = WaitForSingleObject (
  359. g_hEventTerminateEAPOL,
  360. 0)) == WAIT_FAILED)
  361. {
  362. dwRetCode = GetLastError ();
  363. if ( g_dwTraceId != INVALID_TRACEID )
  364. {
  365. TRACE1 (INIT, "ElWaitOnEvent: WaitForSingleObject failed with error %ld, Terminating cleanup",
  366. dwRetCode);
  367. }
  368. // log
  369. return dwRetCode;
  370. }
  371. if (dwStatus == WAIT_OBJECT_0)
  372. {
  373. if ( g_dwTraceId != INVALID_TRACEID )
  374. {
  375. dwRetCode = NO_ERROR;
  376. TRACE0 (INIT, "ElWaitOnEvent: g_hEventTerminateEAPOL already signaled, returning");
  377. }
  378. return dwRetCode;
  379. }
  380. if (!g_dwMachineAuthEnabled)
  381. {
  382. if ((dwRetCode = UserLogon()) != NO_ERROR)
  383. {
  384. TRACE1 (ANY, "ElWaitOnEvent: UserLogon failed with error %ld",
  385. dwRetCode);
  386. return dwRetCode;
  387. }
  388. }
  389. do
  390. {
  391. do
  392. {
  393. hEvents[0] = g_hEventTerminateEAPOL;
  394. dwStatus = MsgWaitForMultipleObjects(
  395. 1,
  396. hEvents,
  397. FALSE,
  398. INFINITE,
  399. QS_ALLINPUT | QS_ALLEVENTS | QS_ALLPOSTMESSAGE);
  400. if (dwStatus == WAIT_FAILED)
  401. {
  402. dwRetCode = GetLastError ();
  403. TRACE1 (ANY, "ElWaitOnEvent: MsgWaitForMultipleObjects failed with error %ld",
  404. dwRetCode);
  405. // log
  406. break;
  407. }
  408. switch (dwStatus)
  409. {
  410. case WAIT_OBJECT_0:
  411. // Service exit detected
  412. fExitThread = TRUE;
  413. TRACE0 (ANY, "ElWaitOnEvent: Service exit detected");
  414. break;
  415. default:
  416. while (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
  417. {
  418. if (Msg.message == WM_QUIT)
  419. {
  420. break;
  421. }
  422. TRACE3 (ANY, "ElWaitonEvent: Mesg %ld, wparam %lx, lparam %lx",
  423. (DWORD)Msg.message, Msg.wParam, Msg.lParam);
  424. if (!IsDialogMessage(g_hWnd, &Msg))
  425. {
  426. TranslateMessage(&Msg);
  427. DispatchMessage(&Msg);
  428. }
  429. }
  430. break;
  431. }
  432. } while (dwStatus != WAIT_OBJECT_0);
  433. if ((dwRetCode != NO_ERROR) || (fExitThread))
  434. {
  435. TRACE0 (ANY, "ElWaitOnEvent: Exit wait loop");
  436. break;
  437. }
  438. } while (TRUE);
  439. return dwRetCode;
  440. }
  441. //
  442. // WndProc
  443. //
  444. // Description:
  445. //
  446. // Function called to process taskbar events
  447. //
  448. // Arguments:
  449. //
  450. // Return values:
  451. //
  452. LONG_PTR FAR PASCAL
  453. WndProc (
  454. IN HWND hWnd,
  455. IN unsigned message,
  456. IN WPARAM wParam,
  457. IN LPARAM lParam
  458. )
  459. {
  460. DWORD dwRetCode = NO_ERROR;
  461. TRACE1 (ANY, "WndProc: Came into WndProc %ld", (DWORD)message );
  462. switch (message)
  463. {
  464. case WM_ENDSESSION:
  465. TRACE2 (ANY, "WndProc: Endsession (logoff) %x %x\n",
  466. wParam, lParam);
  467. if(wParam)
  468. {
  469. // Only user session logoff
  470. if (lParam & ENDSESSION_LOGOFF)
  471. {
  472. if ((dwRetCode = UserLogoff()) != NO_ERROR)
  473. {
  474. TRACE1 (ANY, "WndProc: UserLogoff failed with error %ld",
  475. dwRetCode);
  476. }
  477. }
  478. }
  479. break;
  480. default:
  481. if (message == g_TaskbarCreated)
  482. {
  483. TRACE0 (ANY, "WndProc: Taskbar created (Logon)\n");
  484. if ((dwRetCode = UserLogon()) != NO_ERROR)
  485. {
  486. TRACE1 (ANY, "WndProc: UserLogon failed with error %ld",
  487. dwRetCode);
  488. }
  489. }
  490. }
  491. return (DefWindowProc(hWnd, message, wParam, lParam));
  492. }
  493. //
  494. // ElUserLogonDetection
  495. //
  496. // Description:
  497. //
  498. // Function called to initialize module detecting user logon/logoff
  499. //
  500. // Arguments:
  501. // pvContext - Unused
  502. //
  503. // Return values:
  504. //
  505. VOID
  506. ElUserLogonDetection (
  507. PVOID pvContext
  508. )
  509. {
  510. DWORD dwRetCode = NO_ERROR;
  511. do
  512. {
  513. if ((dwRetCode = WindowInit()) != NO_ERROR)
  514. {
  515. break;
  516. }
  517. if ((dwRetCode = ElWaitOnEvent()) != NO_ERROR)
  518. {
  519. // no action
  520. }
  521. } while (FALSE);
  522. dwRetCode = WindowShut();
  523. if (dwRetCode != NO_ERROR)
  524. {
  525. TRACE1 (ANY, "ElUserLogonDetection: Error in processing = %ld",
  526. dwRetCode);
  527. // log
  528. }
  529. return;
  530. }