#include <windows.h> #include<iostream> #include <tchar.h> using namespace std; typedef struct ThreadParam{ HANDLE hIOCP; DWORD dwNumBytesTransferred; ULONG CompletionKey; LPOVERLAPPED pOverlapped; DWORD dwTimeOut; }*pThreadParam; void MonitorCompletePort(LPVOID lpParam){ pThreadParam tp = (pThreadParam)lpParam; BOOL bRuslt = FALSE; printf("Run thread success. "); while (TRUE){ bRuslt = GetQueuedCompletionStatus(tp->hIOCP, &tp->dwNumBytesTransferred, &tp->CompletionKey, &tp->pOverlapped, INFINITE); switch (tp->dwNumBytesTransferred){ case JOB_OBJECT_MSG_END_OF_JOB_TIME: printf("JOB_OBJECT_MSG_END_OF_JOB_TIME "); break; case JOB_OBJECT_MSG_END_OF_PROCESS_TIME: printf("JOB_OBJECT_MSG_END_OF_PROCESS_TIME "); break; case JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT: printf("JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT "); break; case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO: printf("JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO "); break; case JOB_OBJECT_MSG_NEW_PROCESS: printf("JOB_OBJECT_MSG_NEW_PROCESS "); break; case JOB_OBJECT_MSG_EXIT_PROCESS: printf("JOB_OBJECT_MSG_EXIT_PROCESS "); break; case JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS: printf("JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS "); break; case JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT: printf("JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT "); break; case JOB_OBJECT_MSG_JOB_MEMORY_LIMIT: printf("JOB_OBJECT_MSG_JOB_MEMORY_LIMIT "); break; case JOB_OBJECT_MSG_NOTIFICATION_LIMIT: printf("JOB_OBJECT_MSG_NOTIFICATION_LIMIT "); break; } } printf("End thread success. "); } void main(){ //Check if the process has been in a job. If not, create a job object. BOOL bInJob = FALSE; IsProcessInJob(GetCurrentProcess(), NULL, &bInJob);//如果用命令行启动,就返回false;如果直接用vs调试启动,就返回true。
if (bInJob){ printf("Been in a job. "); }
HANDLE hJob = CreateJobObject(NULL, _T("Wintellect_RestrictedProcessJob")); //Add some basic restrictions.
JOBOBJECT_BASIC_LIMIT_INFORMATION jobli = { 0 };
jobli.PriorityClass = IDLE_PRIORITY_CLASS;
jobli.PerJobUserTimeLimit.QuadPart = 10000;
jobli.LimitFlags = JOB_OBJECT_LIMIT_PRIORITY_CLASS | 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)); //Create a process object
STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi;
BOOL bResult = CreateProcess("C:\Windows\System32\notepad.exe", NULL, NULL, NULL, FALSE, CREATE_SUSPENDED | CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
AssignProcessToJobObject(hJob, pi.hProcess); //Create io completion port.
HANDLE hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 3);
JOBOBJECT_ASSOCIATE_COMPLETION_PORT joacp; joacp.CompletionKey = (PVOID)1;
joacp.CompletionPort = hIOCP;
SetInformationJobObject(hJob, JobObjectAssociateCompletionPortInformation, &joacp, sizeof(joacp)); //Create a thread to monitor the job.
DWORD dwNumBytesTransferred = 0;
ULONG lCompletionKey = 0;
ThreadParam tp;
OVERLAPPED op = { 0 };
tp.hIOCP = hIOCP;
tp.dwNumBytesTransferred = dwNumBytesTransferred;
tp.CompletionKey = lCompletionKey;
tp.pOverlapped = NULL;
tp.dwTimeOut = INFINITE;
DWORD lpThread;
HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MonitorCompletePort, &tp, 0, &lpThread); Sleep(5000);
ResumeThread(pi.hThread); CloseHandle(pi.hThread);
WaitForSingleObject(hThread, INFINITE);//Naution:if use while(true) in the thread, the thread will never return. If use INIFINITE as param //of function WaitForSingleObject, the main thread will never return. CloseHandle(hThread); getchar(); }
第一次执行GetQueuedCompletionStatus返回6(JOB_OBJECT_MSG_NEW_PROCESS),表示将一个进程添加进一个作业;第二次执行GetQueuedCompletionStatus返回1(JOB_OBJECT_MSG_END_OF_JOB_TIME),表示作业超时;第二次执行GetQueuedCompletionStatus返回1(JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO),表示作业中进程的数量降至0.