美文网首页
作业调度

作业调度

作者: FallMR | 来源:发表于2017-02-20 21:58 被阅读0次

    作业可以视为进程的集合,或者说沙箱,可以对这一系列进程进行统一的限制等操作
    下面是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

    相关文章

      网友评论

          本文标题:作业调度

          本文链接:https://www.haomeiwen.com/subject/gutywttx.html