809 lines
21 KiB
C++
809 lines
21 KiB
C++
|
//+----------------------------------------------------------------------------
|
||
|
//
|
||
|
// File: ConnStat.cpp
|
||
|
//
|
||
|
// Module: CMMON32.EXE
|
||
|
//
|
||
|
// Synopsis: Implementation of class CConnStatistics
|
||
|
//
|
||
|
// Copyright (c) 1998-1999 Microsoft Corporation
|
||
|
//
|
||
|
// Author: Fengsun Created 10/15/97
|
||
|
//
|
||
|
//+----------------------------------------------------------------------------
|
||
|
|
||
|
#include "cmmaster.h"
|
||
|
#include "ConnStat.h"
|
||
|
#include "cm_misc.h" // for MYDBGASSERT
|
||
|
#include "DynamicLib.h"
|
||
|
#include "resource.h"
|
||
|
#include "perf_str.h"
|
||
|
|
||
|
//
|
||
|
// DeviceIoControl code
|
||
|
//
|
||
|
|
||
|
#define UNIMODEM_IOCTL_GET_STATISTICS 0x0000a007
|
||
|
|
||
|
//
|
||
|
// Constructor and destructor
|
||
|
//
|
||
|
|
||
|
CConnStatistics::CConnStatistics()
|
||
|
{
|
||
|
m_TrafficRing.Reset();
|
||
|
m_dwReadPerSecond = m_dwWritePerSecond = m_dwBaudRate = m_dwDuration = 0;
|
||
|
m_dwInitBytesRead = m_dwInitBytesWrite = (DWORD)-1;
|
||
|
m_hStatDevice = NULL;
|
||
|
m_hKey = NULL;
|
||
|
m_fAdapter2 = FALSE;
|
||
|
m_fAdapterSet = FALSE;
|
||
|
m_pszTotalBytesRecvd = m_pszTotalBytesXmit = m_pszConnectSpeed = NULL;
|
||
|
}
|
||
|
|
||
|
CConnStatistics::~CConnStatistics()
|
||
|
{
|
||
|
Close();
|
||
|
}
|
||
|
|
||
|
//+----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CConnStatistics::OpenByDevice
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: HRASCONN hrcRasConn - the ras connection handle, needed for
|
||
|
// non-tunnle connection, when registry is not available
|
||
|
//
|
||
|
// Returns: BOOL - Whether open succeeded.
|
||
|
// Because the TAPI device handle maybe available later from cmstat dll
|
||
|
// Use IsAvailable() to see whether statistics is available
|
||
|
//
|
||
|
// History: fengsun Created Header 10/29/97
|
||
|
//
|
||
|
//+----------------------------------------------------------------------------
|
||
|
BOOL CConnStatistics::OpenByDevice(HRASCONN hrcRasConn)
|
||
|
{
|
||
|
MYDBGASSERT(OS_W95);
|
||
|
MYDBGASSERT(!IsAvailable());
|
||
|
MYDBGASSERT(hrcRasConn);
|
||
|
|
||
|
if (GetDeviceHandle(hrcRasConn))
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// NOTE: For win95 gold, GetDeviceHandle will fail if TAPI 2.1 is installed.
|
||
|
// We used to have a hack there to hook the lights.exe. We decided to take
|
||
|
// it out and to let the setup program ask user to upgrade TAPI or DUN. We
|
||
|
// dropped HookLight(), because it does not work for multiple connections.
|
||
|
//
|
||
|
|
||
|
MYDBGASSERT(FALSE);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: Open()
|
||
|
//
|
||
|
// Synopsis: Encapsulates the opening of the statistics data store
|
||
|
//
|
||
|
// Arguments: HINSTANCE hInst - The instance to LoadString "Dial-up Adapter"
|
||
|
// DWORD dwInitBytesRecv - Initial value of TotalBytesRecvd
|
||
|
// DWORD dwInitBytesSend - Initial value of TotalBytesXmit
|
||
|
// HRASCONN hDial - Handle to dial-up connection, if any
|
||
|
// HRASCONN hTunnel - Handle to tunnel connection, if any
|
||
|
//
|
||
|
// Returns: TRUE if succeed
|
||
|
// FALSE otherwise
|
||
|
//
|
||
|
// History: nickball 03/04/00 Created. Wrapped existing code.
|
||
|
//
|
||
|
// Note: This function initialize the connection statistics from one
|
||
|
// of three places.
|
||
|
//
|
||
|
// 1) W98 registry
|
||
|
// 2) NT5 RAS API
|
||
|
// 3) W95 Tapi device handle.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
void CConnStatistics::Open(HINSTANCE hInst,
|
||
|
DWORD dwInitBytesRecv,
|
||
|
DWORD dwInitBytesSend,
|
||
|
HRASCONN hDial,
|
||
|
HRASCONN hTunnel)
|
||
|
{
|
||
|
//
|
||
|
// Start statistics
|
||
|
//
|
||
|
|
||
|
if (OS_NT5)
|
||
|
{
|
||
|
OpenByStatisticsApi(dwInitBytesRecv, dwInitBytesSend, hDial, hTunnel);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
OpenByPerformanceKey(hInst,
|
||
|
dwInitBytesRecv,
|
||
|
dwInitBytesSend);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// See if we have stats, go with plan B if not.
|
||
|
//
|
||
|
|
||
|
if (!IsAvailable())
|
||
|
{
|
||
|
//
|
||
|
// On W95, we have a fallback position of hooking the TAPI handle
|
||
|
// via RAS, so use it. Note: We will retry initializing stats on every
|
||
|
// timer tick if we don't get them here, so all is not lost for W98.
|
||
|
// Note that we only check hDial here because if you are on win95 without
|
||
|
// MSDUN 1.2, you aren't able to tunnel.
|
||
|
//
|
||
|
|
||
|
if (OS_W95 && hDial)
|
||
|
{
|
||
|
OpenByDevice(hDial);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: OpenByStatisticsApi()
|
||
|
//
|
||
|
// Synopsis: Sets initial values and makes sure the RasApis are loaded.
|
||
|
//
|
||
|
// Arguments: DWORD dwInitBytesRecv - Initial value of TotalBytesRecvd
|
||
|
// DWORD dwInitBytesSend - Initial value of TotalBytesXmit
|
||
|
// HRASCONN hDial - Handle to dial-up connection, if any
|
||
|
// HRASCONN hTunnel - Handle to tunnel connection, if any
|
||
|
//
|
||
|
// Returns: Nothing
|
||
|
//
|
||
|
// History: nickball 03/04/00 Created from OpenByPerformanceKey
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
void CConnStatistics::OpenByStatisticsApi(DWORD dwInitBytesRecv,
|
||
|
DWORD dwInitBytesSend,
|
||
|
HRASCONN hDial,
|
||
|
HRASCONN hTunnel)
|
||
|
{
|
||
|
//
|
||
|
// Initialize our APIs
|
||
|
//
|
||
|
|
||
|
m_RasApiDll.Load();
|
||
|
|
||
|
//
|
||
|
// Get the handle that we'll use to look up stats.
|
||
|
// Try tunnel first, then drop back to dial-up
|
||
|
//
|
||
|
|
||
|
CMTRACE2(TEXT("CConnStatistics::OpenByStatisticsApi() hTunnel is 0x%x and hDial is 0x%x"), hTunnel, hDial);
|
||
|
|
||
|
m_hRasConn = hTunnel ? hTunnel : hDial;
|
||
|
|
||
|
//
|
||
|
// Init the bytes sent and received with whatever was pushed down to us.
|
||
|
//
|
||
|
|
||
|
m_dwInitBytesRead = dwInitBytesRecv;
|
||
|
m_dwInitBytesWrite = dwInitBytesSend;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: OpenByPerformanceKey()
|
||
|
//
|
||
|
// Synopsis: Open the registry key for Dial-Up Adapter Performance Data
|
||
|
//
|
||
|
// Arguments: HINSTANCE hInst - The instance to LoadString "Dial-up Adapter"
|
||
|
// DWORD dwInitBytesRecv - Initial value of TotalBytesRecvd
|
||
|
// DWORD dwInitBytesSend - Initial value of TotalBytesXmit
|
||
|
//
|
||
|
// Returns: TRUE if succeed
|
||
|
// FALSE otherwise
|
||
|
//
|
||
|
// History: byao 07/16/97 Created
|
||
|
// fengsun 10/01/97 Make it a member fuction
|
||
|
// nickball 11/14/98 If key exists, use it
|
||
|
//
|
||
|
// Note: This function initialize the connection statistics from the
|
||
|
// registry. It is used when the initial bytes sent/recvd are
|
||
|
// known as is the case when CMDIAL hands off to CMMON.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
void CConnStatistics::OpenByPerformanceKey(HINSTANCE hInst,
|
||
|
DWORD dwInitBytesRecv,
|
||
|
DWORD dwInitBytesSend)
|
||
|
{
|
||
|
//
|
||
|
// If available, there's nothing to do here
|
||
|
//
|
||
|
|
||
|
if (IsAvailable() || !m_fAdapterSet)
|
||
|
{
|
||
|
MYDBGASSERT(FALSE);
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// We haven't opened the key yet, try to do so
|
||
|
//
|
||
|
|
||
|
MYDBGASSERT(!m_hKey);
|
||
|
|
||
|
if (m_hKey)
|
||
|
{
|
||
|
RegCloseKey(m_hKey);
|
||
|
m_hKey = NULL;
|
||
|
}
|
||
|
|
||
|
DWORD dwErrCode = RegOpenKeyExU( HKEY_DYN_DATA,
|
||
|
c_pszDialupPerfKey,
|
||
|
0,
|
||
|
KEY_ALL_ACCESS,
|
||
|
&m_hKey );
|
||
|
|
||
|
if (dwErrCode != ERROR_SUCCESS)
|
||
|
{
|
||
|
CMTRACE1(TEXT("OpenDAPPerfKey() RegOpenKeyEx() returned GLE=%u."), dwErrCode);
|
||
|
m_hKey = NULL;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
m_dwInitBytesRead = dwInitBytesRecv;
|
||
|
m_dwInitBytesWrite = dwInitBytesSend;
|
||
|
|
||
|
GetStatRegValues(hInst);
|
||
|
|
||
|
//
|
||
|
// If intial values are -1, reget the initial values.
|
||
|
//
|
||
|
|
||
|
if (((DWORD)-1 == dwInitBytesRecv) || ((DWORD)-1 == dwInitBytesSend))
|
||
|
{
|
||
|
//
|
||
|
// Get the initial statistics info
|
||
|
//
|
||
|
|
||
|
if (!GetPerfData(m_dwInitBytesRead, m_dwInitBytesWrite, m_dwBaudRate))
|
||
|
{
|
||
|
//
|
||
|
// No dial-up statistic info
|
||
|
//
|
||
|
|
||
|
RegCloseKey(m_hKey);
|
||
|
m_hKey = NULL;
|
||
|
|
||
|
CMTRACE(TEXT("CConnStatistics::OpenByPerformanceKey() - failed to find stats"));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CConnStatistics::GetStatRegValues
|
||
|
//
|
||
|
// Synopsis: Helper method, builds the reg value names using the localized
|
||
|
// form of the word "Dial-up Adapter".
|
||
|
//
|
||
|
// Arguments: HINSTANCE hInst
|
||
|
//
|
||
|
// Returns: Nothing
|
||
|
//
|
||
|
// History: nickball Created 11/14/98
|
||
|
//
|
||
|
//+----------------------------------------------------------------------------
|
||
|
void CConnStatistics::GetStatRegValues(HINSTANCE hInst)
|
||
|
{
|
||
|
CMTRACE1(TEXT("CConnStatistics::GetStatRegValues - m_pszTotalBytesRecvd is %s"), m_pszTotalBytesRecvd);
|
||
|
|
||
|
//
|
||
|
// bug 149367 The word "Dial-up Adapter" need to be localized.
|
||
|
// Load it from resource if no loaded yet
|
||
|
//
|
||
|
|
||
|
if (m_pszTotalBytesRecvd == NULL)
|
||
|
{
|
||
|
m_pszTotalBytesRecvd = CmLoadString(hInst, IDS_REG_DIALUP_ADAPTER);
|
||
|
CmStrCatAlloc(&m_pszTotalBytesRecvd, m_fAdapter2 ? c_pszDialup_2_TotalBytesRcvd : c_pszDialupTotalBytesRcvd);
|
||
|
|
||
|
m_pszTotalBytesXmit = CmLoadString(hInst, IDS_REG_DIALUP_ADAPTER);
|
||
|
CmStrCatAlloc(&m_pszTotalBytesXmit, m_fAdapter2 ? c_pszDialup_2_TotalBytesXmit : c_pszDialupTotalBytesXmit);
|
||
|
|
||
|
m_pszConnectSpeed = CmLoadString(hInst, IDS_REG_DIALUP_ADAPTER);
|
||
|
CmStrCatAlloc(&m_pszConnectSpeed, m_fAdapter2 ? c_pszDialup_2_ConnectSpeed : c_pszDialupConnectSpeed);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CConnStatistics::Close
|
||
|
//
|
||
|
// Synopsis: Stop gathering statistic and close the handle
|
||
|
//
|
||
|
// Arguments:
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: Created Header 10/15/97
|
||
|
//
|
||
|
//+----------------------------------------------------------------------------
|
||
|
void CConnStatistics::Close()
|
||
|
{
|
||
|
if (m_hStatDevice)
|
||
|
{
|
||
|
BOOL bRes = CloseHandle(m_hStatDevice);
|
||
|
m_hStatDevice = NULL;
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
if (!bRes)
|
||
|
{
|
||
|
CMTRACE1(TEXT("CConnStatistics::Close() CloseHandle() failed, GLE=%u."), GetLastError());
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
if (m_hKey)
|
||
|
{
|
||
|
DWORD dwErrCode = RegCloseKey(m_hKey);
|
||
|
CMTRACE1(TEXT("Close() RegCloseKey() returned GLE=%u."), dwErrCode);
|
||
|
m_hKey = NULL;
|
||
|
}
|
||
|
|
||
|
CmFree( m_pszTotalBytesRecvd );
|
||
|
CmFree( m_pszTotalBytesXmit );
|
||
|
CmFree( m_pszConnectSpeed );
|
||
|
|
||
|
m_pszTotalBytesRecvd = m_pszTotalBytesXmit = m_pszConnectSpeed = NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//+----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CConnStatistics::Update
|
||
|
//
|
||
|
// Synopsis: Gather new statistic information
|
||
|
//
|
||
|
// Arguments: None
|
||
|
//
|
||
|
// Returns: Nothing
|
||
|
//
|
||
|
// History: Fengsun Created 10/15/97
|
||
|
//
|
||
|
//+----------------------------------------------------------------------------
|
||
|
void CConnStatistics::Update()
|
||
|
{
|
||
|
if (!IsAvailable())
|
||
|
{
|
||
|
MYDBGASSERT(FALSE);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
CTraffic curTraffic;
|
||
|
curTraffic.dwTime = GetTickCount();
|
||
|
|
||
|
MYDBGASSERT(curTraffic.dwTime > m_TrafficRing.GetOldest().dwTime);
|
||
|
|
||
|
if (curTraffic.dwTime == m_TrafficRing.GetOldest().dwTime)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Prefer performace registry data
|
||
|
//
|
||
|
|
||
|
if (OS_NT5)
|
||
|
{
|
||
|
RAS_STATS RasStats;
|
||
|
|
||
|
ZeroMemory(&RasStats, sizeof(RasStats));
|
||
|
RasStats.dwSize = sizeof(RAS_STATS);
|
||
|
|
||
|
DWORD dwRet = m_RasApiDll.RasGetConnectionStatistics(m_hRasConn, &RasStats);
|
||
|
|
||
|
if (ERROR_SUCCESS == dwRet)
|
||
|
{
|
||
|
curTraffic.dwRead = RasStats.dwBytesRcved;
|
||
|
curTraffic.dwWrite = RasStats.dwBytesXmited;
|
||
|
m_dwBaudRate = RasStats.dwBps;
|
||
|
m_dwDuration = RasStats.dwConnectDuration;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// Not NT5, try the registry
|
||
|
//
|
||
|
|
||
|
if (m_hKey)
|
||
|
{
|
||
|
if (!GetPerfData(curTraffic.dwRead, curTraffic.dwWrite, m_dwBaudRate))
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
curTraffic.dwRead -= m_dwInitBytesRead;
|
||
|
curTraffic.dwWrite -= m_dwInitBytesWrite;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// Last resort for 9x, try to use stat device
|
||
|
//
|
||
|
|
||
|
if (m_hStatDevice)
|
||
|
{
|
||
|
if (!GetTapiDeviceStats(curTraffic.dwRead, curTraffic.dwWrite, m_dwBaudRate))
|
||
|
{
|
||
|
BOOL bRes = CloseHandle(m_hStatDevice);
|
||
|
m_hStatDevice = NULL;
|
||
|
|
||
|
if (!bRes)
|
||
|
{
|
||
|
CMTRACE1(TEXT("CConnStatistics::Update() CloseHandle() failed, GLE=%u."), GetLastError());
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
MYDBGASSERT(m_hStatDevice);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Calculate the avarage between two interval
|
||
|
//
|
||
|
const CTraffic& lastTraffic = m_TrafficRing.GetOldest();
|
||
|
|
||
|
DWORD dwDeltaTime = curTraffic.dwTime - lastTraffic.dwTime;
|
||
|
m_dwReadPerSecond = ((curTraffic.dwRead - lastTraffic.dwRead)*1000) /dwDeltaTime;
|
||
|
m_dwWritePerSecond = ((curTraffic.dwWrite - lastTraffic.dwWrite)*1000) /dwDeltaTime;
|
||
|
|
||
|
m_TrafficRing.Add(curTraffic);
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: GetPerfData
|
||
|
//
|
||
|
// Synopsis: Get Performance Data from DUN1.2 performance registry
|
||
|
//
|
||
|
// Arguments:
|
||
|
//
|
||
|
// Returns: TRUE: succeed
|
||
|
// FALSE otherwise
|
||
|
//
|
||
|
// History: byao created 7/16/97
|
||
|
// fengsun change it into a member function 10/14/97
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL CConnStatistics::GetPerfData(DWORD& dwRead, DWORD& dwWrite, DWORD& dwBaudRate) const
|
||
|
{
|
||
|
if (OS_W9X)
|
||
|
{
|
||
|
MYDBGASSERT(m_hKey != NULL);
|
||
|
MYDBGASSERT(m_pszTotalBytesRecvd && *m_pszTotalBytesRecvd);
|
||
|
|
||
|
LONG dwErrCode;
|
||
|
|
||
|
DWORD dwValueSize, dwValueType;
|
||
|
DWORD dwValue;
|
||
|
|
||
|
//
|
||
|
// "Dial-up Adapter\TotalBytesRecvd"
|
||
|
//
|
||
|
dwValueSize = sizeof(DWORD);
|
||
|
dwErrCode = RegQueryValueExU(
|
||
|
m_hKey,
|
||
|
m_pszTotalBytesRecvd,
|
||
|
NULL,
|
||
|
&dwValueType,
|
||
|
(PBYTE)&dwValue,
|
||
|
&dwValueSize);
|
||
|
|
||
|
if (dwErrCode == ERROR_SUCCESS)
|
||
|
{
|
||
|
dwRead = dwValue;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CMTRACE2(TEXT("GetPerfData() RegQueryValueEx() %s failed and returned GLE=%u."),
|
||
|
m_pszTotalBytesRecvd, dwErrCode);
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// "Dial-up Adapter\TotalBytesXmit"
|
||
|
//
|
||
|
|
||
|
dwValueSize = sizeof(DWORD);
|
||
|
dwErrCode = RegQueryValueExU(
|
||
|
m_hKey,
|
||
|
m_pszTotalBytesXmit,
|
||
|
NULL,
|
||
|
&dwValueType,
|
||
|
(PBYTE)&dwValue,
|
||
|
&dwValueSize);
|
||
|
|
||
|
if (dwErrCode == ERROR_SUCCESS)
|
||
|
{
|
||
|
dwWrite = dwValue;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CMTRACE2(TEXT("GetPerfData() RegQueryValueEx() %s failed and returned GLE=%u."),
|
||
|
m_pszTotalBytesXmit, dwErrCode);
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// "Dial-up Adapter\ConnectSpeed"
|
||
|
//
|
||
|
dwValueSize = sizeof(DWORD);
|
||
|
dwErrCode = RegQueryValueExU(
|
||
|
m_hKey,
|
||
|
m_pszConnectSpeed,
|
||
|
NULL,
|
||
|
&dwValueType,
|
||
|
(PBYTE)&dwValue,
|
||
|
&dwValueSize);
|
||
|
|
||
|
if (dwErrCode == ERROR_SUCCESS)
|
||
|
{
|
||
|
dwBaudRate = dwValue;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CMTRACE2(TEXT("GetPerfData() RegQueryValueEx() %s failed and returned GLE=%u."), m_pszConnectSpeed, dwErrCode);
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: GetTapiDeviceStats
|
||
|
//
|
||
|
// Synopsis: Get Modem Performance Data by DeviceIoControl
|
||
|
//
|
||
|
// Arguments:
|
||
|
//
|
||
|
// Returns: TRUE: succeed
|
||
|
// FALSE otherwise
|
||
|
//
|
||
|
// History: byao created 7/16/97
|
||
|
// fengsun change it into a member function 10/14/97
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL CConnStatistics::GetTapiDeviceStats(DWORD& dwRead, DWORD& dwWrite, DWORD& dwBaudRate) const
|
||
|
{
|
||
|
BOOL bRes;
|
||
|
DWORD dwRet;
|
||
|
|
||
|
typedef struct tagAPISTATS {
|
||
|
LPVOID hPort;
|
||
|
DWORD fConnected;
|
||
|
DWORD DCERate;
|
||
|
DWORD dwPerfRead;
|
||
|
DWORD dwPerfWrite;
|
||
|
} APISTATS;
|
||
|
|
||
|
APISTATS ApiStats;
|
||
|
|
||
|
if (m_hStatDevice)
|
||
|
{
|
||
|
bRes = DeviceIoControl(m_hStatDevice,
|
||
|
UNIMODEM_IOCTL_GET_STATISTICS,
|
||
|
&ApiStats,
|
||
|
sizeof(ApiStats),
|
||
|
&ApiStats,
|
||
|
sizeof(ApiStats),
|
||
|
&dwRet,
|
||
|
NULL);
|
||
|
if (bRes && ApiStats.fConnected)
|
||
|
{
|
||
|
dwRead = ApiStats.dwPerfRead;
|
||
|
dwWrite = ApiStats.dwPerfWrite;
|
||
|
dwBaudRate = ApiStats.DCERate;
|
||
|
return (TRUE);
|
||
|
}
|
||
|
|
||
|
CMTRACE(TEXT("GetTapiDeviceStats() DeviceIoControl() failed - disabling hStatDevice."));
|
||
|
}
|
||
|
|
||
|
return (FALSE);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//+----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CConnStatistics::GetDeviceHandle
|
||
|
//
|
||
|
// Synopsis: Get the TAPI device handle
|
||
|
//
|
||
|
// Arguments: HRASCONN hrcRasConn - the ras connection handle
|
||
|
//
|
||
|
// Returns: BOOL - TRUE if succeed
|
||
|
//
|
||
|
// History: fengsun Created Header 10/29/97
|
||
|
//
|
||
|
//+----------------------------------------------------------------------------
|
||
|
BOOL CConnStatistics::GetDeviceHandle(HRASCONN hrcRasConn)
|
||
|
{
|
||
|
MYDBGASSERT(hrcRasConn);
|
||
|
MYDBGASSERT(!m_hStatDevice);
|
||
|
|
||
|
typedef struct tagDEVICE_PORT_INFO
|
||
|
{
|
||
|
DWORD dwSize;
|
||
|
HANDLE hDevicePort;
|
||
|
HLINE hLine;
|
||
|
HCALL hCall;
|
||
|
DWORD dwAddressID;
|
||
|
DWORD dwLinkSpeed;
|
||
|
char szDeviceClass[RAS_MaxDeviceType+1];
|
||
|
} DEVICE_PORT_INFO, *LPDEVICE_PORT_INFO;
|
||
|
|
||
|
typedef struct tagMacInfo
|
||
|
{
|
||
|
VARSTRING varstring;
|
||
|
HANDLE hCommDevice;
|
||
|
char szDeviceClass[1];
|
||
|
} MacInfo;
|
||
|
|
||
|
typedef DWORD (WINAPI *RnaGetDevicePortFUNC)(HANDLE,LPDEVICE_PORT_INFO);
|
||
|
RnaGetDevicePortFUNC pfnRnaGetDevicePort;
|
||
|
|
||
|
//
|
||
|
// Load rasapi32.dll and call RnaGetDevicePort
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// The destructor of CDynamicLibrary automaticly call FreeLibrary
|
||
|
//
|
||
|
CDynamicLibrary RasLib;
|
||
|
|
||
|
if (!RasLib.Load(TEXT("rasapi32.dll")))
|
||
|
{
|
||
|
CMTRACE1(TEXT("GetDeviceHandle() LoadLibrary() failed, GLE=%u."), GetLastError());
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
pfnRnaGetDevicePort = (RnaGetDevicePortFUNC) RasLib.GetProcAddress("RnaGetDevicePort");
|
||
|
if (!pfnRnaGetDevicePort)
|
||
|
{
|
||
|
CMTRACE1(TEXT("GetDeviceHandle() GetProcAddress() failed, GLE=%u."), GetLastError());
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
DWORD dwRes;
|
||
|
DEVICE_PORT_INFO dpi;
|
||
|
|
||
|
ZeroMemory(&dpi,sizeof(dpi));
|
||
|
dpi.dwSize = sizeof(dpi);
|
||
|
|
||
|
dwRes = pfnRnaGetDevicePort(hrcRasConn,&dpi);
|
||
|
if (dwRes)
|
||
|
{
|
||
|
CMTRACE1(TEXT("GetDeviceHandle() RnaGetDevicePort() failed, GLE=%u."), dwRes);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Load TAPI32.dll
|
||
|
// CDynamicLibrary Free the lib on destructor
|
||
|
//
|
||
|
CDynamicLibrary LibTapi;
|
||
|
|
||
|
if (!LibTapi.Load(TEXT("TAPI32.DLL")))
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
typedef LONG (WINAPI *TapiLineGetIDFUNC)
|
||
|
(HLINE, DWORD, HCALL, DWORD, LPVARSTRING, LPCSTR);
|
||
|
|
||
|
//
|
||
|
// Always call the Ansi version since this is a Win9x only function
|
||
|
//
|
||
|
TapiLineGetIDFUNC pfnTapiLineGetID;
|
||
|
pfnTapiLineGetID = (TapiLineGetIDFUNC) LibTapi.GetProcAddress("lineGetID");
|
||
|
|
||
|
if (pfnTapiLineGetID == NULL)
|
||
|
{
|
||
|
MYDBGASSERT(pfnTapiLineGetID != NULL);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
LONG lRes;
|
||
|
|
||
|
CMTRACE3(TEXT("GetDeviceHandle() hDevicePort=0x%x, hLine=0x%x, hCall=0x%x,"), dpi.hDevicePort, dpi.hLine, dpi.hCall);
|
||
|
CMTRACE3(TEXT("\tdwAddressID=0x%x, dwLinkSpeed=%u, szDeviceClass=%s."), dpi.dwAddressID, dpi.dwLinkSpeed, dpi.szDeviceClass);
|
||
|
|
||
|
m_dwBaudRate = dpi.dwLinkSpeed;
|
||
|
|
||
|
MacInfo* pmi = NULL;
|
||
|
DWORD dwSize = sizeof(*pmi);
|
||
|
|
||
|
do
|
||
|
{
|
||
|
CmFree(pmi);
|
||
|
pmi = (MacInfo *) CmMalloc(dwSize);
|
||
|
if (pmi == NULL)
|
||
|
{
|
||
|
lRes = ERROR_OUTOFMEMORY;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
pmi->varstring.dwTotalSize = dwSize;
|
||
|
|
||
|
|
||
|
lRes = pfnTapiLineGetID(dpi.hLine,
|
||
|
dpi.dwAddressID,
|
||
|
NULL,
|
||
|
LINECALLSELECT_ADDRESS,
|
||
|
&pmi->varstring,
|
||
|
"comm/datamodem");
|
||
|
|
||
|
dwSize = pmi->varstring.dwNeededSize;
|
||
|
} while(pmi->varstring.dwNeededSize > pmi->varstring.dwTotalSize);
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
if (lRes)
|
||
|
{
|
||
|
CMTRACE1(TEXT("CConnStatistics::GetDeviceHandle() lineGetID() failed, GLE=%u."), lRes);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if (!lRes && pmi != NULL )
|
||
|
{
|
||
|
m_hStatDevice = pmi->hCommDevice;
|
||
|
}
|
||
|
|
||
|
CmFree(pmi);
|
||
|
|
||
|
return m_hStatDevice != NULL;
|
||
|
}
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
//+----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CConnStatistics::AssertValid
|
||
|
//
|
||
|
// Synopsis: For debug purpose only, assert the object is valid
|
||
|
//
|
||
|
// Arguments: None
|
||
|
//
|
||
|
// Returns: Nothing
|
||
|
//
|
||
|
// History: Created Header 2/12/98
|
||
|
//
|
||
|
//+----------------------------------------------------------------------------
|
||
|
void CConnStatistics::AssertValid() const
|
||
|
{
|
||
|
MYDBGASSERT(m_hKey == NULL || m_hStatDevice == NULL);
|
||
|
MYDBGASSERT(m_fAdapter2 == TRUE || m_fAdapter2 == FALSE);
|
||
|
ASSERT_VALID(&m_TrafficRing);
|
||
|
}
|
||
|
#endif
|