正在写一个oj系统,对于Job作业对象的一些功能看不懂,《windows核心编程》也是一笔带过……无奈中这是《windows核心编程》上的example,我改了一下。其中test.file.exe的作用仅仅是停5秒钟,但是获得的时间通常小于20ms。不解
GetLasterror出来1812……。。#include <iostream>
#include <cstdio>
#define _WIN32_WINNT 0x0601
#include <windows.h>
using namespace std;
void StartRestrictedProcess()
{
    // Check if we are not already associated with a job.
    // If this is the case, there is no way to switch to
    // another job.    // Create a job kernel object.
    HANDLE hjob = CreateJobObject(NULL,
                                  "Wintellect_RestrictedProcessJob");
    // Place some restrictions on processes in the job.
    // First, set some basic restrictions.
    JOBOBJECT_BASIC_LIMIT_INFORMATION jobli = { 0 };
    // The process always runs in the idle priority class.
    jobli.PriorityClass = IDLE_PRIORITY_CLASS;
    // The job cannot use more than 1 second of CPU time.
    jobli.PerJobUserTimeLimit.QuadPart = 10000000; // 1 sec in 100-ns intervals
    // These are the only 2 restrictions I want placed on the job (process).
    jobli.LimitFlags = JOB_OBJECT_LIMIT_PRIORITY_CLASS
                       | JOB_OBJECT_LIMIT_JOB_TIME;
    SetInformationJobObject(hjob, JobObjectBasicLimitInformation, &jobli,
                            sizeof(jobli));
    // Second, set some UI restrictions.
    JOBOBJECT_BASIC_UI_RESTRICTIONS jobuir;
    jobuir.UIRestrictionsClass = 0; // A fancy zero
    // The process can't log off the system.
    jobuir.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_EXITWINDOWS;
    // The process can't access USER objects (such as other windows)
    // in the system.
    jobuir.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_HANDLES;
    SetInformationJobObject(hjob, JobObjectBasicUIRestrictions, &jobuir,
                            sizeof(jobuir));
    // Spawn the process that is to be in the job.
    // Note: You must first spawn the process and then place the process in
    //      the job. This means that the process’ thread must be initially
    //      suspended so that it can’t execute any code outside of the job's
    //      restrictions.
    STARTUPINFO si = { sizeof(si) };
    PROCESS_INFORMATION pi;
    BOOL bResult =
        CreateProcess(
            NULL, (char *)"file.test.exe", NULL, NULL, FALSE,
            CREATE_SUSPENDED | CREATE_NEW_CONSOLE | CREATE_BREAKAWAY_FROM_JOB, NULL, NULL, &si, &pi);
    cerr<<bResult<<endl;
    // Place the process in the job.
    // Note: If this process spawns any children, the children are
    //      automatically part of the same job.
    bResult = AssignProcessToJobObject(hjob, pi.hProcess);
    cerr<<bResult<<endl;
    cerr<<GetLastError()<<endl;
    // Now we can allow the child process' thread to execute code.
    ResumeThread(pi.hThread);
    CloseHandle(pi.hThread);
    // Wait for the process to terminate or
    // for all the job's allotted CPU time to be used.
    HANDLE h[2];
    h[0] = pi.hProcess;
    h[1] = hjob;
    DWORD dw = WaitForMultipleObjects(2, h, FALSE, INFINITE);
    switch (dw - WAIT_OBJECT_0)
    {
    case 0:
        // The process has terminated...
        break;
    case 1:
        // All of the job's allotted CPU time was used...
        break;
    }
    LARGE_INTEGER CreationTime;
    LARGE_INTEGER ExitTime;
    LARGE_INTEGER KernelTime;
    LARGE_INTEGER UserTime;    GetProcessTimes(pi.hProcess, (LPFILETIME)&CreationTime, (LPFILETIME)&ExitTime,
                    (LPFILETIME)&KernelTime, (LPFILETIME)&UserTime);
    printf("Kernel = %u | User = %u\n", KernelTime.QuadPart / 100000, UserTime.QuadPart / 100000);
    //MessageBox(GetActiveWindow(), szInfo, "Restricted Process times",
    //           MB_ICONINFORMATION | MB_OK);
    // Clean up properly.
    CloseHandle(pi.hProcess);
    CloseHandle(hjob);
}
int main(void)
{
    StartRestrictedProcess();
    return 0;
}
另外求解如何限制job中进程不允许读写文件、关闭计算机(也就是问JOBOBJECT_SECURITY_LIMIT_INFORMATION 的各个参数和作用)

解决方案 »

  1.   

    不允许读写文件、关闭计算机
    ----------------------------
    这个Job限制不了。得Hook
      

  2.   

    JOBOBJECT_SECURITY_LIMIT_INFORMATION 的各个参数和作用
    -----------------------------------------------
    该结构有点诡异,因为它包含了与限制作业无关的成员。首先,IoInfo是保留成员,不应以任何方式访问它。此外,PeakProcessMemoryUsed和PeakJobMemoryUsed成员是只读的,分别告诉我们已调拨给作业中的任何一个进程所需的存储空间的峰值,以及已调拨给作业中全部进程所需的存储空间的峰值。其余两个成员ProcessMemoryLimit和JobMemoryLimit分别限制着作业中的任何一个进程或全部进程所使用的己调拨的存储空间。为了设置这样的限制,需要在LimitFlags成员中分别指定JOB_OBJECT_LIMIT_JOB_MEMORY和JOB_OBJECT_LIMIT_PROCESS_MEMORY标志。
      

  3.   

    基本限制               
    JOBOBJECT_BASIC_LIMIT_INFORMATION
    扩展后的基本限制 
    JOBOBJECT_EXTENDED_LIMIT_INFORMATION
    基本的UI限制       
    JOBOBJECT_BASIC_UI_RESTRICTIONS
    安全限制
    JOBOBJECT_SECURITY_LIMIT_INFORMATION
      

  4.   

    @Tr0j4n:某位神仙用内核级别的用户+Job实现了……
      

  5.   


    部分代码如下:Imports VijosNT.LocalDbNamespace Executing
        Friend Class Executor
            Implements IDisposable        Private m_SyncRoot As Object
            Private m_AvailableSlots As Int32
            Private m_Pools As Dictionary(Of EnvironmentTag, EnvironmentPoolBase)
            Private m_PendingExecutees As Queue(Of Executee)
            Private m_EnableSecurity As Boolean        Public Sub New()
                Dim Slots As Int32 = Config.ExecutorSlots            m_SyncRoot = New Object()
                m_AvailableSlots = Slots
                m_Pools = New Dictionary(Of EnvironmentTag, EnvironmentPoolBase)()
                m_PendingExecutees = New Queue(Of Executee)()
                m_EnableSecurity = Config.EnableSecurity            Dim TrustedPool As New TrustedEnvironmentPool()
                TrustedPool.Executor = Me
                m_Pools.Add(EnvironmentTag.Trusted, TrustedPool)            If m_EnableSecurity Then
                    Dim UntrustedPool As New UntrustedEnvironmentPool(GetUntrustedEnvironments())
                    UntrustedPool.Executor = Me
                    m_Pools.Add(EnvironmentTag.Untrusted, UntrustedPool)
                Else
                    m_Pools.Add(EnvironmentTag.Untrusted, TrustedPool)
                End If
            End Sub        Private Function GetUntrustedEnvironments() As IEnumerable(Of UntrustedEnvironment)
                Dim Result As New List(Of UntrustedEnvironment)
                Using Reader As IDataReader = UntrustedEnvironments.GetAll()
                    While Reader.Read()
                        Result.Add(New UntrustedEnvironment(Reader("UserName"), Reader("Password")))
                    End While
                End Using
                Return Result
            End Function        Public Function Take() As Boolean
                SyncLock m_SyncRoot
                    If m_AvailableSlots <> 0 Then
                        m_AvailableSlots -= 1
                        Return True
                    Else
                        Return False
                    End If
                End SyncLock
            End Function        Public Sub Untake()
                SyncLock m_SyncRoot
                    If m_PendingExecutees.Count <> 0 Then
                        Dim Executee As Executee = m_PendingExecutees.Dequeue()
                        m_Pools(Executee.RequiredEnvironment).Queue(Executee)
                    Else
                        m_AvailableSlots += 1
                    End If
                End SyncLock
            End Sub        Public Sub Queue(ByVal Executee As Executee)
                If Take() Then
                    m_Pools(Executee.RequiredEnvironment).Queue(Executee)
                Else
                    SyncLock m_SyncRoot
                        m_PendingExecutees.Enqueue(Executee)
                    End SyncLock
                End If
            End Sub#Region "IDisposable Support"
            Private disposedValue As Boolean ' 检测冗余的调用        ' IDisposable
            Protected Overridable Sub Dispose(ByVal disposing As Boolean)
                If Not Me.disposedValue Then
                    If disposing Then
                        For Each Pool As EnvironmentPoolBase In m_Pools.Values
                            Pool.Dispose()
                        Next
                    End If
                End If
                Me.disposedValue = True
            End Sub        ' Visual Basic 添加此代码是为了正确实现可处置模式。
            Public Sub Dispose() Implements IDisposable.Dispose
                ' 不要更改此代码。请将清理代码放入上面的 Dispose(ByVal disposing As Boolean)中。
                Dispose(True)
                GC.SuppressFinalize(Me)
            End Sub
    #End Region    End Class
    End Namespace完整代码请见http://code.google.com/p/vijosnt-mini/
      

  6.   

    好大一个工程啊,懒得分析了。你已经下载了工程,你告诉我,JOB相关代码在哪里
      

  7.   

    你不知情你怎么知道它是用Job做的?!
      

  8.   

    我看过源代码了    Friend Class JobObject
            Inherits KernelObject
            Implements IDisposable他说的Job,是自己弄的一个Job跟我们C++核心编程里的Job不是一回事