static VOID PhpRefreshSectionPageInfo( _In_ HWND hwndDlg, _In_ PCOMMON_PAGE_CONTEXT PageContext ) { HANDLE sectionHandle; SECTION_BASIC_INFORMATION basicInfo; PWSTR sectionType = L"Unknown"; PPH_STRING sectionSize = NULL; PPH_STRING fileName = NULL; if (!NT_SUCCESS(PageContext->OpenObject( §ionHandle, SECTION_QUERY | SECTION_MAP_READ, PageContext->Context ))) { if (!NT_SUCCESS(PageContext->OpenObject( §ionHandle, SECTION_QUERY | SECTION_MAP_READ, PageContext->Context ))) { return; } } if (NT_SUCCESS(PhGetSectionBasicInformation(sectionHandle, &basicInfo))) { if (basicInfo.AllocationAttributes & SEC_COMMIT) sectionType = L"Commit"; else if (basicInfo.AllocationAttributes & SEC_FILE) sectionType = L"File"; else if (basicInfo.AllocationAttributes & SEC_IMAGE) sectionType = L"Image"; else if (basicInfo.AllocationAttributes & SEC_RESERVE) sectionType = L"Reserve"; sectionSize = PhaFormatSize(basicInfo.MaximumSize.QuadPart, -1); } if (NT_SUCCESS(PhGetSectionFileName(sectionHandle, &fileName))) { PPH_STRING newFileName; PH_AUTO(fileName); if (newFileName = PhResolveDevicePrefix(fileName)) fileName = PH_AUTO(newFileName); } SetDlgItemText(hwndDlg, IDC_TYPE, sectionType); SetDlgItemText(hwndDlg, IDC_SIZE_, PhGetStringOrDefault(sectionSize, L"Unknown")); SetDlgItemText(hwndDlg, IDC_FILE, PhGetStringOrDefault(fileName, L"N/A")); NtClose(sectionHandle); }
static BOOLEAN NTAPI PhpHiddenProcessesCallback( _In_ PPH_HIDDEN_PROCESS_ENTRY Process, _In_opt_ PVOID Context ) { PPH_HIDDEN_PROCESS_ENTRY entry; INT lvItemIndex; WCHAR pidString[PH_INT32_STR_LEN_1]; entry = PhAllocateCopy(Process, sizeof(PH_HIDDEN_PROCESS_ENTRY)); if (entry->FileName) PhReferenceObject(entry->FileName); PhAddItemList(ProcessesList, entry); lvItemIndex = PhAddListViewItem(PhHiddenProcessesListViewHandle, MAXINT, PhGetStringOrDefault(entry->FileName, L"(unknown)"), entry); PhPrintUInt32(pidString, HandleToUlong(entry->ProcessId)); PhSetListViewSubItem(PhHiddenProcessesListViewHandle, lvItemIndex, 1, pidString); if (entry->Type == HiddenProcess) NumberOfHiddenProcesses++; else if (entry->Type == TerminatedProcess) NumberOfTerminatedProcesses++; return TRUE; }
VOID PhpRefreshPluginDetails( _In_ HWND hwndDlg ) { PPH_STRING fileName; PH_IMAGE_VERSION_INFO versionInfo; if (SelectedPlugin && SelectedPlugin->FileName) // if there's no FileName, then it's a fake disabled plugin instance { fileName = SelectedPlugin->FileName; SetDlgItemText(hwndDlg, IDC_NAME, SelectedPlugin->Information.DisplayName ? SelectedPlugin->Information.DisplayName : L"(unnamed)"); SetDlgItemText(hwndDlg, IDC_INTERNALNAME, SelectedPlugin->Name.Buffer); SetDlgItemText(hwndDlg, IDC_AUTHOR, SelectedPlugin->Information.Author); SetDlgItemText(hwndDlg, IDC_FILENAME, fileName->Buffer); SetDlgItemText(hwndDlg, IDC_DESCRIPTION, SelectedPlugin->Information.Description); SetDlgItemText(hwndDlg, IDC_URL, SelectedPlugin->Information.Url); if (PhInitializeImageVersionInfo(&versionInfo, fileName->Buffer)) { SetDlgItemText(hwndDlg, IDC_VERSION, PhGetStringOrDefault(versionInfo.FileVersion, L"Unknown")); PhDeleteImageVersionInfo(&versionInfo); } else { SetDlgItemText(hwndDlg, IDC_VERSION, L"Unknown"); } ShowWindow(GetDlgItem(hwndDlg, IDC_OPENURL), SelectedPlugin->Information.Url ? SW_SHOW : SW_HIDE); EnableWindow(GetDlgItem(hwndDlg, IDC_DISABLE), TRUE); SetDlgItemText(hwndDlg, IDC_DISABLE, PhpGetPluginDisableButtonText(PhpGetPluginBaseName(SelectedPlugin))); EnableWindow(GetDlgItem(hwndDlg, IDC_OPTIONS), SelectedPlugin->Information.HasOptions); } else { SetDlgItemText(hwndDlg, IDC_NAME, L"N/A"); SetDlgItemText(hwndDlg, IDC_VERSION, L"N/A"); SetDlgItemText(hwndDlg, IDC_INTERNALNAME, L"N/A"); SetDlgItemText(hwndDlg, IDC_AUTHOR, L"N/A"); SetDlgItemText(hwndDlg, IDC_URL, L"N/A"); SetDlgItemText(hwndDlg, IDC_FILENAME, L"N/A"); SetDlgItemText(hwndDlg, IDC_DESCRIPTION, L"N/A"); ShowWindow(GetDlgItem(hwndDlg, IDC_OPENURL), SW_HIDE); if (SelectedPlugin) { // This is a disabled plugin. EnableWindow(GetDlgItem(hwndDlg, IDC_DISABLE), TRUE); SetDlgItemText(hwndDlg, IDC_DISABLE, PhpGetPluginDisableButtonText(SelectedPlugin->Name.Buffer)); } else { EnableWindow(GetDlgItem(hwndDlg, IDC_DISABLE), FALSE); SetDlgItemText(hwndDlg, IDC_DISABLE, L"Disable"); } EnableWindow(GetDlgItem(hwndDlg, IDC_OPTIONS), FALSE); } }
PPH_STRING PhFormatLogEntry( _In_ PPH_LOG_ENTRY Entry ) { switch (Entry->Type) { case PH_LOG_ENTRY_PROCESS_CREATE: return PhFormatString( L"Process created: %s (%u) started by %s (%u)", Entry->Process.Name->Buffer, (ULONG)Entry->Process.ProcessId, PhGetStringOrDefault(Entry->Process.ParentName, L"Unknown Process"), (ULONG)Entry->Process.ParentProcessId ); case PH_LOG_ENTRY_PROCESS_DELETE: return PhFormatString(L"Process terminated: %s (%u)", Entry->Process.Name->Buffer, (ULONG)Entry->Process.ProcessId); case PH_LOG_ENTRY_SERVICE_CREATE: return PhFormatString(L"Service created: %s (%s)", Entry->Service.Name->Buffer, Entry->Service.DisplayName->Buffer); case PH_LOG_ENTRY_SERVICE_DELETE: return PhFormatString(L"Service deleted: %s (%s)", Entry->Service.Name->Buffer, Entry->Service.DisplayName->Buffer); case PH_LOG_ENTRY_SERVICE_START: return PhFormatString(L"Service started: %s (%s)", Entry->Service.Name->Buffer, Entry->Service.DisplayName->Buffer); case PH_LOG_ENTRY_SERVICE_STOP: return PhFormatString(L"Service stopped: %s (%s)", Entry->Service.Name->Buffer, Entry->Service.DisplayName->Buffer); case PH_LOG_ENTRY_SERVICE_CONTINUE: return PhFormatString(L"Service continued: %s (%s)", Entry->Service.Name->Buffer, Entry->Service.DisplayName->Buffer); case PH_LOG_ENTRY_SERVICE_PAUSE: return PhFormatString(L"Service paused: %s (%s)", Entry->Service.Name->Buffer, Entry->Service.DisplayName->Buffer); case PH_LOG_ENTRY_MESSAGE: PhReferenceObject(Entry->Message); return Entry->Message; default: return PhReferenceEmptyString(); } }
static NTSTATUS PhpRefreshThreadStack( _In_ HWND hwnd, _In_ PTHREAD_STACK_CONTEXT ThreadStackContext ) { ULONG i; ThreadStackContext->StopWalk = FALSE; PhSwapReference2(&ThreadStackContext->StatusMessage, PhCreateString(L"Loading stack...")); DialogBoxParam( PhInstanceHandle, MAKEINTRESOURCE(IDD_PROGRESS), hwnd, PhpThreadStackProgressDlgProc, (LPARAM)ThreadStackContext ); if (!ThreadStackContext->StopWalk && NT_SUCCESS(ThreadStackContext->WalkStatus)) { for (i = 0; i < ThreadStackContext->List->Count; i++) PhpFreeThreadStackItem(ThreadStackContext->List->Items[i]); PhDereferenceObject(ThreadStackContext->List); ThreadStackContext->List = ThreadStackContext->NewList; ThreadStackContext->NewList = PhCreateList(10); ListView_DeleteAllItems(ThreadStackContext->ListViewHandle); SendMessage(ThreadStackContext->ListViewHandle, WM_SETREDRAW, FALSE, 0); for (i = 0; i < ThreadStackContext->List->Count; i++) { PTHREAD_STACK_ITEM item = ThreadStackContext->List->Items[i]; INT lvItemIndex; WCHAR integerString[PH_INT32_STR_LEN_1]; PhPrintUInt32(integerString, item->Index); lvItemIndex = PhAddListViewItem(ThreadStackContext->ListViewHandle, MAXINT, integerString, item); PhSetListViewSubItem(ThreadStackContext->ListViewHandle, lvItemIndex, 1, PhGetStringOrDefault(item->Symbol, L"???")); } SendMessage(ThreadStackContext->ListViewHandle, WM_SETREDRAW, TRUE, 0); InvalidateRect(ThreadStackContext->ListViewHandle, NULL, FALSE); } else { for (i = 0; i < ThreadStackContext->NewList->Count; i++) PhpFreeThreadStackItem(ThreadStackContext->NewList->Items[i]); PhClearList(ThreadStackContext->NewList); } if (ThreadStackContext->StopWalk) return STATUS_ABANDONED; return ThreadStackContext->WalkStatus; }
VOID PhpHandlePluginLoadError( _In_ PPH_STRING FileName, _In_opt_ PPH_STRING ErrorMessage ) { PPH_STRING baseName; baseName = PhGetBaseName(FileName); if (PhShowMessage( NULL, MB_ICONERROR | MB_YESNO, L"Unable to load %s: %s\nDo you want to disable the plugin?", baseName->Buffer, PhGetStringOrDefault(ErrorMessage, L"An unknown error occurred.") ) == IDYES) { PhSetPluginDisabled(&baseName->sr, TRUE); } PhDereferenceObject(baseName); }
INT_PTR CALLBACK DotNetAsmPageDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { LPPROPSHEETPAGE propSheetPage; PPH_PROCESS_PROPPAGECONTEXT propPageContext; PPH_PROCESS_ITEM processItem; PASMPAGE_CONTEXT context; if (PhPropPageDlgProcHeader(hwndDlg, uMsg, lParam, &propSheetPage, &propPageContext, &processItem)) { context = propPageContext->Context; } else { return FALSE; } switch (uMsg) { case WM_INITDIALOG: { PPH_STRING settings; HWND tnHandle; context = PhAllocate(sizeof(ASMPAGE_CONTEXT)); memset(context, 0, sizeof(ASMPAGE_CONTEXT)); propPageContext->Context = context; context->WindowHandle = hwndDlg; context->ProcessItem = processItem; context->ClrVersions = 0; PhGetProcessIsDotNetEx(processItem->ProcessId, NULL, 0, NULL, &context->ClrVersions); tnHandle = GetDlgItem(hwndDlg, IDC_LIST); context->TnHandle = tnHandle; TreeNew_SetCallback(tnHandle, DotNetAsmTreeNewCallback, context); TreeNew_SetExtendedFlags(tnHandle, TN_FLAG_ITEM_DRAG_SELECT, TN_FLAG_ITEM_DRAG_SELECT); PhSetControlTheme(tnHandle, L"explorer"); SendMessage(TreeNew_GetTooltips(tnHandle), TTM_SETMAXTIPWIDTH, 0, MAXSHORT); PhAddTreeNewColumn(tnHandle, DNATNC_STRUCTURE, TRUE, L"Structure", 240, PH_ALIGN_LEFT, -2, 0); PhAddTreeNewColumn(tnHandle, DNATNC_ID, TRUE, L"ID", 50, PH_ALIGN_RIGHT, 0, DT_RIGHT); PhAddTreeNewColumn(tnHandle, DNATNC_FLAGS, TRUE, L"Flags", 120, PH_ALIGN_LEFT, 1, 0); PhAddTreeNewColumn(tnHandle, DNATNC_PATH, TRUE, L"Path", 600, PH_ALIGN_LEFT, 2, 0); // don't use path ellipsis - the user already has the base file name PhAddTreeNewColumn(tnHandle, DNATNC_NATIVEPATH, TRUE, L"Native image path", 600, PH_ALIGN_LEFT, 3, 0); settings = PhGetStringSetting(SETTING_NAME_ASM_TREE_LIST_COLUMNS); PhCmLoadSettings(tnHandle, &settings->sr); PhDereferenceObject(settings); PhSwapReference(&context->TnErrorMessage, PhCreateString(L"Loading .NET assemblies...")); TreeNew_SetEmptyText(tnHandle, &context->TnErrorMessage->sr, 0); if ( !IsProcessSuspended(processItem->ProcessId) || PhShowMessage(hwndDlg, MB_ICONWARNING | MB_YESNO, L".NET assembly enumeration may not work properly because the process is currently suspended. Do you want to continue?") == IDYES ) { CreateDotNetTraceQueryThread( hwndDlg, context->ClrVersions, processItem->ProcessId ); } else { PhSwapReference(&context->TnErrorMessage, PhCreateString(L"Unable to start the event tracing session because the process is suspended.") ); TreeNew_SetEmptyText(tnHandle, &context->TnErrorMessage->sr, 0); InvalidateRect(tnHandle, NULL, FALSE); } } break; case WM_DESTROY: { PPH_STRING settings; ULONG i; settings = PhCmSaveSettings(context->TnHandle); PhSetStringSetting2(SETTING_NAME_ASM_TREE_LIST_COLUMNS, &settings->sr); PhDereferenceObject(settings); if (context->NodeList) { for (i = 0; i < context->NodeList->Count; i++) DestroyNode(context->NodeList->Items[i]); PhDereferenceObject(context->NodeList); } if (context->NodeRootList) PhDereferenceObject(context->NodeRootList); PhClearReference(&context->TnErrorMessage); PhFree(context); PhPropPageDlgProcDestroy(hwndDlg); } break; case WM_SHOWWINDOW: { PPH_LAYOUT_ITEM dialogItem; if (dialogItem = PhBeginPropPageLayout(hwndDlg, propPageContext)) { PhAddPropPageLayoutItem(hwndDlg, GetDlgItem(hwndDlg, IDC_LIST), dialogItem, PH_ANCHOR_ALL); PhEndPropPageLayout(hwndDlg, propPageContext); } } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case ID_COPY: { PPH_STRING text; text = PhGetTreeNewText(context->TnHandle, 0); PhSetClipboardString(context->TnHandle, &text->sr); PhDereferenceObject(text); } break; } } break; case UPDATE_MSG: { ULONG result = (ULONG)wParam; PASMPAGE_QUERY_CONTEXT queryContext = (PASMPAGE_QUERY_CONTEXT)lParam; if (result == 0) { PhSwapReference(&context->NodeList, queryContext->NodeList); PhSwapReference(&context->NodeRootList, queryContext->NodeRootList); DestroyDotNetTraceQuery(queryContext); TreeNew_NodesStructured(context->TnHandle); } else { PhSwapReference(&context->TnErrorMessage, PhConcatStrings2(L"Unable to start the event tracing session: ", PhGetStringOrDefault(PhGetWin32Message(result), L"Unknown error")) ); TreeNew_SetEmptyText(context->TnHandle, &context->TnErrorMessage->sr, 0); InvalidateRect(context->TnHandle, NULL, FALSE); } } 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 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)); }
VOID PhpRefreshProcessMemoryList( _In_ HWND hwndDlg, _In_ PPH_PROCESS_PROPPAGECONTEXT PropPageContext ) { PPH_MEMORY_CONTEXT memoryContext = PropPageContext->Context; if (memoryContext->MemoryItemListValid) { PhDeleteMemoryItemList(&memoryContext->MemoryItemList); memoryContext->MemoryItemListValid = FALSE; } memoryContext->LastRunStatus = PhQueryMemoryItemList( memoryContext->ProcessId, PH_QUERY_MEMORY_REGION_TYPE | PH_QUERY_MEMORY_WS_COUNTERS, &memoryContext->MemoryItemList ); if (NT_SUCCESS(memoryContext->LastRunStatus)) { if (PhPluginsEnabled) { PH_PLUGIN_MEMORY_ITEM_LIST_CONTROL control; control.Type = PluginMemoryItemListInitialized; control.u.Initialized.List = &memoryContext->MemoryItemList; PhInvokeCallback(PhGetGeneralCallback(GeneralCallbackMemoryItemListControl), &control); } memoryContext->MemoryItemListValid = TRUE; TreeNew_SetEmptyText(memoryContext->ListContext.TreeNewHandle, &EmptyMemoryText, 0); PhReplaceMemoryList(&memoryContext->ListContext, &memoryContext->MemoryItemList); } else { PPH_STRING message; message = PhGetStatusMessage(memoryContext->LastRunStatus, 0); PhMoveReference(&memoryContext->ErrorMessage, PhFormatString(L"Unable to query memory information:\n%s", PhGetStringOrDefault(message, L"Unknown error."))); PhClearReference(&message); TreeNew_SetEmptyText(memoryContext->ListContext.TreeNewHandle, &memoryContext->ErrorMessage->sr, 0); PhReplaceMemoryList(&memoryContext->ListContext, NULL); } }
VOID PhpUpdateThreadDetails( _In_ HWND hwndDlg, _In_ PPH_THREADS_CONTEXT Context, _In_ BOOLEAN Force ) { PPH_THREAD_ITEM *threads; ULONG numberOfThreads; PPH_THREAD_ITEM threadItem; PPH_STRING startModule = NULL; PPH_STRING started = NULL; WCHAR kernelTime[PH_TIMESPAN_STR_LEN_1] = L"N/A"; WCHAR userTime[PH_TIMESPAN_STR_LEN_1] = L"N/A"; PPH_STRING contextSwitches = NULL; PPH_STRING cycles = NULL; PPH_STRING state = NULL; WCHAR priority[PH_INT32_STR_LEN_1] = L"N/A"; WCHAR basePriority[PH_INT32_STR_LEN_1] = L"N/A"; PWSTR ioPriority = L"N/A"; PWSTR pagePriority = L"N/A"; WCHAR idealProcessor[PH_INT32_STR_LEN + 1 + PH_INT32_STR_LEN + 1] = L"N/A"; HANDLE threadHandle; SYSTEMTIME time; IO_PRIORITY_HINT ioPriorityInteger; ULONG pagePriorityInteger; PROCESSOR_NUMBER idealProcessorNumber; ULONG suspendCount; PhGetSelectedThreadItems(&Context->ListContext, &threads, &numberOfThreads); if (numberOfThreads == 1) threadItem = threads[0]; else threadItem = NULL; PhFree(threads); if (numberOfThreads != 1 && !Force) return; if (numberOfThreads == 1) { startModule = threadItem->StartAddressFileName; PhLargeIntegerToLocalSystemTime(&time, &threadItem->CreateTime); started = PhaFormatDateTime(&time); PhPrintTimeSpan(kernelTime, threadItem->KernelTime.QuadPart, PH_TIMESPAN_HMSM); PhPrintTimeSpan(userTime, threadItem->UserTime.QuadPart, PH_TIMESPAN_HMSM); contextSwitches = PhaFormatUInt64(threadItem->ContextSwitchesDelta.Value, TRUE); if (WINDOWS_HAS_CYCLE_TIME) cycles = PhaFormatUInt64(threadItem->CyclesDelta.Value, TRUE); if (threadItem->State != Waiting) { if ((ULONG)threadItem->State < MaximumThreadState) state = PhaCreateString(PhKThreadStateNames[(ULONG)threadItem->State]); else state = PhaCreateString(L"Unknown"); } else { if ((ULONG)threadItem->WaitReason < MaximumWaitReason) state = PhaConcatStrings2(L"Wait:", PhKWaitReasonNames[(ULONG)threadItem->WaitReason]); else state = PhaCreateString(L"Waiting"); } PhPrintInt32(priority, threadItem->Priority); PhPrintInt32(basePriority, threadItem->BasePriority); if (NT_SUCCESS(PhOpenThread(&threadHandle, ThreadQueryAccess, threadItem->ThreadId))) { if (NT_SUCCESS(PhGetThreadIoPriority(threadHandle, &ioPriorityInteger)) && ioPriorityInteger < MaxIoPriorityTypes) { ioPriority = PhIoPriorityHintNames[ioPriorityInteger]; } if (NT_SUCCESS(PhGetThreadPagePriority(threadHandle, &pagePriorityInteger)) && pagePriorityInteger <= MEMORY_PRIORITY_NORMAL) { pagePriority = PhPagePriorityNames[pagePriorityInteger]; } if (NT_SUCCESS(NtQueryInformationThread(threadHandle, ThreadIdealProcessorEx, &idealProcessorNumber, sizeof(PROCESSOR_NUMBER), NULL))) { PH_FORMAT format[3]; PhInitFormatU(&format[0], idealProcessorNumber.Group); PhInitFormatC(&format[1], ':'); PhInitFormatU(&format[2], idealProcessorNumber.Number); PhFormatToBuffer(format, 3, idealProcessor, sizeof(idealProcessor), NULL); } if (threadItem->WaitReason == Suspended && NT_SUCCESS(NtQueryInformationThread(threadHandle, ThreadSuspendCount, &suspendCount, sizeof(ULONG), NULL))) { PH_FORMAT format[4]; PhInitFormatSR(&format[0], state->sr); PhInitFormatS(&format[1], L" ("); PhInitFormatU(&format[2], suspendCount); PhInitFormatS(&format[3], L")"); state = PH_AUTO(PhFormat(format, 4, 30)); } NtClose(threadHandle); } } if (Force) { // These don't change... SetDlgItemText(hwndDlg, IDC_STARTMODULE, PhGetStringOrEmpty(startModule)); EnableWindow(GetDlgItem(hwndDlg, IDC_OPENSTARTMODULE), !!startModule); SetDlgItemText(hwndDlg, IDC_STARTED, PhGetStringOrDefault(started, L"N/A")); } SetDlgItemText(hwndDlg, IDC_KERNELTIME, kernelTime); SetDlgItemText(hwndDlg, IDC_USERTIME, userTime); SetDlgItemText(hwndDlg, IDC_CONTEXTSWITCHES, PhGetStringOrDefault(contextSwitches, L"N/A")); SetDlgItemText(hwndDlg, IDC_CYCLES, PhGetStringOrDefault(cycles, L"N/A")); SetDlgItemText(hwndDlg, IDC_STATE, PhGetStringOrDefault(state, L"N/A")); SetDlgItemText(hwndDlg, IDC_PRIORITY, priority); SetDlgItemText(hwndDlg, IDC_BASEPRIORITY, basePriority); SetDlgItemText(hwndDlg, IDC_IOPRIORITY, ioPriority); SetDlgItemText(hwndDlg, IDC_PAGEPRIORITY, pagePriority); SetDlgItemText(hwndDlg, IDC_IDEALPROCESSOR, idealProcessor); }
/** * Loads plugins from the default plugins directory. */ VOID PhLoadPlugins( VOID ) { HANDLE pluginsDirectoryHandle; PPH_STRING pluginsDirectory; pluginsDirectory = PhGetStringSetting(L"PluginsDirectory"); if (RtlDetermineDosPathNameType_U(pluginsDirectory->Buffer) == RtlPathTypeRelative) { // Not absolute. Make sure it is. PluginsDirectory = PhConcatStrings(4, PhApplicationDirectory->Buffer, L"\\", pluginsDirectory->Buffer, L"\\"); PhDereferenceObject(pluginsDirectory); } else { PluginsDirectory = pluginsDirectory; } if (NT_SUCCESS(PhCreateFileWin32( &pluginsDirectoryHandle, PluginsDirectory->Buffer, FILE_GENERIC_READ, 0, FILE_SHARE_READ, FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ))) { UNICODE_STRING pattern = RTL_CONSTANT_STRING(L"*.dll"); PhEnumDirectoryFile(pluginsDirectoryHandle, &pattern, EnumPluginsDirectoryCallback, NULL); NtClose(pluginsDirectoryHandle); } // Handle load errors. // In certain startup modes we want to ignore all plugin load errors. if (LoadErrors && LoadErrors->Count != 0 && !PhStartupParameters.PhSvc) { PH_STRING_BUILDER sb; ULONG i; PPHP_PLUGIN_LOAD_ERROR loadError; PPH_STRING baseName; PhInitializeStringBuilder(&sb, 100); PhAppendStringBuilder2(&sb, L"Unable to load the following plugin(s):\n\n"); for (i = 0; i < LoadErrors->Count; i++) { loadError = LoadErrors->Items[i]; baseName = PhGetBaseName(loadError->FileName); PhAppendFormatStringBuilder(&sb, L"%s: %s\n", baseName->Buffer, PhGetStringOrDefault(loadError->ErrorMessage, L"An unknown error occurred.")); PhDereferenceObject(baseName); } PhAppendStringBuilder2(&sb, L"\nDo you want to disable the above plugin(s)?"); if (PhShowMessage( NULL, MB_ICONERROR | MB_YESNO, sb.String->Buffer ) == IDYES) { ULONG i; for (i = 0; i < LoadErrors->Count; i++) { loadError = LoadErrors->Items[i]; baseName = PhGetBaseName(loadError->FileName); PhSetPluginDisabled(&baseName->sr, TRUE); PhDereferenceObject(baseName); } } PhDeleteStringBuilder(&sb); } // When we loaded settings before, we didn't know about plugin settings, so they // went into the ignored settings list. Now that they've had a chance to add // settings, we should scan the ignored settings list and move the settings to // the right places. if (PhSettingsFileName) PhConvertIgnoredSettings(); PhpExecuteCallbackForAllPlugins(PluginCallbackLoad, TRUE); }
INT_PTR CALLBACK DotNetAsmPageDlgProc( __in HWND hwndDlg, __in UINT uMsg, __in WPARAM wParam, __in LPARAM lParam ) { LPPROPSHEETPAGE propSheetPage; PPH_PROCESS_PROPPAGECONTEXT propPageContext; PPH_PROCESS_ITEM processItem; PASMPAGE_CONTEXT context; if (PhPropPageDlgProcHeader(hwndDlg, uMsg, lParam, &propSheetPage, &propPageContext, &processItem)) { context = propPageContext->Context; } else { return FALSE; } switch (uMsg) { case WM_INITDIALOG: { ULONG result = 0; PPH_STRING settings; LARGE_INTEGER timeout; HWND tnHandle; context = PhAllocate(sizeof(ASMPAGE_CONTEXT)); memset(context, 0, sizeof(ASMPAGE_CONTEXT)); propPageContext->Context = context; context->WindowHandle = hwndDlg; context->ProcessItem = processItem; context->ClrVersions = GetProcessDotNetVersions(processItem->ProcessId); context->NodeList = PhCreateList(64); context->NodeRootList = PhCreateList(2); tnHandle = GetDlgItem(hwndDlg, IDC_LIST); context->TnHandle = tnHandle; TreeNew_SetRedraw(tnHandle, FALSE); TreeNew_SetCallback(tnHandle, DotNetAsmTreeNewCallback, context); TreeNew_SetExtendedFlags(tnHandle, TN_FLAG_ITEM_DRAG_SELECT, TN_FLAG_ITEM_DRAG_SELECT); PhSetControlTheme(tnHandle, L"explorer"); SendMessage(TreeNew_GetTooltips(tnHandle), TTM_SETMAXTIPWIDTH, 0, MAXSHORT); PhAddTreeNewColumn(tnHandle, DNATNC_STRUCTURE, TRUE, L"Structure", 240, PH_ALIGN_LEFT, -2, 0); PhAddTreeNewColumn(tnHandle, DNATNC_ID, TRUE, L"ID", 50, PH_ALIGN_RIGHT, 0, DT_RIGHT); PhAddTreeNewColumn(tnHandle, DNATNC_FLAGS, TRUE, L"Flags", 120, PH_ALIGN_LEFT, 1, 0); PhAddTreeNewColumn(tnHandle, DNATNC_PATH, TRUE, L"Path", 600, PH_ALIGN_LEFT, 2, 0); // don't use path ellipsis - the user already has the base file name PhAddTreeNewColumn(tnHandle, DNATNC_NATIVEPATH, TRUE, L"Native Image Path", 600, PH_ALIGN_LEFT, 3, 0); settings = PhGetStringSetting(SETTING_NAME_ASM_TREE_LIST_COLUMNS); PhCmLoadSettings(tnHandle, &settings->sr); PhDereferenceObject(settings); SetCursor(LoadCursor(NULL, IDC_WAIT)); if (context->ClrVersions & CLR_VERSION_1_0) { AddFakeClrNode(context, L"CLR v1.0.3705"); // what PE displays } if (context->ClrVersions & CLR_VERSION_1_1) { AddFakeClrNode(context, L"CLR v1.1.4322"); } timeout.QuadPart = -10 * PH_TIMEOUT_SEC; if (context->ClrVersions & CLR_VERSION_2_0) { context->ClrV2Node = AddFakeClrNode(context, L"CLR v2.0.50727"); result = UpdateDotNetTraceInfoWithTimeout(context, TRUE, &timeout); } if (context->ClrVersions & CLR_VERSION_4_ABOVE) { result = UpdateDotNetTraceInfoWithTimeout(context, FALSE, &timeout); } TreeNew_NodesStructured(tnHandle); TreeNew_SetRedraw(tnHandle, TRUE); SetCursor(LoadCursor(NULL, IDC_ARROW)); if (result != 0) { ShowWindow(tnHandle, SW_HIDE); ShowWindow(GetDlgItem(hwndDlg, IDC_ERROR), SW_SHOW); if (result == ERROR_ACCESS_DENIED) { SetDlgItemText(hwndDlg, IDC_ERROR, L"Unable to start the event tracing session. Make sure Process Hacker is running with administrative privileges."); } else { SetDlgItemText(hwndDlg, IDC_ERROR, PhaConcatStrings2(L"Unable to start the event tracing session: %s", PhGetStringOrDefault(PhGetWin32Message(result), L"Unknown error"))->Buffer); } } } break; case WM_DESTROY: { PPH_STRING settings; ULONG i; settings = PhCmSaveSettings(context->TnHandle); PhSetStringSetting2(SETTING_NAME_ASM_TREE_LIST_COLUMNS, &settings->sr); PhDereferenceObject(settings); for (i = 0; i < context->NodeList->Count; i++) DestroyNode(context->NodeList->Items[i]); PhDereferenceObject(context->NodeList); PhDereferenceObject(context->NodeRootList); PhFree(context); PhPropPageDlgProcDestroy(hwndDlg); } break; case WM_SHOWWINDOW: { PPH_LAYOUT_ITEM dialogItem; if (dialogItem = PhBeginPropPageLayout(hwndDlg, propPageContext)) { PhAddPropPageLayoutItem(hwndDlg, GetDlgItem(hwndDlg, IDC_LIST), dialogItem, PH_ANCHOR_ALL); PhAddPropPageLayoutItem(hwndDlg, GetDlgItem(hwndDlg, IDC_ERROR), dialogItem, PH_ANCHOR_LEFT | PH_ANCHOR_TOP | PH_ANCHOR_RIGHT | PH_LAYOUT_FORCE_INVALIDATE); PhEndPropPageLayout(hwndDlg, propPageContext); } } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case ID_COPY: { PPH_STRING text; text = PhGetTreeNewText(context->TnHandle, DNATNC_MAXIMUM); PhSetClipboardStringEx(context->TnHandle, text->Buffer, text->Length); PhDereferenceObject(text); } break; } } break; } return FALSE; }
INT_PTR CALLBACK EspServiceOtherDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PSERVICE_OTHER_CONTEXT context; if (uMsg == WM_INITDIALOG) { context = PhAllocate(sizeof(SERVICE_OTHER_CONTEXT)); memset(context, 0, sizeof(SERVICE_OTHER_CONTEXT)); SetProp(hwndDlg, L"Context", (HANDLE)context); } else { context = (PSERVICE_OTHER_CONTEXT)GetProp(hwndDlg, L"Context"); if (uMsg == WM_DESTROY) RemoveProp(hwndDlg, L"Context"); } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { NTSTATUS status; LPPROPSHEETPAGE propSheetPage = (LPPROPSHEETPAGE)lParam; PPH_SERVICE_ITEM serviceItem = (PPH_SERVICE_ITEM)propSheetPage->lParam; HWND privilegesLv; context->ServiceItem = serviceItem; context->PrivilegesLv = privilegesLv = GetDlgItem(hwndDlg, IDC_PRIVILEGES); PhSetListViewStyle(privilegesLv, FALSE, TRUE); PhSetControlTheme(privilegesLv, L"explorer"); PhAddListViewColumn(privilegesLv, 0, 0, 0, LVCFMT_LEFT, 140, L"Name"); PhAddListViewColumn(privilegesLv, 1, 1, 1, LVCFMT_LEFT, 220, L"Display Name"); PhSetExtendedListView(privilegesLv); context->PrivilegeList = PhCreateList(32); if (context->ServiceItem->Type == SERVICE_KERNEL_DRIVER || context->ServiceItem->Type == SERVICE_FILE_SYSTEM_DRIVER) { // Drivers don't support required privileges. EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); } EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), FALSE); PhAddComboBoxStrings(GetDlgItem(hwndDlg, IDC_SIDTYPE), EspServiceSidTypeStrings, sizeof(EspServiceSidTypeStrings) / sizeof(PWSTR)); PhAddComboBoxStrings(GetDlgItem(hwndDlg, IDC_PROTECTION), EspServiceLaunchProtectedStrings, sizeof(EspServiceLaunchProtectedStrings) / sizeof(PWSTR)); if (WindowsVersion < WINDOWS_8_1) EnableWindow(GetDlgItem(hwndDlg, IDC_PROTECTION), FALSE); SetDlgItemText(hwndDlg, IDC_SERVICESID, PhGetStringOrDefault(PH_AUTO(EspGetServiceSidString(&serviceItem->Name->sr)), L"N/A")); status = EspLoadOtherInfo(hwndDlg, context); if (!NT_SUCCESS(status)) { PhShowWarning(hwndDlg, L"Unable to query service information: %s", ((PPH_STRING)PH_AUTO(PhGetNtMessage(status)))->Buffer); } context->Ready = TRUE; } break; case WM_DESTROY: { if (context->PrivilegeList) { PhDereferenceObjects(context->PrivilegeList->Items, context->PrivilegeList->Count); PhDereferenceObject(context->PrivilegeList); } PhFree(context); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_ADD: { NTSTATUS status; LSA_HANDLE policyHandle; LSA_ENUMERATION_HANDLE enumContext; PPOLICY_PRIVILEGE_DEFINITION buffer; ULONG count; ULONG i; PPH_LIST choices; PPH_STRING selectedChoice = NULL; choices = PH_AUTO(PhCreateList(100)); if (!NT_SUCCESS(status = PhOpenLsaPolicy(&policyHandle, POLICY_VIEW_LOCAL_INFORMATION, NULL))) { PhShowStatus(hwndDlg, L"Unable to open LSA policy", status, 0); break; } enumContext = 0; while (TRUE) { status = LsaEnumeratePrivileges( policyHandle, &enumContext, &buffer, 0x100, &count ); if (status == STATUS_NO_MORE_ENTRIES) break; if (!NT_SUCCESS(status)) break; for (i = 0; i < count; i++) { PhAddItemList(choices, PhaCreateStringEx(buffer[i].Name.Buffer, buffer[i].Name.Length)->Buffer); } LsaFreeMemory(buffer); } LsaClose(policyHandle); qsort(choices->Items, choices->Count, sizeof(PWSTR), PrivilegeNameCompareFunction); while (PhaChoiceDialog( hwndDlg, L"Add privilege", L"Select a privilege to add:", (PWSTR *)choices->Items, choices->Count, NULL, PH_CHOICE_DIALOG_CHOICE, &selectedChoice, NULL, NULL )) { BOOLEAN found = FALSE; PPH_STRING privilegeString; INT lvItemIndex; PPH_STRING displayName; // Check for duplicates. for (i = 0; i < context->PrivilegeList->Count; i++) { if (PhEqualString(context->PrivilegeList->Items[i], selectedChoice, FALSE)) { found = TRUE; break; } } if (found) { if (PhShowMessage( hwndDlg, MB_OKCANCEL | MB_ICONERROR, L"The selected privilege has already been added." ) == IDOK) { continue; } else { break; } } PhSetReference(&privilegeString, selectedChoice); PhAddItemList(context->PrivilegeList, privilegeString); lvItemIndex = PhAddListViewItem(context->PrivilegesLv, MAXINT, privilegeString->Buffer, privilegeString); if (PhLookupPrivilegeDisplayName(&privilegeString->sr, &displayName)) { PhSetListViewSubItem(context->PrivilegesLv, lvItemIndex, 1, displayName->Buffer); PhDereferenceObject(displayName); } ExtendedListView_SortItems(context->PrivilegesLv); context->Dirty = TRUE; context->RequiredPrivilegesValid = TRUE; break; } } break; case IDC_REMOVE: { INT lvItemIndex; PPH_STRING privilegeString; ULONG index; lvItemIndex = ListView_GetNextItem(context->PrivilegesLv, -1, LVNI_SELECTED); if (lvItemIndex != -1 && PhGetListViewItemParam(context->PrivilegesLv, lvItemIndex, (PVOID *)&privilegeString)) { index = PhFindItemList(context->PrivilegeList, privilegeString); if (index != -1) { PhDereferenceObject(privilegeString); PhRemoveItemList(context->PrivilegeList, index); PhRemoveListViewItem(context->PrivilegesLv, lvItemIndex); context->Dirty = TRUE; context->RequiredPrivilegesValid = TRUE; } } } break; } switch (HIWORD(wParam)) { case EN_CHANGE: case CBN_SELCHANGE: { if (context->Ready) { context->Dirty = TRUE; switch (LOWORD(wParam)) { case IDC_PRESHUTDOWNTIMEOUT: context->PreshutdownTimeoutValid = TRUE; break; case IDC_SIDTYPE: context->SidTypeValid = TRUE; break; case IDC_PROTECTION: context->LaunchProtectedValid = TRUE; break; } } } break; } } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case PSN_KILLACTIVE: { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE); } return TRUE; case PSN_APPLY: { SC_HANDLE serviceHandle = NULL; ULONG win32Result = 0; BOOLEAN connectedToPhSvc = FALSE; PPH_STRING launchProtectedString; ULONG launchProtected; SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); launchProtectedString = PH_AUTO(PhGetWindowText(GetDlgItem(hwndDlg, IDC_PROTECTION))); launchProtected = EspGetServiceLaunchProtectedInteger(launchProtectedString->Buffer); if (context->LaunchProtectedValid && launchProtected != 0 && launchProtected != context->OriginalLaunchProtected) { if (PhShowMessage( hwndDlg, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2, L"Setting service protection will prevent the service from being controlled, modified, or deleted. Do you want to continue?" ) == IDNO) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID); return TRUE; } } if (context->Dirty) { SERVICE_PRESHUTDOWN_INFO preshutdownInfo; SERVICE_REQUIRED_PRIVILEGES_INFO requiredPrivilegesInfo; SERVICE_SID_INFO sidInfo; SERVICE_LAUNCH_PROTECTED_INFO launchProtectedInfo; if (!(serviceHandle = PhOpenService(context->ServiceItem->Name->Buffer, SERVICE_CHANGE_CONFIG))) { win32Result = GetLastError(); if (win32Result == ERROR_ACCESS_DENIED && !PhElevated) { // Elevate using phsvc. if (PhUiConnectToPhSvc(hwndDlg, FALSE)) { win32Result = 0; connectedToPhSvc = TRUE; } else { // User cancelled elevation. win32Result = ERROR_CANCELLED; goto Done; } } else { goto Done; } } if (context->PreshutdownTimeoutValid) { preshutdownInfo.dwPreshutdownTimeout = GetDlgItemInt(hwndDlg, IDC_PRESHUTDOWNTIMEOUT, NULL, FALSE); if (!EspChangeServiceConfig2(context->ServiceItem->Name->Buffer, serviceHandle, SERVICE_CONFIG_PRESHUTDOWN_INFO, &preshutdownInfo)) { win32Result = GetLastError(); } } if (context->RequiredPrivilegesValid) { PH_STRING_BUILDER sb; ULONG i; PhInitializeStringBuilder(&sb, 100); for (i = 0; i < context->PrivilegeList->Count; i++) { PhAppendStringBuilder(&sb, &((PPH_STRING)context->PrivilegeList->Items[i])->sr); PhAppendCharStringBuilder(&sb, 0); } requiredPrivilegesInfo.pmszRequiredPrivileges = sb.String->Buffer; if (win32Result == 0 && !EspChangeServiceConfig2(context->ServiceItem->Name->Buffer, serviceHandle, SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO, &requiredPrivilegesInfo)) { win32Result = GetLastError(); } PhDeleteStringBuilder(&sb); } if (context->SidTypeValid) { PPH_STRING sidTypeString; sidTypeString = PH_AUTO(PhGetWindowText(GetDlgItem(hwndDlg, IDC_SIDTYPE))); sidInfo.dwServiceSidType = EspGetServiceSidTypeInteger(sidTypeString->Buffer); if (win32Result == 0 && !EspChangeServiceConfig2(context->ServiceItem->Name->Buffer, serviceHandle, SERVICE_CONFIG_SERVICE_SID_INFO, &sidInfo)) { win32Result = GetLastError(); } } if (context->LaunchProtectedValid) { launchProtectedInfo.dwLaunchProtected = launchProtected; if (!EspChangeServiceConfig2(context->ServiceItem->Name->Buffer, serviceHandle, SERVICE_CONFIG_LAUNCH_PROTECTED, &launchProtectedInfo)) { // For now, ignore errors here. // win32Result = GetLastError(); } } Done: if (connectedToPhSvc) PhUiDisconnectFromPhSvc(); if (serviceHandle) CloseServiceHandle(serviceHandle); if (win32Result != 0) { if (win32Result == ERROR_CANCELLED || PhShowMessage( hwndDlg, MB_ICONERROR | MB_RETRYCANCEL, L"Unable to change service information: %s", ((PPH_STRING)PH_AUTO(PhGetWin32Message(win32Result)))->Buffer ) == IDRETRY) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID); } } } return TRUE; } break; case LVN_ITEMCHANGED: { if (header->hwndFrom == context->PrivilegesLv) { EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), ListView_GetSelectedCount(context->PrivilegesLv) == 1); } } break; } } break; } return FALSE; }
VOID PhpUpdateProcessStatistics( _In_ HWND hwndDlg, _In_ PPH_PROCESS_ITEM ProcessItem, _In_ PPH_STATISTICS_CONTEXT Context ) { WCHAR timeSpan[PH_TIMESPAN_STR_LEN_1]; SetDlgItemInt(hwndDlg, IDC_ZPRIORITY_V, ProcessItem->BasePriority, TRUE); // priority PhPrintTimeSpan(timeSpan, ProcessItem->KernelTime.QuadPart, PH_TIMESPAN_HMSM); // kernel time SetDlgItemText(hwndDlg, IDC_ZKERNELTIME_V, timeSpan); PhPrintTimeSpan(timeSpan, ProcessItem->UserTime.QuadPart, PH_TIMESPAN_HMSM); // user time SetDlgItemText(hwndDlg, IDC_ZUSERTIME_V, timeSpan); PhPrintTimeSpan(timeSpan, ProcessItem->KernelTime.QuadPart + ProcessItem->UserTime.QuadPart, PH_TIMESPAN_HMSM); // total time SetDlgItemText(hwndDlg, IDC_ZTOTALTIME_V, timeSpan); SetDlgItemText(hwndDlg, IDC_ZPRIVATEBYTES_V, PhaFormatSize(ProcessItem->VmCounters.PagefileUsage, -1)->Buffer); // private bytes (same as PrivateUsage) SetDlgItemText(hwndDlg, IDC_ZPEAKPRIVATEBYTES_V, PhaFormatSize(ProcessItem->VmCounters.PeakPagefileUsage, -1)->Buffer); // peak private bytes SetDlgItemText(hwndDlg, IDC_ZVIRTUALSIZE_V, PhaFormatSize(ProcessItem->VmCounters.VirtualSize, -1)->Buffer); // virtual size SetDlgItemText(hwndDlg, IDC_ZPEAKVIRTUALSIZE_V, PhaFormatSize(ProcessItem->VmCounters.PeakVirtualSize, -1)->Buffer); // peak virtual size SetDlgItemText(hwndDlg, IDC_ZPAGEFAULTS_V, PhaFormatUInt64(ProcessItem->VmCounters.PageFaultCount, TRUE)->Buffer); // page faults SetDlgItemText(hwndDlg, IDC_ZWORKINGSET_V, PhaFormatSize(ProcessItem->VmCounters.WorkingSetSize, -1)->Buffer); // working set SetDlgItemText(hwndDlg, IDC_ZPEAKWORKINGSET_V, PhaFormatSize(ProcessItem->VmCounters.PeakWorkingSetSize, -1)->Buffer); // peak working set SetDlgItemText(hwndDlg, IDC_ZIOREADS_V, PhaFormatUInt64(ProcessItem->IoCounters.ReadOperationCount, TRUE)->Buffer); // reads SetDlgItemText(hwndDlg, IDC_ZIOREADBYTES_V, PhaFormatSize(ProcessItem->IoCounters.ReadTransferCount, -1)->Buffer); // read bytes SetDlgItemText(hwndDlg, IDC_ZIOWRITES_V, PhaFormatUInt64(ProcessItem->IoCounters.WriteOperationCount, TRUE)->Buffer); // writes SetDlgItemText(hwndDlg, IDC_ZIOWRITEBYTES_V, PhaFormatSize(ProcessItem->IoCounters.WriteTransferCount, -1)->Buffer); // write bytes SetDlgItemText(hwndDlg, IDC_ZIOOTHER_V, PhaFormatUInt64(ProcessItem->IoCounters.OtherOperationCount, TRUE)->Buffer); // other SetDlgItemText(hwndDlg, IDC_ZIOOTHERBYTES_V, PhaFormatSize(ProcessItem->IoCounters.OtherTransferCount, -1)->Buffer); // read bytes SetDlgItemText(hwndDlg, IDC_ZHANDLES_V, PhaFormatUInt64(ProcessItem->NumberOfHandles, TRUE)->Buffer); // handles // Optional information if (!PH_IS_FAKE_PROCESS_ID(ProcessItem->ProcessId)) { PPH_STRING peakHandles = NULL; PPH_STRING gdiHandles = NULL; PPH_STRING userHandles = NULL; PPH_STRING cycles = NULL; ULONG pagePriority = -1; IO_PRIORITY_HINT ioPriority = -1; PPH_STRING privateWs = NULL; PPH_STRING shareableWs = NULL; PPH_STRING sharedWs = NULL; BOOLEAN gotCycles = FALSE; BOOLEAN gotWsCounters = FALSE; if (ProcessItem->QueryHandle) { ULONG64 cycleTime; if (WindowsVersion >= WINDOWS_7) { PROCESS_HANDLE_INFORMATION handleInfo; if (NT_SUCCESS(NtQueryInformationProcess( ProcessItem->QueryHandle, ProcessHandleCount, &handleInfo, sizeof(PROCESS_HANDLE_INFORMATION), NULL ))) { peakHandles = PhaFormatUInt64(handleInfo.HandleCountHighWatermark, TRUE); } } gdiHandles = PhaFormatUInt64(GetGuiResources(ProcessItem->QueryHandle, GR_GDIOBJECTS), TRUE); // GDI handles userHandles = PhaFormatUInt64(GetGuiResources(ProcessItem->QueryHandle, GR_USEROBJECTS), TRUE); // USER handles if (WINDOWS_HAS_CYCLE_TIME && NT_SUCCESS(PhGetProcessCycleTime(ProcessItem->QueryHandle, &cycleTime))) { cycles = PhaFormatUInt64(cycleTime, TRUE); gotCycles = TRUE; } if (WindowsVersion >= WINDOWS_VISTA) { PhGetProcessPagePriority(ProcessItem->QueryHandle, &pagePriority); PhGetProcessIoPriority(ProcessItem->QueryHandle, &ioPriority); } } if (Context->ProcessHandle) { PH_PROCESS_WS_COUNTERS wsCounters; if (NT_SUCCESS(PhGetProcessWsCounters(Context->ProcessHandle, &wsCounters))) { privateWs = PhaFormatSize((ULONG64)wsCounters.NumberOfPrivatePages * PAGE_SIZE, -1); shareableWs = PhaFormatSize((ULONG64)wsCounters.NumberOfShareablePages * PAGE_SIZE, -1); sharedWs = PhaFormatSize((ULONG64)wsCounters.NumberOfSharedPages * PAGE_SIZE, -1); gotWsCounters = TRUE; } } if (WindowsVersion >= WINDOWS_7) { if (!gotCycles) cycles = PhaFormatUInt64(ProcessItem->CycleTimeDelta.Value, TRUE); if (!gotWsCounters) privateWs = PhaFormatSize(ProcessItem->WorkingSetPrivateSize, -1); } if (WindowsVersion >= WINDOWS_7) SetDlgItemText(hwndDlg, IDC_ZPEAKHANDLES_V, PhGetStringOrDefault(peakHandles, L"Unknown")); else SetDlgItemText(hwndDlg, IDC_ZPEAKHANDLES_V, L"N/A"); SetDlgItemText(hwndDlg, IDC_ZGDIHANDLES_V, PhGetStringOrDefault(gdiHandles, L"Unknown")); SetDlgItemText(hwndDlg, IDC_ZUSERHANDLES_V, PhGetStringOrDefault(userHandles, L"Unknown")); SetDlgItemText(hwndDlg, IDC_ZCYCLES_V, PhGetStringOrDefault(cycles, WINDOWS_HAS_CYCLE_TIME ? L"Unknown" : L"N/A")); if (WindowsVersion >= WINDOWS_VISTA) { if (pagePriority != -1 && pagePriority <= MEMORY_PRIORITY_NORMAL) SetDlgItemText(hwndDlg, IDC_ZPAGEPRIORITY_V, PhPagePriorityNames[pagePriority]); else SetDlgItemText(hwndDlg, IDC_ZPAGEPRIORITY_V, L"Unknown"); if (ioPriority != -1 && ioPriority < MaxIoPriorityTypes) SetDlgItemText(hwndDlg, IDC_ZIOPRIORITY_V, PhIoPriorityHintNames[ioPriority]); else SetDlgItemText(hwndDlg, IDC_ZIOPRIORITY_V, L"Unknown"); } else { SetDlgItemText(hwndDlg, IDC_ZPAGEPRIORITY_V, L"N/A"); SetDlgItemText(hwndDlg, IDC_ZIOPRIORITY_V, L"N/A"); } SetDlgItemText(hwndDlg, IDC_ZPRIVATEWS_V, PhGetStringOrDefault(privateWs, L"Unknown")); SetDlgItemText(hwndDlg, IDC_ZSHAREABLEWS_V, PhGetStringOrDefault(shareableWs, L"Unknown")); SetDlgItemText(hwndDlg, IDC_ZSHAREDWS_V, PhGetStringOrDefault(sharedWs, L"Unknown")); } else { SetDlgItemText(hwndDlg, IDC_ZPEAKHANDLES_V, L"N/A"); SetDlgItemText(hwndDlg, IDC_ZGDIHANDLES_V, L"N/A"); SetDlgItemText(hwndDlg, IDC_ZUSERHANDLES_V, L"N/A"); SetDlgItemText(hwndDlg, IDC_ZCYCLES_V, L"N/A"); SetDlgItemText(hwndDlg, IDC_ZPAGEPRIORITY_V, L"N/A"); SetDlgItemText(hwndDlg, IDC_ZIOPRIORITY_V, L"N/A"); SetDlgItemText(hwndDlg, IDC_ZPRIVATEWS_V, L"N/A"); SetDlgItemText(hwndDlg, IDC_ZSHAREABLEWS_V, L"N/A"); SetDlgItemText(hwndDlg, IDC_ZSHAREDWS_V, L"N/A"); } }
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; }
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); }