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); }
// 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)); }
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); }
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); }