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.

808 lines
22 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: ConnStat.cpp
  4. //
  5. // Module: CMMON32.EXE
  6. //
  7. // Synopsis: Implementation of class CConnStatistics
  8. //
  9. // Copyright (c) 1998-1999 Microsoft Corporation
  10. //
  11. // Author: Fengsun Created 10/15/97
  12. //
  13. //+----------------------------------------------------------------------------
  14. #include "cmmaster.h"
  15. #include "ConnStat.h"
  16. #include "cm_misc.h" // for MYDBGASSERT
  17. #include "DynamicLib.h"
  18. #include "resource.h"
  19. #include "perf_str.h"
  20. //
  21. // DeviceIoControl code
  22. //
  23. #define UNIMODEM_IOCTL_GET_STATISTICS 0x0000a007
  24. //
  25. // Constructor and destructor
  26. //
  27. CConnStatistics::CConnStatistics()
  28. {
  29. m_TrafficRing.Reset();
  30. m_dwReadPerSecond = m_dwWritePerSecond = m_dwBaudRate = m_dwDuration = 0;
  31. m_dwInitBytesRead = m_dwInitBytesWrite = (DWORD)-1;
  32. m_hStatDevice = NULL;
  33. m_hKey = NULL;
  34. m_fAdapter2 = FALSE;
  35. m_fAdapterSet = FALSE;
  36. m_pszTotalBytesRecvd = m_pszTotalBytesXmit = m_pszConnectSpeed = NULL;
  37. }
  38. CConnStatistics::~CConnStatistics()
  39. {
  40. Close();
  41. }
  42. //+----------------------------------------------------------------------------
  43. //
  44. // Function: CConnStatistics::OpenByDevice
  45. //
  46. // Synopsis:
  47. //
  48. // Arguments: HRASCONN hrcRasConn - the ras connection handle, needed for
  49. // non-tunnle connection, when registry is not available
  50. //
  51. // Returns: BOOL - Whether open succeeded.
  52. // Because the TAPI device handle maybe available later from cmstat dll
  53. // Use IsAvailable() to see whether statistics is available
  54. //
  55. // History: fengsun Created Header 10/29/97
  56. //
  57. //+----------------------------------------------------------------------------
  58. BOOL CConnStatistics::OpenByDevice(HRASCONN hrcRasConn)
  59. {
  60. MYDBGASSERT(OS_W95);
  61. MYDBGASSERT(!IsAvailable());
  62. MYDBGASSERT(hrcRasConn);
  63. if (GetDeviceHandle(hrcRasConn))
  64. {
  65. return TRUE;
  66. }
  67. //
  68. // NOTE: For win95 gold, GetDeviceHandle will fail if TAPI 2.1 is installed.
  69. // We used to have a hack there to hook the lights.exe. We decided to take
  70. // it out and to let the setup program ask user to upgrade TAPI or DUN. We
  71. // dropped HookLight(), because it does not work for multiple connections.
  72. //
  73. MYDBGASSERT(FALSE);
  74. return FALSE;
  75. }
  76. //+---------------------------------------------------------------------------
  77. //
  78. // Function: Open()
  79. //
  80. // Synopsis: Encapsulates the opening of the statistics data store
  81. //
  82. // Arguments: HINSTANCE hInst - The instance to LoadString "Dial-up Adapter"
  83. // DWORD dwInitBytesRecv - Initial value of TotalBytesRecvd
  84. // DWORD dwInitBytesSend - Initial value of TotalBytesXmit
  85. // HRASCONN hDial - Handle to dial-up connection, if any
  86. // HRASCONN hTunnel - Handle to tunnel connection, if any
  87. //
  88. // Returns: TRUE if succeed
  89. // FALSE otherwise
  90. //
  91. // History: nickball 03/04/00 Created. Wrapped existing code.
  92. //
  93. // Note: This function initialize the connection statistics from one
  94. // of three places.
  95. //
  96. // 1) W98 registry
  97. // 2) NT5 RAS API
  98. // 3) W95 Tapi device handle.
  99. //
  100. //----------------------------------------------------------------------------
  101. void CConnStatistics::Open(HINSTANCE hInst,
  102. DWORD dwInitBytesRecv,
  103. DWORD dwInitBytesSend,
  104. HRASCONN hDial,
  105. HRASCONN hTunnel)
  106. {
  107. //
  108. // Start statistics
  109. //
  110. if (OS_NT5)
  111. {
  112. OpenByStatisticsApi(dwInitBytesRecv, dwInitBytesSend, hDial, hTunnel);
  113. }
  114. else
  115. {
  116. OpenByPerformanceKey(hInst,
  117. dwInitBytesRecv,
  118. dwInitBytesSend);
  119. }
  120. //
  121. // See if we have stats, go with plan B if not.
  122. //
  123. if (!IsAvailable())
  124. {
  125. //
  126. // On W95, we have a fallback position of hooking the TAPI handle
  127. // via RAS, so use it. Note: We will retry initializing stats on every
  128. // timer tick if we don't get them here, so all is not lost for W98.
  129. // Note that we only check hDial here because if you are on win95 without
  130. // MSDUN 1.2, you aren't able to tunnel.
  131. //
  132. if (OS_W95 && hDial)
  133. {
  134. OpenByDevice(hDial);
  135. }
  136. }
  137. }
  138. //+---------------------------------------------------------------------------
  139. //
  140. // Function: OpenByStatisticsApi()
  141. //
  142. // Synopsis: Sets initial values and makes sure the RasApis are loaded.
  143. //
  144. // Arguments: DWORD dwInitBytesRecv - Initial value of TotalBytesRecvd
  145. // DWORD dwInitBytesSend - Initial value of TotalBytesXmit
  146. // HRASCONN hDial - Handle to dial-up connection, if any
  147. // HRASCONN hTunnel - Handle to tunnel connection, if any
  148. //
  149. // Returns: Nothing
  150. //
  151. // History: nickball 03/04/00 Created from OpenByPerformanceKey
  152. //
  153. //----------------------------------------------------------------------------
  154. void CConnStatistics::OpenByStatisticsApi(DWORD dwInitBytesRecv,
  155. DWORD dwInitBytesSend,
  156. HRASCONN hDial,
  157. HRASCONN hTunnel)
  158. {
  159. //
  160. // Initialize our APIs
  161. //
  162. m_RasApiDll.Load();
  163. //
  164. // Get the handle that we'll use to look up stats.
  165. // Try tunnel first, then drop back to dial-up
  166. //
  167. CMTRACE2(TEXT("CConnStatistics::OpenByStatisticsApi() hTunnel is 0x%x and hDial is 0x%x"), hTunnel, hDial);
  168. m_hRasConn = hTunnel ? hTunnel : hDial;
  169. //
  170. // Init the bytes sent and received with whatever was pushed down to us.
  171. //
  172. m_dwInitBytesRead = dwInitBytesRecv;
  173. m_dwInitBytesWrite = dwInitBytesSend;
  174. }
  175. //+---------------------------------------------------------------------------
  176. //
  177. // Function: OpenByPerformanceKey()
  178. //
  179. // Synopsis: Open the registry key for Dial-Up Adapter Performance Data
  180. //
  181. // Arguments: HINSTANCE hInst - The instance to LoadString "Dial-up Adapter"
  182. // DWORD dwInitBytesRecv - Initial value of TotalBytesRecvd
  183. // DWORD dwInitBytesSend - Initial value of TotalBytesXmit
  184. //
  185. // Returns: TRUE if succeed
  186. // FALSE otherwise
  187. //
  188. // History: byao 07/16/97 Created
  189. // fengsun 10/01/97 Make it a member fuction
  190. // nickball 11/14/98 If key exists, use it
  191. //
  192. // Note: This function initialize the connection statistics from the
  193. // registry. It is used when the initial bytes sent/recvd are
  194. // known as is the case when CMDIAL hands off to CMMON.
  195. //
  196. //----------------------------------------------------------------------------
  197. void CConnStatistics::OpenByPerformanceKey(HINSTANCE hInst,
  198. DWORD dwInitBytesRecv,
  199. DWORD dwInitBytesSend)
  200. {
  201. //
  202. // If available, there's nothing to do here
  203. //
  204. if (IsAvailable() || !m_fAdapterSet)
  205. {
  206. MYDBGASSERT(FALSE);
  207. return;
  208. }
  209. //
  210. // We haven't opened the key yet, try to do so
  211. //
  212. MYDBGASSERT(!m_hKey);
  213. if (m_hKey)
  214. {
  215. RegCloseKey(m_hKey);
  216. m_hKey = NULL;
  217. }
  218. DWORD dwErrCode = RegOpenKeyExU( HKEY_DYN_DATA,
  219. c_pszDialupPerfKey,
  220. 0,
  221. KEY_ALL_ACCESS,
  222. &m_hKey );
  223. if (dwErrCode != ERROR_SUCCESS)
  224. {
  225. CMTRACE1(TEXT("OpenDAPPerfKey() RegOpenKeyEx() returned GLE=%u."), dwErrCode);
  226. m_hKey = NULL;
  227. return;
  228. }
  229. m_dwInitBytesRead = dwInitBytesRecv;
  230. m_dwInitBytesWrite = dwInitBytesSend;
  231. GetStatRegValues(hInst);
  232. //
  233. // If intial values are -1, reget the initial values.
  234. //
  235. if (((DWORD)-1 == dwInitBytesRecv) || ((DWORD)-1 == dwInitBytesSend))
  236. {
  237. //
  238. // Get the initial statistics info
  239. //
  240. if (!GetPerfData(m_dwInitBytesRead, m_dwInitBytesWrite, m_dwBaudRate))
  241. {
  242. //
  243. // No dial-up statistic info
  244. //
  245. RegCloseKey(m_hKey);
  246. m_hKey = NULL;
  247. CMTRACE(TEXT("CConnStatistics::OpenByPerformanceKey() - failed to find stats"));
  248. }
  249. }
  250. }
  251. //+----------------------------------------------------------------------------
  252. //
  253. // Function: CConnStatistics::GetStatRegValues
  254. //
  255. // Synopsis: Helper method, builds the reg value names using the localized
  256. // form of the word "Dial-up Adapter".
  257. //
  258. // Arguments: HINSTANCE hInst
  259. //
  260. // Returns: Nothing
  261. //
  262. // History: nickball Created 11/14/98
  263. //
  264. //+----------------------------------------------------------------------------
  265. void CConnStatistics::GetStatRegValues(HINSTANCE hInst)
  266. {
  267. CMTRACE1(TEXT("CConnStatistics::GetStatRegValues - m_pszTotalBytesRecvd is %s"), m_pszTotalBytesRecvd);
  268. //
  269. // bug 149367 The word "Dial-up Adapter" need to be localized.
  270. // Load it from resource if no loaded yet
  271. //
  272. if (m_pszTotalBytesRecvd == NULL)
  273. {
  274. m_pszTotalBytesRecvd = CmLoadString(hInst, IDS_REG_DIALUP_ADAPTER);
  275. CmStrCatAlloc(&m_pszTotalBytesRecvd, m_fAdapter2 ? c_pszDialup_2_TotalBytesRcvd : c_pszDialupTotalBytesRcvd);
  276. m_pszTotalBytesXmit = CmLoadString(hInst, IDS_REG_DIALUP_ADAPTER);
  277. CmStrCatAlloc(&m_pszTotalBytesXmit, m_fAdapter2 ? c_pszDialup_2_TotalBytesXmit : c_pszDialupTotalBytesXmit);
  278. m_pszConnectSpeed = CmLoadString(hInst, IDS_REG_DIALUP_ADAPTER);
  279. CmStrCatAlloc(&m_pszConnectSpeed, m_fAdapter2 ? c_pszDialup_2_ConnectSpeed : c_pszDialupConnectSpeed);
  280. }
  281. }
  282. //+----------------------------------------------------------------------------
  283. //
  284. // Function: CConnStatistics::Close
  285. //
  286. // Synopsis: Stop gathering statistic and close the handle
  287. //
  288. // Arguments:
  289. //
  290. // Returns:
  291. //
  292. // History: Created Header 10/15/97
  293. //
  294. //+----------------------------------------------------------------------------
  295. void CConnStatistics::Close()
  296. {
  297. if (m_hStatDevice)
  298. {
  299. BOOL bRes = CloseHandle(m_hStatDevice);
  300. m_hStatDevice = NULL;
  301. #ifdef DEBUG
  302. if (!bRes)
  303. {
  304. CMTRACE1(TEXT("CConnStatistics::Close() CloseHandle() failed, GLE=%u."), GetLastError());
  305. }
  306. #endif
  307. }
  308. if (m_hKey)
  309. {
  310. DWORD dwErrCode = RegCloseKey(m_hKey);
  311. CMTRACE1(TEXT("Close() RegCloseKey() returned GLE=%u."), dwErrCode);
  312. m_hKey = NULL;
  313. }
  314. CmFree( m_pszTotalBytesRecvd );
  315. CmFree( m_pszTotalBytesXmit );
  316. CmFree( m_pszConnectSpeed );
  317. m_pszTotalBytesRecvd = m_pszTotalBytesXmit = m_pszConnectSpeed = NULL;
  318. }
  319. //+----------------------------------------------------------------------------
  320. //
  321. // Function: CConnStatistics::Update
  322. //
  323. // Synopsis: Gather new statistic information
  324. //
  325. // Arguments: None
  326. //
  327. // Returns: Nothing
  328. //
  329. // History: Fengsun Created 10/15/97
  330. //
  331. //+----------------------------------------------------------------------------
  332. void CConnStatistics::Update()
  333. {
  334. if (!IsAvailable())
  335. {
  336. MYDBGASSERT(FALSE);
  337. return;
  338. }
  339. CTraffic curTraffic;
  340. curTraffic.dwTime = GetTickCount();
  341. MYDBGASSERT(curTraffic.dwTime > m_TrafficRing.GetOldest().dwTime);
  342. if (curTraffic.dwTime == m_TrafficRing.GetOldest().dwTime)
  343. {
  344. return;
  345. }
  346. //
  347. // Prefer performace registry data
  348. //
  349. if (OS_NT5)
  350. {
  351. RAS_STATS RasStats;
  352. ZeroMemory(&RasStats, sizeof(RasStats));
  353. RasStats.dwSize = sizeof(RAS_STATS);
  354. DWORD dwRet = m_RasApiDll.RasGetConnectionStatistics(m_hRasConn, &RasStats);
  355. if (ERROR_SUCCESS == dwRet)
  356. {
  357. curTraffic.dwRead = RasStats.dwBytesRcved;
  358. curTraffic.dwWrite = RasStats.dwBytesXmited;
  359. m_dwBaudRate = RasStats.dwBps;
  360. m_dwDuration = RasStats.dwConnectDuration;
  361. }
  362. }
  363. else
  364. {
  365. //
  366. // Not NT5, try the registry
  367. //
  368. if (m_hKey)
  369. {
  370. if (!GetPerfData(curTraffic.dwRead, curTraffic.dwWrite, m_dwBaudRate))
  371. {
  372. return;
  373. }
  374. curTraffic.dwRead -= m_dwInitBytesRead;
  375. curTraffic.dwWrite -= m_dwInitBytesWrite;
  376. }
  377. else
  378. {
  379. //
  380. // Last resort for 9x, try to use stat device
  381. //
  382. if (m_hStatDevice)
  383. {
  384. if (!GetTapiDeviceStats(curTraffic.dwRead, curTraffic.dwWrite, m_dwBaudRate))
  385. {
  386. BOOL bRes = CloseHandle(m_hStatDevice);
  387. m_hStatDevice = NULL;
  388. if (!bRes)
  389. {
  390. CMTRACE1(TEXT("CConnStatistics::Update() CloseHandle() failed, GLE=%u."), GetLastError());
  391. }
  392. return;
  393. }
  394. }
  395. else
  396. {
  397. MYDBGASSERT(m_hStatDevice);
  398. return;
  399. }
  400. }
  401. }
  402. //
  403. // Calculate the avarage between two interval
  404. //
  405. const CTraffic& lastTraffic = m_TrafficRing.GetOldest();
  406. DWORD dwDeltaTime = curTraffic.dwTime - lastTraffic.dwTime;
  407. m_dwReadPerSecond = ((curTraffic.dwRead - lastTraffic.dwRead)*1000) /dwDeltaTime;
  408. m_dwWritePerSecond = ((curTraffic.dwWrite - lastTraffic.dwWrite)*1000) /dwDeltaTime;
  409. m_TrafficRing.Add(curTraffic);
  410. }
  411. //+---------------------------------------------------------------------------
  412. //
  413. // Function: GetPerfData
  414. //
  415. // Synopsis: Get Performance Data from DUN1.2 performance registry
  416. //
  417. // Arguments:
  418. //
  419. // Returns: TRUE: succeed
  420. // FALSE otherwise
  421. //
  422. // History: byao created 7/16/97
  423. // fengsun change it into a member function 10/14/97
  424. //
  425. //----------------------------------------------------------------------------
  426. BOOL CConnStatistics::GetPerfData(DWORD& dwRead, DWORD& dwWrite, DWORD& dwBaudRate) const
  427. {
  428. if (OS_W9X)
  429. {
  430. MYDBGASSERT(m_hKey != NULL);
  431. MYDBGASSERT(m_pszTotalBytesRecvd && *m_pszTotalBytesRecvd);
  432. LONG dwErrCode;
  433. DWORD dwValueSize, dwValueType;
  434. DWORD dwValue;
  435. //
  436. // "Dial-up Adapter\TotalBytesRecvd"
  437. //
  438. dwValueSize = sizeof(DWORD);
  439. dwErrCode = RegQueryValueExU(
  440. m_hKey,
  441. m_pszTotalBytesRecvd,
  442. NULL,
  443. &dwValueType,
  444. (PBYTE)&dwValue,
  445. &dwValueSize);
  446. if (dwErrCode == ERROR_SUCCESS)
  447. {
  448. dwRead = dwValue;
  449. }
  450. else
  451. {
  452. CMTRACE2(TEXT("GetPerfData() RegQueryValueEx() %s failed and returned GLE=%u."),
  453. m_pszTotalBytesRecvd, dwErrCode);
  454. return FALSE;
  455. }
  456. //
  457. // "Dial-up Adapter\TotalBytesXmit"
  458. //
  459. dwValueSize = sizeof(DWORD);
  460. dwErrCode = RegQueryValueExU(
  461. m_hKey,
  462. m_pszTotalBytesXmit,
  463. NULL,
  464. &dwValueType,
  465. (PBYTE)&dwValue,
  466. &dwValueSize);
  467. if (dwErrCode == ERROR_SUCCESS)
  468. {
  469. dwWrite = dwValue;
  470. }
  471. else
  472. {
  473. CMTRACE2(TEXT("GetPerfData() RegQueryValueEx() %s failed and returned GLE=%u."),
  474. m_pszTotalBytesXmit, dwErrCode);
  475. return FALSE;
  476. }
  477. //
  478. // "Dial-up Adapter\ConnectSpeed"
  479. //
  480. dwValueSize = sizeof(DWORD);
  481. dwErrCode = RegQueryValueExU(
  482. m_hKey,
  483. m_pszConnectSpeed,
  484. NULL,
  485. &dwValueType,
  486. (PBYTE)&dwValue,
  487. &dwValueSize);
  488. if (dwErrCode == ERROR_SUCCESS)
  489. {
  490. dwBaudRate = dwValue;
  491. }
  492. else
  493. {
  494. CMTRACE2(TEXT("GetPerfData() RegQueryValueEx() %s failed and returned GLE=%u."), m_pszConnectSpeed, dwErrCode);
  495. return FALSE;
  496. }
  497. }
  498. return TRUE;
  499. }
  500. //+---------------------------------------------------------------------------
  501. //
  502. // Function: GetTapiDeviceStats
  503. //
  504. // Synopsis: Get Modem Performance Data by DeviceIoControl
  505. //
  506. // Arguments:
  507. //
  508. // Returns: TRUE: succeed
  509. // FALSE otherwise
  510. //
  511. // History: byao created 7/16/97
  512. // fengsun change it into a member function 10/14/97
  513. //
  514. //----------------------------------------------------------------------------
  515. BOOL CConnStatistics::GetTapiDeviceStats(DWORD& dwRead, DWORD& dwWrite, DWORD& dwBaudRate) const
  516. {
  517. BOOL bRes;
  518. DWORD dwRet;
  519. typedef struct tagAPISTATS {
  520. LPVOID hPort;
  521. DWORD fConnected;
  522. DWORD DCERate;
  523. DWORD dwPerfRead;
  524. DWORD dwPerfWrite;
  525. } APISTATS;
  526. APISTATS ApiStats;
  527. if (m_hStatDevice)
  528. {
  529. bRes = DeviceIoControl(m_hStatDevice,
  530. UNIMODEM_IOCTL_GET_STATISTICS,
  531. &ApiStats,
  532. sizeof(ApiStats),
  533. &ApiStats,
  534. sizeof(ApiStats),
  535. &dwRet,
  536. NULL);
  537. if (bRes && ApiStats.fConnected)
  538. {
  539. dwRead = ApiStats.dwPerfRead;
  540. dwWrite = ApiStats.dwPerfWrite;
  541. dwBaudRate = ApiStats.DCERate;
  542. return (TRUE);
  543. }
  544. CMTRACE(TEXT("GetTapiDeviceStats() DeviceIoControl() failed - disabling hStatDevice."));
  545. }
  546. return (FALSE);
  547. }
  548. //+----------------------------------------------------------------------------
  549. //
  550. // Function: CConnStatistics::GetDeviceHandle
  551. //
  552. // Synopsis: Get the TAPI device handle
  553. //
  554. // Arguments: HRASCONN hrcRasConn - the ras connection handle
  555. //
  556. // Returns: BOOL - TRUE if succeed
  557. //
  558. // History: fengsun Created Header 10/29/97
  559. //
  560. //+----------------------------------------------------------------------------
  561. BOOL CConnStatistics::GetDeviceHandle(HRASCONN hrcRasConn)
  562. {
  563. MYDBGASSERT(hrcRasConn);
  564. MYDBGASSERT(!m_hStatDevice);
  565. typedef struct tagDEVICE_PORT_INFO
  566. {
  567. DWORD dwSize;
  568. HANDLE hDevicePort;
  569. HLINE hLine;
  570. HCALL hCall;
  571. DWORD dwAddressID;
  572. DWORD dwLinkSpeed;
  573. char szDeviceClass[RAS_MaxDeviceType+1];
  574. } DEVICE_PORT_INFO, *LPDEVICE_PORT_INFO;
  575. typedef struct tagMacInfo
  576. {
  577. VARSTRING varstring;
  578. HANDLE hCommDevice;
  579. char szDeviceClass[1];
  580. } MacInfo;
  581. typedef DWORD (WINAPI *RnaGetDevicePortFUNC)(HANDLE,LPDEVICE_PORT_INFO);
  582. RnaGetDevicePortFUNC pfnRnaGetDevicePort;
  583. //
  584. // Load rasapi32.dll and call RnaGetDevicePort
  585. //
  586. //
  587. // The destructor of CDynamicLibrary automaticly call FreeLibrary
  588. //
  589. CDynamicLibrary RasLib;
  590. if (!RasLib.Load(TEXT("rasapi32.dll")))
  591. {
  592. CMTRACE1(TEXT("GetDeviceHandle() LoadLibrary() failed, GLE=%u."), GetLastError());
  593. return FALSE;
  594. }
  595. pfnRnaGetDevicePort = (RnaGetDevicePortFUNC) RasLib.GetProcAddress("RnaGetDevicePort");
  596. if (!pfnRnaGetDevicePort)
  597. {
  598. CMTRACE1(TEXT("GetDeviceHandle() GetProcAddress() failed, GLE=%u."), GetLastError());
  599. return FALSE;
  600. }
  601. DWORD dwRes;
  602. DEVICE_PORT_INFO dpi;
  603. ZeroMemory(&dpi,sizeof(dpi));
  604. dpi.dwSize = sizeof(dpi);
  605. dwRes = pfnRnaGetDevicePort(hrcRasConn,&dpi);
  606. if (dwRes)
  607. {
  608. CMTRACE1(TEXT("GetDeviceHandle() RnaGetDevicePort() failed, GLE=%u."), dwRes);
  609. return FALSE;
  610. }
  611. //
  612. // Load TAPI32.dll
  613. // CDynamicLibrary Free the lib on destructor
  614. //
  615. CDynamicLibrary LibTapi;
  616. if (!LibTapi.Load(TEXT("TAPI32.DLL")))
  617. {
  618. return FALSE;
  619. }
  620. typedef LONG (WINAPI *TapiLineGetIDFUNC)
  621. (HLINE, DWORD, HCALL, DWORD, LPVARSTRING, LPCSTR);
  622. //
  623. // Always call the Ansi version since this is a Win9x only function
  624. //
  625. TapiLineGetIDFUNC pfnTapiLineGetID;
  626. pfnTapiLineGetID = (TapiLineGetIDFUNC) LibTapi.GetProcAddress("lineGetID");
  627. if (pfnTapiLineGetID == NULL)
  628. {
  629. MYDBGASSERT(pfnTapiLineGetID != NULL);
  630. return FALSE;
  631. }
  632. LONG lRes;
  633. CMTRACE3(TEXT("GetDeviceHandle() hDevicePort=0x%x, hLine=0x%x, hCall=0x%x,"), dpi.hDevicePort, dpi.hLine, dpi.hCall);
  634. CMTRACE3(TEXT("\tdwAddressID=0x%x, dwLinkSpeed=%u, szDeviceClass=%s."), dpi.dwAddressID, dpi.dwLinkSpeed, dpi.szDeviceClass);
  635. m_dwBaudRate = dpi.dwLinkSpeed;
  636. MacInfo* pmi = NULL;
  637. DWORD dwSize = sizeof(*pmi);
  638. do
  639. {
  640. CmFree(pmi);
  641. pmi = (MacInfo *) CmMalloc(dwSize);
  642. if (pmi == NULL)
  643. {
  644. lRes = ERROR_OUTOFMEMORY;
  645. break;
  646. }
  647. pmi->varstring.dwTotalSize = dwSize;
  648. lRes = pfnTapiLineGetID(dpi.hLine,
  649. dpi.dwAddressID,
  650. NULL,
  651. LINECALLSELECT_ADDRESS,
  652. &pmi->varstring,
  653. "comm/datamodem");
  654. dwSize = pmi->varstring.dwNeededSize;
  655. } while(pmi->varstring.dwNeededSize > pmi->varstring.dwTotalSize);
  656. #ifdef DEBUG
  657. if (lRes)
  658. {
  659. CMTRACE1(TEXT("CConnStatistics::GetDeviceHandle() lineGetID() failed, GLE=%u."), lRes);
  660. }
  661. #endif
  662. if (!lRes && pmi != NULL )
  663. {
  664. m_hStatDevice = pmi->hCommDevice;
  665. }
  666. CmFree(pmi);
  667. return m_hStatDevice != NULL;
  668. }
  669. #ifdef DEBUG
  670. //+----------------------------------------------------------------------------
  671. //
  672. // Function: CConnStatistics::AssertValid
  673. //
  674. // Synopsis: For debug purpose only, assert the object is valid
  675. //
  676. // Arguments: None
  677. //
  678. // Returns: Nothing
  679. //
  680. // History: Created Header 2/12/98
  681. //
  682. //+----------------------------------------------------------------------------
  683. void CConnStatistics::AssertValid() const
  684. {
  685. MYDBGASSERT(m_hKey == NULL || m_hStatDevice == NULL);
  686. MYDBGASSERT(m_fAdapter2 == TRUE || m_fAdapter2 == FALSE);
  687. ASSERT_VALID(&m_TrafficRing);
  688. }
  689. #endif