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.

454 lines
10 KiB

  1. /*++
  2. Copyright (c) 2000, Microsoft Corporation
  3. Module Name:
  4. eldialog.cpp
  5. Abstract:
  6. Module to handle the communication from 802.1X state machine to netshell
  7. Revision History:
  8. sachins, March 20, 2001, Created
  9. --*/
  10. #include "pcheapol.h"
  11. #pragma hdrstop
  12. #include <netconp.h>
  13. #include <dbt.h>
  14. #include "eldialog.h"
  15. //
  16. // WZCNetmanConnectionStatusChanged
  17. //
  18. // Description:
  19. //
  20. // Function called to update NCS status with netman
  21. //
  22. // Arguments:
  23. // pGUIDConn - Interface GUID
  24. // ncs - NETCON_STATUS of GUID
  25. //
  26. // Return values:
  27. // HRESULT
  28. //
  29. HRESULT
  30. WZCNetmanConnectionStatusChanged (
  31. IN GUID *pGUIDConn,
  32. IN NETCON_STATUS ncs
  33. )
  34. {
  35. HRESULT hr = S_OK;
  36. INetConnectionRefresh *pNetmanNotify = NULL;
  37. TRACE0 (NOTIFY, "WZCNetmanConnectionStatusChanged: Entered");
  38. if (!g_fTrayIconReady)
  39. {
  40. return hr;
  41. }
  42. hr = CoInitializeEx (NULL, COINIT_MULTITHREADED);
  43. if (SUCCEEDED (hr))
  44. {
  45. hr = CoCreateInstance (
  46. &CLSID_ConnectionManager,
  47. NULL,
  48. CLSCTX_ALL,
  49. &IID_INetConnectionRefresh,
  50. (LPVOID *)&pNetmanNotify);
  51. if (SUCCEEDED (hr))
  52. {
  53. TRACE0 (NOTIFY, "QueueEvent: CoCreateInstance succeeded");
  54. pNetmanNotify->lpVtbl->ConnectionStatusChanged (
  55. pNetmanNotify, pGUIDConn, ncs);
  56. pNetmanNotify->lpVtbl->Release (pNetmanNotify);
  57. }
  58. else
  59. {
  60. TRACE0 (NOTIFY, "ConnectionStatusChanged: CoCreateInstance failed");
  61. }
  62. CoUninitialize ();
  63. }
  64. else
  65. {
  66. TRACE0 (NOTIFY, "ConnectionStatusChanged: CoInitializeEx failed");
  67. }
  68. TRACE0 (NOTIFY, "ConnectionStatusChanged completed");
  69. return hr;
  70. }
  71. //
  72. // WZCNetmanShowBalloon
  73. //
  74. // Description:
  75. //
  76. // Function called to display balloon on tray icon
  77. //
  78. // Arguments:
  79. // pGUIDConn - Interface GUID
  80. // pszCookie - Cookie for the transaction
  81. // pszBalloonText - Balloon text to be displayed
  82. //
  83. // Return values:
  84. // HRESULT
  85. //
  86. HRESULT
  87. WZCNetmanShowBalloon (
  88. IN GUID *pGUIDConn,
  89. IN BSTR pszCookie,
  90. IN BSTR pszBalloonText
  91. )
  92. {
  93. HRESULT hr = S_OK;
  94. INetConnectionRefresh *pNetmanNotify = NULL;
  95. TRACE0 (NOTIFY, "WZCNetmanShowBalloon: Entered");
  96. if (!g_fTrayIconReady)
  97. {
  98. return hr;
  99. }
  100. hr = CoInitializeEx (NULL, COINIT_MULTITHREADED);
  101. if (SUCCEEDED (hr))
  102. {
  103. hr = CoCreateInstance (
  104. &CLSID_ConnectionManager,
  105. NULL,
  106. CLSCTX_ALL,
  107. &IID_INetConnectionRefresh,
  108. (LPVOID *)&pNetmanNotify);
  109. if (SUCCEEDED (hr))
  110. {
  111. TRACE0 (NOTIFY, "WZCNetmanShowBalloon: CoCreateInstance succeeded");
  112. pNetmanNotify->lpVtbl->ShowBalloon
  113. (pNetmanNotify, pGUIDConn, pszCookie, pszBalloonText);
  114. pNetmanNotify->lpVtbl->Release (pNetmanNotify);
  115. }
  116. else
  117. {
  118. TRACE0 (NOTIFY, "WZCNetmanShowBalloon: CoCreateInstance failed");
  119. }
  120. CoUninitialize ();
  121. }
  122. else
  123. {
  124. TRACE0 (NOTIFY, "WZCNetmanShowBalloon: CoInitializeEx failed");
  125. }
  126. TRACE0 (NOTIFY, "WZCNetmanShowBalloon completed");
  127. return hr;
  128. }
  129. //
  130. // EAPOLQueryGUIDNCSState
  131. //
  132. // Purpose: Called by Netman module query the ncs state of the
  133. // GUID
  134. //
  135. // Arguments:
  136. // pGuidConn - Interface GUID
  137. // pncs - NCS status of the interface
  138. //
  139. // Returns:
  140. // S_OK - no error
  141. // !S_OK - error
  142. //
  143. HRESULT
  144. EAPOLQueryGUIDNCSState (
  145. IN GUID * pGuidConn,
  146. OUT NETCON_STATUS * pncs
  147. )
  148. {
  149. WCHAR wszGuid[GUID_STRING_LEN_WITH_TERM];
  150. CHAR szGuid[GUID_STRING_LEN_WITH_TERM];
  151. EAPOL_PCB *pPCB = NULL;
  152. DWORD dwRetCode = NO_ERROR;
  153. HRESULT hr = S_OK;
  154. InterlockedIncrement (&g_lWorkerThreads);
  155. do
  156. {
  157. if (g_dwModulesStarted != ALL_MODULES_STARTED)
  158. {
  159. hr = S_FALSE;
  160. break;
  161. }
  162. StringFromGUID2 (pGuidConn, wszGuid, GUID_STRING_LEN_WITH_TERM);
  163. ACQUIRE_WRITE_LOCK (&g_PCBLock);
  164. pPCB = ElGetPCBPointerFromPortGUID (wszGuid);
  165. if (pPCB)
  166. {
  167. EAPOL_REFERENCE_PORT (pPCB);
  168. }
  169. RELEASE_WRITE_LOCK (&g_PCBLock);
  170. if (pPCB == NULL)
  171. {
  172. hr = S_FALSE;
  173. break;
  174. }
  175. ACQUIRE_WRITE_LOCK (&(pPCB->rwLock));
  176. if (pPCB->fIsRemoteEndEAPOLAware)
  177. {
  178. switch (pPCB->State)
  179. {
  180. case EAPOLSTATE_LOGOFF:
  181. hr = S_FALSE;
  182. break;
  183. case EAPOLSTATE_DISCONNECTED:
  184. if (pPCB->dwAuthFailCount >= pPCB->dwTotalMaxAuthFailCount)
  185. {
  186. *pncs = NCS_AUTHENTICATION_FAILED;
  187. break;
  188. }
  189. hr = S_FALSE;
  190. break;
  191. case EAPOLSTATE_CONNECTING:
  192. hr = S_FALSE;
  193. break;
  194. case EAPOLSTATE_ACQUIRED:
  195. *pncs = NCS_CREDENTIALS_REQUIRED;
  196. break;
  197. case EAPOLSTATE_AUTHENTICATING:
  198. *pncs = NCS_AUTHENTICATING;
  199. break;
  200. case EAPOLSTATE_HELD:
  201. *pncs = NCS_AUTHENTICATION_FAILED;
  202. break;
  203. case EAPOLSTATE_AUTHENTICATED:
  204. *pncs = NCS_AUTHENTICATION_SUCCEEDED;
  205. break;
  206. default:
  207. hr = S_FALSE;
  208. break;
  209. }
  210. }
  211. else
  212. {
  213. hr = S_FALSE;
  214. }
  215. RELEASE_WRITE_LOCK (&(pPCB->rwLock));
  216. EAPOL_DEREFERENCE_PORT (pPCB);
  217. }
  218. while (FALSE);
  219. InterlockedDecrement (&g_lWorkerThreads);
  220. return hr;
  221. }
  222. //
  223. // EAPOLTrayIconReady
  224. //
  225. // Purpose: Called by Netman module to inform about Tray being
  226. // ready for notifications from WZCSVC
  227. //
  228. // Arguments:
  229. // pszUserName - Username of the user logged in on the desktop
  230. //
  231. // Returns:
  232. // NONE
  233. //
  234. VOID
  235. EAPOLTrayIconReady (
  236. IN const WCHAR * pwszUserName
  237. )
  238. {
  239. BOOLEAN fDecrWorkerThreadCount = FALSE;
  240. PVOID pvContext = NULL;
  241. DWORD dwRetCode = NO_ERROR;
  242. TRACE1 (NOTIFY, "EAPOLTrayIconReady: Advise username = %ws", pwszUserName);
  243. do
  244. {
  245. pvContext = (VOID *) MALLOC ((wcslen(pwszUserName)+1)*sizeof(WCHAR));
  246. if (pvContext == NULL)
  247. {
  248. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  249. TRACE0 (NOTIFY, "EAPOLTrayIconReady: MALLOC failed for pvContext");
  250. break;
  251. }
  252. memcpy (pvContext, (PVOID)pwszUserName, (wcslen(pwszUserName)+1)*sizeof(WCHAR));
  253. InterlockedIncrement (&g_lWorkerThreads);
  254. fDecrWorkerThreadCount = TRUE;
  255. if (!QueueUserWorkItem (
  256. (LPTHREAD_START_ROUTINE)EAPOLTrayIconReadyWorker,
  257. (PVOID)pvContext,
  258. WT_EXECUTELONGFUNCTION))
  259. {
  260. dwRetCode = GetLastError();
  261. TRACE1 (NOTIFY, "EAPOLTrayIconReady: QueueUserWorkItem failed with error %ld",
  262. dwRetCode);
  263. break;
  264. }
  265. else
  266. {
  267. fDecrWorkerThreadCount = FALSE;
  268. }
  269. }
  270. while (FALSE);
  271. if (fDecrWorkerThreadCount)
  272. {
  273. InterlockedDecrement (&g_lWorkerThreads);
  274. }
  275. return;
  276. }
  277. //
  278. // EAPOLTrayIconReadyWorker
  279. //
  280. // Purpose: Called by Netman module to inform about Tray being
  281. // ready for notifications from WZCSVC
  282. //
  283. // Arguments:
  284. // pszUserName - Username of the user logged in on the desktop
  285. //
  286. // Returns:
  287. // NONE
  288. //
  289. DWORD
  290. WINAPI
  291. EAPOLTrayIconReadyWorker (
  292. IN PVOID pvContext
  293. )
  294. {
  295. HANDLE hToken = NULL;
  296. WCHAR *pwszUserName = NULL;
  297. WCHAR *pwszActiveUserName = NULL;
  298. DWORD dwLoop = 0;
  299. DWORD dwRetCode = NO_ERROR;
  300. do
  301. {
  302. pwszUserName = (WCHAR *)pvContext;
  303. TRACE1 (NOTIFY, "EAPOLTrayIconReadyWorker: Advise username = %ws", pwszUserName);
  304. // Loop 3 times, since there have been timing issues between
  305. // notification coming through and the call failing
  306. while ((dwLoop++) < 3)
  307. {
  308. dwRetCode = NO_ERROR;
  309. Sleep (1000);
  310. if (g_dwCurrentSessionId != 0xffffffff)
  311. {
  312. if (hToken != NULL)
  313. {
  314. if (!CloseHandle (hToken))
  315. {
  316. dwRetCode = GetLastError ();
  317. TRACE1 (NOTIFY, "EAPOLTrayIconReadyWorker: CloseHandle failed with error (%ld)",
  318. dwRetCode);
  319. dwRetCode = NO_ERROR;
  320. }
  321. hToken = NULL;
  322. }
  323. if (pwszActiveUserName != NULL)
  324. {
  325. FREE (pwszActiveUserName);
  326. pwszActiveUserName = NULL;
  327. }
  328. if ((dwRetCode = ElGetWinStationUserToken (g_dwCurrentSessionId, &hToken))
  329. != NO_ERROR)
  330. {
  331. TRACE1 (NOTIFY, "EAPOLTrayIconReadyWorker: ElGetWinStationUserToken failed with error %ld",
  332. dwRetCode);
  333. continue;
  334. }
  335. if ((dwRetCode = ElGetLoggedOnUserName (hToken, &pwszActiveUserName))
  336. != NO_ERROR)
  337. {
  338. TRACE1 (NOTIFY, "EAPOLTrayIconReadyWorker: ElGetLoggedOnUserName failed with error %ld",
  339. dwRetCode);
  340. if (dwRetCode == ERROR_BAD_IMPERSONATION_LEVEL)
  341. {
  342. break;
  343. }
  344. continue;
  345. }
  346. if (!wcscmp (pwszUserName, pwszActiveUserName))
  347. {
  348. TRACE1 (NOTIFY, "EAPOLTrayIconReadyWorker: Tray icon ready for username %ws",
  349. pwszUserName);
  350. g_fTrayIconReady = TRUE;
  351. break;
  352. }
  353. }
  354. else
  355. {
  356. TRACE0 (NOTIFY, "EAPOLTrayIconReadyWorker: No user logged on");
  357. }
  358. } // while
  359. }
  360. while (FALSE);
  361. if (hToken != NULL)
  362. {
  363. CloseHandle (hToken);
  364. }
  365. if (pvContext != NULL)
  366. {
  367. FREE (pvContext);
  368. }
  369. if (pwszActiveUserName != NULL)
  370. {
  371. FREE (pwszActiveUserName);
  372. }
  373. InterlockedDecrement (&g_lWorkerThreads);
  374. return dwRetCode;
  375. }