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.

641 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. HrGetAutoNetSetting(m_guidId, &(m_psmEngineData->SMED_DHCP_ADDRESS_TYPE) );
  199. m_psmEngineData->SMED_INFRASTRUCTURE_MODE = IM_NOT_SUPPORTED;
  200. }
  201. }
  202. }
  203. else if (m_dwCharacter & NCCF_INCOMING_ONLY)
  204. {
  205. // RAS inbound connection
  206. EnterCriticalSection(&g_csStatmonData);
  207. if (!m_psmEngineData)
  208. {
  209. m_psmEngineData = new STATMON_ENGINEDATA;
  210. if(m_psmEngineData)
  211. {
  212. ZeroMemory(m_psmEngineData, sizeof(STATMON_ENGINEDATA));
  213. }
  214. }
  215. // Set the status
  216. //
  217. if (m_psmEngineData)
  218. {
  219. // Set the status to connected by default
  220. // Unless we get ERROR_INVALID_PARAMETER on any of the function calls below
  221. //
  222. m_psmEngineData->SMED_CONNECTIONSTATUS = NCS_CONNECTED;
  223. }
  224. else
  225. {
  226. hr = E_OUTOFMEMORY;
  227. }
  228. LeaveCriticalSection(&g_csStatmonData);
  229. if (SUCCEEDED(hr) && m_psmEngineData)
  230. {
  231. // Get the server handle
  232. //
  233. RAS_SERVER_HANDLE hMprAdmin;
  234. DWORD dwError = MprAdminServerConnect(NULL, &hMprAdmin);
  235. if (dwError == NO_ERROR)
  236. {
  237. // Get connection duration
  238. //
  239. RAS_CONNECTION_0 * pConn0;
  240. dwError = MprAdminConnectionGetInfo(hMprAdmin,
  241. 0,
  242. m_hRasConn,
  243. (LPBYTE*)&pConn0);
  244. if (dwError == NO_ERROR)
  245. {
  246. // duration needs to be in milliseconds
  247. m_psmEngineData->SMED_DURATION = pConn0->dwConnectDuration;
  248. MprAdminBufferFree(pConn0);
  249. // Get connection speed
  250. // Don't pass out speed info for VPN connections (357758)
  251. if (NCM_TUNNEL != m_ncmType)
  252. {
  253. // Enum all the ports and add up the link speed
  254. //
  255. RAS_PORT_0 * pPort0;
  256. DWORD dwPortCount;
  257. DWORD dwTotalEntries;
  258. dwError = MprAdminPortEnum (hMprAdmin,
  259. 0,
  260. m_hRasConn,
  261. (LPBYTE*)&pPort0,
  262. -1,
  263. &dwPortCount,
  264. &dwTotalEntries,
  265. NULL);
  266. if (dwError == NOERROR)
  267. {
  268. RAS_PORT_0 * pCurPort0 = pPort0;
  269. DWORD dwConnSpeed=0;
  270. while (dwPortCount)
  271. {
  272. RAS_PORT_1 * pCurPort1;
  273. dwError = MprAdminPortGetInfo(hMprAdmin,
  274. 1,
  275. pCurPort0->hPort,
  276. (LPBYTE*)&pCurPort1);
  277. if (dwError == NO_ERROR)
  278. {
  279. dwConnSpeed += pCurPort1->dwLineSpeed;
  280. }
  281. else
  282. {
  283. break;
  284. }
  285. MprAdminBufferFree(pCurPort1);
  286. dwPortCount--;
  287. pCurPort0++;
  288. }
  289. MprAdminBufferFree(pPort0);
  290. if (dwError == NO_ERROR)
  291. {
  292. // Get the accumulated connection speed
  293. m_psmEngineData->SMED_SPEEDTRANSMITTING = dwConnSpeed;
  294. m_psmEngineData->SMED_SPEEDRECEIVING = dwConnSpeed;
  295. }
  296. }
  297. }
  298. if (dwError == NO_ERROR)
  299. {
  300. // Get Transmitted\Received Bytes, Compression and Bytes
  301. RAS_CONNECTION_1 * pConn1;
  302. dwError = MprAdminConnectionGetInfo(hMprAdmin,
  303. 1,
  304. m_hRasConn,
  305. (LPBYTE*)&pConn1);
  306. if (dwError == NO_ERROR)
  307. {
  308. // Update the change flags if asked for
  309. //
  310. if (pdwChangeFlags)
  311. {
  312. if (m_psmEngineData->SMED_BYTESTRANSMITTING
  313. != pConn1->dwBytesXmited)
  314. {
  315. *pdwChangeFlags |= SMDCF_TRANSMITTING;
  316. }
  317. if (m_psmEngineData->SMED_BYTESRECEIVING
  318. != pConn1->dwBytesRcved)
  319. {
  320. *pdwChangeFlags |= SMDCF_RECEIVING;
  321. }
  322. }
  323. m_psmEngineData->SMED_BYTESTRANSMITTING = pConn1->dwBytesXmited;
  324. m_psmEngineData->SMED_BYTESRECEIVING = pConn1->dwBytesRcved;
  325. m_psmEngineData->SMED_COMPRESSIONTRANSMITTING = pConn1->dwCompressionRatioOut;
  326. m_psmEngineData->SMED_COMPRESSIONRECEIVING = pConn1->dwCompressionRatioIn;
  327. m_psmEngineData->SMED_ERRORSTRANSMITTING = 0;
  328. m_psmEngineData->SMED_ERRORSRECEIVING = pConn1->dwCrcErr +
  329. pConn1->dwTimeoutErr +
  330. pConn1->dwAlignmentErr +
  331. pConn1->dwHardwareOverrunErr +
  332. pConn1->dwFramingErr +
  333. pConn1->dwBufferOverrunErr;
  334. }
  335. MprAdminBufferFree(pConn1);
  336. }
  337. }
  338. if (dwError != NO_ERROR)
  339. {
  340. *pfNoLongerConnected = TRUE;
  341. // set the connection status to "disconnected" so we can close the UI
  342. m_psmEngineData->SMED_CONNECTIONSTATUS = NCS_DISCONNECTED;
  343. hr = S_OK;
  344. }
  345. }
  346. MprAdminServerDisconnect (hMprAdmin);
  347. }
  348. }
  349. TraceError("CRasStatEngine::HrUpdateData", hr);
  350. return hr;
  351. }
  352. //////////////////////////////////////////////////////////////////////////////
  353. // //
  354. // CPspRasGen //
  355. // //
  356. //////////////////////////////////////////////////////////////////////////////
  357. CPspRasGen::CPspRasGen(VOID)
  358. {
  359. m_ncmType = NCM_PHONE;
  360. m_dwCharacter = NCCF_OUTGOING_ONLY;
  361. m_adwHelpIDs = NULL;
  362. }
  363. //+---------------------------------------------------------------------------
  364. //
  365. // Member: CPspRasGen::put_MediaType
  366. //
  367. // Purpose: Pass media type of RAS connection type to the RAS engine
  368. //
  369. // Arguments: ncmType - NETCON_MEDIATYPE being set
  370. // ncsmType - NETCON_SUBMEDIATYPE being set
  371. //
  372. // Returns:
  373. //
  374. VOID CPspRasGen::put_MediaType(NETCON_MEDIATYPE ncmType, NETCON_SUBMEDIATYPE ncsmType)
  375. {
  376. m_ncmType = ncmType;
  377. m_ncsmType = ncsmType;
  378. }
  379. VOID CPspRasGen::put_Character(DWORD dwCharacter)
  380. {
  381. m_dwCharacter = dwCharacter;
  382. }
  383. //////////////////////////////////////////////////////////////////////////////
  384. // //
  385. // CPspRasTool //
  386. // //
  387. //////////////////////////////////////////////////////////////////////////////
  388. CPspRasTool::CPspRasTool(VOID)
  389. {
  390. m_ncmType = NCM_PHONE;
  391. m_dwCharacter = NCCF_OUTGOING_ONLY;
  392. m_adwHelpIDs = NULL;
  393. }
  394. VOID CPspRasTool::put_MediaType(NETCON_MEDIATYPE ncmType, NETCON_SUBMEDIATYPE ncsmType)
  395. {
  396. m_ncmType = ncmType;
  397. m_ncsmType = ncsmType;
  398. }
  399. VOID CPspRasTool::put_Character(DWORD dwCharacter)
  400. {
  401. m_dwCharacter = dwCharacter;
  402. }
  403. //+---------------------------------------------------------------------------
  404. //
  405. // Member: CPspRasTool::HrInitToolPageType
  406. //
  407. // Purpose: Gets from the connection any information that is relevant to
  408. // this particular connection type.
  409. //
  410. // Arguments: pncInit - The connection assocatied with this dialog
  411. //
  412. // Returns: Error code
  413. //
  414. HRESULT CPspRasTool::HrInitToolPageType(INetConnection* pncInit)
  415. {
  416. HRESULT hr = S_OK;
  417. TraceError("CPspRasTool::HrInitToolPageType", hr);
  418. return hr;
  419. }
  420. //+---------------------------------------------------------------------------
  421. //
  422. // Member: CPspRasTool::HrAddCommandLineFlags
  423. //
  424. // Purpose: Adds the flags for this selection to the command line for the
  425. // tool being launched.
  426. //
  427. // Arguments: pstrFlags - The command line that the flags have to be
  428. // appended to
  429. // psmteSel - The tool entry associated with this selection
  430. //
  431. // Returns: Error code
  432. //
  433. HRESULT CPspRasTool::HrAddCommandLineFlags(tstring* pstrFlags,
  434. CStatMonToolEntry* psmteSel)
  435. {
  436. HRESULT hr = S_OK;
  437. //
  438. // Check what flags are asked for and provide them if we can
  439. //
  440. TraceError("CPspRasTool::HrAddCommandLineFlags", hr);
  441. return hr;
  442. }
  443. HRESULT CPspRasTool::HrGetDeviceType(INetConnection* pncInit)
  444. {
  445. HRESULT hr = S_OK;
  446. RASCONN* aRasConn;
  447. DWORD cRasConn;
  448. hr = HrRasEnumAllActiveConnections (
  449. &aRasConn,
  450. &cRasConn);
  451. if (SUCCEEDED(hr))
  452. {
  453. for (DWORD i = 0; i < cRasConn; i++)
  454. {
  455. if (m_guidId == aRasConn[i].guidEntry)
  456. {
  457. // Note: device types in RAS connections are defined
  458. // as follows in public\sdk\inc ras.h as RASDT_XXX
  459. m_strDeviceType = aRasConn[i].szDeviceType;
  460. break;
  461. }
  462. }
  463. MemFree (aRasConn);
  464. }
  465. return S_OK;
  466. }
  467. HRESULT CPspRasTool::HrGetComponentList(INetConnection* pncInit)
  468. {
  469. // Obtain ras handle to this connection
  470. HRESULT hr = S_OK;
  471. HRASCONN hRasConn = NULL;
  472. if (m_dwCharacter & NCCF_OUTGOING_ONLY)
  473. {
  474. // for outgoing connection
  475. INetRasConnection* pnrcNew = NULL;
  476. hr = HrQIAndSetProxyBlanket(pncInit, &pnrcNew);
  477. if (SUCCEEDED(hr))
  478. {
  479. hr = pnrcNew->GetRasConnectionHandle(
  480. reinterpret_cast<ULONG_PTR*>(&hRasConn));
  481. ReleaseObj(pnrcNew);
  482. }
  483. }
  484. else if (m_dwCharacter & NCCF_INCOMING_ONLY)
  485. {
  486. // for incoming connection
  487. INetInboundConnection* pnicNew;
  488. hr = HrQIAndSetProxyBlanket(pncInit, &pnicNew);
  489. if (SUCCEEDED(hr))
  490. {
  491. hr = pnicNew->GetServerConnectionHandle(
  492. reinterpret_cast<ULONG_PTR*>(&hRasConn));
  493. ReleaseObj(pnicNew);
  494. }
  495. }
  496. if (SUCCEEDED(hr) && hRasConn)
  497. {
  498. // Get protocols list
  499. DWORD dwRetCode;
  500. DWORD dwSize;
  501. // RASP_PppIp
  502. RASPPPIP RasPppIp;
  503. RasPppIp.dwSize = sizeof( RasPppIp );
  504. dwSize = sizeof( RasPppIp );
  505. dwRetCode = RasGetProjectionInfo (hRasConn, RASP_PppIp, &RasPppIp, &dwSize);
  506. if ((dwRetCode == NO_ERROR) && (NO_ERROR == RasPppIp.dwError))
  507. {
  508. m_lstpstrCompIds.push_back(new tstring(L"MS_TCPIP"));
  509. }
  510. // RASP_PppIpx
  511. RASPPPIPX RasPppIpx;
  512. RasPppIpx.dwSize = sizeof( RasPppIpx );
  513. dwSize = sizeof( RasPppIpx );
  514. dwRetCode = RasGetProjectionInfo (hRasConn, RASP_PppIpx, &RasPppIpx, &dwSize);
  515. if ((dwRetCode == NO_ERROR) && (NO_ERROR == RasPppIpx.dwError))
  516. {
  517. m_lstpstrCompIds.push_back(new tstring(L"MS_NWIPX"));
  518. }
  519. // RASP_PppNbf
  520. RASPPPNBF RasPppNbf;
  521. RasPppNbf.dwSize = sizeof( RasPppNbf );
  522. dwSize = sizeof( RasPppNbf );
  523. dwRetCode = RasGetProjectionInfo (hRasConn, RASP_PppNbf, &RasPppNbf, &dwSize);
  524. if ((dwRetCode == NO_ERROR) && (NO_ERROR == RasPppNbf.dwError))
  525. {
  526. m_lstpstrCompIds.push_back(new tstring(L"MS_NetBEUI"));
  527. }
  528. // RASP_Slip
  529. RASSLIP RasSlip;
  530. RasSlip.dwSize = sizeof( RasSlip );
  531. dwSize = sizeof( RasSlip );
  532. dwRetCode = RasGetProjectionInfo (hRasConn, RASP_Slip, &RasSlip, &dwSize);
  533. if ((dwRetCode == NO_ERROR) && (NO_ERROR == RasSlip.dwError))
  534. {
  535. m_lstpstrCompIds.push_back(new tstring(L"MS_TCPIP"));
  536. }
  537. }
  538. // Get client and services
  539. // $REVIEW(tongl 10/19): checked with Rao, for now we hard code
  540. // using MSClient and F&P services for all RAS connections
  541. // (raid #132575)
  542. m_lstpstrCompIds.push_back(new tstring(L"MS_MSCLIENT"));
  543. m_lstpstrCompIds.push_back(new tstring(L"MS_SERVER"));
  544. return S_OK;
  545. }