internal SafeProcessHandle(int processId, SafeWaitHandle handle) : this(handle.DangerousGetHandle(), ownsHandle : false) { ProcessId = processId; _handle = handle; handle.DangerousAddRef(ref _releaseRef); }
public static bool ResetEvent (SafeWaitHandle handle) { bool release = false; try { handle.DangerousAddRef (ref release); return ResetEvent_internal (handle.DangerousGetHandle ()); } finally { if (release) handle.DangerousRelease (); } }
internal static int MsgWaitForMultipleObjects(SafeWaitHandle handle, bool waitAll, int milliseconds, int wakeMask) { int terminationEvent, lastWin32Error; if (handle == null) { terminationEvent = UnsafeNativeMethods.MsgWaitForMultipleObjects(0, null, waitAll, milliseconds, wakeMask); lastWin32Error = Marshal.GetLastWin32Error(); } else { RuntimeHelpers.PrepareConstrainedRegions(); bool fRelease = false; try { handle.DangerousAddRef(ref fRelease); IntPtr[] handles = { handle.DangerousGetHandle() }; terminationEvent = UnsafeNativeMethods.MsgWaitForMultipleObjects(1, handles, waitAll, milliseconds, wakeMask); lastWin32Error = Marshal.GetLastWin32Error(); } finally { if (fRelease) { handle.DangerousRelease(); } } } if (terminationEvent == NativeMethods.WAIT_FAILED) { ThrowWin32ExceptionsIfError(lastWin32Error); } return terminationEvent; }
internal void SetHandleInternal(SafeWaitHandle handle) { safeWaitHandle = handle; waitHandle = handle.DangerousGetHandle(); }
internal void SetHandleInternal(Microsoft.Win32.SafeHandles.SafeWaitHandle handle) { this.safeWaitHandle = handle; this.waitHandle = handle.DangerousGetHandle(); }
internal static int WaitOneNative(SafeWaitHandle waitableSafeHandle, long millisecondsTimeout) { Debug.Assert(millisecondsTimeout >= -1 && millisecondsTimeout <= int.MaxValue); waitableSafeHandle.DangerousAddRef(); try { return LowLevelThread.WaitForSingleObject(waitableSafeHandle.DangerousGetHandle(), (int)millisecondsTimeout); } finally { waitableSafeHandle.DangerousRelease(); } }
public void ResumeThread(SafeWaitHandle threadHandle) { ResumeThread(threadHandle.DangerousGetHandle()); }
static int SignalAndWaitOne (SafeWaitHandle waitHandleToSignal,SafeWaitHandle waitHandleToWaitOn, int millisecondsTimeout, bool hasThreadAffinity, bool exitContext) { bool releaseHandleToSignal = false, releaseHandleToWaitOn = false; try { waitHandleToSignal.DangerousAddRef (ref releaseHandleToSignal); waitHandleToWaitOn.DangerousAddRef (ref releaseHandleToWaitOn); return SignalAndWait_Internal (waitHandleToSignal.DangerousGetHandle (), waitHandleToWaitOn.DangerousGetHandle (), millisecondsTimeout); } finally { if (releaseHandleToSignal) waitHandleToSignal.DangerousRelease (); if (releaseHandleToWaitOn) waitHandleToWaitOn.DangerousRelease (); } }
/// <summary> /// Create a process and attach it to a job. The process is resumed /// by the time the call returns if the call was successful. /// </summary> /// <param name="ExeFileName">Supplies the fully qualified exe file /// name of the main process image.</param> /// <param name="CommandLine">Supplies command line arguments that do /// not include the implicit exe file name argument.</param> /// <param name="Job">Supplies a job handle.</param> /// <param name="BreakawayOk">Supplies true if job breakaway is to be /// considered acceptable.</param> /// <returns>A System.Diagnostics.Process describing the created /// process object.</returns> private static Process CreateProcessInJob(string ExeFileName, string CommandLine, SafeWaitHandle Job, bool BreakawayOk = false) { PROCESS_INFORMATION ProcessInfo; STARTUPINFO StartupInfo; bool Succeeded = false; ProcessInfo.hProcess = IntPtr.Zero; ProcessInfo.hThread = IntPtr.Zero; StartupInfo.cb = 0; StartupInfo.lpReserved = null; StartupInfo.lpDesktop = null; StartupInfo.lpTitle = null; StartupInfo.dwX = 0; StartupInfo.dwY = 0; StartupInfo.dwXSize = 0; StartupInfo.dwYSize = 0; StartupInfo.dwXCountChars = 0; StartupInfo.dwYCountChars = 0; StartupInfo.dwFillAttribute = 0; StartupInfo.dwFlags = (UInt32)STARTFLAGS.UseShowWindow; StartupInfo.wShowWindow = (UInt16)SHOWCMD.SW_HIDE; StartupInfo.cbReserved2 = 0; StartupInfo.lpReserved2 = IntPtr.Zero; StartupInfo.hStdInput = IntPtr.Zero; StartupInfo.hStdOutput = IntPtr.Zero; StartupInfo.hStdError = IntPtr.Zero; StartupInfo.cb = Marshal.SizeOf(StartupInfo); try { string RealCommandLine = String.Format("\"{0}\" {1}", ExeFileName, CommandLine); bool BreakawayTried = false; // // Create the process. // for (; ; ) { if (CreateProcessA(ExeFileName, CommandLine, IntPtr.Zero, IntPtr.Zero, 0, PROCESSCREATIONFLAGS.CreateSuspended | (BreakawayOk && !BreakawayTried ? PROCESSCREATIONFLAGS.CreateBreakawayFromJob : 0), IntPtr.Zero, null, ref StartupInfo, out ProcessInfo) == 0) { int LastError = Marshal.GetLastWin32Error(); ProcessInfo.hProcess = IntPtr.Zero; ProcessInfo.hThread = IntPtr.Zero; if ((LastError == ERROR_ACCESS_DENIED) && (BreakawayOk) && (!BreakawayTried)) { Logger.Log("DatabaseConnector.CreateProcessInJob: Failed to create process with breakaway due to ERROR_ACCESS_DENIED, trying again without breakaway."); BreakawayTried = true; continue; } throw new ApplicationException(String.Format("CreateProcessA(ExeFileName = '{0}', CommandLine = '{1}') failed: {2}", ExeFileName, CommandLine, LastError)); } break; } // // Join it to the job so that it will be cleaned up if the // nwn2server process exits unexpectedly. // if (AssignProcessToJobObject(Job.DangerousGetHandle(), ProcessInfo.hProcess) == 0) { int LastError = Marshal.GetLastWin32Error(); bool ContinueAnyway = false; if (LastError == ERROR_ACCESS_DENIED) { if (BreakawayOk == false) { Logger.Log("DatabaseConnector.CreateProcessInJob: Failed to assign process to job due to ERROR_ACCESS_DENIED, trying with breakaway."); return CreateProcessInJob(ExeFileName, CommandLine, Job, true); } else { Logger.Log("DatabaseConnector.CreateProcessInJob: Failed to assign process to job due to ERROR_ACCESS_DENIED and breakaway failed, ignoring failure."); ContinueAnyway = true; } } if (!ContinueAnyway) throw new ApplicationException("AssignProcessToJobObject failed: " + LastError); } // // Attach a Process object to the process by ID. Since a // handle to the process is currently open, the process ID is // guaranteed to not be recycled in this interval. The .NET // Process object will be used to wait on the process to exit // in the monitor thread. // Process ProcessObject = Process.GetProcessById((int)ProcessInfo.dwProcessId); // // Finally, resume the thread and call it done. // if (ResumeThread(ProcessInfo.hThread) == UInt32.MaxValue) throw new ApplicationException("ResumeThread failed: " + Marshal.GetLastWin32Error()); Succeeded = true; return ProcessObject; } finally { if (ProcessInfo.hProcess != IntPtr.Zero) { if (!Succeeded) TerminateProcess(ProcessInfo.hProcess, 0); CloseHandle(ProcessInfo.hProcess); ProcessInfo.hProcess = IntPtr.Zero; } if (ProcessInfo.hThread != IntPtr.Zero) { CloseHandle(ProcessInfo.hThread); ProcessInfo.hThread = IntPtr.Zero; } } }
/// <summary> /// Configure a job object for use by the database connector. It is /// set up so that once the last job handle lapses, all of the /// processes joined to the job are terminated. /// </summary> /// <param name="Job">Supplies a job object handle.</param> private static void ConfigureJob(SafeWaitHandle Job) { JOBOBJECT_EXTENDED_LIMIT_INFORMATION ExtendedLimit; ExtendedLimit.BasicLimitInformation.PerProcessUserTimeLimit = 0; ExtendedLimit.BasicLimitInformation.PerJobUserTimeLimit = 0; ExtendedLimit.BasicLimitInformation.LimitFlags = 0; ExtendedLimit.BasicLimitInformation.MinimumWorkingSetSize = UIntPtr.Zero; ExtendedLimit.BasicLimitInformation.MaximumWorkingSetSize = UIntPtr.Zero; ExtendedLimit.BasicLimitInformation.ActiveProcessLimit = 0; ExtendedLimit.BasicLimitInformation.Affinity = UIntPtr.Zero; ExtendedLimit.BasicLimitInformation.PriorityClass = 0; ExtendedLimit.BasicLimitInformation.SchedulingClass = 0; ExtendedLimit.IoInfo.ReadOperationCount = 0; ExtendedLimit.IoInfo.WriteOperationCount = 0; ExtendedLimit.IoInfo.OtherOperationCount = 0; ExtendedLimit.IoInfo.ReadTransferCount = 0; ExtendedLimit.IoInfo.WriteTransferCount = 0; ExtendedLimit.IoInfo.OtherTransferCount = 0; ExtendedLimit.ProcessMemoryLimit = UIntPtr.Zero; ExtendedLimit.JobMemoryLimit = UIntPtr.Zero; ExtendedLimit.PeakProcessMemoryUsed = UIntPtr.Zero; ExtendedLimit.PeakJobMemoryUsed = UIntPtr.Zero; // // Set the job to terminate all contained processes on last handle // close (for the job itself), and to terminate all processes that // are in the job and which have an unhandled exception in lieu of // blocking them on the hard error dialog box. // ExtendedLimit.BasicLimitInformation.LimitFlags = JOBOBJECTLIMIT.KillOnJobClose | JOBOBJECTLIMIT.DieOnUnhandledException; int LimitSize = Marshal.SizeOf(ExtendedLimit); IntPtr JobInformation = Marshal.AllocHGlobal(LimitSize); try { Marshal.StructureToPtr(ExtendedLimit, JobInformation, false); if (SetInformationJobObject(Job.DangerousGetHandle(), JOBOBJECTINFOCLASS.ExtendedLimitInformation, JobInformation, (uint)LimitSize) == 0) { throw new ApplicationException("SetInformationJobObject failed: " + Marshal.GetLastWin32Error()); } } finally { Marshal.FreeHGlobal(JobInformation); } }
private static int CreateMutexHandle(bool initiallyOwned, string name, Win32Native.SECURITY_ATTRIBUTES securityAttribute, out SafeWaitHandle mutexHandle) { bool flag = false; bool flag2 = false; bool flag3 = false; Label_0006: flag2 = false; flag3 = false; mutexHandle = Win32Native.CreateMutex(securityAttribute, initiallyOwned, name); int num = Marshal.GetLastWin32Error(); if (!mutexHandle.IsInvalid || (num != 5)) { return num; } RuntimeHelpers.PrepareConstrainedRegions(); try { RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { Thread.BeginThreadAffinity(); flag = true; } mutexHandle = Win32Native.OpenMutex(0x100001, false, name); if (!mutexHandle.IsInvalid) { num = 0xb7; if (Environment.IsW2k3) { SafeWaitHandle handle = Win32Native.OpenMutex(0x100001, false, name); if (!handle.IsInvalid) { RuntimeHelpers.PrepareConstrainedRegions(); try { uint num2 = 0; IntPtr ptr = mutexHandle.DangerousGetHandle(); IntPtr ptr2 = handle.DangerousGetHandle(); IntPtr[] handles = new IntPtr[] { ptr, ptr2 }; num2 = Win32Native.WaitForMultipleObjects(2, handles, true, 0); GC.KeepAlive(handles); if (num2 == uint.MaxValue) { if (Marshal.GetLastWin32Error() != 0x57) { mutexHandle.Dispose(); flag3 = true; } } else { flag2 = true; if ((num2 >= 0) && (num2 < 2)) { Win32Native.ReleaseMutex(mutexHandle); Win32Native.ReleaseMutex(handle); } else if ((num2 >= 0x80) && (num2 < 130)) { Win32Native.ReleaseMutex(mutexHandle); Win32Native.ReleaseMutex(handle); } mutexHandle.Dispose(); } goto Label_0166; } finally { handle.Dispose(); } } mutexHandle.Dispose(); flag3 = true; } } else { num = Marshal.GetLastWin32Error(); } } finally { if (flag) { Thread.EndThreadAffinity(); } } Label_0166: if ((flag2 || flag3) || (num == 2)) { goto Label_0006; } if (num == 0) { num = 0xb7; } return num; }