windows核心编程:5章:将一个进程放入一个作业中,以限制此进程具体能够做那些事情
windows核心编程:5章:将一个进程放入一个作业中,以限制此进程具体能够做那些事情
/*
05-ProcessInfo.cpp
将一个进程放入一个作业中,以限制此进程具体能够做那些事情
*/
#include <Windows.h>
#include <tchar.h>
#include <strsafe.h>
void StartRestrictedProcess();
int WINAPI WinMain(HINSTANCE hinstExe, HINSTANCE, LPSTR pszCmdLine, int)
{
StartRestrictedProcess();
}
void StartRestrictedProcess()
{
//检查当前进程是否已经与一个作业关联,如果是这种情况,没有办法切换到另一个作业
BOOL bInJob = FALSE;
/* */
IsProcessInJob(GetCurrentProcess(), NULL, &bInJob);
if (bInJob)
{
MessageBox(NULL, TEXT("Process already in job"),
TEXT(" "), MB_ICONINFORMATION | MB_OK);
return;
}
//第一步:创建一个作业内核对象
HANDLE hjob = CreateJobObject(NULL,//指向SECURITY_ATTRIBUTES结构体的指针,获得默认的安全描述符
TEXT("Wintellect_RestrictedProcessJob"));
//第二部:对作业中的流程进行一些限制
//1,设置一些基本的限制
JOBOBJECT_BASIC_LIMIT_INFORMATION jobli = { 0 };
//进程总是运行在空闲的优先级类中
jobli.PriorityClass = IDLE_PRIORITY_CLASS;
//作业占用cpu时间不能超过1毫秒= 0.001s
jobli.PerJobUserTimeLimit.QuadPart = 10000;//1sec以100ns为单位
//这里是我们希望对作业关联进程施加的唯一的两个限制
jobli.LimitFlags = JOB_OBJECT_LIMIT_PRIORITY_CLASS | JOB_OBJECT_LIMIT_JOB_TIME;
SetInformationJobObject(hjob, JobObjectBasicLimitInformation, &jobli, sizeof(jobli));
//设置UI限制
JOBOBJECT_BASIC_UI_RESTRICTIONS jobuir;
jobuir.UIRestrictionsClass = JOB_OBJECT_UILIMIT_NONE;
//进程不能退出系统
jobuir.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_EXITWINDOWS;
//在系统中,进程不能访问USER对象(例如其他窗口)
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"));
//CREATE_SUSPENDED:新进程的主线程处于挂起状态创建:EREATE_NEW_CONSOLE;新进程具有新控件
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);
//等待进程终止活拨给作业的所有CPU时间已经用完
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:
//拨给作 业的所有的cpu时间已经用完
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("CreationTime = %u | ExitTime = %u | Kernel = %u | User = %u\n"),
CreationTime.dwLowDateTime / 10000,
ExitTime.dwLowDateTime / 10000,
KernelTime.dwLowDateTime / 1000,
UserTime.dwLowDateTime / 10000);
MessageBox(GetActiveWindow(), szInfo, TEXT("Restricted Process times"),
MB_ICONINFORMATION | MB_OK);
//清理
CloseHandle(pi.hProcess);
CloseHandle(hjob);
}