VOID ShowOptionsCallback( __in_opt PVOID Parameter, __in_opt PVOID Context ) { PhShowError((HWND)Parameter, L"Show some options here."); }
VOID NTAPI MenuItemCallback( _In_opt_ PVOID Parameter, _In_opt_ PVOID Context ) { PPH_PLUGIN_MENU_ITEM menuItem = (PPH_PLUGIN_MENU_ITEM)Parameter; switch (menuItem->Id) { case BOOT_ENTRIES_MENUITEM: { if (!EfiSupported()) { PhShowError(menuItem->OwnerWindow, L"Windows was installed using legacy BIOS."); return; } DialogBox( PluginInstance->DllBase, MAKEINTRESOURCE(IDD_FIRMWARE), NULL, UefiEntriesDlgProc ); } break; } }
static VOID DbgShowErrorMessage( _Inout_ PPH_DBGEVENTS_CONTEXT Context, _In_ PWSTR Type ) { ULONG errorCode = GetLastError(); PPH_STRING errorMessage = PhGetWin32Message(errorCode); if (errorMessage) { PhShowError(Context->DialogHandle, PhaFormatString(L"%s: [%u] %s", Type, errorCode, errorMessage->Buffer)->Buffer); PhDereferenceObject(errorMessage); } }
VOID PhShowNetworkStackDialog( _In_ HWND ParentWindowHandle, _In_ PPH_NETWORK_ITEM NetworkItem ) { NETWORK_STACK_CONTEXT networkStackContext; networkStackContext.NetworkItem = NetworkItem; networkStackContext.SymbolProvider = PhCreateSymbolProvider(NetworkItem->ProcessId); if (networkStackContext.SymbolProvider->IsRealHandle) { // Load symbols for the process. networkStackContext.LoadingProcessId = NetworkItem->ProcessId; PhEnumGenericModules( NetworkItem->ProcessId, networkStackContext.SymbolProvider->ProcessHandle, 0, LoadSymbolsEnumGenericModulesCallback, &networkStackContext ); // Load symbols for kernel-mode. networkStackContext.LoadingProcessId = SYSTEM_PROCESS_ID; PhEnumGenericModules( SYSTEM_PROCESS_ID, NULL, 0, LoadSymbolsEnumGenericModulesCallback, &networkStackContext ); } else { PhDereferenceObject(networkStackContext.SymbolProvider); PhShowError(ParentWindowHandle, L"Unable to open the process."); return; } DialogBoxParam( PhInstanceHandle, MAKEINTRESOURCE(IDD_NETSTACK), ParentWindowHandle, PhpNetworkStackDlgProc, (LPARAM)&networkStackContext ); PhDereferenceObject(networkStackContext.SymbolProvider); }
VOID PhShowHandleObjectProperties2( _In_ HWND hWnd, _In_ PPH_HANDLE_ITEM_INFO Info ) { if (PhIsNullOrEmptyString(Info->TypeName)) return; if (PhEqualString2(Info->TypeName, L"File", TRUE) || PhEqualString2(Info->TypeName, L"DLL", TRUE) || PhEqualString2(Info->TypeName, L"Mapped file", TRUE) || PhEqualString2(Info->TypeName, L"Mapped image", TRUE)) { if (Info->BestObjectName) PhShellProperties(hWnd, Info->BestObjectName->Buffer); else PhShowError(hWnd, L"Unable to open file properties because the object is unnamed."); } }
VOID PhShowSessionShadowDialog( _In_ HWND ParentWindowHandle, _In_ ULONG SessionId ) { if (SessionId == NtCurrentPeb()->SessionId) { PhShowError(ParentWindowHandle, L"You cannot remote control the current session."); return; } DialogBoxParam( PhInstanceHandle, MAKEINTRESOURCE(IDD_SHADOWSESSION), ParentWindowHandle, PhpSessionShadowDlgProc, (LPARAM)SessionId ); }
INT_PTR CALLBACK PhpProcessMemoryDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { LPPROPSHEETPAGE propSheetPage; PPH_PROCESS_PROPPAGECONTEXT propPageContext; PPH_PROCESS_ITEM processItem; PPH_MEMORY_CONTEXT memoryContext; HWND tnHandle; if (PhpPropPageDlgProcHeader(hwndDlg, uMsg, lParam, &propSheetPage, &propPageContext, &processItem)) { memoryContext = (PPH_MEMORY_CONTEXT)propPageContext->Context; if (memoryContext) tnHandle = memoryContext->ListContext.TreeNewHandle; } else { return FALSE; } switch (uMsg) { case WM_INITDIALOG: { memoryContext = propPageContext->Context = PhAllocate(PhEmGetObjectSize(EmMemoryContextType, sizeof(PH_MEMORY_CONTEXT))); memset(memoryContext, 0, sizeof(PH_MEMORY_CONTEXT)); memoryContext->ProcessId = processItem->ProcessId; // Initialize the list. tnHandle = GetDlgItem(hwndDlg, IDC_LIST); BringWindowToTop(tnHandle); PhInitializeMemoryList(hwndDlg, tnHandle, &memoryContext->ListContext); TreeNew_SetEmptyText(tnHandle, &PhpLoadingText, 0); memoryContext->LastRunStatus = -1; memoryContext->ErrorMessage = NULL; PhEmCallObjectOperation(EmMemoryContextType, memoryContext, EmObjectCreate); if (PhPluginsEnabled) { PH_PLUGIN_TREENEW_INFORMATION treeNewInfo; treeNewInfo.TreeNewHandle = tnHandle; treeNewInfo.CmData = &memoryContext->ListContext.Cm; treeNewInfo.SystemContext = memoryContext; PhInvokeCallback(PhGetGeneralCallback(GeneralCallbackMemoryTreeNewInitializing), &treeNewInfo); } PhLoadSettingsMemoryList(&memoryContext->ListContext); PhSetOptionsMemoryList(&memoryContext->ListContext, TRUE); Button_SetCheck(GetDlgItem(hwndDlg, IDC_HIDEFREEREGIONS), memoryContext->ListContext.HideFreeRegions ? BST_CHECKED : BST_UNCHECKED); PhpRefreshProcessMemoryList(hwndDlg, propPageContext); } break; case WM_DESTROY: { PhEmCallObjectOperation(EmMemoryContextType, memoryContext, EmObjectDelete); if (PhPluginsEnabled) { PH_PLUGIN_TREENEW_INFORMATION treeNewInfo; treeNewInfo.TreeNewHandle = tnHandle; treeNewInfo.CmData = &memoryContext->ListContext.Cm; PhInvokeCallback(PhGetGeneralCallback(GeneralCallbackMemoryTreeNewUninitializing), &treeNewInfo); } PhSaveSettingsMemoryList(&memoryContext->ListContext); PhDeleteMemoryList(&memoryContext->ListContext); if (memoryContext->MemoryItemListValid) PhDeleteMemoryItemList(&memoryContext->MemoryItemList); PhClearReference(&memoryContext->ErrorMessage); PhFree(memoryContext); PhpPropPageDlgProcDestroy(hwndDlg); } break; case WM_SHOWWINDOW: { if (!propPageContext->LayoutInitialized) { PPH_LAYOUT_ITEM dialogItem; dialogItem = PhAddPropPageLayoutItem(hwndDlg, hwndDlg, PH_PROP_PAGE_TAB_CONTROL_PARENT, PH_ANCHOR_ALL); PhAddPropPageLayoutItem(hwndDlg, GetDlgItem(hwndDlg, IDC_STRINGS), dialogItem, PH_ANCHOR_TOP | PH_ANCHOR_RIGHT); PhAddPropPageLayoutItem(hwndDlg, GetDlgItem(hwndDlg, IDC_REFRESH), dialogItem, PH_ANCHOR_TOP | PH_ANCHOR_RIGHT); PhAddPropPageLayoutItem(hwndDlg, memoryContext->ListContext.TreeNewHandle, dialogItem, PH_ANCHOR_ALL); PhDoPropPageLayout(hwndDlg); propPageContext->LayoutInitialized = TRUE; } } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case ID_SHOWCONTEXTMENU: { PhShowMemoryContextMenu(hwndDlg, processItem, memoryContext, (PPH_TREENEW_CONTEXT_MENU)lParam); } break; case ID_MEMORY_READWRITEMEMORY: { PPH_MEMORY_NODE memoryNode = PhGetSelectedMemoryNode(&memoryContext->ListContext); if (memoryNode && !memoryNode->IsAllocationBase) { if (memoryNode->MemoryItem->State & MEM_COMMIT) { PPH_SHOWMEMORYEDITOR showMemoryEditor = PhAllocate(sizeof(PH_SHOWMEMORYEDITOR)); memset(showMemoryEditor, 0, sizeof(PH_SHOWMEMORYEDITOR)); showMemoryEditor->ProcessId = processItem->ProcessId; showMemoryEditor->BaseAddress = memoryNode->MemoryItem->BaseAddress; showMemoryEditor->RegionSize = memoryNode->MemoryItem->RegionSize; showMemoryEditor->SelectOffset = -1; showMemoryEditor->SelectLength = 0; ProcessHacker_ShowMemoryEditor(PhMainWndHandle, showMemoryEditor); } else { PhShowError(hwndDlg, L"Unable to edit the memory region because it is not committed."); } } } break; case ID_MEMORY_SAVE: { NTSTATUS status; HANDLE processHandle; PPH_MEMORY_NODE *memoryNodes; ULONG numberOfMemoryNodes; if (!NT_SUCCESS(status = PhOpenProcess( &processHandle, PROCESS_VM_READ, processItem->ProcessId ))) { PhShowStatus(hwndDlg, L"Unable to open the process", status, 0); break; } PhGetSelectedMemoryNodes(&memoryContext->ListContext, &memoryNodes, &numberOfMemoryNodes); if (numberOfMemoryNodes != 0) { static PH_FILETYPE_FILTER filters[] = { { L"Binary files (*.bin)", L"*.bin" }, { L"All files (*.*)", L"*.*" } }; PVOID fileDialog; fileDialog = PhCreateSaveFileDialog(); PhSetFileDialogFilter(fileDialog, filters, sizeof(filters) / sizeof(PH_FILETYPE_FILTER)); PhSetFileDialogFileName(fileDialog, PhaConcatStrings2(processItem->ProcessName->Buffer, L".bin")->Buffer); if (PhShowFileDialog(hwndDlg, fileDialog)) { PPH_STRING fileName; PPH_FILE_STREAM fileStream; PVOID buffer; ULONG i; ULONG_PTR offset; fileName = PH_AUTO(PhGetFileDialogFileName(fileDialog)); if (NT_SUCCESS(status = PhCreateFileStream( &fileStream, fileName->Buffer, FILE_GENERIC_WRITE, FILE_SHARE_READ, FILE_OVERWRITE_IF, 0 ))) { buffer = PhAllocatePage(PAGE_SIZE, NULL); // Go through each selected memory item and append the region contents // to the file. for (i = 0; i < numberOfMemoryNodes; i++) { PPH_MEMORY_NODE memoryNode = memoryNodes[i]; PPH_MEMORY_ITEM memoryItem = memoryNode->MemoryItem; if (!memoryNode->IsAllocationBase && !(memoryItem->State & MEM_COMMIT)) continue; for (offset = 0; offset < memoryItem->RegionSize; offset += PAGE_SIZE) { if (NT_SUCCESS(NtReadVirtualMemory( processHandle, PTR_ADD_OFFSET(memoryItem->BaseAddress, offset), buffer, PAGE_SIZE, NULL ))) { PhWriteFileStream(fileStream, buffer, PAGE_SIZE); } } } PhFreePage(buffer); PhDereferenceObject(fileStream); } if (!NT_SUCCESS(status)) PhShowStatus(hwndDlg, L"Unable to create the file", status, 0); } PhFreeFileDialog(fileDialog); } PhFree(memoryNodes); NtClose(processHandle); } break; case ID_MEMORY_CHANGEPROTECTION: { PPH_MEMORY_NODE memoryNode = PhGetSelectedMemoryNode(&memoryContext->ListContext); if (memoryNode) { PhReferenceObject(memoryNode->MemoryItem); PhShowMemoryProtectDialog(hwndDlg, processItem, memoryNode->MemoryItem); PhUpdateMemoryNode(&memoryContext->ListContext, memoryNode); PhDereferenceObject(memoryNode->MemoryItem); } } break; case ID_MEMORY_FREE: { PPH_MEMORY_NODE memoryNode = PhGetSelectedMemoryNode(&memoryContext->ListContext); if (memoryNode) { PhReferenceObject(memoryNode->MemoryItem); PhUiFreeMemory(hwndDlg, processItem->ProcessId, memoryNode->MemoryItem, TRUE); PhDereferenceObject(memoryNode->MemoryItem); // TODO: somehow update the list } } break; case ID_MEMORY_DECOMMIT: { PPH_MEMORY_NODE memoryNode = PhGetSelectedMemoryNode(&memoryContext->ListContext); if (memoryNode) { PhReferenceObject(memoryNode->MemoryItem); PhUiFreeMemory(hwndDlg, processItem->ProcessId, memoryNode->MemoryItem, FALSE); PhDereferenceObject(memoryNode->MemoryItem); } } break; case ID_MEMORY_READWRITEADDRESS: { PPH_STRING selectedChoice = NULL; if (!memoryContext->MemoryItemListValid) break; while (PhaChoiceDialog( hwndDlg, L"Read/Write Address", L"Enter an address:", NULL, 0, NULL, PH_CHOICE_DIALOG_USER_CHOICE, &selectedChoice, NULL, L"MemoryReadWriteAddressChoices" )) { ULONG64 address64; PVOID address; if (selectedChoice->Length == 0) continue; if (PhStringToInteger64(&selectedChoice->sr, 0, &address64)) { PPH_MEMORY_ITEM memoryItem; address = (PVOID)address64; memoryItem = PhLookupMemoryItemList(&memoryContext->MemoryItemList, address); if (memoryItem) { PPH_SHOWMEMORYEDITOR showMemoryEditor = PhAllocate(sizeof(PH_SHOWMEMORYEDITOR)); memset(showMemoryEditor, 0, sizeof(PH_SHOWMEMORYEDITOR)); showMemoryEditor->ProcessId = processItem->ProcessId; showMemoryEditor->BaseAddress = memoryItem->BaseAddress; showMemoryEditor->RegionSize = memoryItem->RegionSize; showMemoryEditor->SelectOffset = (ULONG)((ULONG_PTR)address - (ULONG_PTR)memoryItem->BaseAddress); showMemoryEditor->SelectLength = 0; ProcessHacker_ShowMemoryEditor(PhMainWndHandle, showMemoryEditor); break; } else { PhShowError(hwndDlg, L"Unable to find the memory region for the selected address."); } } } } break; case ID_MEMORY_COPY: { PPH_STRING text; text = PhGetTreeNewText(tnHandle, 0); PhSetClipboardString(tnHandle, &text->sr); PhDereferenceObject(text); } break; case IDC_HIDEFREEREGIONS: { BOOLEAN hide; hide = Button_GetCheck(GetDlgItem(hwndDlg, IDC_HIDEFREEREGIONS)) == BST_CHECKED; PhSetOptionsMemoryList(&memoryContext->ListContext, hide); } break; case IDC_STRINGS: PhShowMemoryStringDialog(hwndDlg, processItem); break; case IDC_REFRESH: PhpRefreshProcessMemoryList(hwndDlg, propPageContext); break; } } break; } return FALSE; }
VOID PhShowThreadStackDialog( _In_ HWND ParentWindowHandle, _In_ HANDLE ProcessId, _In_ HANDLE ThreadId, _In_ PPH_SYMBOL_PROVIDER SymbolProvider ) { NTSTATUS status; THREAD_STACK_CONTEXT threadStackContext; HANDLE threadHandle = NULL; // If the user is trying to view a system thread stack // but KProcessHacker is not loaded, show an error message. if (ProcessId == SYSTEM_PROCESS_ID && !KphIsConnected()) { PhShowError(ParentWindowHandle, KPH_ERROR_MESSAGE); return; } memset(&threadStackContext, 0, sizeof(THREAD_STACK_CONTEXT)); threadStackContext.ProcessId = ProcessId; threadStackContext.ThreadId = ThreadId; threadStackContext.SymbolProvider = SymbolProvider; if (!NT_SUCCESS(status = PhOpenThread( &threadHandle, THREAD_GET_CONTEXT | THREAD_SUSPEND_RESUME, ThreadId ))) { if (KphIsConnected()) { status = PhOpenThread( &threadHandle, ThreadQueryAccess, ThreadId ); } } if (!NT_SUCCESS(status)) { PhShowStatus(ParentWindowHandle, L"Unable to open the thread", status, 0); return; } threadStackContext.ThreadHandle = threadHandle; threadStackContext.List = PhCreateList(10); threadStackContext.NewList = PhCreateList(10); PhInitializeQueuedLock(&threadStackContext.StatusLock); DialogBoxParam( PhInstanceHandle, MAKEINTRESOURCE(IDD_THRDSTACK), ParentWindowHandle, PhpThreadStackDlgProc, (LPARAM)&threadStackContext ); PhSwapReference(&threadStackContext.StatusMessage, NULL); PhDereferenceObject(threadStackContext.NewList); PhDereferenceObject(threadStackContext.List); if (threadStackContext.ThreadHandle) NtClose(threadStackContext.ThreadHandle); }
VOID PhShellExecuteUserString( __in HWND hWnd, __in PWSTR Setting, __in PWSTR String, __in BOOLEAN UseShellExecute, __in_opt PWSTR ErrorMessage ) { static PH_STRINGREF replacementToken = PH_STRINGREF_INIT(L"%s"); PPH_STRING executeString; PH_STRINGREF stringBefore; PH_STRINGREF stringMiddle; PH_STRINGREF stringAfter; PPH_STRING newString; PPH_STRING ntMessage; executeString = PhGetStringSetting(Setting); // Make sure the user executable string is absolute. // We can't use RtlDetermineDosPathNameType_U here because the string // may be a URL. if (PhFindCharInString(executeString, 0, ':') == -1) { newString = PhConcatStringRef2(&PhApplicationDirectory->sr, &executeString->sr); PhDereferenceObject(executeString); executeString = newString; } // Replace "%s" with the string, or use the original string if "%s" is not present. if (PhSplitStringRefAtString(&executeString->sr, &replacementToken, FALSE, &stringBefore, &stringAfter)) { PhInitializeStringRef(&stringMiddle, String); newString = PhConcatStringRef3(&stringBefore, &stringMiddle, &stringAfter); } else { newString = executeString; PhReferenceObject(newString); } PhDereferenceObject(executeString); if (UseShellExecute) { PhShellExecute(hWnd, newString->Buffer, NULL); } else { NTSTATUS status; status = PhCreateProcessWin32(NULL, newString->Buffer, NULL, NULL, 0, NULL, NULL, NULL); if (!NT_SUCCESS(status)) { if (ErrorMessage) { ntMessage = PhGetNtMessage(status); PhShowError(hWnd, L"Unable to execute the command: %s\n%s", PhGetStringOrDefault(ntMessage, L"An unknown error occurred."), ErrorMessage); PhDereferenceObject(ntMessage); } else { PhShowStatus(hWnd, L"Unable to execute the command", status, 0); } } } PhDereferenceObject(newString); }
VOID PhShowHandleObjectProperties1( _In_ HWND hWnd, _In_ PPH_HANDLE_ITEM_INFO Info ) { if (PhIsNullOrEmptyString(Info->TypeName)) return; if (PhEqualString2(Info->TypeName, L"File", TRUE) || PhEqualString2(Info->TypeName, L"DLL", TRUE) || PhEqualString2(Info->TypeName, L"Mapped file", TRUE) || PhEqualString2(Info->TypeName, L"Mapped image", TRUE)) { if (Info->BestObjectName) { PhShellExecuteUserString( PhMainWndHandle, L"FileBrowseExecutable", Info->BestObjectName->Buffer, FALSE, L"Make sure the Explorer executable file is present." ); } else PhShowError(hWnd, L"Unable to open file location because the object is unnamed."); } else if (PhEqualString2(Info->TypeName, L"Key", TRUE)) { if (Info->BestObjectName) PhShellOpenKey2(hWnd, Info->BestObjectName); else PhShowError(hWnd, L"Unable to open key because the object is unnamed."); } else if (PhEqualString2(Info->TypeName, L"Process", TRUE)) { HANDLE processHandle; HANDLE processId; PPH_PROCESS_ITEM targetProcessItem; processId = NULL; if (KphIsConnected()) { if (NT_SUCCESS(PhOpenProcess( &processHandle, PROCESS_QUERY_LIMITED_INFORMATION, Info->ProcessId ))) { PROCESS_BASIC_INFORMATION basicInfo; if (NT_SUCCESS(KphQueryInformationObject( processHandle, Info->Handle, KphObjectProcessBasicInformation, &basicInfo, sizeof(PROCESS_BASIC_INFORMATION), NULL ))) { processId = basicInfo.UniqueProcessId; } NtClose(processHandle); } } else { HANDLE handle; PROCESS_BASIC_INFORMATION basicInfo; if (NT_SUCCESS(PhpDuplicateHandleFromProcessItem( &handle, PROCESS_QUERY_LIMITED_INFORMATION, Info->ProcessId, Info->Handle ))) { if (NT_SUCCESS(PhGetProcessBasicInformation(handle, &basicInfo))) processId = basicInfo.UniqueProcessId; NtClose(handle); } } if (processId) { targetProcessItem = PhReferenceProcessItem(processId); if (targetProcessItem) { ProcessHacker_ShowProcessProperties(PhMainWndHandle, targetProcessItem); PhDereferenceObject(targetProcessItem); } else { PhShowError(hWnd, L"The process does not exist."); } } } else if (PhEqualString2(Info->TypeName, L"Section", TRUE)) { NTSTATUS status; HANDLE handle = NULL; BOOLEAN readOnly = FALSE; if (!NT_SUCCESS(status = PhpDuplicateHandleFromProcessItem( &handle, SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE, Info->ProcessId, Info->Handle ))) { status = PhpDuplicateHandleFromProcessItem( &handle, SECTION_QUERY | SECTION_MAP_READ, Info->ProcessId, Info->Handle ); readOnly = TRUE; } if (handle) { PPH_STRING sectionName = NULL; SECTION_BASIC_INFORMATION basicInfo; SIZE_T viewSize = PH_MAX_SECTION_EDIT_SIZE; PVOID viewBase = NULL; BOOLEAN tooBig = FALSE; PhGetHandleInformation(NtCurrentProcess(), handle, ULONG_MAX, NULL, NULL, NULL, §ionName); if (NT_SUCCESS(status = PhGetSectionBasicInformation(handle, &basicInfo))) { if (basicInfo.MaximumSize.QuadPart <= PH_MAX_SECTION_EDIT_SIZE) viewSize = (SIZE_T)basicInfo.MaximumSize.QuadPart; else tooBig = TRUE; status = NtMapViewOfSection( handle, NtCurrentProcess(), &viewBase, 0, 0, NULL, &viewSize, ViewShare, 0, readOnly ? PAGE_READONLY : PAGE_READWRITE ); if (status == STATUS_SECTION_PROTECTION && !readOnly) { status = NtMapViewOfSection( handle, NtCurrentProcess(), &viewBase, 0, 0, NULL, &viewSize, ViewShare, 0, PAGE_READONLY ); } if (NT_SUCCESS(status)) { PPH_SHOW_MEMORY_EDITOR showMemoryEditor = PhAllocate(sizeof(PH_SHOW_MEMORY_EDITOR)); if (tooBig) PhShowWarning(hWnd, L"The section size is greater than 32 MB. Only the first 32 MB will be available for editing."); memset(showMemoryEditor, 0, sizeof(PH_SHOW_MEMORY_EDITOR)); showMemoryEditor->ProcessId = NtCurrentProcessId(); showMemoryEditor->BaseAddress = viewBase; showMemoryEditor->RegionSize = viewSize; showMemoryEditor->SelectOffset = ULONG_MAX; showMemoryEditor->SelectLength = 0; showMemoryEditor->Title = sectionName ? PhConcatStrings2(L"Section - ", sectionName->Buffer) : PhCreateString(L"Section"); showMemoryEditor->Flags = PH_MEMORY_EDITOR_UNMAP_VIEW_OF_SECTION; ProcessHacker_ShowMemoryEditor(PhMainWndHandle, showMemoryEditor); } else { PhShowStatus(hWnd, L"Unable to map a view of the section.", status, 0); } } PhClearReference(§ionName); NtClose(handle); } if (!NT_SUCCESS(status)) { PhShowStatus(hWnd, L"Unable to query the section.", status, 0); } } else if (PhEqualString2(Info->TypeName, L"Thread", TRUE)) { HANDLE processHandle; CLIENT_ID clientId; PPH_PROCESS_ITEM targetProcessItem; PPH_PROCESS_PROPCONTEXT propContext; clientId.UniqueProcess = NULL; clientId.UniqueThread = NULL; if (KphIsConnected()) { if (NT_SUCCESS(PhOpenProcess( &processHandle, PROCESS_QUERY_LIMITED_INFORMATION, Info->ProcessId ))) { THREAD_BASIC_INFORMATION basicInfo; if (NT_SUCCESS(KphQueryInformationObject( processHandle, Info->Handle, KphObjectThreadBasicInformation, &basicInfo, sizeof(THREAD_BASIC_INFORMATION), NULL ))) { clientId = basicInfo.ClientId; } NtClose(processHandle); } } else { HANDLE handle; THREAD_BASIC_INFORMATION basicInfo; if (NT_SUCCESS(PhpDuplicateHandleFromProcessItem( &handle, THREAD_QUERY_LIMITED_INFORMATION, Info->ProcessId, Info->Handle ))) { if (NT_SUCCESS(PhGetThreadBasicInformation(handle, &basicInfo))) clientId = basicInfo.ClientId; NtClose(handle); } } if (clientId.UniqueProcess) { targetProcessItem = PhReferenceProcessItem(clientId.UniqueProcess); if (targetProcessItem) { propContext = PhCreateProcessPropContext(NULL, targetProcessItem); PhDereferenceObject(targetProcessItem); PhSetSelectThreadIdProcessPropContext(propContext, clientId.UniqueThread); ProcessHacker_Invoke(PhMainWndHandle, PhpShowProcessPropContext, propContext); } else { PhShowError(hWnd, L"The process does not exist."); } } } }
INT WINAPI wWinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ PWSTR lpCmdLine, _In_ INT nCmdShow ) { LONG result; #ifdef DEBUG PHP_BASE_THREAD_DBG dbg; #endif CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); #ifndef DEBUG SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); #endif PhInstanceHandle = (HINSTANCE)NtCurrentPeb()->ImageBaseAddress; if (!NT_SUCCESS(PhInitializePhLib())) return 1; if (!PhInitializeAppSystem()) return 1; PhInitializeCommonControls(); if (PhCurrentTokenQueryHandle) { PTOKEN_USER tokenUser; if (NT_SUCCESS(PhGetTokenUser(PhCurrentTokenQueryHandle, &tokenUser))) { PhCurrentUserName = PhGetSidFullName(tokenUser->User.Sid, TRUE, NULL); PhFree(tokenUser); } } PhLocalSystemName = PhGetSidFullName(&PhSeLocalSystemSid, TRUE, NULL); // There has been a report of the above call failing. if (!PhLocalSystemName) PhLocalSystemName = PhCreateString(L"NT AUTHORITY\\SYSTEM"); PhApplicationFileName = PhGetApplicationFileName(); PhApplicationDirectory = PhGetApplicationDirectory(); // Just in case if (!PhApplicationFileName) PhApplicationFileName = PhCreateString(L"ProcessHacker.exe"); if (!PhApplicationDirectory) PhApplicationDirectory = PhReferenceEmptyString(); PhpProcessStartupParameters(); PhSettingsInitialization(); PhpEnablePrivileges(); if (PhStartupParameters.RunAsServiceMode) { RtlExitUserProcess(PhRunAsServiceStart(PhStartupParameters.RunAsServiceMode)); } PhpInitializeSettings(); // Activate a previous instance if required. if (PhGetIntegerSetting(L"AllowOnlyOneInstance") && !PhStartupParameters.NewInstance && !PhStartupParameters.ShowOptions && !PhStartupParameters.CommandMode && !PhStartupParameters.PhSvc) { PhActivatePreviousInstance(); } if (PhGetIntegerSetting(L"EnableKph") && !PhStartupParameters.NoKph && !PhIsExecutingInWow64()) PhInitializeKph(); if (PhStartupParameters.CommandMode && PhStartupParameters.CommandType && PhStartupParameters.CommandAction) { NTSTATUS status; status = PhCommandModeStart(); if (!NT_SUCCESS(status) && !PhStartupParameters.Silent) { PhShowStatus(NULL, L"Unable to execute the command", status, 0); } RtlExitUserProcess(status); } #ifdef DEBUG dbg.ClientId = NtCurrentTeb()->ClientId; dbg.StartAddress = wWinMain; dbg.Parameter = NULL; InsertTailList(&PhDbgThreadListHead, &dbg.ListEntry); TlsSetValue(PhDbgThreadDbgTlsIndex, &dbg); #endif PhInitializeAutoPool(&BaseAutoPool); PhEmInitialization(); PhGuiSupportInitialization(); PhTreeNewInitialization(); PhGraphControlInitialization(); PhHexEditInitialization(); PhColorBoxInitialization(); PhSmallIconSize.X = GetSystemMetrics(SM_CXSMICON); PhSmallIconSize.Y = GetSystemMetrics(SM_CYSMICON); PhLargeIconSize.X = GetSystemMetrics(SM_CXICON); PhLargeIconSize.Y = GetSystemMetrics(SM_CYICON); if (PhStartupParameters.ShowOptions) { // Elevated options dialog for changing the value of Replace Task Manager with Process Hacker. PhShowOptionsDialog(PhStartupParameters.WindowHandle); RtlExitUserProcess(STATUS_SUCCESS); } #ifndef DEBUG if (PhIsExecutingInWow64() && !PhStartupParameters.PhSvc) { PhShowWarning( NULL, L"You are attempting to run the 32-bit version of Process Hacker on 64-bit Windows. " L"Most features will not work correctly.\n\n" L"Please run the 64-bit version of Process Hacker instead." ); } #endif PhPluginsEnabled = PhGetIntegerSetting(L"EnablePlugins") && !PhStartupParameters.NoPlugins; if (PhPluginsEnabled) { PhPluginsInitialization(); PhLoadPlugins(); } if (PhStartupParameters.PhSvc) { MSG message; // Turn the feedback cursor off. PostMessage(NULL, WM_NULL, 0, 0); GetMessage(&message, NULL, 0, 0); RtlExitUserProcess(PhSvcMain(NULL, NULL, NULL)); } // Create a mutant for the installer. { HANDLE mutantHandle; OBJECT_ATTRIBUTES oa; UNICODE_STRING mutantName; RtlInitUnicodeString(&mutantName, L"\\BaseNamedObjects\\ProcessHacker2Mutant"); InitializeObjectAttributes( &oa, &mutantName, 0, NULL, NULL ); NtCreateMutant(&mutantHandle, MUTANT_ALL_ACCESS, &oa, FALSE); } // Set priority. { PROCESS_PRIORITY_CLASS priorityClass; priorityClass.Foreground = FALSE; priorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_HIGH; if (PhStartupParameters.PriorityClass != 0) priorityClass.PriorityClass = (UCHAR)PhStartupParameters.PriorityClass; NtSetInformationProcess(NtCurrentProcess(), ProcessPriorityClass, &priorityClass, sizeof(PROCESS_PRIORITY_CLASS)); } if (!PhMainWndInitialization(nCmdShow)) { PhShowError(NULL, L"Unable to initialize the main window."); return 1; } PhDrainAutoPool(&BaseAutoPool); result = PhMainMessageLoop(); RtlExitUserProcess(result); }
static VOID FilterResults( _In_ HWND hwndDlg, _In_ PMEMORY_RESULTS_CONTEXT Context, _In_ ULONG Type ) { PPH_STRING selectedChoice = NULL; PPH_LIST results; pcre2_code *compiledExpression; pcre2_match_data *matchData; results = Context->Results; SetCursor(LoadCursor(NULL, IDC_WAIT)); while (PhaChoiceDialog( hwndDlg, L"Filter", L"Enter the filter pattern:", NULL, 0, NULL, PH_CHOICE_DIALOG_USER_CHOICE, &selectedChoice, NULL, L"MemFilterChoices" )) { PPH_LIST newResults = NULL; ULONG i; if (Type == FILTER_CONTAINS || Type == FILTER_CONTAINS_IGNORECASE) { newResults = PhCreateList(1024); if (Type == FILTER_CONTAINS) { for (i = 0; i < results->Count; i++) { PPH_MEMORY_RESULT result = results->Items[i]; if (wcsstr(result->Display.Buffer, selectedChoice->Buffer)) { PhReferenceMemoryResult(result); PhAddItemList(newResults, result); } } } else { PPH_STRING upperChoice; upperChoice = PhaUpperString(selectedChoice); for (i = 0; i < results->Count; i++) { PPH_MEMORY_RESULT result = results->Items[i]; PWSTR upperDisplay; upperDisplay = PhAllocateForMemorySearch(result->Display.Length + sizeof(WCHAR)); // Copy the null terminator as well. memcpy(upperDisplay, result->Display.Buffer, result->Display.Length + sizeof(WCHAR)); _wcsupr(upperDisplay); if (wcsstr(upperDisplay, upperChoice->Buffer)) { PhReferenceMemoryResult(result); PhAddItemList(newResults, result); } PhFreeForMemorySearch(upperDisplay); } } } else if (Type == FILTER_REGEX || Type == FILTER_REGEX_IGNORECASE) { int errorCode; PCRE2_SIZE errorOffset; compiledExpression = pcre2_compile( selectedChoice->Buffer, selectedChoice->Length / sizeof(WCHAR), (Type == FILTER_REGEX_IGNORECASE ? PCRE2_CASELESS : 0) | PCRE2_DOTALL, &errorCode, &errorOffset, NULL ); if (!compiledExpression) { PhShowError(hwndDlg, L"Unable to compile the regular expression: \"%s\" at position %zu.", PhGetStringOrDefault(PH_AUTO(PhPcre2GetErrorMessage(errorCode)), L"Unknown error"), errorOffset ); continue; } matchData = pcre2_match_data_create_from_pattern(compiledExpression, NULL); newResults = PhCreateList(1024); for (i = 0; i < results->Count; i++) { PPH_MEMORY_RESULT result = results->Items[i]; if (pcre2_match( compiledExpression, result->Display.Buffer, result->Display.Length / sizeof(WCHAR), 0, 0, matchData, NULL ) >= 0) { PhReferenceMemoryResult(result); PhAddItemList(newResults, result); } } pcre2_match_data_free(matchData); pcre2_code_free(compiledExpression); } if (newResults) { PhShowMemoryResultsDialog(Context->ProcessId, newResults); PhDereferenceMemoryResults((PPH_MEMORY_RESULT *)newResults->Items, newResults->Count); PhDereferenceObject(newResults); break; } } SetCursor(LoadCursor(NULL, IDC_ARROW)); }
INT_PTR CALLBACK PhpSessionShadowDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { HWND virtualKeyComboBox; PH_INTEGER_PAIR hotkey; ULONG i; PWSTR stringToSelect; SetProp(hwndDlg, L"SessionId", (HANDLE)(ULONG)lParam); PhCenterWindow(hwndDlg, GetParent(hwndDlg)); hotkey = PhGetIntegerPairSetting(L"SessionShadowHotkey"); // Set up the hotkeys. virtualKeyComboBox = GetDlgItem(hwndDlg, IDC_VIRTUALKEY); stringToSelect = L"{*}"; for (i = 0; i < sizeof(VirtualKeyPairs) / sizeof(PH_KEY_VALUE_PAIR); i++) { ComboBox_AddString(virtualKeyComboBox, VirtualKeyPairs[i].Key); if ((ULONG)VirtualKeyPairs[i].Value == (ULONG)hotkey.X) { stringToSelect = VirtualKeyPairs[i].Key; } } PhSelectComboBoxString(virtualKeyComboBox, stringToSelect, FALSE); // Set up the modifiers. Button_SetCheck(GetDlgItem(hwndDlg, IDC_SHIFT), hotkey.Y & KBDSHIFT); Button_SetCheck(GetDlgItem(hwndDlg, IDC_CTRL), hotkey.Y & KBDCTRL); Button_SetCheck(GetDlgItem(hwndDlg, IDC_ALT), hotkey.Y & KBDALT); } break; case WM_DESTROY: { RemoveProp(hwndDlg, L"SessionId"); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); break; case IDOK: { ULONG sessionId = (ULONG)GetProp(hwndDlg, L"SessionId"); ULONG virtualKey; ULONG modifiers; WCHAR computerName[64]; ULONG computerNameLength = 64; virtualKey = VK_MULTIPLY; PhFindIntegerSiKeyValuePairs( VirtualKeyPairs, sizeof(VirtualKeyPairs), PhaGetDlgItemText(hwndDlg, IDC_VIRTUALKEY)->Buffer, &virtualKey ); modifiers = 0; if (Button_GetCheck(GetDlgItem(hwndDlg, IDC_SHIFT)) == BST_CHECKED) modifiers |= KBDSHIFT; if (Button_GetCheck(GetDlgItem(hwndDlg, IDC_CTRL)) == BST_CHECKED) modifiers |= KBDCTRL; if (Button_GetCheck(GetDlgItem(hwndDlg, IDC_ALT)) == BST_CHECKED) modifiers |= KBDALT; if (GetComputerName(computerName, &computerNameLength)) { if (WinStationShadow(NULL, computerName, sessionId, (UCHAR)virtualKey, (USHORT)modifiers)) { PH_INTEGER_PAIR hotkey; hotkey.X = virtualKey; hotkey.Y = modifiers; PhSetIntegerPairSetting(L"SessionShadowHotkey", hotkey); EndDialog(hwndDlg, IDOK); } else { PhShowStatus(hwndDlg, L"Unable to remote control the session", 0, GetLastError()); } } else { PhShowError(hwndDlg, L"The computer name is too long."); } } break; } } break; } return FALSE; }
INT_PTR CALLBACK EtpModuleServicesDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { PMODULE_SERVICES_CONTEXT context = (PMODULE_SERVICES_CONTEXT)lParam; ULONG win32Result; PQUERY_TAG_INFORMATION I_QueryTagInformation; TAG_INFO_NAMES_REFERENCING_MODULE namesReferencingModule; PPH_LIST serviceList; PPH_SERVICE_ITEM *serviceItems; HWND serviceListHandle; RECT rect; PPH_PROCESS_ITEM processItem; PPH_STRING message; PhCenterWindow(hwndDlg, GetParent(hwndDlg)); I_QueryTagInformation = PhGetModuleProcAddress(L"advapi32.dll", "I_QueryTagInformation"); if (!I_QueryTagInformation) { PhShowError(hwndDlg, L"Unable to query services because the feature is not supported by the operating system."); EndDialog(hwndDlg, IDCANCEL); return FALSE; } memset(&namesReferencingModule, 0, sizeof(TAG_INFO_NAMES_REFERENCING_MODULE)); namesReferencingModule.InParams.dwPid = HandleToUlong(context->ProcessId); namesReferencingModule.InParams.pszModule = context->ModuleName; win32Result = I_QueryTagInformation(NULL, eTagInfoLevelNamesReferencingModule, &namesReferencingModule); if (win32Result == ERROR_NO_MORE_ITEMS) win32Result = 0; if (win32Result != 0) { PhShowStatus(hwndDlg, L"Unable to query services", 0, win32Result); EndDialog(hwndDlg, IDCANCEL); return FALSE; } serviceList = PhCreateList(16); if (namesReferencingModule.OutParams.pmszNames) { PPH_SERVICE_ITEM serviceItem; PWSTR serviceName; ULONG nameLength; serviceName = namesReferencingModule.OutParams.pmszNames; while (TRUE) { nameLength = (ULONG)PhCountStringZ(serviceName); if (nameLength == 0) break; if (serviceItem = PhReferenceServiceItem(serviceName)) PhAddItemList(serviceList, serviceItem); serviceName += nameLength + 1; } LocalFree(namesReferencingModule.OutParams.pmszNames); } serviceItems = PhAllocateCopy(serviceList->Items, serviceList->Count * sizeof(PPH_SERVICE_ITEM)); PhDereferenceObject(serviceList); serviceListHandle = PhCreateServiceListControl(hwndDlg, serviceItems, serviceList->Count); // Position the control. GetWindowRect(GetDlgItem(hwndDlg, IDC_SERVICES_LAYOUT), &rect); MapWindowPoints(NULL, hwndDlg, (POINT *)&rect, 2); MoveWindow(serviceListHandle, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, FALSE); ShowWindow(serviceListHandle, SW_SHOW); if (processItem = PhReferenceProcessItem(context->ProcessId)) { message = PhFormatString(L"Services referencing %s in %s:", context->ModuleName, processItem->ProcessName->Buffer); PhDereferenceObject(processItem); } else { message = PhFormatString(L"Services referencing %s:", context->ModuleName); } SetDlgItemText(hwndDlg, IDC_MESSAGE, message->Buffer); PhDereferenceObject(message); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: EndDialog(hwndDlg, IDOK); break; } } break; } return FALSE; }
INT_PTR CALLBACK EtpWsWatchDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PWS_WATCH_CONTEXT context; if (uMsg == WM_INITDIALOG) { context = (PWS_WATCH_CONTEXT)lParam; SetProp(hwndDlg, L"Context", (HANDLE)context); } else { context = (PWS_WATCH_CONTEXT)GetProp(hwndDlg, L"Context"); if (uMsg == WM_DESTROY) RemoveProp(hwndDlg, L"Context"); } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { HWND lvHandle; PhCenterWindow(hwndDlg, GetParent(hwndDlg)); context->WindowHandle = hwndDlg; context->ListViewHandle = lvHandle = GetDlgItem(hwndDlg, IDC_LIST); PhSetListViewStyle(lvHandle, FALSE, TRUE); PhSetControlTheme(lvHandle, L"explorer"); PhAddListViewColumn(lvHandle, 0, 0, 0, LVCFMT_LEFT, 340, L"Instruction"); PhAddListViewColumn(lvHandle, 1, 1, 1, LVCFMT_LEFT, 80, L"Count"); PhSetExtendedListView(lvHandle); ExtendedListView_SetSort(lvHandle, 1, DescendingSortOrder); context->Hashtable = PhCreateSimpleHashtable(64); context->BufferSize = 0x2000; context->Buffer = PhAllocate(context->BufferSize); PhInitializeQueuedLock(&context->ResultListLock); context->SymbolProvider = PhCreateSymbolProvider(context->ProcessItem->ProcessId); PhLoadSymbolProviderOptions(context->SymbolProvider); if (!context->SymbolProvider || !context->SymbolProvider->IsRealHandle) { PhShowError(hwndDlg, L"Unable to open the process."); EndDialog(hwndDlg, IDCANCEL); break; } context->ProcessHandle = context->SymbolProvider->ProcessHandle; // Load symbols for both process and kernel modules. context->LoadingSymbolsForProcessId = context->ProcessItem->ProcessId; PhEnumGenericModules( NULL, context->ProcessHandle, 0, EnumGenericModulesCallback, context ); context->LoadingSymbolsForProcessId = SYSTEM_PROCESS_ID; PhEnumGenericModules( SYSTEM_PROCESS_ID, NULL, 0, EnumGenericModulesCallback, context ); context->Enabled = EtpUpdateWsWatch(hwndDlg, context); if (context->Enabled) { // WS Watch is already enabled for the process. Enable updating. EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE), FALSE); ShowWindow(GetDlgItem(hwndDlg, IDC_WSWATCHENABLED), SW_SHOW); SetTimer(hwndDlg, 1, 1000, NULL); } else { // WS Watch has not yet been enabled for the process. } } break; case WM_DESTROY: { context->Destroying = TRUE; PhDereferenceObject(context->Hashtable); if (context->Buffer) { PhFree(context->Buffer); context->Buffer = NULL; } } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: EndDialog(hwndDlg, IDOK); break; case IDC_ENABLE: { NTSTATUS status; HANDLE processHandle; if (NT_SUCCESS(status = PhOpenProcess( &processHandle, PROCESS_SET_INFORMATION, context->ProcessItem->ProcessId ))) { status = NtSetInformationProcess( processHandle, ProcessWorkingSetWatchEx, NULL, 0 ); NtClose(processHandle); } if (NT_SUCCESS(status)) { EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE), FALSE); ShowWindow(GetDlgItem(hwndDlg, IDC_WSWATCHENABLED), SW_SHOW); SetTimer(hwndDlg, 1, 1000, NULL); } else { PhShowStatus(hwndDlg, L"Unable to enable WS watch", status, 0); } } break; } } break; case WM_NOTIFY: { PhHandleListViewNotifyForCopy(lParam, context->ListViewHandle); } break; case WM_TIMER: { switch (wParam) { case 1: { EtpUpdateWsWatch(hwndDlg, context); } break; } } break; } return FALSE; }
static INT_PTR CALLBACK PhpHiddenProcessesDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { HWND lvHandle; PhCenterWindow(hwndDlg, GetParent(hwndDlg)); PhHiddenProcessesListViewHandle = lvHandle = GetDlgItem(hwndDlg, IDC_PROCESSES); PhInitializeLayoutManager(&WindowLayoutManager, hwndDlg); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_INTRO), NULL, PH_ANCHOR_LEFT | PH_ANCHOR_TOP | PH_ANCHOR_RIGHT | PH_LAYOUT_FORCE_INVALIDATE); PhAddLayoutItem(&WindowLayoutManager, lvHandle, NULL, PH_ANCHOR_ALL); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_DESCRIPTION), NULL, PH_ANCHOR_LEFT | PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM | PH_LAYOUT_FORCE_INVALIDATE); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_METHOD), NULL, PH_ANCHOR_LEFT | PH_ANCHOR_BOTTOM); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_TERMINATE), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_SAVE), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_SCAN), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); MinimumSize.left = 0; MinimumSize.top = 0; MinimumSize.right = 330; MinimumSize.bottom = 140; MapDialogRect(hwndDlg, &MinimumSize); PhRegisterDialog(hwndDlg); PhLoadWindowPlacementFromSetting(L"HiddenProcessesWindowPosition", L"HiddenProcessesWindowSize", hwndDlg); PhSetListViewStyle(lvHandle, TRUE, TRUE); PhSetControlTheme(lvHandle, L"explorer"); PhAddListViewColumn(lvHandle, 0, 0, 0, LVCFMT_LEFT, 320, L"Process"); PhAddListViewColumn(lvHandle, 1, 1, 1, LVCFMT_LEFT, 60, L"PID"); PhSetExtendedListView(lvHandle); PhLoadListViewColumnsFromSetting(L"HiddenProcessesListViewColumns", lvHandle); ExtendedListView_AddFallbackColumn(lvHandle, 0); ExtendedListView_AddFallbackColumn(lvHandle, 1); ExtendedListView_SetItemColorFunction(lvHandle, PhpHiddenProcessesColorFunction); ComboBox_AddString(GetDlgItem(hwndDlg, IDC_METHOD), L"Brute Force"); ComboBox_AddString(GetDlgItem(hwndDlg, IDC_METHOD), L"CSR Handles"); PhSelectComboBoxString(GetDlgItem(hwndDlg, IDC_METHOD), L"CSR Handles", FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_TERMINATE), FALSE); } break; case WM_DESTROY: { PhSaveWindowPlacementToSetting(L"HiddenProcessesWindowPosition", L"HiddenProcessesWindowSize", hwndDlg); PhSaveListViewColumnsToSetting(L"HiddenProcessesListViewColumns", PhHiddenProcessesListViewHandle); } break; case WM_CLOSE: { // Hide, don't close. ShowWindow(hwndDlg, SW_HIDE); SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, 0); } return TRUE; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: { SendMessage(hwndDlg, WM_CLOSE, 0, 0); } break; case IDC_SCAN: { NTSTATUS status; PPH_STRING method; method = PhGetWindowText(GetDlgItem(hwndDlg, IDC_METHOD)); PhAutoDereferenceObject(method); if (ProcessesList) { ULONG i; for (i = 0; i < ProcessesList->Count; i++) { PPH_HIDDEN_PROCESS_ENTRY entry = ProcessesList->Items[i]; if (entry->FileName) PhDereferenceObject(entry->FileName); PhFree(entry); } PhDereferenceObject(ProcessesList); } ListView_DeleteAllItems(PhHiddenProcessesListViewHandle); ProcessesList = PhCreateList(40); ProcessesMethod = PhEqualString2(method, L"Brute Force", TRUE) ? BruteForceScanMethod : CsrHandlesScanMethod; NumberOfHiddenProcesses = 0; NumberOfTerminatedProcesses = 0; ExtendedListView_SetRedraw(PhHiddenProcessesListViewHandle, FALSE); status = PhEnumHiddenProcesses( ProcessesMethod, PhpHiddenProcessesCallback, NULL ); ExtendedListView_SortItems(PhHiddenProcessesListViewHandle); ExtendedListView_SetRedraw(PhHiddenProcessesListViewHandle, TRUE); if (NT_SUCCESS(status)) { SetDlgItemText(hwndDlg, IDC_DESCRIPTION, PhaFormatString(L"%u hidden process(es), %u terminated process(es).", NumberOfHiddenProcesses, NumberOfTerminatedProcesses)->Buffer ); InvalidateRect(GetDlgItem(hwndDlg, IDC_DESCRIPTION), NULL, TRUE); } else { PhShowStatus(hwndDlg, L"Unable to perform the scan", status, 0); } } break; case IDC_TERMINATE: { PPH_HIDDEN_PROCESS_ENTRY *entries; ULONG numberOfEntries; ULONG i; PhGetSelectedListViewItemParams(PhHiddenProcessesListViewHandle, &entries, &numberOfEntries); if (numberOfEntries != 0) { if (!PhGetIntegerSetting(L"EnableWarnings") || PhShowConfirmMessage( hwndDlg, L"terminate", L"the selected process(es)", L"Terminating a hidden process may cause the system to become unstable " L"or crash.", TRUE )) { NTSTATUS status; HANDLE processHandle; BOOLEAN refresh; refresh = FALSE; for (i = 0; i < numberOfEntries; i++) { if (ProcessesMethod == BruteForceScanMethod) { status = PhOpenProcess( &processHandle, PROCESS_TERMINATE, entries[i]->ProcessId ); } else { status = PhOpenProcessByCsrHandles( &processHandle, PROCESS_TERMINATE, entries[i]->ProcessId ); } if (NT_SUCCESS(status)) { status = PhTerminateProcess(processHandle, STATUS_SUCCESS); NtClose(processHandle); if (NT_SUCCESS(status)) refresh = TRUE; } else { PhShowStatus(hwndDlg, L"Unable to terminate the process", status, 0); } } if (refresh) { LARGE_INTEGER interval; // Sleep for a bit before continuing. It seems to help avoid // BSODs. interval.QuadPart = -250 * PH_TIMEOUT_MS; NtDelayExecution(FALSE, &interval); SendMessage(hwndDlg, WM_COMMAND, IDC_SCAN, 0); } } } PhFree(entries); } break; case IDC_SAVE: { static PH_FILETYPE_FILTER filters[] = { { L"Text files (*.txt)", L"*.txt" }, { L"All files (*.*)", L"*.*" } }; PVOID fileDialog; fileDialog = PhCreateSaveFileDialog(); PhSetFileDialogFilter(fileDialog, filters, sizeof(filters) / sizeof(PH_FILETYPE_FILTER)); PhSetFileDialogFileName(fileDialog, L"Hidden Processes.txt"); if (PhShowFileDialog(hwndDlg, fileDialog)) { NTSTATUS status; PPH_STRING fileName; PPH_FILE_STREAM fileStream; fileName = PhGetFileDialogFileName(fileDialog); PhAutoDereferenceObject(fileName); if (NT_SUCCESS(status = PhCreateFileStream( &fileStream, fileName->Buffer, FILE_GENERIC_WRITE, FILE_SHARE_READ, FILE_OVERWRITE_IF, 0 ))) { PhWriteStringAsUtf8FileStream(fileStream, &PhUnicodeByteOrderMark); PhWritePhTextHeader(fileStream); PhWriteStringAsUtf8FileStream2(fileStream, L"Method: "); PhWriteStringAsUtf8FileStream2(fileStream, ProcessesMethod == BruteForceScanMethod ? L"Brute Force\r\n" : L"CSR Handles\r\n"); PhWriteStringFormatAsUtf8FileStream( fileStream, L"Hidden: %u\r\nTerminated: %u\r\n\r\n", NumberOfHiddenProcesses, NumberOfTerminatedProcesses ); if (ProcessesList) { ULONG i; for (i = 0; i < ProcessesList->Count; i++) { PPH_HIDDEN_PROCESS_ENTRY entry = ProcessesList->Items[i]; if (entry->Type == HiddenProcess) PhWriteStringAsUtf8FileStream2(fileStream, L"[HIDDEN] "); else if (entry->Type == TerminatedProcess) PhWriteStringAsUtf8FileStream2(fileStream, L"[Terminated] "); else if (entry->Type != NormalProcess) continue; PhWriteStringFormatAsUtf8FileStream( fileStream, L"%s (%u)\r\n", entry->FileName->Buffer, HandleToUlong(entry->ProcessId) ); } } PhDereferenceObject(fileStream); } if (!NT_SUCCESS(status)) PhShowStatus(hwndDlg, L"Unable to create the file", status, 0); } PhFreeFileDialog(fileDialog); } break; } } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; PhHandleListViewNotifyBehaviors(lParam, PhHiddenProcessesListViewHandle, PH_LIST_VIEW_DEFAULT_1_BEHAVIORS); switch (header->code) { case LVN_ITEMCHANGED: { if (header->hwndFrom == PhHiddenProcessesListViewHandle) { EnableWindow( GetDlgItem(hwndDlg, IDC_TERMINATE), ListView_GetSelectedCount(PhHiddenProcessesListViewHandle) > 0 ); } } break; case NM_DBLCLK: { if (header->hwndFrom == PhHiddenProcessesListViewHandle) { PPH_HIDDEN_PROCESS_ENTRY entry; entry = PhGetSelectedListViewItemParam(PhHiddenProcessesListViewHandle); if (entry) { PPH_PROCESS_ITEM processItem; if (processItem = PhpCreateProcessItemForHiddenProcess(entry)) { ProcessHacker_ShowProcessProperties(PhMainWndHandle, processItem); PhDereferenceObject(processItem); } else { PhShowError(hwndDlg, L"Unable to create a process structure for the selected process."); } } } } break; } } break; case WM_SIZE: { PhLayoutManagerLayout(&WindowLayoutManager); } break; case WM_SIZING: { PhResizingMinimumSize((PRECT)lParam, wParam, MinimumSize.right, MinimumSize.bottom); } break; case WM_CTLCOLORSTATIC: { if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_DESCRIPTION)) { if (NumberOfHiddenProcesses != 0) { SetTextColor((HDC)wParam, RGB(0xff, 0x00, 0x00)); } SetBkColor((HDC)wParam, GetSysColor(COLOR_3DFACE)); return (INT_PTR)GetSysColorBrush(COLOR_3DFACE); } } break; } REFLECT_MESSAGE_DLG(hwndDlg, PhHiddenProcessesListViewHandle, uMsg, wParam, lParam); return FALSE; }
INT_PTR CALLBACK WepWindowsDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PWINDOWS_CONTEXT context; if (uMsg == WM_INITDIALOG) { context = (PWINDOWS_CONTEXT)lParam; SetProp(hwndDlg, L"Context", (HANDLE)context); } else { context = (PWINDOWS_CONTEXT)GetProp(hwndDlg, L"Context"); if (uMsg == WM_DESTROY) RemoveProp(hwndDlg, L"Context"); } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { PPH_STRING windowTitle; PH_RECTANGLE windowRectangle; context->TreeNewHandle = GetDlgItem(hwndDlg, IDC_LIST); WeInitializeWindowTree(hwndDlg, context->TreeNewHandle, &context->TreeContext); PhRegisterDialog(hwndDlg); PhInitializeLayoutManager(&context->LayoutManager, hwndDlg); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_LIST), NULL, PH_ANCHOR_ALL); if (MinimumSize.left == -1) { RECT rect; rect.left = 0; rect.top = 0; rect.right = 160; rect.bottom = 100; MapDialogRect(hwndDlg, &rect); MinimumSize = rect; MinimumSize.left = 0; } // Set up the window position and size. windowRectangle.Position = PhGetIntegerPairSetting(SETTING_NAME_WINDOWS_WINDOW_POSITION); windowRectangle.Size = PhGetIntegerPairSetting(SETTING_NAME_WINDOWS_WINDOW_SIZE); PhAdjustRectangleToWorkingArea(hwndDlg, &windowRectangle); MoveWindow(hwndDlg, windowRectangle.Left, windowRectangle.Top, windowRectangle.Width, windowRectangle.Height, FALSE); // Implement cascading by saving an offsetted rectangle. windowRectangle.Left += 20; windowRectangle.Top += 20; PhSetIntegerPairSetting(SETTING_NAME_WINDOWS_WINDOW_POSITION, windowRectangle.Position); windowTitle = WepGetWindowTitleForSelector(&context->Selector); SetWindowText(hwndDlg, windowTitle->Buffer); PhDereferenceObject(windowTitle); WepRefreshWindows(context); } break; case WM_DESTROY: { PhSaveWindowPlacementToSetting(SETTING_NAME_WINDOWS_WINDOW_POSITION, SETTING_NAME_WINDOWS_WINDOW_SIZE, hwndDlg); PhDeleteLayoutManager(&context->LayoutManager); PhUnregisterDialog(hwndDlg); WeDeleteWindowTree(&context->TreeContext); WepDeleteWindowSelector(&context->Selector); PhFree(context); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: //case IDOK: DestroyWindow(hwndDlg); break; case IDC_REFRESH: WepRefreshWindows(context); break; case ID_SHOWCONTEXTMENU: { POINT point; PWE_WINDOW_NODE *windows; ULONG numberOfWindows; HMENU menu; HMENU subMenu; point.x = (SHORT)LOWORD(lParam); point.y = (SHORT)HIWORD(lParam); WeGetSelectedWindowNodes( &context->TreeContext, &windows, &numberOfWindows ); if (numberOfWindows != 0) { menu = LoadMenu(PluginInstance->DllBase, MAKEINTRESOURCE(IDR_WINDOW)); subMenu = GetSubMenu(menu, 0); SetMenuDefaultItem(subMenu, ID_WINDOW_PROPERTIES, FALSE); if (numberOfWindows == 1) { WINDOWPLACEMENT placement = { sizeof(placement) }; BYTE alpha; ULONG flags; ULONG i; ULONG id; // State GetWindowPlacement(windows[0]->WindowHandle, &placement); if (placement.showCmd == SW_MINIMIZE) PhEnableMenuItem(subMenu, ID_WINDOW_MINIMIZE, FALSE); else if (placement.showCmd == SW_MAXIMIZE) PhEnableMenuItem(subMenu, ID_WINDOW_MAXIMIZE, FALSE); else if (placement.showCmd == SW_NORMAL) PhEnableMenuItem(subMenu, ID_WINDOW_RESTORE, FALSE); // Visible CheckMenuItem(subMenu, ID_WINDOW_VISIBLE, (GetWindowLong(windows[0]->WindowHandle, GWL_STYLE) & WS_VISIBLE) ? MF_CHECKED : MF_UNCHECKED); // Enabled CheckMenuItem(subMenu, ID_WINDOW_ENABLED, !(GetWindowLong(windows[0]->WindowHandle, GWL_STYLE) & WS_DISABLED) ? MF_CHECKED : MF_UNCHECKED); // Always on Top CheckMenuItem(subMenu, ID_WINDOW_ALWAYSONTOP, (GetWindowLong(windows[0]->WindowHandle, GWL_EXSTYLE) & WS_EX_TOPMOST) ? MF_CHECKED : MF_UNCHECKED); // Opacity if (GetLayeredWindowAttributes(windows[0]->WindowHandle, NULL, &alpha, &flags)) { if (!(flags & LWA_ALPHA)) alpha = 255; } else { alpha = 255; } if (alpha == 255) { id = ID_OPACITY_OPAQUE; } else { id = 0; // Due to integer division, we cannot use simple arithmetic to calculate which menu item to check. for (i = 0; i < 10; i++) { if (alpha == (BYTE)(255 * (i + 1) / 10)) { id = ID_OPACITY_10 + i; break; } } } if (id != 0) { CheckMenuRadioItem(subMenu, ID_OPACITY_10, ID_OPACITY_OPAQUE, id, MF_BYCOMMAND); } } else { PhEnableAllMenuItems(subMenu, FALSE); PhEnableMenuItem(subMenu, ID_WINDOW_COPY, TRUE); } TrackPopupMenu( subMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON, point.x, point.y, 0, hwndDlg, NULL ); DestroyMenu(menu); } } break; case ID_WINDOW_BRINGTOFRONT: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { WINDOWPLACEMENT placement = { sizeof(placement) }; GetWindowPlacement(selectedNode->WindowHandle, &placement); if (placement.showCmd == SW_MINIMIZE) ShowWindowAsync(selectedNode->WindowHandle, SW_RESTORE); else SetForegroundWindow(selectedNode->WindowHandle); } } break; case ID_WINDOW_RESTORE: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { ShowWindowAsync(selectedNode->WindowHandle, SW_RESTORE); } } break; case ID_WINDOW_MINIMIZE: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { ShowWindowAsync(selectedNode->WindowHandle, SW_MINIMIZE); } } break; case ID_WINDOW_MAXIMIZE: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { ShowWindowAsync(selectedNode->WindowHandle, SW_MAXIMIZE); } } break; case ID_WINDOW_CLOSE: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { PostMessage(selectedNode->WindowHandle, WM_CLOSE, 0, 0); } } break; case ID_WINDOW_VISIBLE: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { if (IsWindowVisible(selectedNode->WindowHandle)) { selectedNode->WindowVisible = FALSE; ShowWindowAsync(selectedNode->WindowHandle, SW_HIDE); } else { selectedNode->WindowVisible = TRUE; ShowWindowAsync(selectedNode->WindowHandle, SW_SHOW); } PhInvalidateTreeNewNode(&selectedNode->Node, TN_CACHE_COLOR); TreeNew_InvalidateNode(context->TreeNewHandle, &selectedNode->Node); } } break; case ID_WINDOW_ENABLED: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { EnableWindow(selectedNode->WindowHandle, !IsWindowEnabled(selectedNode->WindowHandle)); } } break; case ID_WINDOW_ALWAYSONTOP: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { LOGICAL topMost; topMost = GetWindowLong(selectedNode->WindowHandle, GWL_EXSTYLE) & WS_EX_TOPMOST; SetWindowPos(selectedNode->WindowHandle, topMost ? HWND_NOTOPMOST : HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); } } break; case ID_OPACITY_10: case ID_OPACITY_20: case ID_OPACITY_30: case ID_OPACITY_40: case ID_OPACITY_50: case ID_OPACITY_60: case ID_OPACITY_70: case ID_OPACITY_80: case ID_OPACITY_90: case ID_OPACITY_OPAQUE: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { ULONG opacity; opacity = ((ULONG)LOWORD(wParam) - ID_OPACITY_10) + 1; if (opacity == 10) { // Remove the WS_EX_LAYERED bit since it is not needed. PhSetWindowExStyle(selectedNode->WindowHandle, WS_EX_LAYERED, 0); RedrawWindow(selectedNode->WindowHandle, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); } else { // Add the WS_EX_LAYERED bit so opacity will work. PhSetWindowExStyle(selectedNode->WindowHandle, WS_EX_LAYERED, WS_EX_LAYERED); SetLayeredWindowAttributes(selectedNode->WindowHandle, 0, (BYTE)(255 * opacity / 10), LWA_ALPHA); } } } break; case ID_WINDOW_HIGHLIGHT: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { if (context->HighlightingWindow) { if (context->HighlightingWindowCount & 1) WeInvertWindowBorder(context->HighlightingWindow); } context->HighlightingWindow = selectedNode->WindowHandle; context->HighlightingWindowCount = 10; SetTimer(hwndDlg, 9, 100, NULL); } } break; case ID_WINDOW_GOTOTHREAD: { PWE_WINDOW_NODE selectedNode; PPH_PROCESS_ITEM processItem; PPH_PROCESS_PROPCONTEXT propContext; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { if (processItem = PhReferenceProcessItem(selectedNode->ClientId.UniqueProcess)) { if (propContext = PhCreateProcessPropContext(WE_PhMainWndHandle, processItem)) { PhSetSelectThreadIdProcessPropContext(propContext, selectedNode->ClientId.UniqueThread); PhShowProcessProperties(propContext); PhDereferenceObject(propContext); } PhDereferenceObject(processItem); } else { PhShowError(hwndDlg, L"The process does not exist."); } } } break; case ID_WINDOW_PROPERTIES: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) WeShowWindowProperties(WE_PhMainWndHandle, selectedNode->WindowHandle); } break; case ID_WINDOW_COPY: { PPH_STRING text; text = PhGetTreeNewText(context->TreeNewHandle, 0); PhSetClipboardStringEx(hwndDlg, text->Buffer, text->Length); PhDereferenceObject(text); } break; } } break; case WM_TIMER: { switch (wParam) { case 9: { WeInvertWindowBorder(context->HighlightingWindow); if (--context->HighlightingWindowCount == 0) KillTimer(hwndDlg, 9); } break; } } break; case WM_SIZE: { PhLayoutManagerLayout(&context->LayoutManager); } break; case WM_SIZING: { PhResizingMinimumSize((PRECT)lParam, wParam, MinimumSize.right, MinimumSize.bottom); } break; case WM_WE_PLUSMINUS: { PWE_WINDOW_NODE node = (PWE_WINDOW_NODE)lParam; if (!node->Opened) { TreeNew_SetRedraw(context->TreeNewHandle, FALSE); WepAddChildWindows(context, node, node->WindowHandle, NULL, NULL); node->Opened = TRUE; TreeNew_SetRedraw(context->TreeNewHandle, TRUE); } } break; } return FALSE; }
INT_PTR CALLBACK PhpMemoryEditorDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PMEMORY_EDITOR_CONTEXT context; if (uMsg != WM_INITDIALOG) { context = GetProp(hwndDlg, PhMakeContextAtom()); } else { context = (PMEMORY_EDITOR_CONTEXT)lParam; SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)context); } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { NTSTATUS status; if (context->Title) { SetWindowText(hwndDlg, context->Title->Buffer); } else { PPH_PROCESS_ITEM processItem; if (processItem = PhReferenceProcessItem(context->ProcessId)) { SetWindowText(hwndDlg, PhaFormatString(L"%s (%u) (0x%Ix - 0x%Ix)", processItem->ProcessName->Buffer, HandleToUlong(context->ProcessId), context->BaseAddress, (ULONG_PTR)context->BaseAddress + context->RegionSize)->Buffer); PhDereferenceObject(processItem); } } PhInitializeLayoutManager(&context->LayoutManager, hwndDlg); if (context->RegionSize > 1024 * 1024 * 1024) // 1 GB { PhShowError(NULL, L"Unable to edit the memory region because it is too large."); return TRUE; } if (!NT_SUCCESS(status = PhOpenProcess( &context->ProcessHandle, PROCESS_VM_READ, context->ProcessId ))) { PhShowStatus(NULL, L"Unable to open the process", status, 0); return TRUE; } context->Buffer = PhAllocatePage(context->RegionSize, NULL); if (!context->Buffer) { PhShowError(NULL, L"Unable to allocate memory for the buffer."); return TRUE; } if (!NT_SUCCESS(status = PhReadVirtualMemory( context->ProcessHandle, context->BaseAddress, context->Buffer, context->RegionSize, NULL ))) { PhShowStatus(PhMainWndHandle, L"Unable to read memory", status, 0); return TRUE; } PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_SAVE), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_BYTESPERROW), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_GOTO), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_WRITE), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_REREAD), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT); if (MinimumSize.left == -1) { RECT rect; rect.left = 0; rect.top = 0; rect.right = 290; rect.bottom = 140; MapDialogRect(hwndDlg, &rect); MinimumSize = rect; MinimumSize.left = 0; } context->HexEditHandle = GetDlgItem(hwndDlg, IDC_MEMORY); PhAddLayoutItem(&context->LayoutManager, context->HexEditHandle, NULL, PH_ANCHOR_ALL); HexEdit_SetBuffer(context->HexEditHandle, context->Buffer, (ULONG)context->RegionSize); { PH_RECTANGLE windowRectangle; windowRectangle.Position = PhGetIntegerPairSetting(L"MemEditPosition"); windowRectangle.Size = PhGetScalableIntegerPairSetting(L"MemEditSize", TRUE).Pair; PhAdjustRectangleToWorkingArea(NULL, &windowRectangle); MoveWindow(hwndDlg, windowRectangle.Left, windowRectangle.Top, windowRectangle.Width, windowRectangle.Height, FALSE); // Implement cascading by saving an offsetted rectangle. windowRectangle.Left += 20; windowRectangle.Top += 20; PhSetIntegerPairSetting(L"MemEditPosition", windowRectangle.Position); PhSetScalableIntegerPairSetting2(L"MemEditSize", windowRectangle.Size); } { PWSTR bytesPerRowStrings[7]; ULONG i; ULONG bytesPerRow; for (i = 0; i < sizeof(bytesPerRowStrings) / sizeof(PWSTR); i++) bytesPerRowStrings[i] = PhaFormatString(L"%u bytes per row", 1 << (2 + i))->Buffer; PhAddComboBoxStrings(GetDlgItem(hwndDlg, IDC_BYTESPERROW), bytesPerRowStrings, sizeof(bytesPerRowStrings) / sizeof(PWSTR)); bytesPerRow = PhGetIntegerSetting(L"MemEditBytesPerRow"); if (bytesPerRow >= 4) { HexEdit_SetBytesPerRow(context->HexEditHandle, bytesPerRow); PhSelectComboBoxString(GetDlgItem(hwndDlg, IDC_BYTESPERROW), PhaFormatString(L"%u bytes per row", bytesPerRow)->Buffer, FALSE); } } context->LoadCompleted = TRUE; } break; case WM_DESTROY: { if (context->LoadCompleted) { PhSaveWindowPlacementToSetting(L"MemEditPosition", L"MemEditSize", hwndDlg); PhRemoveElementAvlTree(&PhMemoryEditorSet, &context->Links); PhUnregisterDialog(hwndDlg); } RemoveProp(hwndDlg, PhMakeContextAtom()); PhDeleteLayoutManager(&context->LayoutManager); if (context->Buffer) PhFreePage(context->Buffer); if (context->ProcessHandle) NtClose(context->ProcessHandle); PhClearReference(&context->Title); if ((context->Flags & PH_MEMORY_EDITOR_UNMAP_VIEW_OF_SECTION) && context->ProcessId == NtCurrentProcessId()) NtUnmapViewOfSection(NtCurrentProcess(), context->BaseAddress); PhFree(context); } break; case WM_SHOWWINDOW: { SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)context->HexEditHandle, TRUE); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: DestroyWindow(hwndDlg); break; case IDC_SAVE: { static PH_FILETYPE_FILTER filters[] = { { L"Binary files (*.bin)", L"*.bin" }, { L"All files (*.*)", L"*.*" } }; PVOID fileDialog; PPH_PROCESS_ITEM processItem; fileDialog = PhCreateSaveFileDialog(); PhSetFileDialogFilter(fileDialog, filters, sizeof(filters) / sizeof(PH_FILETYPE_FILTER)); if (!context->Title && (processItem = PhReferenceProcessItem(context->ProcessId))) { PhSetFileDialogFileName(fileDialog, PhaFormatString(L"%s_0x%Ix-0x%Ix.bin", processItem->ProcessName->Buffer, context->BaseAddress, context->RegionSize)->Buffer); PhDereferenceObject(processItem); } else { PhSetFileDialogFileName(fileDialog, L"Memory.bin"); } if (PhShowFileDialog(hwndDlg, fileDialog)) { NTSTATUS status; PPH_STRING fileName; PPH_FILE_STREAM fileStream; fileName = PH_AUTO(PhGetFileDialogFileName(fileDialog)); if (NT_SUCCESS(status = PhCreateFileStream( &fileStream, fileName->Buffer, FILE_GENERIC_WRITE, FILE_SHARE_READ, FILE_OVERWRITE_IF, 0 ))) { status = PhWriteFileStream(fileStream, context->Buffer, (ULONG)context->RegionSize); PhDereferenceObject(fileStream); } if (!NT_SUCCESS(status)) PhShowStatus(hwndDlg, L"Unable to create the file", status, 0); } PhFreeFileDialog(fileDialog); } break; case IDC_GOTO: { PPH_STRING selectedChoice = NULL; while (PhaChoiceDialog( hwndDlg, L"Go to Offset", L"Enter an offset:", NULL, 0, NULL, PH_CHOICE_DIALOG_USER_CHOICE, &selectedChoice, NULL, L"MemEditGotoChoices" )) { ULONG64 offset; if (selectedChoice->Length == 0) continue; if (PhStringToInteger64(&selectedChoice->sr, 0, &offset)) { if (offset >= context->RegionSize) { PhShowError(hwndDlg, L"The offset is too large."); continue; } SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)context->HexEditHandle, TRUE); HexEdit_SetSel(context->HexEditHandle, (LONG)offset, (LONG)offset); break; } } } break; case IDC_WRITE: { NTSTATUS status; if (!context->WriteAccess) { HANDLE processHandle; if (!NT_SUCCESS(status = PhOpenProcess( &processHandle, PROCESS_VM_READ | PROCESS_VM_WRITE, context->ProcessId ))) { PhShowStatus(hwndDlg, L"Unable to open the process", status, 0); break; } if (context->ProcessHandle) NtClose(context->ProcessHandle); context->ProcessHandle = processHandle; context->WriteAccess = TRUE; } if (!NT_SUCCESS(status = PhWriteVirtualMemory( context->ProcessHandle, context->BaseAddress, context->Buffer, context->RegionSize, NULL ))) { PhShowStatus(hwndDlg, L"Unable to write memory", status, 0); } } break; case IDC_REREAD: { NTSTATUS status; if (!NT_SUCCESS(status = PhReadVirtualMemory( context->ProcessHandle, context->BaseAddress, context->Buffer, context->RegionSize, NULL ))) { PhShowStatus(hwndDlg, L"Unable to read memory", status, 0); } InvalidateRect(context->HexEditHandle, NULL, TRUE); } break; case IDC_BYTESPERROW: if (HIWORD(wParam) == CBN_SELCHANGE) { PPH_STRING bytesPerRowString = PhaGetDlgItemText(hwndDlg, IDC_BYTESPERROW); PH_STRINGREF firstPart; PH_STRINGREF secondPart; ULONG64 bytesPerRow64; if (PhSplitStringRefAtChar(&bytesPerRowString->sr, ' ', &firstPart, &secondPart)) { if (PhStringToInteger64(&firstPart, 10, &bytesPerRow64)) { PhSetIntegerSetting(L"MemEditBytesPerRow", (ULONG)bytesPerRow64); HexEdit_SetBytesPerRow(context->HexEditHandle, (ULONG)bytesPerRow64); SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)context->HexEditHandle, TRUE); } } } break; } } break; case WM_SIZE: { PhLayoutManagerLayout(&context->LayoutManager); } break; case WM_SIZING: { PhResizingMinimumSize((PRECT)lParam, wParam, MinimumSize.right, MinimumSize.bottom); } break; case WM_PH_SELECT_OFFSET: { HexEdit_SetEditMode(context->HexEditHandle, EDIT_ASCII); HexEdit_SetSel(context->HexEditHandle, (ULONG)wParam, (ULONG)wParam + (ULONG)lParam); } break; } return FALSE; }
INT_PTR CALLBACK PhpProcessRecordDlgProc( __in HWND hwndDlg, __in UINT uMsg, __in WPARAM wParam, __in LPARAM lParam ) { PPROCESS_RECORD_CONTEXT context = NULL; if (uMsg == WM_INITDIALOG) { context = (PPROCESS_RECORD_CONTEXT)lParam; SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)context); } else { context = (PPROCESS_RECORD_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom()); if (uMsg == WM_DESTROY) { RemoveProp(hwndDlg, PhMakeContextAtom()); } } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { PH_IMAGE_VERSION_INFO versionInfo; BOOLEAN versionInfoInitialized; PPH_STRING processNameString; PPH_PROCESS_ITEM processItem; if (!PH_IS_FAKE_PROCESS_ID(context->Record->ProcessId)) { processNameString = PhaFormatString(L"%s (%u)", context->Record->ProcessName->Buffer, (ULONG)context->Record->ProcessId); } else { processNameString = context->Record->ProcessName; } PhCenterWindow(hwndDlg, GetParent(hwndDlg)); SetWindowText(hwndDlg, processNameString->Buffer); SetDlgItemText(hwndDlg, IDC_PROCESSNAME, processNameString->Buffer); if (processItem = PhReferenceProcessItemForRecord(context->Record)) { PPH_PROCESS_ITEM parentProcess; if (parentProcess = PhReferenceProcessItemForParent( processItem->ParentProcessId, processItem->ProcessId, &processItem->CreateTime )) { CLIENT_ID clientId; clientId.UniqueProcess = parentProcess->ProcessId; clientId.UniqueThread = NULL; SetDlgItemText(hwndDlg, IDC_PARENT, ((PPH_STRING)PHA_DEREFERENCE(PhGetClientIdNameEx(&clientId, parentProcess->ProcessName)))->Buffer); PhDereferenceObject(parentProcess); } else { SetDlgItemText(hwndDlg, IDC_PARENT, PhaFormatString(L"Non-existent process (%u)", (ULONG)context->Record->ParentProcessId)->Buffer); } PhDereferenceObject(processItem); } else { SetDlgItemText(hwndDlg, IDC_PARENT, PhaFormatString(L"Unknown process (%u)", (ULONG)context->Record->ParentProcessId)->Buffer); EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTIES), FALSE); } memset(&versionInfo, 0, sizeof(PH_IMAGE_VERSION_INFO)); versionInfoInitialized = FALSE; if (context->Record->FileName) { if (PhInitializeImageVersionInfo(&versionInfo, context->Record->FileName->Buffer)) versionInfoInitialized = TRUE; } context->FileIcon = PhGetFileShellIcon(PhGetString(context->Record->FileName), L".exe", TRUE); SendMessage(GetDlgItem(hwndDlg, IDC_OPENFILENAME), BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)PH_LOAD_SHARED_IMAGE(MAKEINTRESOURCE(IDB_FOLDER), IMAGE_BITMAP)); SendMessage(GetDlgItem(hwndDlg, IDC_FILEICON), STM_SETICON, (WPARAM)context->FileIcon, 0); SetDlgItemText(hwndDlg, IDC_NAME, PhpGetStringOrNa(versionInfo.FileDescription)); SetDlgItemText(hwndDlg, IDC_COMPANYNAME, PhpGetStringOrNa(versionInfo.CompanyName)); SetDlgItemText(hwndDlg, IDC_VERSION, PhpGetStringOrNa(versionInfo.FileVersion)); SetDlgItemText(hwndDlg, IDC_FILENAME, PhpGetStringOrNa(context->Record->FileName)); if (versionInfoInitialized) PhDeleteImageVersionInfo(&versionInfo); if (!context->Record->FileName) EnableWindow(GetDlgItem(hwndDlg, IDC_OPENFILENAME), FALSE); SetDlgItemText(hwndDlg, IDC_CMDLINE, PhpGetStringOrNa(context->Record->CommandLine)); if (context->Record->CreateTime.QuadPart != 0) SetDlgItemText(hwndDlg, IDC_STARTED, PhapGetRelativeTimeString(&context->Record->CreateTime)->Buffer); else SetDlgItemText(hwndDlg, IDC_STARTED, L"N/A"); if (context->Record->ExitTime.QuadPart != 0) SetDlgItemText(hwndDlg, IDC_TERMINATED, PhapGetRelativeTimeString(&context->Record->ExitTime)->Buffer); else SetDlgItemText(hwndDlg, IDC_TERMINATED, L"N/A"); SetDlgItemInt(hwndDlg, IDC_SESSIONID, context->Record->SessionId, FALSE); } break; case WM_DESTROY: { if (context->FileIcon) DestroyIcon(context->FileIcon); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: { EndDialog(hwndDlg, IDOK); } break; case IDC_OPENFILENAME: { if (context->Record->FileName) PhShellExploreFile(hwndDlg, context->Record->FileName->Buffer); } break; case IDC_PROPERTIES: { PPH_PROCESS_ITEM processItem; if (processItem = PhReferenceProcessItemForRecord(context->Record)) { ProcessHacker_ShowProcessProperties(PhMainWndHandle, processItem); PhDereferenceObject(processItem); } else { PhShowError(hwndDlg, L"The process has already terminated; only the process record is available."); } } break; } } break; } return FALSE; }
static INT_PTR CALLBACK PhpFindObjectsDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { HWND lvHandle; PhCenterWindow(hwndDlg, GetParent(hwndDlg)); PhFindObjectsListViewHandle = lvHandle = GetDlgItem(hwndDlg, IDC_RESULTS); PhInitializeLayoutManager(&WindowLayoutManager, hwndDlg); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_FILTER), NULL, PH_ANCHOR_LEFT | PH_ANCHOR_TOP | PH_ANCHOR_RIGHT); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_REGEX), NULL, PH_ANCHOR_TOP | PH_ANCHOR_RIGHT); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_TOP | PH_ANCHOR_RIGHT); PhAddLayoutItem(&WindowLayoutManager, lvHandle, NULL, PH_ANCHOR_ALL); MinimumSize.left = 0; MinimumSize.top = 0; MinimumSize.right = 150; MinimumSize.bottom = 100; MapDialogRect(hwndDlg, &MinimumSize); PhRegisterDialog(hwndDlg); PhLoadWindowPlacementFromSetting(L"FindObjWindowPosition", L"FindObjWindowSize", hwndDlg); PhSetListViewStyle(lvHandle, TRUE, TRUE); PhSetControlTheme(lvHandle, L"explorer"); PhAddListViewColumn(lvHandle, 0, 0, 0, LVCFMT_LEFT, 100, L"Process"); PhAddListViewColumn(lvHandle, 1, 1, 1, LVCFMT_LEFT, 100, L"Type"); PhAddListViewColumn(lvHandle, 2, 2, 2, LVCFMT_LEFT, 200, L"Name"); PhAddListViewColumn(lvHandle, 3, 3, 3, LVCFMT_LEFT, 80, L"Handle"); PhSetExtendedListView(lvHandle); ExtendedListView_SetSortFast(lvHandle, TRUE); ExtendedListView_SetCompareFunction(lvHandle, 0, PhpObjectProcessCompareFunction); ExtendedListView_SetCompareFunction(lvHandle, 1, PhpObjectTypeCompareFunction); ExtendedListView_SetCompareFunction(lvHandle, 2, PhpObjectNameCompareFunction); ExtendedListView_SetCompareFunction(lvHandle, 3, PhpObjectHandleCompareFunction); PhLoadListViewColumnsFromSetting(L"FindObjListViewColumns", lvHandle); Button_SetCheck(GetDlgItem(hwndDlg, IDC_REGEX), PhGetIntegerSetting(L"FindObjRegex") ? BST_CHECKED : BST_UNCHECKED); } break; case WM_DESTROY: { PhSetIntegerSetting(L"FindObjRegex", Button_GetCheck(GetDlgItem(hwndDlg, IDC_REGEX)) == BST_CHECKED); PhSaveWindowPlacementToSetting(L"FindObjWindowPosition", L"FindObjWindowSize", hwndDlg); PhSaveListViewColumnsToSetting(L"FindObjListViewColumns", PhFindObjectsListViewHandle); } break; case WM_SHOWWINDOW: { SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDC_FILTER), TRUE); Edit_SetSel(GetDlgItem(hwndDlg, IDC_FILTER), 0, -1); } break; case WM_CLOSE: { ShowWindow(hwndDlg, SW_HIDE); // IMPORTANT // Set the result to 0 so the default dialog message // handler doesn't invoke IDCANCEL, which will send // WM_CLOSE, creating an infinite loop. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, 0); } return TRUE; case WM_SETCURSOR: { if (SearchThreadHandle) { SetCursor(LoadCursor(NULL, IDC_WAIT)); SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE); return TRUE; } } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDOK: { // Don't continue if the user requested cancellation. if (SearchStop) break; if (!SearchThreadHandle) { ULONG i; PhMoveReference(&SearchString, PhGetWindowText(GetDlgItem(hwndDlg, IDC_FILTER))); if (SearchRegexCompiledExpression) { pcre2_code_free(SearchRegexCompiledExpression); SearchRegexCompiledExpression = NULL; } if (SearchRegexMatchData) { pcre2_match_data_free(SearchRegexMatchData); SearchRegexMatchData = NULL; } if (Button_GetCheck(GetDlgItem(hwndDlg, IDC_REGEX)) == BST_CHECKED) { int errorCode; PCRE2_SIZE errorOffset; SearchRegexCompiledExpression = pcre2_compile( SearchString->Buffer, SearchString->Length / sizeof(WCHAR), PCRE2_CASELESS | PCRE2_DOTALL, &errorCode, &errorOffset, NULL ); if (!SearchRegexCompiledExpression) { PhShowError(hwndDlg, L"Unable to compile the regular expression: \"%s\" at position %zu.", PhGetStringOrDefault(PH_AUTO(PhPcre2GetErrorMessage(errorCode)), L"Unknown error"), errorOffset ); break; } SearchRegexMatchData = pcre2_match_data_create_from_pattern(SearchRegexCompiledExpression, NULL); } // Clean up previous results. ListView_DeleteAllItems(PhFindObjectsListViewHandle); if (SearchResults) { for (i = 0; i < SearchResults->Count; i++) { PPHP_OBJECT_SEARCH_RESULT searchResult = SearchResults->Items[i]; PhDereferenceObject(searchResult->TypeName); PhDereferenceObject(searchResult->Name); if (searchResult->ProcessName) PhDereferenceObject(searchResult->ProcessName); PhFree(searchResult); } PhDereferenceObject(SearchResults); } // Start the search. SearchResults = PhCreateList(128); SearchResultsAddIndex = 0; SearchThreadHandle = PhCreateThread(0, PhpFindObjectsThreadStart, NULL); if (!SearchThreadHandle) { PhClearReference(&SearchResults); break; } SetDlgItemText(hwndDlg, IDOK, L"Cancel"); SetCursor(LoadCursor(NULL, IDC_WAIT)); } else { SearchStop = TRUE; EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE); } } break; case IDCANCEL: { SendMessage(hwndDlg, WM_CLOSE, 0, 0); } break; case ID_OBJECT_CLOSE: { PPHP_OBJECT_SEARCH_RESULT *results; ULONG numberOfResults; ULONG i; PhGetSelectedListViewItemParams( PhFindObjectsListViewHandle, &results, &numberOfResults ); if (numberOfResults != 0 && PhShowConfirmMessage( hwndDlg, L"close", numberOfResults == 1 ? L"the selected handle" : L"the selected handles", L"Closing handles may cause system instability and data corruption.", FALSE )) { for (i = 0; i < numberOfResults; i++) { NTSTATUS status; HANDLE processHandle; if (results[i]->ResultType != HandleSearchResult) continue; if (NT_SUCCESS(status = PhOpenProcess( &processHandle, PROCESS_DUP_HANDLE, results[i]->ProcessId ))) { if (NT_SUCCESS(status = PhDuplicateObject( processHandle, results[i]->Handle, NULL, NULL, 0, 0, DUPLICATE_CLOSE_SOURCE ))) { PhRemoveListViewItem(PhFindObjectsListViewHandle, PhFindListViewItemByParam(PhFindObjectsListViewHandle, 0, results[i])); } NtClose(processHandle); } if (!NT_SUCCESS(status)) { if (!PhShowContinueStatus(hwndDlg, PhaFormatString(L"Unable to close \"%s\"", results[i]->Name->Buffer)->Buffer, status, 0 )) break; } } } PhFree(results); } break; case ID_HANDLE_OBJECTPROPERTIES1: case ID_HANDLE_OBJECTPROPERTIES2: { PPHP_OBJECT_SEARCH_RESULT result = PhGetSelectedListViewItemParam(PhFindObjectsListViewHandle); if (result) { PH_HANDLE_ITEM_INFO info; info.ProcessId = result->ProcessId; info.Handle = result->Handle; info.TypeName = result->TypeName; info.BestObjectName = result->Name; if (LOWORD(wParam) == ID_HANDLE_OBJECTPROPERTIES1) PhShowHandleObjectProperties1(hwndDlg, &info); else PhShowHandleObjectProperties2(hwndDlg, &info); } } break; case ID_OBJECT_GOTOOWNINGPROCESS: { PPHP_OBJECT_SEARCH_RESULT result = PhGetSelectedListViewItemParam(PhFindObjectsListViewHandle); if (result) { PPH_PROCESS_NODE processNode; if (processNode = PhFindProcessNode(result->ProcessId)) { ProcessHacker_SelectTabPage(PhMainWndHandle, 0); ProcessHacker_SelectProcessNode(PhMainWndHandle, processNode); ProcessHacker_ToggleVisible(PhMainWndHandle, TRUE); } } } break; case ID_OBJECT_PROPERTIES: { PPHP_OBJECT_SEARCH_RESULT result = PhGetSelectedListViewItemParam(PhFindObjectsListViewHandle); if (result) { if (result->ResultType == HandleSearchResult) { PPH_HANDLE_ITEM handleItem; handleItem = PhCreateHandleItem(&result->Info); handleItem->BestObjectName = handleItem->ObjectName = result->Name; PhReferenceObjectEx(result->Name, 2); handleItem->TypeName = result->TypeName; PhReferenceObject(result->TypeName); PhShowHandleProperties( hwndDlg, result->ProcessId, handleItem ); PhDereferenceObject(handleItem); } else { // DLL or Mapped File. Just show file properties. PhShellProperties(hwndDlg, result->Name->Buffer); } } } break; case ID_OBJECT_COPY: { PhCopyListView(PhFindObjectsListViewHandle); } break; } } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case NM_DBLCLK: { if (header->hwndFrom == PhFindObjectsListViewHandle) { SendMessage(hwndDlg, WM_COMMAND, ID_OBJECT_PROPERTIES, 0); } } break; case LVN_KEYDOWN: { if (header->hwndFrom == PhFindObjectsListViewHandle) { LPNMLVKEYDOWN keyDown = (LPNMLVKEYDOWN)header; switch (keyDown->wVKey) { case 'C': if (GetKeyState(VK_CONTROL) < 0) SendMessage(hwndDlg, WM_COMMAND, ID_OBJECT_COPY, 0); break; case 'A': if (GetKeyState(VK_CONTROL) < 0) PhSetStateAllListViewItems(PhFindObjectsListViewHandle, LVIS_SELECTED, LVIS_SELECTED); break; case VK_DELETE: SendMessage(hwndDlg, WM_COMMAND, ID_OBJECT_CLOSE, 0); break; } } } break; } } break; case WM_CONTEXTMENU: { if ((HWND)wParam == PhFindObjectsListViewHandle) { POINT point; PPHP_OBJECT_SEARCH_RESULT *results; ULONG numberOfResults; point.x = (SHORT)LOWORD(lParam); point.y = (SHORT)HIWORD(lParam); if (point.x == -1 && point.y == -1) PhGetListViewContextMenuPoint((HWND)wParam, &point); PhGetSelectedListViewItemParams(PhFindObjectsListViewHandle, &results, &numberOfResults); if (numberOfResults != 0) { PPH_EMENU menu; menu = PhCreateEMenu(); PhLoadResourceEMenuItem(menu, PhInstanceHandle, MAKEINTRESOURCE(IDR_FINDOBJ), 0); PhSetFlagsEMenuItem(menu, ID_OBJECT_PROPERTIES, PH_EMENU_DEFAULT, PH_EMENU_DEFAULT); PhpInitializeFindObjMenu(menu, results, numberOfResults); PhShowEMenu( menu, hwndDlg, PH_EMENU_SHOW_SEND_COMMAND | PH_EMENU_SHOW_LEFTRIGHT, PH_ALIGN_LEFT | PH_ALIGN_TOP, point.x, point.y ); PhDestroyEMenu(menu); } PhFree(results); } } break; case WM_SIZE: { PhLayoutManagerLayout(&WindowLayoutManager); } break; case WM_SIZING: { PhResizingMinimumSize((PRECT)lParam, wParam, MinimumSize.right, MinimumSize.bottom); } break; case WM_PH_SEARCH_UPDATE: { HWND lvHandle; ULONG i; lvHandle = GetDlgItem(hwndDlg, IDC_RESULTS); ExtendedListView_SetRedraw(lvHandle, FALSE); PhAcquireQueuedLockExclusive(&SearchResultsLock); for (i = SearchResultsAddIndex; i < SearchResults->Count; i++) { PPHP_OBJECT_SEARCH_RESULT searchResult = SearchResults->Items[i]; CLIENT_ID clientId; PPH_PROCESS_ITEM processItem; PPH_STRING clientIdName; INT lvItemIndex; clientId.UniqueProcess = searchResult->ProcessId; clientId.UniqueThread = NULL; processItem = PhReferenceProcessItem(clientId.UniqueProcess); clientIdName = PhGetClientIdNameEx(&clientId, processItem ? processItem->ProcessName : NULL); lvItemIndex = PhAddListViewItem( lvHandle, MAXINT, clientIdName->Buffer, searchResult ); PhDereferenceObject(clientIdName); if (processItem) { PhSetReference(&searchResult->ProcessName, processItem->ProcessName); PhDereferenceObject(processItem); } else { searchResult->ProcessName = NULL; } PhSetListViewSubItem(lvHandle, lvItemIndex, 1, searchResult->TypeName->Buffer); PhSetListViewSubItem(lvHandle, lvItemIndex, 2, searchResult->Name->Buffer); PhSetListViewSubItem(lvHandle, lvItemIndex, 3, searchResult->HandleString); } SearchResultsAddIndex = i; PhReleaseQueuedLockExclusive(&SearchResultsLock); ExtendedListView_SetRedraw(lvHandle, TRUE); } break; case WM_PH_SEARCH_FINISHED: { NTSTATUS handleSearchStatus = (NTSTATUS)wParam; // Add any un-added items. SendMessage(hwndDlg, WM_PH_SEARCH_UPDATE, 0, 0); NtWaitForSingleObject(SearchThreadHandle, FALSE, NULL); NtClose(SearchThreadHandle); SearchThreadHandle = NULL; SearchStop = FALSE; ExtendedListView_SortItems(GetDlgItem(hwndDlg, IDC_RESULTS)); SetDlgItemText(hwndDlg, IDOK, L"Find"); EnableWindow(GetDlgItem(hwndDlg, IDOK), TRUE); SetCursor(LoadCursor(NULL, IDC_ARROW)); if (handleSearchStatus == STATUS_INSUFFICIENT_RESOURCES) { PhShowWarning( hwndDlg, L"Unable to search for handles because the total number of handles on the system is too large. " L"Please check if there are any processes with an extremely large number of handles open." ); } } break; } return FALSE; }
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; }
static INT_PTR CALLBACK OptionsDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PPH_PERFMON_CONTEXT context = NULL; if (uMsg == WM_INITDIALOG) { context = (PPH_PERFMON_CONTEXT)PhAllocate(sizeof(PH_PERFMON_CONTEXT)); memset(context, 0, sizeof(PH_PERFMON_CONTEXT)); SetProp(hwndDlg, L"Context", (HANDLE)context); } else { context = (PPH_PERFMON_CONTEXT)GetProp(hwndDlg, L"Context"); if (uMsg == WM_NCDESTROY) { PPH_STRING string; ClearCounterList(CountersList); CopyCounterList(CountersList, context->CountersListEdited); PhDereferenceObject(context->CountersListEdited); string = SaveCounterList(CountersList); PhSetStringSetting2(SETTING_NAME_PERFMON_LIST, &string->sr); PhDereferenceObject(string); RemoveProp(hwndDlg, L"Context"); PhFree(context); } } if (context == NULL) return FALSE; switch (uMsg) { case WM_INITDIALOG: { context->CountersListEdited = PhCreateList(2); context->ListViewHandle = GetDlgItem(hwndDlg, IDC_PERFCOUNTER_LISTVIEW); PhSetListViewStyle(context->ListViewHandle, FALSE, TRUE); PhSetControlTheme(context->ListViewHandle, L"explorer"); PhAddListViewColumn(context->ListViewHandle, 0, 0, 0, LVCFMT_LEFT, 420, L"Counter"); PhSetExtendedListView(context->ListViewHandle); ClearCounterList(context->CountersListEdited); CopyCounterList(context->CountersListEdited, CountersList); LoadCountersToListView(context, context->CountersListEdited); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_ADD_BUTTON: { PDH_STATUS counterStatus = 0; PPH_STRING counterPathString = NULL; PPH_STRING counterWildCardString = NULL; PDH_BROWSE_DLG_CONFIG browseConfig = { 0 }; WCHAR counterPathBuffer[PDH_MAX_COUNTER_PATH] = L""; browseConfig.bIncludeInstanceIndex = FALSE; browseConfig.bSingleCounterPerAdd = FALSE;// Fix empty CounterPathBuffer browseConfig.bSingleCounterPerDialog = TRUE; browseConfig.bLocalCountersOnly = FALSE; browseConfig.bWildCardInstances = TRUE; // Seems to cause a lot of crashes browseConfig.bHideDetailBox = TRUE; browseConfig.bInitializePath = FALSE; browseConfig.bDisableMachineSelection = FALSE; browseConfig.bIncludeCostlyObjects = FALSE; browseConfig.bShowObjectBrowser = FALSE; browseConfig.hWndOwner = hwndDlg; browseConfig.szReturnPathBuffer = counterPathBuffer; browseConfig.cchReturnPathLength = PDH_MAX_COUNTER_PATH; browseConfig.CallBackStatus = ERROR_SUCCESS; browseConfig.dwDefaultDetailLevel = PERF_DETAIL_WIZARD; browseConfig.szDialogBoxCaption = L"Select a counter to monitor."; __try { // Display the counter browser window. if ((counterStatus = PdhBrowseCounters(&browseConfig)) != ERROR_SUCCESS) { if (counterStatus != PDH_DIALOG_CANCELLED) { PhShowError(hwndDlg, L"PdhBrowseCounters failed with status 0x%x.", counterStatus); } __leave; } else if (wcslen(counterPathBuffer) == 0) { // This gets called when pressing the X on the BrowseCounters dialog. __leave; } counterPathString = PhCreateString(counterPathBuffer); // Check if we need to expand any wildcards... if (PhFindCharInString(counterPathString, 0, '*') != -1) { ULONG counterWildCardLength = 0; // Query WildCard buffer length... PdhExpandWildCardPath( NULL, counterPathString->Buffer, NULL, &counterWildCardLength, 0 ); counterWildCardString = PhCreateStringEx(NULL, counterWildCardLength * sizeof(WCHAR)); if ((counterStatus = PdhExpandWildCardPath( NULL, counterPathString->Buffer, counterWildCardString->Buffer, &counterWildCardLength, 0 )) == ERROR_SUCCESS) { PH_STRINGREF part; PH_STRINGREF remaining = counterWildCardString->sr; while (remaining.Length != 0) { // Split the results if (!PhSplitStringRefAtChar(&remaining, '\0', &part, &remaining)) break; if (remaining.Length == 0) break; if ((counterStatus = PdhValidatePath(part.Buffer)) != ERROR_SUCCESS) { PhShowError(hwndDlg, L"PdhValidatePath failed with status 0x%x.", counterStatus); __leave; } AddCounterToListView(context, part.Buffer); } } else { PhShowError(hwndDlg, L"PdhExpandWildCardPath failed with status 0x%x.", counterStatus); } } else { if ((counterStatus = PdhValidatePath(counterPathString->Buffer)) != ERROR_SUCCESS) { PhShowError(hwndDlg, L"PdhValidatePath failed with status 0x%x.", counterStatus); __leave; } AddCounterToListView(context, counterPathString->Buffer); } } __finally { if (counterWildCardString) PhDereferenceObject(counterWildCardString); if (counterPathString) PhDereferenceObject(counterPathString); } } break; case IDC_REMOVE_BUTTON: { INT itemIndex; // Get the first selected item itemIndex = ListView_GetNextItem(context->ListViewHandle, -1, LVNI_SELECTED); while (itemIndex != -1) { PPH_PERFMON_ENTRY entry; if (PhGetListViewItemParam(context->ListViewHandle, itemIndex, (PPVOID)&entry)) { ULONG index = PhFindItemList(context->CountersListEdited, entry); if (index != -1) { PhRemoveItemList(context->CountersListEdited, index); PhRemoveListViewItem(context->ListViewHandle, itemIndex); FreeCounterEntry(entry); } } // Get the next selected item itemIndex = ListView_GetNextItem(context->ListViewHandle, -1, LVNI_SELECTED); } } break; case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); break; case IDOK: EndDialog(hwndDlg, IDOK); break; } } break; } return FALSE; }
INT_PTR CALLBACK WepWindowsPageProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PWINDOWS_CONTEXT context; LPPROPSHEETPAGE propSheetPage; PPH_PROCESS_PROPPAGECONTEXT propPageContext; PPH_PROCESS_ITEM processItem; if (PhPropPageDlgProcHeader(hwndDlg, uMsg, lParam, &propSheetPage, &propPageContext, &processItem)) { context = propPageContext->Context; } else { return FALSE; } switch (uMsg) { case WM_INITDIALOG: { context->TreeNewHandle = GetDlgItem(hwndDlg, IDC_LIST); context->SearchBoxHandle = GetDlgItem(hwndDlg, IDC_SEARCHEDIT); PhCreateSearchControl(hwndDlg, context->SearchBoxHandle, L"Search Windows (Ctrl+K)"); WeInitializeWindowTree(hwndDlg, context->TreeNewHandle, &context->TreeContext); PhRegisterDialog(hwndDlg); PhInitializeLayoutManager(&context->LayoutManager, hwndDlg); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_SEARCHEDIT), NULL, PH_ANCHOR_TOP | PH_ANCHOR_RIGHT); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_LIST), NULL, PH_ANCHOR_ALL); WepRefreshWindows(context); } break; case WM_SHOWWINDOW: { if (PhBeginPropPageLayout(hwndDlg, propPageContext)) PhEndPropPageLayout(hwndDlg, propPageContext); } break; case WM_DESTROY: { PhDeleteLayoutManager(&context->LayoutManager); PhUnregisterDialog(hwndDlg); WeDeleteWindowTree(&context->TreeContext); WepDeleteWindowSelector(&context->Selector); PhFree(context); } break; case WM_COMMAND: { switch (GET_WM_COMMAND_CMD(wParam, lParam)) { case EN_CHANGE: { PPH_STRING newSearchboxText; if (GET_WM_COMMAND_HWND(wParam, lParam) != context->SearchBoxHandle) break; newSearchboxText = PH_AUTO(PhGetWindowText(context->SearchBoxHandle)); if (!PhEqualString(context->TreeContext.SearchboxText, newSearchboxText, FALSE)) { PhSwapReference(&context->TreeContext.SearchboxText, newSearchboxText); if (!PhIsNullOrEmptyString(context->TreeContext.SearchboxText)) WeExpandAllWindowNodes(&context->TreeContext, TRUE); PhApplyTreeNewFilters(&context->TreeContext.FilterSupport); TreeNew_NodesStructured(context->TreeNewHandle); // PhInvokeCallback(&SearchChangedEvent, SearchboxText); } } break; } switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDC_REFRESH: WepRefreshWindows(context); break; case ID_SHOWCONTEXTMENU: { PPH_TREENEW_CONTEXT_MENU contextMenuEvent = (PPH_TREENEW_CONTEXT_MENU)lParam; PWE_WINDOW_NODE *windows; ULONG numberOfWindows; PPH_EMENU menu; PPH_EMENU selectedItem; WeGetSelectedWindowNodes( &context->TreeContext, &windows, &numberOfWindows ); if (numberOfWindows != 0) { menu = PhCreateEMenu(); PhLoadResourceEMenuItem(menu, PluginInstance->DllBase, MAKEINTRESOURCE(IDR_WINDOW), 0); PhInsertCopyCellEMenuItem(menu, ID_WINDOW_COPY, context->TreeNewHandle, contextMenuEvent->Column); PhSetFlagsEMenuItem(menu, ID_WINDOW_PROPERTIES, PH_EMENU_DEFAULT, PH_EMENU_DEFAULT); if (numberOfWindows == 1) { WINDOWPLACEMENT placement = { sizeof(placement) }; BYTE alpha; ULONG flags; ULONG i; ULONG id; // State GetWindowPlacement(windows[0]->WindowHandle, &placement); if (placement.showCmd == SW_MINIMIZE) PhSetFlagsEMenuItem(menu, ID_WINDOW_MINIMIZE, PH_EMENU_DISABLED, PH_EMENU_DISABLED); else if (placement.showCmd == SW_MAXIMIZE) PhSetFlagsEMenuItem(menu, ID_WINDOW_MAXIMIZE, PH_EMENU_DISABLED, PH_EMENU_DISABLED); else if (placement.showCmd == SW_NORMAL) PhSetFlagsEMenuItem(menu, ID_WINDOW_RESTORE, PH_EMENU_DISABLED, PH_EMENU_DISABLED); // Visible PhSetFlagsEMenuItem(menu, ID_WINDOW_VISIBLE, PH_EMENU_CHECKED, (GetWindowLong(windows[0]->WindowHandle, GWL_STYLE) & WS_VISIBLE) ? PH_EMENU_CHECKED : 0); // Enabled PhSetFlagsEMenuItem(menu, ID_WINDOW_ENABLED, PH_EMENU_CHECKED, !(GetWindowLong(windows[0]->WindowHandle, GWL_STYLE) & WS_DISABLED) ? PH_EMENU_CHECKED : 0); // Always on Top PhSetFlagsEMenuItem(menu, ID_WINDOW_ALWAYSONTOP, PH_EMENU_CHECKED, (GetWindowLong(windows[0]->WindowHandle, GWL_EXSTYLE) & WS_EX_TOPMOST) ? PH_EMENU_CHECKED : 0); // Opacity if (GetLayeredWindowAttributes(windows[0]->WindowHandle, NULL, &alpha, &flags)) { if (!(flags & LWA_ALPHA)) alpha = 255; } else { alpha = 255; } if (alpha == 255) { id = ID_OPACITY_OPAQUE; } else { id = 0; // Due to integer division, we cannot use simple arithmetic to calculate which menu item to check. for (i = 0; i < 10; i++) { if (alpha == (BYTE)(255 * (i + 1) / 10)) { id = ID_OPACITY_10 + i; break; } } } if (id != 0) { PhSetFlagsEMenuItem(menu, id, PH_EMENU_CHECKED | PH_EMENU_RADIOCHECK, PH_EMENU_CHECKED | PH_EMENU_RADIOCHECK); } } else { PhSetFlagsAllEMenuItems(menu, PH_EMENU_DISABLED, PH_EMENU_DISABLED); PhSetFlagsEMenuItem(menu, ID_WINDOW_COPY, PH_EMENU_DISABLED, 0); } selectedItem = PhShowEMenu( menu, hwndDlg, PH_EMENU_SHOW_SEND_COMMAND | PH_EMENU_SHOW_LEFTRIGHT, PH_ALIGN_LEFT | PH_ALIGN_TOP, contextMenuEvent->Location.x, contextMenuEvent->Location.y ); if (selectedItem && selectedItem->Id != -1) { BOOLEAN handled = FALSE; handled = PhHandleCopyCellEMenuItem(selectedItem); } PhDestroyEMenu(menu); } } break; case ID_WINDOW_BRINGTOFRONT: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { WINDOWPLACEMENT placement = { sizeof(placement) }; GetWindowPlacement(selectedNode->WindowHandle, &placement); if (placement.showCmd == SW_MINIMIZE) ShowWindowAsync(selectedNode->WindowHandle, SW_RESTORE); else SetForegroundWindow(selectedNode->WindowHandle); } } break; case ID_WINDOW_RESTORE: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { ShowWindowAsync(selectedNode->WindowHandle, SW_RESTORE); } } break; case ID_WINDOW_MINIMIZE: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { ShowWindowAsync(selectedNode->WindowHandle, SW_MINIMIZE); } } break; case ID_WINDOW_MAXIMIZE: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { ShowWindowAsync(selectedNode->WindowHandle, SW_MAXIMIZE); } } break; case ID_WINDOW_CLOSE: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { PostMessage(selectedNode->WindowHandle, WM_CLOSE, 0, 0); } } break; case ID_WINDOW_VISIBLE: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { if (IsWindowVisible(selectedNode->WindowHandle)) { selectedNode->WindowVisible = FALSE; ShowWindowAsync(selectedNode->WindowHandle, SW_HIDE); } else { selectedNode->WindowVisible = TRUE; ShowWindowAsync(selectedNode->WindowHandle, SW_SHOW); } PhInvalidateTreeNewNode(&selectedNode->Node, TN_CACHE_COLOR); TreeNew_InvalidateNode(context->TreeNewHandle, &selectedNode->Node); } } break; case ID_WINDOW_ENABLED: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { EnableWindow(selectedNode->WindowHandle, !IsWindowEnabled(selectedNode->WindowHandle)); } } break; case ID_WINDOW_ALWAYSONTOP: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { LOGICAL topMost; topMost = GetWindowLong(selectedNode->WindowHandle, GWL_EXSTYLE) & WS_EX_TOPMOST; SetWindowPos(selectedNode->WindowHandle, topMost ? HWND_NOTOPMOST : HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); } } break; case ID_OPACITY_10: case ID_OPACITY_20: case ID_OPACITY_30: case ID_OPACITY_40: case ID_OPACITY_50: case ID_OPACITY_60: case ID_OPACITY_70: case ID_OPACITY_80: case ID_OPACITY_90: case ID_OPACITY_OPAQUE: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { ULONG opacity; opacity = ((ULONG)LOWORD(wParam) - ID_OPACITY_10) + 1; if (opacity == 10) { // Remove the WS_EX_LAYERED bit since it is not needed. PhSetWindowExStyle(selectedNode->WindowHandle, WS_EX_LAYERED, 0); RedrawWindow(selectedNode->WindowHandle, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); } else { // Add the WS_EX_LAYERED bit so opacity will work. PhSetWindowExStyle(selectedNode->WindowHandle, WS_EX_LAYERED, WS_EX_LAYERED); SetLayeredWindowAttributes(selectedNode->WindowHandle, 0, (BYTE)(255 * opacity / 10), LWA_ALPHA); } } } break; case ID_WINDOW_HIGHLIGHT: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { if (context->HighlightingWindow) { if (context->HighlightingWindowCount & 1) WeInvertWindowBorder(context->HighlightingWindow); } context->HighlightingWindow = selectedNode->WindowHandle; context->HighlightingWindowCount = 10; SetTimer(hwndDlg, 9, 100, NULL); } } break; case ID_WINDOW_GOTOTHREAD: { PWE_WINDOW_NODE selectedNode; PPH_PROCESS_ITEM processItem; PPH_PROCESS_PROPCONTEXT propContext; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { if (processItem = PhReferenceProcessItem(selectedNode->ClientId.UniqueProcess)) { if (propContext = PhCreateProcessPropContext(WE_PhMainWndHandle, processItem)) { PhSetSelectThreadIdProcessPropContext(propContext, selectedNode->ClientId.UniqueThread); PhShowProcessProperties(propContext); PhDereferenceObject(propContext); } PhDereferenceObject(processItem); } else { PhShowError(hwndDlg, L"The process does not exist."); } } } break; case ID_WINDOW_PROPERTIES: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) WeShowWindowProperties(hwndDlg, selectedNode->WindowHandle); } break; case ID_WINDOW_COPY: { PPH_STRING text; text = PhGetTreeNewText(context->TreeNewHandle, 0); PhSetClipboardString(hwndDlg, &text->sr); PhDereferenceObject(text); } break; } } break; case WM_TIMER: { switch (wParam) { case 9: { WeInvertWindowBorder(context->HighlightingWindow); if (--context->HighlightingWindowCount == 0) KillTimer(hwndDlg, 9); } break; } } break; case WM_SIZE: PhLayoutManagerLayout(&context->LayoutManager); break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case PSN_QUERYINITIALFOCUS: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LPARAM)GetDlgItem(hwndDlg, IDC_REFRESH)); return TRUE; } } break; } return FALSE; }