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; }
BOOLEAN ProcessTreeFilterCallback( _In_ PPH_TREENEW_NODE Node, _In_opt_ PVOID Context ) { PPH_PROCESS_NODE processNode = (PPH_PROCESS_NODE)Node; if (PhIsNullOrEmptyString(SearchboxText)) return TRUE; if (!PhIsNullOrEmptyString(processNode->ProcessItem->ProcessName)) { if (WordMatchStringRef(&processNode->ProcessItem->ProcessName->sr)) return TRUE; } if (!PhIsNullOrEmptyString(processNode->ProcessItem->FileName)) { if (WordMatchStringRef(&processNode->ProcessItem->FileName->sr)) return TRUE; } if (!PhIsNullOrEmptyString(processNode->ProcessItem->CommandLine)) { if (WordMatchStringRef(&processNode->ProcessItem->CommandLine->sr)) return TRUE; } if (!PhIsNullOrEmptyString(processNode->ProcessItem->VersionInfo.CompanyName)) { if (WordMatchStringRef(&processNode->ProcessItem->VersionInfo.CompanyName->sr)) return TRUE; } if (!PhIsNullOrEmptyString(processNode->ProcessItem->VersionInfo.FileDescription)) { if (WordMatchStringRef(&processNode->ProcessItem->VersionInfo.FileDescription->sr)) return TRUE; } if (!PhIsNullOrEmptyString(processNode->ProcessItem->VersionInfo.FileVersion)) { if (WordMatchStringRef(&processNode->ProcessItem->VersionInfo.FileVersion->sr)) return TRUE; } if (!PhIsNullOrEmptyString(processNode->ProcessItem->VersionInfo.ProductName)) { if (WordMatchStringRef(&processNode->ProcessItem->VersionInfo.ProductName->sr)) return TRUE; } if (!PhIsNullOrEmptyString(processNode->ProcessItem->UserName)) { if (WordMatchStringRef(&processNode->ProcessItem->UserName->sr)) return TRUE; } if (processNode->ProcessItem->IntegrityString) { if (WordMatchStringZ(processNode->ProcessItem->IntegrityString)) return TRUE; } if (!PhIsNullOrEmptyString(processNode->ProcessItem->JobName)) { if (WordMatchStringRef(&processNode->ProcessItem->JobName->sr)) return TRUE; } if (!PhIsNullOrEmptyString(processNode->ProcessItem->VerifySignerName)) { if (WordMatchStringRef(&processNode->ProcessItem->VerifySignerName->sr)) return TRUE; } if (processNode->ProcessItem->ProcessIdString[0]) { if (WordMatchStringZ(processNode->ProcessItem->ProcessIdString)) return TRUE; } if (processNode->ProcessItem->ParentProcessIdString[0]) { if (WordMatchStringZ(processNode->ProcessItem->ParentProcessIdString)) return TRUE; } if (processNode->ProcessItem->SessionIdString[0]) { if (WordMatchStringZ(processNode->ProcessItem->SessionIdString)) return TRUE; } if (!PhIsNullOrEmptyString(processNode->ProcessItem->PackageFullName)) { if (WordMatchStringRef(&processNode->ProcessItem->PackageFullName->sr)) return TRUE; } if (WordMatchStringZ(PhGetProcessPriorityClassString(processNode->ProcessItem->PriorityClass))) { return TRUE; } if (processNode->ProcessItem->VerifyResult != VrUnknown) { switch (processNode->ProcessItem->VerifyResult) { case VrNoSignature: if (WordMatchStringZ(L"NoSignature")) return TRUE; break; case VrTrusted: if (WordMatchStringZ(L"Trusted")) return TRUE; break; case VrExpired: if (WordMatchStringZ(L"Expired")) return TRUE; break; case VrRevoked: if (WordMatchStringZ(L"Revoked")) return TRUE; break; case VrDistrust: if (WordMatchStringZ(L"Distrust")) return TRUE; break; case VrSecuritySettings: if (WordMatchStringZ(L"SecuritySettings")) return TRUE; break; case VrBadSignature: if (WordMatchStringZ(L"BadSignature")) return TRUE; break; default: if (WordMatchStringZ(L"Unknown")) return TRUE; break; } } if (processNode->ProcessItem->ElevationType != TokenElevationTypeDefault) { switch (processNode->ProcessItem->ElevationType) { case TokenElevationTypeLimited: if (WordMatchStringZ(L"Limited")) return TRUE; break; case TokenElevationTypeFull: if (WordMatchStringZ(L"Full")) return TRUE; break; default: if (WordMatchStringZ(L"Unknown")) return TRUE; break; } } if (WordMatchStringZ(L"IsBeingDebugged") && processNode->ProcessItem->IsBeingDebugged) { return TRUE; } if (WordMatchStringZ(L"IsDotNet") && processNode->ProcessItem->IsDotNet) { return TRUE; } if (WordMatchStringZ(L"IsElevated") && processNode->ProcessItem->IsElevated) { return TRUE; } if (WordMatchStringZ(L"IsInJob") && processNode->ProcessItem->IsInJob) { return TRUE; } if (WordMatchStringZ(L"IsInSignificantJob") && processNode->ProcessItem->IsInSignificantJob) { return TRUE; } if (WordMatchStringZ(L"IsPacked") && processNode->ProcessItem->IsPacked) { return TRUE; } if (WordMatchStringZ(L"IsSuspended") && processNode->ProcessItem->IsSuspended) { return TRUE; } if (WordMatchStringZ(L"IsWow64") && processNode->ProcessItem->IsWow64) { return TRUE; } if (WordMatchStringZ(L"IsImmersive") && processNode->ProcessItem->IsImmersive) { return TRUE; } if (WordMatchStringZ(L"IsProtectedProcess") && processNode->ProcessItem->IsProtectedProcess) { return TRUE; } if (WordMatchStringZ(L"IsSecureProcess") && processNode->ProcessItem->IsSecureProcess) { return TRUE; } if (WordMatchStringZ(L"IsPicoProcess") && processNode->ProcessItem->IsSubsystemProcess) { return TRUE; } if (processNode->ProcessItem->ServiceList && processNode->ProcessItem->ServiceList->Count) { ULONG enumerationKey = 0; PPH_SERVICE_ITEM serviceItem; PPH_LIST serviceList; ULONG i; BOOLEAN matched = FALSE; // Copy the service list so we can search it. serviceList = PhCreateList(processNode->ProcessItem->ServiceList->Count); PhAcquireQueuedLockShared(&processNode->ProcessItem->ServiceListLock); while (PhEnumPointerList( processNode->ProcessItem->ServiceList, &enumerationKey, &serviceItem )) { PhReferenceObject(serviceItem); PhAddItemList(serviceList, serviceItem); } PhReleaseQueuedLockShared(&processNode->ProcessItem->ServiceListLock); for (i = 0; i < serviceList->Count; i++) { PPH_STRING serviceFileName = NULL; PPH_STRING serviceBinaryPath = NULL; serviceItem = serviceList->Items[i]; if (!PhIsNullOrEmptyString(serviceItem->Name)) { if (WordMatchStringRef(&serviceItem->Name->sr)) { matched = TRUE; break; } } if (!PhIsNullOrEmptyString(serviceItem->DisplayName)) { if (WordMatchStringRef(&serviceItem->DisplayName->sr)) { matched = TRUE; break; } } if (serviceItem->ProcessId) { if (WordMatchStringZ(serviceItem->ProcessIdString)) { matched = TRUE; break; } } if (NT_SUCCESS(QueryServiceFileName( &serviceItem->Name->sr, &serviceFileName, &serviceBinaryPath ))) { if (serviceFileName) { if (WordMatchStringRef(&serviceFileName->sr)) { matched = TRUE; } PhDereferenceObject(serviceFileName); } if (serviceBinaryPath) { if (WordMatchStringRef(&serviceBinaryPath->sr)) { matched = TRUE; } PhDereferenceObject(serviceBinaryPath); } if (matched) break; } } PhDereferenceObjects(serviceList->Items, serviceList->Count); PhDereferenceObject(serviceList); if (matched) return TRUE; } return FALSE; }