784 lines
31 KiB
C
784 lines
31 KiB
C
/*
|
|
* Process Hacker Extended Tools -
|
|
* process and network tree support
|
|
*
|
|
* Copyright (C) 2011 wj32
|
|
*
|
|
* 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 "exttools.h"
|
|
#define CINTERFACE
|
|
#define COBJMACROS
|
|
#include <netfw.h>
|
|
|
|
LONG EtpProcessTreeNewSortFunction(
|
|
_In_ PVOID Node1,
|
|
_In_ PVOID Node2,
|
|
_In_ ULONG SubId,
|
|
_In_ PVOID Context
|
|
);
|
|
|
|
LONG EtpNetworkTreeNewSortFunction(
|
|
_In_ PVOID Node1,
|
|
_In_ PVOID Node2,
|
|
_In_ ULONG SubId,
|
|
_In_ PVOID Context
|
|
);
|
|
|
|
typedef struct _COLUMN_INFO
|
|
{
|
|
ULONG SubId;
|
|
PWSTR Text;
|
|
ULONG Width;
|
|
ULONG Alignment;
|
|
ULONG TextFlags;
|
|
BOOLEAN SortDescending;
|
|
} COLUMN_INFO, *PCOLUMN_INFO;
|
|
|
|
static ULONG ProcessTreeListSortColumn;
|
|
static PH_SORT_ORDER ProcessTreeListSortOrder;
|
|
|
|
static GUID IID_INetFwMgr_I = { 0xf7898af5, 0xcac4, 0x4632, { 0xa2, 0xec, 0xda, 0x06, 0xe5, 0x11, 0x1a, 0xf2 } };
|
|
static GUID CLSID_NetFwMgr_I = { 0x304ce942, 0x6e39, 0x40d8, { 0x94, 0x3a, 0xb9, 0x13, 0xc4, 0x0c, 0x9c, 0xd4 } };
|
|
|
|
VOID EtpAddTreeNewColumn(
|
|
_In_ PPH_PLUGIN_TREENEW_INFORMATION TreeNewInfo,
|
|
_In_ ULONG SubId,
|
|
_In_ PWSTR Text,
|
|
_In_ ULONG Width,
|
|
_In_ ULONG Alignment,
|
|
_In_ ULONG TextFlags,
|
|
_In_ BOOLEAN SortDescending,
|
|
_In_ PPH_PLUGIN_TREENEW_SORT_FUNCTION SortFunction
|
|
)
|
|
{
|
|
PH_TREENEW_COLUMN column;
|
|
|
|
memset(&column, 0, sizeof(PH_TREENEW_COLUMN));
|
|
column.SortDescending = SortDescending;
|
|
column.Text = Text;
|
|
column.Width = Width;
|
|
column.Alignment = Alignment;
|
|
column.TextFlags = TextFlags;
|
|
|
|
PhPluginAddTreeNewColumn(
|
|
PluginInstance,
|
|
TreeNewInfo->CmData,
|
|
&column,
|
|
SubId,
|
|
NULL,
|
|
SortFunction
|
|
);
|
|
}
|
|
|
|
VOID EtProcessTreeNewInitializing(
|
|
_In_ PVOID Parameter
|
|
)
|
|
{
|
|
static COLUMN_INFO columns[] =
|
|
{
|
|
{ ETPRTNC_DISKREADS, L"Disk reads", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_DISKWRITES, L"Disk writes", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_DISKREADBYTES, L"Disk read bytes", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_DISKWRITEBYTES, L"Disk write bytes", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_DISKTOTALBYTES, L"Disk total bytes", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_DISKREADSDELTA, L"Disk reads delta", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_DISKWRITESDELTA, L"Disk writes delta", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_DISKREADBYTESDELTA, L"Disk read bytes delta", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_DISKWRITEBYTESDELTA, L"Disk write bytes delta", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_DISKTOTALBYTESDELTA, L"Disk total bytes delta", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_NETWORKRECEIVES, L"Network receives", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_NETWORKSENDS, L"Network sends", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_NETWORKRECEIVEBYTES, L"Network receive bytes", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_NETWORKSENDBYTES, L"Network send bytes", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_NETWORKTOTALBYTES, L"Network total bytes", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_NETWORKRECEIVESDELTA, L"Network receives delta", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_NETWORKSENDSDELTA, L"Network sends delta", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_NETWORKRECEIVEBYTESDELTA, L"Network receive bytes delta", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_NETWORKSENDBYTESDELTA, L"Network send bytes delta", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_NETWORKTOTALBYTESDELTA, L"Network total bytes delta", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_HARDFAULTS, L"Hard faults", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_HARDFAULTSDELTA, L"Hard faults delta", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_PEAKTHREADS, L"Peak threads", 45, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_GPU, L"GPU", 45, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_GPUDEDICATEDBYTES, L"GPU dedicated bytes", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_GPUSHAREDBYTES, L"GPU shared bytes", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_DISKREADRATE, L"Disk read rate", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_DISKWRITERATE, L"Disk write rate", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_DISKTOTALRATE, L"Disk total rate", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_NETWORKRECEIVERATE, L"Network receive rate", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_NETWORKSENDRATE, L"Network send rate", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETPRTNC_NETWORKTOTALRATE, L"Network total rate", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE }
|
|
};
|
|
|
|
PPH_PLUGIN_TREENEW_INFORMATION treeNewInfo = Parameter;
|
|
ULONG i;
|
|
|
|
for (i = 0; i < sizeof(columns) / sizeof(COLUMN_INFO); i++)
|
|
{
|
|
EtpAddTreeNewColumn(treeNewInfo, columns[i].SubId, columns[i].Text, columns[i].Width, columns[i].Alignment,
|
|
columns[i].TextFlags, columns[i].SortDescending, EtpProcessTreeNewSortFunction);
|
|
}
|
|
|
|
PhPluginEnableTreeNewNotify(PluginInstance, treeNewInfo->CmData);
|
|
}
|
|
|
|
FLOAT EtpCalculateInclusiveGpuUsage(
|
|
_In_ PPH_PROCESS_NODE ProcessNode
|
|
)
|
|
{
|
|
FLOAT gpuUsage;
|
|
ULONG i;
|
|
|
|
gpuUsage = EtGetProcessBlock(ProcessNode->ProcessItem)->GpuNodeUsage;
|
|
|
|
for (i = 0; i < ProcessNode->Children->Count; i++)
|
|
{
|
|
gpuUsage += EtpCalculateInclusiveGpuUsage(ProcessNode->Children->Items[i]);
|
|
}
|
|
|
|
return gpuUsage;
|
|
}
|
|
|
|
VOID EtProcessTreeNewMessage(
|
|
_In_ PVOID Parameter
|
|
)
|
|
{
|
|
PPH_PLUGIN_TREENEW_MESSAGE message = Parameter;
|
|
PPH_PROCESS_NODE processNode;
|
|
PET_PROCESS_BLOCK block;
|
|
|
|
if (message->Message == TreeNewGetCellText)
|
|
{
|
|
PPH_TREENEW_GET_CELL_TEXT getCellText = message->Parameter1;
|
|
PPH_STRING text;
|
|
|
|
processNode = (PPH_PROCESS_NODE)getCellText->Node;
|
|
block = EtGetProcessBlock(processNode->ProcessItem);
|
|
|
|
PhAcquireQueuedLockExclusive(&block->TextCacheLock);
|
|
|
|
if (block->TextCacheValid[message->SubId])
|
|
{
|
|
if (block->TextCache[message->SubId])
|
|
getCellText->Text = block->TextCache[message->SubId]->sr;
|
|
}
|
|
else
|
|
{
|
|
text = NULL;
|
|
|
|
switch (message->SubId)
|
|
{
|
|
case ETPRTNC_DISKREADS:
|
|
if (block->DiskReadCount != 0)
|
|
text = PhFormatUInt64(block->DiskReadCount, TRUE);
|
|
break;
|
|
case ETPRTNC_DISKWRITES:
|
|
if (block->DiskWriteCount != 0)
|
|
text = PhFormatUInt64(block->DiskWriteCount, TRUE);
|
|
break;
|
|
case ETPRTNC_DISKREADBYTES:
|
|
if (block->DiskReadRaw != 0)
|
|
text = PhFormatSize(block->DiskReadRaw, -1);
|
|
break;
|
|
case ETPRTNC_DISKWRITEBYTES:
|
|
if (block->DiskWriteRaw != 0)
|
|
text = PhFormatSize(block->DiskWriteRaw, -1);
|
|
break;
|
|
case ETPRTNC_DISKTOTALBYTES:
|
|
if (block->DiskReadRaw + block->DiskWriteRaw != 0)
|
|
text = PhFormatSize(block->DiskReadRaw + block->DiskWriteRaw, -1);
|
|
break;
|
|
case ETPRTNC_DISKREADSDELTA:
|
|
if (block->DiskReadDelta.Delta != 0)
|
|
text = PhFormatUInt64(block->DiskReadDelta.Delta, TRUE);
|
|
break;
|
|
case ETPRTNC_DISKWRITESDELTA:
|
|
if (block->DiskWriteDelta.Delta != 0)
|
|
text = PhFormatUInt64(block->DiskWriteDelta.Delta, TRUE);
|
|
break;
|
|
case ETPRTNC_DISKREADBYTESDELTA:
|
|
if (block->DiskReadRawDelta.Delta != 0)
|
|
text = PhFormatSize(block->DiskReadRawDelta.Delta, -1);
|
|
break;
|
|
case ETPRTNC_DISKWRITEBYTESDELTA:
|
|
if (block->DiskWriteRawDelta.Delta != 0)
|
|
text = PhFormatSize(block->DiskWriteRawDelta.Delta, -1);
|
|
break;
|
|
case ETPRTNC_DISKTOTALBYTESDELTA:
|
|
if (block->DiskReadRawDelta.Delta + block->DiskWriteRawDelta.Delta != 0)
|
|
text = PhFormatSize(block->DiskReadRawDelta.Delta + block->DiskWriteRawDelta.Delta, -1);
|
|
break;
|
|
case ETPRTNC_NETWORKRECEIVES:
|
|
if (block->NetworkReceiveCount != 0)
|
|
text = PhFormatUInt64(block->NetworkReceiveCount, TRUE);
|
|
break;
|
|
case ETPRTNC_NETWORKSENDS:
|
|
if (block->NetworkSendCount != 0)
|
|
text = PhFormatUInt64(block->NetworkSendCount, TRUE);
|
|
break;
|
|
case ETPRTNC_NETWORKRECEIVEBYTES:
|
|
if (block->NetworkReceiveRaw != 0)
|
|
text = PhFormatSize(block->NetworkReceiveRaw, -1);
|
|
break;
|
|
case ETPRTNC_NETWORKSENDBYTES:
|
|
if (block->NetworkSendRaw != 0)
|
|
text = PhFormatSize(block->NetworkSendRaw, -1);
|
|
break;
|
|
case ETPRTNC_NETWORKTOTALBYTES:
|
|
if (block->NetworkReceiveRaw + block->NetworkSendRaw != 0)
|
|
text = PhFormatSize(block->NetworkReceiveRaw + block->NetworkSendRaw, -1);
|
|
break;
|
|
case ETPRTNC_NETWORKRECEIVESDELTA:
|
|
if (block->NetworkReceiveDelta.Delta != 0)
|
|
text = PhFormatUInt64(block->NetworkReceiveDelta.Delta, TRUE);
|
|
break;
|
|
case ETPRTNC_NETWORKSENDSDELTA:
|
|
if (block->NetworkSendDelta.Delta != 0)
|
|
text = PhFormatUInt64(block->NetworkSendDelta.Delta, TRUE);
|
|
break;
|
|
case ETPRTNC_NETWORKRECEIVEBYTESDELTA:
|
|
if (block->NetworkReceiveRawDelta.Delta != 0)
|
|
text = PhFormatSize(block->NetworkReceiveRawDelta.Delta, -1);
|
|
break;
|
|
case ETPRTNC_NETWORKSENDBYTESDELTA:
|
|
if (block->NetworkSendRawDelta.Delta != 0)
|
|
text = PhFormatSize(block->NetworkSendRawDelta.Delta, -1);
|
|
break;
|
|
case ETPRTNC_NETWORKTOTALBYTESDELTA:
|
|
if (block->NetworkReceiveRawDelta.Delta + block->NetworkSendRawDelta.Delta != 0)
|
|
text = PhFormatSize(block->NetworkReceiveRawDelta.Delta + block->NetworkSendRawDelta.Delta, -1);
|
|
break;
|
|
case ETPRTNC_HARDFAULTS:
|
|
text = PhFormatUInt64(block->HardFaultsDelta.Value, TRUE);
|
|
break;
|
|
case ETPRTNC_HARDFAULTSDELTA:
|
|
if (block->HardFaultsDelta.Delta != 0)
|
|
text = PhFormatUInt64(block->HardFaultsDelta.Delta, TRUE);
|
|
break;
|
|
case ETPRTNC_PEAKTHREADS:
|
|
text = PhFormatUInt64(block->ProcessItem->PeakNumberOfThreads, TRUE);
|
|
break;
|
|
case ETPRTNC_GPU:
|
|
{
|
|
FLOAT gpuUsage;
|
|
|
|
if (!PhGetIntegerSetting(L"PropagateCpuUsage") || processNode->Node.Expanded || ProcessTreeListSortOrder != NoSortOrder)
|
|
{
|
|
gpuUsage = block->GpuNodeUsage * 100;
|
|
}
|
|
else
|
|
{
|
|
gpuUsage = EtpCalculateInclusiveGpuUsage(processNode) * 100;
|
|
}
|
|
|
|
if (gpuUsage >= 0.01)
|
|
{
|
|
PH_FORMAT format;
|
|
|
|
PhInitFormatF(&format, gpuUsage, 2);
|
|
text = PhFormat(&format, 1, 0);
|
|
}
|
|
}
|
|
break;
|
|
case ETPRTNC_GPUDEDICATEDBYTES:
|
|
if (block->GpuDedicatedUsage != 0)
|
|
text = PhFormatSize(block->GpuDedicatedUsage, -1);
|
|
break;
|
|
case ETPRTNC_GPUSHAREDBYTES:
|
|
if (block->GpuSharedUsage != 0)
|
|
text = PhFormatSize(block->GpuSharedUsage, -1);
|
|
break;
|
|
case ETPRTNC_DISKREADRATE:
|
|
if (block->DiskReadRawDelta.Delta != 0)
|
|
EtFormatRate(block->DiskReadRawDelta.Delta, &text, NULL);
|
|
break;
|
|
case ETPRTNC_DISKWRITERATE:
|
|
if (block->DiskWriteRawDelta.Delta != 0)
|
|
EtFormatRate(block->DiskWriteRawDelta.Delta, &text, NULL);
|
|
break;
|
|
case ETPRTNC_DISKTOTALRATE:
|
|
if (block->DiskReadRawDelta.Delta + block->DiskWriteRawDelta.Delta != 0)
|
|
EtFormatRate(block->DiskReadRawDelta.Delta + block->DiskWriteRawDelta.Delta, &text, NULL);
|
|
break;
|
|
case ETPRTNC_NETWORKRECEIVERATE:
|
|
if (block->NetworkReceiveRawDelta.Delta != 0)
|
|
EtFormatRate(block->NetworkReceiveRawDelta.Delta, &text, NULL);
|
|
break;
|
|
case ETPRTNC_NETWORKSENDRATE:
|
|
if (block->NetworkSendRawDelta.Delta != 0)
|
|
EtFormatRate(block->NetworkSendRawDelta.Delta, &text, NULL);
|
|
break;
|
|
case ETPRTNC_NETWORKTOTALRATE:
|
|
if (block->NetworkReceiveRawDelta.Delta + block->NetworkSendRawDelta.Delta != 0)
|
|
EtFormatRate(block->NetworkReceiveRawDelta.Delta + block->NetworkSendRawDelta.Delta, &text, NULL);
|
|
break;
|
|
}
|
|
|
|
if (text)
|
|
{
|
|
getCellText->Text = text->sr;
|
|
}
|
|
|
|
PhMoveReference(&block->TextCache[message->SubId], text);
|
|
block->TextCacheValid[message->SubId] = TRUE;
|
|
}
|
|
|
|
PhReleaseQueuedLockExclusive(&block->TextCacheLock);
|
|
}
|
|
else if (message->Message == TreeNewSortChanged)
|
|
{
|
|
TreeNew_GetSort(message->TreeNewHandle, &ProcessTreeListSortColumn, &ProcessTreeListSortOrder);
|
|
}
|
|
else if (message->Message == TreeNewNodeExpanding)
|
|
{
|
|
processNode = message->Parameter1;
|
|
block = EtGetProcessBlock(processNode->ProcessItem);
|
|
|
|
if (PhGetIntegerSetting(L"PropagateCpuUsage"))
|
|
block->TextCacheValid[ETPRTNC_GPU] = FALSE;
|
|
}
|
|
}
|
|
|
|
LONG EtpProcessTreeNewSortFunction(
|
|
_In_ PVOID Node1,
|
|
_In_ PVOID Node2,
|
|
_In_ ULONG SubId,
|
|
_In_ PVOID Context
|
|
)
|
|
{
|
|
LONG result;
|
|
PPH_PROCESS_NODE node1 = Node1;
|
|
PPH_PROCESS_NODE node2 = Node2;
|
|
PET_PROCESS_BLOCK block1;
|
|
PET_PROCESS_BLOCK block2;
|
|
|
|
block1 = EtGetProcessBlock(node1->ProcessItem);
|
|
block2 = EtGetProcessBlock(node2->ProcessItem);
|
|
|
|
result = 0;
|
|
|
|
switch (SubId)
|
|
{
|
|
case ETPRTNC_DISKREADS:
|
|
result = uint64cmp(block1->DiskReadCount, block2->DiskReadCount);
|
|
break;
|
|
case ETPRTNC_DISKWRITES:
|
|
result = uint64cmp(block1->DiskWriteCount, block2->DiskWriteCount);
|
|
break;
|
|
case ETPRTNC_DISKREADBYTES:
|
|
result = uint64cmp(block1->DiskReadRaw, block2->DiskReadRaw);
|
|
break;
|
|
case ETPRTNC_DISKWRITEBYTES:
|
|
result = uint64cmp(block1->DiskWriteRaw, block2->DiskWriteRaw);
|
|
break;
|
|
case ETPRTNC_DISKTOTALBYTES:
|
|
result = uint64cmp(block1->DiskReadRaw + block1->DiskWriteRaw, block2->DiskReadRaw + block2->DiskWriteRaw);
|
|
break;
|
|
case ETPRTNC_DISKREADSDELTA:
|
|
result = uint64cmp(block1->DiskReadDelta.Delta, block2->DiskReadDelta.Delta);
|
|
break;
|
|
case ETPRTNC_DISKWRITESDELTA:
|
|
result = uint64cmp(block1->DiskWriteDelta.Delta, block2->DiskWriteDelta.Delta);
|
|
break;
|
|
case ETPRTNC_DISKREADBYTESDELTA:
|
|
result = uint64cmp(block1->DiskReadRawDelta.Delta, block2->DiskReadRawDelta.Delta);
|
|
break;
|
|
case ETPRTNC_DISKWRITEBYTESDELTA:
|
|
result = uint64cmp(block1->DiskWriteRawDelta.Delta, block2->DiskWriteRawDelta.Delta);
|
|
break;
|
|
case ETPRTNC_DISKTOTALBYTESDELTA:
|
|
result = uint64cmp(block1->DiskReadRawDelta.Delta + block1->DiskWriteRawDelta.Delta, block2->DiskReadRawDelta.Delta + block2->DiskWriteRawDelta.Delta);
|
|
break;
|
|
case ETPRTNC_NETWORKRECEIVES:
|
|
result = uint64cmp(block1->NetworkReceiveCount, block2->NetworkReceiveCount);
|
|
break;
|
|
case ETPRTNC_NETWORKSENDS:
|
|
result = uint64cmp(block1->NetworkSendCount, block2->NetworkSendCount);
|
|
break;
|
|
case ETPRTNC_NETWORKRECEIVEBYTES:
|
|
result = uint64cmp(block1->NetworkReceiveRaw, block2->NetworkReceiveRaw);
|
|
break;
|
|
case ETPRTNC_NETWORKSENDBYTES:
|
|
result = uint64cmp(block1->NetworkSendRaw, block2->NetworkSendRaw);
|
|
break;
|
|
case ETPRTNC_NETWORKTOTALBYTES:
|
|
result = uint64cmp(block1->NetworkReceiveRaw + block1->NetworkSendRaw, block2->NetworkReceiveRaw + block2->NetworkSendRaw);
|
|
break;
|
|
case ETPRTNC_NETWORKRECEIVESDELTA:
|
|
result = uint64cmp(block1->NetworkReceiveDelta.Delta, block2->NetworkReceiveDelta.Delta);
|
|
break;
|
|
case ETPRTNC_NETWORKSENDSDELTA:
|
|
result = uint64cmp(block1->NetworkSendDelta.Delta, block2->NetworkSendDelta.Delta);
|
|
break;
|
|
case ETPRTNC_NETWORKRECEIVEBYTESDELTA:
|
|
result = uint64cmp(block1->NetworkReceiveRawDelta.Delta, block2->NetworkReceiveRawDelta.Delta);
|
|
break;
|
|
case ETPRTNC_NETWORKSENDBYTESDELTA:
|
|
result = uint64cmp(block1->NetworkSendRawDelta.Delta, block2->NetworkSendRawDelta.Delta);
|
|
break;
|
|
case ETPRTNC_NETWORKTOTALBYTESDELTA:
|
|
result = uint64cmp(block1->NetworkReceiveRawDelta.Delta + block1->NetworkSendRawDelta.Delta, block2->NetworkReceiveRawDelta.Delta + block2->NetworkSendRawDelta.Delta);
|
|
break;
|
|
case ETPRTNC_HARDFAULTS:
|
|
result = uintcmp(block1->HardFaultsDelta.Value, block2->HardFaultsDelta.Value);
|
|
break;
|
|
case ETPRTNC_HARDFAULTSDELTA:
|
|
result = uintcmp(block1->HardFaultsDelta.Delta, block2->HardFaultsDelta.Delta);
|
|
break;
|
|
case ETPRTNC_PEAKTHREADS:
|
|
result = uintcmp(block1->ProcessItem->PeakNumberOfThreads, block2->ProcessItem->PeakNumberOfThreads);
|
|
break;
|
|
case ETPRTNC_GPU:
|
|
result = singlecmp(block1->GpuNodeUsage, block2->GpuNodeUsage);
|
|
break;
|
|
case ETPRTNC_GPUDEDICATEDBYTES:
|
|
result = uint64cmp(block1->GpuDedicatedUsage, block2->GpuDedicatedUsage);
|
|
break;
|
|
case ETPRTNC_GPUSHAREDBYTES:
|
|
result = uint64cmp(block1->GpuSharedUsage, block2->GpuSharedUsage);
|
|
break;
|
|
case ETPRTNC_DISKREADRATE:
|
|
result = uint64cmp(block1->DiskReadRawDelta.Delta, block2->DiskReadRawDelta.Delta);
|
|
break;
|
|
case ETPRTNC_DISKWRITERATE:
|
|
result = uint64cmp(block1->DiskWriteRawDelta.Delta, block2->DiskWriteRawDelta.Delta);
|
|
break;
|
|
case ETPRTNC_DISKTOTALRATE:
|
|
result = uint64cmp(block1->DiskReadRawDelta.Delta + block1->DiskWriteRawDelta.Delta, block2->DiskReadRawDelta.Delta + block2->DiskWriteRawDelta.Delta);
|
|
break;
|
|
case ETPRTNC_NETWORKRECEIVERATE:
|
|
result = uint64cmp(block1->NetworkReceiveRawDelta.Delta, block2->NetworkReceiveRawDelta.Delta);
|
|
break;
|
|
case ETPRTNC_NETWORKSENDRATE:
|
|
result = uint64cmp(block1->NetworkSendRawDelta.Delta, block2->NetworkSendRawDelta.Delta);
|
|
break;
|
|
case ETPRTNC_NETWORKTOTALRATE:
|
|
result = uint64cmp(block1->NetworkReceiveRawDelta.Delta + block1->NetworkSendRawDelta.Delta, block2->NetworkReceiveRawDelta.Delta + block2->NetworkSendRawDelta.Delta);
|
|
break;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
VOID EtNetworkTreeNewInitializing(
|
|
_In_ PVOID Parameter
|
|
)
|
|
{
|
|
static COLUMN_INFO columns[] =
|
|
{
|
|
{ ETNETNC_RECEIVES, L"Receives", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETNETNC_SENDS, L"Sends", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETNETNC_RECEIVEBYTES, L"Receive bytes", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETNETNC_SENDBYTES, L"Send bytes", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETNETNC_TOTALBYTES, L"Total bytes", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETNETNC_RECEIVESDELTA, L"Receives delta", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETNETNC_SENDSDELTA, L"Sends delta", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETNETNC_RECEIVEBYTESDELTA, L"Receive bytes delta", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETNETNC_SENDBYTESDELTA, L"Send bytes delta", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETNETNC_TOTALBYTESDELTA, L"Total bytes delta", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETNETNC_FIREWALLSTATUS, L"Firewall status", 170, PH_ALIGN_LEFT, 0, FALSE },
|
|
{ ETNETNC_RECEIVERATE, L"Receive rate", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETNETNC_SENDRATE, L"Send rate", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE },
|
|
{ ETNETNC_TOTALRATE, L"Total rate", 70, PH_ALIGN_RIGHT, DT_RIGHT, TRUE }
|
|
};
|
|
|
|
PPH_PLUGIN_TREENEW_INFORMATION treeNewInfo = Parameter;
|
|
ULONG i;
|
|
|
|
for (i = 0; i < sizeof(columns) / sizeof(COLUMN_INFO); i++)
|
|
{
|
|
EtpAddTreeNewColumn(treeNewInfo, columns[i].SubId, columns[i].Text, columns[i].Width, columns[i].Alignment,
|
|
columns[i].TextFlags, columns[i].SortDescending, EtpNetworkTreeNewSortFunction);
|
|
}
|
|
}
|
|
|
|
VOID EtpUpdateFirewallStatus(
|
|
_Inout_ PET_NETWORK_BLOCK Block
|
|
)
|
|
{
|
|
if (!Block->FirewallStatusValid)
|
|
{
|
|
Block->FirewallStatus = EtQueryFirewallStatus(Block->NetworkItem);
|
|
Block->FirewallStatusValid = TRUE;
|
|
}
|
|
}
|
|
|
|
VOID EtNetworkTreeNewMessage(
|
|
_In_ PVOID Parameter
|
|
)
|
|
{
|
|
PPH_PLUGIN_TREENEW_MESSAGE message = Parameter;
|
|
|
|
if (message->Message == TreeNewGetCellText)
|
|
{
|
|
PPH_TREENEW_GET_CELL_TEXT getCellText = message->Parameter1;
|
|
PPH_NETWORK_NODE networkNode = (PPH_NETWORK_NODE)getCellText->Node;
|
|
PET_NETWORK_BLOCK block;
|
|
PPH_STRING text;
|
|
|
|
block = EtGetNetworkBlock(networkNode->NetworkItem);
|
|
|
|
PhAcquireQueuedLockExclusive(&block->TextCacheLock);
|
|
|
|
if (block->TextCacheValid[message->SubId])
|
|
{
|
|
if (block->TextCache[message->SubId])
|
|
getCellText->Text = block->TextCache[message->SubId]->sr;
|
|
}
|
|
else
|
|
{
|
|
text = NULL;
|
|
|
|
switch (message->SubId)
|
|
{
|
|
case ETNETNC_RECEIVES:
|
|
if (block->ReceiveCount != 0)
|
|
text = PhFormatUInt64(block->ReceiveCount, TRUE);
|
|
break;
|
|
case ETNETNC_SENDS:
|
|
if (block->SendCount != 0)
|
|
text = PhFormatUInt64(block->SendCount, TRUE);
|
|
break;
|
|
case ETNETNC_RECEIVEBYTES:
|
|
if (block->ReceiveRaw != 0)
|
|
text = PhFormatSize(block->ReceiveRaw, -1);
|
|
break;
|
|
case ETNETNC_SENDBYTES:
|
|
if (block->SendRaw != 0)
|
|
text = PhFormatSize(block->SendRaw, -1);
|
|
break;
|
|
case ETNETNC_TOTALBYTES:
|
|
if (block->ReceiveRaw + block->SendRaw != 0)
|
|
text = PhFormatSize(block->ReceiveRaw + block->SendRaw, -1);
|
|
break;
|
|
case ETNETNC_RECEIVESDELTA:
|
|
if (block->ReceiveDelta.Delta != 0)
|
|
text = PhFormatUInt64(block->ReceiveDelta.Delta, TRUE);
|
|
break;
|
|
case ETNETNC_SENDSDELTA:
|
|
if (block->SendDelta.Delta != 0)
|
|
text = PhFormatUInt64(block->SendDelta.Delta, TRUE);
|
|
break;
|
|
case ETNETNC_RECEIVEBYTESDELTA:
|
|
if (block->ReceiveRawDelta.Delta != 0)
|
|
text = PhFormatSize(block->ReceiveRawDelta.Delta, -1);
|
|
break;
|
|
case ETNETNC_SENDBYTESDELTA:
|
|
if (block->SendRawDelta.Delta != 0)
|
|
text = PhFormatSize(block->SendRawDelta.Delta, -1);
|
|
break;
|
|
case ETNETNC_TOTALBYTESDELTA:
|
|
if (block->ReceiveRawDelta.Delta + block->SendRawDelta.Delta != 0)
|
|
text = PhFormatSize(block->ReceiveRawDelta.Delta + block->SendRawDelta.Delta, -1);
|
|
break;
|
|
case ETNETNC_FIREWALLSTATUS:
|
|
{
|
|
static PPH_STRING strings[FirewallMaximumStatus];
|
|
static PH_INITONCE initOnce = PH_INITONCE_INIT;
|
|
|
|
if (PhBeginInitOnce(&initOnce))
|
|
{
|
|
strings[FirewallUnknownStatus] = NULL;
|
|
strings[FirewallAllowedNotRestricted] = PhCreateString(L"Allowed, not restricted");
|
|
strings[FirewallAllowedRestricted] = PhCreateString(L"Allowed, restricted");
|
|
strings[FirewallNotAllowedNotRestricted] = PhCreateString(L"Not allowed, not restricted");
|
|
strings[FirewallNotAllowedRestricted] = PhCreateString(L"Not allowed, restricted");
|
|
PhEndInitOnce(&initOnce);
|
|
}
|
|
|
|
EtpUpdateFirewallStatus(block);
|
|
|
|
if (block->FirewallStatus < FirewallMaximumStatus)
|
|
PhSetReference(&text, strings[block->FirewallStatus]);
|
|
}
|
|
break;
|
|
case ETNETNC_RECEIVERATE:
|
|
if (block->ReceiveRawDelta.Delta != 0)
|
|
EtFormatRate(block->ReceiveRawDelta.Delta, &text, NULL);
|
|
break;
|
|
case ETNETNC_SENDRATE:
|
|
if (block->SendRawDelta.Delta != 0)
|
|
EtFormatRate(block->SendRawDelta.Delta, &text, NULL);
|
|
break;
|
|
case ETNETNC_TOTALRATE:
|
|
if (block->ReceiveRawDelta.Delta + block->SendRawDelta.Delta != 0)
|
|
EtFormatRate(block->ReceiveRawDelta.Delta + block->SendRawDelta.Delta, &text, NULL);
|
|
break;
|
|
}
|
|
|
|
if (text)
|
|
{
|
|
getCellText->Text = text->sr;
|
|
}
|
|
|
|
PhMoveReference(&block->TextCache[message->SubId], text);
|
|
block->TextCacheValid[message->SubId] = TRUE;
|
|
}
|
|
|
|
PhReleaseQueuedLockExclusive(&block->TextCacheLock);
|
|
}
|
|
}
|
|
|
|
LONG EtpNetworkTreeNewSortFunction(
|
|
_In_ PVOID Node1,
|
|
_In_ PVOID Node2,
|
|
_In_ ULONG SubId,
|
|
_In_ PVOID Context
|
|
)
|
|
{
|
|
LONG result;
|
|
PPH_NETWORK_NODE node1 = Node1;
|
|
PPH_NETWORK_NODE node2 = Node2;
|
|
PET_NETWORK_BLOCK block1;
|
|
PET_NETWORK_BLOCK block2;
|
|
|
|
block1 = EtGetNetworkBlock(node1->NetworkItem);
|
|
block2 = EtGetNetworkBlock(node2->NetworkItem);
|
|
|
|
result = 0;
|
|
|
|
switch (SubId)
|
|
{
|
|
case ETNETNC_RECEIVES:
|
|
result = uint64cmp(block1->ReceiveCount, block2->ReceiveCount);
|
|
break;
|
|
case ETNETNC_SENDS:
|
|
result = uint64cmp(block1->SendCount, block2->SendCount);
|
|
break;
|
|
case ETNETNC_RECEIVEBYTES:
|
|
result = uint64cmp(block1->ReceiveRaw, block2->ReceiveRaw);
|
|
break;
|
|
case ETNETNC_SENDBYTES:
|
|
result = uint64cmp(block1->SendRaw, block2->SendRaw);
|
|
break;
|
|
case ETNETNC_TOTALBYTES:
|
|
result = uint64cmp(block1->ReceiveRaw + block1->SendRaw, block2->ReceiveRaw + block2->SendRaw);
|
|
break;
|
|
case ETNETNC_RECEIVESDELTA:
|
|
result = uint64cmp(block1->ReceiveDelta.Delta, block2->ReceiveDelta.Delta);
|
|
break;
|
|
case ETNETNC_SENDSDELTA:
|
|
result = uint64cmp(block1->SendDelta.Delta, block2->SendDelta.Delta);
|
|
break;
|
|
case ETNETNC_RECEIVEBYTESDELTA:
|
|
result = uint64cmp(block1->ReceiveRawDelta.Delta, block2->ReceiveRawDelta.Delta);
|
|
break;
|
|
case ETNETNC_SENDBYTESDELTA:
|
|
result = uint64cmp(block1->SendRawDelta.Delta, block2->SendRawDelta.Delta);
|
|
break;
|
|
case ETNETNC_TOTALBYTESDELTA:
|
|
result = uint64cmp(block1->ReceiveRawDelta.Delta + block1->SendRawDelta.Delta, block2->ReceiveRawDelta.Delta + block2->SendRawDelta.Delta);
|
|
break;
|
|
case ETNETNC_FIREWALLSTATUS:
|
|
EtpUpdateFirewallStatus(block1);
|
|
EtpUpdateFirewallStatus(block2);
|
|
result = intcmp(block1->FirewallStatus, block2->FirewallStatus);
|
|
break;
|
|
case ETNETNC_RECEIVERATE:
|
|
result = uint64cmp(block1->ReceiveRawDelta.Delta, block2->ReceiveRawDelta.Delta);
|
|
break;
|
|
case ETNETNC_SENDRATE:
|
|
result = uint64cmp(block1->SendRawDelta.Delta, block2->SendRawDelta.Delta);
|
|
break;
|
|
case ETNETNC_TOTALRATE:
|
|
result = uint64cmp(block1->ReceiveRawDelta.Delta + block1->SendRawDelta.Delta, block2->ReceiveRawDelta.Delta + block2->SendRawDelta.Delta);
|
|
break;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
ET_FIREWALL_STATUS EtQueryFirewallStatus(
|
|
_In_ PPH_NETWORK_ITEM NetworkItem
|
|
)
|
|
{
|
|
static INetFwMgr* manager = NULL;
|
|
ET_FIREWALL_STATUS result;
|
|
PPH_PROCESS_ITEM processItem;
|
|
BSTR imageFileNameBStr;
|
|
BSTR localAddressBStr;
|
|
VARIANT allowed;
|
|
VARIANT restricted;
|
|
|
|
if (!manager)
|
|
{
|
|
if (!SUCCEEDED(CoCreateInstance(&CLSID_NetFwMgr_I, NULL, CLSCTX_INPROC_SERVER, &IID_INetFwMgr_I, &manager)))
|
|
return FirewallUnknownStatus;
|
|
|
|
if (!manager)
|
|
return FirewallUnknownStatus;
|
|
}
|
|
|
|
processItem = PhReferenceProcessItem(NetworkItem->ProcessId);
|
|
|
|
if (!processItem)
|
|
return FirewallUnknownStatus;
|
|
|
|
if (!processItem->FileName)
|
|
{
|
|
PhDereferenceObject(processItem);
|
|
return FirewallUnknownStatus;
|
|
}
|
|
|
|
result = FirewallUnknownStatus;
|
|
|
|
if (imageFileNameBStr = SysAllocStringLen(processItem->FileName->Buffer, (ULONG)processItem->FileName->Length / sizeof(WCHAR)))
|
|
{
|
|
localAddressBStr = NULL;
|
|
|
|
if (!PhIsNullIpAddress(&NetworkItem->LocalEndpoint.Address))
|
|
localAddressBStr = SysAllocString(NetworkItem->LocalAddressString);
|
|
|
|
if (SUCCEEDED(INetFwMgr_IsPortAllowed(
|
|
manager,
|
|
imageFileNameBStr,
|
|
(NetworkItem->ProtocolType & PH_IPV6_NETWORK_TYPE) ? NET_FW_IP_VERSION_V6 : NET_FW_IP_VERSION_V4,
|
|
NetworkItem->LocalEndpoint.Port,
|
|
localAddressBStr,
|
|
(NetworkItem->ProtocolType & PH_UDP_PROTOCOL_TYPE) ? NET_FW_IP_PROTOCOL_UDP : NET_FW_IP_PROTOCOL_TCP,
|
|
&allowed,
|
|
&restricted
|
|
)))
|
|
{
|
|
if (allowed.boolVal)
|
|
{
|
|
if (restricted.boolVal)
|
|
result = FirewallAllowedRestricted;
|
|
else
|
|
result = FirewallAllowedNotRestricted;
|
|
}
|
|
else
|
|
{
|
|
if (restricted.boolVal)
|
|
result = FirewallNotAllowedRestricted;
|
|
else
|
|
result = FirewallNotAllowedNotRestricted;
|
|
}
|
|
}
|
|
|
|
if (localAddressBStr)
|
|
SysFreeString(localAddressBStr);
|
|
|
|
SysFreeString(imageFileNameBStr);
|
|
}
|
|
|
|
PhDereferenceObject(processItem);
|
|
|
|
return result;
|
|
}
|