Ejemplo n.º 1
0
void CSettings::OnBnClickedSelectPerfCounters()
{
	std::vector<std::wstring> counters;
	PDH_BROWSE_DLG_CONFIG config = {};
	CallbackArg arg = {};
	const size_t arbitrary_magic_buffer_size = 10000;
	arg.counter_names.resize(arbitrary_magic_buffer_size);
	arg.config = &config;
	arg.counters = &counters;
	config.bSingleCounterPerDialog = false;
	config.bIncludeCostlyObjects = false;
	config.bIncludeInstanceIndex = true;

	// I get crashes deep inside pdhui.dll if I set this to false and select
	// something (All Instances) that results in a wildcard. WTF?
	config.bWildCardInstances = true;
	config.bDisableMachineSelection = true;
	// /analyze warns that this const_cast is not needed, but when compiling with
	// /Zc:strictStrings it absolutely is. The type of szDialogBoxCaption needs to
	// be changed for this to work cleanly.
	config.szDialogBoxCaption = const_cast<wchar_t*>(L"Select performance counters");

	config.hWndOwner = *this;

	config.pCallBack = &CounterCallBack;
	config.dwCallBackArg = reinterpret_cast<DWORD_PTR>(&arg);
	config.dwDefaultDetailLevel = PERF_DETAIL_EXPERT;
	config.szReturnPathBuffer = arg.counter_names.data();
	config.cchReturnPathLength = static_cast<DWORD>(arg.counter_names.size());
	// Need some way to initialize the dialog with the previous settings?
	const PDH_STATUS status = PdhBrowseCounters(&config);
	if (status == ERROR_SUCCESS || status == PDH_DIALOG_CANCELLED)
	{
		std::wstring counters_string;
		for (auto& counter : counters)
		{
			counters_string += counter;
			counters_string += ';'; // I hope that is a valid separator.
		}
		// Trim the trailing ';'
		if (!counters_string.empty())
			counters_string.resize(counters_string.size() - 1);
		SetDlgItemTextW(IDC_PERFORMANCECOUNTERS, counters_string.c_str());
	}
}
long __cdecl _tmain(int argc, TCHAR **argv)
{

	HQUERY          hQuery;
	HCOUNTER        hCounter;
	PDH_STATUS      pdhStatus;
	PDH_FMT_COUNTERVALUE   fmtValue;
	DWORD           ctrType;
	SYSTEMTIME      stSampleTime;
	PDH_BROWSE_DLG_CONFIG  BrowseDlgData;
	CHAR            szPathBuffer[PDH_MAX_COUNTER_PATH];

	// Create a query.
	pdhStatus = PdhOpenQuery(NULL, NULL, &hQuery);
	if (ERROR_SUCCESS != pdhStatus)
	{
		_tprintf(TEXT("PdhOpenQuery failed with %ld.\n"), pdhStatus);
		goto cleanup;
	}

	ZeroMemory(&szPathBuffer, sizeof(szPathBuffer));

	// Initialize the browser dialog window settings.
	ZeroMemory(&BrowseDlgData, sizeof(PDH_BROWSE_DLG_CONFIG));
	BrowseDlgData.bIncludeInstanceIndex = FALSE;   
	BrowseDlgData.bSingleCounterPerAdd = TRUE;
	BrowseDlgData.bSingleCounterPerDialog = TRUE;  
	BrowseDlgData.bLocalCountersOnly = FALSE;      
	BrowseDlgData.bWildCardInstances = TRUE;
	BrowseDlgData.bHideDetailBox = TRUE;
	BrowseDlgData.bInitializePath = FALSE;     
	BrowseDlgData.bDisableMachineSelection = FALSE;
	BrowseDlgData.bIncludeCostlyObjects = FALSE;
	BrowseDlgData.bShowObjectBrowser = FALSE;
	BrowseDlgData.hWndOwner = NULL;   
	BrowseDlgData.szReturnPathBuffer = szPathBuffer;
	BrowseDlgData.cchReturnPathLength = sizeof(szPathBuffer);
	BrowseDlgData.pCallBack = NULL;   
	BrowseDlgData.dwCallBackArg = 0;
	BrowseDlgData.CallBackStatus = ERROR_SUCCESS;
	BrowseDlgData.dwDefaultDetailLevel = PERF_DETAIL_WIZARD;
	BrowseDlgData.szDialogBoxCaption = "Select a counter to monitor.";

	// Display the counter browser window. The dialog is configured
	// to return a single selection from the counter list.
// 	DWORD sized = PDH_MAX_COUNTER_PATH;
// 	pdhStatus = PdhLookupPerfNameByIndex(NULL,2,szPathBuffer,&sized);

	pdhStatus = PdhBrowseCounters (&BrowseDlgData);


	if (ERROR_SUCCESS != pdhStatus)
	{
		if (PDH_DIALOG_CANCELLED != pdhStatus)
		{
			_tprintf(TEXT("PdhBrowseCounters failed with %ld.\n"), pdhStatus);
		}

		goto cleanup;
	}

	// Add the selected counter to the query.
	pdhStatus = PdhAddCounter (hQuery,
		szPathBuffer, 
		0, 
		&hCounter);
	if (ERROR_SUCCESS != pdhStatus)
	{
		_tprintf(TEXT("PdhBrowseCounters failed with %ld.\n"), pdhStatus);
		goto cleanup;
	}

	// Most counters require two sample values to display a formatted value.
	// PDH stores the current sample value and the previously collected
	// sample value. This call retrieves the first value that will be used
	// by PdhGetFormattedCounterValue in the first iteration of the loop
	// Note that this value is lost if the counter does not require two
	// values to compute a displayable value.
// 	pdhStatus = PdhCollectQueryData (hQuery);
// 	if (ERROR_SUCCESS != pdhStatus)
// 	{
// 		_tprintf(TEXT("PdhCollectQueryData failed with %ld.\n"), pdhStatus);
// 		goto cleanup;
// 	}

	// Print counter values until a key is pressed.
	while (!_kbhit()) {

		// Wait one interval.
		Sleep(SAMPLE_INTERVAL_MS);

		// Get the sample time.
		GetLocalTime (&stSampleTime);

		// Get the current data value.
		pdhStatus = PdhCollectQueryData (hQuery);

		// Print the time stamp for the sample.
		_tprintf (
			TEXT("\n\"%2.2d/%2.2d/%4.4d %2.2d:%2.2d:%2.2d.%3.3d\""),
			stSampleTime.wMonth, 
			stSampleTime.wDay, 
			stSampleTime.wYear,
			stSampleTime.wHour, 
			stSampleTime.wMinute, 
			stSampleTime.wSecond,
			stSampleTime.wMilliseconds);

		// Compute a displayable value for the counter.
		pdhStatus = PdhGetFormattedCounterValue (hCounter,
			PDH_FMT_DOUBLE,
			&ctrType,
			&fmtValue);

		if (pdhStatus == ERROR_SUCCESS)
		{
			_tprintf (TEXT(",\"%.20g\""), fmtValue.doubleValue);
		}
		else
		{
			_tprintf(TEXT("\nPdhGetFormattedCounterValue failed with %ld.\n"), pdhStatus);
// 			goto cleanup;
		}
	}

cleanup:
	// Close the query.
	if (hQuery)
		PdhCloseQuery (hQuery);

	system ("pause");

	return pdhStatus;
}
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;
}