作业调度

作业可以视为进程的集合,或者说沙箱,可以对这一系列进程进行统一的限制等操作
下面是windows核心编程中的StartRestrictedPrcess函数:

void StartRestrictedProcess()
{
    BOOL bInJob = FALSE;
    IsProcessInJob(GetCurrentProcess(), NULL, &bInJob);
    if(bInJob)
    {
        MessageBox(NULL, TEXT("Process already in a job"), TEXT(""), MB_ICONINFORMATION | MB_OK);
        return;
    }

    HANDLE hjob = CreateJobObject(NULL, TEXT("Wintellect_RestrictedProcessJob"));

    JOBOBJECT_BASIC_LIMIT_INFORMATION jobli = {0};
    jobli.PriorityClass = IDLE_PRIORITY_CLASS;
    jobli.PerJobUserTimeLimit.QuadPart = 10000;
    jobli.LimitFlags = JOB_OBJECT_LIMIT_JOB_TIME;
    SetInformationJobObject(hjob, JobObjectBasicLimitInformation, &jobli, sizeof(jobli));
    JOBOBJECT_BASIC_UI_RESTRICTIONS jobuir;
    jobuir.UIRestrictionsClass = JOB_OBJECT_UILIMIT_NONE;
    jobuir.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_EXITWINDOWS;
    jobuir.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_HANDLES;
    SetInformationJobObject(hjob, JobObjectBasicUIRestrictions, &jobuir, sizeof(jobuir));

    STARTUPINFO si = {sizeof(si)};
    PROCESS_INFORMATION pi;
    TCHAR szCmdLine[8];
    _tcscpy_s(szCmdLine, _countof(szCmdLine), TEXT("CMD"));
    BOOL bResult = CreateProcess(NULL, szCmdLine, NULL, NULL, FALSE, CREATE_SUSPENDED | CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);

    AssignProcessToJobObject(hjob, pi.hProcess);
    ResumeThread(pi.hThread);
    CloseHandle(pi.hThread);
    HANDLE h[2];
    h[0] = pi.hProcess;
    h[1] = hjob;
    DWORD dw = WaitForMultipleObjects(2, h, FALSE, INFINITE);
    switch (dw - WAIT_OBJECT_0)
    {
        case 0:
            break;
        case 1:
            break;
    }
    FILETIME CreationTime;
    FILETIME ExitTime;
    FILETIME KernelTime;
    FILETIME UserTime;
    TCHAR szInfo[MAX_PATH];
    GetProcessTimes(pi.hProcess, &CreationTime, &ExitTime, &KernelTime, &UserTime);
    StringCchPrintf(szInfo, _countof(szInfo), TEXT("Kernel = %u | User = %u\n"), KernelTime.dwLowDateTime / 10000, UserTime.dwLowDateTime /10000);
    MessageBox(GetActiveWindow(), szInfo, TEXT("Restricted Process times"), MB_ICONINFORMATION | MB_OK);
    CloseHandle(pi.hProcess);
    CloseHandle(hjob);
}

这个函数包含了一个作业的创建、设置以及将进程加入作业的全部流程
从头开始分析这个函数:
首先是一个IsProcessInJob函数,可以验证一个进程是否在一个作业控制之下运行,函数原型如下:

BOOL WINAPI IsProcessInJob(
  _In_      HANDLE ProcessHandle,
  _In_opt_  HANDLE JobHandle,
  _Out_     PBOOL Result
);

当第二个参数传入的是NULL时,会遍历所有现有作业

然后如果已经在作业里面了,程序会弹个对话框然后over

接下来是创建作业,使用CreateJobObject函数,原型如下:
HANDLE WINAPI CreateJobObject(
In_opt LPSECURITY_ATTRIBUTES lpJobAttributes,
In_opt LPCTSTR lpName
);
这个函数将返回所创建的作业的句柄,需要指定两个参数
第一个是出镜率极高的安全描述符,和以前一样没特殊需求NULL即可
第二个是命名,如果使用了OpenJobObject函数将会使用到

下一步是对作业中的进程进行限制,使用的函数为SetInformationJobObject,原型如下:

BOOL WINAPI SetInformationJobObject(
  _In_  HANDLE hJob,
  _In_  JOBOBJECTINFOCLASS JobObjectInfoClass,
  _In_  LPVOID lpJobObjectInfo,
  _In_  DWORD cbJobObjectInfoLength
);

参数需要注意的是中间两个,分别指定了限制的类型,具体内容
每一个限制类型又对应一个结构体,然后就往里面设置就好了,代码里面很清楚
这个好长= = 干脆把msdn扔上来好了https://msdn.microsoft.com/en-us/library/windows/desktop/ms686216(v=vs.85).aspx

再然后就是把进程加入作业里面了,使用AssignProcessToJobObject函数,这个就俩句柄,原型也懒得找了

如果要结束作业里面所有进程 调用TerminateJobObject即可
参数就一个句柄一个ExitCode

你可能感兴趣的:(作业调度)