#pragma once
#include <malloc.h>
class CJob
{
public:
CJob(HANDLE hJob = NULL);
~CJob();
public:
operator HANDLE() const;
BOOL Create(PSECURITY_ATTRIBUTES psa = NULL, PCTSTR pszName = NULL);
BOOL Open(PCTSTR pszName, DWORD dwDesireAccess, BOOL bInherit = FALSE);
BOOL AssignProcess(HANDLE hProcess);
BOOL Terminate(UINT uExitCode);
BOOL SetExtendedLimitInfo(PJOBOBJECT_EXTENDED_LIMIT_INFORMATION pJobLim, BOOL bPrevJobTime);
BOOL SetBasicUIRestrictions(DWORD dwLimits);
BOOL GrantUserHandleAccess(HANDLE hUserObj, BOOL bGrant = TRUE);
BOOL SetSecurityLimitInfo(PJOBOBJECT_SECURITY_LIMIT_INFORMATION pJobInfo);
BOOL QueryExtendedLimitInfo(PJOBOBJECT_EXTENDED_LIMIT_INFORMATION pJobLim);
BOOL QueryBasicUIRestrictions(PDWORD pdwRestrictions);
BOOL QuerySecurityLimitInfo(PJOBOBJECT_SECURITY_LIMIT_INFORMATION pJobLim);
BOOL QueryBasicAccountingInfo(PJOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION pJobInfo);
BOOL QueryBasicProcessIdList(DWORD dwMaxProcess, PDWORD pdwProcessIdList, PDWORD pdwProcessRt = NULL);
BOOL AssociateCompletionPort(HANDLE hIOCP, ULONG_PTR CompKey);
BOOL QueryAssociatedCompletionPort(PJOBOBJECT_ASSOCIATE_COMPLETION_PORT pJobPort);
BOOL SetEndOfJobInfo(DWORD dwEndOfJobInfo = JOB_OBJECT_TERMINATE_AT_END_OF_JOB);
BOOL QueryEndOfJobTimeInfo(PDWORD pdwEndOfJobTimeInfo);
private:
HANDLE m_hJob;
};
inline CJob::CJob(HANDLE hJob)
{
this->m_hJob = hJob;
}
inline CJob::~CJob()
{
if (NULL != this->m_hJob)
{
::CloseHandle(this->m_hJob);
}
}
inline BOOL CJob::Create(PSECURITY_ATTRIBUTES psa, PCTSTR pszName)
{
this->m_hJob = ::CreateJobObject(psa, pszName);
return (NULL != this->m_hJob);
}
inline BOOL CJob::Open(PCTSTR pszName, DWORD dwDesAcc, BOOL bInherit)
{
if (NULL != this->m_hJob)
{
::CloseHandle(this->m_hJob);
}
this->m_hJob = ::OpenJobObject(dwDesAcc, bInherit, pszName);
return (NULL != this->m_hJob);
}
inline BOOL CJob::AssignProcess(HANDLE hProcess)
{
return ::AssignProcessToJobObject(this->m_hJob, hProcess);
}
inline BOOL CJob::AssociateCompletionPort(HANDLE hIocp, ULONG_PTR CompKey)
{
JOBOBJECT_ASSOCIATE_COMPLETION_PORT jobPort;
::memset(&jobPort, 0, sizeof(jobPort));
jobPort.CompletionKey = (LPVOID)CompKey;
jobPort.CompletionPort = hIocp;
return ::SetInformationJobObject(this->m_hJob, JobObjectAssociateCompletionPortInformation, &jobPort, sizeof(jobPort));
}
inline BOOL CJob::SetExtendedLimitInfo(PJOBOBJECT_EXTENDED_LIMIT_INFORMATION pJobLim, BOOL bPrevJobTime)
{
const DWORD dwFlag = (JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME | JOB_OBJECT_LIMIT_JOB_TIME);
if (bPrevJobTime)
{
pJobLim->BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME;
}
if ( dwFlag == (pJobLim->BasicLimitInformation.LimitFlags & dwFlag))
{
DebugBreak();
}
return ::SetInformationJobObject(this->m_hJob, JobObjectExtendedLimitInformation, pJobLim, sizeof(*pJobLim));
}
inline BOOL CJob::SetBasicUIRestrictions(DWORD dwLimits)
{
JOBOBJECT_BASIC_UI_RESTRICTIONS jobRes;
::memset(&jobRes, 0, sizeof(jobRes));
jobRes.UIRestrictionsClass = dwLimits;
return ::SetInformationJobObject(this->m_hJob, JobObjectBasicUIRestrictions, &jobRes, sizeof(jobRes));
}
inline BOOL CJob::SetEndOfJobInfo(DWORD dwEndOfJobInfo)
{
JOBOBJECT_END_OF_JOB_TIME_INFORMATION jobInfo;
::memset(&jobInfo, 0, sizeof(jobInfo));
jobInfo.EndOfJobTimeAction = dwEndOfJobInfo;
return ::SetInformationJobObject(this->m_hJob, JobObjectEndOfJobTimeInformation, &jobInfo, sizeof(jobInfo));
}
inline BOOL CJob::SetSecurityLimitInfo(PJOBOBJECT_SECURITY_LIMIT_INFORMATION pJobInfo)
{
return ::SetInformationJobObject(this->m_hJob, JobObjectSecurityLimitInformation, pJobInfo, sizeof(*pJobInfo));
}
inline BOOL CJob::QueryAssociatedCompletionPort(PJOBOBJECT_ASSOCIATE_COMPLETION_PORT pJobPort)
{
return ::QueryInformationJobObject(this->m_hJob, JobObjectSecurityLimitInformation, pJobPort, sizeof(*pJobPort), NULL);
}
inline BOOL CJob::QueryBasicAccountingInfo(PJOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION pJobInfo)
{
return ::QueryInformationJobObject(this->m_hJob, JobObjectBasicAndIoAccountingInformation, pJobInfo, sizeof(&pJobInfo), NULL);
}
inline BOOL CJob::QueryExtendedLimitInfo(PJOBOBJECT_EXTENDED_LIMIT_INFORMATION pJobInfo)
{
return ::QueryInformationJobObject(this->m_hJob, JobObjectExtendedLimitInformation, pJobInfo, sizeof(&pJobInfo), NULL);
}
inline BOOL CJob::QueryBasicProcessIdList(DWORD dwMaxProcess, PDWORD pdwProcessIdList, PDWORD pdwProcessRt)
{
PJOBOBJECT_BASIC_PROCESS_ID_LIST plsJob = NULL;
DWORD dw = sizeof(JOBOBJECT_BASIC_PROCESS_ID_LIST) + (sizeof(DWORD) * (dwMaxProcess - 1));
BOOL bOk = FALSE;
plsJob = (PJOBOBJECT_BASIC_PROCESS_ID_LIST)_alloca(dw);
bOk = (plsJob != NULL);
if (bOk)
{
plsJob->NumberOfProcessIdsInList = dwMaxProcess;
bOk = ::QueryInformationJobObject(this->m_hJob, JobObjectBasicProcessIdList, plsJob, dw, NULL);
if (bOk)
{
if (pdwProcessRt)
{
*pdwProcessRt = plsJob->NumberOfProcessIdsInList;
}
::CopyMemory(pdwProcessIdList, plsJob->ProcessIdList, sizeof(DWORD) * plsJob->NumberOfProcessIdsInList);
}
}
return bOk;
}
inline BOOL CJob::QueryBasicUIRestrictions(PDWORD pdwRes)
{
JOBOBJECT_BASIC_UI_RESTRICTIONS jobInfo;
BOOL bOk;
bOk = ::QueryInformationJobObject(this->m_hJob, JobObjectBasicUIRestrictions, &jobInfo, sizeof(jobInfo), NULL);
if (bOk)
{
*pdwRes = jobInfo.UIRestrictionsClass;
}
return bOk;
}
inline BOOL CJob::QueryEndOfJobTimeInfo(PDWORD pdwEndTimeInfo)
{
JOBOBJECT_END_OF_JOB_TIME_INFORMATION jobInfo;
BOOL bOk = FALSE;
bOk = ::QueryInformationJobObject(this->m_hJob, JobObjectBasicUIRestrictions, &jobInfo, sizeof(jobInfo), NULL);
if (bOk)
{
*pdwEndTimeInfo = jobInfo.EndOfJobTimeAction;
}
return bOk;
}
inline BOOL CJob::QuerySecurityLimitInfo(PJOBOBJECT_SECURITY_LIMIT_INFORMATION pJobLim)
{
return ::QueryInformationJobObject(this->m_hJob, JobObjectSecurityLimitInformation, pJobLim, sizeof(&pJobLim), NULL);
}
inline BOOL CJob::Terminate(UINT uExitCode)
{
return ::TerminateJobObject(this->m_hJob, uExitCode);
}
inline BOOL CJob::GrantUserHandleAccess(HANDLE hUserObj, BOOL bGrant)
{
return ::UserHandleGrantAccess(hUserObj, this->m_hJob, bGrant);
}
.