Ejemplo n.º 1
0
PerfCounter::PerfCounter()
{
	PdhOpenQuery(NULL, NULL, &m_query);

	HMODULE hProcess = GetModuleHandle(NULL);
	wchar_t fileNameBuf[MAX_PATH];
	GetModuleFileName((HMODULE) hProcess, fileNameBuf, MAX_PATH);
	wchar_t baseNameBuf[MAX_PATH];
	_wsplitpath_s(fileNameBuf, NULL, 0, NULL, 0, baseNameBuf, MAX_PATH, NULL, 0);
	m_processName = baseNameBuf;
	DWORD processId = GetProcessId(GetCurrentProcess());

	//we need to figure out the correct instance name
	//start by asking for all the counters which match the process name
	std::wstring wildcard = (boost::wformat(L"\\Process(%1%*)\\ID Process") % m_processName).str();
	wchar_t paths[1024];
	DWORD size = 1024;
	PdhExpandWildCardPath(NULL, wildcard.c_str(), paths, &size, 0);

	//create each ProcessID counter, check its value to see if it's the one we want
	size_t len = wcslen(paths);
	wchar_t* pathPtr = paths;
	bool found = false;
	while(len != 0)
	{
		PDH_HCOUNTER counter;
		PdhAddCounter(m_query, pathPtr, NULL, &counter);
		PdhCollectQueryData(m_query);
		PDH_RAW_COUNTER counterValue;
		PdhGetRawCounterValue(counter, 0, &counterValue);
		PdhRemoveCounter(counter);

		if(counterValue.FirstValue == processId)
		{
			found = true;
			break;
		}

		pathPtr += len + 1;
		len = wcslen(pathPtr);
	}

	if(found)
	{
		//we've got our desired instance name, which is ProcessName#N
		const wchar_t* instStart = wcschr(wildcard.c_str(), L'(') + 1;
		const wchar_t* instEnd = wcschr(wildcard.c_str(), L')') - 1;
		m_instName = std::wstring(instStart, instEnd - instStart);
	}
	else
	{
		//oh well, just roll with what we've got
		m_instName = m_processName;
	}
}
bool PerfCounterMuninNodePlugin::OpenCounter()
{
  PDH_STATUS status;  

  m_Name = m_SectionName.substr(strlen(PerfCounterMuninNodePlugin::SectionPrefix));

  OSVERSIONINFO osvi;    
  ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  if (!GetVersionEx(&osvi) || (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT)) {
	  _Module.LogError("PerfCounter plugin: %s: unknown OS or not NT based", m_Name.c_str());
	  return false; //unknown OS or not NT based
  }

  // Create a PDH query
  status = PdhOpenQuery(NULL, 0, &m_PerfQuery);
  if (status != ERROR_SUCCESS) {
	  _Module.LogError("PerfCounter plugin: %s: PdhOpenQuery error=%x", m_Name.c_str(), status);
	  return false;
  }

  TString objectName = A2TConvert(g_Config.GetValue(m_SectionName, "Object", "LogicalDisk"));
  TString counterName = A2TConvert(g_Config.GetValue(m_SectionName, "Counter", "% Disk Time"));
  TString instanceName = A2TConvert(g_Config.GetValue(m_SectionName, "Instance", "*"));

  bool useEnglishNames = g_Config.GetValueB(m_SectionName, "UseEnglishObjectNames", true);
  if (useEnglishNames) {
	  counterName = GetPdhCounterLocalizedName(counterName.c_str());
	  objectName = GetPdhCounterLocalizedName(objectName.c_str());
	  // NB: instance names are not localized
  }

  TCHAR *counterPath = new TCHAR[MAX_PATH];

  status = _sntprintf(counterPath, MAX_PATH, _T("\\%s(%s)\\%s"), objectName.c_str(), instanceName.c_str(), counterName.c_str());
  DWORD pathListBufsz = 0;
  status = PdhExpandWildCardPath(NULL, counterPath, NULL, &pathListBufsz, 0);
  if (status != PDH_MORE_DATA && status != PDH_INSUFFICIENT_BUFFER) {
	  _Module.LogError("PerfCounter plugin: %s: PdhExpandWildCardPath error=%x", m_Name.c_str(), status);
	  return false;
  }
  TCHAR *pathList = new TCHAR[pathListBufsz+2];
  status = PdhExpandWildCardPath(NULL, counterPath, (PZZTSTR)pathList, &pathListBufsz, 0);
  if (status != ERROR_SUCCESS) {
	  _Module.LogError("PerfCounter plugin: %s: PdhExpandWildCardPath error=%x", m_Name.c_str(), status);
	  return false;
  }

  // read config
  TString includeRE = A2TConvert(g_Config.GetValue(m_SectionName, "IncludePaths", ".+"));
  TString excludeRE = A2TConvert(g_Config.GetValue(m_SectionName, "ExcludePaths", "^$"));

  // create regex matchers
  CRegexpT <TCHAR> includeRegEx(includeRE.c_str(), IGNORECASE);
  CRegexpT <TCHAR> excludeRegEx(excludeRE.c_str(), IGNORECASE);

  HCOUNTER counterHandle;
  for (; *pathList; pathList += _tcslen(pathList) + 1) {
	  /* anatomy of a PDH path: \\machine\object(instance)\counter
	   * anomalies of a PDH path: the instance name is optional, and
	   * may contain parantheses and/or backslashes
	   * thus, the safest way is to check for the first '(' and the
	   * last '\' to separate the object, counter, instance names
	   */
	  int backslashes[2] = {0, 0};
	  int para = 0;
	  int idx;
	  for (idx = 2; pathList[idx]; idx++) {
		  if (pathList[idx] == '\\') {
			  if (backslashes[0]) {
				  backslashes[1] = idx;
			  } else {
				  backslashes[0] = idx;
			  }
		  } else if (pathList[idx] == '(' && (!para) && backslashes[0] && (!backslashes[1])) {
			  para = idx;
		  }
	  }
	  TCHAR *matchPath;
	  // use regex matching either on the original path or the
	  // back-translated constructed path
	  if (useEnglishNames) {
		  DWORD instPos = para ? para : backslashes[1];
		  TCHAR *oName = new TCHAR[instPos - backslashes[0]];
		  TCHAR *cName = new TCHAR[idx - backslashes[1] + 1];
		  TCHAR *iName = new TCHAR[backslashes[1] - para + 1];
		  // copy the object name
		  wcsncpy(oName, pathList + backslashes[0] + 1, instPos - backslashes[0] - 1);
		  oName[instPos - backslashes[0] - 1] = 0;
		  // copy the counter name (end of complete path, so \0 already exists)
		  wcsncpy(cName, pathList + backslashes[1] + 1, idx - backslashes[1]);
		  cName[idx - backslashes[1]] = 0;
		  // if there's an instance name, copy it, too.
		  if (para) {
			  wcsncpy(iName, pathList + para, backslashes[1] - para);
		  }
		  iName[backslashes[1] - para] = 0;
		  matchPath = new TCHAR[MAX_PATH];
		  _snwprintf(matchPath, MAX_PATH, _T("\\%s%s\\%s"), GetPdhCounterEnglishName(oName), iName, GetPdhCounterEnglishName(cName));
		  delete oName;
		  delete cName;
		  delete iName;
	  } else {
		  matchPath = pathList;
	  }
	  // handle includes & excludes
	  if (!includeRegEx.MatchExact(matchPath).IsMatched()
		  || excludeRegEx.MatchExact(matchPath).IsMatched()) {
		  if (useEnglishNames) {
			  delete matchPath;
		  }
		  continue;
	  }
	  if (useEnglishNames) {
		  delete matchPath;
	  }
	  // add the counter
	  status = PdhAddCounter(m_PerfQuery, pathList, 0, &counterHandle);
	  if (status != ERROR_SUCCESS) {
		  _Module.LogError("PerfCounter plugin: %s: PDH add counter error=%x", m_Name.c_str(), status);
		  return false;
	  }

	  // replace the backslash before the counter name with a space
	  pathList[backslashes[1]] = ' ';

	  std::string cn = W2IConvert(pathList + (para ? para : (backslashes[1] + 1)));
	  _Module.LogEvent("PerfCounter plugin: %s: added counter %s", m_Name.c_str(), cn.c_str());
	  m_Counters.push_back(counterHandle);
	  m_CounterNames.push_back(cn);
  }
  
  // Collect init data
  status = PdhCollectQueryData(m_PerfQuery);
  if (status != ERROR_SUCCESS) {
	  if (status == PDH_INVALID_HANDLE) {
		  _Module.LogError("PerfCounter plugin: %s: PDH collect data: PDH_INVALID_HANDLE", m_Name.c_str());
		  return false;
	  }
	  if (status == PDH_NO_DATA) {
		  _Module.LogError("PerfCounter plugin: %s: PDH collect data: PDH_NO_DATA", m_Name.c_str());
		  return false;
	  }
	  _Module.LogError("PerfCounter plugin: %s: PDH collect data error", m_Name.c_str());
	  return false;
  }

  // Setup Counter Format
  m_dwCounterFormat = PDH_FMT_DOUBLE;
  std::string counterFormatStr = g_Config.GetValue(m_SectionName, "CounterFormat", "double");
  if (!counterFormatStr.compare("double")
    || !counterFormatStr.compare("float")) {
    m_dwCounterFormat = PDH_FMT_DOUBLE;

  } else if (!counterFormatStr.compare("int") 
    || !counterFormatStr.compare("long")) {
    m_dwCounterFormat = PDH_FMT_LONG;

  } else if (!counterFormatStr.compare("int64") 
    || !counterFormatStr.compare("longlong") 
    || !counterFormatStr.compare("large")) {
    m_dwCounterFormat = PDH_FMT_LARGE;

  } else {
	  _Module.LogError("PerfCounter plugin: %s: Unknown CounterFormat", m_Name.c_str());
	  assert(!"Unknown CounterFormat!");
  }

  m_CounterMultiply = g_Config.GetValueF(m_SectionName, "CounterMultiply", 1.0);

  return true;
}
Ejemplo n.º 3
0
static INT_PTR CALLBACK OptionsDlgProc(
    _In_ HWND hwndDlg,
    _In_ UINT uMsg,
    _In_ WPARAM wParam,
    _In_ LPARAM lParam
    )
{
    PPH_PERFMON_CONTEXT context = NULL;

    if (uMsg == WM_INITDIALOG)
    {
        context = (PPH_PERFMON_CONTEXT)PhAllocate(sizeof(PH_PERFMON_CONTEXT));
        memset(context, 0, sizeof(PH_PERFMON_CONTEXT));

        SetProp(hwndDlg, L"Context", (HANDLE)context);
    }
    else
    {
        context = (PPH_PERFMON_CONTEXT)GetProp(hwndDlg, L"Context");

        if (uMsg == WM_NCDESTROY)
        {
            PPH_STRING string;

            ClearCounterList(CountersList);
            CopyCounterList(CountersList, context->CountersListEdited);
            PhDereferenceObject(context->CountersListEdited);

            string = SaveCounterList(CountersList);
            PhSetStringSetting2(SETTING_NAME_PERFMON_LIST, &string->sr);
            PhDereferenceObject(string);

            RemoveProp(hwndDlg, L"Context");
            PhFree(context);
        }
    }

    if (context == NULL)
        return FALSE;

    switch (uMsg)
    {
    case WM_INITDIALOG:
        {
            context->CountersListEdited = PhCreateList(2);
            context->ListViewHandle = GetDlgItem(hwndDlg, IDC_PERFCOUNTER_LISTVIEW);

            PhSetListViewStyle(context->ListViewHandle, FALSE, TRUE);
            PhSetControlTheme(context->ListViewHandle, L"explorer");
            PhAddListViewColumn(context->ListViewHandle, 0, 0, 0, LVCFMT_LEFT, 420, L"Counter");
            PhSetExtendedListView(context->ListViewHandle);

            ClearCounterList(context->CountersListEdited);
            CopyCounterList(context->CountersListEdited, CountersList);
            LoadCountersToListView(context, context->CountersListEdited);
        }
        break;
    case WM_COMMAND:
        {
            switch (LOWORD(wParam))
            {
            case IDC_ADD_BUTTON:
                {
                    PDH_STATUS counterStatus = 0;
                    PPH_STRING counterPathString = NULL;
                    PPH_STRING counterWildCardString = NULL;
                    PDH_BROWSE_DLG_CONFIG browseConfig = { 0 };
                    WCHAR counterPathBuffer[PDH_MAX_COUNTER_PATH] = L"";

                    browseConfig.bIncludeInstanceIndex = FALSE;
                    browseConfig.bSingleCounterPerAdd = FALSE;// Fix empty CounterPathBuffer
                    browseConfig.bSingleCounterPerDialog = TRUE;
                    browseConfig.bLocalCountersOnly = FALSE;
                    browseConfig.bWildCardInstances = TRUE; // Seems to cause a lot of crashes
                    browseConfig.bHideDetailBox = TRUE;
                    browseConfig.bInitializePath = FALSE;
                    browseConfig.bDisableMachineSelection = FALSE;
                    browseConfig.bIncludeCostlyObjects = FALSE;
                    browseConfig.bShowObjectBrowser = FALSE;
                    browseConfig.hWndOwner = hwndDlg;
                    browseConfig.szReturnPathBuffer = counterPathBuffer;
                    browseConfig.cchReturnPathLength = PDH_MAX_COUNTER_PATH;
                    browseConfig.CallBackStatus = ERROR_SUCCESS;
                    browseConfig.dwDefaultDetailLevel = PERF_DETAIL_WIZARD;
                    browseConfig.szDialogBoxCaption = L"Select a counter to monitor.";

                    __try
                    {
                        // Display the counter browser window.
                        if ((counterStatus = PdhBrowseCounters(&browseConfig)) != ERROR_SUCCESS)
                        {
                            if (counterStatus != PDH_DIALOG_CANCELLED)
                            {
                                PhShowError(hwndDlg, L"PdhBrowseCounters failed with status 0x%x.", counterStatus);
                            }

                            __leave;
                        }
                        else if (wcslen(counterPathBuffer) == 0)
                        {
                            // This gets called when pressing the X on the BrowseCounters dialog.
                            __leave;
                        }

                        counterPathString = PhCreateString(counterPathBuffer);

                        // Check if we need to expand any wildcards...
                        if (PhFindCharInString(counterPathString, 0, '*') != -1)
                        {
                            ULONG counterWildCardLength = 0;

                            // Query WildCard buffer length...
                            PdhExpandWildCardPath(
                                NULL,
                                counterPathString->Buffer,
                                NULL,
                                &counterWildCardLength,
                                0
                                );

                            counterWildCardString = PhCreateStringEx(NULL, counterWildCardLength * sizeof(WCHAR));

                            if ((counterStatus = PdhExpandWildCardPath(
                                NULL,
                                counterPathString->Buffer,
                                counterWildCardString->Buffer,
                                &counterWildCardLength,
                                0
                                )) == ERROR_SUCCESS)
                            {
                                PH_STRINGREF part;
                                PH_STRINGREF remaining = counterWildCardString->sr;

                                while (remaining.Length != 0)
                                {
                                    // Split the results
                                    if (!PhSplitStringRefAtChar(&remaining, '\0', &part, &remaining))
                                        break;
                                    if (remaining.Length == 0)
                                        break;

                                    if ((counterStatus = PdhValidatePath(part.Buffer)) != ERROR_SUCCESS)
                                    {
                                        PhShowError(hwndDlg, L"PdhValidatePath failed with status 0x%x.", counterStatus);
                                        __leave;
                                    }

                                    AddCounterToListView(context, part.Buffer);
                                }
                            }
                            else
                            {
                                PhShowError(hwndDlg, L"PdhExpandWildCardPath failed with status 0x%x.", counterStatus);
                            }
                        }
                        else
                        {
                            if ((counterStatus = PdhValidatePath(counterPathString->Buffer)) != ERROR_SUCCESS)
                            {
                                PhShowError(hwndDlg, L"PdhValidatePath failed with status 0x%x.", counterStatus);
                                __leave;
                            }

                            AddCounterToListView(context, counterPathString->Buffer);
                        }
                    }
                    __finally
                    {
                        if (counterWildCardString)
                            PhDereferenceObject(counterWildCardString);

                        if (counterPathString)
                            PhDereferenceObject(counterPathString);
                    }
                }
                break;
            case IDC_REMOVE_BUTTON:
                {
                    INT itemIndex;

                    // Get the first selected item
                    itemIndex = ListView_GetNextItem(context->ListViewHandle, -1, LVNI_SELECTED);

                    while (itemIndex != -1)
                    {
                        PPH_PERFMON_ENTRY entry;

                        if (PhGetListViewItemParam(context->ListViewHandle, itemIndex, (PPVOID)&entry))
                        {
                            ULONG index = PhFindItemList(context->CountersListEdited, entry);

                            if (index != -1)
                            {
                                PhRemoveItemList(context->CountersListEdited, index);
                                PhRemoveListViewItem(context->ListViewHandle, itemIndex);
                                FreeCounterEntry(entry);
                            }
                        }

                        // Get the next selected item
                        itemIndex = ListView_GetNextItem(context->ListViewHandle, -1, LVNI_SELECTED);
                    }
                }
                break;
            case IDCANCEL:
                EndDialog(hwndDlg, IDCANCEL);
                break;
            case IDOK:
                EndDialog(hwndDlg, IDOK);
                break;
            }
        }
        break;
    }

    return FALSE;
}