|
|
@@ -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; |
|
|
|