www.pudn.com > afdialer_src.rar > AlexfPerf.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#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 //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 FALSE; //Open up the "HKEY_DYN_DATA\PerfStats\StatData" key if (RegOpenKeyEx(hKeyDynData, _T("PerfStats\\StatData"), 0, KEY_READ, &hOpen) != ERROR_SUCCESS) {RegCloseKey(hKeyDynData); return FALSE;} //Query the specifed key for the data 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; // Get memory for PPERF_DATA_BLOCK. pdb = (PPERF_DATA_BLOCK) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytes); // Get performance data. while(ERROR_MORE_DATA == RegQueryValueEx(HKEY_PERFORMANCE_DATA, m_SObj, NULL, NULL, (LPBYTE)pdb, &dwBytes)) { // Increase memory. dwBytes += 1000; // Allocated memory is too small; reallocate new memory. pdb = (PPERF_DATA_BLOCK) HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (LPVOID)pdb, dwBytes); } // Get PERF_OBJECT_TYPE. pot = (PPERF_OBJECT_TYPE)((PBYTE)pdb + pdb->HeaderLength); // Get the first counter definition. 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)); } // Get the first instance of the object. pid = (PPERF_INSTANCE_DEFINITION)((PBYTE)pot + pot->DefinitionLength); // COLLECT INFO dwData = *((DWORD *) ((PBYTE)pid + dwCounterIdOffset)); // Free the allocated memory. if(!HeapFree(GetProcessHeap(), 0, (LPVOID)pdb)) m_bSuccess = FALSE; // Close handle to the key. 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; // Open the key. RegOpenKeyEx(HKEY_LOCAL_MACHINE, Key, 0, KEY_READ, &hKeyIndex); // Get the size of the counter. RegQueryValueEx(hKeyIndex, "Counter", NULL, NULL, NULL, &dwBytes); // Allocate memory for the buffer. pszBuffer = (char *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytes); if (!pszBuffer) {RegCloseKey(hKeyIndex); return FALSE;} // Get the titles and counters. RegQueryValueEx(hKeyIndex, "Counter", NULL, NULL, (LPBYTE)pszBuffer, &dwBytes); // Find the index value 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; } // Deallocate the memory. HeapFree(GetProcessHeap(), 0, (LPVOID)pszBuffer); // Close the key. 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; }