27 typedef struct _JOB_PAGE_CONTEXT
37 _In_ LPPROPSHEETPAGE ppsp
48 _In_ HWND ParentWindowHandle,
60 _In_ HWND ParentWindowHandle,
62 _In_opt_ PVOID Context,
66 PROPSHEETHEADER propSheetHeader = {
sizeof(propSheetHeader) };
67 HPROPSHEETPAGE pages[1];
69 propSheetHeader.dwFlags =
73 propSheetHeader.hwndParent = ParentWindowHandle;
74 propSheetHeader.pszCaption = Title ? Title : L
"Job";
75 propSheetHeader.nPages = 1;
76 propSheetHeader.nStartPage = 0;
77 propSheetHeader.phpage = pages;
81 PropertySheet(&propSheetHeader);
86 _In_opt_ PVOID Context,
87 _In_opt_ DLGPROC HookProc
90 HPROPSHEETPAGE propSheetPageHandle;
91 PROPSHEETPAGE propSheetPage;
96 jobPageContext->OpenObject = OpenObject;
97 jobPageContext->Context = Context;
98 jobPageContext->HookProc = HookProc;
100 memset(&propSheetPage, 0,
sizeof(PROPSHEETPAGE));
101 propSheetPage.dwSize =
sizeof(PROPSHEETPAGE);
102 propSheetPage.dwFlags = PSP_USECALLBACK;
103 propSheetPage.pszTemplate = MAKEINTRESOURCE(
IDD_OBJJOB);
105 propSheetPage.lParam = (LPARAM)jobPageContext;
108 propSheetPageHandle = CreatePropertySheetPage(&propSheetPage);
113 return propSheetPageHandle;
119 _In_ LPPROPSHEETPAGE ppsp
126 if (uMsg == PSPCB_ADDREF)
130 else if (uMsg == PSPCB_RELEASE)
146 hwndDlg, uMsg, wParam, lParam, L
"JobPageContext");
149 static VOID PhpAddLimit(
161 static VOID PhpAddJobProcesses(
163 _In_ HANDLE JobHandle
166 PJOBOBJECT_BASIC_PROCESS_ID_LIST processIdList;
179 for (i = 0; i < processIdList->NumberOfProcessIdsInList; i++)
181 clientId.
UniqueProcess = (HANDLE)processIdList->ProcessIdList[i];
205 if (jobPageContext->HookProc)
207 if (jobPageContext->HookProc(hwndDlg, uMsg, wParam, lParam))
231 SetDlgItemText(hwndDlg,
IDC_NAME, L
"Unknown");
236 jobPageContext->Context
240 JOBOBJECT_EXTENDED_LIMIT_INFORMATION extendedLimits;
241 JOBOBJECT_BASIC_UI_RESTRICTIONS basicUiRestrictions;
256 if (jobObjectName && jobObjectName->
Length == 0)
257 jobObjectName = NULL;
262 PhpAddJobProcesses(hwndDlg, jobHandle);
268 ULONG flags = extendedLimits.BasicLimitInformation.LimitFlags;
270 if (flags & JOB_OBJECT_LIMIT_ACTIVE_PROCESS)
273 PhPrintUInt32(value, extendedLimits.BasicLimitInformation.ActiveProcessLimit);
274 PhpAddLimit(limitsLv, L
"Active Processes", value);
277 if (flags & JOB_OBJECT_LIMIT_AFFINITY)
280 PhPrintPointer(value, (PVOID)extendedLimits.BasicLimitInformation.Affinity);
281 PhpAddLimit(limitsLv, L
"Affinity", value);
284 if (flags & JOB_OBJECT_LIMIT_BREAKAWAY_OK)
286 PhpAddLimit(limitsLv, L
"Breakaway OK", L
"Enabled");
289 if (flags & JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION)
291 PhpAddLimit(limitsLv, L
"Die on Unhandled Exception", L
"Enabled");
294 if (flags & JOB_OBJECT_LIMIT_JOB_MEMORY)
297 PhpAddLimit(limitsLv, L
"Job Memory", value->
Buffer);
301 if (flags & JOB_OBJECT_LIMIT_JOB_TIME)
304 PhPrintTimeSpan(value, extendedLimits.BasicLimitInformation.PerJobUserTimeLimit.QuadPart,
306 PhpAddLimit(limitsLv, L
"Job Time", value);
309 if (flags & JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE)
311 PhpAddLimit(limitsLv, L
"Kill on Job Close", L
"Enabled");
314 if (flags & JOB_OBJECT_LIMIT_PRIORITY_CLASS)
316 PhpAddLimit(limitsLv, L
"Priority Class",
320 if (flags & JOB_OBJECT_LIMIT_PROCESS_MEMORY)
323 PhpAddLimit(limitsLv, L
"Process Memory", value->
Buffer);
327 if (flags & JOB_OBJECT_LIMIT_PROCESS_TIME)
330 PhPrintTimeSpan(value, extendedLimits.BasicLimitInformation.PerProcessUserTimeLimit.QuadPart,
332 PhpAddLimit(limitsLv, L
"Process Time", value);
335 if (flags & JOB_OBJECT_LIMIT_SCHEDULING_CLASS)
338 PhPrintUInt32(value, extendedLimits.BasicLimitInformation.SchedulingClass);
339 PhpAddLimit(limitsLv, L
"Scheduling Class", value);
342 if (flags & JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK)
344 PhpAddLimit(limitsLv, L
"Silent Breakaway OK", L
"Enabled");
347 if (flags & JOB_OBJECT_LIMIT_WORKINGSET)
351 value =
PhFormatSize(extendedLimits.BasicLimitInformation.MinimumWorkingSetSize, -1);
352 PhpAddLimit(limitsLv, L
"Working Set Minimum", value->
Buffer);
355 value =
PhFormatSize(extendedLimits.BasicLimitInformation.MaximumWorkingSetSize, -1);
356 PhpAddLimit(limitsLv, L
"Working Set Maximum", value->
Buffer);
363 ULONG flags = basicUiRestrictions.UIRestrictionsClass;
365 if (flags & JOB_OBJECT_UILIMIT_DESKTOP)
366 PhpAddLimit(limitsLv, L
"Desktop", L
"Limited");
367 if (flags & JOB_OBJECT_UILIMIT_DISPLAYSETTINGS)
368 PhpAddLimit(limitsLv, L
"Display Settings", L
"Limited");
369 if (flags & JOB_OBJECT_UILIMIT_EXITWINDOWS)
370 PhpAddLimit(limitsLv, L
"Exit Windows", L
"Limited");
371 if (flags & JOB_OBJECT_UILIMIT_GLOBALATOMS)
372 PhpAddLimit(limitsLv, L
"Global Atoms", L
"Limited");
373 if (flags & JOB_OBJECT_UILIMIT_HANDLES)
374 PhpAddLimit(limitsLv, L
"Handles", L
"Limited");
375 if (flags & JOB_OBJECT_UILIMIT_READCLIPBOARD)
376 PhpAddLimit(limitsLv, L
"Read Clipboard", L
"Limited");
377 if (flags & JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS)
378 PhpAddLimit(limitsLv, L
"System Parameters", L
"Limited");
379 if (flags & JOB_OBJECT_UILIMIT_WRITECLIPBOARD)
380 PhpAddLimit(limitsLv, L
"Write Clipboard", L
"Limited");
389 switch (LOWORD(wParam))
397 L
"Terminating a job will terminate all processes assigned to it.",
404 if (
NT_SUCCESS(status = jobPageContext->OpenObject(
407 jobPageContext->Context
410 status = NtTerminateJobObject(jobHandle, STATUS_SUCCESS);
415 PhShowStatus(hwndDlg, L
"Unable to terminate the job", status, 0);
423 HANDLE processHandle;
428 L
"Select a process to add to the job permanently.",
438 if (
NT_SUCCESS(status = jobPageContext->OpenObject(
441 jobPageContext->Context
444 status = NtAssignProcessToJobObject(jobHandle, processHandle);
449 PhpAddJobProcesses(hwndDlg, jobHandle);
455 NtClose(processHandle);
461 PhShowStatus(hwndDlg, L
"Unable to add the process to the job", status, 0);
485 _In_ HWND ParentWindowHandle,
489 PROPSHEETHEADER propSheetHeader = {
sizeof(propSheetHeader) };
490 HPROPSHEETPAGE pages[2];
491 PROPSHEETPAGE statisticsPage;
494 ULONG numberOfAccessEntries;
496 propSheetHeader.dwFlags =
500 propSheetHeader.hwndParent = ParentWindowHandle;
501 propSheetHeader.pszCaption = L
"Job";
502 propSheetHeader.nPages = 2;
503 propSheetHeader.nStartPage = 0;
504 propSheetHeader.phpage = pages;
508 memset(&statisticsPage, 0,
sizeof(PROPSHEETPAGE));
509 statisticsPage.dwSize =
sizeof(PROPSHEETPAGE);
512 statisticsPage.lParam = (LPARAM)Context;
513 pages[0] = CreatePropertySheetPage(&statisticsPage);
517 stdObjectSecurity.
OpenObject = Context->OpenObject;
519 stdObjectSecurity.
Context = Context->Context;
529 numberOfAccessEntries
534 PropertySheet(&propSheetHeader);
537 static VOID PhpRefreshJobStatisticsInfo(
542 HANDLE jobHandle = NULL;
543 JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION basicAndIo;
544 JOBOBJECT_EXTENDED_LIMIT_INFORMATION extendedLimitInfo;
638 PhpRefreshJobStatisticsInfo(hwndDlg, jobPageContext);
646 PhpRefreshJobStatisticsInfo(hwndDlg, jobPageContext);