add plugins-extra

This commit is contained in:
AirDog46
2025-05-13 19:49:49 +03:00
parent c5fab8aa94
commit 3575d86c17
531 changed files with 70258 additions and 1 deletions

View File

@@ -0,0 +1,5 @@
1.1
* Fixed system information graphs
1.0
* Initial release

View File

@@ -0,0 +1,147 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (Australia) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS
#pragma code_page(1252)
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,1,0,0
PRODUCTVERSION 1,1,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "0c0904b0"
BEGIN
VALUE "CompanyName", "dmex"
VALUE "FileDescription", "Performance counters plugin for Process Hacker"
VALUE "FileVersion", "1.1"
VALUE "InternalName", "dmex.PerfMonPlugin"
VALUE "LegalCopyright", "Licensed under the GNU GPL, v3."
VALUE "OriginalFilename", "PerfMonPlugin.dll"
VALUE "ProductName", "Performance counters plugin for Process Hacker"
VALUE "ProductVersion", "1.1"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0xc09, 1200
END
END
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\0"
END
3 TEXTINCLUDE
BEGIN
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_PERFMON_OPTIONS DIALOGEX 0, 0, 371, 220
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "PerfMon Options"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
PUSHBUTTON "Close",IDOK,314,199,50,14
CONTROL "",IDC_PERFCOUNTER_LISTVIEW,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP,7,18,357,179
PUSHBUTTON "Add",IDC_ADD_BUTTON,7,199,50,14
LTEXT "Warning: Performance counters degrade application performance.",IDC_STATIC,7,7,213,8
END
IDD_PERFMON_DIALOG DIALOGEX 0, 0, 269, 130
STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_APPWINDOW
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "",IDC_GRAPH_LAYOUT,0,21,269,103,NOT WS_VISIBLE | WS_BORDER
LTEXT "Static",IDC_COUNTERNAME,0,0,269,21
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_PERFMON_OPTIONS, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 364
TOPMARGIN, 7
BOTTOMMARGIN, 213
END
IDD_PERFMON_DIALOG, DIALOG
BEGIN
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// AFX_DIALOG_LAYOUT
//
IDD_PERFMON_OPTIONS AFX_DIALOG_LAYOUT
BEGIN
0
END
#endif // English (Australia) resources
/////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,128 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{E373C568-D6C5-4E0E-94ED-A759EDE16A9E}</ProjectGuid>
<RootNamespace>PerfMonPlugin</RootNamespace>
<Keyword>Win32Proj</Keyword>
<ProjectName>PerfMonPlugin</ProjectName>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\ExtraPlugins.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\ExtraPlugins.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\ExtraPlugins.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\ExtraPlugins.props" />
</ImportGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Debug32</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release64</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release32</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Link>
<AdditionalDependencies>pdh.lib;%(AdditionalDependencies)</AdditionalDependencies>
<DelayLoadDLLs>pdh.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
</Link>
<ClCompile>
<TreatWarningAsError>false</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Link>
<AdditionalDependencies>pdh.lib;%(AdditionalDependencies)</AdditionalDependencies>
<DelayLoadDLLs>pdh.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
</Link>
<ClCompile>
<TreatWarningAsError>false</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Link>
<AdditionalDependencies>pdh.lib;%(AdditionalDependencies)</AdditionalDependencies>
<DelayLoadDLLs>pdh.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
</Link>
<ClCompile>
<TreatWarningAsError>false</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Link>
<AdditionalDependencies>pdh.lib;%(AdditionalDependencies)</AdditionalDependencies>
<DelayLoadDLLs>pdh.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
</Link>
<ClCompile>
<TreatWarningAsError>false</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="counters.c" />
<ClCompile Include="graph.c" />
<ClCompile Include="main.c" />
<ClCompile Include="options.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="perfmon.h" />
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="PerfMonPlugin.rc" />
</ItemGroup>
<ItemGroup>
<None Include="CHANGELOG.txt" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{47359E56-A930-4DDC-A651-E2E99D48E957}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{4965CB7A-371A-4B22-AC3F-E70DC77C5D24}</UniqueIdentifier>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{00475F04-2369-42D8-9A52-9DB77E37AE62}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="perfmon.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="options.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="graph.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="counters.c" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="PerfMonPlugin.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<None Include="CHANGELOG.txt" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,195 @@
/*
* Process Hacker Plugins -
* Performance Monitor Plugin
*
* Copyright (C) 2016 dmex
*
* This file is part of Process Hacker.
*
* Process Hacker 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 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "perfmon.h"
VOID PerfMonEntryDeleteProcedure(
_In_ PVOID Object,
_In_ ULONG Flags
)
{
PPERF_COUNTER_ENTRY entry = Object;
PhAcquireQueuedLockExclusive(&PerfCounterListLock);
PhRemoveItemList(PerfCounterList, PhFindItemList(PerfCounterList, entry));
PhReleaseQueuedLockExclusive(&PerfCounterListLock);
DeletePerfCounterId(&entry->Id);
PhDeleteCircularBuffer_ULONG64(&entry->HistoryBuffer);
if (entry->PerfQueryHandle)
{
PdhCloseQuery(entry->PerfQueryHandle);
entry->PerfQueryHandle = NULL;
}
if (entry->PerfCounterInfo)
{
PhFree(entry->PerfCounterInfo);
entry->PerfCounterInfo = NULL;
}
//PhDereferenceObject(entry);
}
VOID PerfMonInitialize(
VOID
)
{
PerfCounterList = PhCreateList(1);
PerfCounterEntryType = PhCreateObjectType(L"PerfMonEntry", 0, PerfMonEntryDeleteProcedure);
}
VOID PerfMonUpdate(
VOID
)
{
static ULONG runCount = 0; // MUST keep in sync with runCount in process provider
PhAcquireQueuedLockShared(&PerfCounterListLock);
for (ULONG i = 0; i < PerfCounterList->Count; i++)
{
PPERF_COUNTER_ENTRY entry;
ULONG counterType = 0;
PDH_FMT_COUNTERVALUE displayValue = { 0 };
entry = PhReferenceObjectSafe(PerfCounterList->Items[i]);
if (!entry)
continue;
if (entry->HaveFirstSample)
{
if (!entry->PerfQueryHandle)
{
if (PdhOpenQuery(NULL, 0, &entry->PerfQueryHandle) == ERROR_SUCCESS)
{
if (PdhAddCounter(entry->PerfQueryHandle, PhGetString(entry->Id.PerfCounterPath), 0, &entry->PerfCounterHandle) == ERROR_SUCCESS)
{
ULONG counterLength;
if (PdhGetCounterInfo(entry->PerfCounterHandle, TRUE, &counterLength, NULL) == PDH_MORE_DATA)
{
entry->PerfCounterInfo = PhAllocate(counterLength);
memset(entry->PerfCounterInfo, 0, counterLength);
}
if (PdhGetCounterInfo(entry->PerfCounterHandle, TRUE, &counterLength, entry->PerfCounterInfo) == ERROR_SUCCESS)
{
}
OutputDebugString(L"");
}
}
}
// Update the counter data
PdhCollectQueryData(entry->PerfQueryHandle);
//PdhSetCounterScaleFactor(entry->PerfCounterHandle, PDH_MAX_SCALE);
//PdhGetRawCounterValue(entry->PerfCounterHandle, 0, &rawValue);
if (PdhGetFormattedCounterValue(
entry->PerfCounterHandle,
PDH_FMT_LARGE | PDH_FMT_NOSCALE | PDH_FMT_NOCAP100,
&counterType,
&displayValue
) == ERROR_SUCCESS && counterType == PERF_COUNTER_COUNTER)
{
PhUpdateDelta(&entry->HistoryDelta, displayValue.largeValue);
}
}
else
{
PhInitializeDelta(&entry->HistoryDelta); // The first sample must be zero
entry->HaveFirstSample = TRUE;
}
if (runCount != 0)
{
PhAddItemCircularBuffer_ULONG64(&entry->HistoryBuffer, entry->HistoryDelta.Value);
}
PhDereferenceObjectDeferDelete(entry);
}
PhReleaseQueuedLockShared(&PerfCounterListLock);
runCount++;
}
VOID InitializePerfCounterId(
_Out_ PPERF_COUNTER_ID Id,
_In_ PPH_STRING PerfCounterPath
)
{
PhSetReference(&Id->PerfCounterPath, PerfCounterPath);
}
VOID CopyPerfCounterId(
_Out_ PPERF_COUNTER_ID Destination,
_In_ PPERF_COUNTER_ID Source
)
{
InitializePerfCounterId(Destination, Source->PerfCounterPath);
}
VOID DeletePerfCounterId(
_Inout_ PPERF_COUNTER_ID Id
)
{
PhClearReference(&Id->PerfCounterPath);
}
BOOLEAN EquivalentPerfCounterId(
_In_ PPERF_COUNTER_ID Id1,
_In_ PPERF_COUNTER_ID Id2
)
{
if (!Id1 || !Id2)
return FALSE;
return PhEqualString(Id1->PerfCounterPath, Id2->PerfCounterPath, TRUE);
}
PPERF_COUNTER_ENTRY CreatePerfCounterEntry(
_In_ PPERF_COUNTER_ID Id
)
{
PPERF_COUNTER_ENTRY entry;
entry = PhCreateObject(sizeof(PERF_COUNTER_ENTRY), PerfCounterEntryType);
memset(entry, 0, sizeof(PERF_COUNTER_ENTRY));
CopyPerfCounterId(&entry->Id, Id);
PhInitializeCircularBuffer_ULONG64(&entry->HistoryBuffer, PhGetIntegerSetting(L"SampleCount"));
PhAcquireQueuedLockExclusive(&PerfCounterListLock);
PhAddItemList(PerfCounterList, entry);
PhReleaseQueuedLockExclusive(&PerfCounterListLock);
return entry;
}

View File

@@ -0,0 +1,357 @@
/*
* Process Hacker Extra Plugins -
* Performance Monitor Plugin
*
* Copyright (C) 2015-2016 dmex
*
* This file is part of Process Hacker.
*
* Process Hacker 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 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "perfmon.h"
#define MSG_UPDATE (WM_APP + 1)
PPH_STRING PerfCounterLabelYFunction(
_In_ PPH_GRAPH_DRAW_INFO DrawInfo,
_In_ ULONG DataIndex,
_In_ FLOAT Value,
_In_ FLOAT Parameter
)
{
ULONG64 size;
size = (ULONG64)(Value * Parameter);
if (size != 0)
{
return PhFormatUInt64(size, TRUE);
}
else
{
return PhReferenceEmptyString();
}
}
VOID NTAPI ProcessesUpdatedHandler(
_In_opt_ PVOID Parameter,
_In_opt_ PVOID Context
)
{
PPH_PERFMON_SYSINFO_CONTEXT context = Context;
if (context->WindowHandle)
{
PostMessage(context->WindowHandle, MSG_UPDATE, 0, 0);
}
}
VOID PerfCounterUpdateGraphs(
_Inout_ PPH_PERFMON_SYSINFO_CONTEXT Context
)
{
Context->GraphState.Valid = FALSE;
Context->GraphState.TooltipIndex = -1;
Graph_MoveGrid(Context->GraphHandle, 1);
Graph_Draw(Context->GraphHandle);
Graph_UpdateTooltip(Context->GraphHandle);
InvalidateRect(Context->GraphHandle, NULL, FALSE);
}
INT_PTR CALLBACK PerfCounterDialogProc(
_In_ HWND hwndDlg,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
PPH_PERFMON_SYSINFO_CONTEXT context = NULL;
if (uMsg == WM_INITDIALOG)
{
context = (PPH_PERFMON_SYSINFO_CONTEXT)lParam;
SetProp(hwndDlg, L"Context", (HANDLE)context);
}
else
{
context = (PPH_PERFMON_SYSINFO_CONTEXT)GetProp(hwndDlg, L"Context");
if (uMsg == WM_DESTROY)
{
PhDeleteLayoutManager(&context->LayoutManager);
PhDeleteGraphState(&context->GraphState);
if (context->GraphHandle)
DestroyWindow(context->GraphHandle);
PhUnregisterCallback(&PhProcessesUpdatedEvent, &context->ProcessesUpdatedRegistration);
RemoveProp(hwndDlg, L"Context");
}
}
if (context == NULL)
return FALSE;
switch (uMsg)
{
case WM_INITDIALOG:
{
PPH_LAYOUT_ITEM panelItem;
context->WindowHandle = hwndDlg;
// Create the graph control.
context->GraphHandle = CreateWindow(
PH_GRAPH_CLASSNAME,
NULL,
WS_VISIBLE | WS_CHILD | WS_BORDER,
0,
0,
3,
3,
hwndDlg,
NULL,
NULL,
NULL
);
Graph_SetTooltip(context->GraphHandle, TRUE);
PhInitializeGraphState(&context->GraphState);
PhInitializeLayoutManager(&context->LayoutManager, hwndDlg);
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_COUNTERNAME), NULL, PH_ANCHOR_LEFT | PH_ANCHOR_TOP | PH_ANCHOR_RIGHT | PH_LAYOUT_FORCE_INVALIDATE);
panelItem = PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_GRAPH_LAYOUT), NULL, PH_ANCHOR_ALL);
PhAddLayoutItemEx(&context->LayoutManager, context->GraphHandle, NULL, PH_ANCHOR_ALL, panelItem->Margin);
SendMessage(GetDlgItem(hwndDlg, IDC_COUNTERNAME), WM_SETFONT, (WPARAM)context->SysinfoSection->Parameters->LargeFont, FALSE);
SetDlgItemText(hwndDlg, IDC_COUNTERNAME, context->SysinfoSection->Name.Buffer);
PhRegisterCallback(
&PhProcessesUpdatedEvent,
ProcessesUpdatedHandler,
context,
&context->ProcessesUpdatedRegistration
);
PerfCounterUpdateGraphs(context);
}
break;
case WM_SIZE:
PhLayoutManagerLayout(&context->LayoutManager);
break;
case WM_NOTIFY:
{
NMHDR* header = (NMHDR*)lParam;
if (header->hwndFrom == context->GraphHandle)
{
switch (header->code)
{
case GCN_GETDRAWINFO:
{
PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)header;
PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo;
drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y | PH_GRAPH_LABEL_MAX_Y;
context->SysinfoSection->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), 0);
PhGraphStateGetDrawInfo(&context->GraphState, getDrawInfo, context->Entry->HistoryBuffer.Count);
if (!context->GraphState.Valid)
{
FLOAT max = 0;
for (ULONG i = 0; i < drawInfo->LineDataCount; i++)
{
context->GraphState.Data1[i] = (FLOAT)PhGetItemCircularBuffer_ULONG64(&context->Entry->HistoryBuffer, i);
if (context->GraphState.Data1[i] > max)
max = context->GraphState.Data1[i];
}
if (max != 0)
{
// Scale the data.
PhDivideSinglesBySingle(
context->GraphState.Data1,
max,
drawInfo->LineDataCount
);
}
drawInfo->LabelYFunction = PerfCounterLabelYFunction;
drawInfo->LabelYFunctionParameter = max;
context->GraphState.Valid = TRUE;
}
}
break;
case GCN_GETTOOLTIPTEXT:
{
PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)header;
if (getTooltipText->Index < getTooltipText->TotalCount)
{
if (context->GraphState.TooltipIndex != getTooltipText->Index)
{
ULONG64 itemUsage = PhGetItemCircularBuffer_ULONG64(
&context->Entry->HistoryBuffer,
getTooltipText->Index
);
PhMoveReference(&context->GraphState.TooltipText, PhFormatString(
L"%I64u\n%s",
itemUsage,
((PPH_STRING)PhAutoDereferenceObject(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer
));
}
getTooltipText->Text = context->GraphState.TooltipText->sr;
}
}
break;
}
}
}
break;
case MSG_UPDATE:
PerfCounterUpdateGraphs(context);
break;
}
return FALSE;
}
BOOLEAN PerfCounterSectionCallback(
_In_ PPH_SYSINFO_SECTION Section,
_In_ PH_SYSINFO_SECTION_MESSAGE Message,
_In_opt_ PVOID Parameter1,
_In_opt_ PVOID Parameter2
)
{
PPH_PERFMON_SYSINFO_CONTEXT context = (PPH_PERFMON_SYSINFO_CONTEXT)Section->Context;
switch (Message)
{
case SysInfoCreate:
return TRUE;
case SysInfoDestroy:
return TRUE;
case SysInfoTick:
return TRUE;
case SysInfoCreateDialog:
{
PPH_SYSINFO_CREATE_DIALOG createDialog = (PPH_SYSINFO_CREATE_DIALOG)Parameter1;
createDialog->Instance = PluginInstance->DllBase;
createDialog->Template = MAKEINTRESOURCE(IDD_PERFMON_DIALOG);
createDialog->DialogProc = PerfCounterDialogProc;
createDialog->Parameter = context;
}
return TRUE;
case SysInfoGraphGetDrawInfo:
{
PPH_GRAPH_DRAW_INFO drawInfo = (PPH_GRAPH_DRAW_INFO)Parameter1;
drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y | PH_GRAPH_LABEL_MAX_Y;
Section->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), 0);
PhGetDrawInfoGraphBuffers(&Section->GraphState.Buffers, drawInfo, context->Entry->HistoryBuffer.Count);
if (!Section->GraphState.Valid)
{
FLOAT max = 0;
for (ULONG i = 0; i < drawInfo->LineDataCount; i++)
{
Section->GraphState.Data1[i] = (FLOAT)PhGetItemCircularBuffer_ULONG64(&context->Entry->HistoryBuffer, i);
if (Section->GraphState.Data1[i] > max)
max = Section->GraphState.Data1[i];
}
if (max != 0)
{
// Scale the data.
PhDivideSinglesBySingle(
Section->GraphState.Data1,
max,
drawInfo->LineDataCount
);
}
drawInfo->LabelYFunction = PerfCounterLabelYFunction;
drawInfo->LabelYFunctionParameter = max;
Section->GraphState.Valid = TRUE;
}
}
return TRUE;
case SysInfoGraphGetTooltipText:
{
PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT getTooltipText = (PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT)Parameter1;
ULONG64 counterValue = PhGetItemCircularBuffer_ULONG64(
&context->Entry->HistoryBuffer,
getTooltipText->Index
);
PhMoveReference(&Section->GraphState.TooltipText, PhFormatString(
L"%I64u\n%s",
counterValue,
((PPH_STRING)PhAutoDereferenceObject(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer
));
getTooltipText->Text = Section->GraphState.TooltipText->sr;
}
return TRUE;
case SysInfoGraphDrawPanel:
{
PPH_SYSINFO_DRAW_PANEL drawPanel = (PPH_SYSINFO_DRAW_PANEL)Parameter1;
drawPanel->Title = PhCreateString(Section->Name.Buffer);
drawPanel->SubTitle = PhFormatUInt64(context->Entry->HistoryDelta.Value, TRUE);
}
return TRUE;
}
return FALSE;
}
VOID PerfMonCounterSysInfoInitializing(
_In_ PPH_PLUGIN_SYSINFO_POINTERS Pointers,
_In_ PPERF_COUNTER_ENTRY Entry
)
{
PH_SYSINFO_SECTION section;
PPH_PERFMON_SYSINFO_CONTEXT context;
context = (PPH_PERFMON_SYSINFO_CONTEXT)PhAllocate(sizeof(PH_PERFMON_SYSINFO_CONTEXT));
memset(context, 0, sizeof(PH_PERFMON_SYSINFO_CONTEXT));
memset(&section, 0, sizeof(PH_SYSINFO_SECTION));
context->Entry = Entry;
section.Context = context;
section.Callback = PerfCounterSectionCallback;
PhInitializeStringRef(&section.Name, PhGetStringOrEmpty(Entry->Id.PerfCounterPath));
context->SysinfoSection = Pointers->CreateSection(&section);
}

View File

@@ -0,0 +1,156 @@
/*
* Process Hacker Extra Plugins -
* Performance Monitor Plugin
*
* Copyright (C) 2015-2016 dmex
*
* This file is part of Process Hacker.
*
* Process Hacker 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 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "perfmon.h"
PPH_LIST PerfCounterList = NULL;
PPH_OBJECT_TYPE PerfCounterEntryType = NULL;
PH_QUEUED_LOCK PerfCounterListLock = PH_QUEUED_LOCK_INIT;
PPH_PLUGIN PluginInstance;
PH_CALLBACK_REGISTRATION PluginLoadCallbackRegistration;
PH_CALLBACK_REGISTRATION PluginUnloadCallbackRegistration;
PH_CALLBACK_REGISTRATION PluginShowOptionsCallbackRegistration;
PH_CALLBACK_REGISTRATION SystemInformationInitializingCallbackRegistration;
PH_CALLBACK_REGISTRATION ProcessesUpdatedCallbackRegistration;
VOID NTAPI ProcessesUpdatedCallback(
_In_opt_ PVOID Parameter,
_In_opt_ PVOID Context
)
{
PerfMonUpdate();
}
VOID NTAPI LoadCallback(
_In_opt_ PVOID Parameter,
_In_opt_ PVOID Context
)
{
PerfMonInitialize();
PerfMonLoadList();
}
VOID NTAPI UnloadCallback(
_In_opt_ PVOID Parameter,
_In_opt_ PVOID Context
)
{
NOTHING;
}
VOID NTAPI ShowOptionsCallback(
_In_opt_ PVOID Parameter,
_In_opt_ PVOID Context
)
{
ShowOptionsDialog((HWND)Parameter);
}
VOID NTAPI SystemInformationInitializingCallback(
_In_opt_ PVOID Parameter,
_In_opt_ PVOID Context
)
{
PPH_PLUGIN_SYSINFO_POINTERS pluginEntry = (PPH_PLUGIN_SYSINFO_POINTERS)Parameter;
PhAcquireQueuedLockShared(&PerfCounterListLock);
for (ULONG i = 0; i < PerfCounterList->Count; i++)
{
PPERF_COUNTER_ENTRY entry = PhReferenceObjectSafe(PerfCounterList->Items[i]);
if (!entry)
continue;
if (entry->UserReference)
{
PerfMonCounterSysInfoInitializing(pluginEntry, entry);
}
}
PhReleaseQueuedLockShared(&PerfCounterListLock);
}
LOGICAL DllMain(
_In_ HINSTANCE Instance,
_In_ ULONG Reason,
_Reserved_ PVOID Reserved
)
{
switch (Reason)
{
case DLL_PROCESS_ATTACH:
{
PPH_PLUGIN_INFORMATION info;
PH_SETTING_CREATE settings[] =
{
{ StringSettingType, SETTING_NAME_PERFMON_LIST, L"" }
};
PluginInstance = PhRegisterPlugin(PLUGIN_NAME, Instance, &info);
if (!PluginInstance)
return FALSE;
info->DisplayName = L"Performance Counters";
info->Author = L"dmex";
info->Description = L"Plugin for adding Performance Counters to the System Information window.";
info->HasOptions = TRUE;
PhRegisterCallback(
PhGetPluginCallback(PluginInstance, PluginCallbackLoad),
LoadCallback,
NULL,
&PluginLoadCallbackRegistration
);
PhRegisterCallback(
PhGetPluginCallback(PluginInstance, PluginCallbackUnload),
UnloadCallback,
NULL,
&PluginUnloadCallbackRegistration
);
PhRegisterCallback(
PhGetPluginCallback(PluginInstance, PluginCallbackShowOptions),
ShowOptionsCallback,
NULL,
&PluginShowOptionsCallbackRegistration
);
PhRegisterCallback(
PhGetGeneralCallback(GeneralCallbackSystemInformationInitializing),
SystemInformationInitializingCallback,
NULL,
&SystemInformationInitializingCallbackRegistration
);
PhRegisterCallback(
&PhProcessesUpdatedEvent,
ProcessesUpdatedCallback,
NULL,
&ProcessesUpdatedCallbackRegistration
);
PhAddSettings(settings, ARRAYSIZE(settings));
}
break;
}
return TRUE;
}

View File

@@ -0,0 +1,429 @@
/*
* Process Hacker Extra Plugins -
* Performance Monitor Plugin
*
* Copyright (C) 2015-2016 dmex
*
* This file is part of Process Hacker.
*
* Process Hacker 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 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "perfmon.h"
INT AddListViewItemGroupId(
_In_ HWND ListViewHandle,
_In_ INT Index,
_In_ PWSTR Text,
_In_opt_ PVOID Param
)
{
LVITEM item;
memset(&item, 0, sizeof(LVITEM));
item.mask = LVIF_TEXT;
item.iItem = Index;
item.iSubItem = 0;
item.pszText = Text;
if (Param)
{
item.mask |= LVIF_PARAM;
item.lParam = (LPARAM)Param;
}
return ListView_InsertItem(ListViewHandle, &item);
}
VOID PerfMonAddCounter(
_In_ PPH_PERFMON_CONTEXT Context,
_In_ PPH_STRING CounterPath
)
{
INT lvItemIndex;
PERF_COUNTER_ID id;
PPERF_COUNTER_ENTRY entry;
InitializePerfCounterId(&id, CounterPath);
entry = CreatePerfCounterEntry(&id);
DeletePerfCounterId(&id);
entry->UserReference = TRUE;
lvItemIndex = AddListViewItemGroupId(
Context->ListViewHandle,
MAXINT,
PhGetStringOrEmpty(entry->Id.PerfCounterPath),
entry
);
ListView_SetItemState(Context->ListViewHandle, lvItemIndex, ITEM_CHECKED, LVIS_STATEIMAGEMASK);
}
VOID PerfMonLoadCounters(
_In_ PPH_PERFMON_CONTEXT Context
)
{
PhAcquireQueuedLockShared(&PerfCounterListLock);
for (ULONG i = 0; i < PerfCounterList->Count; i++)
{
INT lvItemIndex;
PPERF_COUNTER_ENTRY entry = PhReferenceObjectSafe(PerfCounterList->Items[i]);
if (!entry)
continue;
if (entry->UserReference)
{
lvItemIndex = AddListViewItemGroupId(
Context->ListViewHandle,
MAXINT,
PhGetStringOrEmpty(entry->Id.PerfCounterPath),
entry
);
ListView_SetItemState(Context->ListViewHandle, lvItemIndex, ITEM_CHECKED, LVIS_STATEIMAGEMASK);
}
}
PhReleaseQueuedLockShared(&PerfCounterListLock);
}
VOID PerfMonLoadList(
VOID
)
{
PPH_STRING settingsString;
PH_STRINGREF remaining;
settingsString = PhaGetStringSetting(SETTING_NAME_PERFMON_LIST);
remaining = settingsString->sr;
while (remaining.Length != 0)
{
PH_STRINGREF part;
PERF_COUNTER_ID id;
PPERF_COUNTER_ENTRY entry;
if (remaining.Length == 0)
break;
PhSplitStringRefAtChar(&remaining, ',', &part, &remaining);
InitializePerfCounterId(&id, PhCreateString2(&part));
entry = CreatePerfCounterEntry(&id);
DeletePerfCounterId(&id);
entry->UserReference = TRUE;
}
}
VOID PerfMonSaveList(
VOID
)
{
PH_STRING_BUILDER stringBuilder;
PPH_STRING settingsString;
PhInitializeStringBuilder(&stringBuilder, 260);
PhAcquireQueuedLockShared(&PerfCounterListLock);
for (ULONG i = 0; i < PerfCounterList->Count; i++)
{
PPERF_COUNTER_ENTRY entry = PhReferenceObjectSafe(PerfCounterList->Items[i]);
if (!entry)
continue;
if (entry->UserReference)
{
PhAppendFormatStringBuilder(&stringBuilder, L"%s,", PhGetStringOrEmpty(entry->Id.PerfCounterPath));
}
PhDereferenceObjectDeferDelete(entry);
}
PhReleaseQueuedLockShared(&PerfCounterListLock);
if (stringBuilder.String->Length != 0)
PhRemoveEndStringBuilder(&stringBuilder, 1);
settingsString = PH_AUTO(PhFinalStringBuilderString(&stringBuilder));
PhSetStringSetting2(SETTING_NAME_PERFMON_LIST, &settingsString->sr);
}
BOOLEAN PerfMonFindEntry(
_In_ PPERF_COUNTER_ID Id,
_In_ BOOLEAN RemoveUserReference
)
{
BOOLEAN found = FALSE;
PhAcquireQueuedLockShared(&PerfCounterListLock);
for (ULONG i = 0; i < PerfCounterList->Count; i++)
{
PPERF_COUNTER_ENTRY entry = PhReferenceObjectSafe(PerfCounterList->Items[i]);
if (!entry)
continue;
found = EquivalentPerfCounterId(&entry->Id, Id);
if (found)
{
if (RemoveUserReference)
{
if (entry->UserReference)
{
PhDereferenceObjectDeferDelete(entry);
entry->UserReference = FALSE;
}
}
PhDereferenceObjectDeferDelete(entry);
break;
}
else
{
PhDereferenceObjectDeferDelete(entry);
}
}
PhReleaseQueuedLockShared(&PerfCounterListLock);
return found;
}
VOID PerfMonShowCounters(
_In_ PPH_PERFMON_CONTEXT Context,
_In_ HWND Parent
)
{
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 = Parent;
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.";
if ((counterStatus = PdhBrowseCounters(&browseConfig)) != ERROR_SUCCESS)
{
goto CleanupExit;
}
if (PhCountStringZ(counterPathBuffer) == 0)
{
goto CleanupExit;
}
counterPathString = PhCreateString(counterPathBuffer);
if (PhFindCharInString(counterPathString, 0, '*') != -1) // Check for wildcards
{
ULONG wildCardLength = 0;
PdhExpandWildCardPath(
NULL,
PhGetString(counterPathString),
NULL,
&wildCardLength,
0
);
counterWildCardString = PhCreateStringEx(NULL, wildCardLength * sizeof(WCHAR));
if (PdhExpandWildCardPath(
NULL,
PhGetString(counterPathString),
PhGetString(counterWildCardString),
&wildCardLength,
0
) == ERROR_SUCCESS)
{
PH_STRINGREF part;
PH_STRINGREF remaining = counterWildCardString->sr;
while (remaining.Length != 0)
{
if (!PhSplitStringRefAtChar(&remaining, '\0', &part, &remaining))
break;
if (remaining.Length == 0)
break;
if (PdhValidatePath(part.Buffer) != ERROR_SUCCESS)
{
goto CleanupExit;
}
PerfMonAddCounter(Context, PhCreateString2(&part));
}
}
}
else
{
if (PdhValidatePath(PhGetString(counterPathString)) != ERROR_SUCCESS)
{
goto CleanupExit;
}
PerfMonAddCounter(Context, PhCreateString2(&counterPathString->sr));
}
CleanupExit:
if (counterWildCardString)
PhDereferenceObject(counterWildCardString);
if (counterPathString)
PhDereferenceObject(counterPathString);
}
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_DESTROY)
{
PerfMonSaveList();
RemoveProp(hwndDlg, L"Context");
PhFree(context);
}
}
if (context == NULL)
return FALSE;
switch (uMsg)
{
case WM_INITDIALOG:
{
context->ListViewHandle = GetDlgItem(hwndDlg, IDC_PERFCOUNTER_LISTVIEW);
PhCenterWindow(hwndDlg, GetParent(hwndDlg));
PhSetListViewStyle(context->ListViewHandle, FALSE, TRUE);
ListView_SetExtendedListViewStyleEx(context->ListViewHandle,
LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER,
LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER);
PhSetControlTheme(context->ListViewHandle, L"explorer");
PhAddListViewColumn(context->ListViewHandle, 0, 0, 0, LVCFMT_LEFT, 500, L"Counter");
PhSetExtendedListView(context->ListViewHandle);
PerfMonLoadCounters(context);
}
break;
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDC_ADD_BUTTON:
PerfMonShowCounters(context, hwndDlg);
break;
case IDCANCEL:
case IDOK:
EndDialog(hwndDlg, IDOK);
break;
}
}
break;
case WM_NOTIFY:
{
LPNMHDR header = (LPNMHDR)lParam;
if (header->code == LVN_ITEMCHANGED)
{
LPNM_LISTVIEW listView = (LPNM_LISTVIEW)lParam;
if (!PhTryAcquireReleaseQueuedLockExclusive(&PerfCounterListLock))
break;
if (listView->uChanged & LVIF_STATE)
{
switch (listView->uNewState & LVIS_STATEIMAGEMASK)
{
case 0x2000: // checked
{
PPERF_COUNTER_ID param = (PPERF_COUNTER_ID)listView->lParam;
if (!PerfMonFindEntry(param, FALSE))
{
PPERF_COUNTER_ENTRY entry;
entry = CreatePerfCounterEntry(param);
entry->UserReference = TRUE;
}
context->OptionsChanged = TRUE;
}
break;
case 0x1000: // unchecked
{
PPERF_COUNTER_ID param = (PPERF_COUNTER_ID)listView->lParam;
PerfMonFindEntry(param, TRUE);
context->OptionsChanged = TRUE;
}
break;
}
}
}
}
break;
}
return FALSE;
}
VOID ShowOptionsDialog(
_In_ HWND ParentHandle
)
{
DialogBox(
PluginInstance->DllBase,
MAKEINTRESOURCE(IDD_PERFMON_OPTIONS),
ParentHandle,
OptionsDlgProc
);
}

View File

@@ -0,0 +1,144 @@
/*
* Process Hacker Extra Plugins -
* Performance Monitor Plugin
*
* Copyright (C) 2015-2016 dmex
*
* This file is part of Process Hacker.
*
* Process Hacker 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 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _PERFMON_H_
#define _PERFMON_H_
#pragma comment(lib, "pdh.lib")
#define PLUGIN_NAME L"dmex.PerfMonPlugin"
#define SETTING_NAME_PERFMON_LIST (PLUGIN_NAME L".PerfMonList")
#define CINTERFACE
#define COBJMACROS
#include <phdk.h>
#include <phappresource.h>
#include <pdh.h>
#include <pdhmsg.h>
#include "resource.h"
extern PPH_PLUGIN PluginInstance;
extern PPH_LIST PerfCounterList;
extern PPH_OBJECT_TYPE PerfCounterEntryType;
extern PH_QUEUED_LOCK PerfCounterListLock;
typedef struct _PERF_COUNTER_ID
{
PPH_STRING PerfCounterPath;
} PERF_COUNTER_ID, *PPERF_COUNTER_ID;
typedef struct _PERF_COUNTER_ENTRY
{
PERF_COUNTER_ID Id;
HQUERY PerfQueryHandle;
HCOUNTER PerfCounterHandle;
PPDH_COUNTER_INFO PerfCounterInfo;
union
{
BOOLEAN BitField;
struct
{
BOOLEAN UserReference : 1;
BOOLEAN HaveFirstSample : 1;
BOOLEAN Spare : 6;
};
};
PH_UINT64_DELTA HistoryDelta;
PH_CIRCULAR_BUFFER_ULONG64 HistoryBuffer;
} PERF_COUNTER_ENTRY, *PPERF_COUNTER_ENTRY;
VOID PerfMonInitialize(
VOID
);
VOID PerfMonUpdate(
VOID
);
VOID InitializePerfCounterId(
_Out_ PPERF_COUNTER_ID Id,
_In_ PPH_STRING DevicePath
);
VOID CopyPerfCounterId(
_Out_ PPERF_COUNTER_ID Destination,
_In_ PPERF_COUNTER_ID Source
);
VOID DeletePerfCounterId(
_Inout_ PPERF_COUNTER_ID Id
);
BOOLEAN EquivalentPerfCounterId(
_In_ PPERF_COUNTER_ID Id1,
_In_ PPERF_COUNTER_ID Id2
);
PPERF_COUNTER_ENTRY CreatePerfCounterEntry(
_In_ PPERF_COUNTER_ID Id
);
VOID PerfMonLoadList(
VOID
);
VOID PerfMonSaveList(
VOID
);
typedef struct _PH_PERFMON_ENTRY
{
PPH_STRING Name;
} PH_PERFMON_ENTRY, *PPH_PERFMON_ENTRY;
typedef struct _PH_PERFMON_CONTEXT
{
BOOLEAN OptionsChanged;
BOOLEAN AddedChanged;
HWND ListViewHandle;
} PH_PERFMON_CONTEXT, *PPH_PERFMON_CONTEXT;
typedef struct _PH_PERFMON_SYSINFO_CONTEXT
{
PPERF_COUNTER_ENTRY Entry;
HWND WindowHandle;
HWND GraphHandle;
PPH_SYSINFO_SECTION SysinfoSection;
PH_GRAPH_STATE GraphState;
PH_LAYOUT_MANAGER LayoutManager;
PH_CALLBACK_REGISTRATION ProcessesUpdatedRegistration;
} PH_PERFMON_SYSINFO_CONTEXT, *PPH_PERFMON_SYSINFO_CONTEXT;
#define ITEM_CHECKED (INDEXTOSTATEIMAGEMASK(2))
#define ITEM_UNCHECKED (INDEXTOSTATEIMAGEMASK(1))
VOID ShowOptionsDialog(
_In_ HWND ParentHandle
);
VOID PerfMonCounterSysInfoInitializing(
_In_ PPH_PLUGIN_SYSINFO_POINTERS Pointers,
_In_ PPERF_COUNTER_ENTRY Entry
);
#endif _ROTHEADER_

View File

@@ -0,0 +1,22 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by PerfMonPlugin.rc
//
#define IDD_PERFMON_OPTIONS 112
#define IDD_PERFMON_DIALOG 113
#define IDC_GRAPH_LAYOUT 114
#define IDC_PERFCOUNTER_LISTVIEW 1023
#define IDC_ADD_BUTTON 1024
#define IDC_REMOVE_BUTTON 1025
#define IDC_COUNTERNAME 1026
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 115
#define _APS_NEXT_COMMAND_VALUE 40006
#define _APS_NEXT_CONTROL_VALUE 1027
#define _APS_NEXT_SYMED_VALUE 108
#endif
#endif