コード例 #1
0
static PPH_STRING PhSipGetMaxIoString(
    _In_ LONG Index
    )
{
    PPH_PROCESS_RECORD maxProcessRecord;
    ULONG64 maxIoReadOther;
    ULONG64 maxIoWrite;

    PPH_STRING maxUsageString = NULL;

    if (maxProcessRecord = PhSipReferenceMaxIoRecord(Index))
    {
        // We found the process record, so now we construct the max. usage string.
        maxIoReadOther = PhGetItemCircularBuffer_ULONG64(SystemStatistics.MaxIoReadOtherHistory, Index);
        maxIoWrite = PhGetItemCircularBuffer_ULONG64(SystemStatistics.MaxIoWriteHistory, Index);

        if (!PH_IS_FAKE_PROCESS_ID(maxProcessRecord->ProcessId))
        {
            maxUsageString = PhaFormatString(
                L"\n%s (%u): R+O: %s, W: %s",
                maxProcessRecord->ProcessName->Buffer,
                HandleToUlong(maxProcessRecord->ProcessId),
                PhaFormatSize(maxIoReadOther, -1)->Buffer,
                PhaFormatSize(maxIoWrite, -1)->Buffer
                );
        }
        else
        {
            maxUsageString = PhaFormatString(
                L"\n%s: R+O: %s, W: %s",
                maxProcessRecord->ProcessName->Buffer,
                PhaFormatSize(maxIoReadOther, -1)->Buffer,
                PhaFormatSize(maxIoWrite, -1)->Buffer
                );
        }

        PhDereferenceProcessRecord(maxProcessRecord);
    }

    return maxUsageString;
}
コード例 #2
0
ファイル: etwprprp.c プロジェクト: PKRoma/ProcessHacker
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;
}
コード例 #3
0
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;
    }
}
コード例 #4
0
ファイル: graph.c プロジェクト: xiaowei0516/processhacker
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;
}
コード例 #5
0
ファイル: graph.c プロジェクト: xiaowei0516/processhacker
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;
}
コード例 #6
0
ファイル: graph.c プロジェクト: lei720/processhacker2
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;
}