diff --git a/shadowsocks-csharp/Util/ProcessManagement/Job.cs b/shadowsocks-csharp/Util/ProcessManagement/Job.cs index b79444d6..94443407 100644 --- a/shadowsocks-csharp/Util/ProcessManagement/Job.cs +++ b/shadowsocks-csharp/Util/ProcessManagement/Job.cs @@ -12,17 +12,17 @@ namespace Shadowsocks.Util.ProcessManagement public class Job : IDisposable { [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] - static extern IntPtr CreateJobObject(IntPtr a, string lpName); + private static extern IntPtr CreateJobObject(IntPtr a, string lpName); [DllImport("kernel32.dll")] - static extern bool SetInformationJobObject(IntPtr hJob, JobObjectInfoType infoType, IntPtr lpJobObjectInfo, UInt32 cbJobObjectInfoLength); + private static extern bool SetInformationJobObject(IntPtr hJob, JobObjectInfoType infoType, IntPtr lpJobObjectInfo, UInt32 cbJobObjectInfoLength); [DllImport("kernel32.dll", SetLastError = true)] - static extern bool AssignProcessToJobObject(IntPtr job, IntPtr process); + private static extern bool AssignProcessToJobObject(IntPtr job, IntPtr process); [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] - static extern bool CloseHandle(IntPtr hObject); + private static extern bool CloseHandle(IntPtr hObject); private IntPtr handle; private bool disposed; @@ -30,7 +30,7 @@ namespace Shadowsocks.Util.ProcessManagement public Job() { handle = CreateJobObject(IntPtr.Zero, null); - + var extendedInfoPtr = IntPtr.Zero; var info = new JOBOBJECT_BASIC_LIMIT_INFORMATION { LimitFlags = 0x2000 @@ -41,12 +41,25 @@ namespace Shadowsocks.Util.ProcessManagement 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())); + 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; + } + } } public void Dispose() @@ -78,8 +91,7 @@ namespace Shadowsocks.Util.ProcessManagement if (!succ) { - var err = Marshal.GetLastWin32Error(); - Logging.Error("Failed to call AssignProcessToJobObject! GetLastError=" + err); + Logging.Error("Failed to call AssignProcessToJobObject! GetLastError=" + Marshal.GetLastWin32Error()); } return succ;