/* * 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 . */ #include "exttools.h" #define CINTERFACE #define COBJMACROS #include 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; }