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.

640 lines
21 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: S M R A S . C P P
  7. //
  8. // Contents: The RAS engine that provides statistics to the status monitor
  9. //
  10. // Notes:
  11. //
  12. // Author: CWill 12/02/1997
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "ncras.h"
  18. #include "sminc.h"
  19. #include "netcon.h"
  20. #include "smpsh.h"
  21. #include "mprapi.h"
  22. //+---------------------------------------------------------------------------
  23. //
  24. // Member: CRasStatEngine::CRasStatEngine
  25. //
  26. // Purpose: Creator
  27. //
  28. // Arguments: None
  29. //
  30. // Returns: Nil
  31. //
  32. CRasStatEngine::CRasStatEngine() :
  33. m_hRasConn(NULL)
  34. {
  35. m_ncmType = NCM_PHONE;
  36. m_dwCharacter = NCCF_OUTGOING_ONLY;
  37. return;
  38. }
  39. //+---------------------------------------------------------------------------
  40. //
  41. // Member: CRasStatEngine::put_RasConn
  42. //
  43. // Purpose: Pass handles to the RAS engine
  44. //
  45. // Arguments: hRasConn - The handle being set
  46. //
  47. // Returns: Error code
  48. //
  49. VOID CRasStatEngine::put_RasConn(HRASCONN hRasConn)
  50. {
  51. AssertSz(hRasConn, "We should have a hRasConn");
  52. m_hRasConn = hRasConn;
  53. }
  54. //+---------------------------------------------------------------------------
  55. //
  56. // Member: CRasStatEngine::put_MediaType
  57. //
  58. // Purpose: Pass media type of RAS connection type to the RAS engine
  59. //
  60. // Arguments: ncmType - NETCON_MEDIATYPE being set
  61. // ncsmType - NETCON_SUBMEDIATYPE being set
  62. //
  63. // Returns:
  64. //
  65. VOID CRasStatEngine::put_MediaType(NETCON_MEDIATYPE ncmType, NETCON_SUBMEDIATYPE ncsmType)
  66. {
  67. m_ncmType = ncmType;
  68. m_ncsmType = ncsmType;
  69. }
  70. //+---------------------------------------------------------------------------
  71. //
  72. // Member: CRasStatEngine::put_Character
  73. //
  74. // Purpose: Character of RAS connection
  75. //
  76. // Arguments: dwCharacter - The character being set
  77. //
  78. // Returns:
  79. //
  80. VOID CRasStatEngine::put_Character(DWORD dwCharacter)
  81. {
  82. m_dwCharacter = dwCharacter;
  83. }
  84. //+---------------------------------------------------------------------------
  85. //
  86. // Member: CRasStatEngine::HrUpdateData
  87. //
  88. // Purpose: Get new statistics from the devices. This data is used to be
  89. // displayed in the UI.
  90. //
  91. // Arguments: pdwChangeFlags - Where to return for statistics
  92. //
  93. // Returns: Error code
  94. //
  95. HRESULT
  96. CRasStatEngine::HrUpdateData (
  97. DWORD* pdwChangeFlags,
  98. BOOL* pfNoLongerConnected)
  99. {
  100. HRESULT hr = S_OK;
  101. // Initialize the output parameters.
  102. //
  103. if (pdwChangeFlags)
  104. {
  105. *pdwChangeFlags = SMDCF_NULL;
  106. }
  107. *pfNoLongerConnected = FALSE;
  108. CExceptionSafeComObjectLock EsLock(this);
  109. // Get a pointer to the elements of the array.
  110. //
  111. if (m_dwCharacter & NCCF_OUTGOING_ONLY)
  112. {
  113. // Get the status of the connection.
  114. //
  115. NETCON_STATUS ncs;
  116. hr = HrRasGetNetconStatusFromRasConnectStatus (
  117. m_hRasConn, &ncs);
  118. // Make sure we have a statistics structure
  119. //
  120. EnterCriticalSection(&g_csStatmonData);
  121. if (!m_psmEngineData)
  122. {
  123. m_psmEngineData = new STATMON_ENGINEDATA;
  124. if (m_psmEngineData)
  125. {
  126. ZeroMemory(m_psmEngineData, sizeof(STATMON_ENGINEDATA));
  127. }
  128. }
  129. // Set the status
  130. //
  131. if (m_psmEngineData)
  132. {
  133. if (SUCCEEDED(hr) && (NCS_DISCONNECTED != ncs))
  134. {
  135. m_psmEngineData->SMED_CONNECTIONSTATUS = ncs;
  136. }
  137. else if (HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE) == hr)
  138. {
  139. *pfNoLongerConnected = TRUE;
  140. // set the connection status to "disconnected" so we can close the UI
  141. m_psmEngineData->SMED_CONNECTIONSTATUS = NCS_DISCONNECTED;
  142. hr = S_OK;
  143. }
  144. }
  145. else
  146. {
  147. hr = E_OUTOFMEMORY;
  148. }
  149. LeaveCriticalSection(&g_csStatmonData);
  150. if ((m_psmEngineData) && SUCCEEDED(hr) && (NCS_DISCONNECTED != ncs))
  151. {
  152. // Retrieve the statistics of the connection
  153. //
  154. RAS_STATS rsNewData;
  155. rsNewData.dwSize = sizeof(RAS_STATS);
  156. DWORD dwErr = RasGetConnectionStatistics(m_hRasConn, &rsNewData);
  157. hr = HRESULT_FROM_WIN32 (dwErr);
  158. TraceError ("RasGetConnectionStatistics", hr);
  159. if (SUCCEEDED(hr))
  160. {
  161. // Update the change flags if asked for
  162. //
  163. if (pdwChangeFlags)
  164. {
  165. if (m_psmEngineData->SMED_PACKETSTRANSMITTING
  166. != rsNewData.dwFramesXmited)
  167. {
  168. *pdwChangeFlags |= SMDCF_TRANSMITTING;
  169. }
  170. if (m_psmEngineData->SMED_PACKETSRECEIVING
  171. != rsNewData.dwFramesRcved)
  172. {
  173. *pdwChangeFlags |= SMDCF_RECEIVING;
  174. }
  175. }
  176. // Get the rest of the data
  177. //
  178. m_psmEngineData->SMED_DURATION = rsNewData.dwConnectDuration/1000;
  179. // Don't pass out speed info for VPN connections (294953)
  180. if (NCM_TUNNEL != m_ncmType)
  181. {
  182. m_psmEngineData->SMED_SPEEDTRANSMITTING = rsNewData.dwBps;
  183. m_psmEngineData->SMED_SPEEDRECEIVING = rsNewData.dwBps;
  184. }
  185. m_psmEngineData->SMED_BYTESTRANSMITTING = rsNewData.dwBytesXmited;
  186. m_psmEngineData->SMED_BYTESRECEIVING = rsNewData.dwBytesRcved;
  187. m_psmEngineData->SMED_COMPRESSIONTRANSMITTING = rsNewData.dwCompressionRatioOut;
  188. m_psmEngineData->SMED_COMPRESSIONRECEIVING = rsNewData.dwCompressionRatioIn;
  189. m_psmEngineData->SMED_ERRORSTRANSMITTING = 0;
  190. m_psmEngineData->SMED_ERRORSRECEIVING = rsNewData.dwCrcErr +
  191. rsNewData.dwTimeoutErr +
  192. rsNewData.dwAlignmentErr +
  193. rsNewData.dwHardwareOverrunErr +
  194. rsNewData.dwFramingErr +
  195. rsNewData.dwBufferOverrunErr;
  196. m_psmEngineData->SMED_PACKETSTRANSMITTING = rsNewData.dwFramesXmited;
  197. m_psmEngineData->SMED_PACKETSRECEIVING = rsNewData.dwFramesRcved;
  198. m_psmEngineData->SMED_INFRASTRUCTURE_MODE = IM_NOT_SUPPORTED;
  199. }
  200. }
  201. }
  202. else if (m_dwCharacter & NCCF_INCOMING_ONLY)
  203. {
  204. // RAS inbound connection
  205. EnterCriticalSection(&g_csStatmonData);
  206. if (!m_psmEngineData)
  207. {
  208. m_psmEngineData = new STATMON_ENGINEDATA;
  209. if(m_psmEngineData)
  210. {
  211. ZeroMemory(m_psmEngineData, sizeof(STATMON_ENGINEDATA));
  212. }
  213. }
  214. // Set the status
  215. //
  216. if (m_psmEngineData)
  217. {
  218. // Set the status to connected by default
  219. // Unless we get ERROR_INVALID_PARAMETER on any of the function calls below
  220. //
  221. m_psmEngineData->SMED_CONNECTIONSTATUS = NCS_CONNECTED;
  222. }
  223. else
  224. {
  225. hr = E_OUTOFMEMORY;
  226. }
  227. LeaveCriticalSection(&g_csStatmonData);
  228. if (SUCCEEDED(hr) && m_psmEngineData)
  229. {
  230. // Get the server handle
  231. //
  232. RAS_SERVER_HANDLE hMprAdmin;
  233. DWORD dwError = MprAdminServerConnect(NULL, &hMprAdmin);
  234. if (dwError == NO_ERROR)
  235. {
  236. // Get connection duration
  237. //
  238. RAS_CONNECTION_0 * pConn0;
  239. dwError = MprAdminConnectionGetInfo(hMprAdmin,
  240. 0,
  241. m_hRasConn,
  242. (LPBYTE*)&pConn0);
  243. if (dwError == NO_ERROR)
  244. {
  245. // duration needs to be in milliseconds
  246. m_psmEngineData->SMED_DURATION = pConn0->dwConnectDuration;
  247. MprAdminBufferFree(pConn0);
  248. // Get connection speed
  249. // Don't pass out speed info for VPN connections (357758)
  250. if (NCM_TUNNEL != m_ncmType)
  251. {
  252. // Enum all the ports and add up the link speed
  253. //
  254. RAS_PORT_0 * pPort0;
  255. DWORD dwPortCount;
  256. DWORD dwTotalEntries;
  257. dwError = MprAdminPortEnum (hMprAdmin,
  258. 0,
  259. m_hRasConn,
  260. (LPBYTE*)&pPort0,
  261. -1,
  262. &dwPortCount,
  263. &dwTotalEntries,
  264. NULL);
  265. if (dwError == NOERROR)
  266. {
  267. RAS_PORT_0 * pCurPort0 = pPort0;
  268. DWORD dwConnSpeed=0;
  269. while (dwPortCount)
  270. {
  271. RAS_PORT_1 * pCurPort1;
  272. dwError = MprAdminPortGetInfo(hMprAdmin,
  273. 1,
  274. pCurPort0->hPort,
  275. (LPBYTE*)&pCurPort1);
  276. if (dwError == NO_ERROR)
  277. {
  278. dwConnSpeed += pCurPort1->dwLineSpeed;
  279. }
  280. else
  281. {
  282. break;
  283. }
  284. MprAdminBufferFree(pCurPort1);
  285. dwPortCount--;
  286. pCurPort0++;
  287. }
  288. MprAdminBufferFree(pPort0);
  289. if (dwError == NO_ERROR)
  290. {
  291. // Get the accumulated connection speed
  292. m_psmEngineData->SMED_SPEEDTRANSMITTING = dwConnSpeed;
  293. m_psmEngineData->SMED_SPEEDRECEIVING = dwConnSpeed;
  294. }
  295. }
  296. }
  297. if (dwError == NO_ERROR)
  298. {
  299. // Get Transmitted\Received Bytes, Compression and Bytes
  300. RAS_CONNECTION_1 * pConn1;
  301. dwError = MprAdminConnectionGetInfo(hMprAdmin,
  302. 1,
  303. m_hRasConn,
  304. (LPBYTE*)&pConn1);
  305. if (dwError == NO_ERROR)
  306. {
  307. // Update the change flags if asked for
  308. //
  309. if (pdwChangeFlags)
  310. {
  311. if (m_psmEngineData->SMED_BYTESTRANSMITTING
  312. != pConn1->dwBytesXmited)
  313. {
  314. *pdwChangeFlags |= SMDCF_TRANSMITTING;
  315. }
  316. if (m_psmEngineData->SMED_BYTESRECEIVING
  317. != pConn1->dwBytesRcved)
  318. {
  319. *pdwChangeFlags |= SMDCF_RECEIVING;
  320. }
  321. }
  322. m_psmEngineData->SMED_BYTESTRANSMITTING = pConn1->dwBytesXmited;
  323. m_psmEngineData->SMED_BYTESRECEIVING = pConn1->dwBytesRcved;
  324. m_psmEngineData->SMED_COMPRESSIONTRANSMITTING = pConn1->dwCompressionRatioOut;
  325. m_psmEngineData->SMED_COMPRESSIONRECEIVING = pConn1->dwCompressionRatioIn;
  326. m_psmEngineData->SMED_ERRORSTRANSMITTING = 0;
  327. m_psmEngineData->SMED_ERRORSRECEIVING = pConn1->dwCrcErr +
  328. pConn1->dwTimeoutErr +
  329. pConn1->dwAlignmentErr +
  330. pConn1->dwHardwareOverrunErr +
  331. pConn1->dwFramingErr +
  332. pConn1->dwBufferOverrunErr;
  333. }
  334. MprAdminBufferFree(pConn1);
  335. }
  336. }
  337. if (dwError != NO_ERROR)
  338. {
  339. *pfNoLongerConnected = TRUE;
  340. // set the connection status to "disconnected" so we can close the UI
  341. m_psmEngineData->SMED_CONNECTIONSTATUS = NCS_DISCONNECTED;
  342. hr = S_OK;
  343. }
  344. }
  345. MprAdminServerDisconnect (hMprAdmin);
  346. }
  347. }
  348. TraceError("CRasStatEngine::HrUpdateData", hr);
  349. return hr;
  350. }
  351. //////////////////////////////////////////////////////////////////////////////
  352. // //
  353. // CPspRasGen //
  354. // //
  355. //////////////////////////////////////////////////////////////////////////////
  356. CPspRasGen::CPspRasGen(VOID)
  357. {
  358. m_ncmType = NCM_PHONE;
  359. m_dwCharacter = NCCF_OUTGOING_ONLY;
  360. m_adwHelpIDs = NULL;
  361. }
  362. //+---------------------------------------------------------------------------
  363. //
  364. // Member: CPspRasGen::put_MediaType
  365. //
  366. // Purpose: Pass media type of RAS connection type to the RAS engine
  367. //
  368. // Arguments: ncmType - NETCON_MEDIATYPE being set
  369. // ncsmType - NETCON_SUBMEDIATYPE being set
  370. //
  371. // Returns:
  372. //
  373. VOID CPspRasGen::put_MediaType(NETCON_MEDIATYPE ncmType, NETCON_SUBMEDIATYPE ncsmType)
  374. {
  375. m_ncmType = ncmType;
  376. m_ncsmType = ncsmType;
  377. }
  378. VOID CPspRasGen::put_Character(DWORD dwCharacter)
  379. {
  380. m_dwCharacter = dwCharacter;
  381. }
  382. //////////////////////////////////////////////////////////////////////////////
  383. // //
  384. // CPspRasTool //
  385. // //
  386. //////////////////////////////////////////////////////////////////////////////
  387. CPspRasTool::CPspRasTool(VOID)
  388. {
  389. m_ncmType = NCM_PHONE;
  390. m_dwCharacter = NCCF_OUTGOING_ONLY;
  391. m_adwHelpIDs = NULL;
  392. }
  393. VOID CPspRasTool::put_MediaType(NETCON_MEDIATYPE ncmType, NETCON_SUBMEDIATYPE ncsmType)
  394. {
  395. m_ncmType = ncmType;
  396. m_ncsmType = ncsmType;
  397. }
  398. VOID CPspRasTool::put_Character(DWORD dwCharacter)
  399. {
  400. m_dwCharacter = dwCharacter;
  401. }
  402. //+---------------------------------------------------------------------------
  403. //
  404. // Member: CPspRasTool::HrInitToolPageType
  405. //
  406. // Purpose: Gets from the connection any information that is relevant to
  407. // this particular connection type.
  408. //
  409. // Arguments: pncInit - The connection assocatied with this dialog
  410. //
  411. // Returns: Error code
  412. //
  413. HRESULT CPspRasTool::HrInitToolPageType(INetConnection* pncInit)
  414. {
  415. HRESULT hr = S_OK;
  416. TraceError("CPspRasTool::HrInitToolPageType", hr);
  417. return hr;
  418. }
  419. //+---------------------------------------------------------------------------
  420. //
  421. // Member: CPspRasTool::HrAddCommandLineFlags
  422. //
  423. // Purpose: Adds the flags for this selection to the command line for the
  424. // tool being launched.
  425. //
  426. // Arguments: pstrFlags - The command line that the flags have to be
  427. // appended to
  428. // psmteSel - The tool entry associated with this selection
  429. //
  430. // Returns: Error code
  431. //
  432. HRESULT CPspRasTool::HrAddCommandLineFlags(tstring* pstrFlags,
  433. CStatMonToolEntry* psmteSel)
  434. {
  435. HRESULT hr = S_OK;
  436. //
  437. // Check what flags are asked for and provide them if we can
  438. //
  439. TraceError("CPspRasTool::HrAddCommandLineFlags", hr);
  440. return hr;
  441. }
  442. HRESULT CPspRasTool::HrGetDeviceType(INetConnection* pncInit)
  443. {
  444. HRESULT hr = S_OK;
  445. RASCONN* aRasConn;
  446. DWORD cRasConn;
  447. hr = HrRasEnumAllActiveConnections (
  448. &aRasConn,
  449. &cRasConn);
  450. if (SUCCEEDED(hr))
  451. {
  452. for (DWORD i = 0; i < cRasConn; i++)
  453. {
  454. if (m_guidId == aRasConn[i].guidEntry)
  455. {
  456. // Note: device types in RAS connections are defined
  457. // as follows in public\sdk\inc ras.h as RASDT_XXX
  458. m_strDeviceType = aRasConn[i].szDeviceType;
  459. break;
  460. }
  461. }
  462. MemFree (aRasConn);
  463. }
  464. return S_OK;
  465. }
  466. HRESULT CPspRasTool::HrGetComponentList(INetConnection* pncInit)
  467. {
  468. // Obtain ras handle to this connection
  469. HRESULT hr = S_OK;
  470. HRASCONN hRasConn = NULL;
  471. if (m_dwCharacter & NCCF_OUTGOING_ONLY)
  472. {
  473. // for outgoing connection
  474. INetRasConnection* pnrcNew = NULL;
  475. hr = HrQIAndSetProxyBlanket(pncInit, &pnrcNew);
  476. if (SUCCEEDED(hr))
  477. {
  478. hr = pnrcNew->GetRasConnectionHandle(
  479. reinterpret_cast<ULONG_PTR*>(&hRasConn));
  480. ReleaseObj(pnrcNew);
  481. }
  482. }
  483. else if (m_dwCharacter & NCCF_INCOMING_ONLY)
  484. {
  485. // for incoming connection
  486. INetInboundConnection* pnicNew;
  487. hr = HrQIAndSetProxyBlanket(pncInit, &pnicNew);
  488. if (SUCCEEDED(hr))
  489. {
  490. hr = pnicNew->GetServerConnectionHandle(
  491. reinterpret_cast<ULONG_PTR*>(&hRasConn));
  492. ReleaseObj(pnicNew);
  493. }
  494. }
  495. if (SUCCEEDED(hr) && hRasConn)
  496. {
  497. // Get protocols list
  498. DWORD dwRetCode;
  499. DWORD dwSize;
  500. // RASP_PppIp
  501. RASPPPIP RasPppIp;
  502. RasPppIp.dwSize = sizeof( RasPppIp );
  503. dwSize = sizeof( RasPppIp );
  504. dwRetCode = RasGetProjectionInfo (hRasConn, RASP_PppIp, &RasPppIp, &dwSize);
  505. if ((dwRetCode == NO_ERROR) && (NO_ERROR == RasPppIp.dwError))
  506. {
  507. m_lstpstrCompIds.push_back(new tstring(L"MS_TCPIP"));
  508. }
  509. // RASP_PppIpx
  510. RASPPPIPX RasPppIpx;
  511. RasPppIpx.dwSize = sizeof( RasPppIpx );
  512. dwSize = sizeof( RasPppIpx );
  513. dwRetCode = RasGetProjectionInfo (hRasConn, RASP_PppIpx, &RasPppIpx, &dwSize);
  514. if ((dwRetCode == NO_ERROR) && (NO_ERROR == RasPppIpx.dwError))
  515. {
  516. m_lstpstrCompIds.push_back(new tstring(L"MS_NWIPX"));
  517. }
  518. // RASP_PppNbf
  519. RASPPPNBF RasPppNbf;
  520. RasPppNbf.dwSize = sizeof( RasPppNbf );
  521. dwSize = sizeof( RasPppNbf );
  522. dwRetCode = RasGetProjectionInfo (hRasConn, RASP_PppNbf, &RasPppNbf, &dwSize);
  523. if ((dwRetCode == NO_ERROR) && (NO_ERROR == RasPppNbf.dwError))
  524. {
  525. m_lstpstrCompIds.push_back(new tstring(L"MS_NetBEUI"));
  526. }
  527. // RASP_Slip
  528. RASSLIP RasSlip;
  529. RasSlip.dwSize = sizeof( RasSlip );
  530. dwSize = sizeof( RasSlip );
  531. dwRetCode = RasGetProjectionInfo (hRasConn, RASP_Slip, &RasSlip, &dwSize);
  532. if ((dwRetCode == NO_ERROR) && (NO_ERROR == RasSlip.dwError))
  533. {
  534. m_lstpstrCompIds.push_back(new tstring(L"MS_TCPIP"));
  535. }
  536. }
  537. // Get client and services
  538. // $REVIEW(tongl 10/19): checked with Rao, for now we hard code
  539. // using MSClient and F&P services for all RAS connections
  540. // (raid #132575)
  541. m_lstpstrCompIds.push_back(new tstring(L"MS_MSCLIENT"));
  542. m_lstpstrCompIds.push_back(new tstring(L"MS_SERVER"));
  543. return S_OK;
  544. }