Пример #1
0
        public ProcessContainer(Process p, Job j)
        {
            _proc  = p;
            _job   = j;
            handle = CreateJobObject(IntPtr.Zero, null);

            var info = new JOBOBJECT_BASIC_LIMIT_INFORMATION
            {
                LimitFlags = 0x2000
            };

            var extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION
            {
                BasicLimitInformation = info
            };

            int    length          = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
            IntPtr extendedInfoPtr = Marshal.AllocHGlobal(length);

            Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);

            if (!SetInformationJobObject(handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length))
            {
                throw new Exception(string.Format("Unable to set information.  Error: {0}", Marshal.GetLastWin32Error()));
            }

            // Set the value to an unknown
            Result = InteractionResult.Unknown;
        }
Пример #2
0
        public ChildProcessManager(ulong memoryLimit)
        {
            _handle = new SafeJobHandle(CreateJobObject(IntPtr.Zero, null));

            var info = new JOBOBJECT_BASIC_LIMIT_INFORMATION
            {
                LimitFlags = 0x00000100
            };

            var extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION
            {
                BasicLimitInformation = info,
                ProcessMemoryLimit    = (UIntPtr)memoryLimit
            };

            var length          = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
            var extendedInfoPtr = Marshal.AllocHGlobal(length);

            Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);

            if (!SetInformationJobObject(_handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr,
                                         (uint)length))
            {
                throw new InvalidOperationException($"Unable to set information.  Error: {Marshal.GetLastWin32Error()}");
            }
        }
Пример #3
0
        private static SafeFileHandle CreateJobHandle()
        {
            var handle = NativeMethods.CreateJobObject(IntPtr.Zero, null);

            if (handle == null)
            {
                throw new LastWin32ErrorException("Error creating job handle");
            }

            var info = new JOBOBJECT_BASIC_LIMIT_INFORMATION();

            info.LimitFlags = 0x2000;

            var extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION();

            extendedInfo.BasicLimitInformation = info;

            int length          = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
            var extendedInfoPtr = Marshal.AllocHGlobal(length);

            try {
                Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);

                if (!NativeMethods.SetInformationJobObject(handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length))
                {
                    throw new LastWin32ErrorException("Unable to set job information");
                }

                return(handle);
            }
            finally {
                Marshal.FreeHGlobal(extendedInfoPtr);
            }
        }
Пример #4
0
        public Job()
        {
            const uint JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = 0x2000;

            const uint JOB_OBJECT_LIMIT_BREAKAWAY_OK = 0x800;

            _handle = CreateJobObject(IntPtr.Zero, null);

            var info = new JOBOBJECT_BASIC_LIMIT_INFORMATION
            {
                LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | JOB_OBJECT_LIMIT_BREAKAWAY_OK
            };

            var extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION
            {
                BasicLimitInformation = info
            };

            int    length          = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
            IntPtr extendedInfoPtr = Marshal.AllocHGlobal(length);

            Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);

            if (!SetInformationJobObject(_handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length))
            {
                throw new Exception(string.Format("Unable to set information.  Error: {0}", Marshal.GetLastWin32Error()));
            }
        }
 public JOBOBJECT_EXTENDED_LIMIT_INFORMATION(JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation = default, IO_COUNTERS IoInfo = default, System.UIntPtr ProcessMemoryLimit = default, System.UIntPtr JobMemoryLimit = default, System.UIntPtr PeakProcessMemoryUsed = default, System.UIntPtr PeakJobMemoryUsed = default)
 {
     this.BasicLimitInformation = BasicLimitInformation;
     this.IoInfo                = IoInfo;
     this.ProcessMemoryLimit    = ProcessMemoryLimit;
     this.JobMemoryLimit        = JobMemoryLimit;
     this.PeakProcessMemoryUsed = PeakProcessMemoryUsed;
     this.PeakJobMemoryUsed     = PeakJobMemoryUsed;
 }
Пример #6
0
        public static IntPtr Create()
        {
            /*
             * Windows will automatically close any open job handles when our process terminates.
             * This can be verified by using SysInternals' readHandle utility. When the job handle
             * is closed, the child processes will be killed.
             *
             * This feature requires Windows 8 or later. To support Windows 7 requires
             * registry settings to be added if you are using Visual Studio plus an
             * app.manifest change.
             */
            if (!Environment.OSVersion.IsWindows8OrHigher())
            {
                return(IntPtr.Zero);
            }

            // The job name is optional (and can be null) but it helps with diagnostics.
            //  If it's not null, it has to be unique. Use SysInternals' Handle command-line
            //  utility: handle -a ChildProcessTracker
            string jobName   = "ChildProcessTracker" + Process.GetCurrentProcess().Id;
            IntPtr jobHandle = Win32.CreateJobObject(IntPtr.Zero, jobName);

            JOBOBJECT_BASIC_LIMIT_INFORMATION info = new JOBOBJECT_BASIC_LIMIT_INFORMATION
            {
                LimitFlags = JobObjectLimitEnum.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
            };

            // This is the key flag. When our process is killed, Windows will automatically
            //  close the job handle, and when that happens, we want the child processes to
            //  be killed, too.
            JOBOBJECT_EXTENDED_LIMIT_INFORMATION extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION {
                BasicLimitInformation = info
            };

            int    length          = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
            IntPtr extendedInfoPtr = Marshal.AllocHGlobal(length);

            try
            {
                Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);

                if (!Win32.SetInformationJobObject(jobHandle, JobObjectInfoTypeEnum.ExtendedLimitInformation,
                                                   extendedInfoPtr, (uint)length))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
            }
            finally
            {
                Marshal.FreeHGlobal(extendedInfoPtr);
            }

            return(jobHandle);
        }
Пример #7
0
        static void AttachChildProcessToThisProcess(Process proc)
        {
            //Attach 'proc' process to this process, so that it's closed along with this process

            try
            {
                if (ghJob == IntPtr.Zero)
                {
                    ghJob = CreateJobObject(IntPtr.Zero, "");                                   //It will be closed automatically when this process exits or is terminated

                    if (ghJob == IntPtr.Zero)
                    {
                        throw new Win32Exception();
                    }
                }

                JOBOBJECT_BASIC_LIMIT_INFORMATION info = new JOBOBJECT_BASIC_LIMIT_INFORMATION();
                info.LimitFlags = JOBOBJECTLIMIT.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;

                JOBOBJECT_EXTENDED_LIMIT_INFORMATION exInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION();
                exInfo.BasicLimitInformation = info;

                int    nLength   = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
                IntPtr exInfoPtr = Marshal.AllocHGlobal(nLength);

                try
                {
                    Marshal.StructureToPtr(exInfo, exInfoPtr, false);

                    if (!SetInformationJobObject(ghJob, JobObjectInfoType.ExtendedLimitInformation, exInfoPtr, (uint)nLength))
                    {
                        throw new Win32Exception();
                    }

                    //And attach the process
                    if (!AssignProcessToJobObject(ghJob, proc.Handle))
                    {
                        throw new Win32Exception();
                    }
                }
                finally
                {
                    Marshal.FreeHGlobal(exInfoPtr);
                }
            }
            catch (Exception ex)
            {
                //Error
                gEventLog.logMessage(EventLogMsgType.ELM_TYP_Error, "Failed to assign miner job: " + ex.ToString());
                OutputConsoleError("ERROR: Failed to assign miner job: " + ex.ToString());
            }
        }
Пример #8
0
        static ChildProcessTracker()
        {
            // This feature requires Windows 8 or later. To support Windows 7 requires
            //  registry settings to be added if you are using Visual Studio plus an
            //  app.manifest change.
            //  https://stackoverflow.com/a/4232259/386091
            //  https://stackoverflow.com/a/9507862/386091
            if (Environment.OSVersion.Version < new Version(6, 2))
            {
                return;
            }

            // The job name is optional (and can be null) but it helps with diagnostics.
            //  If it's not null, it has to be unique. Use SysInternals' Handle command-line
            //  utility: handle -a ChildProcessTracker
            string jobName = "ChildProcessTracker" + Process.GetCurrentProcess().Id;

            s_jobHandle = CreateJobObject(IntPtr.Zero, jobName);

            var info = new JOBOBJECT_BASIC_LIMIT_INFORMATION
            {
                // This is the key flag. When our process is killed, Windows will automatically
                //  close the job handle, and when that happens, we want the child processes to
                //  be killed, too.
                LimitFlags = JOBOBJECTLIMIT.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
            };

            var extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION
            {
                BasicLimitInformation = info
            };

            int    length          = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
            IntPtr extendedInfoPtr = Marshal.AllocHGlobal(length);

            try
            {
                Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);

                if (!SetInformationJobObject(s_jobHandle, JobObjectInfoType.ExtendedLimitInformation,
                                             extendedInfoPtr, (uint)length))
                {
                    throw new Win32Exception();
                }
            }
            finally
            {
                Marshal.FreeHGlobal(extendedInfoPtr);
            }
        }
Пример #9
0
        static ProcessHelper()
        {
            job = CreateJobObject(IntPtr.Zero, null);

            JOBOBJECT_BASIC_LIMIT_INFORMATION info = new JOBOBJECT_BASIC_LIMIT_INFORMATION();
            info.LimitFlags = 0x2000;

            JOBOBJECT_EXTENDED_LIMIT_INFORMATION extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION();
            extendedInfo.BasicLimitInformation = info;

            int length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
            IntPtr extendedInfoPtr = Marshal.AllocHGlobal(length);
            Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);

            SetInformationJobObject(job, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length);
        }
        public static void Start(Process process = null)
        {
            // this is here to make it so if the player crashes
            // the process it started is killed along with it
            if (!Started)
            {
                if (jobHandle == IntPtr.Zero)
                {
                    jobHandle = CreateJobObject(IntPtr.Zero, null);

                    if (jobHandle == IntPtr.Zero)
                    {
                        throw new JobObjectException("Could not create the Job Object.");
                    }
                }

                JOBOBJECT_BASIC_LIMIT_INFORMATION jobobjectBasicLimitInformation = new JOBOBJECT_BASIC_LIMIT_INFORMATION {
                    LimitFlags = JOB_OBJECT_LIMIT.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
                };

                JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobobjectExtendedLimitInformation = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION {
                    BasicLimitInformation = jobobjectBasicLimitInformation
                };

                int    jobobjectExtendedLimitInformationSize    = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
                IntPtr jobobjectExtendedLimitInformationPointer = Marshal.AllocHGlobal(jobobjectExtendedLimitInformationSize);

                Marshal.StructureToPtr(jobobjectExtendedLimitInformation, jobobjectExtendedLimitInformationPointer, false);

                bool result = SetInformationJobObject(jobHandle, JOBOBJECTINFOCLASS.JobObjectExtendedLimitInformation, jobobjectExtendedLimitInformationPointer, (uint)jobobjectExtendedLimitInformationSize);

                Marshal.FreeHGlobal(jobobjectExtendedLimitInformationPointer);

                if (process == null)
                {
                    process = Process.GetCurrentProcess();
                }

                if (!result || !AssignProcessToJobObject(jobHandle, process.Handle))
                {
                    throw new JobObjectException("Could not set the Job Object Information or assign the Process to the Job Object.");
                }

                Started = true;
            }
        }
Пример #11
0
    public Job()
    {
        m_handle = CreateJobObject(null, null);
        JOBOBJECT_BASIC_LIMIT_INFORMATION info = new JOBOBJECT_BASIC_LIMIT_INFORMATION();

        info.LimitFlags = 0x2000;
        JOBOBJECT_EXTENDED_LIMIT_INFORMATION extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION();

        extendedInfo.BasicLimitInformation = info;
        int    length          = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
        IntPtr extendedInfoPtr = Marshal.AllocHGlobal(length);

        Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);
        if (!SetInformationJobObject(m_handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length))
        {
            throw new Exception(string.Format("Unable to set information.  Error: {0}", Marshal.GetLastWin32Error()));
        }
    }
Пример #12
0
        /// <summary>
        /// Creates a new <see cref="ChildProcessManager"/>.
        /// </summary>
        public ChildProcessManager()
        {
            if (Common.IsPosixEnvironment)
            {
                // On non-Windows operating systems we just track associated processes
                m_childProcesses = new List <WeakReference <Process> >();
            }
            else
            {
                // Let safe handle manage terminations on Windows
                GC.SuppressFinalize(this);

                // On Windows we add child processes to a job object such that when the job
                // is terminated, so are the child processes. Since safe handle ensures proper
                // closing of job handle, child processes will be terminated even if parent
                // process is abnormally terminated
                m_jobHandle = new SafeJobHandle(CreateJobObject(IntPtr.Zero, null));

                JOBOBJECT_BASIC_LIMIT_INFORMATION info = new JOBOBJECT_BASIC_LIMIT_INFORMATION
                {
                    LimitFlags = 0x2000
                };

                JOBOBJECT_EXTENDED_LIMIT_INFORMATION extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION
                {
                    BasicLimitInformation = info
                };

                int length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));

                IntPtr extendedInfoPtr = Marshal.AllocHGlobal(length);
                Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);

                if (!SetInformationJobObject(m_jobHandle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length))
                {
                    throw new InvalidOperationException($"Unable to set information for ChildProcessManager job. Error: {Marshal.GetLastWin32Error()}");
                }
            }
        }
        public JobObject()
        {
            handle = NativeMethods.CreateJobObject(IntPtr.Zero, null);

            var info = new JOBOBJECT_BASIC_LIMIT_INFORMATION
            {
                LimitFlags = KillOnJobClose
            };

            var extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION
            {
                BasicLimitInformation = info
            };

            var length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
            var extendedInfoPtr = Marshal.AllocHGlobal(length);
            Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);

            if (!NativeMethods.SetInformationJobObject(handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length))
            {
                throw new Exception(string.Format("Unable to set information.  Error: {0}", Marshal.GetLastWin32Error()));
            }
        }
Пример #14
0
        public Job()
        {
            handle = CreateJobObject(IntPtr.Zero, null);
            var extendedInfoPtr = IntPtr.Zero;
            var info            = new JOBOBJECT_BASIC_LIMIT_INFORMATION
            {
                LimitFlags = 0x2000
            };

            var extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION
            {
                BasicLimitInformation = info
            };

            try
            {
                int length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
                extendedInfoPtr = Marshal.AllocHGlobal(length);
                Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);

                if (!SetInformationJobObject(handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr,
                                             (uint)length))
                {
                    throw new Exception(string.Format("Unable to set information.  Error: {0}",
                                                      Marshal.GetLastWin32Error()));
                }
            }
            finally
            {
                if (extendedInfoPtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(extendedInfoPtr);
                    extendedInfoPtr = IntPtr.Zero;
                }
            }
        }
Пример #15
0
        public JobObject()
        {
            handle = NativeMethods.CreateJobObject(IntPtr.Zero, null);

            var info = new JOBOBJECT_BASIC_LIMIT_INFORMATION
            {
                LimitFlags = KillOnJobClose
            };

            var extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION
            {
                BasicLimitInformation = info
            };

            var length          = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
            var extendedInfoPtr = Marshal.AllocHGlobal(length);

            Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);

            if (!NativeMethods.SetInformationJobObject(handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length))
            {
                throw new Exception(string.Format("Unable to set information.  Error: {0}", Marshal.GetLastWin32Error()));
            }
        }
Пример #16
0
        public ChildProcessManager()
        {
            _handle = new SafeJobHandle(CreateJobObject(IntPtr.Zero, null));

            var info = new JOBOBJECT_BASIC_LIMIT_INFORMATION
            {
                LimitFlags = 0x2000
            };

            var extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION
            {
                BasicLimitInformation = info
            };

            var length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
            var extendedInfoPtr = Marshal.AllocHGlobal(length);
            Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);

            if (!SetInformationJobObject(_handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr,
                    (uint)length))
            {
                throw new InvalidOperationException($"Unable to set information.  Error: {Marshal.GetLastWin32Error()}");
            }
        }
Пример #17
0
 internal static extern bool SetInformationJobObject(SafeJobObjectHandle hJob, JobObjectInformationClass JobObjectInfoClass, [In] ref JOBOBJECT_BASIC_LIMIT_INFORMATION lpJobObjectInfo, int cbJobObjectInfoLength);
Пример #18
0
 internal static extern bool QueryInformationJobObject(SafeJobObjectHandle hJob, JobObjectInformationClass JobObjectInfoClass, [Out] out JOBOBJECT_BASIC_LIMIT_INFORMATION lpJobObjectInfo, int cbJobObjectInfoLength, IntPtr lpReturnLength);