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

📄 prfdata.cpp

📁 ftpserver very good sample
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/********************************************************************Module name: PrfData.cppNotices: Written 1998 by Jeffrey RichterDescription: C++ template classes for Performance Object data types.********************************************************************///#include "CmnHdr.h"#include "StdAfx.h"#include "PrfData.h"//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Helper function that finds a set of bytes in a memory blockPBYTE FindMemory(PBYTE pbBuf, DWORD cbBuf,    PBYTE pbSearchBytes, DWORD cbSearchBytes) {   for (DWORD n = 0; n < (cbBuf - cbSearchBytes); n++) {      if (pbBuf[n] == pbSearchBytes[0]) {         for (DWORD x = 1; x < cbSearchBytes; x++) {            if (pbBuf[n + x] != pbSearchBytes[x])                break; // Not a match         }         if (x == cbSearchBytes) return(&pbBuf[n]); // Match!      }   }   return(NULL);  // Not found at all}/////////////////////////////////////////////////////////////////////// Address of the ONE instance of this class (See Collect)//CPrfData* CPrfData::sm_pPrfData = NULL;/////////////////////////////////////////////////////////////////////// Constructor: initializes member variables CPrfData::CPrfData(LPCWSTR pszAppName, PPRFITM pPrfItms) :   m_pszAppName(pszAppName), m_pPrfItms(pPrfItms),    m_nNumPrfItems(0),        m_nNumObjects(0),            m_pPrfData(NULL),         m_hfm(NULL),   m_dwFirstCounter(0),      m_dwLastCounter(0),   m_dwFirstHelp(1),         m_dwLastHelp(1),   m_Optex(pszAppName, 4000),m_bIsActive(false) {   chASSERT(sm_pPrfData == NULL);  // Only one instance can exist   sm_pPrfData = this;	// Sanity check performance data object/counter map   VerifyPrfItemTable();}/////////////////////////////////////////////////////////////////////   // DestructorCPrfData::~CPrfData() {   if (m_pPrfData != NULL)       UnmapViewOfFile(m_pPrfData);   if (m_hfm != NULL)       CloseHandle(m_hfm);}/////////////////////////////////////////////////////////////////////// Installs performance object/counter map info into registryvoid CPrfData::InstallPrfData(LPCWSTR pszDllPathname) {   DWORD dwLastCounter = 0, dwLastHelp = 1;   // Read the last counter/help global values from the registry   CRegSettings regPerfLib, regApp;   chVERIFY(ERROR_SUCCESS ==       regPerfLib.OpenSubkey(FALSE, HKEY_LOCAL_MACHINE,       L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib"));   regPerfLib.GetDWORD(L"Last Counter", &dwLastCounter);    regPerfLib.GetDWORD(L"Last Help",    &dwLastHelp);    // Read the first/last counter/help app values from the registry   WCHAR szSubkey[100];   wsprintfW(szSubkey,       L"SYSTEM\\CurrentControlSet\\Services\\%s\\Performance",       m_pszAppName);   chVERIFY(ERROR_SUCCESS ==       regApp.OpenSubkey(FALSE, HKEY_LOCAL_MACHINE, szSubkey));	// Advance to the next counter / help   m_dwFirstCounter = m_dwLastCounter = dwLastCounter + 2;   m_dwFirstHelp    = m_dwLastHelp    = dwLastHelp + 2;   // Install our counters into the registry   AppendRegStrings(regPerfLib, TRUE,  &m_dwLastCounter);   AppendRegStrings(regPerfLib, FALSE, &m_dwLastHelp);   // Tell the registry where the next set of counter can go   regPerfLib.SetDWORD(L"Last Counter", m_dwLastCounter);    regPerfLib.SetDWORD(L"Last Help", m_dwLastHelp);    // Save the installation results for our app   regApp.SetString(L"Library",       pszDllPathname);    regApp.SetString(L"Open",          L"PrfData_Open");    regApp.SetString(L"Close",         L"PrfData_Close");    regApp.SetString(L"Collect",       L"PrfData_Collect");    regApp.SetDWORD (L"First Counter", m_dwFirstCounter);    regApp.SetDWORD (L"First Help",    m_dwFirstHelp);    regApp.SetDWORD (L"Last Counter",  m_dwLastCounter);    regApp.SetDWORD (L"Last Help",     m_dwLastHelp); }/////////////////////////////////////////////////////////////////////// Takes this app's performance info out of the registryvoid CPrfData::UninstallPrfData() {   // Read the last counter/help global values from the registry   CRegSettings regPerfLib, regApp;   chVERIFY(ERROR_SUCCESS ==       regPerfLib.OpenSubkey(FALSE, HKEY_LOCAL_MACHINE,       L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib"));   DWORD dwLastCounter = 0, dwLastHelp = 1;   regPerfLib.GetDWORD(L"Last Counter", &dwLastCounter);    regPerfLib.GetDWORD(L"Last Help",    &dwLastHelp);    // Read the first/last counter/help app values from the registry   WCHAR szSubkey[100];   wsprintfW(szSubkey,       L"SYSTEM\\CurrentControlSet\\Services\\%s\\Performance",       m_pszAppName);   if(ERROR_SUCCESS != regApp.OpenSubkey(TRUE, HKEY_LOCAL_MACHINE, szSubkey))   {       regApp.CloseKey();        return; // Not installed   }   regApp.CloseKey();    if (ERROR_SUCCESS ==        regApp.OpenSubkey(FALSE, HKEY_LOCAL_MACHINE, szSubkey))   {       regApp.GetDWORD(L"First Counter", &m_dwFirstCounter);        regApp.GetDWORD(L"First Help",    &m_dwFirstHelp);        regApp.GetDWORD(L"Last Counter",  &m_dwLastCounter);        regApp.GetDWORD(L"Last Help",     &m_dwLastHelp);       PIINDEX num_items = (m_dwLastCounter - m_dwFirstCounter) / 2 + 1;       if (num_items == m_nNumPrfItems)       {           // Only do sanity check when the number of items match.           // Else, installing of removing counters will be non-trivial           chASSERT((DWORD) m_nNumPrfItems ==               (m_dwLastCounter - m_dwFirstCounter) / 2 + 1);           chASSERT((DWORD) m_nNumPrfItems ==                (m_dwLastHelp - m_dwFirstHelp) / 2 + 1);           chASSERT((m_dwFirstCounter <= m_dwLastCounter) &&                (m_dwFirstHelp <= m_dwLastHelp));           chASSERT((m_dwLastCounter <= dwLastCounter) &&                (m_dwLastHelp <= dwLastHelp));       }              // Remove the strings from the registry       RemoveRegStrings(regPerfLib, TRUE,             m_dwFirstCounter, m_dwLastCounter);       RemoveRegStrings(regPerfLib, FALSE,            m_dwFirstHelp, m_dwLastHelp);              // If these counters are the last in, truncate the end       // otherwise we leave a gap in the performance counter numbers       if (m_dwLastCounter == dwLastCounter) {           dwLastCounter -= (int) num_items * 2;           dwLastHelp    -= (int) num_items * 2;           regPerfLib.SetDWORD(L"Last Counter", dwLastCounter);            regPerfLib.SetDWORD(L"Last Help", dwLastHelp);        }   }      // Delete the app's registry key   regApp.CloseKey();    ::RegDeleteKeyW(HKEY_LOCAL_MACHINE, szSubkey);}/////////////////////////////////////////////////////////////////////// Appends our performance object/counter text/help in the registryvoid CPrfData::AppendRegStrings(CRegSettings& regPerfLib,    BOOL fCounter, PDWORD pdwIndex) {   // Calculate the number of required for the stuff we want to add   DWORD cbInc = 0;   for (PIINDEX pii = 0; m_pPrfItms[pii].pit != PIT_END; pii++) {      cbInc += (6 + 1) * sizeof(WCHAR); // 6 digit index plus 0-char      cbInc += (lstrlenW(fCounter ? m_pPrfItms[pii].pszName          : m_pPrfItms[pii].pszHelp) + 1) * sizeof(WCHAR);   }   // Allocate buffer big enough for original + new data & read it in   CRegSettings regLang(FALSE, regPerfLib, L"009");   LPCWSTR pszValue = fCounter ? L"Counter" : L"Help";   DWORD cbOrig = 0;   regLang.GetSize(pszValue, &cbOrig);   LPWSTR psz = (LPWSTR)       HeapAlloc(GetProcessHeap(), 0, cbOrig + cbInc);   regLang.GetMultiString(pszValue, psz, cbOrig);    // Append our new stuff to the end of the buffer   // Subtract 1 for extra terminating 0 char   LPWSTR pszInc = (LPWSTR) ((PBYTE) psz + cbOrig) - 1;     // Append our strings   for (pii = 0; m_pPrfItms[pii].pit != PIT_END; pii++) {      LPCWSTR psz = fCounter ? m_pPrfItms[pii].pszName          : m_pPrfItms[pii].pszHelp;      lstrcpyW(pszInc +=          wsprintfW(pszInc, L"%d", *pdwIndex) + 1, psz);      pszInc += lstrlenW(psz) + 1;      *pdwIndex += 2;   // Always increment the number by 2   }   *pdwIndex -= 2;   *pszInc++ = 0;   // Append extra terminating 0-char   regLang.SetMultiString(pszValue, psz);    HeapFree(GetProcessHeap(), 0, psz);}/////////////////////////////////////////////////////////////////////// Remove the object/counter strings from the registryvoid CPrfData::RemoveRegStrings(CRegSettings& regPerfLib,    BOOL fCounter, DWORD dwIndexLo, DWORD dwIndexHi) {   // Allocate buffer big enough for original data & read it in   CRegSettings regLang(FALSE, regPerfLib, L"009");   LPCWSTR pszValue = fCounter ? L"Counter" : L"Help";   DWORD cbOrig = 0;   regLang.GetSize(pszValue, &cbOrig);   LPWSTR psz = (LPWSTR) HeapAlloc(GetProcessHeap(), 0, cbOrig);   regLang.GetMultiString(pszValue, psz, cbOrig);    // Find the bounds of what we want to remove   WCHAR szNum[10] = { 0 };   // Look for \0#\0   wsprintfW(&szNum[1], L"%d", dwIndexLo);   PBYTE pbLo = FindMemory((PBYTE) psz, cbOrig,       (PBYTE) szNum, sizeof(WCHAR) * (lstrlenW(&szNum[1]) + 2));   pbLo += sizeof(WCHAR);  // 1st byte of stuff to remove   wsprintfW(&szNum[1], L"%d", dwIndexHi);   PBYTE pbHi = FindMemory((PBYTE) psz, cbOrig,       (PBYTE) szNum, sizeof(WCHAR) * (lstrlenW(&szNum[1]) + 2));   pbHi += sizeof(WCHAR);  // 1st byte of last counter to remove   // Skip over number and text   pbHi += (lstrlenW((LPCWSTR) pbHi) + 1) * sizeof(WCHAR);    pbHi += (lstrlenW((LPCWSTR) pbHi) + 1) * sizeof(WCHAR);   // Shift the strings to keep down over the stuff to delete   chASSERT(pbLo <= pbHi);   MoveMemory(pbLo, pbHi, ((PBYTE) psz + cbOrig) - pbHi);   // Save the updated string information   regLang.SetMultiString(pszValue, psz);    HeapFree(GetProcessHeap(), 0, psz);}/////////////////////////////////////////////////////////////////////// Creates the shared memory region for the performance informationDWORD CPrfData::ActivatePrfData() {   // Read the first/last object/counter text/help values   WCHAR szSubkey[100];   wsprintfW(szSubkey,       L"SYSTEM\\CurrentControlSet\\Services\\%s\\Performance",       m_pszAppName);   CRegSettings regApp(TRUE, HKEY_LOCAL_MACHINE, szSubkey);   regApp.GetDWORD(L"First Counter", &m_dwFirstCounter);    regApp.GetDWORD(L"First Help",    &m_dwFirstHelp);    regApp.GetDWORD(L"Last Counter",  &m_dwLastCounter);    regApp.GetDWORD(L"Last Help",     &m_dwLastHelp);    // Do sanity checks   chASSERT((DWORD) m_nNumPrfItems ==       (m_dwLastCounter - m_dwFirstCounter) / 2 + 1);   chASSERT((DWORD) m_nNumPrfItems ==       (m_dwLastHelp - m_dwFirstHelp) / 2 + 1);   chASSERT(m_pPrfData == NULL);   // This can only be done once   // Calculate how many bytes are needed for the shared memory   DWORD cbBytesNeededForAllObjs = 0;   for (OBJORD ObjOrd = 0; ObjOrd < (OBJORD) m_nNumObjects; ObjOrd++) {      PRFMETRICS pm;      PPRFITM pPrfObj;      CalcPrfMetrics(ObjOrd, 0, &pm, &pPrfObj);      // No instances                   Instances      // ---------------------------    ---------------------------      // 1 PERF_OBJECT_TABLE            1 PERF_OBJECT_TABLE      // 1 PERF_COUNTER_DEFINITION      1 PERF_COUNTER_DEFINITION       // 0 PERF_INSTANCE_DEFINITION     x PERF_INSTANCE_DEFINITIONs      // 1 PERF_COUNTER_BLOCK           x PERF_COUNTER_BLOCKs      // 0 instance names               x instance names      pPrfObj->cbOffsetToNextObj = pm.cbPOT + pm.cbPCD +          pm.cbPID * (pm.fSupportsInstances ? pm.MaxInstances : 0) +          pm.cbPCB * (pm.fSupportsInstances ? pm.MaxInstances : 1) +          pm.cbPIN * (pm.fSupportsInstances ? pm.MaxInstances : 0);      cbBytesNeededForAllObjs += pPrfObj->cbOffsetToNextObj;   }   // Attempt to allocate a MMF big enough for the data   m_hfm = CreateFileMappingW((HANDLE) 0xffffffff, NULL, PAGE_READWRITE,       0, cbBytesNeededForAllObjs, m_pszAppName);   // If dwErr = ERROR_ALREADY_EXISTS, another app has created the    // shared data area. This instance doesn't need to initialize it   DWORD dwErr = GetLastError();   if (m_hfm == NULL) return(dwErr);   m_pPrfData = (PBYTE) MapViewOfFile(m_hfm, FILE_MAP_WRITE, 0, 0, 0);   if (dwErr == ERROR_ALREADY_EXISTS)    {       m_bIsActive = true;       return(dwErr);   }   // This instance actually allocated the shared data, initialize it   DWORD dwCounter = m_dwFirstCounter, dwHelp = m_dwFirstHelp;   // Set the PERF_OBJECT_TYPEs for each object   for (ObjOrd = 0; ObjOrd < m_nNumObjects; ObjOrd++) {      PRFMETRICS pm;      PPRFITM pPrfObj;      CalcPrfMetrics(ObjOrd, 0, &pm, &pPrfObj);      // Set the PERF_OBJECT_TYPE members      pm.pPOT->TotalByteLength      = 0;   // Set in Collect function      pm.pPOT->DefinitionLength     = sizeof(PERF_OBJECT_TYPE) +          sizeof(PERF_COUNTER_DEFINITION) *          (int) pPrfObj->NumCounters;       pm.pPOT->HeaderLength         = sizeof(PERF_OBJECT_TYPE);       pm.pPOT->ObjectNameTitleIndex = dwCounter;      pm.pPOT->ObjectNameTitle      = NULL; // Set by PerfMon      pm.pPOT->ObjectHelpTitleIndex = dwHelp;      pm.pPOT->ObjectHelpTitle      = NULL; // Set by PerfMon      pm.pPOT->DetailLevel          = pPrfObj->dwDetailLevel;       pm.pPOT->NumCounters          = (DWORD) pPrfObj->NumCounters;      if (pPrfObj->DefCounter == (CTRID) -1) {         pm.pPOT->DefaultCounter = -1;      } else {         // If a default CTRID specified, convert it to index         CvtCtrIdToPrfItmIndex(pPrfObj->DefCounter,             (int*) &pm.pPOT->DefaultCounter);      }      pm.pPOT->NumInstances         = (int) pPrfObj->MaxInstances;      pm.pPOT->CodePage             = NULL;       pm.pPOT->PerfTime.QuadPart    = 0;       pm.pPOT->PerfFreq.QuadPart    = 0;       dwCounter += 2;      dwHelp += 2;      // Set the PERF_COUNTER_DEFINITIONs for each counter

⌨️ 快捷键说明

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