H文件:rasSpdM.h #ifndef __RASSPDMON_H_
#define __RASSPDMON_H_
void InitSpeedMonitor(void);
void ClearSpeedMonitor(void);
void GetRASSpeed(DWORD* pTPS,DWORD* pRPS,DWORD* pTT,DWORD* pRT);
////参数:每秒发送,每秒接收,总发送,总接受
#endif
CPP文件rasSpdM.cpp
#include "stdafx.h"
#include "rasSpdM.h"
#include
#define TOTALBYTES 4096
#define BYTEINCREMENT 1024
LPSTR lpNameStrings=NULL;
LPSTR *lpNamesArray=NULL;
BOOL glo_fFromDynReg=TRUE;
/*
在9x下通过dyn_data注册表得到速度
*/
DWORD GetTotalRecv(void)
{
HKEY hKey;
DWORD dwValue=(DWORD)-1;
if(0==RegOpenKey(HKEY_DYN_DATA,"PerfStats\\StatData",&hKey))
{
DWORD dwType,dwLen=sizeof(DWORD);
RegQueryValueEx(hKey,"Dial-Up Adapter\\TotalBytesRecvd",NULL,&dwType,(BYTE*)&dwValue,&dwLen);
RegCloseKey(hKey);
}
return dwValue;
}
DWORD GetTotalXmit(void)
{
HKEY hKey;
DWORD dwValue=(DWORD)-1;
if(0==RegOpenKey(HKEY_DYN_DATA,"PerfStats\\StatData",&hKey))
{
DWORD dwType,dwLen=sizeof(DWORD);
RegQueryValueEx(hKey,"Dial-Up Adapter\\TotalBytesXmit",NULL,&dwType,(BYTE*)&dwValue,&dwLen);
RegCloseKey(hKey);
}
return dwValue;
}
DWORD GetPerSecondRecv(void)
{
HKEY hKey;
DWORD dwValue=(DWORD)-1;
if(0==RegOpenKey(HKEY_DYN_DATA,"PerfStats\\StatData",&hKey))
{
DWORD dwType,dwLen=sizeof(DWORD);
RegQueryValueEx(hKey,"Dial-Up Adapter\\BytesRecvd",NULL,&dwType,(BYTE*)&dwValue,&dwLen);
RegCloseKey(hKey);
}
return dwValue;
}
DWORD GetPerSecondXmit(void)
{
HKEY hKey;
DWORD dwValue=(DWORD)-1;
if(0==RegOpenKey(HKEY_DYN_DATA,"PerfStats\\StatData",&hKey))
{
DWORD dwType,dwLen=sizeof(DWORD);
RegQueryValueEx(hKey,"Dial-Up Adapter\\BytesXmit",NULL,&dwType,(BYTE*)&dwValue,&dwLen);
RegCloseKey(hKey);
}
return dwValue;
}
/*****************************************************************
在NT下通过per Data得到
*****************************************************************/
PPERF_OBJECT_TYPE FirstObject( PPERF_DATA_BLOCK PerfData )
{
return( (PPERF_OBJECT_TYPE)((PBYTE)PerfData +
PerfData->HeaderLength) );
}
PPERF_OBJECT_TYPE NextObject( PPERF_OBJECT_TYPE PerfObj )
{
return( (PPERF_OBJECT_TYPE)((PBYTE)PerfObj +
PerfObj->TotalByteLength) );
}
PPERF_INSTANCE_DEFINITION FirstInstance( PPERF_OBJECT_TYPE PerfObj )
{
return( (PPERF_INSTANCE_DEFINITION)((PBYTE)PerfObj +
PerfObj->DefinitionLength) );
}
PPERF_INSTANCE_DEFINITION NextInstance(
PPERF_INSTANCE_DEFINITION PerfInst )
{
PPERF_COUNTER_BLOCK PerfCntrBlk;
PerfCntrBlk = (PPERF_COUNTER_BLOCK)((PBYTE)PerfInst +
PerfInst->ByteLength);
return( (PPERF_INSTANCE_DEFINITION)((PBYTE)PerfCntrBlk +
PerfCntrBlk->ByteLength) );
}
PPERF_COUNTER_DEFINITION FirstCounter( PPERF_OBJECT_TYPE PerfObj )
{
return( (PPERF_COUNTER_DEFINITION) ((PBYTE)PerfObj +
PerfObj->HeaderLength) );
}
PPERF_COUNTER_DEFINITION NextCounter(
PPERF_COUNTER_DEFINITION PerfCntr )
{
return( (PPERF_COUNTER_DEFINITION)((PBYTE)PerfCntr +
PerfCntr->ByteLength) );
}
/*****************************************************************
* *
* Load the counter and object names from the registry to the *
* global variable lpNamesArray. *
* *
*****************************************************************/
void GetNameStrings( )
{
HKEY hKeyPerflib; // handle to registry key
HKEY hKeyPerflib009; // handle to registry key
DWORD dwMaxValueLen; // maximum size of key values
DWORD dwBuffer; // bytes to allocate for buffers
DWORD dwBufferSize; // size of dwBuffer
LPSTR lpCurrentString; // pointer for enumerating data strings
DWORD dwCounter; // current counter index
// Get the number of Counter items.
RegOpenKeyEx( HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib",
0,
KEY_READ,
&hKeyPerflib);
dwBufferSize = sizeof(dwBuffer);
RegQueryValueEx( hKeyPerflib,
"Last Counter",
NULL,
NULL,
(LPBYTE) &dwBuffer,
&dwBufferSize );
RegCloseKey( hKeyPerflib );
// Allocate memory for the names array.
lpNamesArray = (char**)malloc( (dwBuffer+1) * sizeof(LPSTR) );
// Open key containing counter and object names.
RegOpenKeyEx( HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\009",
0,
KEY_READ,
&hKeyPerflib009);
// Get the size of the largest value in the key (Counter or Help).
RegQueryInfoKey( hKeyPerflib009,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
&dwMaxValueLen,
NULL,
NULL);
// Allocate memory for the counter and object names.
dwBuffer = dwMaxValueLen + 1;
lpNameStrings = (char*)malloc( dwBuffer * sizeof(CHAR) );
// Read Counter value.
RegQueryValueEx( hKeyPerflib009,
"Counter",
NULL,
NULL,
(BYTE*)lpNameStrings, &dwBuffer );
// Load names into an array, by index.
int iC=1;
for( lpCurrentString = lpNameStrings; *lpCurrentString;
lpCurrentString += (lstrlen(lpCurrentString)+1) )
{
dwCounter = atol( lpCurrentString );
lpCurrentString += (lstrlen(lpCurrentString)+1);
//printf("%d length=%d data=%s\n",iC++,dwCounter,lpCurrentString);
lpNamesArray[dwCounter] = (LPSTR) lpCurrentString;
}
}
/*****************************************************************
得到下RAS速度
*****************************************************************/
void GetRASSpeedOn9X(DWORD* pTPS,DWORD* pRPS,DWORD* pTT,DWORD* pRT)
{// under 9x
*pTPS=GetPerSecondXmit();
*pRPS=GetPerSecondRecv();
*pTT=GetTotalXmit();
*pRT=GetTotalRecv();
}
void GetRASSpeedOnNT(DWORD* pTPS,DWORD* pRPS,DWORD* pTT,DWORD* pRT)
{// under NT
////参数:每秒发送,每秒接收,总发送,总接受
PPERF_DATA_BLOCK PerfData = NULL;
PPERF_OBJECT_TYPE PerfObj;
PPERF_INSTANCE_DEFINITION PerfInst;
PPERF_COUNTER_DEFINITION PerfCntr, CurCntr;
PPERF_COUNTER_BLOCK PtrToCntr;
DWORD BufferSize = TOTALBYTES;
DWORD i, j, k;
// Get the name strings through the registry.
//return;
// Allocate the buffer for the performance data.
PerfData = (PPERF_DATA_BLOCK) malloc( BufferSize );
while( RegQueryValueEx( HKEY_PERFORMANCE_DATA,
"906",//"Global",
NULL,
NULL,
(LPBYTE) PerfData,
&BufferSize ) == ERROR_MORE_DATA )
{
// Get a buffer that is big enough.
BufferSize += BYTEINCREMENT;
PerfData = (PPERF_DATA_BLOCK) realloc( PerfData, BufferSize );
}
// Get the first object type.
PerfObj = FirstObject( PerfData );
// Process all objects.
//printf("object total=%d\n",PerfData->NumObjectTypes);
//getchar();
for( i=0; i < PerfData->NumObjectTypes; i++ )
{
// Display the object by index and name.
// Get the first counter.
PerfCntr = FirstCounter( PerfObj );
if( PerfObj->NumInstances > 0 )
{
//exit(0);
}
else
{
// Get the counter block.
PtrToCntr = (PPERF_COUNTER_BLOCK) ((PBYTE)PerfObj +
PerfObj->DefinitionLength );
// Retrieve all counters.
for( j=0; j < PerfObj->NumCounters; j++ )
{
// Display the counter by index and name.
if(strcmp("Bytes Transmitted/Sec",lpNamesArray[PerfCntr->CounterNameTitleIndex])==0)
{
*pTPS=*((DWORD*)((BYTE*)PtrToCntr+PerfCntr->CounterOffset));
}
if(strcmp("Bytes Received/Sec",lpNamesArray[PerfCntr->CounterNameTitleIndex])==0)
{
*pRPS=*((DWORD*)((BYTE*)PtrToCntr+PerfCntr->CounterOffset));
}
if(strcmp("Bytes Transmitted",lpNamesArray[PerfCntr->CounterNameTitleIndex])==0)
{
*pTT=*((DWORD*)((BYTE*)PtrToCntr+PerfCntr->CounterOffset));
}
if(strcmp("Bytes Received",lpNamesArray[PerfCntr->CounterNameTitleIndex])==0)
{
*pRT=*((DWORD*)((BYTE*)PtrToCntr+PerfCntr->CounterOffset));
}
// Get the next counter.
PerfCntr = NextCounter( PerfCntr );
}
}
// Get the next object type.
PerfObj = NextObject( PerfObj );
}
}
void GetRASSpeed(DWORD* pTPS,DWORD* pRPS,DWORD* pTT,DWORD* pRT)
{////参数:每秒发送,每秒接收,总发送,总接受
if(glo_fFromDynReg==FALSE)
{
GetRASSpeedOnNT(pTPS,pRPS, pTT,pRT);
}
else
{
GetRASSpeedOn9X(pTPS,pRPS, pTT,pRT);
}
}
void InitSpeedMonitor(void)
{
DWORD dwVersion = GetVersion();
// Get major and minor version numbers of Windows
DWORD dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
DWORD dwWindowsMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
// Get build numbers for Windows NT or Win32s
if (dwVersion>>31 ==0) // Windows NT
{
glo_fFromDynReg=FALSE;
GetNameStrings( );
}
else // Windows 95 - 98
glo_fFromDynReg=TRUE;
}
void ClearSpeedMonitor(void)
{
if(lpNameStrings)
free(lpNameStrings);
if(lpNamesArray)
free(lpNamesArray);
}
使用方法:
#include "rasSpdM.h"
BOOL CYourApp::InitInstance()
{
//初始化RAS速度访问
InitSpeedMonitor();
...
}
#include "rasSpdM.h"
void CYourWnd::OnTimer(UINT nIDEvent)
{
DWORD dwR,dwS,dwPSR,dwPSS;//总接收,总发送,每秒接收,每秒发送
GetRASSpeed(&dwPSS,&dwPSR,&dwS,&dwR);//pTPS,DWORD* pRPS,DWORD* pTT,DWORD* pRT)
//参数:每秒发送,每秒接收,总发送,总接收
...
}
但我在使用过程中发现每秒发送,每秒接收这两个结果并不十分正确,所以我是采用总数相减的方式来计算每秒速度的。