VOID PhpInitializeMemoryMenu( _In_ PPH_EMENU Menu, _In_ HANDLE ProcessId, _In_ PPH_MEMORY_NODE *MemoryNodes, _In_ ULONG NumberOfMemoryNodes ) { if (NumberOfMemoryNodes == 0) { PhSetFlagsAllEMenuItems(Menu, PH_EMENU_DISABLED, PH_EMENU_DISABLED); } else if (NumberOfMemoryNodes == 1 && !MemoryNodes[0]->IsAllocationBase) { if (MemoryNodes[0]->MemoryItem->State & MEM_FREE) { PhEnableEMenuItem(Menu, ID_MEMORY_CHANGEPROTECTION, FALSE); PhEnableEMenuItem(Menu, ID_MEMORY_FREE, FALSE); PhEnableEMenuItem(Menu, ID_MEMORY_DECOMMIT, FALSE); } else if (MemoryNodes[0]->MemoryItem->Type & (MEM_MAPPED | MEM_IMAGE)) { PhEnableEMenuItem(Menu, ID_MEMORY_DECOMMIT, FALSE); } } else { ULONG i; ULONG numberOfAllocationBase = 0; PhSetFlagsAllEMenuItems(Menu, PH_EMENU_DISABLED, PH_EMENU_DISABLED); PhEnableEMenuItem(Menu, ID_MEMORY_COPY, TRUE); for (i = 0; i < NumberOfMemoryNodes; i++) { if (MemoryNodes[i]->IsAllocationBase) numberOfAllocationBase++; } if (numberOfAllocationBase == 0 || numberOfAllocationBase == NumberOfMemoryNodes) PhEnableEMenuItem(Menu, ID_MEMORY_SAVE, TRUE); } PhEnableEMenuItem(Menu, ID_MEMORY_READWRITEADDRESS, TRUE); }
VOID PhpInitializeFindObjMenu( _In_ PPH_EMENU Menu, _In_ PPHP_OBJECT_SEARCH_RESULT *Results, _In_ ULONG NumberOfResults ) { BOOLEAN allCanBeClosed = TRUE; ULONG i; if (NumberOfResults == 1) { PH_HANDLE_ITEM_INFO info; info.ProcessId = Results[0]->ProcessId; info.Handle = Results[0]->Handle; info.TypeName = Results[0]->TypeName; info.BestObjectName = Results[0]->Name; PhInsertHandleObjectPropertiesEMenuItems(Menu, ID_OBJECT_PROPERTIES, FALSE, &info); } else { PhSetFlagsAllEMenuItems(Menu, PH_EMENU_DISABLED, PH_EMENU_DISABLED); PhEnableEMenuItem(Menu, ID_OBJECT_COPY, TRUE); } for (i = 0; i < NumberOfResults; i++) { if (Results[i]->ResultType != HandleSearchResult) { allCanBeClosed = FALSE; break; } } PhEnableEMenuItem(Menu, ID_OBJECT_CLOSE, allCanBeClosed); }
VOID PhpInitializeThreadMenu( _In_ PPH_EMENU Menu, _In_ HANDLE ProcessId, _In_ PPH_THREAD_ITEM *Threads, _In_ ULONG NumberOfThreads ) { PPH_EMENU_ITEM item; if (NumberOfThreads == 0) { PhSetFlagsAllEMenuItems(Menu, PH_EMENU_DISABLED, PH_EMENU_DISABLED); } else if (NumberOfThreads == 1) { // All menu items are enabled by default. } else { ULONG menuItemsMultiEnabled[] = { ID_THREAD_TERMINATE, ID_THREAD_SUSPEND, ID_THREAD_RESUME, ID_THREAD_COPY }; ULONG i; PhSetFlagsAllEMenuItems(Menu, PH_EMENU_DISABLED, PH_EMENU_DISABLED); // These menu items are capable of manipulating // multiple threads. for (i = 0; i < sizeof(menuItemsMultiEnabled) / sizeof(ULONG); i++) { PhEnableEMenuItem(Menu, menuItemsMultiEnabled[i], TRUE); } } // Remove irrelevant menu items. if (WindowsVersion < WINDOWS_VISTA) { // Remove I/O priority. if (item = PhFindEMenuItem(Menu, 0, L"I/O Priority", 0)) PhDestroyEMenuItem(item); // Remove page priority. if (item = PhFindEMenuItem(Menu, 0, L"Page Priority", 0)) PhDestroyEMenuItem(item); } PhEnableEMenuItem(Menu, ID_THREAD_TOKEN, FALSE); // Priority if (NumberOfThreads == 1) { HANDLE threadHandle; ULONG threadPriority = THREAD_PRIORITY_ERROR_RETURN; IO_PRIORITY_HINT ioPriority = -1; ULONG pagePriority = -1; ULONG id = 0; if (NT_SUCCESS(PhOpenThread( &threadHandle, ThreadQueryAccess, Threads[0]->ThreadId ))) { THREAD_BASIC_INFORMATION basicInfo; if (NT_SUCCESS(PhGetThreadBasicInformation(threadHandle, &basicInfo))) { threadPriority = basicInfo.BasePriority; } if (WindowsVersion >= WINDOWS_VISTA) { PhGetThreadIoPriority(threadHandle, &ioPriority); PhGetThreadPagePriority(threadHandle, &pagePriority); } // Token { HANDLE tokenHandle; if (NT_SUCCESS(NtOpenThreadToken( threadHandle, TOKEN_QUERY, TRUE, &tokenHandle ))) { PhEnableEMenuItem(Menu, ID_THREAD_TOKEN, TRUE); NtClose(tokenHandle); } } NtClose(threadHandle); } switch (threadPriority) { case THREAD_PRIORITY_TIME_CRITICAL + 1: case THREAD_PRIORITY_TIME_CRITICAL: id = ID_PRIORITY_TIMECRITICAL; break; case THREAD_PRIORITY_HIGHEST: id = ID_PRIORITY_HIGHEST; break; case THREAD_PRIORITY_ABOVE_NORMAL: id = ID_PRIORITY_ABOVENORMAL; break; case THREAD_PRIORITY_NORMAL: id = ID_PRIORITY_NORMAL; break; case THREAD_PRIORITY_BELOW_NORMAL: id = ID_PRIORITY_BELOWNORMAL; break; case THREAD_PRIORITY_LOWEST: id = ID_PRIORITY_LOWEST; break; case THREAD_PRIORITY_IDLE: case THREAD_PRIORITY_IDLE - 1: id = ID_PRIORITY_IDLE; break; } if (id != 0) { PhSetFlagsEMenuItem(Menu, id, PH_EMENU_CHECKED | PH_EMENU_RADIOCHECK, PH_EMENU_CHECKED | PH_EMENU_RADIOCHECK); } if (ioPriority != -1) { id = 0; switch (ioPriority) { case IoPriorityVeryLow: id = ID_IOPRIORITY_VERYLOW; break; case IoPriorityLow: id = ID_IOPRIORITY_LOW; break; case IoPriorityNormal: id = ID_IOPRIORITY_NORMAL; break; case IoPriorityHigh: id = ID_IOPRIORITY_HIGH; break; } if (id != 0) { PhSetFlagsEMenuItem(Menu, id, PH_EMENU_CHECKED | PH_EMENU_RADIOCHECK, PH_EMENU_CHECKED | PH_EMENU_RADIOCHECK); } } if (pagePriority != -1) { id = 0; switch (pagePriority) { case MEMORY_PRIORITY_VERY_LOW: id = ID_PAGEPRIORITY_VERYLOW; break; case MEMORY_PRIORITY_LOW: id = ID_PAGEPRIORITY_LOW; break; case MEMORY_PRIORITY_MEDIUM: id = ID_PAGEPRIORITY_MEDIUM; break; case MEMORY_PRIORITY_BELOW_NORMAL: id = ID_PAGEPRIORITY_BELOWNORMAL; break; case MEMORY_PRIORITY_NORMAL: id = ID_PAGEPRIORITY_NORMAL; break; } if (id != 0) { PhSetFlagsEMenuItem(Menu, id, PH_EMENU_CHECKED | PH_EMENU_RADIOCHECK, PH_EMENU_CHECKED | PH_EMENU_RADIOCHECK); } } } }
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; }