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.

782 lines
17 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1997 - 1999
  3. Module Name:
  4. apiproc.cxx
  5. Abstract:
  6. This file contains the implementations of all the RPC Server
  7. Manager routines exported by SENS.
  8. Author:
  9. Gopal Parupudi <GopalP>
  10. [Notes:]
  11. optional-notes
  12. Revision History:
  13. GopalP 10/11/1997 Start.
  14. --*/
  15. #include <precomp.hxx>
  16. #include <notify.h>
  17. error_status_t
  18. RPC_IsNetworkAlive(
  19. IN handle_t hRpc,
  20. OUT LPDWORD lpdwFlags,
  21. OUT LPBOOL lpbAlive,
  22. OUT LPDWORD lpdwLastError
  23. )
  24. /*++
  25. Routine Description:
  26. Get the current Network State that is maintained by this service.
  27. If either WAN or LAN connectivity is not present, we try to re-evaluate
  28. and update the state, if possible.
  29. Arguments:
  30. hRpc - The RPC Binding handle.
  31. lpdwFlags - The flags indicating which type of network connectivity is
  32. present. The possible values are
  33. NETWORK_ALIVE_WAN
  34. NETWORK_ALIVE_LAN
  35. lpbAlive - Boolean indicating whether the network is alive or not.
  36. lpdwLastError - The out parameter that holds the error code returned
  37. from GetLastError() when there is no network connectivity.
  38. Return Value:
  39. RPC_S_OK, normally.
  40. RPC Error, if there is an RPC-related problem.
  41. --*/
  42. {
  43. DWORD dwNow;
  44. DWORD fNetNature;
  45. BOOL bNetAlive;
  46. BOOL bLanAlive;
  47. BOOL bWanAlive;
  48. DWORD dwWanLastError;
  49. DWORD dwLanLastError;
  50. DWORD dwNetState;
  51. //
  52. // Some basic argument checks
  53. //
  54. if (NULL == lpdwLastError)
  55. {
  56. return RPC_S_INVALID_ARG;
  57. }
  58. if ( (NULL == lpdwFlags)
  59. || (NULL == lpbAlive))
  60. {
  61. *lpdwLastError = ERROR_INVALID_PARAMETER;
  62. return RPC_S_OK;
  63. }
  64. *lpdwFlags = 0x0;
  65. *lpbAlive = FALSE;
  66. *lpdwLastError = ERROR_SUCCESS;
  67. dwNow = GetTickCount();
  68. fNetNature = 0x0;
  69. dwNetState = 0;
  70. bLanAlive = FALSE;
  71. bWanAlive = FALSE;
  72. bNetAlive = FALSE;
  73. SensPrintA(SENS_INFO, ("--------------------------------------------------------------\n"));
  74. SensPrintA(SENS_INFO, ("RPC_IsNetworkAlive() - Current Statistics"
  75. "\n\tLAN State (%s), LAN (%d sec),"
  76. "\n\tWAN State (%s) WAN Time (%d sec)\n",
  77. gdwLANState ? "TRUE" : "FALSE",
  78. (dwNow - gdwLastLANTime)/1000,
  79. gdwWANState ? "TRUE" : "FALSE",
  80. (dwNow - gdwLastWANTime)/1000)
  81. );
  82. #if defined(AOL_PLATFORM)
  83. SensPrintA(SENS_INFO, (""
  84. "\n\tAOL State (%s) AOL Time (%d sec)\n",
  85. gdwAOLState ? "TRUE" : "FALSE",
  86. (dwNow - gdwLastWANTime)/1000));
  87. #endif // AOL_PLATFORM
  88. //
  89. // First, get information about the WAN
  90. //
  91. if ((dwNow - gdwLastWANTime) > MAX_WAN_INTERVAL)
  92. {
  93. SensPrintA(SENS_INFO, ("WAN State information expired. Trying again.\n"));
  94. // WAN state is stale, refresh it.
  95. bWanAlive = EvaluateWanConnectivity(&dwWanLastError);
  96. if (bWanAlive)
  97. {
  98. fNetNature |= NETWORK_ALIVE_WAN;
  99. bNetAlive = TRUE;
  100. }
  101. else
  102. {
  103. *lpdwLastError = MapLastError(dwWanLastError);
  104. }
  105. }
  106. else
  107. {
  108. // Return the WAN state.
  109. if (gdwWANState)
  110. {
  111. fNetNature |= NETWORK_ALIVE_WAN;
  112. bNetAlive = TRUE;
  113. bWanAlive = TRUE;
  114. }
  115. }
  116. #if defined(AOL_PLATFORM)
  117. if (bWanAlive && gdwAOLState)
  118. {
  119. fNetNature |= NETWORK_ALIVE_AOL;
  120. }
  121. #endif // AOL_PLATFORM
  122. //
  123. // If we can determine both types of connectivity at this stage, return.
  124. //
  125. if ( ((dwNow - gdwLastLANTime) <= MAX_LAN_INTERVAL)
  126. && (gdwLANState == TRUE))
  127. {
  128. fNetNature |= NETWORK_ALIVE_LAN;
  129. bNetAlive = TRUE;
  130. *lpdwFlags = fNetNature;
  131. *lpbAlive = bNetAlive;
  132. *lpdwLastError = ERROR_SUCCESS;
  133. SensPrintA(SENS_INFO, ("--------------------------------------------------------------\n"));
  134. return (RPC_S_OK);
  135. }
  136. //
  137. // One of the following is TRUE at this stage.
  138. //
  139. // a. Information about LAN is stale.
  140. // b. Information about LAN is current but there is no LAN connectivity.
  141. // So, we go and check for it again.
  142. //
  143. if (gdwLANState == FALSE)
  144. {
  145. SensPrintA(SENS_INFO, ("LAN State either stale or there is no connectivity. Trying again.\n"));
  146. }
  147. else
  148. {
  149. SensPrintA(SENS_INFO, ("LAN State information expired. Trying again.\n"));
  150. }
  151. bLanAlive = EvaluateLanConnectivity(&dwLanLastError);
  152. if (bLanAlive)
  153. {
  154. fNetNature |= NETWORK_ALIVE_LAN;
  155. bNetAlive = TRUE;
  156. }
  157. else
  158. {
  159. *lpdwLastError = MapLastError(dwLanLastError);
  160. }
  161. *lpdwFlags = fNetNature;
  162. *lpbAlive = bNetAlive;
  163. if (bNetAlive)
  164. {
  165. *lpdwLastError = ERROR_SUCCESS;
  166. }
  167. SensPrintA(SENS_INFO, ("--------------------------------------------------------------\n"));
  168. return (RPC_S_OK);
  169. }
  170. error_status_t
  171. RPC_IsDestinationReachableW(
  172. IN handle_t h,
  173. IN wchar_t * lpszDestination,
  174. IN OUT LPQOCINFO lpQOCInfo,
  175. OUT LPBOOL lpbReachable,
  176. OUT LPDWORD lpdwLastError
  177. )
  178. /*++
  179. Routine Description:
  180. Check to see if the given destination is reachable. If so, return Quality
  181. Of Connection (QOC) information, if necessary.
  182. Arguments:
  183. hRpc - The RPC Binding handle.
  184. lpszDestination - The destination whose reachability is of interest.
  185. lpQOCInfo - Pointer to a buffer that will receive Quality of Connection
  186. (QOC) Information. Can be NULL if QOC is not desired.
  187. lpbReachable - Boolean indicating whether the destination is reachable
  188. or not.
  189. lpdwLastError - The out parameter that holds the error code returned
  190. from GetLastError() when the destination is not reachable.
  191. Notes:
  192. This function does nothing on Win9x platforms. It should never be called on Win9x
  193. platforms.
  194. Return Value:
  195. RPC_S_OK, normally.
  196. RPC Error, if there is an RPC-related problem.
  197. --*/
  198. {
  199. BOOL bPingStatus;
  200. BOOL bFound;
  201. DWORD dwStatus;
  202. DWORD dwIpAddress;
  203. DWORD dwReachGLE;
  204. ULONG ulRTT;
  205. size_t uiLength;
  206. #if !defined(SENS_CHICAGO)
  207. //
  208. // Some basic argument checks
  209. //
  210. if (NULL == lpdwLastError)
  211. {
  212. return RPC_S_INVALID_ARG;
  213. }
  214. if ( (NULL == lpszDestination)
  215. || (NULL == lpbReachable))
  216. {
  217. // Not likely.
  218. *lpdwLastError = ERROR_INVALID_PARAMETER;
  219. return RPC_S_OK;
  220. }
  221. uiLength = wcslen(lpszDestination);
  222. if ( (uiLength > MAX_DESTINATION_LENGTH)
  223. || (uiLength == 0))
  224. {
  225. *lpbReachable = FALSE;
  226. *lpdwLastError = ERROR_INVALID_PARAMETER;
  227. return RPC_S_OK;
  228. }
  229. *lpdwLastError = ERROR_SUCCESS;
  230. *lpbReachable = FALSE;
  231. ulRTT = 0;
  232. dwStatus = 0;
  233. dwIpAddress = 0;
  234. dwReachGLE = ERROR_SUCCESS;
  235. bPingStatus = FALSE;
  236. bFound = FALSE;
  237. SensPrintA(SENS_INFO, ("--------------------------------------------------------------\n"));
  238. SensPrint(SENS_INFO, (SENS_STRING("RPC_IsDestinationReachableW(%s, 0x%x) called.\n"),
  239. lpszDestination, lpQOCInfo));
  240. dwStatus = ResolveName(lpszDestination, &dwIpAddress);
  241. if (dwStatus)
  242. {
  243. *lpdwLastError = MapLastError(dwStatus);
  244. *lpbReachable = FALSE;
  245. SensPrint(SENS_INFO, (SENS_STRING("The Destination %s cannot be resolved - %d\n"),
  246. lpszDestination, dwStatus));
  247. SensPrintA(SENS_INFO, ("--------------------------------------------------------------\n"));
  248. return RPC_S_OK;
  249. }
  250. SensPrint(SENS_INFO, (SENS_STRING("Destination \"%s\" is resolved as 0x%x\n"),
  251. lpszDestination, dwIpAddress));
  252. bFound = CheckForReachability(
  253. dwIpAddress,
  254. lpQOCInfo,
  255. &dwReachGLE
  256. );
  257. SensPrintA(SENS_INFO, ("--------------------------------------------------------------\n"));
  258. *lpbReachable = bFound;
  259. *lpdwLastError = MapLastError(dwReachGLE);
  260. #endif // SENS_CHICAGO
  261. return RPC_S_OK;
  262. }
  263. error_status_t
  264. RPC_IsDestinationReachableA(
  265. IN handle_t h,
  266. IN char * lpszDestination,
  267. IN OUT LPQOCINFO lpQOCInfo,
  268. OUT LPBOOL lpbReachable,
  269. OUT LPDWORD lpdwLastError
  270. )
  271. /*++
  272. Routine Description:
  273. Check to see if the given destination is reachable. If so, return Quality
  274. Of Connection (QOC) information, if necessary.
  275. Arguments:
  276. hRpc - The RPC Binding handle.
  277. lpszDestination - The destination whose reachability is of interest.
  278. lpQOCInfo - Pointer to a buffer that will receive Quality of Connection
  279. (QOC) Information. Can be NULL if QOC is not desired.
  280. lpbReachable - Boolean indicating whether the destination is reachable
  281. or not.
  282. lpdwLastError - The out parameter that holds the error code returned
  283. from GetLastError() when the destination is not reachable.
  284. Notes:
  285. This function does nothing on NT platforms. It should never be called on NT
  286. platforms.
  287. Return Value:
  288. RPC_S_OK, normally.
  289. RPC Error, if there is an RPC-related problem.
  290. --*/
  291. {
  292. BOOL bPingStatus;
  293. BOOL bFound;
  294. DWORD dwStatus;
  295. DWORD dwIpAddress;
  296. DWORD dwReachGLE;
  297. ULONG ulRTT;
  298. size_t uiLength;
  299. #if defined(SENS_CHICAGO)
  300. //
  301. // Some basic argument checks
  302. //
  303. if (NULL == lpdwLastError)
  304. {
  305. return RPC_S_INVALID_ARG;
  306. }
  307. if ( (NULL == lpszDestination)
  308. || (NULL == lpbReachable))
  309. {
  310. // Not likely.
  311. *lpdwLastError = ERROR_INVALID_PARAMETER;
  312. return RPC_S_OK;
  313. }
  314. uiLength = strlen(lpszDestination);
  315. if ( (uiLength > MAX_DESTINATION_LENGTH)
  316. || (uiLength == 0))
  317. {
  318. *lpbReachable = FALSE;
  319. *lpdwLastError = ERROR_INVALID_PARAMETER;
  320. return RPC_S_OK;
  321. }
  322. *lpdwLastError = ERROR_SUCCESS;
  323. *lpbReachable = FALSE;
  324. ulRTT = 0;
  325. dwStatus = 0;
  326. dwIpAddress = 0;
  327. dwReachGLE = ERROR_SUCCESS;
  328. bPingStatus = FALSE;
  329. bFound = FALSE;
  330. SensPrintA(SENS_INFO, ("--------------------------------------------------------------\n"));
  331. SensPrint(SENS_INFO, (SENS_STRING("RPC_IsDestinationReachableA(%s, 0x%x) called.\n"),
  332. lpszDestination, lpQOCInfo));
  333. dwStatus = ResolveName(lpszDestination, &dwIpAddress);
  334. if (dwStatus)
  335. {
  336. *lpdwLastError = MapLastError(dwStatus);
  337. *lpbReachable = FALSE;
  338. SensPrint(SENS_INFO, (SENS_STRING("The Destination %s cannot be resolved - %d\n"),
  339. lpszDestination, dwStatus));
  340. SensPrintA(SENS_INFO, ("--------------------------------------------------------------\n"));
  341. return RPC_S_OK;
  342. }
  343. SensPrint(SENS_INFO, (SENS_STRING("Destination \"%s\" is resolved as 0x%x\n"),
  344. lpszDestination, dwIpAddress));
  345. bFound = CheckForReachability(
  346. dwIpAddress,
  347. lpQOCInfo,
  348. &dwReachGLE
  349. );
  350. SensPrintA(SENS_INFO, ("--------------------------------------------------------------\n"));
  351. *lpbReachable = bFound;
  352. *lpdwLastError = MapLastError(dwReachGLE);
  353. #endif // SENS_CHICAGO
  354. return RPC_S_OK;
  355. }
  356. error_status_t
  357. RPC_SensNotifyWinlogonEvent(
  358. handle_t h,
  359. PSENS_NOTIFY_WINLOGON pEvent
  360. )
  361. /*++
  362. Routine Description:
  363. Arguments:
  364. Return Value:
  365. --*/
  366. {
  367. SENSEVENT_WINLOGON Data;
  368. switch (pEvent->eType)
  369. {
  370. case SENS_NOTIFY_WINLOGON_LOGON:
  371. Data.eType = SENS_EVENT_LOGON;
  372. break;
  373. case SENS_NOTIFY_WINLOGON_LOGOFF:
  374. Data.eType = SENS_EVENT_LOGOFF;
  375. break;
  376. case SENS_NOTIFY_WINLOGON_STARTSHELL:
  377. Data.eType = SENS_EVENT_STARTSHELL;
  378. break;
  379. case SENS_NOTIFY_WINLOGON_POSTSHELL:
  380. Data.eType = SENS_EVENT_POSTSHELL;
  381. break;
  382. case SENS_NOTIFY_WINLOGON_SESSION_DISCONNECT:
  383. Data.eType = SENS_EVENT_SESSION_DISCONNECT;
  384. break;
  385. case SENS_NOTIFY_WINLOGON_SESSION_RECONNECT:
  386. Data.eType = SENS_EVENT_SESSION_RECONNECT;
  387. break;
  388. case SENS_NOTIFY_WINLOGON_LOCK:
  389. // If already locked, there is nothing to do.
  390. if (TRUE == gdwLocked)
  391. {
  392. return RPC_S_OK;
  393. }
  394. // Update info in cache.
  395. gdwLocked = TRUE;
  396. UpdateSensCache(LOCK);
  397. Data.eType = SENS_EVENT_LOCK;
  398. break;
  399. case SENS_NOTIFY_WINLOGON_UNLOCK:
  400. // If already unlocked, there is nothing to do.
  401. if (FALSE == gdwLocked)
  402. {
  403. return RPC_S_OK;
  404. }
  405. // Update info in cache.
  406. gdwLocked = FALSE;
  407. UpdateSensCache(LOCK);
  408. Data.eType = SENS_EVENT_UNLOCK;
  409. break;
  410. case SENS_NOTIFY_WINLOGON_STARTSCREENSAVER:
  411. Data.eType = SENS_EVENT_STARTSCREENSAVER;
  412. break;
  413. case SENS_NOTIFY_WINLOGON_STOPSCREENSAVER:
  414. Data.eType = SENS_EVENT_STOPSCREENSAVER;
  415. break;
  416. default:
  417. SensPrintA(SENS_WARN, ("BOGUS WINLOGON EVENT\n"));
  418. ASSERT(0 && "BOGUS WINLOGON EVENT");
  419. return RPC_S_OK;
  420. }
  421. memcpy(&Data.Info, &pEvent->Info, sizeof(WINLOGON_INFO));
  422. //
  423. // PERFORMANCE NOTE:
  424. //
  425. // o We want the Logoff event to be synchronous. That is, until all
  426. // the subscribers to this event are done handling this event,
  427. // System Logoff should not occur.
  428. // o As of today, LCE fires events to the subscribers on the publishers
  429. // thread. If we fire on a threadpool thread, it will release the
  430. // publisher thread which will go and allow System Logoff to continue.
  431. // o This has performance implications. We need to make sure that we
  432. // don't impact System Logoff time when there are no subscriptions
  433. // to this event.
  434. //
  435. if (SENS_EVENT_LOGOFF != Data.eType)
  436. {
  437. // Queue workitem to threadpool
  438. SensFireEvent(&Data);
  439. }
  440. else
  441. {
  442. PVOID pAllocatedData;
  443. pAllocatedData = AllocateEventData(&Data);
  444. if (NULL == pAllocatedData)
  445. {
  446. SensPrintA(SENS_ERR, ("RPC_NotifyWinlogonEvent(): Failed to allocate Event Data!\n"));
  447. return (RPC_S_OUT_OF_MEMORY);
  448. }
  449. // Synchronously call LCE and then free allocated Data.
  450. SensFireEventHelper(pAllocatedData);
  451. }
  452. return (RPC_S_OK);
  453. }
  454. error_status_t
  455. RPC_SensNotifyRasEvent(
  456. handle_t h,
  457. PSENS_NOTIFY_RAS pEvent
  458. )
  459. /*++
  460. Routine Description:
  461. Arguments:
  462. Return Value:
  463. --*/
  464. {
  465. DWORD dwIgnore;
  466. SENSEVENT_RAS Data;
  467. switch (pEvent->eType)
  468. {
  469. case SENS_NOTIFY_RAS_STARTED:
  470. Data.eType = SENS_EVENT_RAS_STARTED;
  471. break;
  472. case SENS_NOTIFY_RAS_STOPPED:
  473. Data.eType = SENS_EVENT_RAS_STOPPED;
  474. break;
  475. case SENS_NOTIFY_RAS_CONNECT:
  476. Data.eType = SENS_EVENT_RAS_CONNECT;
  477. break;
  478. case SENS_NOTIFY_RAS_DISCONNECT:
  479. Data.eType = SENS_EVENT_RAS_DISCONNECT;
  480. break;
  481. case SENS_NOTIFY_RAS_DISCONNECT_PENDING:
  482. Data.eType = SENS_EVENT_RAS_DISCONNECT_PENDING;
  483. break;
  484. default:
  485. SensPrintA(SENS_WARN, ("\t| BOGUS RAS EVENT - Type is %d\n", pEvent->eType));
  486. return RPC_S_OK;
  487. }
  488. Data.hConnection = pEvent->hConnection;
  489. SensFireEvent(&Data);
  490. EvaluateConnectivity(TYPE_WAN);
  491. return (RPC_S_OK);
  492. }
  493. error_status_t
  494. RPC_SensNotifyNetconEvent(
  495. handle_t h,
  496. PSENS_NOTIFY_NETCON_P pEvent
  497. )
  498. /*++
  499. Routine Description:
  500. Arguments:
  501. Return Value:
  502. --*/
  503. {
  504. SENSEVENT_LAN Data;
  505. switch (pEvent->eType)
  506. {
  507. case SENS_NOTIFY_LAN_CONNECT:
  508. Data.eType = SENS_EVENT_LAN_CONNECT;
  509. break;
  510. case SENS_NOTIFY_LAN_DISCONNECT:
  511. Data.eType = SENS_EVENT_LAN_DISCONNECT;
  512. break;
  513. default:
  514. SensPrintA(SENS_WARN, ("\t| BOGUS LAN EVENT - Type is %d\n", pEvent->eType));
  515. return RPC_S_OK;
  516. }
  517. Data.Name = pEvent->Name;
  518. Data.Status = pEvent->Status;
  519. Data.Type = pEvent->Type;
  520. // Force a recalculation of LAN Connectivity
  521. gdwLastLANTime -= (MAX_LAN_INTERVAL + 1);
  522. SensFireEvent(&Data);
  523. EvaluateConnectivity(TYPE_LAN);
  524. return (RPC_S_OK);
  525. }
  526. DWORD
  527. MapLastError(
  528. DWORD dwInGLE
  529. )
  530. /*++
  531. Routine Description:
  532. This rountine maps the GLEs returned by the SENS Connecitivity engine to
  533. GLEs that describe the failure of the SENS APIs more accurately.
  534. Arguments:
  535. dwInGLE - The GLE that needs to be mapped
  536. Return Value:
  537. The mapped (and better) GLE.
  538. --*/
  539. {
  540. DWORD dwOutGLE;
  541. switch (dwInGLE)
  542. {
  543. //
  544. // When IP stack is not present, we typically get these errors.
  545. //
  546. case ERROR_INVALID_FUNCTION:
  547. case ERROR_NOT_SUPPORTED:
  548. dwOutGLE = ERROR_NO_NETWORK;
  549. break;
  550. //
  551. // No mapping by default.
  552. //
  553. default:
  554. dwOutGLE = dwInGLE;
  555. break;
  556. } // switch
  557. return dwOutGLE;
  558. }