Example #1
0
PPH_STRING PhGetPhVersion(
    VOID
    )
{
    PH_FORMAT format[3];

    PhInitFormatU(&format[0], PHAPP_VERSION_MAJOR);
    PhInitFormatC(&format[1], '.');
    PhInitFormatU(&format[2], PHAPP_VERSION_MINOR);

    return PhFormat(format, 3, 16);
}
Example #2
0
// copied from ProcessHacker\netlist.c..
static PPH_STRING PhpNetworkTreeGetNetworkItemProcessName(
    _In_ PPH_NETWORK_ITEM NetworkItem
    )
{
    PH_FORMAT format[4];

    if (!NetworkItem->ProcessId)
        return PhaCreateString(L"Waiting connections");

    PhInitFormatS(&format[1], L" (");
    PhInitFormatU(&format[2], HandleToUlong(NetworkItem->ProcessId));
    PhInitFormatC(&format[3], ')');

    if (NetworkItem->ProcessName)
        PhInitFormatSR(&format[0], NetworkItem->ProcessName->sr);
    else
        PhInitFormatS(&format[0], L"Unknown process");

    return PH_AUTO(PhFormat(format, 4, 96));
}
Example #3
0
PPH_STRING PhGetSymbolFromAddress(
    _In_ PPH_SYMBOL_PROVIDER SymbolProvider,
    _In_ ULONG64 Address,
    _Out_opt_ PPH_SYMBOL_RESOLVE_LEVEL ResolveLevel,
    _Out_opt_ PPH_STRING *FileName,
    _Out_opt_ PPH_STRING *SymbolName,
    _Out_opt_ PULONG64 Displacement
    )
{
    PSYMBOL_INFOW symbolInfo;
    ULONG nameLength;
    PPH_STRING symbol = NULL;
    PH_SYMBOL_RESOLVE_LEVEL resolveLevel;
    ULONG64 displacement;
    PPH_STRING modFileName = NULL;
    PPH_STRING modBaseName = NULL;
    ULONG64 modBase;
    PPH_STRING symbolName = NULL;

    if (!SymFromAddrW_I && !SymFromAddr_I)
        return NULL;

    if (Address == 0)
    {
        if (ResolveLevel) *ResolveLevel = PhsrlInvalid;
        if (FileName) *FileName = NULL;
        if (SymbolName) *SymbolName = NULL;
        if (Displacement) *Displacement = 0;

        return NULL;
    }

#ifdef PH_SYMBOL_PROVIDER_DELAY_INIT
    PhpRegisterSymbolProvider(SymbolProvider);
#endif

    symbolInfo = PhAllocate(FIELD_OFFSET(SYMBOL_INFOW, Name) + PH_MAX_SYMBOL_NAME_LEN * 2);
    memset(symbolInfo, 0, sizeof(SYMBOL_INFOW));
    symbolInfo->SizeOfStruct = sizeof(SYMBOL_INFOW);
    symbolInfo->MaxNameLen = PH_MAX_SYMBOL_NAME_LEN;

    // Get the symbol name.

    PH_LOCK_SYMBOLS();

    // Note that we don't care whether this call
    // succeeds or not, based on the assumption that
    // it will not write to the symbolInfo structure
    // if it fails. We've already zeroed the structure,
    // so we can deal with it.

    if (SymFromAddrW_I)
    {
        SymFromAddrW_I(
            SymbolProvider->ProcessHandle,
            Address,
            &displacement,
            symbolInfo
            );
        nameLength = symbolInfo->NameLen;

        if (nameLength + 1 > PH_MAX_SYMBOL_NAME_LEN)
        {
            PhFree(symbolInfo);
            symbolInfo = PhAllocate(FIELD_OFFSET(SYMBOL_INFOW, Name) + nameLength * 2 + 2);
            memset(symbolInfo, 0, sizeof(SYMBOL_INFOW));
            symbolInfo->SizeOfStruct = sizeof(SYMBOL_INFOW);
            symbolInfo->MaxNameLen = nameLength + 1;

            SymFromAddrW_I(
                SymbolProvider->ProcessHandle,
                Address,
                &displacement,
                symbolInfo
                );
        }
    }
    else if (SymFromAddr_I)
    {
        PSYMBOL_INFO symbolInfoA;

        symbolInfoA = PhAllocate(FIELD_OFFSET(SYMBOL_INFO, Name) + PH_MAX_SYMBOL_NAME_LEN);
        memset(symbolInfoA, 0, sizeof(SYMBOL_INFO));
        symbolInfoA->SizeOfStruct = sizeof(SYMBOL_INFO);
        symbolInfoA->MaxNameLen = PH_MAX_SYMBOL_NAME_LEN;

        SymFromAddr_I(
            SymbolProvider->ProcessHandle,
            Address,
            &displacement,
            symbolInfoA
            );
        nameLength = symbolInfoA->NameLen;

        if (nameLength + 1 > PH_MAX_SYMBOL_NAME_LEN)
        {
            PhFree(symbolInfoA);
            symbolInfoA = PhAllocate(FIELD_OFFSET(SYMBOL_INFO, Name) + nameLength + 1);
            memset(symbolInfoA, 0, sizeof(SYMBOL_INFO));
            symbolInfoA->SizeOfStruct = sizeof(SYMBOL_INFO);
            symbolInfoA->MaxNameLen = nameLength + 1;

            SymFromAddr_I(
                SymbolProvider->ProcessHandle,
                Address,
                &displacement,
                symbolInfoA
                );

            // Also reallocate the Unicode-based buffer.
            PhFree(symbolInfo);
            symbolInfo = PhAllocate(FIELD_OFFSET(SYMBOL_INFOW, Name) + nameLength * 2 + 2);
            memset(symbolInfo, 0, sizeof(SYMBOL_INFOW));
            symbolInfo->SizeOfStruct = sizeof(SYMBOL_INFOW);
            symbolInfo->MaxNameLen = nameLength + 1;
        }

        PhpSymbolInfoAnsiToUnicode(symbolInfo, symbolInfoA);
        PhFree(symbolInfoA);
    }

    PH_UNLOCK_SYMBOLS();

    // Find the module name.

    if (symbolInfo->ModBase == 0)
    {
        modBase = PhGetModuleFromAddress(
            SymbolProvider,
            Address,
            &modFileName
            );
    }
    else
    {
        PH_SYMBOL_MODULE lookupSymbolModule;
        PPH_AVL_LINKS existingLinks;
        PPH_SYMBOL_MODULE symbolModule;

        lookupSymbolModule.BaseAddress = symbolInfo->ModBase;

        PhAcquireQueuedLockShared(&SymbolProvider->ModulesListLock);

        existingLinks = PhFindElementAvlTree(&SymbolProvider->ModulesSet, &lookupSymbolModule.Links);

        if (existingLinks)
        {
            symbolModule = CONTAINING_RECORD(existingLinks, PH_SYMBOL_MODULE, Links);
            modFileName = symbolModule->FileName;
            PhReferenceObject(modFileName);
        }

        PhReleaseQueuedLockShared(&SymbolProvider->ModulesListLock);
    }

    // If we don't have a module name, return an address.
    if (!modFileName)
    {
        resolveLevel = PhsrlAddress;
        symbol = PhCreateStringEx(NULL, PH_PTR_STR_LEN * 2);
        PhPrintPointer(symbol->Buffer, (PVOID)Address);
        PhTrimToNullTerminatorString(symbol);

        goto CleanupExit;
    }

    modBaseName = PhGetBaseName(modFileName);

    // If we have a module name but not a symbol name,
    // return the module plus an offset: module+offset.

    if (symbolInfo->NameLen == 0)
    {
        PH_FORMAT format[3];

        resolveLevel = PhsrlModule;

        PhInitFormatSR(&format[0], modBaseName->sr);
        PhInitFormatS(&format[1], L"+0x");
        PhInitFormatIX(&format[2], (ULONG_PTR)(Address - modBase));
        symbol = PhFormat(format, 3, modBaseName->Length + 6 + 32);

        goto CleanupExit;
    }

    // If we have everything, return the full symbol
    // name: module!symbol+offset.

    symbolName = PhCreateStringEx(
        symbolInfo->Name,
        symbolInfo->NameLen * 2
        );

    resolveLevel = PhsrlFunction;

    if (displacement == 0)
    {
        PH_FORMAT format[3];

        PhInitFormatSR(&format[0], modBaseName->sr);
        PhInitFormatC(&format[1], '!');
        PhInitFormatSR(&format[2], symbolName->sr);

        symbol = PhFormat(format, 3, modBaseName->Length + 2 + symbolName->Length);
    }
    else
    {
        PH_FORMAT format[5];

        PhInitFormatSR(&format[0], modBaseName->sr);
        PhInitFormatC(&format[1], '!');
        PhInitFormatSR(&format[2], symbolName->sr);
        PhInitFormatS(&format[3], L"+0x");
        PhInitFormatIX(&format[4], (ULONG_PTR)displacement);

        symbol = PhFormat(format, 5, modBaseName->Length + 2 + symbolName->Length + 6 + 32);
    }

CleanupExit:

    if (ResolveLevel)
        *ResolveLevel = resolveLevel;
    if (FileName)
    {
        *FileName = modFileName;

        if (modFileName)
            PhReferenceObject(modFileName);
    }
    if (SymbolName)
    {
        *SymbolName = symbolName;

        if (symbolName)
            PhReferenceObject(symbolName);
    }
    if (Displacement)
        *Displacement = displacement;

    if (modFileName)
        PhDereferenceObject(modFileName);
    if (modBaseName)
        PhDereferenceObject(modBaseName);
    if (symbolName)
        PhDereferenceObject(symbolName);

    PhFree(symbolInfo);

    return symbol;
}
VOID EtpNetworkIconUpdateCallback(
    _In_ struct _PH_NF_ICON *Icon,
    _Out_ PVOID *NewIconOrBitmap,
    _Out_ PULONG Flags,
    _Out_ PPH_STRING *NewText,
    _In_opt_ PVOID Context
    )
{
    static PH_GRAPH_DRAW_INFO drawInfo =
    {
        16,
        16,
        PH_GRAPH_USE_LINE_2,
        2,
        RGB(0x00, 0x00, 0x00),

        16,
        NULL,
        NULL,
        0,
        0,
        0,
        0
    };
    ULONG maxDataCount;
    ULONG lineDataCount;
    PFLOAT lineData1;
    PFLOAT lineData2;
    FLOAT max;
    ULONG i;
    HBITMAP bitmap;
    PVOID bits;
    HDC hdc;
    HBITMAP oldBitmap;
    HANDLE maxNetworkProcessId;
    PPH_PROCESS_ITEM maxNetworkProcessItem;
    PH_FORMAT format[6];

    // Icon

    Icon->Pointers->BeginBitmap(&drawInfo.Width, &drawInfo.Height, &bitmap, &bits, &hdc, &oldBitmap);
    maxDataCount = drawInfo.Width / 2 + 1;
    lineData1 = _alloca(maxDataCount * sizeof(FLOAT));
    lineData2 = _alloca(maxDataCount * sizeof(FLOAT));

    lineDataCount = min(maxDataCount, EtNetworkReceiveHistory.Count);
    max = 1024 * 1024; // minimum scaling of 1 MB.

    for (i = 0; i < lineDataCount; i++)
    {
        lineData1[i] = (FLOAT)PhGetItemCircularBuffer_ULONG(&EtNetworkReceiveHistory, i);
        lineData2[i] = (FLOAT)PhGetItemCircularBuffer_ULONG(&EtNetworkSendHistory, i);

        if (max < lineData1[i] + lineData2[i])
            max = lineData1[i] + lineData2[i];
    }

    PhDivideSinglesBySingle(lineData1, max, lineDataCount);
    PhDivideSinglesBySingle(lineData2, max, lineDataCount);

    drawInfo.LineDataCount = lineDataCount;
    drawInfo.LineData1 = lineData1;
    drawInfo.LineData2 = lineData2;
    drawInfo.LineColor1 = PhGetIntegerSetting(L"ColorIoReadOther");
    drawInfo.LineColor2 = PhGetIntegerSetting(L"ColorIoWrite");
    drawInfo.LineBackColor1 = PhHalveColorBrightness(drawInfo.LineColor1);
    drawInfo.LineBackColor2 = PhHalveColorBrightness(drawInfo.LineColor2);

    if (bits)
        PhDrawGraphDirect(hdc, bits, &drawInfo);

    SelectObject(hdc, oldBitmap);
    *NewIconOrBitmap = bitmap;
    *Flags = PH_NF_UPDATE_IS_BITMAP;

    // Text

    if (EtMaxNetworkHistory.Count != 0)
        maxNetworkProcessId = UlongToHandle(PhGetItemCircularBuffer_ULONG(&EtMaxNetworkHistory, 0));
    else
        maxNetworkProcessId = NULL;

    if (maxNetworkProcessId)
        maxNetworkProcessItem = PhReferenceProcessItem(maxNetworkProcessId);
    else
        maxNetworkProcessItem = NULL;

    PhInitFormatS(&format[0], L"Network\nR: ");
    PhInitFormatSize(&format[1], EtNetworkReceiveDelta.Delta);
    PhInitFormatS(&format[2], L"\nS: ");
    PhInitFormatSize(&format[3], EtNetworkSendDelta.Delta);

    if (maxNetworkProcessItem)
    {
        PhInitFormatC(&format[4], '\n');
        PhInitFormatSR(&format[5], maxNetworkProcessItem->ProcessName->sr);
    }

    *NewText = PhFormat(format, maxNetworkProcessItem ? 6 : 4, 128);
    if (maxNetworkProcessItem) PhDereferenceObject(maxNetworkProcessItem);
}
VOID EtpGpuIconUpdateCallback(
    _In_ struct _PH_NF_ICON *Icon,
    _Out_ PVOID *NewIconOrBitmap,
    _Out_ PULONG Flags,
    _Out_ PPH_STRING *NewText,
    _In_opt_ PVOID Context
    )
{
    static PH_GRAPH_DRAW_INFO drawInfo =
    {
        16,
        16,
        0,
        2,
        RGB(0x00, 0x00, 0x00),

        16,
        NULL,
        NULL,
        0,
        0,
        0,
        0
    };
    ULONG maxDataCount;
    ULONG lineDataCount;
    PFLOAT lineData1;
    HBITMAP bitmap;
    PVOID bits;
    HDC hdc;
    HBITMAP oldBitmap;
    HANDLE maxGpuProcessId;
    PPH_PROCESS_ITEM maxGpuProcessItem;
    PH_FORMAT format[8];

    // Icon

    Icon->Pointers->BeginBitmap(&drawInfo.Width, &drawInfo.Height, &bitmap, &bits, &hdc, &oldBitmap);
    maxDataCount = drawInfo.Width / 2 + 1;
    lineData1 = _alloca(maxDataCount * sizeof(FLOAT));

    lineDataCount = min(maxDataCount, EtGpuNodeHistory.Count);
    PhCopyCircularBuffer_FLOAT(&EtGpuNodeHistory, lineData1, lineDataCount);

    drawInfo.LineDataCount = lineDataCount;
    drawInfo.LineData1 = lineData1;
    drawInfo.LineColor1 = PhGetIntegerSetting(L"ColorCpuKernel");
    drawInfo.LineBackColor1 = PhHalveColorBrightness(drawInfo.LineColor1);

    if (bits)
        PhDrawGraphDirect(hdc, bits, &drawInfo);

    SelectObject(hdc, oldBitmap);
    *NewIconOrBitmap = bitmap;
    *Flags = PH_NF_UPDATE_IS_BITMAP;

    // Text

    if (EtMaxGpuNodeHistory.Count != 0)
        maxGpuProcessId = UlongToHandle(PhGetItemCircularBuffer_ULONG(&EtMaxGpuNodeHistory, 0));
    else
        maxGpuProcessId = NULL;

    if (maxGpuProcessId)
        maxGpuProcessItem = PhReferenceProcessItem(maxGpuProcessId);
    else
        maxGpuProcessItem = NULL;

    PhInitFormatS(&format[0], L"GPU Usage: ");
    PhInitFormatF(&format[1], EtGpuNodeUsage * 100, 2);
    PhInitFormatC(&format[2], '%');

    if (maxGpuProcessItem)
    {
        PhInitFormatC(&format[3], '\n');
        PhInitFormatSR(&format[4], maxGpuProcessItem->ProcessName->sr);
        PhInitFormatS(&format[5], L": ");
        PhInitFormatF(&format[6], EtGetProcessBlock(maxGpuProcessItem)->GpuNodeUsage * 100, 2);
        PhInitFormatC(&format[7], '%');
    }

    *NewText = PhFormat(format, maxGpuProcessItem ? 8 : 3, 128);
    if (maxGpuProcessItem) PhDereferenceObject(maxGpuProcessItem);
}
Example #6
0
VOID PhpUpdateThreadDetails(
    _In_ HWND hwndDlg,
    _In_ PPH_THREADS_CONTEXT Context,
    _In_ BOOLEAN Force
    )
{
    PPH_THREAD_ITEM *threads;
    ULONG numberOfThreads;
    PPH_THREAD_ITEM threadItem;
    PPH_STRING startModule = NULL;
    PPH_STRING started = NULL;
    WCHAR kernelTime[PH_TIMESPAN_STR_LEN_1] = L"N/A";
    WCHAR userTime[PH_TIMESPAN_STR_LEN_1] = L"N/A";
    PPH_STRING contextSwitches = NULL;
    PPH_STRING cycles = NULL;
    PPH_STRING state = NULL;
    WCHAR priority[PH_INT32_STR_LEN_1] = L"N/A";
    WCHAR basePriority[PH_INT32_STR_LEN_1] = L"N/A";
    PWSTR ioPriority = L"N/A";
    PWSTR pagePriority = L"N/A";
    WCHAR idealProcessor[PH_INT32_STR_LEN + 1 + PH_INT32_STR_LEN + 1] = L"N/A";
    HANDLE threadHandle;
    SYSTEMTIME time;
    IO_PRIORITY_HINT ioPriorityInteger;
    ULONG pagePriorityInteger;
    PROCESSOR_NUMBER idealProcessorNumber;
    ULONG suspendCount;

    PhGetSelectedThreadItems(&Context->ListContext, &threads, &numberOfThreads);

    if (numberOfThreads == 1)
        threadItem = threads[0];
    else
        threadItem = NULL;

    PhFree(threads);

    if (numberOfThreads != 1 && !Force)
        return;

    if (numberOfThreads == 1)
    {
        startModule = threadItem->StartAddressFileName;

        PhLargeIntegerToLocalSystemTime(&time, &threadItem->CreateTime);
        started = PhaFormatDateTime(&time);

        PhPrintTimeSpan(kernelTime, threadItem->KernelTime.QuadPart, PH_TIMESPAN_HMSM);
        PhPrintTimeSpan(userTime, threadItem->UserTime.QuadPart, PH_TIMESPAN_HMSM);

        contextSwitches = PhaFormatUInt64(threadItem->ContextSwitchesDelta.Value, TRUE);

        if (WINDOWS_HAS_CYCLE_TIME)
            cycles = PhaFormatUInt64(threadItem->CyclesDelta.Value, TRUE);

        if (threadItem->State != Waiting)
        {
            if ((ULONG)threadItem->State < MaximumThreadState)
                state = PhaCreateString(PhKThreadStateNames[(ULONG)threadItem->State]);
            else
                state = PhaCreateString(L"Unknown");
        }
        else
        {
            if ((ULONG)threadItem->WaitReason < MaximumWaitReason)
                state = PhaConcatStrings2(L"Wait:", PhKWaitReasonNames[(ULONG)threadItem->WaitReason]);
            else
                state = PhaCreateString(L"Waiting");
        }

        PhPrintInt32(priority, threadItem->Priority);
        PhPrintInt32(basePriority, threadItem->BasePriority);

        if (NT_SUCCESS(PhOpenThread(&threadHandle, ThreadQueryAccess, threadItem->ThreadId)))
        {
            if (NT_SUCCESS(PhGetThreadIoPriority(threadHandle, &ioPriorityInteger)) &&
                ioPriorityInteger < MaxIoPriorityTypes)
            {
                ioPriority = PhIoPriorityHintNames[ioPriorityInteger];
            }

            if (NT_SUCCESS(PhGetThreadPagePriority(threadHandle, &pagePriorityInteger)) &&
                pagePriorityInteger <= MEMORY_PRIORITY_NORMAL)
            {
                pagePriority = PhPagePriorityNames[pagePriorityInteger];
            }

            if (NT_SUCCESS(NtQueryInformationThread(threadHandle, ThreadIdealProcessorEx, &idealProcessorNumber, sizeof(PROCESSOR_NUMBER), NULL)))
            {
                PH_FORMAT format[3];

                PhInitFormatU(&format[0], idealProcessorNumber.Group);
                PhInitFormatC(&format[1], ':');
                PhInitFormatU(&format[2], idealProcessorNumber.Number);
                PhFormatToBuffer(format, 3, idealProcessor, sizeof(idealProcessor), NULL);
            }

            if (threadItem->WaitReason == Suspended && NT_SUCCESS(NtQueryInformationThread(threadHandle, ThreadSuspendCount, &suspendCount, sizeof(ULONG), NULL)))
            {
                PH_FORMAT format[4];

                PhInitFormatSR(&format[0], state->sr);
                PhInitFormatS(&format[1], L" (");
                PhInitFormatU(&format[2], suspendCount);
                PhInitFormatS(&format[3], L")");
                state = PH_AUTO(PhFormat(format, 4, 30));
            }

            NtClose(threadHandle);
        }
    }

    if (Force)
    {
        // These don't change...

        SetDlgItemText(hwndDlg, IDC_STARTMODULE, PhGetStringOrEmpty(startModule));
        EnableWindow(GetDlgItem(hwndDlg, IDC_OPENSTARTMODULE), !!startModule);

        SetDlgItemText(hwndDlg, IDC_STARTED, PhGetStringOrDefault(started, L"N/A"));
    }

    SetDlgItemText(hwndDlg, IDC_KERNELTIME, kernelTime);
    SetDlgItemText(hwndDlg, IDC_USERTIME, userTime);
    SetDlgItemText(hwndDlg, IDC_CONTEXTSWITCHES, PhGetStringOrDefault(contextSwitches, L"N/A"));
    SetDlgItemText(hwndDlg, IDC_CYCLES, PhGetStringOrDefault(cycles, L"N/A"));
    SetDlgItemText(hwndDlg, IDC_STATE, PhGetStringOrDefault(state, L"N/A"));
    SetDlgItemText(hwndDlg, IDC_PRIORITY, priority);
    SetDlgItemText(hwndDlg, IDC_BASEPRIORITY, basePriority);
    SetDlgItemText(hwndDlg, IDC_IOPRIORITY, ioPriority);
    SetDlgItemText(hwndDlg, IDC_PAGEPRIORITY, pagePriority);
    SetDlgItemText(hwndDlg, IDC_IDEALPROCESSOR, idealProcessor);
}