Сбой AssignProcessToJobObject с JOB_OBJECT_UILIMIT_HANDLES при вызове из службы - PullRequest
1 голос
/ 13 мая 2011

У меня есть служба, из которой я хочу создать ограниченный процесс для текущего зарегистрированного пользователя.Если я пытаюсь присвоить процесс объекту задания, для которого установлено 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());
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...