PPH_STRING PhSipGetMaxCpuString( _In_ LONG Index ) { PPH_PROCESS_RECORD maxProcessRecord; #ifdef PH_RECORD_MAX_USAGE FLOAT maxCpuUsage; #endif PPH_STRING maxUsageString = NULL; if (maxProcessRecord = PhSipReferenceMaxCpuRecord(Index)) { // We found the process record, so now we construct the max. usage string. #ifdef PH_RECORD_MAX_USAGE maxCpuUsage = PhGetItemCircularBuffer_FLOAT(&PhMaxCpuUsageHistory, Index); // Make sure we don't try to display the PID of DPCs or Interrupts. if (!PH_IS_FAKE_PROCESS_ID(maxProcessRecord->ProcessId)) { maxUsageString = PhaFormatString( L"\n%s (%u): %.2f%%", maxProcessRecord->ProcessName->Buffer, HandleToUlong(maxProcessRecord->ProcessId), maxCpuUsage * 100 ); } else { maxUsageString = PhaFormatString( L"\n%s: %.2f%%", maxProcessRecord->ProcessName->Buffer, maxCpuUsage * 100 ); } #else maxUsageString = PhaConcatStrings2(L"\n", maxProcessRecord->ProcessName->Buffer); #endif PhDereferenceProcessRecord(maxProcessRecord); } return maxUsageString; }
VOID ToolbarUpdateGraphsInfo(LPNMHDR Header) { switch (Header->code) { case GCN_GETDRAWINFO: { if (ToolStatusConfig.CpuGraphEnabled && Header->hwndFrom == CpuGraphHandle) { 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_LINE_2; PhSiSetColorsGraphDrawInfo(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), PhGetIntegerSetting(L"ColorCpuUser")); if (ProcessesUpdatedCount < 2) return; PhGraphStateGetDrawInfo(&CpuGraphState, getDrawInfo, SystemStatistics.CpuUserHistory->Count); if (!CpuGraphState.Valid) { PhCopyCircularBuffer_FLOAT(SystemStatistics.CpuKernelHistory, CpuGraphState.Data1, drawInfo->LineDataCount); PhCopyCircularBuffer_FLOAT(SystemStatistics.CpuUserHistory, CpuGraphState.Data2, drawInfo->LineDataCount); CpuGraphState.Valid = TRUE; } } else if (ToolStatusConfig.MemGraphEnabled && Header->hwndFrom == MemGraphHandle) { PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)Header; PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo; drawInfo->Flags = PH_GRAPH_USE_GRID_X; PhSiSetColorsGraphDrawInfo(drawInfo, PhGetIntegerSetting(L"ColorPhysical"), 0); if (ProcessesUpdatedCount < 2) return; PhGraphStateGetDrawInfo(&MemGraphState, getDrawInfo, SystemStatistics.PhysicalHistory->Count); if (!MemGraphState.Valid) { for (ULONG i = 0; i < drawInfo->LineDataCount; i++) { MemGraphState.Data1[i] = (FLOAT)PhGetItemCircularBuffer_ULONG(SystemStatistics.PhysicalHistory, i); } PhDivideSinglesBySingle( MemGraphState.Data1, (FLOAT)PhSystemBasicInformation.NumberOfPhysicalPages, drawInfo->LineDataCount ); MemGraphState.Valid = TRUE; } } else if (ToolStatusConfig.CommitGraphEnabled && Header->hwndFrom == CommitGraphHandle) { PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)Header; PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo; drawInfo->Flags = PH_GRAPH_USE_GRID_X; PhSiSetColorsGraphDrawInfo(drawInfo, PhGetIntegerSetting(L"ColorPrivate"), 0); if (ProcessesUpdatedCount < 2) return; PhGraphStateGetDrawInfo(&CommitGraphState, getDrawInfo, SystemStatistics.CommitHistory->Count); if (!CommitGraphState.Valid) { for (ULONG i = 0; i < drawInfo->LineDataCount; i++) { CommitGraphState.Data1[i] = (FLOAT)PhGetItemCircularBuffer_ULONG(SystemStatistics.CommitHistory, i); } PhDivideSinglesBySingle( CommitGraphState.Data1, (FLOAT)SystemStatistics.Performance->CommitLimit, drawInfo->LineDataCount ); CommitGraphState.Valid = TRUE; } } else if (ToolStatusConfig.IoGraphEnabled && Header->hwndFrom == IoGraphHandle) { 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_LINE_2; PhSiSetColorsGraphDrawInfo(drawInfo, PhGetIntegerSetting(L"ColorIoReadOther"), PhGetIntegerSetting(L"ColorIoWrite")); if (ProcessesUpdatedCount < 2) return; PhGraphStateGetDrawInfo(&IoGraphState, getDrawInfo, SystemStatistics.IoReadHistory->Count); if (!IoGraphState.Valid) { FLOAT max = 1024 * 1024; // minimum scaling of 1 MB. for (ULONG i = 0; i < drawInfo->LineDataCount; i++) { IoGraphState.Data1[i] = (FLOAT)PhGetItemCircularBuffer_ULONG64(SystemStatistics.IoReadHistory, i) + (FLOAT)PhGetItemCircularBuffer_ULONG64(SystemStatistics.IoOtherHistory, i); IoGraphState.Data2[i] = (FLOAT)PhGetItemCircularBuffer_ULONG64(SystemStatistics.IoWriteHistory, i); if (max < IoGraphState.Data1[i] + IoGraphState.Data2[i]) max = IoGraphState.Data1[i] + IoGraphState.Data2[i]; } PhDivideSinglesBySingle(IoGraphState.Data1, max, drawInfo->LineDataCount); PhDivideSinglesBySingle(IoGraphState.Data2, max, drawInfo->LineDataCount); drawInfo->GridHeight = 1 / max; IoGraphState.Valid = TRUE; } } } break; case GCN_GETTOOLTIPTEXT: { PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)Header; if (getTooltipText->Index < getTooltipText->TotalCount) { if (ToolStatusConfig.CpuGraphEnabled && Header->hwndFrom == CpuGraphHandle) { if (CpuGraphState.TooltipIndex != getTooltipText->Index) { FLOAT cpuKernel; FLOAT cpuUser; cpuKernel = PhGetItemCircularBuffer_FLOAT(SystemStatistics.CpuKernelHistory, getTooltipText->Index); cpuUser = PhGetItemCircularBuffer_FLOAT(SystemStatistics.CpuUserHistory, getTooltipText->Index); PhMoveReference(&CpuGraphState.TooltipText, PhFormatString( L"%.2f%%%s\n%s", (cpuKernel + cpuUser) * 100, PhGetStringOrEmpty(PhSipGetMaxCpuString(getTooltipText->Index)), ((PPH_STRING)PH_AUTO(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer )); } getTooltipText->Text = CpuGraphState.TooltipText->sr; } else if (ToolStatusConfig.MemGraphEnabled && Header->hwndFrom == MemGraphHandle) { ULONG physicalUsage; physicalUsage = PhGetItemCircularBuffer_ULONG(SystemStatistics.PhysicalHistory, getTooltipText->Index); PhMoveReference(&MemGraphState.TooltipText, PhFormatString( L"Physical Memory: %s\n%s", PhaFormatSize(UInt32x32To64(physicalUsage, PAGE_SIZE), -1)->Buffer, ((PPH_STRING)PH_AUTO(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer )); getTooltipText->Text = MemGraphState.TooltipText->sr; } else if (ToolStatusConfig.CommitGraphEnabled && Header->hwndFrom == CommitGraphHandle) { ULONG commitUsage; commitUsage = PhGetItemCircularBuffer_ULONG(SystemStatistics.CommitHistory, getTooltipText->Index); PhMoveReference(&CommitGraphState.TooltipText, PhFormatString( L"Commit: %s\n%s", PhaFormatSize(UInt32x32To64(commitUsage, PAGE_SIZE), -1)->Buffer, ((PPH_STRING)PH_AUTO(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer )); getTooltipText->Text = CommitGraphState.TooltipText->sr; } else if (ToolStatusConfig.IoGraphEnabled && Header->hwndFrom == IoGraphHandle) { ULONG64 ioRead; ULONG64 ioWrite; ULONG64 ioOther; ioRead = PhGetItemCircularBuffer_ULONG64(SystemStatistics.IoReadHistory, getTooltipText->Index); ioWrite = PhGetItemCircularBuffer_ULONG64(SystemStatistics.IoWriteHistory, getTooltipText->Index); ioOther = PhGetItemCircularBuffer_ULONG64(SystemStatistics.IoOtherHistory, getTooltipText->Index); PhMoveReference(&IoGraphState.TooltipText, PhFormatString( L"R: %s\nW: %s\nO: %s%s\n%s", PhaFormatSize(ioRead, -1)->Buffer, PhaFormatSize(ioWrite, -1)->Buffer, PhaFormatSize(ioOther, -1)->Buffer, PhGetStringOrEmpty(PhSipGetMaxIoString(getTooltipText->Index)), ((PPH_STRING)PH_AUTO(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer )); getTooltipText->Text = IoGraphState.TooltipText->sr; } } } break; case GCN_MOUSEEVENT: { PPH_GRAPH_MOUSEEVENT mouseEvent = (PPH_GRAPH_MOUSEEVENT)Header; PPH_PROCESS_RECORD record = NULL; if (ToolStatusConfig.CpuGraphEnabled && Header->hwndFrom == CpuGraphHandle) { if (mouseEvent->Message == WM_RBUTTONUP) { ShowCustomizeMenu(); } else { if (mouseEvent->Message == WM_LBUTTONDBLCLK && mouseEvent->Index < mouseEvent->TotalCount) { record = PhSipReferenceMaxCpuRecord(mouseEvent->Index); } if (record) { PhShowProcessRecordDialog(PhMainWndHandle, record); PhDereferenceProcessRecord(record); } } } else if (ToolStatusConfig.MemGraphEnabled && Header->hwndFrom == MemGraphHandle) { if (mouseEvent->Message == WM_RBUTTONUP) { ShowCustomizeMenu(); } } else if (ToolStatusConfig.CommitGraphEnabled && Header->hwndFrom == CommitGraphHandle) { if (mouseEvent->Message == WM_RBUTTONUP) { ShowCustomizeMenu(); } } else if (ToolStatusConfig.IoGraphEnabled && Header->hwndFrom == IoGraphHandle) { if (mouseEvent->Message == WM_RBUTTONUP) { ShowCustomizeMenu(); } else { if (mouseEvent->Message == WM_LBUTTONDBLCLK && mouseEvent->Index < mouseEvent->TotalCount) { record = PhSipReferenceMaxIoRecord(mouseEvent->Index); } if (record) { PhShowProcessRecordDialog(PhMainWndHandle, record); PhDereferenceProcessRecord(record); } } } } break; } }
VOID PhSipNotifyCpuGraph( _In_ ULONG Index, _In_ NMHDR *Header ) { 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_USE_LINE_2; PhSiSetColorsGraphDrawInfo(drawInfo, PhCsColorCpuKernel, PhCsColorCpuUser); if (Index == -1) { PhGraphStateGetDrawInfo( &CpuGraphState, getDrawInfo, PhCpuKernelHistory.Count ); if (!CpuGraphState.Valid) { PhCopyCircularBuffer_FLOAT(&PhCpuKernelHistory, CpuGraphState.Data1, drawInfo->LineDataCount); PhCopyCircularBuffer_FLOAT(&PhCpuUserHistory, CpuGraphState.Data2, drawInfo->LineDataCount); CpuGraphState.Valid = TRUE; } } else { PhGraphStateGetDrawInfo( &CpusGraphState[Index], getDrawInfo, PhCpuKernelHistory.Count ); if (!CpusGraphState[Index].Valid) { PhCopyCircularBuffer_FLOAT(&PhCpusKernelHistory[Index], CpusGraphState[Index].Data1, drawInfo->LineDataCount); PhCopyCircularBuffer_FLOAT(&PhCpusUserHistory[Index], CpusGraphState[Index].Data2, drawInfo->LineDataCount); CpusGraphState[Index].Valid = TRUE; } } } break; case GCN_GETTOOLTIPTEXT: { PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)Header; if (getTooltipText->Index < getTooltipText->TotalCount) { if (Index == -1) { if (CpuGraphState.TooltipIndex != getTooltipText->Index) { FLOAT cpuKernel; FLOAT cpuUser; cpuKernel = PhGetItemCircularBuffer_FLOAT(&PhCpuKernelHistory, getTooltipText->Index); cpuUser = PhGetItemCircularBuffer_FLOAT(&PhCpuUserHistory, getTooltipText->Index); PhMoveReference(&CpuGraphState.TooltipText, PhFormatString( L"%.2f%%%s\n%s", (cpuKernel + cpuUser) * 100, PhGetStringOrEmpty(PhSipGetMaxCpuString(getTooltipText->Index)), PH_AUTO_T(PH_STRING, PhGetStatisticsTimeString(NULL, getTooltipText->Index))->Buffer )); } getTooltipText->Text = CpuGraphState.TooltipText->sr; } else { if (CpusGraphState[Index].TooltipIndex != getTooltipText->Index) { FLOAT cpuKernel; FLOAT cpuUser; cpuKernel = PhGetItemCircularBuffer_FLOAT(&PhCpusKernelHistory[Index], getTooltipText->Index); cpuUser = PhGetItemCircularBuffer_FLOAT(&PhCpusUserHistory[Index], getTooltipText->Index); PhMoveReference(&CpusGraphState[Index].TooltipText, PhFormatString( L"%.2f%% (K: %.2f%%, U: %.2f%%)%s\n%s", (cpuKernel + cpuUser) * 100, cpuKernel * 100, cpuUser * 100, PhGetStringOrEmpty(PhSipGetMaxCpuString(getTooltipText->Index)), PH_AUTO_T(PH_STRING, PhGetStatisticsTimeString(NULL, getTooltipText->Index))->Buffer )); } getTooltipText->Text = CpusGraphState[Index].TooltipText->sr; } } } break; case GCN_MOUSEEVENT: { PPH_GRAPH_MOUSEEVENT mouseEvent = (PPH_GRAPH_MOUSEEVENT)Header; PPH_PROCESS_RECORD record; record = NULL; if (mouseEvent->Message == WM_LBUTTONDBLCLK && mouseEvent->Index < mouseEvent->TotalCount) { record = PhSipReferenceMaxCpuRecord(mouseEvent->Index); } if (record) { PhShowProcessRecordDialog(CpuDialog, record); PhDereferenceProcessRecord(record); } } break; } }