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.

650 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. return NO_ERROR;
  173. }
  174. //
  175. // WindowShut
  176. //
  177. // Description:
  178. //
  179. // Function called to delete the task bar created to detect user logon/logoff
  180. //
  181. // Arguments:
  182. //
  183. // Return values:
  184. // NO_ERROR - success
  185. // NON-zero - error
  186. //
  187. DWORD
  188. WindowShut ()
  189. {
  190. DWORD dwRetCode = NO_ERROR;
  191. do
  192. {
  193. if (g_hWnd)
  194. {
  195. if (!DestroyWindow (g_hWnd))
  196. {
  197. dwRetCode = GetLastError ();
  198. TRACE1 (ANY, "WindowShut: DestroyWindow failed with error %ld\n",
  199. dwRetCode);
  200. // log
  201. }
  202. }
  203. if (g_hInstance)
  204. {
  205. if (!UnregisterClass (
  206. EAPOLClassName,
  207. g_hInstance))
  208. {
  209. dwRetCode = GetLastError ();
  210. TRACE1 (ANY, "WindowShut: UnregisterClass failed with error %ld\n",
  211. dwRetCode);
  212. // log
  213. }
  214. g_hInstance = NULL;
  215. }
  216. if (hDeskUser)
  217. {
  218. if (CloseDesktop(hDeskUser) == 0)
  219. {
  220. dwRetCode = GetLastError ();
  221. TRACE1 (ANY, "WindowShut: CloseDesktop-hDeskUser failed with error %ld\n",
  222. dwRetCode);
  223. // log
  224. }
  225. hDeskUser = 0;
  226. }
  227. if (hWinStaUser)
  228. {
  229. if (CloseWindowStation(hWinStaUser) == 0)
  230. {
  231. dwRetCode = GetLastError ();
  232. TRACE1 (ANY, "WindowShut: CloseWindowStation-hWinStaUser failed with error %ld\n",
  233. dwRetCode);
  234. // log
  235. }
  236. hWinStaUser = 0;
  237. }
  238. if (hSaveDesk)
  239. {
  240. if (!SetThreadDesktop(hSaveDesk))
  241. {
  242. dwRetCode = GetLastError ();
  243. TRACE1 (ANY, "WindowShut: SetThreadDesktop failed with error %ld\n",
  244. dwRetCode);
  245. // log
  246. }
  247. if (hSaveWinSta)
  248. {
  249. if (SetProcessWindowStation(hSaveWinSta) == 0)
  250. {
  251. TRACE1 (ANY, "WindowShut: SetProcessWindowStation failed with error %ld\n",
  252. dwRetCode);
  253. dwRetCode = GetLastError ();
  254. // log
  255. }
  256. }
  257. if (CloseDesktop(hSaveDesk) == 0)
  258. {
  259. dwRetCode = GetLastError ();
  260. TRACE1 (ANY, "WindowShut: CloseDesktop-hSaveDesk failed with error %ld\n",
  261. dwRetCode);
  262. // log
  263. }
  264. hSaveDesk = 0;
  265. if (hSaveWinSta)
  266. {
  267. if (CloseWindowStation(hSaveWinSta) == 0)
  268. {
  269. dwRetCode = GetLastError ();
  270. TRACE1 (ANY, "WindowShut: CloseWindowStation-hSaveWinSta failed with error %ld\n",
  271. dwRetCode);
  272. // log
  273. }
  274. hSaveWinSta = 0;
  275. }
  276. }
  277. } while (FALSE);
  278. return dwRetCode;
  279. }
  280. //
  281. // UserLogon
  282. //
  283. // Description:
  284. //
  285. // Function called to do processing when user logs on
  286. //
  287. // Arguments:
  288. //
  289. // Return values:
  290. // NO_ERROR - success
  291. // NON-zero - error
  292. //
  293. DWORD
  294. UserLogon ()
  295. {
  296. DWORD dwRetCode = NO_ERROR;
  297. TRACE0 (ANY, "Came into UserLogon ===================\n");
  298. do
  299. {
  300. #if 0
  301. ElUserLogonCallback (
  302. NULL,
  303. TRUE
  304. );
  305. TRACE0 (ANY, "UserLogon: ElUserLogonCallback completed");
  306. #endif
  307. } while (FALSE);
  308. return dwRetCode;
  309. }
  310. //
  311. // UserLogoff
  312. //
  313. // Description:
  314. //
  315. // Function called to do processing when user logs off
  316. //
  317. // Arguments:
  318. //
  319. // Return values:
  320. // NO_ERROR - success
  321. // NON-zero - error
  322. //
  323. DWORD
  324. UserLogoff ()
  325. {
  326. DWORD dwRetCode = NO_ERROR;
  327. TRACE0 (ANY, "Came into UserLogoff ===================\n");
  328. do
  329. {
  330. #if 0
  331. ElUserLogoffCallback (
  332. NULL,
  333. TRUE
  334. );
  335. TRACE0 (ANY, "UserLogoff: ElUserLogoffCallback completed");
  336. #endif
  337. } while (FALSE);
  338. return dwRetCode;
  339. }
  340. //
  341. // ElWaitOnEvent
  342. //
  343. // Description:
  344. //
  345. // Function called to wait on taskbar event changes
  346. //
  347. // Arguments:
  348. //
  349. // Return values:
  350. // NO_ERROR - success
  351. // NON-zero - error
  352. //
  353. DWORD
  354. ElWaitOnEvent ()
  355. {
  356. MSG Msg;
  357. HANDLE hEvents[1];
  358. BOOL fExitThread = FALSE;
  359. DWORD dwStatus = NO_ERROR;
  360. DWORD dwRetCode = NO_ERROR;
  361. // Check if 802.1X service has stopped
  362. // Exit if so
  363. if (( dwStatus = WaitForSingleObject (
  364. g_hEventTerminateEAPOL,
  365. 0)) == WAIT_FAILED)
  366. {
  367. dwRetCode = GetLastError ();
  368. if ( g_dwTraceId != INVALID_TRACEID )
  369. {
  370. TRACE1 (INIT, "ElWaitOnEvent: WaitForSingleObject failed with error %ld, Terminating cleanup",
  371. dwRetCode);
  372. }
  373. // log
  374. return dwRetCode;
  375. }
  376. if (dwStatus == WAIT_OBJECT_0)
  377. {
  378. if ( g_dwTraceId != INVALID_TRACEID )
  379. {
  380. dwRetCode = NO_ERROR;
  381. TRACE0 (INIT, "ElWaitOnEvent: g_hEventTerminateEAPOL already signaled, returning");
  382. }
  383. return dwRetCode;
  384. }
  385. if (!g_dwMachineAuthEnabled)
  386. {
  387. if ((dwRetCode = UserLogon()) != NO_ERROR)
  388. {
  389. TRACE1 (ANY, "ElWaitOnEvent: UserLogon failed with error %ld",
  390. dwRetCode);
  391. return dwRetCode;
  392. }
  393. }
  394. do
  395. {
  396. do
  397. {
  398. hEvents[0] = g_hEventTerminateEAPOL;
  399. dwStatus = MsgWaitForMultipleObjects(
  400. 1,
  401. hEvents,
  402. FALSE,
  403. INFINITE,
  404. QS_ALLINPUT | QS_ALLEVENTS | QS_ALLPOSTMESSAGE);
  405. if (dwStatus == WAIT_FAILED)
  406. {
  407. dwRetCode = GetLastError ();
  408. TRACE1 (ANY, "ElWaitOnEvent: MsgWaitForMultipleObjects failed with error %ld",
  409. dwRetCode);
  410. // log
  411. break;
  412. }
  413. switch (dwStatus)
  414. {
  415. case WAIT_OBJECT_0:
  416. // Service exit detected
  417. fExitThread = TRUE;
  418. TRACE0 (ANY, "ElWaitOnEvent: Service exit detected");
  419. break;
  420. default:
  421. while (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
  422. {
  423. if (Msg.message == WM_QUIT)
  424. {
  425. break;
  426. }
  427. TRACE3 (ANY, "ElWaitonEvent: Mesg %ld, wparam %lx, lparam %lx",
  428. (DWORD)Msg.message, Msg.wParam, Msg.lParam);
  429. if (!IsDialogMessage(g_hWnd, &Msg))
  430. {
  431. TranslateMessage(&Msg);
  432. DispatchMessage(&Msg);
  433. }
  434. }
  435. break;
  436. }
  437. } while (dwStatus != WAIT_OBJECT_0);
  438. if ((dwRetCode != NO_ERROR) || (fExitThread))
  439. {
  440. TRACE0 (ANY, "ElWaitOnEvent: Exit wait loop");
  441. break;
  442. }
  443. } while (TRUE);
  444. return dwRetCode;
  445. }
  446. //
  447. // WndProc
  448. //
  449. // Description:
  450. //
  451. // Function called to process taskbar events
  452. //
  453. // Arguments:
  454. //
  455. // Return values:
  456. //
  457. LONG_PTR FAR PASCAL
  458. WndProc (
  459. IN HWND hWnd,
  460. IN unsigned message,
  461. IN WPARAM wParam,
  462. IN LPARAM lParam
  463. )
  464. {
  465. DWORD dwRetCode = NO_ERROR;
  466. TRACE1 (ANY, "WndProc: Came into WndProc %ld", (DWORD)message );
  467. switch (message)
  468. {
  469. case WM_ENDSESSION:
  470. TRACE2 (ANY, "WndProc: Endsession (logoff) %x %x\n",
  471. wParam, lParam);
  472. if(wParam)
  473. {
  474. // Only user session logoff
  475. if (lParam & ENDSESSION_LOGOFF)
  476. {
  477. if ((dwRetCode = UserLogoff()) != NO_ERROR)
  478. {
  479. TRACE1 (ANY, "WndProc: UserLogoff failed with error %ld",
  480. dwRetCode);
  481. }
  482. }
  483. }
  484. break;
  485. default:
  486. if (message == g_TaskbarCreated)
  487. {
  488. TRACE0 (ANY, "WndProc: Taskbar created (Logon)\n");
  489. if ((dwRetCode = UserLogon()) != NO_ERROR)
  490. {
  491. TRACE1 (ANY, "WndProc: UserLogon failed with error %ld",
  492. dwRetCode);
  493. }
  494. }
  495. }
  496. return (DefWindowProc(hWnd, message, wParam, lParam));
  497. }
  498. //
  499. // ElUserLogonDetection
  500. //
  501. // Description:
  502. //
  503. // Function called to initialize module detecting user logon/logoff
  504. //
  505. // Arguments:
  506. // pvContext - Unused
  507. //
  508. // Return values:
  509. //
  510. VOID
  511. ElUserLogonDetection (
  512. PVOID pvContext
  513. )
  514. {
  515. DWORD dwRetCode = NO_ERROR;
  516. do
  517. {
  518. if ((dwRetCode = WindowInit()) != NO_ERROR)
  519. {
  520. break;
  521. }
  522. if ((dwRetCode = ElWaitOnEvent()) != NO_ERROR)
  523. {
  524. // no action
  525. }
  526. } while (FALSE);
  527. dwRetCode = WindowShut();
  528. if (dwRetCode != NO_ERROR)
  529. {
  530. TRACE1 (ANY, "ElUserLogonDetection: Error in processing = %ld",
  531. dwRetCode);
  532. // log
  533. }
  534. InterlockedDecrement (&g_lWorkerThreads);
  535. return;
  536. }