mirror of
https://github.com/mirror/processhacker
synced 2026-06-08 16:03:24 +00:00
The "Include CPU (and other) usage of children in collapsed processes" option now aggregates memory and I/O statistics; Change size formatting so that formatted values between 1000 and 1024 are disallowed; Fix bug in PhInitializeTreeNewColumnMenuEx regarding the "Reset Sort" menu item
git-svn-id: svn://svn.code.sf.net/p/processhacker/code@6320 21ef857c-d57f-4fe0-8362-d861dc6d29cd
This commit is contained in:
@@ -3,6 +3,7 @@ Process Hacker
|
||||
2.37
|
||||
* HIGHLIGHTS:
|
||||
* Updated for Windows 10
|
||||
* The "Include CPU (and other) usage of children in collapsed processes" option now aggregates memory and I/O statistics
|
||||
* Added regex search to "Find Handles or DLLs"
|
||||
* Added process exit codes to log
|
||||
* Fixed crash that occurred under some conditions when processes terminated
|
||||
|
||||
@@ -1321,8 +1321,8 @@ BEGIN
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,43,167,10
|
||||
CONTROL "Resolve addresses for network connections",IDC_ENABLENETWORKRESOLVE,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,55,155,10
|
||||
CONTROL "Include CPU usage of children in collapsed processes",IDC_PROPAGATECPUUSAGE,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,67,184,10
|
||||
CONTROL "Include CPU (and other) usage of children in collapsed processes",IDC_PROPAGATECPUUSAGE,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,67,223,10
|
||||
CONTROL "Show tooltips instantly",IDC_ENABLEINSTANTTOOLTIPS,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,79,88,10
|
||||
CONTROL "Enable cycle-based CPU usage",IDC_ENABLECYCLECPUUSAGE,
|
||||
@@ -2484,6 +2484,11 @@ BEGIN
|
||||
0
|
||||
END
|
||||
|
||||
IDD_OPTADVANCED AFX_DIALOG_LAYOUT
|
||||
BEGIN
|
||||
0
|
||||
END
|
||||
|
||||
#endif // English (Australia) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -1578,7 +1578,7 @@ VOID PhInitializeTreeNewColumnMenuEx(
|
||||
|
||||
TreeNew_GetSort(Data->TreeNewHandle, &sortColumn, &sortOrder);
|
||||
|
||||
if (sortColumn != Data->DefaultSortColumn || sortOrder != Data->DefaultSortOrder)
|
||||
if (sortOrder != Data->DefaultSortOrder || (Data->DefaultSortOrder != NoSortOrder && sortColumn != Data->DefaultSortColumn))
|
||||
resetSortMenuItem = PhCreateEMenuItem(0, PH_TN_COLUMN_MENU_RESET_SORT_ID, L"Reset Sort", NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,20 @@
|
||||
#include <emenu.h>
|
||||
#include <verify.h>
|
||||
|
||||
typedef enum _PHP_AGGREGATE_TYPE
|
||||
{
|
||||
AggregateTypeFloat,
|
||||
AggregateTypeInt32,
|
||||
AggregateTypeInt64,
|
||||
AggregateTypeIntPtr
|
||||
} PHP_AGGREGATE_TYPE;
|
||||
|
||||
typedef enum _PHP_AGGREGATE_LOCATION
|
||||
{
|
||||
AggregateLocationProcessNode,
|
||||
AggregateLocationProcessItem
|
||||
} PHP_AGGREGATE_LOCATION;
|
||||
|
||||
VOID PhpRemoveProcessNode(
|
||||
_In_ PPH_PROCESS_NODE ProcessNode
|
||||
);
|
||||
@@ -692,21 +706,86 @@ static BOOLEAN PhpFormatInt32GroupDigits(
|
||||
}
|
||||
}
|
||||
|
||||
static FLOAT PhpCalculateInclusiveCpuUsage(
|
||||
_In_ PPH_PROCESS_NODE ProcessNode
|
||||
FORCEINLINE PVOID PhpFieldForAggregate(
|
||||
_In_ PPH_PROCESS_NODE ProcessNode,
|
||||
_In_ PHP_AGGREGATE_LOCATION Location,
|
||||
_In_ SIZE_T FieldOffset
|
||||
)
|
||||
{
|
||||
PVOID object;
|
||||
|
||||
switch (Location)
|
||||
{
|
||||
case AggregateLocationProcessNode:
|
||||
object = ProcessNode;
|
||||
break;
|
||||
case AggregateLocationProcessItem:
|
||||
object = ProcessNode->ProcessItem;
|
||||
break;
|
||||
default:
|
||||
PhRaiseStatus(STATUS_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
return PTR_ADD_OFFSET(object, FieldOffset);
|
||||
}
|
||||
|
||||
FORCEINLINE VOID PhpAccumulateField(
|
||||
_Inout_ PVOID Accumulator,
|
||||
_In_ PVOID Value,
|
||||
_In_ PHP_AGGREGATE_TYPE Type
|
||||
)
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
case AggregateTypeFloat:
|
||||
*(PFLOAT)Accumulator += *(PFLOAT)Value;
|
||||
break;
|
||||
case AggregateTypeInt32:
|
||||
*(PULONG)Accumulator += *(PULONG)Value;
|
||||
break;
|
||||
case AggregateTypeInt64:
|
||||
*(PULONG64)Accumulator += *(PULONG64)Value;
|
||||
break;
|
||||
case AggregateTypeIntPtr:
|
||||
*(PULONG_PTR)Accumulator += *(PULONG_PTR)Value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static VOID PhpAggregateField(
|
||||
_In_ PPH_PROCESS_NODE ProcessNode,
|
||||
_In_ PHP_AGGREGATE_TYPE Type,
|
||||
_In_ PHP_AGGREGATE_LOCATION Location,
|
||||
_In_ SIZE_T FieldOffset,
|
||||
_Inout_ PVOID AggregatedValue
|
||||
)
|
||||
{
|
||||
FLOAT cpuUsage;
|
||||
ULONG i;
|
||||
|
||||
cpuUsage = ProcessNode->ProcessItem->CpuUsage;
|
||||
PhpAccumulateField(AggregatedValue, PhpFieldForAggregate(ProcessNode, Location, FieldOffset), Type);
|
||||
|
||||
for (i = 0; i < ProcessNode->Children->Count; i++)
|
||||
{
|
||||
cpuUsage += PhpCalculateInclusiveCpuUsage(ProcessNode->Children->Items[i]);
|
||||
PhpAggregateField(ProcessNode->Children->Items[i], Type, Location, FieldOffset, AggregatedValue);
|
||||
}
|
||||
}
|
||||
|
||||
return cpuUsage;
|
||||
static VOID PhpAggregateFieldIfNeeded(
|
||||
_In_ PPH_PROCESS_NODE ProcessNode,
|
||||
_In_ PHP_AGGREGATE_TYPE Type,
|
||||
_In_ PHP_AGGREGATE_LOCATION Location,
|
||||
_In_ SIZE_T FieldOffset,
|
||||
_Inout_ PVOID AggregatedValue
|
||||
)
|
||||
{
|
||||
if (!PhCsPropagateCpuUsage || ProcessNode->Node.Expanded || ProcessTreeListSortOrder != NoSortOrder)
|
||||
{
|
||||
PhpAccumulateField(AggregatedValue, PhpFieldForAggregate(ProcessNode, Location, FieldOffset), Type);
|
||||
}
|
||||
else
|
||||
{
|
||||
PhpAggregateField(ProcessNode, Type, Location, FieldOffset, AggregatedValue);
|
||||
}
|
||||
}
|
||||
|
||||
static VOID PhpUpdateProcessNodeWsCounters(
|
||||
@@ -1943,16 +2022,10 @@ BOOLEAN NTAPI PhpProcessTreeNewCallback(
|
||||
break;
|
||||
case PHPRTLC_CPU:
|
||||
{
|
||||
FLOAT cpuUsage;
|
||||
FLOAT cpuUsage = 0;
|
||||
|
||||
if (!PhCsPropagateCpuUsage || node->Node.Expanded || ProcessTreeListSortOrder != NoSortOrder)
|
||||
{
|
||||
cpuUsage = processItem->CpuUsage * 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpuUsage = PhpCalculateInclusiveCpuUsage(node) * 100;
|
||||
}
|
||||
PhpAggregateFieldIfNeeded(node, AggregateTypeFloat, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, CpuUsage), &cpuUsage);
|
||||
cpuUsage *= 100;
|
||||
|
||||
if (cpuUsage >= 0.01)
|
||||
{
|
||||
@@ -1985,18 +2058,16 @@ BOOLEAN NTAPI PhpProcessTreeNewCallback(
|
||||
break;
|
||||
case PHPRTLC_IOTOTALRATE:
|
||||
{
|
||||
ULONG64 number;
|
||||
ULONG64 number = 0;
|
||||
|
||||
if (processItem->IoReadDelta.Delta != processItem->IoReadDelta.Value) // delta is wrong on first run of process provider
|
||||
{
|
||||
number = processItem->IoReadDelta.Delta + processItem->IoWriteDelta.Delta + processItem->IoOtherDelta.Delta;
|
||||
PhpAggregateFieldIfNeeded(node, AggregateTypeInt64, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, IoReadDelta.Delta), &number);
|
||||
PhpAggregateFieldIfNeeded(node, AggregateTypeInt64, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, IoWriteDelta.Delta), &number);
|
||||
PhpAggregateFieldIfNeeded(node, AggregateTypeInt64, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, IoOtherDelta.Delta), &number);
|
||||
number *= 1000;
|
||||
number /= PhCsUpdateInterval;
|
||||
}
|
||||
else
|
||||
{
|
||||
number = 0;
|
||||
}
|
||||
|
||||
if (number != 0)
|
||||
{
|
||||
@@ -2010,8 +2081,12 @@ BOOLEAN NTAPI PhpProcessTreeNewCallback(
|
||||
}
|
||||
break;
|
||||
case PHPRTLC_PRIVATEBYTES:
|
||||
PhMoveReference(&node->PrivateBytesText, PhFormatSize(processItem->VmCounters.PagefileUsage, -1));
|
||||
getCellText->Text = node->PrivateBytesText->sr;
|
||||
{
|
||||
SIZE_T value = 0;
|
||||
PhpAggregateFieldIfNeeded(node, AggregateTypeIntPtr, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, VmCounters.PagefileUsage), &value);
|
||||
PhMoveReference(&node->PrivateBytesText, PhFormatSize(value, -1));
|
||||
getCellText->Text = node->PrivateBytesText->sr;
|
||||
}
|
||||
break;
|
||||
case PHPRTLC_USERNAME:
|
||||
getCellText->Text = PhGetStringRef(processItem->UserName);
|
||||
@@ -2039,8 +2114,12 @@ BOOLEAN NTAPI PhpProcessTreeNewCallback(
|
||||
getCellText->Text = node->PeakPrivateBytesText->sr;
|
||||
break;
|
||||
case PHPRTLC_WORKINGSET:
|
||||
PhMoveReference(&node->WorkingSetText, PhFormatSize(processItem->VmCounters.WorkingSetSize, -1));
|
||||
getCellText->Text = node->WorkingSetText->sr;
|
||||
{
|
||||
SIZE_T value = 0;
|
||||
PhpAggregateFieldIfNeeded(node, AggregateTypeIntPtr, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, VmCounters.WorkingSetSize), &value);
|
||||
PhMoveReference(&node->WorkingSetText, PhFormatSize(value, -1));
|
||||
getCellText->Text = node->WorkingSetText->sr;
|
||||
}
|
||||
break;
|
||||
case PHPRTLC_PEAKWORKINGSET:
|
||||
PhMoveReference(&node->PeakWorkingSetText, PhFormatSize(processItem->VmCounters.PeakWorkingSetSize, -1));
|
||||
@@ -2091,10 +2170,18 @@ BOOLEAN NTAPI PhpProcessTreeNewCallback(
|
||||
PhInitializeStringRefLongHint(&getCellText->Text, node->BasePriorityText);
|
||||
break;
|
||||
case PHPRTLC_THREADS:
|
||||
PhpFormatInt32GroupDigits(processItem->NumberOfThreads, node->ThreadsText, sizeof(node->ThreadsText), &getCellText->Text);
|
||||
{
|
||||
ULONG value = 0;
|
||||
PhpAggregateFieldIfNeeded(node, AggregateTypeInt32, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, NumberOfThreads), &value);
|
||||
PhpFormatInt32GroupDigits(value, node->ThreadsText, sizeof(node->ThreadsText), &getCellText->Text);
|
||||
}
|
||||
break;
|
||||
case PHPRTLC_HANDLES:
|
||||
PhpFormatInt32GroupDigits(processItem->NumberOfHandles, node->HandlesText, sizeof(node->HandlesText), &getCellText->Text);
|
||||
{
|
||||
ULONG value = 0;
|
||||
PhpAggregateFieldIfNeeded(node, AggregateTypeInt32, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, NumberOfHandles), &value);
|
||||
PhpFormatInt32GroupDigits(value, node->HandlesText, sizeof(node->HandlesText), &getCellText->Text);
|
||||
}
|
||||
break;
|
||||
case PHPRTLC_GDIHANDLES:
|
||||
PhpUpdateProcessNodeGdiUserHandles(node);
|
||||
@@ -2106,18 +2193,15 @@ BOOLEAN NTAPI PhpProcessTreeNewCallback(
|
||||
break;
|
||||
case PHPRTLC_IORORATE:
|
||||
{
|
||||
ULONG64 number;
|
||||
ULONG64 number = 0;
|
||||
|
||||
if (processItem->IoReadDelta.Delta != processItem->IoReadDelta.Value)
|
||||
{
|
||||
number = processItem->IoReadDelta.Delta + processItem->IoOtherDelta.Delta;
|
||||
PhpAggregateFieldIfNeeded(node, AggregateTypeInt64, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, IoReadDelta.Delta), &number);
|
||||
PhpAggregateFieldIfNeeded(node, AggregateTypeInt64, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, IoOtherDelta.Delta), &number);
|
||||
number *= 1000;
|
||||
number /= PhCsUpdateInterval;
|
||||
}
|
||||
else
|
||||
{
|
||||
number = 0;
|
||||
}
|
||||
|
||||
if (number != 0)
|
||||
{
|
||||
@@ -2132,18 +2216,14 @@ BOOLEAN NTAPI PhpProcessTreeNewCallback(
|
||||
break;
|
||||
case PHPRTLC_IOWRATE:
|
||||
{
|
||||
ULONG64 number;
|
||||
ULONG64 number = 0;
|
||||
|
||||
if (processItem->IoReadDelta.Delta != processItem->IoReadDelta.Value)
|
||||
{
|
||||
number = processItem->IoWriteDelta.Delta;
|
||||
PhpAggregateFieldIfNeeded(node, AggregateTypeInt64, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, IoWriteDelta.Delta), &number);
|
||||
number *= 1000;
|
||||
number /= PhCsUpdateInterval;
|
||||
}
|
||||
else
|
||||
{
|
||||
number = 0;
|
||||
}
|
||||
|
||||
if (number != 0)
|
||||
{
|
||||
@@ -2294,9 +2374,12 @@ BOOLEAN NTAPI PhpProcessTreeNewCallback(
|
||||
case PHPRTLC_CYCLES:
|
||||
if (WindowsVersion >= WINDOWS_7)
|
||||
{
|
||||
if (processItem->CycleTimeDelta.Value != 0)
|
||||
ULONG64 value = 0;
|
||||
PhpAggregateFieldIfNeeded(node, AggregateTypeInt64, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, CycleTimeDelta.Value), &value);
|
||||
|
||||
if (value != 0)
|
||||
{
|
||||
PhMoveReference(&node->CyclesText, PhFormatUInt64(processItem->CycleTimeDelta.Value, TRUE));
|
||||
PhMoveReference(&node->CyclesText, PhFormatUInt64(value, TRUE));
|
||||
getCellText->Text = node->CyclesText->sr;
|
||||
}
|
||||
}
|
||||
@@ -2308,9 +2391,12 @@ BOOLEAN NTAPI PhpProcessTreeNewCallback(
|
||||
case PHPRTLC_CYCLESDELTA:
|
||||
if (WindowsVersion >= WINDOWS_7)
|
||||
{
|
||||
if (processItem->CycleTimeDelta.Delta != 0)
|
||||
ULONG64 value = 0;
|
||||
PhpAggregateFieldIfNeeded(node, AggregateTypeInt64, AggregateLocationProcessItem, FIELD_OFFSET(PH_PROCESS_ITEM, CycleTimeDelta.Delta), &value);
|
||||
|
||||
if (value != 0)
|
||||
{
|
||||
PhMoveReference(&node->CyclesDeltaText, PhFormatUInt64(processItem->CycleTimeDelta.Delta, TRUE));
|
||||
PhMoveReference(&node->CyclesDeltaText, PhFormatUInt64(value, TRUE));
|
||||
getCellText->Text = node->CyclesDeltaText->sr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -494,7 +494,7 @@ CommonInt64Format:
|
||||
maxSizeUnit = PhMaxSizeUnit;
|
||||
|
||||
while (
|
||||
s >= 1024 &&
|
||||
s >= 1000 &&
|
||||
i < sizeof(PhpSizeUnitNamesCounted) / sizeof(PH_STRINGREF) &&
|
||||
i < maxSizeUnit
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user