⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 alexfperf.cpp

📁 Visual C++ 网络通信编程实用案例精选 的配套光盘
💻 CPP
字号:
///////////////////////////////////////////////////////////////////////
// If this program works, it was written by Alexander Fedorov.
// If not, I don't know who wrote it.
// mailto:lamer2000@hotmail.com
// Home Page: http://members.xoom.com/lamer2000/
// This file is part of Alexf Dialer.
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
///////////////////////////////////////////////////////////////////////

// AlexfPerf.cpp: implementation of the CAlexfPerf class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "AlexfPerf.h"
#include <WINPERF.H>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// CAlexfPerf95 - class to receive performance stats under '95-98
//////////////////////////////////////////////////////////////////////

CAlexfPerf95::CAlexfPerf95(LPCTSTR pszObjName, LPCTSTR pszCounterName, LPCTSTR pszComputerName)
{
	m_bSuccess = FALSE;
	//Open up the HKEY_DYN_DATA key on the specified machine
	HKEY hKeyDynData;
	DWORD dwConnect;
	if (pszComputerName)
	{
		TCHAR pszComputer[_MAX_PATH];
		_tcscpy(pszComputer, pszComputerName);
		dwConnect = RegConnectRegistry(pszComputer, HKEY_DYN_DATA, &hKeyDynData);
	}
	else
		dwConnect = RegConnectRegistry(NULL, HKEY_DYN_DATA, &hKeyDynData);
	if (dwConnect != ERROR_SUCCESS) return;
	//Open the "HKEY_DYN_DATA\PerfStats\StartStat" registry key
	HKEY hOpen;
	if (RegOpenKeyEx(hKeyDynData, _T("PerfStats\\StartStat"), 0, KEY_READ, &hOpen) != ERROR_SUCCESS)
	{RegCloseKey(hKeyDynData); return;}
	//Query to get data size
	DWORD dwType;
	DWORD cbData;
	//Form the counter name which we are querying
	CString sCounterName;
	sCounterName.Format(_T("%s\\%s"), pszObjName, pszCounterName);
	if (ERROR_SUCCESS == RegQueryValueEx(hOpen, sCounterName, NULL, &dwType, NULL, &cbData))
	{
		//Query the performance start key to initialise the performace data
		BYTE* pByte = new BYTE[cbData];
		if (pByte)
		{
			m_bSuccess = (ERROR_SUCCESS == RegQueryValueEx(hOpen, sCounterName, NULL, &dwType, pByte, &cbData));
			//Remember the name of the computer we want
			m_sComputerName = pszComputerName;
			//Remember the name of the counter we want
			m_sCounterName = sCounterName;
			//Don't forget to delete the bit of memory we allocated
			delete [] pByte;
		}
	}
	//Don't forget to close the registry key
	RegCloseKey(hOpen);
	//Don't forget to close the registry key
	RegCloseKey(hKeyDynData);
}

CAlexfPerf95::~CAlexfPerf95()
{
	m_bSuccess = FALSE;
	//Handle calling StopCollecting twice
	if (m_sCounterName.IsEmpty()) return;
	//Open up the HKEY_DYN_DATA key on the specified machine
	HKEY hKeyDynData, hOpen;
	LPTSTR pszComputerName = m_sComputerName.GetBuffer(m_sComputerName.GetLength());
	DWORD dwConnect = RegConnectRegistry(pszComputerName, HKEY_DYN_DATA, &hKeyDynData);
	m_sComputerName.ReleaseBuffer();
	if (dwConnect != ERROR_SUCCESS) return;
	//Open the "HKEY_DYN_DATA\PerfStats\StopStat" registry key
	if (RegOpenKeyEx(hKeyDynData, _T("PerfStats\\StopStat"), 0, KEY_READ, &hOpen) != ERROR_SUCCESS)
	{RegCloseKey(hKeyDynData); return;}
	//Query to get data size
	DWORD dwType;
	DWORD cbData;
	if (RegQueryValueEx(hOpen, m_sCounterName, NULL, &dwType, NULL, &cbData) != ERROR_SUCCESS)
	{RegCloseKey(hKeyDynData); RegCloseKey(hOpen); return;}
	//Query the performance stop key to disable collection of performace data
	BYTE* pByte = new BYTE[cbData];
	if (pByte)
	{
		RegQueryValueEx(hOpen, m_sCounterName, NULL, &dwType, pByte, &cbData);
		delete [] pByte;
	}
	//Don't forget to close the registry key
	RegCloseKey(hOpen);
	RegCloseKey(hKeyDynData);
	m_sCounterName.Empty();
}

//接收数据统计
BOOL CAlexfPerf95::Collect(DWORD& dwData)
{
	if (!m_bSuccess) return FALSE;
	m_bSuccess = FALSE;
	ASSERT(m_sCounterName.GetLength()); //did you forget to call Start
	//打开注册表项HKEY_DYN_DATA
	HKEY hKeyDynData, hOpen;
	LPTSTR pszComputerName = m_sComputerName.GetBuffer(m_sComputerName.GetLength());
	DWORD dwConnect = RegConnectRegistry(pszComputerName, HKEY_DYN_DATA, &hKeyDynData);
	m_sComputerName.ReleaseBuffer();
	if (dwConnect != ERROR_SUCCESS) return FALSE;
	//打开注册表"HKEY_DYN_DATA\PerfStats\StatData"
	if (RegOpenKeyEx(hKeyDynData, _T("PerfStats\\StatData"), 0, KEY_READ, &hOpen) != ERROR_SUCCESS)
	//关闭注册表
	{RegCloseKey(hKeyDynData); return FALSE;}
	//获得数据
	DWORD dwType = REG_BINARY;
	DWORD cbData = 4;
	m_bSuccess = TRUE;

	if (RegQueryValueEx(hOpen, m_sCounterName, NULL, &dwType,
	(LPBYTE) &dwData, &cbData) != ERROR_SUCCESS) m_bSuccess = FALSE;
	RegCloseKey(hOpen);
	RegCloseKey(hKeyDynData);
	return m_bSuccess;
}

DWORD CAlexfPerf95::GetData()
{
	DWORD dw = 0;
	if (!m_bSuccess) return dw;
	Collect(dw);
	return dw;
}

//////////////////////////////////////////////////////////////////////
// CAlexfPerfNT - class to receive performance stats under NT
//////////////////////////////////////////////////////////////////////

#define Key "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\009"

CAlexfPerfNT::	CAlexfPerfNT(LPCTSTR pszObjName, LPCTSTR pszCounterName, LPCTSTR pszComputerName)
{
	m_bSuccess = FALSE;
	BOOL b = GetIndex(pszObjName, m_SObj.GetBuffer(512));
	m_SObj.ReleaseBuffer();
	if (!b) return;
	if (m_SObj.IsEmpty()) return;
	b = GetIndex(pszCounterName, m_sCounter.GetBuffer(512));
	m_sCounter.ReleaseBuffer();
	if (!b) return;
	if (m_sCounter.IsEmpty()) return;
	m_bSuccess = TRUE;
}

CAlexfPerfNT::~CAlexfPerfNT()
{

}

BOOL CAlexfPerfNT::Collect(DWORD& dwData)
{
	if (!m_bSuccess) return FALSE;
	DWORD dwBytes = 12000;
	DWORD dwCounterIdOffset = 0;
	PPERF_DATA_BLOCK pdb;
	PPERF_OBJECT_TYPE pot;
	PPERF_COUNTER_DEFINITION pcd;
	PPERF_INSTANCE_DEFINITION pid;
	// 为PPERF_DATA_BLOCK申请空间.
	pdb = (PPERF_DATA_BLOCK) HeapAlloc(GetProcessHeap(),
	HEAP_ZERO_MEMORY, dwBytes);
	// Get performance data.
	//RegQueryValueEx获得特定注册表项的的键值以及类型,函数结构如下:
	/*LONG RegQueryValueEx(
	HKEY hKey,            // handle to key
	LPCTSTR lpValueName,  // 值名称
	LPDWORD lpReserved,   // 保留
	LPDWORD lpType,       // 类型
	LPBYTE lpData,        // 数据
	LPDWORD lpcbData      // 数据缓冲大小
	);*/

	while(ERROR_MORE_DATA == RegQueryValueEx(HKEY_PERFORMANCE_DATA, m_SObj, NULL,
	NULL, (LPBYTE)pdb, &dwBytes))
	{
		// 增加缓冲.
		dwBytes += 1000;
		// 重新申请
		pdb = (PPERF_DATA_BLOCK) HeapReAlloc(GetProcessHeap(),
		HEAP_ZERO_MEMORY, (LPVOID)pdb, dwBytes);
	}
	//获得对象类型PERF_OBJECT_TYPE.
	pot = (PPERF_OBJECT_TYPE)((PBYTE)pdb + pdb->HeaderLength);
	// 获得第一个计数器类型.
	pcd = (PPERF_COUNTER_DEFINITION)((PBYTE)pot + pot->HeaderLength);
	for(int i=0; i< (int)pot->NumCounters; i++)
	{
		if (pcd->CounterNameTitleIndex == (DWORD)atoi(m_sCounter))
		{
			dwCounterIdOffset = pcd->CounterOffset;
			break;
		}
		pcd = ((PPERF_COUNTER_DEFINITION)((PBYTE)pcd + pcd->ByteLength));
	}
	// 获得该对象的第一个实例
	pid = (PPERF_INSTANCE_DEFINITION)((PBYTE)pot + pot->DefinitionLength);
	// 获得信息
	dwData = *((DWORD *) ((PBYTE)pid + dwCounterIdOffset));
	// 释放空间
	if(!HeapFree(GetProcessHeap(), 0, (LPVOID)pdb)) m_bSuccess = FALSE;
	// 关闭注册表
	RegCloseKey(HKEY_PERFORMANCE_DATA);
	return TRUE;
}

BOOL CAlexfPerfNT::GetIndex(const char * pszCounter, char * szIndex)
{
	char*  pszBuffer;
	char*  pszTemp;
	char   szObject[256] = "";
	DWORD  dwBytes;
	HKEY hKeyIndex;
	int i = 0;
	int j = 0;
	// 打开注册表
	RegOpenKeyEx(HKEY_LOCAL_MACHINE, Key, 0, KEY_READ, &hKeyIndex);
	//获得Counter的大小
	RegQueryValueEx(hKeyIndex, "Counter", NULL, NULL, NULL, &dwBytes);
	// 申请空间
	pszBuffer = (char *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytes);
	if (!pszBuffer) {RegCloseKey(hKeyIndex); return FALSE;}
	// 获得标题和计数器
	RegQueryValueEx(hKeyIndex, "Counter", NULL, NULL, (LPBYTE)pszBuffer, &dwBytes);
	// 获得索引值
	pszTemp = pszBuffer;
	while (i != (int)dwBytes)
	{
		while (*(pszTemp+i) != '\0')
		{
			szIndex[j] = *(pszTemp+i);
			i++;
			j++;
		}
		szIndex[j] = '\0';
		i++;
		j = 0;
		while (*(pszTemp+i) != '\0')
		{
			szObject[j] = *(pszTemp+i);
			i++;
			j++;
		}
		szObject[j] = '\0';
		i++;
		j = 0;
		if ('\0' == *(pszTemp+i))
		i++;
		if (0 == strcmp(szObject, pszCounter)) break;
	}
	// 释放空间
	HeapFree(GetProcessHeap(), 0, (LPVOID)pszBuffer);
	// 关闭注册表
	RegCloseKey(hKeyIndex);
	return TRUE;
}


//////////////////////////////////////////////////////////////////////
// CAlexfPerf - class to receive performance stats
//////////////////////////////////////////////////////////////////////

CAlexfPerf::CAlexfPerf(int iPerfType)
{
	m_p95 = NULL;
	m_pNT = NULL;
	m_bSuccess = FALSE;
	m_iPerfType = iPerfType;
	// check os version
	OSVERSIONINFO OSVersionInfo;
	OSVersionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
	GetVersionEx(&OSVersionInfo);
	if (VER_PLATFORM_WIN32_NT == OSVersionInfo.dwPlatformId)
	{
		m_bSuccess = bInitNT(iPerfType);
	}
    else
	{
		m_bSuccess = bInit95(iPerfType);
	}
}

CAlexfPerf::~CAlexfPerf()
{
	if (m_p95) delete m_p95;
	if (m_pNT) delete m_pNT;
}

BOOL CAlexfPerf::bInit95(int iPerfType)
{
	CString sAdapterName;
	CString sss;
	for (int i = 0; i < 10; i++)
	{
		sprintf(sss.GetBuffer(512), "%04ld", i); sss.ReleaseBuffer();
		sAdapterName = GetRegKey(HKEY_LOCAL_MACHINE,
		"System\\CurrentControlSet\\Services\\Class\\Net\\" + sss,
		"AdapterName");
		if (sAdapterName == "MS$PPP") break;
	}
	if (sAdapterName != "MS$PPP") return FALSE;
	sAdapterName = GetRegKey(HKEY_LOCAL_MACHINE,
	"System\\CurrentControlSet\\Services\\Class\\Net\\" + sss,
	"DriverDesc");
	switch (iPerfType)
	{
	case ALEXF_PERF_DIALUP_CONNECTSPEED:
		m_p95 = new CAlexfPerf95(sAdapterName, "ConnectSpeed"); break;
	case ALEXF_PERF_DIALUP_BYTESRECVD:
		m_p95 = new CAlexfPerf95(sAdapterName, "BytesRecvd"); break;
	case ALEXF_PERF_DIALUP_BYTESXMIT:
		m_p95 = new CAlexfPerf95(sAdapterName, "BytesXmit"); break;
	default:
		return FALSE;
	}
	return m_p95->IsOK();
}

BOOL CAlexfPerf::bInitNT(int iPerfType)
{
	switch (iPerfType)
	{
	case ALEXF_PERF_DIALUP_CONNECTSPEED:
		m_pNT = new CAlexfPerfNT("RAS Total", "Total Connections"); break;
	case ALEXF_PERF_DIALUP_BYTESRECVD:
		m_pNT = new CAlexfPerfNT("RAS Total", "Bytes Received"); break;
	case ALEXF_PERF_DIALUP_BYTESXMIT:
		m_pNT = new CAlexfPerfNT("RAS Total", "Bytes Transmitted"); break;
	default:
		return FALSE;
	}
	return m_pNT->IsOK();
}

BOOL CAlexfPerf::Collect(DWORD& dwData)
{
	if (!m_bSuccess) return FALSE;
	if (m_p95) m_bSuccess = m_p95->Collect(dwData);
	if (m_pNT)
	{
		// temporary!!!
		if (ALEXF_PERF_DIALUP_CONNECTSPEED == m_iPerfType)
		dwData = 33600;
		else
		m_bSuccess = m_pNT->Collect(dwData);
	}
	return m_bSuccess;
}

DWORD CAlexfPerf::GetData()
{
	DWORD dw = 0;
	if (!m_bSuccess) return dw;
	Collect(dw);
	return dw;
}

CString CAlexfPerf::GetRegKey(HKEY hOpen, CString key1,CString key2)
{
	CString sss;
	HKEY hkey;
	LONG l = RegOpenKeyEx(hOpen, key1, 0, KEY_READ, &hkey);
	if (l != ERROR_SUCCESS) return sss;
	ULONG LS = _MAX_PATH;
	DWORD lpType = REG_EXPAND_SZ;
	l = RegQueryValueEx(hkey, key2, NULL,
	& lpType, (unsigned char *) sss.GetBuffer(LS), & LS);
	sss.ReleaseBuffer();
	RegCloseKey(hkey);
	if (l != ERROR_SUCCESS) sss.Empty();
	return sss;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -