INT_PTR CALLBACK EtwDiskNetworkPageDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { LPPROPSHEETPAGE propSheetPage; PPH_PROCESS_PROPPAGECONTEXT propPageContext; PPH_PROCESS_ITEM processItem; PET_DISKNET_CONTEXT context; if (PhPropPageDlgProcHeader(hwndDlg, uMsg, lParam, &propSheetPage, &propPageContext, &processItem)) { context = propPageContext->Context; } else { return FALSE; } switch (uMsg) { case WM_INITDIALOG: { ULONG sampleCount; // We have already set the group boxes to have WS_EX_TRANSPARENT to fix // the drawing issue that arises when using WS_CLIPCHILDREN. However // in removing the flicker from the graphs the group boxes will now flicker. // It's a good tradeoff since no one stares at the group boxes. PhSetWindowStyle(hwndDlg, WS_CLIPCHILDREN, WS_CLIPCHILDREN); sampleCount = PhGetIntegerSetting(L"SampleCount"); context = PhAllocateZero(sizeof(ET_DISKNET_CONTEXT)); context->WindowHandle = hwndDlg; context->Block = EtGetProcessBlock(processItem); context->Enabled = TRUE; context->DiskGroupBox = GetDlgItem(hwndDlg, IDC_GROUPDISK); context->NetworkGroupBox = GetDlgItem(hwndDlg, IDC_GROUPNETWORK); propPageContext->Context = context; PhInitializeLayoutManager(&context->LayoutManager, hwndDlg); PhInitializeGraphState(&context->DiskGraphState); PhInitializeGraphState(&context->NetworkGraphState); PhInitializeCircularBuffer_ULONG64(&context->DiskReadHistory, sampleCount); PhInitializeCircularBuffer_ULONG64(&context->DiskWriteHistory, sampleCount); PhInitializeCircularBuffer_ULONG64(&context->NetworkSendHistory, sampleCount); PhInitializeCircularBuffer_ULONG64(&context->NetworkReceiveHistory, sampleCount); EtwDiskNetworkCreateGraphs(context); EtwDiskNetworkCreatePanel(context); EtwDiskNetworkUpdateInfo(context); EtwDiskNetworkUpdatePanel(context); PhRegisterCallback( PhGetGeneralCallback(GeneralCallbackProcessProviderUpdatedEvent), EtwDiskNetworkUpdateHandler, context, &context->ProcessesUpdatedRegistration ); PhInitializeWindowTheme(hwndDlg, !!PhGetIntegerSetting(L"EnableThemeSupport")); } break; case WM_DESTROY: { PhDeleteLayoutManager(&context->LayoutManager); PhDeleteGraphState(&context->DiskGraphState); PhDeleteGraphState(&context->NetworkGraphState); PhDeleteCircularBuffer_ULONG64(&context->DiskReadHistory); PhDeleteCircularBuffer_ULONG64(&context->DiskWriteHistory); PhDeleteCircularBuffer_ULONG64(&context->NetworkSendHistory); PhDeleteCircularBuffer_ULONG64(&context->NetworkReceiveHistory); if (context->DiskGraphHandle) DestroyWindow(context->DiskGraphHandle); if (context->NetworkGraphHandle) DestroyWindow(context->NetworkGraphHandle); if (context->PanelHandle) DestroyWindow(context->PanelHandle); PhUnregisterCallback(PhGetGeneralCallback(GeneralCallbackProcessProviderUpdatedEvent), &context->ProcessesUpdatedRegistration); PhFree(context); } break; case WM_SHOWWINDOW: { if (PhBeginPropPageLayout(hwndDlg, propPageContext)) PhEndPropPageLayout(hwndDlg, propPageContext); } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case PSN_SETACTIVE: context->Enabled = TRUE; break; case PSN_KILLACTIVE: context->Enabled = FALSE; break; case GCN_GETDRAWINFO: { PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)header; PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo; if (header->hwndFrom == context->DiskGraphHandle) { if (PhGetIntegerSetting(L"GraphShowText")) { HDC hdc; PhMoveReference(&context->DiskGraphState.Text, PhFormatString( L"R: %s, W: %s", PhaFormatSize(context->CurrentDiskRead, ULONG_MAX)->Buffer, PhaFormatSize(context->CurrentDiskWrite, ULONG_MAX)->Buffer )); hdc = Graph_GetBufferedContext(context->DiskGraphHandle); SelectObject(hdc, PhApplicationFont); PhSetGraphText(hdc, drawInfo, &context->DiskGraphState.Text->sr, &NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT); } else { drawInfo->Text.Buffer = NULL; } drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y | PH_GRAPH_LABEL_MAX_Y | PH_GRAPH_USE_LINE_2; PhSiSetColorsGraphDrawInfo(drawInfo, PhGetIntegerSetting(L"ColorIoReadOther"), PhGetIntegerSetting(L"ColorIoWrite")); PhGraphStateGetDrawInfo(&context->DiskGraphState, getDrawInfo, context->DiskReadHistory.Count); if (!context->DiskGraphState.Valid) { FLOAT max = 0; for (ULONG i = 0; i < drawInfo->LineDataCount; i++) { FLOAT data1; FLOAT data2; context->DiskGraphState.Data1[i] = data1 = (FLOAT)PhGetItemCircularBuffer_ULONG64(&context->DiskReadHistory, i); context->DiskGraphState.Data2[i] = data2 = (FLOAT)PhGetItemCircularBuffer_ULONG64(&context->DiskWriteHistory, i); if (max < data1 + data2) max = data1 + data2; } // Minimum scaling of 1 MB. //if (max < 1024 * 1024) // max = 1024 * 1024; if (max != 0) { // Scale the data. PhDivideSinglesBySingle( context->DiskGraphState.Data1, max, drawInfo->LineDataCount ); PhDivideSinglesBySingle( context->DiskGraphState.Data2, max, drawInfo->LineDataCount ); } drawInfo->LabelYFunction = PhSiSizeLabelYFunction; drawInfo->LabelYFunctionParameter = max; context->DiskGraphState.Valid = TRUE; } } else if (header->hwndFrom == context->NetworkGraphHandle) { if (PhGetIntegerSetting(L"GraphShowText")) { HDC hdc; PhMoveReference(&context->NetworkGraphState.Text, PhFormatString( L"R: %s, S: %s", PhaFormatSize(context->CurrentNetworkReceive, ULONG_MAX)->Buffer, PhaFormatSize(context->CurrentNetworkSend, ULONG_MAX)->Buffer )); hdc = Graph_GetBufferedContext(context->NetworkGraphHandle); SelectObject(hdc, PhApplicationFont); PhSetGraphText(hdc, drawInfo, &context->NetworkGraphState.Text->sr, &NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT); } else { drawInfo->Text.Buffer = NULL; } drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y | PH_GRAPH_LABEL_MAX_Y | PH_GRAPH_USE_LINE_2; PhSiSetColorsGraphDrawInfo(drawInfo, PhGetIntegerSetting(L"ColorIoReadOther"), PhGetIntegerSetting(L"ColorIoWrite")); PhGraphStateGetDrawInfo(&context->NetworkGraphState, getDrawInfo, context->NetworkSendHistory.Count); if (!context->NetworkGraphState.Valid) { FLOAT max = 0; for (ULONG i = 0; i < drawInfo->LineDataCount; i++) { FLOAT data1; FLOAT data2; context->NetworkGraphState.Data1[i] = data1 = (FLOAT)PhGetItemCircularBuffer_ULONG64(&context->NetworkReceiveHistory, i); context->NetworkGraphState.Data2[i] = data2 = (FLOAT)PhGetItemCircularBuffer_ULONG64(&context->NetworkSendHistory, i); if (max < data1 + data2) max = data1 + data2; } // Minimum scaling of 1 MB. //if (max < 1024 * 1024) // max = 1024 * 1024; if (max != 0) { // Scale the data. PhDivideSinglesBySingle( context->NetworkGraphState.Data1, max, drawInfo->LineDataCount ); PhDivideSinglesBySingle( context->NetworkGraphState.Data2, max, drawInfo->LineDataCount ); } drawInfo->LabelYFunction = PhSiSizeLabelYFunction; drawInfo->LabelYFunctionParameter = max; context->NetworkGraphState.Valid = TRUE; } } } break; case GCN_GETTOOLTIPTEXT: { PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)lParam; if (getTooltipText->Index < getTooltipText->TotalCount) { if (header->hwndFrom == context->DiskGraphHandle) { if (context->DiskGraphState.TooltipIndex != getTooltipText->Index) { ULONG64 diskRead = PhGetItemCircularBuffer_ULONG64( &context->DiskReadHistory, getTooltipText->Index ); ULONG64 diskWrite = PhGetItemCircularBuffer_ULONG64( &context->DiskWriteHistory, getTooltipText->Index ); PhMoveReference(&context->DiskGraphState.TooltipText, PhFormatString( L"R: %s\nW: %s\n%s", PhaFormatSize(diskRead, ULONG_MAX)->Buffer, PhaFormatSize(diskWrite, ULONG_MAX)->Buffer, ((PPH_STRING)PH_AUTO(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer )); } getTooltipText->Text = PhGetStringRef(context->DiskGraphState.TooltipText); } else if (header->hwndFrom == context->NetworkGraphHandle) { if (context->NetworkGraphState.TooltipIndex != getTooltipText->Index) { ULONG64 networkSend = PhGetItemCircularBuffer_ULONG64( &context->NetworkSendHistory, getTooltipText->Index ); ULONG64 networkReceive = PhGetItemCircularBuffer_ULONG64( &context->NetworkReceiveHistory, getTooltipText->Index ); PhMoveReference(&context->NetworkGraphState.TooltipText, PhFormatString( L"S: %s\nR: %s\n%s", PhaFormatSize(networkSend, ULONG_MAX)->Buffer, PhaFormatSize(networkReceive, ULONG_MAX)->Buffer, ((PPH_STRING)PH_AUTO(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer )); } getTooltipText->Text = PhGetStringRef(context->NetworkGraphState.TooltipText); } } } break; } } break; case ET_WM_UPDATE: { if (context->Enabled) { EtwDiskNetworkUpdateInfo(context); EtwDiskNetworkUpdateGraphs(context); EtwDiskNetworkUpdatePanel(context); } } break; case WM_SIZE: { EtwDiskNetworkLayoutGraphs(context); } break; } return FALSE; }
VOID EtpNotifyGpuGraph( __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; GpuSection->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), 0); PhGraphStateGetDrawInfo( &GpuGraphState, getDrawInfo, EtGpuNodeHistory.Count ); if (!GpuGraphState.Valid) { PhCopyCircularBuffer_FLOAT(&EtGpuNodeHistory, GpuGraphState.Data1, drawInfo->LineDataCount); GpuGraphState.Valid = TRUE; } } break; case GCN_GETTOOLTIPTEXT: { PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)Header; if (getTooltipText->Index < getTooltipText->TotalCount) { if (GpuGraphState.TooltipIndex != getTooltipText->Index) { FLOAT gpu; gpu = PhGetItemCircularBuffer_FLOAT(&EtGpuNodeHistory, getTooltipText->Index); PhSwapReference2(&GpuGraphState.TooltipText, PhFormatString( L"%.2f%%%s\n%s", gpu * 100, PhGetStringOrEmpty(EtpGetMaxNodeString(getTooltipText->Index)), ((PPH_STRING)PHA_DEREFERENCE(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer )); } getTooltipText->Text = GpuGraphState.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 = EtpReferenceMaxNodeRecord(mouseEvent->Index); } if (record) { PhShowProcessRecordDialog(GpuDialog, record); PhDereferenceProcessRecord(record); } } break; } }
BOOLEAN PhSipCpuSectionCallback( _In_ PPH_SYSINFO_SECTION Section, _In_ PH_SYSINFO_SECTION_MESSAGE Message, _In_opt_ PVOID Parameter1, _In_opt_ PVOID Parameter2 ) { switch (Message) { case SysInfoCreate: { CpuSection = Section; } return TRUE; case SysInfoDestroy: { if (CpuDialog) { PhSipUninitializeCpuDialog(); CpuDialog = NULL; } } return TRUE; case SysInfoTick: { if (CpuDialog) { PhSipTickCpuDialog(); } } return TRUE; case SysInfoCreateDialog: { PPH_SYSINFO_CREATE_DIALOG createDialog = Parameter1; createDialog->Instance = PhInstanceHandle; createDialog->Template = MAKEINTRESOURCE(IDD_SYSINFO_CPU); createDialog->DialogProc = PhSipCpuDialogProc; } return TRUE; case SysInfoGraphGetDrawInfo: { PPH_GRAPH_DRAW_INFO drawInfo = Parameter1; drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y | PH_GRAPH_USE_LINE_2; Section->Parameters->ColorSetupFunction(drawInfo, PhCsColorCpuKernel, PhCsColorCpuUser); PhGetDrawInfoGraphBuffers(&Section->GraphState.Buffers, drawInfo, PhCpuKernelHistory.Count); if (!Section->GraphState.Valid) { PhCopyCircularBuffer_FLOAT(&PhCpuKernelHistory, Section->GraphState.Data1, drawInfo->LineDataCount); PhCopyCircularBuffer_FLOAT(&PhCpuUserHistory, Section->GraphState.Data2, drawInfo->LineDataCount); Section->GraphState.Valid = TRUE; } } return TRUE; case SysInfoGraphGetTooltipText: { PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT getTooltipText = Parameter1; FLOAT cpuKernel; FLOAT cpuUser; cpuKernel = PhGetItemCircularBuffer_FLOAT(&PhCpuKernelHistory, getTooltipText->Index); cpuUser = PhGetItemCircularBuffer_FLOAT(&PhCpuUserHistory, getTooltipText->Index); PhMoveReference(&Section->GraphState.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 = Section->GraphState.TooltipText->sr; } return TRUE; case SysInfoGraphDrawPanel: { PPH_SYSINFO_DRAW_PANEL drawPanel = Parameter1; drawPanel->Title = PhCreateString(L"CPU"); drawPanel->SubTitle = PhFormatString(L"%.2f%%", (PhCpuKernelUsage + PhCpuUserUsage) * 100); } return TRUE; } return FALSE; }
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; } }
INT_PTR CALLBACK EtpGpuNodesDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { ULONG i; HFONT font; PPH_STRING nodeString; RECT labelRect; RECT tempRect; ULONG numberOfRows; ULONG numberOfColumns; WindowHandle = hwndDlg; PhCenterWindow(hwndDlg, GetParent(hwndDlg)); PhInitializeLayoutManager(&LayoutManager, hwndDlg); PhAddLayoutItem(&LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); LayoutMargin = PhAddLayoutItem(&LayoutManager, GetDlgItem(hwndDlg, IDC_LAYOUT), NULL, PH_ANCHOR_ALL)->Margin; PhRegisterCallback(&PhProcessesUpdatedEvent, ProcessesUpdatedCallback, NULL, &ProcessesUpdatedCallbackRegistration); GraphHandle = PhAllocate(sizeof(HWND) * EtGpuTotalNodeCount); CheckBoxHandle = PhAllocate(sizeof(HWND) * EtGpuTotalNodeCount); GraphState = PhAllocate(sizeof(PH_GRAPH_STATE) * EtGpuTotalNodeCount); font = (HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0); for (i = 0; i < EtGpuTotalNodeCount; i++) { nodeString = PhFormatString(L"Node %lu", i); GraphHandle[i] = CreateWindow( PH_GRAPH_CLASSNAME, NULL, WS_VISIBLE | WS_CHILD | WS_BORDER, 0, 0, 3, 3, hwndDlg, NULL, NULL, NULL ); Graph_SetTooltip(GraphHandle[i], TRUE); CheckBoxHandle[i] = CreateWindow( WC_BUTTON, nodeString->Buffer, WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, 0, 0, 3, 3, hwndDlg, NULL, NULL, NULL ); SendMessage(CheckBoxHandle[i], WM_SETFONT, (WPARAM)font, FALSE); PhInitializeGraphState(&GraphState[i]); PhDereferenceObject(nodeString); } // Calculate the minimum size. numberOfRows = (ULONG)sqrt(EtGpuTotalNodeCount); numberOfColumns = (EtGpuTotalNodeCount + numberOfRows - 1) / numberOfRows; MinimumSize.left = 0; MinimumSize.top = 0; MinimumSize.right = 45; MinimumSize.bottom = 60; MapDialogRect(hwndDlg, &MinimumSize); MinimumSize.right += (MinimumSize.right + GRAPH_PADDING) * numberOfColumns; MinimumSize.bottom += (MinimumSize.bottom + GRAPH_PADDING) * numberOfRows; GetWindowRect(GetDlgItem(hwndDlg, IDC_INSTRUCTION), &labelRect); MapWindowPoints(NULL, hwndDlg, (POINT *)&labelRect, 2); labelRect.right += GetSystemMetrics(SM_CXFRAME) * 2; tempRect.left = 0; tempRect.top = 0; tempRect.right = 7; tempRect.bottom = 0; MapDialogRect(hwndDlg, &tempRect); labelRect.right += tempRect.right; if (MinimumSize.right < labelRect.right) MinimumSize.right = labelRect.right; SetWindowPos(hwndDlg, NULL, 0, 0, MinimumSize.right, MinimumSize.bottom, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER); EtpLoadNodeBitMap(); } break; case WM_DESTROY: { ULONG i; EtpSaveNodeBitMap(); PhUnregisterCallback(&PhProcessesUpdatedEvent, &ProcessesUpdatedCallbackRegistration); for (i = 0; i < EtGpuTotalNodeCount; i++) { PhDeleteGraphState(&GraphState[i]); } PhFree(GraphHandle); PhFree(CheckBoxHandle); PhFree(GraphState); PhDeleteLayoutManager(&LayoutManager); } break; case WM_SIZE: { HDWP deferHandle; RECT clientRect; RECT checkBoxRect; ULONG numberOfRows = (ULONG)sqrt(EtGpuTotalNodeCount); ULONG numberOfColumns = (EtGpuTotalNodeCount + numberOfRows - 1) / numberOfRows; ULONG numberOfYPaddings = numberOfRows - 1; ULONG numberOfXPaddings = numberOfColumns - 1; ULONG cellHeight; ULONG y; ULONG cellWidth; ULONG x; ULONG i; PhLayoutManagerLayout(&LayoutManager); deferHandle = BeginDeferWindowPos(EtGpuTotalNodeCount * 2); GetClientRect(hwndDlg, &clientRect); GetClientRect(GetDlgItem(hwndDlg, IDC_EXAMPLE), &checkBoxRect); cellHeight = (clientRect.bottom - LayoutMargin.top - LayoutMargin.bottom - GRAPH_PADDING * numberOfYPaddings) / numberOfRows; y = LayoutMargin.top; i = 0; for (ULONG row = 0; row < numberOfRows; ++row) { // Give the last row the remaining space; the height we calculated might be off by a few // pixels due to integer division. if (row == numberOfRows - 1) cellHeight = clientRect.bottom - LayoutMargin.bottom - y; cellWidth = (clientRect.right - LayoutMargin.left - LayoutMargin.right - GRAPH_PADDING * numberOfXPaddings) / numberOfColumns; x = LayoutMargin.left; for (ULONG column = 0; column < numberOfColumns; column++) { // Give the last cell the remaining space; the width we calculated might be off by a few // pixels due to integer division. if (column == numberOfColumns - 1) cellWidth = clientRect.right - LayoutMargin.right - x; if (i < EtGpuTotalNodeCount) { deferHandle = DeferWindowPos( deferHandle, GraphHandle[i], NULL, x, y, cellWidth, cellHeight - checkBoxRect.bottom - CHECKBOX_PADDING, SWP_NOACTIVATE | SWP_NOZORDER ); deferHandle = DeferWindowPos( deferHandle, CheckBoxHandle[i], NULL, x, y + cellHeight - checkBoxRect.bottom, cellWidth, checkBoxRect.bottom, SWP_NOACTIVATE | SWP_NOZORDER ); i++; } x += cellWidth + GRAPH_PADDING; } y += cellHeight + GRAPH_PADDING; } EndDeferWindowPos(deferHandle); } break; case WM_SIZING: { PhResizingMinimumSize((PRECT)lParam, wParam, MinimumSize.right, MinimumSize.bottom); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: { EndDialog(hwndDlg, IDOK); } break; } } break; case WM_NOTIFY: { NMHDR *header = (NMHDR *)lParam; ULONG i; 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; SysInfoParameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), 0); for (i = 0; i < EtGpuTotalNodeCount; i++) { if (header->hwndFrom == GraphHandle[i]) { PhGraphStateGetDrawInfo( &GraphState[i], getDrawInfo, EtGpuNodesHistory[i].Count ); if (!GraphState[i].Valid) { PhCopyCircularBuffer_FLOAT(&EtGpuNodesHistory[i], GraphState[i].Data1, drawInfo->LineDataCount); GraphState[i].Valid = TRUE; } break; } } } break; case GCN_GETTOOLTIPTEXT: { PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)header; if (getTooltipText->Index < getTooltipText->TotalCount) { for (i = 0; i < EtGpuTotalNodeCount; i++) { if (header->hwndFrom == GraphHandle[i]) { if (GraphState[i].TooltipIndex != getTooltipText->Index) { FLOAT gpu; ULONG adapterIndex; PPH_STRING adapterDescription; gpu = PhGetItemCircularBuffer_FLOAT(&EtGpuNodesHistory[i], getTooltipText->Index); adapterIndex = EtGetGpuAdapterIndexFromNodeIndex(i); if (adapterIndex != -1) { adapterDescription = EtGetGpuAdapterDescription(adapterIndex); if (adapterDescription && adapterDescription->Length == 0) PhClearReference(&adapterDescription); if (!adapterDescription) adapterDescription = PhFormatString(L"Adapter %lu", adapterIndex); } else { adapterDescription = PhCreateString(L"Unknown Adapter"); } PhMoveReference(&GraphState[i].TooltipText, PhFormatString( L"Node %lu on %s\n%.2f%%\n%s", i, adapterDescription->Buffer, gpu * 100, ((PPH_STRING)PhAutoDereferenceObject(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer )); PhDereferenceObject(adapterDescription); } getTooltipText->Text = GraphState[i].TooltipText->sr; break; } } } } break; } } break; case UPDATE_MSG: { ULONG i; for (i = 0; i < EtGpuTotalNodeCount; i++) { GraphState[i].Valid = FALSE; GraphState[i].TooltipIndex = -1; Graph_MoveGrid(GraphHandle[i], 1); Graph_Draw(GraphHandle[i]); Graph_UpdateTooltip(GraphHandle[i]); InvalidateRect(GraphHandle[i], NULL, FALSE); } } break; } return FALSE; }
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; } }
VOID PhSipNotifyPhysicalGraph( _In_ NMHDR *Header ) { switch (Header->code) { case GCN_GETDRAWINFO: { PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)Header; PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo; ULONG i; drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y; PhSiSetColorsGraphDrawInfo(drawInfo, PhCsColorPhysical, 0); PhGraphStateGetDrawInfo( &PhysicalGraphState, getDrawInfo, PhPhysicalHistory.Count ); if (!PhysicalGraphState.Valid) { for (i = 0; i < drawInfo->LineDataCount; i++) { PhysicalGraphState.Data1[i] = (FLOAT)PhGetItemCircularBuffer_ULONG(&PhPhysicalHistory, i); } if (PhSystemBasicInformation.NumberOfPhysicalPages != 0) { // Scale the data. PhDivideSinglesBySingle( PhysicalGraphState.Data1, (FLOAT)PhSystemBasicInformation.NumberOfPhysicalPages, drawInfo->LineDataCount ); } PhysicalGraphState.Valid = TRUE; } } break; case GCN_GETTOOLTIPTEXT: { PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)Header; if (getTooltipText->Index < getTooltipText->TotalCount) { if (PhysicalGraphState.TooltipIndex != getTooltipText->Index) { ULONG usedPages; usedPages = PhGetItemCircularBuffer_ULONG(&PhPhysicalHistory, getTooltipText->Index); PhMoveReference(&PhysicalGraphState.TooltipText, PhFormatString( L"Physical memory: %s\n%s", PhaFormatSize(UInt32x32To64(usedPages, PAGE_SIZE), -1)->Buffer, PH_AUTO_T(PH_STRING, PhGetStatisticsTimeString(NULL, getTooltipText->Index))->Buffer )); } getTooltipText->Text = PhysicalGraphState.TooltipText->sr; } } break; } }
VOID NvGpuNotifyMemoryGraph( _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; Section->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorPhysical"), 0); PhGraphStateGetDrawInfo(&MemGraphState, getDrawInfo, GpuMemoryHistory.Count); if (PhGetIntegerSetting(L"GraphShowText")) { HDC hdc = Graph_GetBufferedContext(MemGraphHandle); PhMoveReference(&MemGraphState.Text, PhFormatString( L"%s / %s (%.2f%%)", PhaFormatSize(UInt32x32To64(GpuCurrentMemUsage, 1024), -1)->Buffer, PhaFormatSize(UInt32x32To64(GpuMemoryLimit, 1024), -1)->Buffer, (FLOAT)GpuCurrentMemUsage / GpuMemoryLimit * 100 )); SelectObject(hdc, PhApplicationFont); PhSetGraphText(hdc, drawInfo, &MemGraphState.Text->sr, &NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT); } else { drawInfo->Text.Buffer = NULL; } if (!MemGraphState.Valid) { for (ULONG i = 0; i < drawInfo->LineDataCount; i++) { MemGraphState.Data1[i] = (FLOAT)PhGetItemCircularBuffer_ULONG(&GpuMemoryHistory, i); } if (GpuMemoryLimit != 0) { // Scale the data. PhDivideSinglesBySingle( MemGraphState.Data1, (FLOAT)GpuMemoryLimit, drawInfo->LineDataCount ); } MemGraphState.Valid = TRUE; } } break; case GCN_GETTOOLTIPTEXT: { PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)Header; if (getTooltipText->Index < getTooltipText->TotalCount) { if (MemGraphState.TooltipIndex != getTooltipText->Index) { ULONG usedPages; usedPages = PhGetItemCircularBuffer_ULONG(&GpuMemoryHistory, getTooltipText->Index); PhMoveReference(&MemGraphState.TooltipText, PhFormatString( L"%s / %s (%.2f%%)\n%s", PhaFormatSize(UInt32x32To64(usedPages, 1024), -1)->Buffer, PhaFormatSize(UInt32x32To64(GpuMemoryLimit, 1024), -1)->Buffer, (FLOAT)usedPages / GpuMemoryLimit * 100, ((PPH_STRING)PhAutoDereferenceObject(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer )); } getTooltipText->Text = MemGraphState.TooltipText->sr; } } break; } }
static INT_PTR CALLBACK NetAdapterDialogProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PPH_NETADAPTER_SYSINFO_CONTEXT context = NULL; if (uMsg == WM_INITDIALOG) { context = (PPH_NETADAPTER_SYSINFO_CONTEXT)lParam; SetProp(hwndDlg, L"Context", (HANDLE)context); } else { context = (PPH_NETADAPTER_SYSINFO_CONTEXT)GetProp(hwndDlg, L"Context"); if (uMsg == WM_NCDESTROY) { PhDeleteLayoutManager(&context->LayoutManager); PhDeleteGraphState(&context->GraphState); if (context->GraphHandle) DestroyWindow(context->GraphHandle); if (context->PanelWindowHandle) DestroyWindow(context->PanelWindowHandle); PhUnregisterCallback(&PhProcessesUpdatedEvent, &context->ProcessesUpdatedRegistration); RemoveProp(hwndDlg, L"Context"); } } if (context == NULL) return FALSE; switch (uMsg) { case WM_INITDIALOG: { PPH_LAYOUT_ITEM graphItem; PPH_LAYOUT_ITEM panelItem; context->WindowHandle = hwndDlg; PhInitializeGraphState(&context->GraphState); PhInitializeLayoutManager(&context->LayoutManager, hwndDlg); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_ADAPTERNAME), NULL, PH_ANCHOR_LEFT | PH_ANCHOR_TOP | PH_ANCHOR_RIGHT | PH_LAYOUT_FORCE_INVALIDATE); graphItem = PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_GRAPH_LAYOUT), NULL, PH_ANCHOR_ALL); panelItem = PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_LAYOUT), NULL, PH_ANCHOR_LEFT | PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); SendMessage(GetDlgItem(hwndDlg, IDC_ADAPTERNAME), WM_SETFONT, (WPARAM)context->SysinfoSection->Parameters->LargeFont, FALSE); SetDlgItemText(hwndDlg, IDC_ADAPTERNAME, context->SysinfoSection->Name.Buffer); context->PanelWindowHandle = CreateDialog(PluginInstance->DllBase, MAKEINTRESOURCE(IDD_NETADAPTER_PANEL), hwndDlg, NetAdapterPanelDialogProc); ShowWindow(context->PanelWindowHandle, SW_SHOW); PhAddLayoutItemEx(&context->LayoutManager, context->PanelWindowHandle, NULL, PH_ANCHOR_LEFT | PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM, panelItem->Margin); // Create the graph control. context->GraphHandle = CreateWindow( PH_GRAPH_CLASSNAME, NULL, WS_VISIBLE | WS_CHILD | WS_BORDER, 0, 0, 3, 3, hwndDlg, NULL, PluginInstance->DllBase, NULL ); Graph_SetTooltip(context->GraphHandle, TRUE); PhAddLayoutItemEx(&context->LayoutManager, context->GraphHandle, NULL, PH_ANCHOR_ALL, graphItem->Margin); PhRegisterCallback( &PhProcessesUpdatedEvent, ProcessesUpdatedHandler, context, &context->ProcessesUpdatedRegistration ); NetAdapterUpdateGraphs(context); NetAdapterUpdatePanel(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 | PH_GRAPH_USE_LINE_2; context->SysinfoSection->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), PhGetIntegerSetting(L"ColorCpuUser")); PhGraphStateGetDrawInfo( &context->GraphState, getDrawInfo, context->InboundBuffer.Count ); if (!context->GraphState.Valid) { FLOAT maxGraphHeight1 = 0; FLOAT maxGraphHeight2 = 0; for (ULONG i = 0; i < drawInfo->LineDataCount; i++) { context->GraphState.Data1[i] = (FLOAT)PhGetItemCircularBuffer_ULONG64(&context->InboundBuffer, i); context->GraphState.Data2[i] = (FLOAT)PhGetItemCircularBuffer_ULONG64(&context->OutboundBuffer, i); if (context->GraphState.Data1[i] > maxGraphHeight1) maxGraphHeight1 = context->GraphState.Data1[i]; if (context->GraphState.Data2[i] > maxGraphHeight2) maxGraphHeight2 = context->GraphState.Data2[i]; } // Scale the data. PhxfDivideSingle2U( context->GraphState.Data1, maxGraphHeight1, drawInfo->LineDataCount ); // Scale the data. PhxfDivideSingle2U( context->GraphState.Data2, maxGraphHeight2, drawInfo->LineDataCount ); 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 adapterInboundValue = PhGetItemCircularBuffer_ULONG64( &context->InboundBuffer, getTooltipText->Index ); ULONG64 adapterOutboundValue = PhGetItemCircularBuffer_ULONG64( &context->OutboundBuffer, getTooltipText->Index ); PhSwapReference2(&context->GraphState.TooltipText, PhFormatString( L"R: %s\nS: %s\n%s", PhaFormatSize(adapterInboundValue, -1)->Buffer, PhaFormatSize(adapterOutboundValue, -1)->Buffer, ((PPH_STRING)PHA_DEREFERENCE(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer )); } getTooltipText->Text = context->GraphState.TooltipText->sr; } } break; } } } break; case MSG_UPDATE: { NetAdapterUpdateGraphs(context); NetAdapterUpdatePanel(context); } break; } return FALSE; }
static BOOLEAN NetAdapterSectionCallback( _In_ PPH_SYSINFO_SECTION Section, _In_ PH_SYSINFO_SECTION_MESSAGE Message, _In_opt_ PVOID Parameter1, _In_opt_ PVOID Parameter2 ) { PPH_NETADAPTER_SYSINFO_CONTEXT context = (PPH_NETADAPTER_SYSINFO_CONTEXT)Section->Context; switch (Message) { case SysInfoCreate: { if (PhGetIntegerSetting(SETTING_NAME_ENABLE_NDIS)) { PhCreateFileWin32( &context->DeviceHandle, PhaFormatString(L"\\\\.\\%s", context->AdapterEntry->InterfaceGuid->Buffer)->Buffer, FILE_GENERIC_READ, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ); if (context->DeviceHandle) { if (!NetworkAdapterQuerySupported(context->DeviceHandle)) { NtClose(context->DeviceHandle); context->DeviceHandle = NULL; } } } if (WindowsVersion > WINDOWS_VISTA) { if ((context->IphlpHandle = LoadLibrary(L"iphlpapi.dll"))) { context->GetIfEntry2_I = (_GetIfEntry2)GetProcAddress(context->IphlpHandle, "GetIfEntry2"); context->GetInterfaceDescriptionFromGuid_I = (_GetInterfaceDescriptionFromGuid)GetProcAddress(context->IphlpHandle, "NhGetInterfaceDescriptionFromGuid"); } } PhInitializeCircularBuffer_ULONG64(&context->InboundBuffer, PhGetIntegerSetting(L"SampleCount")); PhInitializeCircularBuffer_ULONG64(&context->OutboundBuffer, PhGetIntegerSetting(L"SampleCount")); } return TRUE; case SysInfoDestroy: { if (context->AdapterName) PhDereferenceObject(context->AdapterName); PhDeleteCircularBuffer_ULONG64(&context->InboundBuffer); PhDeleteCircularBuffer_ULONG64(&context->OutboundBuffer); if (context->IphlpHandle) FreeLibrary(context->IphlpHandle); if (context->DeviceHandle) NtClose(context->DeviceHandle); PhFree(context); } return TRUE; case SysInfoTick: { ULONG64 networkInboundSpeed = 0; ULONG64 networkOutboundSpeed = 0; ULONG64 networkInOctets = 0; ULONG64 networkOutOctets = 0; ULONG64 xmitLinkSpeed = 0; ULONG64 rcvLinkSpeed = 0; if (context->DeviceHandle) { NDIS_STATISTICS_INFO interfaceStats; NDIS_LINK_STATE interfaceState; if (NT_SUCCESS(NetworkAdapterQueryStatistics(context->DeviceHandle, &interfaceStats))) { networkInboundSpeed = interfaceStats.ifHCInOctets - context->LastInboundValue; networkOutboundSpeed = interfaceStats.ifHCOutOctets - context->LastOutboundValue; networkInOctets = interfaceStats.ifHCInOctets; networkOutOctets = interfaceStats.ifHCOutOctets; } else { ULONG64 inOctets = NetworkAdapterQueryValue(context->DeviceHandle, OID_GEN_BYTES_RCV); ULONG64 outOctets = NetworkAdapterQueryValue(context->DeviceHandle, OID_GEN_BYTES_XMIT); networkInboundSpeed = inOctets - context->LastInboundValue; networkOutboundSpeed = outOctets - context->LastOutboundValue; networkInOctets = inOctets; networkOutOctets = outOctets; } if (NT_SUCCESS(NetworkAdapterQueryLinkState(context, &interfaceState))) { xmitLinkSpeed = interfaceState.XmitLinkSpeed; rcvLinkSpeed = interfaceState.RcvLinkSpeed; } // HACK: Pull the Adapter name from the current query. if (context->SysinfoSection->Name.Length == 0) { if (context->AdapterName = NetworkAdapterQueryName(context)) { context->SysinfoSection->Name = context->AdapterName->sr; } } } else { if (context->GetIfEntry2_I) { MIB_IF_ROW2 interfaceRow; interfaceRow = QueryInterfaceRowVista(context); networkInboundSpeed = interfaceRow.InOctets - context->LastInboundValue; networkOutboundSpeed = interfaceRow.OutOctets - context->LastOutboundValue; networkInOctets = interfaceRow.InOctets; networkOutOctets = interfaceRow.OutOctets; xmitLinkSpeed = interfaceRow.TransmitLinkSpeed; rcvLinkSpeed = interfaceRow.ReceiveLinkSpeed; // HACK: Pull the Adapter name from the current query. if (context->SysinfoSection->Name.Length == 0) { if (context->AdapterName = PhCreateString(interfaceRow.Description)) { context->SysinfoSection->Name = context->AdapterName->sr; } } } else { MIB_IFROW interfaceRow; interfaceRow = QueryInterfaceRowXP(context); networkInboundSpeed = interfaceRow.dwInOctets - context->LastInboundValue; networkOutboundSpeed = interfaceRow.dwOutOctets - context->LastOutboundValue; networkInOctets = interfaceRow.dwInOctets; networkOutOctets = interfaceRow.dwOutOctets; xmitLinkSpeed = interfaceRow.dwSpeed; rcvLinkSpeed = interfaceRow.dwSpeed; // HACK: Pull the Adapter name from the current query. if (context->SysinfoSection->Name.Length == 0) { if (context->AdapterName = PhCreateStringFromAnsi(interfaceRow.bDescr)) { context->SysinfoSection->Name = context->AdapterName->sr; } } } } if (!context->HaveFirstSample) { networkInboundSpeed = 0; networkOutboundSpeed = 0; context->HaveFirstSample = TRUE; } PhAddItemCircularBuffer_ULONG64(&context->InboundBuffer, networkInboundSpeed); PhAddItemCircularBuffer_ULONG64(&context->OutboundBuffer, networkOutboundSpeed); context->InboundValue = networkInboundSpeed; context->OutboundValue = networkOutboundSpeed; context->LastInboundValue = networkInOctets; context->LastOutboundValue = networkOutOctets; context->MaxSendSpeed = xmitLinkSpeed; context->MaxReceiveSpeed = rcvLinkSpeed; } return TRUE; case SysInfoCreateDialog: { PPH_SYSINFO_CREATE_DIALOG createDialog = (PPH_SYSINFO_CREATE_DIALOG)Parameter1; createDialog->Instance = PluginInstance->DllBase; createDialog->Template = MAKEINTRESOURCE(IDD_NETADAPTER_DIALOG); createDialog->DialogProc = NetAdapterDialogProc; createDialog->Parameter = context; } return TRUE; case SysInfoGraphGetDrawInfo: { PPH_GRAPH_DRAW_INFO drawInfo = (PPH_GRAPH_DRAW_INFO)Parameter1; drawInfo->Flags = PH_GRAPH_USE_GRID | PH_GRAPH_USE_LINE_2; Section->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), PhGetIntegerSetting(L"ColorCpuUser")); PhGetDrawInfoGraphBuffers(&Section->GraphState.Buffers, drawInfo, context->InboundBuffer.Count); if (!Section->GraphState.Valid) { FLOAT maxGraphHeight1 = 0; FLOAT maxGraphHeight2 = 0; for (ULONG i = 0; i < drawInfo->LineDataCount; i++) { Section->GraphState.Data1[i] = (FLOAT)PhGetItemCircularBuffer_ULONG64(&context->InboundBuffer, i); Section->GraphState.Data2[i] = (FLOAT)PhGetItemCircularBuffer_ULONG64(&context->OutboundBuffer, i); if (Section->GraphState.Data1[i] > maxGraphHeight1) maxGraphHeight1 = Section->GraphState.Data1[i]; if (Section->GraphState.Data2[i] > maxGraphHeight2) maxGraphHeight2 = Section->GraphState.Data2[i]; } // Scale the data. PhxfDivideSingle2U( Section->GraphState.Data1, maxGraphHeight1, // (FLOAT)context->MaxReceiveSpeed, drawInfo->LineDataCount ); // Scale the data. PhxfDivideSingle2U( Section->GraphState.Data2, maxGraphHeight2, // (FLOAT)context->MaxSendSpeed, drawInfo->LineDataCount ); Section->GraphState.Valid = TRUE; } } return TRUE; case SysInfoGraphGetTooltipText: { PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT getTooltipText = (PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT)Parameter1; ULONG64 adapterInboundValue = PhGetItemCircularBuffer_ULONG64( &context->InboundBuffer, getTooltipText->Index ); ULONG64 adapterOutboundValue = PhGetItemCircularBuffer_ULONG64( &context->OutboundBuffer, getTooltipText->Index ); PhSwapReference2(&Section->GraphState.TooltipText, PhFormatString( L"R: %s\nS: %s\n%s", PhaFormatSize(adapterInboundValue, -1)->Buffer, PhaFormatSize(adapterOutboundValue, -1)->Buffer, ((PPH_STRING)PHA_DEREFERENCE(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 = PhFormatString( L"R: %s\nS: %s", PhaFormatSize(context->InboundValue, -1)->Buffer, PhaFormatSize(context->OutboundValue, -1)->Buffer ); } return TRUE; } return FALSE; }
static BOOLEAN NetAdapterSectionCallback( _In_ PPH_SYSINFO_SECTION Section, _In_ PH_SYSINFO_SECTION_MESSAGE Message, _In_opt_ PVOID Parameter1, _In_opt_ PVOID Parameter2 ) { PPH_NETADAPTER_SYSINFO_CONTEXT context = (PPH_NETADAPTER_SYSINFO_CONTEXT)Section->Context; switch (Message) { case SysInfoCreate: { if (PhGetIntegerSetting(SETTING_NAME_ENABLE_NDIS)) { // Create the handle to the network device PhCreateFileWin32( &context->DeviceHandle, PhaFormatString(L"\\\\.\\%s", context->AdapterEntry->InterfaceGuid->Buffer)->Buffer, FILE_GENERIC_READ, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ); if (context->DeviceHandle) { // Check the network adapter supports the OIDs we're going to be using. if (!NetworkAdapterQuerySupported(context->DeviceHandle)) { // Device is faulty. Close the handle so we can fallback to GetIfEntry. NtClose(context->DeviceHandle); context->DeviceHandle = NULL; } } } PhInitializeCircularBuffer_ULONG64(&context->InboundBuffer, PhGetIntegerSetting(L"SampleCount")); PhInitializeCircularBuffer_ULONG64(&context->OutboundBuffer, PhGetIntegerSetting(L"SampleCount")); } return TRUE; case SysInfoDestroy: { PhDeleteCircularBuffer_ULONG64(&context->InboundBuffer); PhDeleteCircularBuffer_ULONG64(&context->OutboundBuffer); if (context->AdapterName) PhDereferenceObject(context->AdapterName); if (context->DeviceHandle) NtClose(context->DeviceHandle); PhFree(context); } return TRUE; case SysInfoTick: { ULONG64 networkInOctets = 0; ULONG64 networkOutOctets = 0; ULONG64 networkRcvSpeed = 0; ULONG64 networkXmitSpeed = 0; //ULONG64 networkLinkSpeed = 0; if (context->DeviceHandle) { NDIS_STATISTICS_INFO interfaceStats; //NDIS_LINK_STATE interfaceState; if (NT_SUCCESS(NetworkAdapterQueryStatistics(context->DeviceHandle, &interfaceStats))) { if (!(interfaceStats.SupportedStatistics & NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV)) networkInOctets = NetworkAdapterQueryValue(context->DeviceHandle, OID_GEN_BYTES_RCV); else networkInOctets = interfaceStats.ifHCInOctets; if (!(interfaceStats.SupportedStatistics & NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT)) networkOutOctets = NetworkAdapterQueryValue(context->DeviceHandle, OID_GEN_BYTES_XMIT); else networkOutOctets = interfaceStats.ifHCOutOctets; networkRcvSpeed = networkInOctets - context->LastInboundValue; networkXmitSpeed = networkOutOctets - context->LastOutboundValue; } else { networkInOctets = NetworkAdapterQueryValue(context->DeviceHandle, OID_GEN_BYTES_RCV); networkOutOctets = NetworkAdapterQueryValue(context->DeviceHandle, OID_GEN_BYTES_XMIT); networkRcvSpeed = networkInOctets - context->LastInboundValue; networkXmitSpeed = networkOutOctets - context->LastOutboundValue; } //if (NT_SUCCESS(NetworkAdapterQueryLinkState(context->DeviceHandle, &interfaceState))) //{ // networkLinkSpeed = interfaceState.XmitLinkSpeed; //} //else //{ // NetworkAdapterQueryLinkSpeed(context->DeviceHandle, &networkLinkSpeed); //} // HACK: Pull the Adapter name from the current query. if (context->SysinfoSection->Name.Length == 0) { if (context->AdapterName = NetworkAdapterQueryName(context)) { context->SysinfoSection->Name = context->AdapterName->sr; } } } else if (GetIfEntry2_I) { MIB_IF_ROW2 interfaceRow; interfaceRow = QueryInterfaceRowVista(context->AdapterEntry); networkInOctets = interfaceRow.InOctets; networkOutOctets = interfaceRow.OutOctets; networkRcvSpeed = networkInOctets - context->LastInboundValue; networkXmitSpeed = networkOutOctets - context->LastOutboundValue; //networkLinkSpeed = interfaceRow.TransmitLinkSpeed; // interfaceRow.ReceiveLinkSpeed // HACK: Pull the Adapter name from the current query. if (context->SysinfoSection->Name.Length == 0) { if (context->AdapterName = PhCreateString(interfaceRow.Description)) { context->SysinfoSection->Name = context->AdapterName->sr; } } } else { MIB_IFROW interfaceRow; interfaceRow = QueryInterfaceRowXP(context->AdapterEntry); networkInOctets = interfaceRow.dwInOctets; networkOutOctets = interfaceRow.dwOutOctets; networkRcvSpeed = networkInOctets - context->LastInboundValue; networkXmitSpeed = networkOutOctets - context->LastOutboundValue; //networkLinkSpeed = interfaceRow.dwSpeed; // HACK: Pull the Adapter name from the current query. if (context->SysinfoSection->Name.Length == 0) { if (context->AdapterName = PhConvertMultiByteToUtf16(interfaceRow.bDescr)) { context->SysinfoSection->Name = context->AdapterName->sr; } } } if (!context->HaveFirstSample) { networkRcvSpeed = 0; networkXmitSpeed = 0; context->HaveFirstSample = TRUE; } PhAddItemCircularBuffer_ULONG64(&context->InboundBuffer, networkRcvSpeed); PhAddItemCircularBuffer_ULONG64(&context->OutboundBuffer, networkXmitSpeed); //context->LinkSpeed = networkLinkSpeed; context->InboundValue = networkRcvSpeed; context->OutboundValue = networkXmitSpeed; context->LastInboundValue = networkInOctets; context->LastOutboundValue = networkOutOctets; } return TRUE; case SysInfoCreateDialog: { PPH_SYSINFO_CREATE_DIALOG createDialog = (PPH_SYSINFO_CREATE_DIALOG)Parameter1; createDialog->Instance = PluginInstance->DllBase; createDialog->Template = MAKEINTRESOURCE(IDD_NETADAPTER_DIALOG); createDialog->DialogProc = NetAdapterDialogProc; createDialog->Parameter = context; } return TRUE; case SysInfoGraphGetDrawInfo: { PPH_GRAPH_DRAW_INFO drawInfo = (PPH_GRAPH_DRAW_INFO)Parameter1; drawInfo->Flags = PH_GRAPH_USE_GRID | PH_GRAPH_USE_LINE_2; Section->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorIoReadOther"), PhGetIntegerSetting(L"ColorIoWrite")); PhGetDrawInfoGraphBuffers(&Section->GraphState.Buffers, drawInfo, context->InboundBuffer.Count); if (!Section->GraphState.Valid) { FLOAT max = 0; for (ULONG i = 0; i < drawInfo->LineDataCount; i++) { FLOAT data1; FLOAT data2; Section->GraphState.Data1[i] = data1 = (FLOAT)PhGetItemCircularBuffer_ULONG64(&context->InboundBuffer, i); Section->GraphState.Data2[i] = data2 = (FLOAT)PhGetItemCircularBuffer_ULONG64(&context->OutboundBuffer, i); if (max < data1 + data2) max = data1 + data2; } // Minimum scaling of 1 MB. //if (max < 1024 * 1024) // max = 1024 * 1024; // Scale the data. PhDivideSinglesBySingle( Section->GraphState.Data1, max, drawInfo->LineDataCount ); // Scale the data. PhDivideSinglesBySingle( Section->GraphState.Data2, max, drawInfo->LineDataCount ); Section->GraphState.Valid = TRUE; } } return TRUE; case SysInfoGraphGetTooltipText: { PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT getTooltipText = (PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT)Parameter1; ULONG64 adapterInboundValue = PhGetItemCircularBuffer_ULONG64( &context->InboundBuffer, getTooltipText->Index ); ULONG64 adapterOutboundValue = PhGetItemCircularBuffer_ULONG64( &context->OutboundBuffer, getTooltipText->Index ); PhMoveReference(&Section->GraphState.TooltipText, PhFormatString( L"R: %s\nS: %s\n%s", PhaFormatSize(adapterInboundValue, -1)->Buffer, PhaFormatSize(adapterOutboundValue, -1)->Buffer, ((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 = PhFormatString( L"R: %s\nS: %s", PhaFormatSize(context->InboundValue, -1)->Buffer, PhaFormatSize(context->OutboundValue, -1)->Buffer ); } return TRUE; } return FALSE; }
static BOOLEAN NvGpuSectionCallback( _In_ PPH_SYSINFO_SECTION Section, _In_ PH_SYSINFO_SECTION_MESSAGE Message, _In_opt_ PVOID Parameter1, _In_opt_ PVOID Parameter2 ) { switch (Message) { case SysInfoCreate: return TRUE; case SysInfoDestroy: return TRUE; case SysInfoTick: { if (WindowHandle) PostMessage(WindowHandle, UPDATE_MSG, 0, 0); if (DetailsHandle) PostMessage(DetailsHandle, UPDATE_MSG, 0, 0); } return TRUE; case SysInfoCreateDialog: { PPH_SYSINFO_CREATE_DIALOG createDialog = (PPH_SYSINFO_CREATE_DIALOG)Parameter1; createDialog->Instance = PluginInstance->DllBase; createDialog->Template = MAKEINTRESOURCE(IDD_GPU_DIALOG); createDialog->DialogProc = NvGpuDialogProc; //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; Section->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), 0); PhGetDrawInfoGraphBuffers(&Section->GraphState.Buffers, drawInfo, GpuUtilizationHistory.Count); if (!Section->GraphState.Valid) { PhCopyCircularBuffer_FLOAT(&GpuUtilizationHistory, Section->GraphState.Data1, drawInfo->LineDataCount); Section->GraphState.Valid = TRUE; } } return TRUE; case SysInfoGraphGetTooltipText: { FLOAT gpuUsageValue; PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT getTooltipText = (PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT)Parameter1; gpuUsageValue = PhGetItemCircularBuffer_FLOAT(&GpuUtilizationHistory, getTooltipText->Index); PhMoveReference(&Section->GraphState.TooltipText, PhFormatString( L"%.0f%%\n%s", gpuUsageValue * 100, ((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 = PhFormatString( L"%.0f%%", GpuCurrentGpuUsage * 100 ); } return TRUE; } return FALSE; }
VOID NvGpuNotifyBusGraph( _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; Section->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), 0); PhGraphStateGetDrawInfo(&BusGraphState, getDrawInfo, GpuBusHistory.Count); if (PhGetIntegerSetting(L"GraphShowText")) { HDC hdc = Graph_GetBufferedContext(BusGraphHandle); PhMoveReference(&BusGraphState.Text, PhFormatString( L"%.0f%%", (FLOAT)GpuCurrentBusUsage * 100 )); SelectObject(hdc, PhApplicationFont); PhSetGraphText(hdc, drawInfo, &BusGraphState.Text->sr, &NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT); } else { drawInfo->Text.Buffer = NULL; } if (!BusGraphState.Valid) { PhCopyCircularBuffer_FLOAT(&GpuBusHistory, BusGraphState.Data1, drawInfo->LineDataCount); BusGraphState.Valid = TRUE; } } break; case GCN_GETTOOLTIPTEXT: { PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)Header; if (getTooltipText->Index < getTooltipText->TotalCount) { if (BusGraphState.TooltipIndex != getTooltipText->Index) { FLOAT busUsage; busUsage = PhGetItemCircularBuffer_FLOAT(&GpuBusHistory, getTooltipText->Index); PhMoveReference(&BusGraphState.TooltipText, PhFormatString( L"%.0f%%\n%s", busUsage * 100, ((PPH_STRING)PhAutoDereferenceObject(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer )); } getTooltipText->Text = BusGraphState.TooltipText->sr; } } break; } }
BOOLEAN EtpGpuSectionCallback( __in PPH_SYSINFO_SECTION Section, __in PH_SYSINFO_SECTION_MESSAGE Message, __in_opt PVOID Parameter1, __in_opt PVOID Parameter2 ) { switch (Message) { case SysInfoDestroy: { if (GpuDialog) { EtpUninitializeGpuDialog(); GpuDialog = NULL; } } return TRUE; case SysInfoTick: { if (GpuDialog) { EtpTickGpuDialog(); } } return TRUE; case SysInfoCreateDialog: { PPH_SYSINFO_CREATE_DIALOG createDialog = Parameter1; createDialog->Instance = PluginInstance->DllBase; createDialog->Template = MAKEINTRESOURCE(IDD_SYSINFO_GPU); createDialog->DialogProc = EtpGpuDialogProc; } return TRUE; case SysInfoGraphGetDrawInfo: { PPH_GRAPH_DRAW_INFO drawInfo = Parameter1; drawInfo->Flags = PH_GRAPH_USE_GRID; Section->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), 0); PhGetDrawInfoGraphBuffers(&Section->GraphState.Buffers, drawInfo, EtGpuNodeHistory.Count); if (!Section->GraphState.Valid) { PhCopyCircularBuffer_FLOAT(&EtGpuNodeHistory, Section->GraphState.Data1, drawInfo->LineDataCount); Section->GraphState.Valid = TRUE; } } return TRUE; case SysInfoGraphGetTooltipText: { PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT getTooltipText = Parameter1; FLOAT gpu; gpu = PhGetItemCircularBuffer_FLOAT(&EtGpuNodeHistory, getTooltipText->Index); PhSwapReference2(&Section->GraphState.TooltipText, PhFormatString( L"%.2f%%%s\n%s", gpu * 100, PhGetStringOrEmpty(EtpGetMaxNodeString(getTooltipText->Index)), ((PPH_STRING)PHA_DEREFERENCE(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer )); getTooltipText->Text = Section->GraphState.TooltipText->sr; } return TRUE; case SysInfoGraphDrawPanel: { PPH_SYSINFO_DRAW_PANEL drawPanel = Parameter1; drawPanel->Title = PhCreateString(L"GPU"); drawPanel->SubTitle = PhFormatString(L"%.2f%%", EtGpuNodeUsage * 100); } return TRUE; } return FALSE; }
BOOLEAN PhSipMemorySectionCallback( _In_ PPH_SYSINFO_SECTION Section, _In_ PH_SYSINFO_SECTION_MESSAGE Message, _In_opt_ PVOID Parameter1, _In_opt_ PVOID Parameter2 ) { switch (Message) { case SysInfoCreate: { MemorySection = Section; } return TRUE; case SysInfoDestroy: { if (MemoryDialog) { PhSipUninitializeMemoryDialog(); MemoryDialog = NULL; } } break; case SysInfoTick: { if (MemoryDialog) { PhSipTickMemoryDialog(); } } return TRUE; case SysInfoCreateDialog: { PPH_SYSINFO_CREATE_DIALOG createDialog = Parameter1; createDialog->Instance = PhInstanceHandle; createDialog->Template = MAKEINTRESOURCE(IDD_SYSINFO_MEM); createDialog->DialogProc = PhSipMemoryDialogProc; } return TRUE; case SysInfoGraphGetDrawInfo: { PPH_GRAPH_DRAW_INFO drawInfo = Parameter1; ULONG i; if (PhGetIntegerSetting(L"ShowCommitInSummary")) { drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y; Section->Parameters->ColorSetupFunction(drawInfo, PhCsColorPrivate, 0); PhGetDrawInfoGraphBuffers(&Section->GraphState.Buffers, drawInfo, PhCommitHistory.Count); if (!Section->GraphState.Valid) { for (i = 0; i < drawInfo->LineDataCount; i++) { Section->GraphState.Data1[i] = (FLOAT)PhGetItemCircularBuffer_ULONG(&PhCommitHistory, i); } if (PhPerfInformation.CommitLimit != 0) { // Scale the data. PhDivideSinglesBySingle( Section->GraphState.Data1, (FLOAT)PhPerfInformation.CommitLimit, drawInfo->LineDataCount ); } Section->GraphState.Valid = TRUE; } } else { drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y; Section->Parameters->ColorSetupFunction(drawInfo, PhCsColorPhysical, 0); PhGetDrawInfoGraphBuffers(&Section->GraphState.Buffers, drawInfo, PhPhysicalHistory.Count); if (!Section->GraphState.Valid) { for (i = 0; i < drawInfo->LineDataCount; i++) { Section->GraphState.Data1[i] = (FLOAT)PhGetItemCircularBuffer_ULONG(&PhPhysicalHistory, i); } if (PhSystemBasicInformation.NumberOfPhysicalPages != 0) { // Scale the data. PhDivideSinglesBySingle( Section->GraphState.Data1, (FLOAT)PhSystemBasicInformation.NumberOfPhysicalPages, drawInfo->LineDataCount ); } Section->GraphState.Valid = TRUE; } } } return TRUE; case SysInfoGraphGetTooltipText: { PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT getTooltipText = Parameter1; ULONG usedPages; if (PhGetIntegerSetting(L"ShowCommitInSummary")) { usedPages = PhGetItemCircularBuffer_ULONG(&PhCommitHistory, getTooltipText->Index); PhMoveReference(&Section->GraphState.TooltipText, PhFormatString( L"Commit charge: %s\n%s", PhaFormatSize(UInt32x32To64(usedPages, PAGE_SIZE), -1)->Buffer, PH_AUTO_T(PH_STRING, PhGetStatisticsTimeString(NULL, getTooltipText->Index))->Buffer )); getTooltipText->Text = Section->GraphState.TooltipText->sr; } else { usedPages = PhGetItemCircularBuffer_ULONG(&PhPhysicalHistory, getTooltipText->Index); PhMoveReference(&Section->GraphState.TooltipText, PhFormatString( L"Physical memory: %s\n%s", PhaFormatSize(UInt32x32To64(usedPages, PAGE_SIZE), -1)->Buffer, PH_AUTO_T(PH_STRING, PhGetStatisticsTimeString(NULL, getTooltipText->Index))->Buffer )); getTooltipText->Text = Section->GraphState.TooltipText->sr; } } return TRUE; case SysInfoGraphDrawPanel: { PPH_SYSINFO_DRAW_PANEL drawPanel = Parameter1; ULONG totalPages; ULONG usedPages; if (PhGetIntegerSetting(L"ShowCommitInSummary")) { totalPages = PhPerfInformation.CommitLimit; usedPages = PhPerfInformation.CommittedPages; } else { totalPages = PhSystemBasicInformation.NumberOfPhysicalPages; usedPages = totalPages - PhPerfInformation.AvailablePages; } drawPanel->Title = PhCreateString(L"Memory"); drawPanel->SubTitle = PhFormatString( L"%.0f%%\n%s / %s", (FLOAT)usedPages * 100 / totalPages, PhSipFormatSizeWithPrecision(UInt32x32To64(usedPages, PAGE_SIZE), 1)->Buffer, PhSipFormatSizeWithPrecision(UInt32x32To64(totalPages, PAGE_SIZE), 1)->Buffer ); drawPanel->SubTitleOverflow = PhFormatString( L"%.0f%%\n%s", (FLOAT)usedPages * 100 / totalPages, PhSipFormatSizeWithPrecision(UInt32x32To64(usedPages, PAGE_SIZE), 1)->Buffer ); } return TRUE; } return FALSE; }
VOID EtpNotifySharedGraph( __in NMHDR *Header ) { switch (Header->code) { case GCN_GETDRAWINFO: { PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)Header; PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo; ULONG i; drawInfo->Flags = PH_GRAPH_USE_GRID; GpuSection->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorPhysical"), 0); PhGraphStateGetDrawInfo( &SharedGraphState, getDrawInfo, EtGpuSharedHistory.Count ); if (!SharedGraphState.Valid) { for (i = 0; i < drawInfo->LineDataCount; i++) { SharedGraphState.Data1[i] = (FLOAT)PhGetItemCircularBuffer_ULONG(&EtGpuSharedHistory, i); } if (EtGpuSharedLimit != 0) { // Scale the data. PhxfDivideSingle2U( SharedGraphState.Data1, (FLOAT)EtGpuSharedLimit / PAGE_SIZE, drawInfo->LineDataCount ); } SharedGraphState.Valid = TRUE; } } break; case GCN_GETTOOLTIPTEXT: { PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)Header; if (getTooltipText->Index < getTooltipText->TotalCount) { if (SharedGraphState.TooltipIndex != getTooltipText->Index) { ULONG usedPages; usedPages = PhGetItemCircularBuffer_ULONG(&EtGpuSharedHistory, getTooltipText->Index); PhSwapReference2(&SharedGraphState.TooltipText, PhFormatString( L"Shared Memory: %s\n%s", PhaFormatSize(UInt32x32To64(usedPages, PAGE_SIZE), -1)->Buffer, ((PPH_STRING)PHA_DEREFERENCE(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer )); } getTooltipText->Text = SharedGraphState.TooltipText->sr; } } break; } }
static 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: { ULONG counterLength = 0; PDH_STATUS counterStatus = 0; //PPDH_COUNTER_INFO counterInfo; PhInitializeCircularBuffer_ULONG(&context->HistoryBuffer, PhGetIntegerSetting(L"SampleCount")); // Create the query handle. if ((counterStatus = PdhOpenQuery(NULL, (ULONG_PTR)NULL, &context->PerfQueryHandle)) != ERROR_SUCCESS) { PhShowError(NULL, L"PdhOpenQuery failed with status 0x%x.", counterStatus); } // Add the selected counter to the query handle. if ((counterStatus = PdhAddCounter(context->PerfQueryHandle, Section->Name.Buffer, 0, &context->PerfCounterHandle))) { PhShowError(NULL, L"PdhAddCounter failed with status 0x%x.", counterStatus); } //if ((counterStatus = PdhGetCounterInfo(context->PerfCounterHandle, TRUE, &counterLength, NULL)) == PDH_MORE_DATA) //{ // counterInfo = PhAllocate(counterLength); // memset(counterInfo, 0, counterLength); //} //if ((counterStatus = PdhGetCounterInfo(context->PerfCounterHandle, TRUE, &counterLength, counterInfo))) //{ // PhShowError(NULL, L"PdhGetCounterInfo failed with status 0x%x.", counterStatus); //} } return TRUE; case SysInfoDestroy: { PhDeleteCircularBuffer_ULONG(&context->HistoryBuffer); // Close the query handle. if (context->PerfQueryHandle) { PdhCloseQuery(context->PerfQueryHandle); } PhFree(context); } return TRUE; case SysInfoTick: { ULONG counterType = 0; PDH_FMT_COUNTERVALUE displayValue = { 0 }; // TODO: Handle this on a different thread. PdhCollectQueryData(context->PerfQueryHandle); //PdhSetCounterScaleFactor(context->PerfCounterHandle, PDH_MAX_SCALE); PdhGetFormattedCounterValue( context->PerfCounterHandle, PDH_FMT_LONG | PDH_FMT_NOSCALE | PDH_FMT_NOCAP100, &counterType, &displayValue ); //if (counterType == PERF_COUNTER_COUNTER) { } context->GraphValue = displayValue.longValue; PhAddItemCircularBuffer_ULONG(&context->HistoryBuffer, displayValue.longValue); } 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; Section->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), 0); PhGetDrawInfoGraphBuffers(&Section->GraphState.Buffers, drawInfo, context->HistoryBuffer.Count); if (!Section->GraphState.Valid) { FLOAT maxGraphHeight = 0; for (ULONG i = 0; i < drawInfo->LineDataCount; i++) { Section->GraphState.Data1[i] = (FLOAT)PhGetItemCircularBuffer_ULONG(&context->HistoryBuffer, i); if (Section->GraphState.Data1[i] > maxGraphHeight) maxGraphHeight = Section->GraphState.Data1[i]; } // Scale the data. PhxfDivideSingle2U( Section->GraphState.Data1, maxGraphHeight, drawInfo->LineDataCount ); Section->GraphState.Valid = TRUE; } } return TRUE; case SysInfoGraphGetTooltipText: { PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT getTooltipText = (PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT)Parameter1; ULONG counterValue = PhGetItemCircularBuffer_ULONG( &context->HistoryBuffer, getTooltipText->Index ); PhSwapReference2(&Section->GraphState.TooltipText, PhFormatString( L"%u\n%s", counterValue, ((PPH_STRING)PHA_DEREFERENCE(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 = PhFormatString( L"%u", context->GraphValue ); } return TRUE; } return FALSE; }