class CJob

本文介绍了一个用于Windows平台的C++类CJob,该类提供了一系列方法来创建、配置和管理Job对象。通过这些方法,可以为进程分配Job对象、设置资源限制、监控进程状态等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/******************************************************************************
Module:  Job.h
Notices: Copyright (c) 2000 Jeffrey Richter
******************************************************************************/


#pragma once


///////////////////////////////////////////////////////////////////////////////


#include <malloc.h>  // for _alloca


///////////////////////////////////////////////////////////////////////////////


class CJob {
public:
   CJob(HANDLE hJob = NULL);
   ~CJob();

   operator HANDLE() const { return(m_hJob); }

   // Functions to create/open a job object
   BOOL Create(PSECURITY_ATTRIBUTES psa = NULL, PCTSTR pszName = NULL);
   BOOL Open(PCTSTR pszName, DWORD dwDesiredAccess, 
      BOOL fInheritHandle = FALSE);

   // Functions that manipulate a job object
   BOOL AssignProcess(HANDLE hProcess);
   BOOL Terminate(UINT uExitCode = 0);

   // Functions that set limits/restrictions on the job
   BOOL SetExtendedLimitInfo(PJOBOBJECT_EXTENDED_LIMIT_INFORMATION pjoeli, 
      BOOL fPreserveJobTime = FALSE);
   BOOL SetBasicUIRestrictions(DWORD fdwLimits);
   BOOL GrantUserHandleAccess(HANDLE hUserObj, BOOL fGrant = TRUE);
   BOOL SetSecurityLimitInfo(PJOBOBJECT_SECURITY_LIMIT_INFORMATION pjosli);

   // Functions that query job limits/restrictions
   BOOL QueryExtendedLimitInfo(PJOBOBJECT_EXTENDED_LIMIT_INFORMATION pjoeli);
   BOOL QueryBasicUIRestrictions(PDWORD pfdwRestrictions);
   BOOL QuerySecurityLimitInfo(PJOBOBJECT_SECURITY_LIMIT_INFORMATION pjosli);

   // Functions that query job status information
   BOOL QueryBasicAccountingInfo(
      PJOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION pjobai);
   BOOL QueryBasicProcessIdList(DWORD dwMaxProcesses, 
      PDWORD pdwProcessIdList, PDWORD pdwProcessesReturned = NULL);

   // Functions that set/query job event notifications
   BOOL AssociateCompletionPort(HANDLE hIOCP, ULONG_PTR CompKey);
   BOOL QueryAssociatedCompletionPort(
      PJOBOBJECT_ASSOCIATE_COMPLETION_PORT pjoacp);
   BOOL SetEndOfJobInfo(
      DWORD fdwEndOfJobInfo = JOB_OBJECT_TERMINATE_AT_END_OF_JOB);
   BOOL QueryEndOfJobTimeInfo(PDWORD pfdwEndOfJobTimeInfo);

private:
   HANDLE m_hJob;
};


///////////////////////////////////////////////////////////////////////////////


inline CJob::CJob(HANDLE hJob) {

   m_hJob = hJob;
}


///////////////////////////////////////////////////////////////////////////////


inline CJob::~CJob() {

   if (m_hJob != NULL) 
      CloseHandle(m_hJob);
}


///////////////////////////////////////////////////////////////////////////////


inline BOOL CJob::Create(PSECURITY_ATTRIBUTES psa, PCTSTR pszName) {

   m_hJob = CreateJobObject(psa, pszName);
   return(m_hJob != NULL);
}


///////////////////////////////////////////////////////////////////////////////


inline BOOL CJob::Open(
   PCTSTR pszName, DWORD dwDesiredAccess, BOOL fInheritHandle) {

   m_hJob = OpenJobObject(dwDesiredAccess, fInheritHandle, pszName);
   return(m_hJob != NULL);
}


///////////////////////////////////////////////////////////////////////////////


inline BOOL CJob::AssignProcess(HANDLE hProcess) {

   return(AssignProcessToJobObject(m_hJob, hProcess));
}


///////////////////////////////////////////////////////////////////////////////


inline BOOL CJob::AssociateCompletionPort(HANDLE hIOCP, ULONG_PTR CompKey) {

   JOBOBJECT_ASSOCIATE_COMPLETION_PORT joacp = { (PVOID) CompKey, hIOCP };
   return(SetInformationJobObject(m_hJob, 
      JobObjectAssociateCompletionPortInformation, &joacp, sizeof(joacp)));
}


///////////////////////////////////////////////////////////////////////////////


inline BOOL CJob::SetExtendedLimitInfo(
   PJOBOBJECT_EXTENDED_LIMIT_INFORMATION pjoeli, BOOL fPreserveJobTime) {

   if (fPreserveJobTime)
      pjoeli->BasicLimitInformation.LimitFlags |= 
         JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME;

   // If we are to preserve the job's time information, 
   // the JOB_OBJECT_LIMIT_JOB_TIME flag must not be on
   const DWORD fdwFlagTest = 
      (JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME | JOB_OBJECT_LIMIT_JOB_TIME);

   if ((pjoeli->BasicLimitInformation.LimitFlags & fdwFlagTest) 
      == fdwFlagTest) {
      // These flags are mutually exclusive but both are on, error
      DebugBreak();
   }

   return(SetInformationJobObject(m_hJob, 
      JobObjectExtendedLimitInformation, pjoeli, sizeof(*pjoeli)));
}


///////////////////////////////////////////////////////////////////////////////


inline BOOL CJob::SetBasicUIRestrictions(DWORD fdwLimits) {

   JOBOBJECT_BASIC_UI_RESTRICTIONS jobuir = { fdwLimits };
   return(SetInformationJobObject(m_hJob, 
      JobObjectBasicUIRestrictions, &jobuir, sizeof(jobuir)));
}


///////////////////////////////////////////////////////////////////////////////


inline BOOL CJob::SetEndOfJobInfo(DWORD fdwEndOfJobInfo) {

   JOBOBJECT_END_OF_JOB_TIME_INFORMATION joeojti = { fdwEndOfJobInfo };
   joeojti.EndOfJobTimeAction = fdwEndOfJobInfo;
   return(SetInformationJobObject(m_hJob, 
      JobObjectEndOfJobTimeInformation, &joeojti, sizeof(joeojti)));
}


///////////////////////////////////////////////////////////////////////////////


inline BOOL CJob::SetSecurityLimitInfo(
   PJOBOBJECT_SECURITY_LIMIT_INFORMATION pjosli) {

   return(SetInformationJobObject(m_hJob, 
      JobObjectSecurityLimitInformation, pjosli, sizeof(*pjosli)));
}


///////////////////////////////////////////////////////////////////////////////


inline BOOL CJob::QueryAssociatedCompletionPort(
   PJOBOBJECT_ASSOCIATE_COMPLETION_PORT pjoacp) {

   return(QueryInformationJobObject(m_hJob, 
      JobObjectAssociateCompletionPortInformation, pjoacp, sizeof(*pjoacp), 
      NULL));
}


///////////////////////////////////////////////////////////////////////////////


inline BOOL CJob::QueryBasicAccountingInfo(
   PJOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION pjobai) {

   return(QueryInformationJobObject(m_hJob, 
      JobObjectBasicAndIoAccountingInformation, pjobai, sizeof(*pjobai), 
      NULL));
}


///////////////////////////////////////////////////////////////////////////////


inline BOOL CJob::QueryExtendedLimitInfo(
   PJOBOBJECT_EXTENDED_LIMIT_INFORMATION pjoeli) {

   return(QueryInformationJobObject(m_hJob, JobObjectExtendedLimitInformation, 
      pjoeli, sizeof(*pjoeli), NULL));
}


///////////////////////////////////////////////////////////////////////////////


inline BOOL CJob::QueryBasicProcessIdList(DWORD dwMaxProcesses, 
   PDWORD pdwProcessIdList, PDWORD pdwProcessesReturned) {

   // Calculate the # of bytes necessary
   DWORD cb = sizeof(JOBOBJECT_BASIC_PROCESS_ID_LIST) + 
      (sizeof(DWORD) * (dwMaxProcesses - 1));

   // Allocate those bytes from the stack
   PJOBOBJECT_BASIC_PROCESS_ID_LIST pjobpil = 
      (PJOBOBJECT_BASIC_PROCESS_ID_LIST) _alloca(cb);

   // Were those bytes allocated OK? If so, keep going
   BOOL fOk = (pjobpil != NULL);

   if (fOk) {
      pjobpil->NumberOfProcessIdsInList = dwMaxProcesses;
      fOk = ::QueryInformationJobObject(m_hJob, JobObjectBasicProcessIdList, 
         pjobpil, cb, NULL);

      if (fOk) {
         // We got the information, return it to the caller
         if (pdwProcessesReturned != NULL) 
            *pdwProcessesReturned = pjobpil->NumberOfProcessIdsInList;

         CopyMemory(pdwProcessIdList, pjobpil->ProcessIdList, 
            sizeof(DWORD) * pjobpil->NumberOfProcessIdsInList);
      }
   }
   return(fOk);
}


///////////////////////////////////////////////////////////////////////////////


inline BOOL CJob::QueryBasicUIRestrictions(PDWORD pfdwRestrictions) {

   JOBOBJECT_BASIC_UI_RESTRICTIONS jobuir;
   BOOL fOk = QueryInformationJobObject(m_hJob, JobObjectBasicUIRestrictions, 
      &jobuir, sizeof(jobuir), NULL);
   if (fOk)
      *pfdwRestrictions = jobuir.UIRestrictionsClass;
   return(fOk);
}


///////////////////////////////////////////////////////////////////////////////


inline BOOL CJob::QueryEndOfJobTimeInfo(PDWORD pfdwEndOfJobTimeInfo) {

   JOBOBJECT_END_OF_JOB_TIME_INFORMATION joeojti;
   BOOL fOk = QueryInformationJobObject(m_hJob, JobObjectBasicUIRestrictions, 
      &joeojti, sizeof(joeojti), NULL);
   if (fOk)
      *pfdwEndOfJobTimeInfo = joeojti.EndOfJobTimeAction;
   return(fOk);
}


///////////////////////////////////////////////////////////////////////////////


inline BOOL CJob::QuerySecurityLimitInfo(
   PJOBOBJECT_SECURITY_LIMIT_INFORMATION pjosli) {

   return(QueryInformationJobObject(m_hJob, JobObjectSecurityLimitInformation, 
      pjosli, sizeof(*pjosli), NULL));
}


///////////////////////////////////////////////////////////////////////////////


inline BOOL CJob::Terminate(UINT uExitCode) {

   return(TerminateJobObject(m_hJob, uExitCode));
}


///////////////////////////////////////////////////////////////////////////////


inline BOOL CJob::GrantUserHandleAccess(HANDLE hUserObj, BOOL fGrant) {

   return(UserHandleGrantAccess(hUserObj, m_hJob, fGrant));
}


//////////////////////////////// End of File //////////////////////////////////


//#if (_WIN32_WINNT >= 0x0500)
//#define _WIN32_WINNT   0x500
//#include <windows.h> 
#include "Job.h"
#include "PROCESS.h"
#include "CmnHdr.h"

// Completion keys for the completion port
#define COMPKEY_TERMINATE  ((UINT_PTR) 0)
#define COMPKEY_STATUS     ((UINT_PTR) 1)
#define COMPKEY_JOBOBJECT  ((UINT_PTR) 2)


CJob   g_job;           // Job object

HANDLE g_hIOCP;         // Completion port that receives Job notifications
//HANDLE g_hThreadIOCP;   // Completion port thread

void CCmdInJobDlg::OnCancel() 
{
	// TODO: Add extra cleanup here
	g_job.Terminate(0);  	
	CDialog::OnCancel();
}

	// TODO: Add extra initialization here
	////////////////////////////////////////////////////////////////////////
   // Create the completion port that receives job notifications
   g_hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);

   // Create a thread that waits on the completion port
   //g_hThreadIOCP = chBEGINTHREADEX(NULL, 0, JobNotify, NULL, 0, NULL);

   // Create the job object
   g_job.Create(NULL, TEXT("JobLab"));
   g_job.SetEndOfJobInfo(JOB_OBJECT_POST_AT_END_OF_JOB);
   g_job.AssociateCompletionPort(g_hIOCP, COMPKEY_JOBOBJECT);

   //DialogBox(hinstExe, MAKEINTRESOURCE(IDD_JOBLAB), NULL, Dlg_Proc);

   // Post a special key that tells the completion port thread to terminate
   PostQueuedCompletionStatus(g_hIOCP, 0, COMPKEY_TERMINATE, NULL);

   // Wait for the completion port thread to terminate
   //WaitForSingleObject(g_hThreadIOCP, INFINITE);
   
   // Clean up everything properly
   CloseHandle(g_hIOCP);
   //CloseHandle(g_hThreadIOCP);	
	return TRUE;  // return TRUE  unless you set the focus to a control
}


void CCmdInJobDlg::OnSpawncmdinjob() 
{
         {
         // Spawn a command shell and place it in the job
         STARTUPINFO si = { sizeof(si) };
         PROCESS_INFORMATION pi;
         TCHAR sz[] = TEXT("CMD");
         CreateProcess(NULL, sz, NULL, NULL, 
            FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
         g_job.AssignProcess(pi.hProcess);
         ResumeThread(pi.hThread);
         CloseHandle(pi.hProcess);
         CloseHandle(pi.hThread);
         }
         PostQueuedCompletionStatus(g_hIOCP, 0, COMPKEY_STATUS, NULL);	
}


void CCmdInJobDlg::OnTerminate() 
{
         g_job.Terminate(0);  
         PostQueuedCompletionStatus(g_hIOCP, 0, COMPKEY_STATUS, NULL);	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值