У меня есть служба, из которой я хочу создать ограниченный процесс для текущего зарегистрированного пользователя.Если я пытаюсь присвоить процесс объекту задания, для которого установлено JOB_OBJECT_UILIMIT_HANDLES, вызов завершается неудачно с ERROR_ACCESS_DENIED.Если я удаляю JOB_OBJECT_UILIMIT_HANDLES из настроек задания, все работает нормально.Это также работает, если я выполняю этот код в контексте пользователя.
Есть идеи, что это не так?
Спасибо.
Редактировать:
Вот пример программы, которая воспроизводит проблему.Программа запускает процесс с тем же маркером, что и указанный процесс, и назначает этот процесс объекту задания.
Если вы запускаете процесс как системный (вы можете создать службу с путем к исполняемому файлу, установленному в cmd.exe)и затем вы можете переключиться на системный сеанс и запустить программу оттуда), указать исходный процесс для любого пользовательского процесса и установить для UI предела значение true. При вызове AssignProcessToJobObject произойдет сбой со статусом ERROR_ACCESS_DENIED.Если для параметра limit UI установлено значение false, все работает нормально.
# define _CRT_SECURE_NO_WARNINGS
# include "stdafx.h"
# include <windows.h>
# include <stdio.h>
# include <assert.h>
# include <conio.h>
void main()
{
HANDLE job = NULL;
STARTUPINFO startupInfo = { 0 };
PROCESS_INFORMATION processInformation = { 0 };
JOBOBJECT_EXTENDED_LIMIT_INFORMATION eli = { 0 };
JOBOBJECT_BASIC_UI_RESTRICTIONS bur = { 0 };
HANDLE token = NULL;
HANDLE process = NULL;
BOOL limitUI = TRUE;
DWORD sourcePid = 0;
printf("Enter source pid: ");
scanf("%u", &sourcePid);
process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, sourcePid);
if(process == NULL)
{
printf("OpenProcess failed\n");
goto cleanup;
}
if(!OpenProcessToken(process, TOKEN_ALL_ACCESS, &token))
{
printf("OpenProcessToken failed\n");
goto cleanup;
}
job = CreateJobObject(NULL, NULL);
if(job == NULL)
{
printf("CreateJobObject failed\n");
goto cleanup;
}
eli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
eli.BasicLimitInformation.PriorityClass = NORMAL_PRIORITY_CLASS;
if(!SetInformationJobObject(job, JobObjectExtendedLimitInformation, &eli, sizeof(eli)))
{
printf("SetInformationJobObject failed\n");
goto cleanup;
}
printf("Limit UI: ");
scanf("%u", &limitUI);
if(limitUI)
{
bur.UIRestrictionsClass = JOB_OBJECT_UILIMIT_HANDLES;
if(!SetInformationJobObject(job, JobObjectBasicUIRestrictions, &bur, sizeof(bur)))
{
printf("SetInformationJobObject failed\n");
goto cleanup;
}
}
if(!CreateProcessAsUser(token, L"c:\\windows\\system32\\notepad.exe", L"", NULL, NULL, FALSE,
CREATE_SUSPENDED, NULL, NULL, &startupInfo, &processInformation))
{
printf("CreateProcessAsUser failed\n");
goto cleanup;
}
if(!AssignProcessToJobObject(job, processInformation.hProcess))
{
printf("AssignProcessToJobObject failed\n");
goto cleanup;
}
if(ResumeThread(processInformation.hThread) == (DWORD)-1)
{
printf("ResumeThread failed\n");
goto cleanup;
}
WaitForSingleObject(processInformation.hProcess, INFINITE);
cleanup:
if(processInformation.hThread != NULL)
CloseHandle(processInformation.hThread);
if(processInformation.hProcess != NULL)
CloseHandle(processInformation.hProcess);
if(job != NULL)
CloseHandle(job);
if(token != NULL)
CloseHandle(token);
if(process != NULL)
CloseHandle(process);
printf("Last Error: %d\n", GetLastError());
}