Leaked source code of windows server 2003
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.

779 lines
18 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. //
  207. // Some basic argument checks
  208. //
  209. if (NULL == lpdwLastError)
  210. {
  211. return RPC_S_INVALID_ARG;
  212. }
  213. if ( (NULL == lpszDestination)
  214. || (NULL == lpbReachable))
  215. {
  216. // Not likely.
  217. *lpdwLastError = ERROR_INVALID_PARAMETER;
  218. return RPC_S_OK;
  219. }
  220. uiLength = wcslen(lpszDestination);
  221. if ( (uiLength > MAX_DESTINATION_LENGTH)
  222. || (uiLength == 0))
  223. {
  224. *lpbReachable = FALSE;
  225. *lpdwLastError = ERROR_INVALID_PARAMETER;
  226. return RPC_S_OK;
  227. }
  228. *lpdwLastError = ERROR_SUCCESS;
  229. *lpbReachable = FALSE;
  230. ulRTT = 0;
  231. dwStatus = 0;
  232. dwIpAddress = 0;
  233. dwReachGLE = ERROR_SUCCESS;
  234. bPingStatus = FALSE;
  235. bFound = FALSE;
  236. SensPrintA(SENS_INFO, ("--------------------------------------------------------------\n"));
  237. SensPrint(SENS_INFO, (SENS_STRING("RPC_IsDestinationReachableW(%s, 0x%x) called.\n"),
  238. lpszDestination, lpQOCInfo));
  239. dwStatus = ResolveName(lpszDestination, &dwIpAddress);
  240. if (dwStatus)
  241. {
  242. *lpdwLastError = MapLastError(dwStatus);
  243. *lpbReachable = FALSE;
  244. SensPrint(SENS_INFO, (SENS_STRING("The Destination %s cannot be resolved - %d\n"),
  245. lpszDestination, dwStatus));
  246. SensPrintA(SENS_INFO, ("--------------------------------------------------------------\n"));
  247. return RPC_S_OK;
  248. }
  249. SensPrint(SENS_INFO, (SENS_STRING("Destination \"%s\" is resolved as 0x%x\n"),
  250. lpszDestination, dwIpAddress));
  251. bFound = CheckForReachability(
  252. dwIpAddress,
  253. lpQOCInfo,
  254. &dwReachGLE
  255. );
  256. SensPrintA(SENS_INFO, ("--------------------------------------------------------------\n"));
  257. *lpbReachable = bFound;
  258. *lpdwLastError = MapLastError(dwReachGLE);
  259. return RPC_S_OK;
  260. }
  261. error_status_t
  262. RPC_IsDestinationReachableA(
  263. IN handle_t h,
  264. IN char * lpszDestination,
  265. IN OUT LPQOCINFO lpQOCInfo,
  266. OUT LPBOOL lpbReachable,
  267. OUT LPDWORD lpdwLastError
  268. )
  269. /*++
  270. Routine Description:
  271. Check to see if the given destination is reachable. If so, return Quality
  272. Of Connection (QOC) information, if necessary.
  273. Arguments:
  274. hRpc - The RPC Binding handle.
  275. lpszDestination - The destination whose reachability is of interest.
  276. lpQOCInfo - Pointer to a buffer that will receive Quality of Connection
  277. (QOC) Information. Can be NULL if QOC is not desired.
  278. lpbReachable - Boolean indicating whether the destination is reachable
  279. or not.
  280. lpdwLastError - The out parameter that holds the error code returned
  281. from GetLastError() when the destination is not reachable.
  282. Notes:
  283. This function does nothing on NT platforms. It should never be called on NT
  284. platforms.
  285. Return Value:
  286. RPC_S_OK, normally.
  287. RPC Error, if there is an RPC-related problem.
  288. --*/
  289. {
  290. BOOL bPingStatus;
  291. BOOL bFound;
  292. DWORD dwStatus;
  293. DWORD dwIpAddress;
  294. DWORD dwReachGLE;
  295. ULONG ulRTT;
  296. size_t uiLength;
  297. #if defined(SENS_CHICAGO)
  298. //
  299. // Some basic argument checks
  300. //
  301. if (NULL == lpdwLastError)
  302. {
  303. return RPC_S_INVALID_ARG;
  304. }
  305. if ( (NULL == lpszDestination)
  306. || (NULL == lpbReachable))
  307. {
  308. // Not likely.
  309. *lpdwLastError = ERROR_INVALID_PARAMETER;
  310. return RPC_S_OK;
  311. }
  312. uiLength = strlen(lpszDestination);
  313. if ( (uiLength > MAX_DESTINATION_LENGTH)
  314. || (uiLength == 0))
  315. {
  316. *lpbReachable = FALSE;
  317. *lpdwLastError = ERROR_INVALID_PARAMETER;
  318. return RPC_S_OK;
  319. }
  320. *lpdwLastError = ERROR_SUCCESS;
  321. *lpbReachable = FALSE;
  322. ulRTT = 0;
  323. dwStatus = 0;
  324. dwIpAddress = 0;
  325. dwReachGLE = ERROR_SUCCESS;
  326. bPingStatus = FALSE;
  327. bFound = FALSE;
  328. SensPrintA(SENS_INFO, ("--------------------------------------------------------------\n"));
  329. SensPrint(SENS_INFO, (SENS_STRING("RPC_IsDestinationReachableA(%s, 0x%x) called.\n"),
  330. lpszDestination, lpQOCInfo));
  331. dwStatus = ResolveName(lpszDestination, &dwIpAddress);
  332. if (dwStatus)
  333. {
  334. *lpdwLastError = MapLastError(dwStatus);
  335. *lpbReachable = FALSE;
  336. SensPrint(SENS_INFO, (SENS_STRING("The Destination %s cannot be resolved - %d\n"),
  337. lpszDestination, dwStatus));
  338. SensPrintA(SENS_INFO, ("--------------------------------------------------------------\n"));
  339. return RPC_S_OK;
  340. }
  341. SensPrint(SENS_INFO, (SENS_STRING("Destination \"%s\" is resolved as 0x%x\n"),
  342. lpszDestination, dwIpAddress));
  343. bFound = CheckForReachability(
  344. dwIpAddress,
  345. lpQOCInfo,
  346. &dwReachGLE
  347. );
  348. SensPrintA(SENS_INFO, ("--------------------------------------------------------------\n"));
  349. *lpbReachable = bFound;
  350. *lpdwLastError = MapLastError(dwReachGLE);
  351. #endif // SENS_CHICAGO
  352. return RPC_S_OK;
  353. }
  354. error_status_t
  355. RPC_SensNotifyWinlogonEvent(
  356. handle_t h,
  357. PSENS_NOTIFY_WINLOGON pEvent
  358. )
  359. /*++
  360. Routine Description:
  361. Arguments:
  362. Return Value:
  363. --*/
  364. {
  365. SENSEVENT_WINLOGON Data;
  366. RPC_STATUS status;
  367. switch (pEvent->eType)
  368. {
  369. case SENS_NOTIFY_WINLOGON_LOGON:
  370. Data.eType = SENS_EVENT_LOGON;
  371. break;
  372. case SENS_NOTIFY_WINLOGON_LOGOFF:
  373. Data.eType = SENS_EVENT_LOGOFF;
  374. break;
  375. case SENS_NOTIFY_WINLOGON_STARTSHELL:
  376. Data.eType = SENS_EVENT_STARTSHELL;
  377. break;
  378. case SENS_NOTIFY_WINLOGON_POSTSHELL:
  379. Data.eType = SENS_EVENT_POSTSHELL;
  380. break;
  381. case SENS_NOTIFY_WINLOGON_SESSION_DISCONNECT:
  382. Data.eType = SENS_EVENT_SESSION_DISCONNECT;
  383. break;
  384. case SENS_NOTIFY_WINLOGON_SESSION_RECONNECT:
  385. Data.eType = SENS_EVENT_SESSION_RECONNECT;
  386. break;
  387. case SENS_NOTIFY_WINLOGON_LOCK:
  388. // If already locked, there is nothing to do.
  389. if (TRUE == gdwLocked)
  390. {
  391. return RPC_S_OK;
  392. }
  393. // Update info in cache.
  394. gdwLocked = TRUE;
  395. UpdateSensCache(LOCK);
  396. Data.eType = SENS_EVENT_LOCK;
  397. break;
  398. case SENS_NOTIFY_WINLOGON_UNLOCK:
  399. // If already unlocked, there is nothing to do.
  400. if (FALSE == gdwLocked)
  401. {
  402. return RPC_S_OK;
  403. }
  404. // Update info in cache.
  405. gdwLocked = FALSE;
  406. UpdateSensCache(LOCK);
  407. Data.eType = SENS_EVENT_UNLOCK;
  408. break;
  409. case SENS_NOTIFY_WINLOGON_STARTSCREENSAVER:
  410. Data.eType = SENS_EVENT_STARTSCREENSAVER;
  411. break;
  412. case SENS_NOTIFY_WINLOGON_STOPSCREENSAVER:
  413. Data.eType = SENS_EVENT_STOPSCREENSAVER;
  414. break;
  415. default:
  416. SensPrintA(SENS_WARN, ("BOGUS WINLOGON EVENT\n"));
  417. ASSERT(0 && "BOGUS WINLOGON EVENT");
  418. return RPC_S_OK;
  419. }
  420. memcpy(&Data.Info, &pEvent->Info, sizeof(WINLOGON_INFO));
  421. //
  422. // PERFORMANCE NOTE:
  423. //
  424. // o We want the Logoff event to be synchronous. That is, until all
  425. // the subscribers to this event are done handling this event,
  426. // System Logoff should not occur.
  427. // o As of today, LCE fires events to the subscribers on the publishers
  428. // thread. If we fire on a threadpool thread, it will release the
  429. // publisher thread which will go and allow System Logoff to continue.
  430. // o This has performance implications. We need to make sure that we
  431. // don't impact System Logoff time when there are no subscriptions
  432. // to this event.
  433. //
  434. if (SENS_EVENT_LOGOFF != Data.eType)
  435. {
  436. // Queue workitem to threadpool
  437. SensFireEvent(&Data);
  438. }
  439. else
  440. {
  441. PVOID pAllocatedData;
  442. pAllocatedData = AllocateEventData(&Data);
  443. if (NULL == pAllocatedData)
  444. {
  445. SensPrintA(SENS_ERR, ("RPC_NotifyWinlogonEvent(): Failed to allocate Event Data!\n"));
  446. return (RPC_S_OUT_OF_MEMORY);
  447. }
  448. // Synchronously call LCE and then free allocated Data.
  449. SensFireEventHelper(pAllocatedData);
  450. }
  451. return (RPC_S_OK);
  452. }
  453. error_status_t
  454. RPC_SensNotifyRasEvent(
  455. handle_t h,
  456. PSENS_NOTIFY_RAS pEvent
  457. )
  458. /*++
  459. Routine Description:
  460. Arguments:
  461. Return Value:
  462. --*/
  463. {
  464. DWORD dwIgnore;
  465. SENSEVENT_RAS Data;
  466. switch (pEvent->eType)
  467. {
  468. case SENS_NOTIFY_RAS_STARTED:
  469. Data.eType = SENS_EVENT_RAS_STARTED;
  470. break;
  471. case SENS_NOTIFY_RAS_STOPPED:
  472. Data.eType = SENS_EVENT_RAS_STOPPED;
  473. break;
  474. case SENS_NOTIFY_RAS_CONNECT:
  475. Data.eType = SENS_EVENT_RAS_CONNECT;
  476. break;
  477. case SENS_NOTIFY_RAS_DISCONNECT:
  478. Data.eType = SENS_EVENT_RAS_DISCONNECT;
  479. break;
  480. case SENS_NOTIFY_RAS_DISCONNECT_PENDING:
  481. Data.eType = SENS_EVENT_RAS_DISCONNECT_PENDING;
  482. break;
  483. default:
  484. SensPrintA(SENS_WARN, ("\t| BOGUS RAS EVENT - Type is %d\n", pEvent->eType));
  485. return RPC_S_OK;
  486. }
  487. Data.hConnection = pEvent->hConnection;
  488. SensFireEvent(&Data);
  489. EvaluateConnectivity(TYPE_WAN);
  490. return (RPC_S_OK);
  491. }
  492. error_status_t
  493. RPC_SensNotifyNetconEvent(
  494. handle_t h,
  495. PSENS_NOTIFY_NETCON_P pEvent
  496. )
  497. /*++
  498. Routine Description:
  499. Arguments:
  500. Return Value:
  501. --*/
  502. {
  503. SENSEVENT_LAN Data;
  504. switch (pEvent->eType)
  505. {
  506. case SENS_NOTIFY_LAN_CONNECT:
  507. Data.eType = SENS_EVENT_LAN_CONNECT;
  508. break;
  509. case SENS_NOTIFY_LAN_DISCONNECT:
  510. Data.eType = SENS_EVENT_LAN_DISCONNECT;
  511. break;
  512. default:
  513. SensPrintA(SENS_WARN, ("\t| BOGUS LAN EVENT - Type is %d\n", pEvent->eType));
  514. return RPC_S_OK;
  515. }
  516. Data.Name = pEvent->Name;
  517. Data.Status = pEvent->Status;
  518. Data.Type = pEvent->Type;
  519. // Force a recalculation of LAN Connectivity
  520. gdwLastLANTime -= (MAX_LAN_INTERVAL + 1);
  521. SensFireEvent(&Data);
  522. EvaluateConnectivity(TYPE_LAN);
  523. return (RPC_S_OK);
  524. }
  525. DWORD
  526. MapLastError(
  527. DWORD dwInGLE
  528. )
  529. /*++
  530. Routine Description:
  531. This rountine maps the GLEs returned by the SENS Connecitivity engine to
  532. GLEs that describe the failure of the SENS APIs more accurately.
  533. Arguments:
  534. dwInGLE - The GLE that needs to be mapped
  535. Return Value:
  536. The mapped (and better) GLE.
  537. --*/
  538. {
  539. DWORD dwOutGLE;
  540. switch (dwInGLE)
  541. {
  542. //
  543. // When IP stack is not present, we typically get these errors.
  544. //
  545. case ERROR_INVALID_FUNCTION:
  546. case ERROR_NOT_SUPPORTED:
  547. dwOutGLE = ERROR_NO_NETWORK;
  548. break;
  549. //
  550. // No mapping by default.
  551. //
  552. default:
  553. dwOutGLE = dwInGLE;
  554. break;
  555. } // switch
  556. return dwOutGLE;
  557. }