WINDOWS网络流量监控(区分物理网卡)(Win32)

#include <tchar.h>
#include <STDIO.H>
#include <locale.h>
#include <WINDOWS.H>

#include <atlconv.h>
#include <atlstr.h>

#include <vector>
#include <list>
#include <map>

#include <strsafe.h>

#include <boost\format.hpp>
#include <boost\io\ios_state.hpp>
#include <boost\algorithm\string.hpp>
#include <boost\xpressive\xpressive_dynamic.hpp>

#define PERF_SUBKEY_GLOBAL      _T("Global")
#define REG_SUBKEY_COUNTER      _T("Counter")
#define REG_SUBKEY_HELP         _T("Help")
#define FIRST_PERF_OBJECT_TYPE( PerfData ) ((PPERF_OBJECT_TYPE)((PBYTE)PerfData + PerfData->HeaderLength))
#define NEXT_PERF_OBJECT_TYPE( PerfObj ) ((PPERF_OBJECT_TYPE)((PBYTE)PerfObj + PerfObj->TotalByteLength))
#define FIRST_PERF_COUNTER_DEFINITION( PerfObj ) ((PPERF_COUNTER_DEFINITION)((PBYTE)PerfObj + PerfObj->HeaderLength))
#define NEXT_PERF_COUNTER_DEFINITION( PerfCounterDef ) ((PPERF_COUNTER_DEFINITION)((PBYTE)PerfCounterDef + PerfCounterDef->ByteLength))
#define FIRST_PERF_INSTANCE_DEFINITION( PerfObj ) ((PPERF_INSTANCE_DEFINITION)((PBYTE)PerfObj + PerfObj->DefinitionLength))
#define PERF_COUNTER_BLOCK_FROM_INSTANCE( PerfInst ) ((PPERF_COUNTER_BLOCK)((PBYTE)PerfInst + PerfInst->ByteLength))
#define PERF_COUNTER_BLOCK_FROM_OBJECT( PerfObj ) ((PPERF_COUNTER_BLOCK)((PBYTE)PerfObj + PerfObj->DefinitionLength))
#define NEXT_PERF_INSTANCE_DEFINITION( PerfInst ) ((PPERF_INSTANCE_DEFINITION)((PBYTE)PerfInst + PerfInst->ByteLength + PERF_COUNTER_BLOCK_FROM_INSTANCE(PerfInst)->ByteLength ))
#define GET_COUNTER_VALUE_DWORD( PerfCounter, PerfCounterDef ) (*(LPDWORD)((LPBYTE)PerfCounter + PerfCounterDef->CounterOffset ))
#define GET_COUNTER_VALUE_OF_TYPE( PerfCounter, PerfCounterDef, Type ) (*(Type*)((LPBYTE)PerfCounter + PerfCounterDef->CounterOffset ))

namespace std
{
    typedef basic_string<TCHAR, char_traits<TCHAR>, allocator<TCHAR> > tstring;
}

std::map<DWORD, CString> g_mapCounters;
std::map<DWORD, CString> g_mapHelps;
std::map<std::tstring, BOOL>  g_mapPhys;


typedef struct _PerfInstance_t
{
    PPERF_INSTANCE_DEFINITION       pInstance;
    CString                         strInstanceName;
    CString                         strParentInstanceName;
    PPERF_COUNTER_BLOCK             pPerfCounters;
}PerfInstance_t, *pPerfInstance_t;
typedef struct _PerfObject_t
{
    PPERF_OBJECT_TYPE               pPerfObject;
    
    std::vector<PPERF_COUNTER_DEFINITION>
                                    vecPerfCounterDefs;

    PPERF_COUNTER_BLOCK             pPerfCounters;
    std::vector<PerfInstance_t>     vecPerfInstances;
}PerfObject_t, *pPerfObject_t;
typedef struct _PerfData_t
{
    std::vector<PerfObject_t>       vecPerfObjects;
}PerfData_t, *pPerfData_t;

// 获得性能数据块
std::vector<BYTE> GetRegValueData(
    LPCTSTR lpSubKey,
    HKEY hParentKey = HKEY_PERFORMANCE_DATA,
    LPCTSTR lpMachineName = NULL,
    DWORD dwPerSize = 0x400 )
{
    DWORD dwType;

    CONST DWORD dwDefaultBufferSize = dwPerSize;
    DWORD dwBufferSize = dwDefaultBufferSize;
    // 性能数据缓冲
    std::vector<BYTE> vecBuffer;

    HKEY hKey = hParentKey;
    if( lpMachineName && lpMachineName[0] != _T('\0') )
    {
        if( RegConnectRegistry(
            lpMachineName,
            hKey,
            &hKey ) != ERROR_SUCCESS )
            return vecBuffer;
    }

    LSTATUS lStatus;
    vecBuffer.resize(dwBufferSize);

    while( ( lStatus = RegQueryValueEx(
        hKey,
        lpSubKey,
        NULL,
        &dwType,
        vecBuffer.data(),
        &dwBufferSize ) ) != ERROR_SUCCESS )
    {
        if( lStatus == ERROR_MORE_DATA )
        {
            // 缓冲尺寸太小,增加内存分配
            dwBufferSize += dwDefaultBufferSize;
            vecBuffer.resize( dwBufferSize );
        }
        else
        {
            vecBuffer.clear();
            return vecBuffer;
        }
    }

    vecBuffer.resize( dwBufferSize );
    return vecBuffer;
}

std::vector<BYTE> GetRegValueData(
    DWORD dwSubKey,
    HKEY hParentKey = HKEY_PERFORMANCE_DATA,
    LPCTSTR lpMachineName = NULL,
    DWORD dwPerSize = 0x400 )
{
    TCHAR szSubKey[0x10];
    _ltot_s( dwSubKey, szSubKey, 0x10, 10 );
    return GetRegValueData( szSubKey, hParentKey, lpMachineName, dwPerSize );
}

// 枚举性能对象
BOOL EnumPerfObject(
    IN  PERF_DATA_BLOCK * pPerfData,
    OUT std::list<PERF_OBJECT_TYPE> & vecRefObjType )
{
    vecRefObjType.clear();

    PERF_OBJECT_TYPE * pObjType = FIRST_PERF_OBJECT_TYPE( pPerfData );
    for( DWORD i(0); i < pPerfData->NumObjectTypes; ++i )
    {
        vecRefObjType.push_back( *pObjType );
        pObjType = NEXT_PERF_OBJECT_TYPE( pObjType );
    }

    return TRUE;
}

// 获取性能计数器名字
BOOL GetCounters( std::map<DWORD, CString> & mapCounters )
{
    mapCounters.clear();

    std::vector<BYTE> vecBuffer = GetRegValueData( REG_SUBKEY_COUNTER, HKEY_PERFORMANCE_NLSTEXT );
    if( vecBuffer.empty() ) return FALSE;

    LPTSTR lpStr = (LPTSTR)vecBuffer.data();
    while( *lpStr )
    {
        DWORD dwCounter = _ttol(lpStr);
        lpStr += lstrlen(lpStr) + 1;
        mapCounters[dwCounter] = lpStr;
        lpStr += lstrlen(lpStr) + 1;
    }

    return TRUE;
}
// 获取性能计数器的帮助
BOOL GetHelps( std::map<DWORD, CString> & mapHelps )
{
    mapHelps.clear();

    std::vector<BYTE> vecBuffer = GetRegValueData( REG_SUBKEY_HELP, HKEY_PERFORMANCE_NLSTEXT );
    if( vecBuffer.empty() ) return FALSE;

    LPTSTR lpStr = (LPTSTR)vecBuffer.data();
    while( *lpStr )
    {
        DWORD dwCounter = _ttol(lpStr);
        lpStr += lstrlen(lpStr) + 1;
        mapHelps[dwCounter] = lpStr;
        lpStr += lstrlen(lpStr) + 1;
    }

    return TRUE;
}

PPERF_OBJECT_TYPE GetObjectType(
    PPERF_DATA_BLOCK pPerfDataBlock,
    DWORD dwObjectNameTitleIndex )
{
    PPERF_OBJECT_TYPE pPerfObjectType = FIRST_PERF_OBJECT_TYPE( pPerfDataBlock );

    for( DWORD i(0); i < pPerfDataBlock->NumObjectTypes; ++i )
    {
        if( pPerfObjectType->ObjectNameTitleIndex == dwObjectNameTitleIndex )
        {
            return pPerfObjectType;
        }
        pPerfObjectType = NEXT_PERF_OBJECT_TYPE( pPerfObjectType );
    }

    return NULL;
}

PPERF_INSTANCE_DEFINITION GetParentInstance(
    PPERF_OBJECT_TYPE const pPerfObjectType,
    DWORD dwInstanceIndex )
{
    PPERF_INSTANCE_DEFINITION pPerfInstanceDefinition = FIRST_PERF_INSTANCE_DEFINITION( pPerfObjectType );
    PPERF_COUNTER_BLOCK pPerfCounterBlock = NULL;
    for( DWORD i(0); i < dwInstanceIndex; ++i )
    {
        pPerfCounterBlock = PERF_COUNTER_BLOCK_FROM_INSTANCE( pPerfInstanceDefinition );

        pPerfInstanceDefinition = NEXT_PERF_INSTANCE_DEFINITION( pPerfInstanceDefinition );
    }

    return pPerfInstanceDefinition;
}

CString GetInstanceName(
    PPERF_INSTANCE_DEFINITION pPerfInstanceDefinition,
    UINT CodePage )
{
    CStringW strInstanceNameW;
    const DWORD dwMaxInstNameLen = 0xFF;
    if( pPerfInstanceDefinition->NameLength > dwMaxInstNameLen ) return CString();

    LPBYTE lpInstanceName = (LPBYTE)pPerfInstanceDefinition + pPerfInstanceDefinition->NameOffset;
    if( CodePage == 0 ) // Unicode
    {
        DWORD cch = pPerfInstanceDefinition->NameLength / 2;
        StringCchCopyNW(
            strInstanceNameW.GetBuffer( cch + 1 ),
            cch + 1,
            (LPCWSTR)lpInstanceName,
            cch );
        strInstanceNameW.ReleaseBuffer();
    }
    else if( CodePage != UINT_MAX ) // 异常值
    {
        CStringA strInstanceNameA;
        StringCbCopyNA(
            strInstanceNameA.GetBuffer( pPerfInstanceDefinition->NameLength + 1 ),
            pPerfInstanceDefinition->NameLength + 1,
            (LPCSTR)lpInstanceName,
            pPerfInstanceDefinition->NameLength );
        strInstanceNameA.ReleaseBuffer();

        strInstanceNameW = CA2W( strInstanceNameA, CodePage );
    }
    
    return CString( strInstanceNameW );
}
void GetFullInstanceName(
    PPERF_DATA_BLOCK const pPerfDataBlock,
    PPERF_INSTANCE_DEFINITION pInstance,
    UINT CodePage,
    CString & strName,
    CString & strParentName )
{
    strName = GetInstanceName( pInstance, CodePage );

    if( pInstance->ParentObjectTitleIndex )
    {
        PPERF_OBJECT_TYPE pParentObject = GetObjectType(
            pPerfDataBlock,
            pInstance->ParentObjectTitleIndex );

        if( pParentObject )
        {
            PPERF_INSTANCE_DEFINITION pParentInstance = GetParentInstance(
                pParentObject,
                pInstance->ParentObjectInstance );
            if( pParentInstance )
            {
                strParentName = GetInstanceName( pParentInstance, CodePage );
            }
        }
    }
}

DWORD LoadCounterDefs(
    PPERF_OBJECT_TYPE const pPerfObject,
    std::vector<PPERF_COUNTER_DEFINITION> & vecPerfCounterDefs )
{
    vecPerfCounterDefs.clear();
    DWORD dwSkippedBaseRecords = 0;

    PPERF_COUNTER_DEFINITION pPerfCounterDef = FIRST_PERF_COUNTER_DEFINITION( pPerfObject );
    for( DWORD i(0); i < pPerfObject->NumCounters; ++i )
    {
        vecPerfCounterDefs.push_back( pPerfCounterDef );

        pPerfCounterDef = NEXT_PERF_COUNTER_DEFINITION( pPerfCounterDef );
    }

    return pPerfObject->NumCounters - dwSkippedBaseRecords;
}
void LoadInstances(
    PPERF_DATA_BLOCK const pPerfData,
    PPERF_OBJECT_TYPE const pPerfObject,
    std::vector<PerfInstance_t> & vecPerfInstances )
{
    vecPerfInstances.clear();

    PPERF_INSTANCE_DEFINITION pInstance = FIRST_PERF_INSTANCE_DEFINITION( pPerfObject );
    for( LONG i(0); i < pPerfObject->NumInstances; ++i )
    {
        PerfInstance_t perfInst;
        perfInst.pPerfCounters = PERF_COUNTER_BLOCK_FROM_INSTANCE( pInstance );
        perfInst.pInstance = pInstance;

        GetFullInstanceName(
            pPerfData,
            pInstance,
            pPerfObject->CodePage,
            perfInst.strInstanceName,
            perfInst.strParentInstanceName );

        vecPerfInstances.push_back( perfInst );

        pInstance = NEXT_PERF_INSTANCE_DEFINITION( pInstance );
    }
}
BOOL LoadObjects(
    PPERF_DATA_BLOCK const pPerfDataBlock,
    std::vector<PerfObject_t> & vecPerfObjects )
{
    vecPerfObjects.clear();

    PPERF_OBJECT_TYPE pPerfObject = FIRST_PERF_OBJECT_TYPE( pPerfDataBlock );
    for( DWORD i(0); i < pPerfDataBlock->NumObjectTypes; ++i )
    {
        PerfObject_t perfObj;
        perfObj.pPerfObject = pPerfObject;

        LoadCounterDefs( pPerfObject, perfObj.vecPerfCounterDefs );


        if( pPerfObject->NumInstances == 0 ||
            pPerfObject->NumInstances == PERF_NO_INSTANCES )
        {
            // 没有实例对象
            perfObj.pPerfCounters = PERF_COUNTER_BLOCK_FROM_OBJECT( pPerfObject );
        }
        else
        {
            LoadInstances( pPerfDataBlock, pPerfObject, perfObj.vecPerfInstances );
        }
        vecPerfObjects.push_back( perfObj );

        pPerfObject = NEXT_PERF_OBJECT_TYPE( pPerfObject );
        if( (LPBYTE)pPerfObject >= (LPBYTE)pPerfDataBlock + pPerfDataBlock->TotalByteLength ) break;
    }

    return TRUE;
}

BOOL LoadObjectData(
    PPERF_DATA_BLOCK const pPerfDataBlock,
    PerfData_t & perfData )
{
    if( pPerfDataBlock == NULL ) return FALSE;

    TCHAR szSubKey[0x400] = {0};

    if( !(pPerfDataBlock->Signature[0] == L'P' && 
        pPerfDataBlock->Signature[1] == L'E' &&
        pPerfDataBlock->Signature[2] == L'R' &&
        pPerfDataBlock->Signature[3] == L'F' ) )
    {
        return FALSE;
    }
    
    return LoadObjects( pPerfDataBlock, perfData.vecPerfObjects );
}

DWORD GetNumberOfTextEntries(LPCTSTR lpszSource)
{
    DWORD dwEntries = 0;
    DWORD dwSize = sizeof(DWORD);
    HKEY hKey = NULL;
    do
    {
        LRESULT lResult = RegOpenKeyEx(
            HKEY_LOCAL_MACHINE,
            _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib"),
            0,
            KEY_READ,
            &hKey );
        if( lResult != ERROR_SUCCESS ) break;

        lResult = RegQueryValueEx(
            hKey,
            lpszSource,
            NULL,
            0,
            (LPBYTE)&dwEntries,
            &dwSize );
        if( lResult != ERROR_SUCCESS ) break;

    }while(false);

    if( hKey ) RegCloseKey( hKey );

    return dwEntries;
}

enum ETrafficType               // (查 mapCounters 表可得知)
{
    EAllTraffic      = 388,     // 总的流量
    EIncomingTraffic = 264,     // 输入流量
    EOutGoingTraffic = 506      // 输出流量
};

LSTATUS GetRegDWORDValue( HKEY hRootKey, CString strPath, CString strValueName, DWORD & dwValue )
{
    HKEY hKey;
    LSTATUS lStatus;
    do
    {
        lStatus = RegOpenKey(
            hRootKey,
            strPath,
            &hKey );
        if( lStatus != ERROR_SUCCESS ) break;

        DWORD dwLen = sizeof(DWORD);
        lStatus = RegQueryValueEx(
            hKey,
            strValueName,
            NULL,
            NULL,
            reinterpret_cast<LPBYTE>(&dwValue),
            &dwLen );

    } while (false);

    if( hKey != NULL ) RegCloseKey( hKey );

    return lStatus;
}


LSTATUS GetRegStringValue( HKEY hRootKey, CString strPath, CString strValueName, CString & strValue )
{
    HKEY hKey;
    LSTATUS lStatus;
    do
    {
        lStatus = RegOpenKey(
            hRootKey,
            strPath,
            &hKey );
        if( lStatus != ERROR_SUCCESS ) break;

        DWORD dwMaxValueLen;
        lStatus = RegQueryInfoKey(
            hKey,
            NULL,
            NULL,
            0,
            NULL,
            NULL,
            NULL,
            NULL,
            NULL,
            &dwMaxValueLen,
            NULL,
            NULL );
        if( lStatus != ERROR_SUCCESS ) break;

        lStatus = RegQueryValueEx(
            hKey,
            strValueName,
            NULL,
            NULL,
            reinterpret_cast<LPBYTE>(strValue.GetBuffer( dwMaxValueLen / sizeof(TCHAR) )),
            &dwMaxValueLen );
        strValue.ReleaseBuffer();

    } while (false);

    if( hKey != NULL ) RegCloseKey( hKey );

    return lStatus;
}

void FixInstanceName( std::tstring & name )
{
    name = boost::xpressive::regex_replace(
        name,
        boost::xpressive::basic_regex<std::tstring::const_iterator>::compile( _T("\\W") ),
        _T("") );
    boost::erase_all( name, _T("_") );
}
LSTATUS GetApaptersIsHardwareList( std::map<std::tstring, BOOL> & map )
{
    map.clear();

    LSTATUS lStatus = 0;
    HKEY hKey = NULL;
    do
    {
        CString strRootPath = _T("SYSTEM\\ControlSet001\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}");
        // 打开适配器的注册表路径
        lStatus = RegOpenKey(
            HKEY_LOCAL_MACHINE,
            strRootPath,
            &hKey );
        if( lStatus != ERROR_SUCCESS ) break;
        
        // 获得子键数目和子值最大字节数
        DWORD dwSubKeys;
        DWORD dwMaxKeyNameLen;
        lStatus = RegQueryInfoKey(
            hKey,
            NULL,
            NULL,
            0,
            &dwSubKeys,
            &dwMaxKeyNameLen,
            NULL,
            NULL,
            NULL,
            NULL,
            NULL,
            NULL );
        if( lStatus != ERROR_SUCCESS ) break;

        for( DWORD i(0); i < dwSubKeys; ++i )
        {
            CString strSubKeyName;
            lStatus = RegEnumKey(
                hKey,
                i,
                strSubKeyName.GetBuffer( dwMaxKeyNameLen ),
                dwMaxKeyNameLen );
            strSubKeyName.ReleaseBuffer();
            if( lStatus != ERROR_SUCCESS ) break;

            CString strAdapterPath = (strRootPath + CString(_T("\\")) + strSubKeyName);

            /*
            // 方法一: 获得 DeviceInstanceId
            CString strDeviceInstanceId;
            lStatus = GetRegStringValue( HKEY_LOCAL_MACHINE, strAdapterPath, _T("DeviceInstanceID"), strDeviceInstanceId );
            if( lStatus != ERROR_SUCCESS ) break;
            */
            
            // 方法一: 获得 Characteristics
            DWORD dwCharacteristics;
            lStatus = GetRegDWORDValue( HKEY_LOCAL_MACHINE, strAdapterPath, _T("Characteristics"), dwCharacteristics );
            if( lStatus != ERROR_SUCCESS ) break;

            // 获得驱动描述
            CString strDriverDesc;
            lStatus = GetRegStringValue( HKEY_LOCAL_MACHINE, strAdapterPath, _T("DriverDesc"), strDriverDesc );
            if( lStatus == ERROR_SUCCESS )
            {
                std::tstring tsDriverDesc = strDriverDesc;
                FixInstanceName( tsDriverDesc );
                /*
                // 方法一: 如果 DeviceInstanceId 是以 USB\\ 或 PCI\\ 开头的, 则认为其为物理适配器
                map[tsDriverDesc] =
                    ( strDeviceInstanceId.Left( 4 ).CompareNoCase(_T("USB\\")) == 0 ||
                    strDeviceInstanceId.Left( 4 ).CompareNoCase(_T("PCI\\")) == 0 );
                    */
                // 方法二: 判断 Characteristics(特征) 中是否含有 NCF_PHYSICAL 标志
                map[tsDriverDesc] = ( dwCharacteristics & 0x4 );       // NCF_PHYSICAL
            }
        }
    }while(false);

    return lStatus;
}

void PrintObjectNames(
    std::basic_ostream<TCHAR, std::char_traits<TCHAR> > & os,
    const PerfData_t & perfData,
    const std::map<DWORD, CString> & mapCounters,
    const std::map<DWORD, CString> & mapHelps )
{
    typedef boost::basic_format<TCHAR> format_t;
    typedef std::map< DWORD, DWORD > map_traffics_t;
    typedef std::map<std::tstring, map_traffics_t > map_inst_traffics_t;
    static map_inst_traffics_t map_inst_traffics;                       // 用于保存上一次的流量数据
    for( size_t i = 0; i < perfData.vecPerfObjects.size(); ++i )
    {
        const PerfObject_t & perfObject = perfData.vecPerfObjects[i];
        DWORD dwIndex = perfObject.pPerfObject->ObjectNameTitleIndex;
        
        DWORD dwTotalIn = 0, dwTotalOut = 0;
        if( perfObject.vecPerfInstances.size() == 0 )
        {
            // 如果不是网络适配器(不同的协议种类),那么就不统计
            continue;
        }
        else
        {
            for( size_t j = 0; j < perfObject.vecPerfInstances.size(); ++j )
            {
                std::tstring strInstanceName = perfObject.vecPerfInstances[j].strInstanceName;
                FixInstanceName( strInstanceName );
                // 修正名字(耗资源)

                os << format_t( _T("%1%(%2%)\n") )
                    % perfObject.vecPerfInstances[j].strParentInstanceName.GetString()
                    % perfObject.vecPerfInstances[j].strInstanceName.GetString();
                BOOL bIsPhysicalAdapter = FALSE;
                auto iterPhy = g_mapPhys.find( strInstanceName );
                if( iterPhy != g_mapPhys.end() )
                {
                    bIsPhysicalAdapter = iterPhy->second;
                }
        
                PPERF_COUNTER_BLOCK pPerfCounter = perfObject.vecPerfInstances[j].pPerfCounters;
                DWORD dwAllTraffic = 0, dwIncomingTraffic = 0, dwOutGoingTraffic = 0;

                for( size_t k = 0; k < perfObject.vecPerfCounterDefs.size(); ++k )
                {
                    DWORD dwCounterVal = GET_COUNTER_VALUE_DWORD( pPerfCounter, perfObject.vecPerfCounterDefs[k] );
                    dwIndex = perfObject.vecPerfCounterDefs[k]->CounterNameTitleIndex;
                    switch( dwIndex )
                    {
                    case EAllTraffic: dwAllTraffic = dwCounterVal; break;
                    case EIncomingTraffic: dwIncomingTraffic = dwCounterVal; break;
                    case EOutGoingTraffic: dwOutGoingTraffic = dwCounterVal; break;
                    }
                }

                if( map_inst_traffics.count(strInstanceName ) )
                {
                    if( map_inst_traffics[strInstanceName].size() != 0 )
                    {
                        DWORD dwIn = dwIncomingTraffic - map_inst_traffics[strInstanceName].at(EIncomingTraffic);
                        DWORD dwOut = dwOutGoingTraffic - map_inst_traffics[strInstanceName].at(EOutGoingTraffic);
                        if( bIsPhysicalAdapter )
                        {
                            dwTotalIn += dwIn;
                            dwTotalOut += dwOut;
                        }
                        format_t fmt( _T("  | %s:%|.2f| KB/S - %s:%|.2f| KB/S\n") );
                        fmt % mapCounters.at(EIncomingTraffic).GetString()
                            % ( dwIn / 1024.0f )
                            % mapCounters.at(EOutGoingTraffic).GetString()
                            % ( dwOut / 1024.0f );
                        os << fmt.str();
                    }
                }
                
                map_traffics_t map_traffics;
                map_traffics[EAllTraffic] = dwAllTraffic;
                map_traffics[EIncomingTraffic] = dwIncomingTraffic;
                map_traffics[EOutGoingTraffic] = dwOutGoingTraffic;
                map_inst_traffics[strInstanceName] = map_traffics;
            }
        }

        // 总流量*
        os << _T(" ==== Total ==== ") << std::endl;
        format_t fmt( _T("  | %s:%|.2f| KB/S - %s:%|.2f| KB/S\n") );
        fmt % mapCounters.at(EIncomingTraffic).GetString()
            % ( dwTotalIn / 1024.0f )
            % mapCounters.at(EOutGoingTraffic).GetString()
            % ( dwTotalOut / 1024.0f );
        os << fmt.str();
    }
}

int _tmain()
{
    setlocale(LC_ALL,"");
    // 获得计数器名字和帮助
    GetCounters( g_mapCounters );
    GetHelps( g_mapHelps );

    GetApaptersIsHardwareList( g_mapPhys );

    while( true )
    {
        std::vector<BYTE> vecPerfDataBlock = GetRegValueData(510);
        PPERF_DATA_BLOCK pPerfDataBlock = (PPERF_DATA_BLOCK)vecPerfDataBlock.data();
    
        std::list<PERF_OBJECT_TYPE> vecRefObjType;
        EnumPerfObject( (PPERF_DATA_BLOCK)vecPerfDataBlock.data(), vecRefObjType );
    
        PerfData_t perfData;
        LoadObjectData( pPerfDataBlock, perfData );

        PrintObjectNames( 
#ifdef UNICODE
            std::wcout
#else
            std::cout
#endif
            , perfData, g_mapCounters, g_mapHelps );
        Sleep(1000);
        system("cls");
    }

    getchar();
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值