VOID NTAPI MenuItemCallback( __in_opt PVOID Parameter, __in_opt PVOID Context ) { PPH_PLUGIN_MENU_ITEM menuItem = Parameter; switch (menuItem->Id) { case 1: { if (PhShowConfirmMessage( PhMainWndHandle, L"terminate", L"all sandboxed processes", NULL, FALSE )) { PBOXED_PROCESS boxedProcess; ULONG enumerationKey = 0; // Make sure we have an update-to-date list. RefreshSandboxieInfo(NULL, FALSE); PhAcquireQueuedLockShared(&BoxedProcessesLock); while (PhEnumHashtable(BoxedProcessesHashtable, &boxedProcess, &enumerationKey)) { HANDLE processHandle; if (NT_SUCCESS(PhOpenProcess(&processHandle, PROCESS_TERMINATE, boxedProcess->ProcessId))) { PhTerminateProcess(processHandle, STATUS_SUCCESS); NtClose(processHandle); } } PhReleaseQueuedLockShared(&BoxedProcessesLock); } } break; } }
BOOLEAN EtUiCancelIoThread( __in HWND hWnd, __in PPH_THREAD_ITEM Thread ) { NTSTATUS status; BOOLEAN cont = FALSE; HANDLE threadHandle; IO_STATUS_BLOCK isb; if (!PhGetIntegerSetting(L"EnableWarnings") || PhShowConfirmMessage( hWnd, L"end", L"I/O for the selected thread", NULL, FALSE )) cont = TRUE; if (!cont) return FALSE; if (NT_SUCCESS(status = PhOpenThread(&threadHandle, THREAD_TERMINATE, Thread->ThreadId))) { status = NtCancelSynchronousIoFile(threadHandle, NULL, &isb); } if (status == STATUS_NOT_FOUND) { PhShowInformation(hWnd, L"There is no synchronous I/O to cancel."); return FALSE; } else if (!NT_SUCCESS(status)) { PhShowStatus(hWnd, L"Unable to cancel synchronous I/O", status, 0); return FALSE; } return TRUE; }
INT_PTR CALLBACK PhpJobPageProc( __in HWND hwndDlg, __in UINT uMsg, __in WPARAM wParam, __in LPARAM lParam ) { PJOB_PAGE_CONTEXT jobPageContext; jobPageContext = PhpJobPageHeader(hwndDlg, uMsg, wParam, lParam); if (!jobPageContext) return FALSE; if (jobPageContext->HookProc) { if (jobPageContext->HookProc(hwndDlg, uMsg, wParam, lParam)) return TRUE; } switch (uMsg) { case WM_INITDIALOG: { HANDLE jobHandle; HWND processesLv; HWND limitsLv; processesLv = GetDlgItem(hwndDlg, IDC_PROCESSES); limitsLv = GetDlgItem(hwndDlg, IDC_LIMITS); PhSetListViewStyle(processesLv, FALSE, TRUE); PhSetListViewStyle(limitsLv, FALSE, TRUE); PhSetControlTheme(processesLv, L"explorer"); PhSetControlTheme(limitsLv, L"explorer"); PhAddListViewColumn(processesLv, 0, 0, 0, LVCFMT_LEFT, 240, L"Name"); PhAddListViewColumn(limitsLv, 0, 0, 0, LVCFMT_LEFT, 120, L"Name"); PhAddListViewColumn(limitsLv, 1, 1, 1, LVCFMT_LEFT, 160, L"Value"); SetDlgItemText(hwndDlg, IDC_NAME, L"Unknown"); if (NT_SUCCESS(jobPageContext->OpenObject( &jobHandle, JOB_OBJECT_QUERY, jobPageContext->Context ))) { PPH_STRING jobObjectName = NULL; JOBOBJECT_EXTENDED_LIMIT_INFORMATION extendedLimits; JOBOBJECT_BASIC_UI_RESTRICTIONS basicUiRestrictions; // Name PhGetHandleInformation( NtCurrentProcess(), jobHandle, -1, NULL, NULL, NULL, &jobObjectName ); PHA_DEREFERENCE(jobObjectName); if (jobObjectName && jobObjectName->Length == 0) jobObjectName = NULL; SetDlgItemText(hwndDlg, IDC_NAME, PhGetStringOrDefault(jobObjectName, L"(unnamed job)")); // Processes PhpAddJobProcesses(hwndDlg, jobHandle); // Limits if (NT_SUCCESS(PhGetJobExtendedLimits(jobHandle, &extendedLimits))) { ULONG flags = extendedLimits.BasicLimitInformation.LimitFlags; if (flags & JOB_OBJECT_LIMIT_ACTIVE_PROCESS) { WCHAR value[PH_INT32_STR_LEN_1]; PhPrintUInt32(value, extendedLimits.BasicLimitInformation.ActiveProcessLimit); PhpAddLimit(limitsLv, L"Active Processes", value); } if (flags & JOB_OBJECT_LIMIT_AFFINITY) { WCHAR value[PH_PTR_STR_LEN_1]; PhPrintPointer(value, (PVOID)extendedLimits.BasicLimitInformation.Affinity); PhpAddLimit(limitsLv, L"Affinity", value); } if (flags & JOB_OBJECT_LIMIT_BREAKAWAY_OK) { PhpAddLimit(limitsLv, L"Breakaway OK", L"Enabled"); } if (flags & JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION) { PhpAddLimit(limitsLv, L"Die on Unhandled Exception", L"Enabled"); } if (flags & JOB_OBJECT_LIMIT_JOB_MEMORY) { PPH_STRING value = PhFormatSize(extendedLimits.JobMemoryLimit, -1); PhpAddLimit(limitsLv, L"Job Memory", value->Buffer); PhDereferenceObject(value); } if (flags & JOB_OBJECT_LIMIT_JOB_TIME) { WCHAR value[PH_TIMESPAN_STR_LEN_1]; PhPrintTimeSpan(value, extendedLimits.BasicLimitInformation.PerJobUserTimeLimit.QuadPart, PH_TIMESPAN_DHMS); PhpAddLimit(limitsLv, L"Job Time", value); } if (flags & JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE) { PhpAddLimit(limitsLv, L"Kill on Job Close", L"Enabled"); } if (flags & JOB_OBJECT_LIMIT_PRIORITY_CLASS) { PhpAddLimit(limitsLv, L"Priority Class", PhGetProcessPriorityClassString(extendedLimits.BasicLimitInformation.PriorityClass)); } if (flags & JOB_OBJECT_LIMIT_PROCESS_MEMORY) { PPH_STRING value = PhFormatSize(extendedLimits.ProcessMemoryLimit, -1); PhpAddLimit(limitsLv, L"Process Memory", value->Buffer); PhDereferenceObject(value); } if (flags & JOB_OBJECT_LIMIT_PROCESS_TIME) { WCHAR value[PH_TIMESPAN_STR_LEN_1]; PhPrintTimeSpan(value, extendedLimits.BasicLimitInformation.PerProcessUserTimeLimit.QuadPart, PH_TIMESPAN_DHMS); PhpAddLimit(limitsLv, L"Process Time", value); } if (flags & JOB_OBJECT_LIMIT_SCHEDULING_CLASS) { WCHAR value[PH_INT32_STR_LEN_1]; PhPrintUInt32(value, extendedLimits.BasicLimitInformation.SchedulingClass); PhpAddLimit(limitsLv, L"Scheduling Class", value); } if (flags & JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK) { PhpAddLimit(limitsLv, L"Silent Breakaway OK", L"Enabled"); } if (flags & JOB_OBJECT_LIMIT_WORKINGSET) { PPH_STRING value; value = PhFormatSize(extendedLimits.BasicLimitInformation.MinimumWorkingSetSize, -1); PhpAddLimit(limitsLv, L"Working Set Minimum", value->Buffer); PhDereferenceObject(value); value = PhFormatSize(extendedLimits.BasicLimitInformation.MaximumWorkingSetSize, -1); PhpAddLimit(limitsLv, L"Working Set Maximum", value->Buffer); PhDereferenceObject(value); } } if (NT_SUCCESS(PhGetJobBasicUiRestrictions(jobHandle, &basicUiRestrictions))) { ULONG flags = basicUiRestrictions.UIRestrictionsClass; if (flags & JOB_OBJECT_UILIMIT_DESKTOP) PhpAddLimit(limitsLv, L"Desktop", L"Limited"); if (flags & JOB_OBJECT_UILIMIT_DISPLAYSETTINGS) PhpAddLimit(limitsLv, L"Display Settings", L"Limited"); if (flags & JOB_OBJECT_UILIMIT_EXITWINDOWS) PhpAddLimit(limitsLv, L"Exit Windows", L"Limited"); if (flags & JOB_OBJECT_UILIMIT_GLOBALATOMS) PhpAddLimit(limitsLv, L"Global Atoms", L"Limited"); if (flags & JOB_OBJECT_UILIMIT_HANDLES) PhpAddLimit(limitsLv, L"Handles", L"Limited"); if (flags & JOB_OBJECT_UILIMIT_READCLIPBOARD) PhpAddLimit(limitsLv, L"Read Clipboard", L"Limited"); if (flags & JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS) PhpAddLimit(limitsLv, L"System Parameters", L"Limited"); if (flags & JOB_OBJECT_UILIMIT_WRITECLIPBOARD) PhpAddLimit(limitsLv, L"Write Clipboard", L"Limited"); } NtClose(jobHandle); } } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_TERMINATE: { if (PhShowConfirmMessage( hwndDlg, L"terminate", L"the job", L"Terminating a job will terminate all processes assigned to it.", TRUE )) { NTSTATUS status; HANDLE jobHandle; if (NT_SUCCESS(status = jobPageContext->OpenObject( &jobHandle, JOB_OBJECT_TERMINATE, jobPageContext->Context ))) { status = NtTerminateJobObject(jobHandle, STATUS_SUCCESS); NtClose(jobHandle); } if (!NT_SUCCESS(status)) PhShowStatus(hwndDlg, L"Unable to terminate the job", status, 0); } } break; case IDC_ADD: { NTSTATUS status; HANDLE processId; HANDLE processHandle; HANDLE jobHandle; while (PhShowChooseProcessDialog( hwndDlg, L"Select a process to add to the job permanently.", &processId )) { if (NT_SUCCESS(status = PhOpenProcess( &processHandle, PROCESS_TERMINATE | PROCESS_SET_QUOTA, processId ))) { if (NT_SUCCESS(status = jobPageContext->OpenObject( &jobHandle, JOB_OBJECT_ASSIGN_PROCESS | JOB_OBJECT_QUERY, jobPageContext->Context ))) { status = NtAssignProcessToJobObject(jobHandle, processHandle); if (NT_SUCCESS(status)) { ListView_DeleteAllItems(GetDlgItem(hwndDlg, IDC_PROCESSES)); PhpAddJobProcesses(hwndDlg, jobHandle); } NtClose(jobHandle); } NtClose(processHandle); } if (NT_SUCCESS(status)) break; else PhShowStatus(hwndDlg, L"Unable to add the process to the job", status, 0); } } break; case IDC_ADVANCED: { PhpShowJobAdvancedProperties(hwndDlg, jobPageContext); } break; } } break; case WM_NOTIFY: { PhHandleListViewNotifyBehaviors(lParam, GetDlgItem(hwndDlg, IDC_PROCESSES), PH_LIST_VIEW_DEFAULT_1_BEHAVIORS); PhHandleListViewNotifyBehaviors(lParam, GetDlgItem(hwndDlg, IDC_LIMITS), PH_LIST_VIEW_DEFAULT_1_BEHAVIORS); } 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 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, 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); } break; case WM_DESTROY: { PhSaveWindowPlacementToSetting(L"FindObjWindowPosition", L"FindObjWindowSize", hwndDlg); PhSaveListViewColumnsToSetting(L"FindObjListViewColumns", PhFindObjectsListViewHandle); } break; case WM_SHOWWINDOW: { SetFocus(GetDlgItem(hwndDlg, IDC_FILTER)); 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; // Cleanup 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. SearchString = PhGetWindowText(GetDlgItem(hwndDlg, IDC_FILTER)); SearchResults = PhCreateList(128); SearchResultsAddIndex = 0; SearchThreadHandle = PhCreateThread(0, PhpFindObjectsThreadStart, NULL); if (!SearchThreadHandle) 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_OBJECT_PROCESSPROPERTIES: { PPHP_OBJECT_SEARCH_RESULT result = PhGetSelectedListViewItemParam(PhFindObjectsListViewHandle); if (result) { PPH_PROCESS_ITEM processItem; if (processItem = PhReferenceProcessItem(result->ProcessId)) { ProcessHacker_ShowProcessProperties(PhMainWndHandle, processItem); PhDereferenceObject(processItem); } } } 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 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) { HMENU menu; HMENU subMenu; menu = LoadMenu(PhInstanceHandle, MAKEINTRESOURCE(IDR_FINDOBJ)); subMenu = GetSubMenu(menu, 0); SetMenuDefaultItem(subMenu, ID_OBJECT_PROPERTIES, FALSE); PhpInitializeFindObjMenu( subMenu, results, numberOfResults ); PhShowContextMenu( hwndDlg, PhFindObjectsListViewHandle, subMenu, point ); DestroyMenu(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) { searchResult->ProcessName = processItem->ProcessName; PhReferenceObject(searchResult->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: { // Add any un-added items. SendMessage(hwndDlg, WM_PH_SEARCH_UPDATE, 0, 0); PhDereferenceObject(SearchString); 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)); } break; } return FALSE; }
VOID NTAPI MenuItemCallback( _In_opt_ PVOID Parameter, _In_opt_ PVOID Context ) { PPH_PLUGIN_MENU_ITEM menuItem = Parameter; switch (menuItem->Id) { case CRITICAL_MENU_ITEM: { NTSTATUS status; PPH_PROCESS_ITEM processItem = menuItem->Context; HANDLE processHandle; ULONG breakOnTermination; if (NT_SUCCESS(status = PhOpenProcess(&processHandle, PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION, processItem->ProcessId))) { if (NT_SUCCESS(status = NtQueryInformationProcess(processHandle, ProcessBreakOnTermination, &breakOnTermination, sizeof(ULONG), NULL))) { if (!breakOnTermination && PhShowConfirmMessage( menuItem->OwnerWindow, L"enable", L"critical status on the process", L"If the process ends, the operating system will shut down immediately.", TRUE )) { breakOnTermination = TRUE; status = NtSetInformationProcess(processHandle, ProcessBreakOnTermination, &breakOnTermination, sizeof(ULONG)); } else if (breakOnTermination && PhShowConfirmMessage( menuItem->OwnerWindow, L"disable", L"critical status on the process", NULL, FALSE )) { breakOnTermination = FALSE; status = NtSetInformationProcess(processHandle, ProcessBreakOnTermination, &breakOnTermination, sizeof(ULONG)); } if (!NT_SUCCESS(status)) PhShowStatus(menuItem->OwnerWindow, L"Unable to set critical status", status, 0); } else { PhShowStatus(menuItem->OwnerWindow, L"Unable to query critical status", status, 0); } NtClose(processHandle); } else { PhShowStatus(menuItem->OwnerWindow, L"Unable to open the process", status, 0); } } break; } }
INT_PTR CALLBACK DnsCacheDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { PhCenterWindow(hwndDlg, PhMainWndHandle); ListViewWndHandle = GetDlgItem(hwndDlg, IDC_DNSLIST); PhRegisterDialog(hwndDlg); PhSetListViewStyle(ListViewWndHandle, FALSE, TRUE); PhSetControlTheme(ListViewWndHandle, L"explorer"); PhAddListViewColumn(ListViewWndHandle, 0, 0, 0, LVCFMT_LEFT, 280, L"Host Name"); PhAddListViewColumn(ListViewWndHandle, 1, 1, 1, LVCFMT_LEFT, 70, L"Type"); PhAddListViewColumn(ListViewWndHandle, 2, 2, 2, LVCFMT_LEFT, 100, L"IP Address"); PhAddListViewColumn(ListViewWndHandle, 3, 3, 3, LVCFMT_LEFT, 50, L"TTL"); PhSetExtendedListView(ListViewWndHandle); PhInitializeLayoutManager(&LayoutManager, hwndDlg); PhAddLayoutItem(&LayoutManager, ListViewWndHandle, NULL, PH_ANCHOR_ALL); PhAddLayoutItem(&LayoutManager, GetDlgItem(hwndDlg, IDC_DNS_REFRESH), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT); PhAddLayoutItem(&LayoutManager, GetDlgItem(hwndDlg, IDC_DNS_CLEAR), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT); PhAddLayoutItem(&LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT); PhLoadWindowPlacementFromSetting(SETTING_NAME_WINDOW_POSITION, SETTING_NAME_WINDOW_SIZE, hwndDlg); PhLoadListViewColumnsFromSetting(SETTING_NAME_COLUMNS, ListViewWndHandle); EnumDnsCacheTable(ListViewWndHandle); } break; case WM_DESTROY: { if (DnsApiHandle) { FreeLibrary(DnsApiHandle); DnsApiHandle = NULL; } PhSaveWindowPlacementToSetting(SETTING_NAME_WINDOW_POSITION, SETTING_NAME_WINDOW_SIZE, hwndDlg); PhSaveListViewColumnsToSetting(SETTING_NAME_COLUMNS, ListViewWndHandle); PhDeleteLayoutManager(&LayoutManager); } break; case WM_SIZE: PhLayoutManagerLayout(&LayoutManager); break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_DNS_CLEAR: { if (!PhGetIntegerSetting(L"EnableWarnings") || PhShowConfirmMessage( hwndDlg, L"Flush", L"the dns cache", NULL, FALSE )) { if (DnsFlushResolverCache_I) DnsFlushResolverCache_I(); ExtendedListView_SetRedraw(ListViewWndHandle, FALSE); ListView_DeleteAllItems(ListViewWndHandle); EnumDnsCacheTable(ListViewWndHandle); ExtendedListView_SetRedraw(ListViewWndHandle, TRUE); } } break; case IDC_DNS_REFRESH: { ExtendedListView_SetRedraw(ListViewWndHandle, FALSE); ListView_DeleteAllItems(ListViewWndHandle); EnumDnsCacheTable(ListViewWndHandle); ExtendedListView_SetRedraw(ListViewWndHandle, TRUE); } break; case IDCANCEL: case IDOK: EndDialog(hwndDlg, IDOK); break; } } break; case WM_NOTIFY: { LPNMHDR hdr = (LPNMHDR)lParam; switch (hdr->code) { case NM_RCLICK: { if (hdr->hwndFrom == ListViewWndHandle) ShowStatusMenu(hwndDlg); } break; } } break; } return FALSE; }
VOID ShowStatusMenu( _In_ HWND hwndDlg ) { PPH_STRING cacheEntryName; cacheEntryName = PhGetSelectedListViewItemText(ListViewWndHandle); if (cacheEntryName) { POINT cursorPos; PPH_EMENU menu; PPH_EMENU_ITEM selectedItem; GetCursorPos(&cursorPos); menu = PhCreateEMenu(); PhInsertEMenuItem(menu, PhCreateEMenuItem(0, 1, L"Remove", NULL, NULL), -1); PhInsertEMenuItem(menu, PhCreateEMenuItem(0, 2, L"Copy Host Name", NULL, NULL), -1); selectedItem = PhShowEMenu( menu, PhMainWndHandle, PH_EMENU_SHOW_LEFTRIGHT, PH_ALIGN_LEFT | PH_ALIGN_TOP, cursorPos.x, cursorPos.y ); if (selectedItem && selectedItem->Id != -1) { switch (selectedItem->Id) { case 1: { INT lvItemIndex = PhFindListViewItemByFlags( ListViewWndHandle, -1, LVNI_SELECTED ); if (lvItemIndex != -1) { if (!PhGetIntegerSetting(L"EnableWarnings") || PhShowConfirmMessage( hwndDlg, L"remove", cacheEntryName->Buffer, NULL, FALSE )) { if (DnsFlushResolverCacheEntry_I(cacheEntryName->Buffer)) { ExtendedListView_SetRedraw(ListViewWndHandle, FALSE); ListView_DeleteAllItems(ListViewWndHandle); EnumDnsCacheTable(ListViewWndHandle); ExtendedListView_SetRedraw(ListViewWndHandle, TRUE); } } } } break; case 2: PhSetClipboardString(hwndDlg, &cacheEntryName->sr); break; } } PhDestroyEMenu(menu); PhDereferenceObject(cacheEntryName); } }
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; }
static INT_PTR CALLBACK PhpProcessTerminatorDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { PPH_PROCESS_ITEM processItem = (PPH_PROCESS_ITEM)lParam; PPH_STRING title; HWND lvHandle; HIMAGELIST imageList; ULONG i; PhCenterWindow(hwndDlg, GetParent(hwndDlg)); title = PhFormatString( L"Terminator - %s (%u)", processItem->ProcessName->Buffer, (ULONG)processItem->ProcessId ); SetWindowText(hwndDlg, title->Buffer); PhDereferenceObject(title); SetProp(hwndDlg, L"ProcessItem", (HANDLE)processItem); lvHandle = GetDlgItem(hwndDlg, IDC_TERMINATOR_LIST); PhAddListViewColumn(lvHandle, 0, 0, 0, LVCFMT_LEFT, 70, L"ID"); PhAddListViewColumn(lvHandle, 1, 1, 1, LVCFMT_LEFT, 280, L"Description"); ListView_SetExtendedListViewStyleEx(lvHandle, LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER | LVS_EX_INFOTIP | LVS_EX_LABELTIP | LVS_EX_CHECKBOXES, -1); PhSetControlTheme(lvHandle, L"explorer"); imageList = ImageList_Create(16, 16, ILC_COLOR32, 0, 0); ImageList_SetImageCount(imageList, 2); PhSetImageListBitmap(imageList, CROSS_INDEX, PhInstanceHandle, MAKEINTRESOURCE(IDB_CROSS)); PhSetImageListBitmap(imageList, TICK_INDEX, PhInstanceHandle, MAKEINTRESOURCE(IDB_TICK)); for (i = 0; i < sizeof(PhTerminatorTests) / sizeof(TEST_ITEM); i++) { INT itemIndex; BOOLEAN check; itemIndex = PhAddListViewItem( lvHandle, MAXINT, PhTerminatorTests[i].Id, &PhTerminatorTests[i] ); PhSetListViewSubItem(lvHandle, itemIndex, 1, PhTerminatorTests[i].Description); PhSetListViewItemImageIndex(lvHandle, itemIndex, -1); check = TRUE; if (WSTR_EQUAL(PhTerminatorTests[i].Id, L"TT4") || WSTR_EQUAL(PhTerminatorTests[i].Id, L"M1")) check = FALSE; ListView_SetCheckState(lvHandle, itemIndex, check); } ListView_SetImageList(lvHandle, imageList, LVSIL_SMALL); SetDlgItemText( hwndDlg, IDC_TERMINATOR_TEXT, L"Double-click a termination method or click Run Selected." ); } break; case WM_DESTROY: { RemoveProp(hwndDlg, L"ProcessItem"); } break; case WM_COMMAND: { INT id = LOWORD(wParam); switch (id) { case IDCANCEL: // Esc and X button to close case IDOK: EndDialog(hwndDlg, IDOK); break; case IDC_RUNSELECTED: { if (PhShowConfirmMessage(hwndDlg, L"run", L"the selected terminator tests", NULL, FALSE)) { HWND lvHandle; ULONG i; lvHandle = GetDlgItem(hwndDlg, IDC_TERMINATOR_LIST); for (i = 0; i < sizeof(PhTerminatorTests) / sizeof(TEST_ITEM); i++) { if (ListView_GetCheckState(lvHandle, i)) { if (PhpRunTerminatorTest( hwndDlg, i )) break; } } } } break; } } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; if (header->hwndFrom == GetDlgItem(hwndDlg, IDC_TERMINATOR_LIST)) { if (header->code == NM_DBLCLK) { LPNMITEMACTIVATE itemActivate = (LPNMITEMACTIVATE)header; if (itemActivate->iItem != -1) { if (PhShowConfirmMessage(hwndDlg, L"run", L"the selected test", NULL, FALSE)) { PhpRunTerminatorTest( hwndDlg, itemActivate->iItem ); } } } else if (header->code == LVN_ITEMCHANGED) { ULONG i; BOOLEAN oneSelected; oneSelected = FALSE; for (i = 0; i < sizeof(PhTerminatorTests) / sizeof(TEST_ITEM); i++) { if (ListView_GetCheckState(header->hwndFrom, i)) { oneSelected = TRUE; break; } } EnableWindow(GetDlgItem(hwndDlg, IDC_RUNSELECTED), oneSelected); } } } break; } return FALSE; }
static BOOLEAN PhpRunTerminatorTest( _In_ HWND WindowHandle, _In_ INT Index ) { NTSTATUS status; PTEST_ITEM testItem; PPH_PROCESS_ITEM processItem; HWND lvHandle; PVOID processes; BOOLEAN success = FALSE; LARGE_INTEGER interval; processItem = (PPH_PROCESS_ITEM)GetProp(WindowHandle, L"ProcessItem"); lvHandle = GetDlgItem(WindowHandle, IDC_TERMINATOR_LIST); if (!PhGetListViewItemParam( lvHandle, Index, &testItem )) return FALSE; if (WSTR_EQUAL(testItem->Id, L"TT4")) { if (!PhShowConfirmMessage( WindowHandle, L"run", L"the TT4 test", L"The TT4 test may cause the system to crash.", TRUE )) return FALSE; } status = testItem->TestProc(processItem->ProcessId); interval.QuadPart = -1000 * PH_TIMEOUT_MS; NtDelayExecution(FALSE, &interval); if (status == STATUS_NOT_SUPPORTED) { PPH_STRING concat; concat = PhConcatStrings2(L"(Not available) ", testItem->Description); PhSetListViewSubItem(lvHandle, Index, 1, concat->Buffer); PhDereferenceObject(concat); } if (!NT_SUCCESS(PhEnumProcesses(&processes))) return FALSE; // Check if the process exists. if (!PhFindProcessInformation(processes, processItem->ProcessId)) { PhSetListViewItemImageIndex(lvHandle, Index, TICK_INDEX); SetDlgItemText(WindowHandle, IDC_TERMINATOR_TEXT, L"The process was terminated."); success = TRUE; } else { PhSetListViewItemImageIndex(lvHandle, Index, CROSS_INDEX); } PhFree(processes); UpdateWindow(WindowHandle); return success; }
static VOID ShowStatusMenu( _In_ HWND hwndDlg ) { PPH_STRING cacheEntryName; cacheEntryName = PhGetSelectedListViewItemText(ListViewWndHandle); if (cacheEntryName) { POINT cursorPos; PPH_EMENU menu; PPH_EMENU_ITEM selectedItem; GetCursorPos(&cursorPos); menu = PhCreateEMenu(); PhInsertEMenuItem(menu, PhCreateEMenuItem(0, 1, L"Remove", NULL, NULL), -1); selectedItem = PhShowEMenu( menu, ListViewWndHandle, PH_EMENU_SHOW_LEFTRIGHT, PH_ALIGN_LEFT | PH_ALIGN_TOP, cursorPos.x, cursorPos.y ); if (selectedItem && selectedItem->Id != -1) { switch (selectedItem->Id) { case 1: { INT lvItemIndex = PhFindListViewItemByFlags( ListViewWndHandle, -1, LVNI_SELECTED ); if (lvItemIndex != -1) { if (!PhGetIntegerSetting(L"EnableWarnings") || PhShowConfirmMessage( hwndDlg, L"remove", cacheEntryName->Buffer, NULL, FALSE )) { PATOM_TABLE_INFORMATION atomTable = NULL; if (!NT_SUCCESS(PhEnumAtomTable(&atomTable))) return; for (ULONG i = 0; i < atomTable->NumberOfAtoms; i++) { PATOM_BASIC_INFORMATION atomInfo = NULL; if (!NT_SUCCESS(PhQueryAtomTableEntry(atomTable->Atoms[i], &atomInfo))) continue; if (!PhEqualStringZ(atomInfo->Name, cacheEntryName->Buffer, TRUE)) continue; do { if (!NT_SUCCESS(NtDeleteAtom(atomTable->Atoms[i]))) { break; } PhFree(atomInfo); atomInfo = NULL; if (!NT_SUCCESS(PhQueryAtomTableEntry(atomTable->Atoms[i], &atomInfo))) break; } while (atomInfo->UsageCount >= 1); ListView_DeleteItem(ListViewWndHandle, lvItemIndex); if (atomInfo) { PhFree(atomInfo); } } PhFree(atomTable); } } } break; } } PhDestroyEMenu(menu); PhDereferenceObject(cacheEntryName); } }