Inheritance: System.Threading.WaitHandle
Beispiel #1
0
        IntPtr GetProcessHandle(Kernel32.ProcessAccessFlags access, bool throwIfExited) {
            if (_haveProcessHandle) {
                if (throwIfExited) {
                    // Since haveProcessHandle is true, we know we have the process handle
                    // open with at least SYNCHRONIZE access, so we can wait on it with 
                    // zero timeout to see if the process has exited.
                    ProcessWaitHandle waitHandle = null;
                    try {
                        waitHandle = new ProcessWaitHandle(_processHandle);
                        if (waitHandle.WaitOne(0, false)) {
                            throw new InvalidOperationException("Process has exited");
                        }
                    } finally {
                        waitHandle?.Close();
                    }
                }
                return _processHandle;
            }

            var handle = Kernel32.OpenProcess(access, false, _inner.Id);
            if (throwIfExited && (access & Kernel32.ProcessAccessFlags.QueryInformation) != 0) {
                int exitCode;
                if (Kernel32.GetExitCodeProcess(handle, out exitCode) && exitCode != Kernel32.STILL_ACTIVE) {
                    throw new InvalidOperationException("Process has exited");
                }
            }

            return handle;
        }
Beispiel #2
0
 /// <devdoc>
 ///     Make sure we are watching for a process exit.
 /// </devdoc>
 /// <internalonly/>
 private void EnsureWatchingForExit()
 {
     if (!_watchingForExit)
     {
         lock (this)
         {
             if (!_watchingForExit)
             {
                 Debug.Assert(_haveProcessHandle, "Process.EnsureWatchingForExit called with no process handle");
                 Debug.Assert(Associated, "Process.EnsureWatchingForExit called with no associated process");
                 _watchingForExit = true;
                 try
                 {
                     _waitHandle           = new ProcessWaitHandle(_processHandle);
                     _registeredWaitHandle = ThreadPool.RegisterWaitForSingleObject(_waitHandle,
                                                                                    new WaitOrTimerCallback(CompletionCallback), null, -1, true);
                 }
                 catch
                 {
                     _watchingForExit = false;
                     throw;
                 }
             }
         }
     }
 }
Beispiel #3
0
        /// <summary>
        /// Instructs the Process component to wait the specified number of milliseconds for the associated process to exit.
        /// </summary>
        private bool WaitForExitCore(int milliseconds)
        {
            SafeProcessHandle handle = null;

            try
            {
                handle = GetProcessHandle(Interop.Advapi32.ProcessOptions.SYNCHRONIZE, false);
                if (handle.IsInvalid)
                {
                    return(true);
                }

                using (ProcessWaitHandle processWaitHandle = new ProcessWaitHandle(handle))
                {
                    return(_signaled = processWaitHandle.WaitOne(milliseconds));
                }
            }
            finally
            {
                // If we have a hard timeout, we cannot wait for the streams
                if (_output != null && milliseconds == Timeout.Infinite)
                {
                    _output.WaitUtilEOF();
                }

                if (_error != null && milliseconds == Timeout.Infinite)
                {
                    _error.WaitUtilEOF();
                }

                handle?.Dispose();
            }
        }
Beispiel #4
0
        /// <summary>Checks whether the process has exited and updates state accordingly.</summary>
        private void UpdateHasExited()
        {
            SafeProcessHandle handle = null;

            try
            {
                handle = GetProcessHandle(Interop.Advapi32.ProcessOptions.PROCESS_QUERY_LIMITED_INFORMATION | Interop.Advapi32.ProcessOptions.SYNCHRONIZE, false);
                if (handle.IsInvalid)
                {
                    _exited = true;
                }
                else
                {
                    int localExitCode;

                    // Although this is the wrong way to check whether the process has exited,
                    // it was historically the way we checked for it, and a lot of code then took a dependency on
                    // the fact that this would always be set before the pipes were closed, so they would read
                    // the exit code out after calling ReadToEnd() or standard output or standard error. In order
                    // to allow 259 to function as a valid exit code and to break as few people as possible that
                    // took the ReadToEnd dependency, we check for an exit code before doing the more correct
                    // check to see if we have been signaled.
                    if (Interop.Kernel32.GetExitCodeProcess(handle, out localExitCode) && localExitCode != Interop.Kernel32.HandleOptions.STILL_ACTIVE)
                    {
                        _exitCode = localExitCode;
                        _exited   = true;
                    }
                    else
                    {
                        // The best check for exit is that the kernel process object handle is invalid,
                        // or that it is valid and signaled.  Checking if the exit code != STILL_ACTIVE
                        // does not guarantee the process is closed,
                        // since some process could return an actual STILL_ACTIVE exit code (259).
                        if (!_signaled) // if we just came from WaitForExit, don't repeat
                        {
                            using (var wh = new ProcessWaitHandle(handle))
                            {
                                _signaled = wh.WaitOne(0);
                            }
                        }
                        if (_signaled)
                        {
                            if (!Interop.Kernel32.GetExitCodeProcess(handle, out localExitCode))
                            {
                                throw new Win32Exception();
                            }

                            _exitCode = localExitCode;
                            _exited   = true;
                        }
                    }
                }
            }
            finally
            {
                ReleaseProcessHandle(handle);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Instructs the Process component to wait the specified number of milliseconds for the associated process to exit.
        /// </summary>
        public bool WaitForExit(int milliseconds)
        {
            SafeProcessHandle handle = null;
            bool exited;
            ProcessWaitHandle processWaitHandle = null;

            try
            {
                handle = GetProcessHandle(Interop.SYNCHRONIZE, false);
                if (handle.IsInvalid)
                {
                    exited = true;
                }
                else
                {
                    processWaitHandle = new ProcessWaitHandle(handle);
                    if (processWaitHandle.WaitOne(milliseconds))
                    {
                        exited    = true;
                        _signaled = true;
                    }
                    else
                    {
                        exited    = false;
                        _signaled = false;
                    }
                }
            }
            finally
            {
                if (processWaitHandle != null)
                {
                    processWaitHandle.Dispose();
                }

                // If we have a hard timeout, we cannot wait for the streams
                if (_output != null && milliseconds == -1)
                {
                    _output.WaitUtilEOF();
                }

                if (_error != null && milliseconds == -1)
                {
                    _error.WaitUtilEOF();
                }

                ReleaseProcessHandle(handle);
            }

            if (exited && _watchForExit)
            {
                RaiseOnExited();
            }

            return(exited);
        }
Beispiel #6
0
        /// <devdoc>
        ///     Gets a short-term handle to the process, with the given access.
        ///     If a handle is stored in current process object, then use it.
        ///     Note that the handle we stored in current process object will have all access we need.
        /// </devdoc>
        /// <internalonly/>
        private SafeProcessHandle GetProcessHandle(int access, bool throwIfExited)
        {
#if FEATURE_TRACESWITCH
            Debug.WriteLineIf(_processTracing.TraceVerbose, "GetProcessHandle(access = 0x" + access.ToString("X8", CultureInfo.InvariantCulture) + ", throwIfExited = " + throwIfExited + ")");
#if DEBUG
            if (_processTracing.TraceVerbose)
            {
                StackFrame calledFrom = new StackTrace(true).GetFrame(0);
                Debug.WriteLine("   called from " + calledFrom.GetFileName() + ", line " + calledFrom.GetFileLineNumber());
            }
#endif
#endif
            if (_haveProcessHandle)
            {
                if (throwIfExited)
                {
                    // Since haveProcessHandle is true, we know we have the process handle
                    // open with at least SYNCHRONIZE access, so we can wait on it with
                    // zero timeout to see if the process has exited.
                    using (ProcessWaitHandle waitHandle = new ProcessWaitHandle(_processHandle))
                    {
                        if (waitHandle.WaitOne(0))
                        {
                            if (_haveProcessId)
                            {
                                throw new InvalidOperationException(SR.Format(SR.ProcessHasExited, _processId.ToString(CultureInfo.CurrentCulture)));
                            }
                            else
                            {
                                throw new InvalidOperationException(SR.ProcessHasExitedNoId);
                            }
                        }
                    }
                }

                // If we dispose of our contained handle we'll be in a bad state. NetFX dealt with this
                // by doing a try..finally around every usage of GetProcessHandle and only disposed if
                // it wasn't our handle.
                return(new SafeProcessHandle(_processHandle.DangerousGetHandle(), ownsHandle: false));
            }
            else
            {
                EnsureState(State.HaveId | State.IsLocal);
                SafeProcessHandle handle = SafeProcessHandle.InvalidHandle;
                handle = ProcessManager.OpenProcess(_processId, access, throwIfExited);
                if (throwIfExited && (access & Interop.Advapi32.ProcessOptions.PROCESS_QUERY_INFORMATION) != 0)
                {
                    if (Interop.Kernel32.GetExitCodeProcess(handle, out _exitCode) && _exitCode != Interop.Kernel32.HandleOptions.STILL_ACTIVE)
                    {
                        throw new InvalidOperationException(SR.Format(SR.ProcessHasExited, _processId.ToString(CultureInfo.CurrentCulture)));
                    }
                }
                return(handle);
            }
        }
Beispiel #7
0
        /// <devdoc>
        ///     Gets a short-term handle to the process, with the given access.
        ///     If a handle is stored in current process object, then use it.
        ///     Note that the handle we stored in current process object will have all access we need.
        /// </devdoc>
        /// <internalonly/>
        private SafeProcessHandle GetProcessHandle(int access, bool throwIfExited)
        {
#if FEATURE_TRACESWITCH
            Debug.WriteLineIf(_processTracing.TraceVerbose, "GetProcessHandle(access = 0x" + access.ToString("X8", CultureInfo.InvariantCulture) + ", throwIfExited = " + throwIfExited + ")");
#if DEBUG
            if (_processTracing.TraceVerbose)
            {
                StackFrame calledFrom = new StackTrace(true).GetFrame(0);
                Debug.WriteLine("   called from " + calledFrom.GetFileName() + ", line " + calledFrom.GetFileLineNumber());
            }
#endif
#endif
            if (_haveProcessHandle)
            {
                if (throwIfExited)
                {
                    // Since haveProcessHandle is true, we know we have the process handle
                    // open with at least SYNCHRONIZE access, so we can wait on it with
                    // zero timeout to see if the process has exited.
                    using (ProcessWaitHandle waitHandle = new ProcessWaitHandle(_processHandle))
                    {
                        if (waitHandle.WaitOne(0))
                        {
                            if (_haveProcessId)
                            {
                                throw new InvalidOperationException(SR.Format(SR.ProcessHasExited, _processId.ToString(CultureInfo.CurrentCulture)));
                            }
                            else
                            {
                                throw new InvalidOperationException(SR.ProcessHasExitedNoId);
                            }
                        }
                    }
                }
                return(_processHandle);
            }
            else
            {
                EnsureState(State.HaveId | State.IsLocal);
                SafeProcessHandle handle = SafeProcessHandle.InvalidHandle;
                handle = ProcessManager.OpenProcess(_processId, access, throwIfExited);
                if (throwIfExited && (access & Interop.mincore.ProcessOptions.PROCESS_QUERY_INFORMATION) != 0)
                {
                    if (Interop.mincore.GetExitCodeProcess(handle, out _exitCode) && _exitCode != Interop.mincore.HandleOptions.STILL_ACTIVE)
                    {
                        throw new InvalidOperationException(SR.Format(SR.ProcessHasExited, _processId.ToString(CultureInfo.CurrentCulture)));
                    }
                }
                return(handle);
            }
        }
Beispiel #8
0
        /// <summary>
        /// Instructs the Process component to wait the specified number of milliseconds for the associated process to exit.
        /// </summary>
        private bool WaitForExitCore(int milliseconds)
        {
            SafeProcessHandle handle = null;
            bool exited;
            ProcessWaitHandle processWaitHandle = null;

            try
            {
                handle = GetProcessHandle(Interop.Advapi32.ProcessOptions.SYNCHRONIZE, false);
                if (handle.IsInvalid)
                {
                    exited = true;
                }
                else
                {
                    processWaitHandle = new ProcessWaitHandle(handle);
                    if (processWaitHandle.WaitOne(milliseconds))
                    {
                        exited    = true;
                        _signaled = true;
                    }
                    else
                    {
                        exited    = false;
                        _signaled = false;
                    }
                }
            }
            finally
            {
                if (processWaitHandle != null)
                {
                    processWaitHandle.Dispose();
                }

                // If we have a hard timeout, we cannot wait for the streams
                if (_output != null && milliseconds == Timeout.Infinite)
                {
                    _output.WaitUtilEOF();
                }

                if (_error != null && milliseconds == Timeout.Infinite)
                {
                    _error.WaitUtilEOF();
                }

                ReleaseProcessHandle(handle);
            }

            return(exited);
        }
Beispiel #9
0
        /// <summary>
        /// Instructs the Process component to wait the specified number of milliseconds for the associated process to exit.
        /// </summary>
        private bool WaitForExitCore(int milliseconds)
        {
            SafeProcessHandle handle = null;
            bool exited;
            ProcessWaitHandle processWaitHandle = null;
            try
            {
                handle = GetProcessHandle(Interop.mincore.ProcessOptions.SYNCHRONIZE, false);
                if (handle.IsInvalid)
                {
                    exited = true;
                }
                else
                {
                    processWaitHandle = new ProcessWaitHandle(handle);
                    if (processWaitHandle.WaitOne(milliseconds))
                    {
                        exited = true;
                        _signaled = true;
                    }
                    else
                    {
                        exited = false;
                        _signaled = false;
                    }
                }
            }
            finally
            {
                if (processWaitHandle != null)
                {
                    processWaitHandle.Dispose();
                }

                // If we have a hard timeout, we cannot wait for the streams
                if (_output != null && milliseconds == Timeout.Infinite)
                {
                    _output.WaitUtilEOF();
                }

                if (_error != null && milliseconds == Timeout.Infinite)
                {
                    _error.WaitUtilEOF();
                }

                ReleaseProcessHandle(handle);
            }

            return exited;
        }
            public WorkerProcess(ClipboardAccess clipboard, WmiSession wmisession, IExceptionHandler exceptionhandler, IWorkerProcessHandler wphandler, IntPtr consoletoken)
            {
                this.clipboard = clipboard;
                this.wmisession = wmisession;
                this.exceptionhandler = exceptionhandler;
                this.wphandler = wphandler;

                workerlock = new object();
                try
                {
                    comms = new CommServer(this);
                }
                catch (Exception e)
                {
                    wmisession.Log("Comms server failed to start:" + e.ToString());
                    throw;
                }
                try
                {
                    string path = (string)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Citrix\\XenTools", "Install_Dir", "");
                    string fullpath = string.Format("{0}\\XenDpriv.exe", path);
                    string cmdline = string.Format("XenDpriv.exe {0}", comms.secret);
                    this.worker = new SafeWaitHandle(Win32Impl.CreateUserProcess(consoletoken, fullpath, cmdline), true);
                    workerWaiter = new ProcessWaitHandle(this.worker);
                    registeredWorkerWaiter = ThreadPool.RegisterWaitForSingleObject(workerWaiter, handleWorker, null, Timeout.Infinite, true);
                    this.workerrunning = true;
                    wmisession.Log("Worker Process spawned");
                }
                catch(Exception e)
                {
                    wmisession.Log("Worker process spawn exception : " + e.ToString());
                    comms.CloseMessagePipes();

                    throw;
                }
            }
        private static unsafe int ExecWaitWithCaptureUnimpersonated(SafeUserTokenHandle userToken, string cmd, string currentDir, TempFileCollection tempFiles, ref string outputName, ref string errorName, string trueCmdLine) {

            IntSecurity.UnmanagedCode.Demand();

            FileStream output;
            FileStream error;

            int retValue = 0;

            if (outputName == null || outputName.Length == 0)
                outputName = tempFiles.AddExtension("out");

            if (errorName == null || errorName.Length == 0)
                errorName = tempFiles.AddExtension("err");

            // Create the files
            output = CreateInheritedFile(outputName);
            error = CreateInheritedFile(errorName);

            bool success = false;
            SafeNativeMethods.PROCESS_INFORMATION pi = new SafeNativeMethods.PROCESS_INFORMATION();
            SafeProcessHandle procSH = new SafeProcessHandle();
            SafeThreadHandle threadSH = new SafeThreadHandle();
            SafeUserTokenHandle primaryToken = null;

            try {
                // Output the command line...
                StreamWriter sw = new StreamWriter(output, Encoding.UTF8);
                sw.Write(currentDir);
                sw.Write("> ");
                // 'true' command line is used in case the command line points to
                // a response file
                sw.WriteLine(trueCmdLine != null ? trueCmdLine : cmd);
                sw.WriteLine();
                sw.WriteLine();
                sw.Flush();

                NativeMethods.STARTUPINFO si = new NativeMethods.STARTUPINFO();

                si.cb = Marshal.SizeOf(si);
#if FEATURE_PAL
                si.dwFlags = NativeMethods.STARTF_USESTDHANDLES;
#else //!FEATURE_PAL
                si.dwFlags = NativeMethods.STARTF_USESTDHANDLES | NativeMethods.STARTF_USESHOWWINDOW;
                si.wShowWindow = NativeMethods.SW_HIDE;
#endif //!FEATURE_PAL
                si.hStdOutput = output.SafeFileHandle;
                si.hStdError = error.SafeFileHandle;
                si.hStdInput = new SafeFileHandle(UnsafeNativeMethods.GetStdHandle(NativeMethods.STD_INPUT_HANDLE), false);

                //
                // Prepare the environment
                //
#if PLATFORM_UNIX

                StringDictionary environment = new CaseSensitiveStringDictionary();

#else

                StringDictionary environment = new StringDictionary ();

#endif // PLATFORM_UNIX

                // Add the current environment
                foreach ( DictionaryEntry entry in Environment.GetEnvironmentVariables () )
                    environment[(string) entry.Key] = (string) entry.Value;

                // Add the flag to indicate restricted security in the process
                environment["_ClrRestrictSecAttributes"] = "1";

                #if DEBUG
                environment["OANOCACHE"] = "1";
                #endif

                // set up the environment block parameter
                byte[] environmentBytes = EnvironmentBlock.ToByteArray(environment, false);
                fixed (byte* environmentBytesPtr = environmentBytes) {
                    IntPtr environmentPtr = new IntPtr((void*)environmentBytesPtr);

                    if (userToken == null || userToken.IsInvalid) {
                        RuntimeHelpers.PrepareConstrainedRegions();
                        try {} finally {
                           success = NativeMethods.CreateProcess(
                                                       null,       // String lpApplicationName, 
                                                       new StringBuilder(cmd), // String lpCommandLine, 
                                                       null,       // SECURITY_ATTRIBUTES lpProcessAttributes, 
                                                       null,       // SECURITY_ATTRIBUTES lpThreadAttributes, 
                                                       true,       // bool bInheritHandles, 
                                                       0,          // int dwCreationFlags, 
                                                       environmentPtr, // IntPtr lpEnvironment, 
                                                       currentDir, // String lpCurrentDirectory, 
                                                       si,         // STARTUPINFO lpStartupInfo, 
                                                       pi);        // PROCESS_INFORMATION lpProcessInformation);
                            if ( pi.hProcess!= (IntPtr)0 && pi.hProcess!= (IntPtr)NativeMethods.INVALID_HANDLE_VALUE)
                                procSH.InitialSetHandle(pi.hProcess);  
                            if ( pi.hThread != (IntPtr)0 && pi.hThread != (IntPtr)NativeMethods.INVALID_HANDLE_VALUE)
                               threadSH.InitialSetHandle(pi.hThread);
                        }
                    }
                    else {
#if FEATURE_PAL
                        throw new NotSupportedException();
#else
                        success = SafeUserTokenHandle.DuplicateTokenEx(
                                                    userToken,
                                                    NativeMethods.TOKEN_ALL_ACCESS,
                                                    null,
                                                    NativeMethods.IMPERSONATION_LEVEL_SecurityImpersonation,
                                                    NativeMethods.TOKEN_TYPE_TokenPrimary,
                                                    out primaryToken
                                                    );


                        if (success) {
                            RuntimeHelpers.PrepareConstrainedRegions();
                            try {} finally {
                               success = NativeMethods.CreateProcessAsUser(
                                                           primaryToken,  // int token,
                                                           null,       // String lpApplicationName, 
                                                           cmd,        // String lpCommandLine, 
                                                           null,       // SECURITY_ATTRIBUTES lpProcessAttributes, 
                                                           null,       // SECURITY_ATTRIBUTES lpThreadAttributes, 
                                                           true,       // bool bInheritHandles, 
                                                           0,          // int dwCreationFlags, 
                                                           new HandleRef(null, environmentPtr), // IntPtr lpEnvironment, 
                                                           currentDir, // String lpCurrentDirectory, 
                                                           si,         // STARTUPINFO lpStartupInfo, 
                                                           pi);        // PROCESS_INFORMATION lpProcessInformation);
                               if ( pi.hProcess!= (IntPtr)0 && pi.hProcess!= (IntPtr)NativeMethods.INVALID_HANDLE_VALUE)
                                   procSH.InitialSetHandle(pi.hProcess);  
                               if ( pi.hThread != (IntPtr)0 && pi.hThread != (IntPtr)NativeMethods.INVALID_HANDLE_VALUE)
                                  threadSH.InitialSetHandle(pi.hThread);
                            }
                        }
#endif // !FEATURE_PAL
                    }
                }
            }
            finally {
                // Close the file handles
                if (!success && (primaryToken != null && !primaryToken.IsInvalid)) {
                    primaryToken.Close();
                    primaryToken = null;
                }

                output.Close();
                error.Close();
            }
            
            if (success) {

                try {
                    bool signaled;
                    ProcessWaitHandle pwh = null;
                    try {
                        pwh = new ProcessWaitHandle(procSH);
                        signaled = pwh.WaitOne(ProcessTimeOut, false);
                    } finally {
                        if (pwh != null)
                            pwh.Close();
                    }

                    // Check for timeout
                    if (!signaled) {
                        throw new ExternalException(SR.GetString(SR.ExecTimeout, cmd), NativeMethods.WAIT_TIMEOUT);
                    }

                    // Check the process's exit code
                    int status = NativeMethods.STILL_ACTIVE;
                    if (!NativeMethods.GetExitCodeProcess(procSH, out status)) {
                        throw new ExternalException(SR.GetString(SR.ExecCantGetRetCode, cmd), Marshal.GetLastWin32Error());
                    }

                    retValue = status;
                }
                finally {
                    procSH.Close();
                    threadSH.Close();
                    if (primaryToken != null && !primaryToken.IsInvalid)
                        primaryToken.Close();
                }
            }
            else {
                int err = Marshal.GetLastWin32Error();
                if (err == NativeMethods.ERROR_NOT_ENOUGH_MEMORY)
                    throw new OutOfMemoryException();

                Win32Exception win32Exception = new Win32Exception(err);
                ExternalException ex = new ExternalException(SR.GetString(SR.ExecCantExec, cmd), win32Exception);
                throw ex;
            }

            return retValue;
        }
        private unsafe void VerifyLifetime(InstanceEntry* currentInstancePointer) {
            Debug.Assert(currentInstancePointer->RefCount != 0, "RefCount must be 1 for instances passed to VerifyLifetime");

            CounterEntry* counter = (CounterEntry*) ResolveOffset(currentInstancePointer->FirstCounterOffset, CounterEntrySize);
            if (counter->LifetimeOffset != 0) {
                ProcessLifetimeEntry* lifetime = (ProcessLifetimeEntry*) ResolveOffset(counter->LifetimeOffset, ProcessLifetimeEntrySize);
                if (lifetime->LifetimeType == (int) PerformanceCounterInstanceLifetime.Process) {
                    int pid = lifetime->ProcessId;
                    long startTime = lifetime->StartupTime;

                    if (pid != 0) {

                        // Optimize for this process
                        if (pid == ProcessData.ProcessId) {
                            if ((ProcessData.StartupTime != -1) && (startTime != -1) && (ProcessData.StartupTime != startTime)) {
                                // Process id got recycled.  Reclaim this instance. 
                                currentInstancePointer->RefCount = 0;
                                return;
                            }
                        }
                        else {
                            long processStartTime;
                            using (SafeProcessHandle procHandle = SafeProcessHandle.OpenProcess(NativeMethods.PROCESS_QUERY_INFORMATION, false, pid)) {
                                int error = Marshal.GetLastWin32Error();
                                if ((error == NativeMethods.ERROR_INVALID_PARAMETER) && procHandle.IsInvalid) {
                                    // The process is dead.  Reclaim this instance.  Note that we only clear the refcount here.  
                                    // If we tried to clear the pid and startup time as well, we would have a ---- where
                                    // we could clear the pid/startup time but not the refcount. 
                                    currentInstancePointer->RefCount = 0;
                                    return;
                                }

                                // Defer cleaning the instance when we had previously encountered errors in 
                                // recording process start time (i.e, when startTime == -1) until after the 
                                // process id is not valid (which will be caught in the if check above)
                                if (!procHandle.IsInvalid && startTime != -1) {
                                    long temp;
                                    if (NativeMethods.GetProcessTimes(procHandle, out processStartTime, out temp, out temp, out temp)) {
                                        if (processStartTime != startTime) {
                                            // The process is dead but a new one is using the same pid.  Reclaim this instance. 
                                            currentInstancePointer->RefCount = 0;
                                            return;
                                        }
                                    }
                                }
                            }

                            // Check to see if the process handle has been signaled by the kernel.  If this is the case then it's safe
                            // to reclaim the instance as the process is in the process of exiting.
                            using (SafeProcessHandle procHandle = SafeProcessHandle.OpenProcess(NativeMethods.SYNCHRONIZE, false, pid)) {
                                if (!procHandle.IsInvalid) {
                                    using (ProcessWaitHandle wh = new ProcessWaitHandle(procHandle)) {
                                        if (wh.WaitOne(0, false)) {
                                            // Process has exited
                                            currentInstancePointer->RefCount = 0;
                                            return;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    
                }
            }
        }
Beispiel #13
0
 private SafeProcessHandle GetProcessHandle(int access, bool throwIfExited)
 {
     if (haveProcessHandle)
     {
         if (throwIfExited)
         {
             ProcessWaitHandle processWaitHandle = null;
             try
             {
                 processWaitHandle = new ProcessWaitHandle(m_processHandle);
                 if (processWaitHandle.WaitOne(0, false))
                 {
                     if (haveProcessId)
                     {
                         throw new InvalidOperationException("ProcessHasExited");
                     }
                     throw new InvalidOperationException("ProcessHasExitedNoId");
                 }
             }
             finally
             {
                 if (processWaitHandle != null)
                 {
                     processWaitHandle.Close();
                 }
             }
         }
         return m_processHandle;
     }
     EnsureState((Process2.State)3);
     SafeProcessHandle safeProcessHandle = SafeProcessHandle.InvalidHandle;
     safeProcessHandle = ProcessManager.OpenProcess(processId, access, throwIfExited);
     if (throwIfExited && (access & 1024) != 0 && NativeMethods.GetExitCodeProcess(safeProcessHandle, out exitCode) && exitCode != 259)
     {
         throw new InvalidOperationException();
     }
     return safeProcessHandle;
 }
Beispiel #14
0
 public bool WaitForExit(int milliseconds)
 {
     SafeProcessHandle safeProcessHandle = null;
     ProcessWaitHandle processWaitHandle = null;
     bool flag;
     try
     {
         safeProcessHandle = GetProcessHandle(1048576, false);
         if (safeProcessHandle.IsInvalid)
         {
             flag = true;
         }
         else
         {
             processWaitHandle = new ProcessWaitHandle(safeProcessHandle);
             if (processWaitHandle.WaitOne(milliseconds, false))
             {
                 flag = true;
                 signaled = true;
             }
             else
             {
                 flag = false;
                 signaled = false;
             }
         }
     }
     finally
     {
         if (processWaitHandle != null)
         {
             processWaitHandle.Close();
         }
         if (output != null && milliseconds == -1)
         {
             output.WaitUtilEOF();
         }
         if (error != null && milliseconds == -1)
         {
             error.WaitUtilEOF();
         }
         ReleaseProcessHandle(safeProcessHandle);
     }
     if (flag && watchForExit)
     {
         RaiseOnExited();
     }
     return flag;
 }
 public bool WaitForExit(int milliseconds)
 {
     Microsoft.Win32.SafeHandles.SafeProcessHandle processHandle = null;
     bool flag;
     ProcessWaitHandle handle2 = null;
     try
     {
         processHandle = this.GetProcessHandle(0x100000, false);
         if (processHandle.IsInvalid)
         {
             flag = true;
         }
         else
         {
             handle2 = new ProcessWaitHandle(processHandle);
             if (handle2.WaitOne(milliseconds, false))
             {
                 flag = true;
                 this.signaled = true;
             }
             else
             {
                 flag = false;
                 this.signaled = false;
             }
         }
     }
     finally
     {
         if (handle2 != null)
         {
             handle2.Close();
         }
         if ((this.output != null) && (milliseconds == -1))
         {
             this.output.WaitUtilEOF();
         }
         if ((this.error != null) && (milliseconds == -1))
         {
             this.error.WaitUtilEOF();
         }
         this.ReleaseProcessHandle(processHandle);
     }
     if (flag && this.watchForExit)
     {
         this.RaiseOnExited();
     }
     return flag;
 }
 private Microsoft.Win32.SafeHandles.SafeProcessHandle GetProcessHandle(int access, bool throwIfExited)
 {
     if (this.haveProcessHandle)
     {
         if (throwIfExited)
         {
             ProcessWaitHandle handle = null;
             try
             {
                 handle = new ProcessWaitHandle(this.m_processHandle);
                 if (handle.WaitOne(0, false))
                 {
                     if (this.haveProcessId)
                     {
                         throw new InvalidOperationException(SR.GetString("ProcessHasExited", new object[] { this.processId.ToString(CultureInfo.CurrentCulture) }));
                     }
                     throw new InvalidOperationException(SR.GetString("ProcessHasExitedNoId"));
                 }
             }
             finally
             {
                 if (handle != null)
                 {
                     handle.Close();
                 }
             }
         }
         return this.m_processHandle;
     }
     this.EnsureState(State.IsLocal | State.HaveId);
     Microsoft.Win32.SafeHandles.SafeProcessHandle invalidHandle = Microsoft.Win32.SafeHandles.SafeProcessHandle.InvalidHandle;
     invalidHandle = ProcessManager.OpenProcess(this.processId, access, throwIfExited);
     if ((throwIfExited && ((access & 0x400) != 0)) && (Microsoft.Win32.NativeMethods.GetExitCodeProcess(invalidHandle, out this.exitCode) && (this.exitCode != 0x103)))
     {
         throw new InvalidOperationException(SR.GetString("ProcessHasExited", new object[] { this.processId.ToString(CultureInfo.CurrentCulture) }));
     }
     return invalidHandle;
 }
		void WaitForExitAsyncCallback(object context, bool wasSignaled)
		{
			waitForExitAsyncRegisteredWaitHandle.Unregister(null);
			waitForExitAsyncRegisteredWaitHandle = null;
			waitForExitAsyncWaitHandle.Close();
			waitForExitAsyncWaitHandle = null;
			// Wait until the output is processed
//			if (standardOutputTask != null)
//				await standardOutputTask;
//			if (standardErrorTask != null)
//				await standardErrorTask;
			waitForExitTCS.SetResult(null);
		}
		/// <summary>
		/// Asynchronously waits for the process to exit.
		/// </summary>
		public Task WaitForExitAsync()
		{
			if (hasExited)
				return Task.FromResult(true);
			if (!wasStarted)
				throw new InvalidOperationException("Process was not yet started");
			if (safeProcessHandle.IsClosed)
				throw new ObjectDisposedException("ProcessRunner");
			lock (lockObj) {
				if (waitForExitTCS == null) {
					waitForExitTCS = new TaskCompletionSource<object>();
					waitForExitAsyncWaitHandle = new ProcessWaitHandle(safeProcessHandle);
					waitForExitAsyncRegisteredWaitHandle = ThreadPool.RegisterWaitForSingleObject(waitForExitAsyncWaitHandle, WaitForExitAsyncCallback, null, -1, true);
				}
				return waitForExitTCS.Task;
			}
		}
		public bool WaitForExit(int millisecondsTimeout)
		{
			if (hasExited)
				return true;
			if (!wasStarted)
				throw new InvalidOperationException("Process was not yet started");
			if (safeProcessHandle.IsClosed)
				throw new ObjectDisposedException("ProcessRunner");
			using (var waitHandle = new ProcessWaitHandle(safeProcessHandle)) {
				if (waitHandle.WaitOne(millisecondsTimeout, false)) {
					if (!GetExitCodeProcess(safeProcessHandle, out exitCode))
						throw new Win32Exception();
					// Wait until the output is processed
//					if (standardOutputTask != null)
//						standardOutputTask.Wait();
//					if (standardErrorTask != null)
//						standardErrorTask.Wait();
					hasExited = true;
				}
			}
			return hasExited;
		}
Beispiel #20
0
        public bool WaitForExitSafe(int milliseconds) {
            var handle = IntPtr.Zero;
            bool exited;
            ProcessWaitHandle processWaitHandle = null;

            try {
                handle = GetProcessHandle(Kernel32.ProcessAccessFlags.Synchronize, false);
                if (handle == IntPtr.Zero || handle == new IntPtr(-1)) {
                    exited = true;
                } else {
                    processWaitHandle = new ProcessWaitHandle(handle);
                    if (processWaitHandle.WaitOne(milliseconds, false)) {
                        exited = true;
                        _signaled = true;
                    } else {
                        exited = false;
                        _signaled = false;
                    }
                }
            } finally {
                processWaitHandle?.Close();
                ReleaseProcessHandle(handle);
            }

            if (exited && _watchForExit) {
                RaiseOnExited();
            }

            return exited;
        }
Beispiel #21
0
		void StartExitCallbackIfNeeded ()
		{
			lock (thisLock) {
				bool start = (exitWaitHandle == null && enableRaisingEvents && exited_event != null);
				if (start && process_handle != IntPtr.Zero) {
					WaitOrTimerCallback cb = new WaitOrTimerCallback (CBOnExit);
					ProcessWaitHandle h = new ProcessWaitHandle (process_handle);
					exitWaitHandle = ThreadPool.RegisterWaitForSingleObject (h, cb, this, -1, true);
				}
			}
		}
 private unsafe void VerifyLifetime(InstanceEntry* currentInstancePointer)
 {
     CounterEntry* entryPtr = (CounterEntry*) this.ResolveOffset(currentInstancePointer.FirstCounterOffset, CounterEntrySize);
     if (entryPtr->LifetimeOffset != 0)
     {
         ProcessLifetimeEntry* entryPtr2 = (ProcessLifetimeEntry*) this.ResolveOffset(entryPtr->LifetimeOffset, ProcessLifetimeEntrySize);
         if (entryPtr2->LifetimeType == 1)
         {
             int processId = entryPtr2->ProcessId;
             long startupTime = entryPtr2->StartupTime;
             if (processId != 0)
             {
                 if (processId == ProcessData.ProcessId)
                 {
                     if (((ProcessData.StartupTime != -1L) && (startupTime != -1L)) && (ProcessData.StartupTime != startupTime))
                     {
                         currentInstancePointer.RefCount = 0;
                     }
                 }
                 else
                 {
                     using (Microsoft.Win32.SafeHandles.SafeProcessHandle handle = Microsoft.Win32.SafeHandles.SafeProcessHandle.OpenProcess(0x400, false, processId))
                     {
                         long num3;
                         long num5;
                         if ((Marshal.GetLastWin32Error() == 0x57) && handle.IsInvalid)
                         {
                             currentInstancePointer.RefCount = 0;
                             return;
                         }
                         if ((!handle.IsInvalid && (startupTime != -1L)) && (Microsoft.Win32.NativeMethods.GetProcessTimes(handle, out num3, out num5, out num5, out num5) && (num3 != startupTime)))
                         {
                             currentInstancePointer.RefCount = 0;
                             return;
                         }
                     }
                     using (Microsoft.Win32.SafeHandles.SafeProcessHandle handle2 = Microsoft.Win32.SafeHandles.SafeProcessHandle.OpenProcess(0x100000, false, processId))
                     {
                         if (!handle2.IsInvalid)
                         {
                             using (ProcessWaitHandle handle3 = new ProcessWaitHandle(handle2))
                             {
                                 if (handle3.WaitOne(0, false))
                                 {
                                     currentInstancePointer.RefCount = 0;
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
 }
Beispiel #23
0
        /// <summary>Checks whether the process has exited and updates state accordingly.</summary>
        private void UpdateHasExited()
        {
            SafeProcessHandle handle = null;
            try
            {
                handle = GetProcessHandle(Interop.mincore.ProcessOptions.PROCESS_QUERY_LIMITED_INFORMATION | Interop.mincore.ProcessOptions.SYNCHRONIZE, false);
                if (handle.IsInvalid)
                {
                    _exited = true;
                }
                else
                {
                    int localExitCode;

                    // Although this is the wrong way to check whether the process has exited,
                    // it was historically the way we checked for it, and a lot of code then took a dependency on
                    // the fact that this would always be set before the pipes were closed, so they would read
                    // the exit code out after calling ReadToEnd() or standard output or standard error. In order
                    // to allow 259 to function as a valid exit code and to break as few people as possible that
                    // took the ReadToEnd dependency, we check for an exit code before doing the more correct
                    // check to see if we have been signalled.
                    if (Interop.mincore.GetExitCodeProcess(handle, out localExitCode) && localExitCode != Interop.mincore.HandleOptions.STILL_ACTIVE)
                    {
                        _exitCode = localExitCode;
                        _exited = true;
                    }
                    else
                    {
                        // The best check for exit is that the kernel process object handle is invalid, 
                        // or that it is valid and signaled.  Checking if the exit code != STILL_ACTIVE 
                        // does not guarantee the process is closed,
                        // since some process could return an actual STILL_ACTIVE exit code (259).
                        if (!_signaled) // if we just came from WaitForExit, don't repeat
                        {
                            using (var wh = new ProcessWaitHandle(handle))
                            {
                                _signaled = wh.WaitOne(0);
                            }
                        }
                        if (_signaled)
                        {
                            if (!Interop.mincore.GetExitCodeProcess(handle, out localExitCode))
                                throw new Win32Exception();

                            _exitCode = localExitCode;
                            _exited = true;
                        }
                    }
                }
            }
            finally
            {
                ReleaseProcessHandle(handle);
            }
        }
Beispiel #24
0
        /// <devdoc>
        ///     Gets a short-term handle to the process, with the given access.  
        ///     If a handle is stored in current process object, then use it.
        ///     Note that the handle we stored in current process object will have all access we need.
        /// </devdoc>
        /// <internalonly/>
        private SafeProcessHandle GetProcessHandle(int access, bool throwIfExited)
        {
#if FEATURE_TRACESWITCH
            Debug.WriteLineIf(_processTracing.TraceVerbose, "GetProcessHandle(access = 0x" + access.ToString("X8", CultureInfo.InvariantCulture) + ", throwIfExited = " + throwIfExited + ")");
#if DEBUG
            if (_processTracing.TraceVerbose) {
                StackFrame calledFrom = new StackTrace(true).GetFrame(0);
                Debug.WriteLine("   called from " + calledFrom.GetFileName() + ", line " + calledFrom.GetFileLineNumber());
            }
#endif
#endif
            if (_haveProcessHandle)
            {
                if (throwIfExited)
                {
                    // Since haveProcessHandle is true, we know we have the process handle
                    // open with at least SYNCHRONIZE access, so we can wait on it with 
                    // zero timeout to see if the process has exited.
                    using (ProcessWaitHandle waitHandle = new ProcessWaitHandle(_processHandle))
                    {
                        if (waitHandle.WaitOne(0))
                        {
                            if (_haveProcessId)
                                throw new InvalidOperationException(SR.Format(SR.ProcessHasExited, _processId.ToString(CultureInfo.CurrentCulture)));
                            else
                                throw new InvalidOperationException(SR.ProcessHasExitedNoId);
                        }
                    }
                }
                return _processHandle;
            }
            else
            {
                EnsureState(State.HaveId | State.IsLocal);
                SafeProcessHandle handle = SafeProcessHandle.InvalidHandle;
                handle = ProcessManager.OpenProcess(_processId, access, throwIfExited);
                if (throwIfExited && (access & Interop.mincore.ProcessOptions.PROCESS_QUERY_INFORMATION) != 0)
                {
                    if (Interop.mincore.GetExitCodeProcess(handle, out _exitCode) && _exitCode != Interop.mincore.HandleOptions.STILL_ACTIVE)
                    {
                        throw new InvalidOperationException(SR.Format(SR.ProcessHasExited, _processId.ToString(CultureInfo.CurrentCulture)));
                    }
                }
                return handle;
            }
        }
Beispiel #25
0
		void StartExitCallbackIfNeeded ()
		{
#if !NET_2_1
			bool start = (!already_waiting && enableRaisingEvents && exited_event != null);
			if (start && process_handle != IntPtr.Zero) {
				WaitOrTimerCallback cb = new WaitOrTimerCallback (CBOnExit);
				ProcessWaitHandle h = new ProcessWaitHandle (process_handle);
				ThreadPool.RegisterWaitForSingleObject (h, cb, this, -1, true);
				already_waiting = true;
			}
#endif
		}
 private static unsafe int ExecWaitWithCaptureUnimpersonated(SafeUserTokenHandle userToken, string cmd, string currentDir, TempFileCollection tempFiles, ref string outputName, ref string errorName, string trueCmdLine)
 {
     IntSecurity.UnmanagedCode.Demand();
     if ((outputName == null) || (outputName.Length == 0))
     {
         outputName = tempFiles.AddExtension("out");
     }
     if ((errorName == null) || (errorName.Length == 0))
     {
         errorName = tempFiles.AddExtension("err");
     }
     FileStream stream = CreateInheritedFile(outputName);
     FileStream stream2 = CreateInheritedFile(errorName);
     bool flag = false;
     Microsoft.Win32.SafeNativeMethods.PROCESS_INFORMATION lpProcessInformation = new Microsoft.Win32.SafeNativeMethods.PROCESS_INFORMATION();
     Microsoft.Win32.SafeHandles.SafeProcessHandle processHandle = new Microsoft.Win32.SafeHandles.SafeProcessHandle();
     Microsoft.Win32.SafeHandles.SafeThreadHandle handle2 = new Microsoft.Win32.SafeHandles.SafeThreadHandle();
     SafeUserTokenHandle hNewToken = null;
     try
     {
         Microsoft.Win32.NativeMethods.STARTUPINFO startupinfo;
         StreamWriter writer = new StreamWriter(stream, Encoding.UTF8);
         writer.Write(currentDir);
         writer.Write("> ");
         writer.WriteLine((trueCmdLine != null) ? trueCmdLine : cmd);
         writer.WriteLine();
         writer.WriteLine();
         writer.Flush();
         startupinfo = new Microsoft.Win32.NativeMethods.STARTUPINFO {
             cb = Marshal.SizeOf(startupinfo),
             dwFlags = 0x101,
             wShowWindow = 0,
             hStdOutput = stream.SafeFileHandle,
             hStdError = stream2.SafeFileHandle,
             hStdInput = new SafeFileHandle(Microsoft.Win32.UnsafeNativeMethods.GetStdHandle(-10), false)
         };
         StringDictionary sd = new StringDictionary();
         foreach (DictionaryEntry entry in Environment.GetEnvironmentVariables())
         {
             sd[(string) entry.Key] = (string) entry.Value;
         }
         sd["_ClrRestrictSecAttributes"] = "1";
         byte[] buffer = EnvironmentBlock.ToByteArray(sd, false);
         try
         {
             fixed (byte* numRef = buffer)
             {
                 IntPtr lpEnvironment = new IntPtr((void*) numRef);
                 if ((userToken == null) || userToken.IsInvalid)
                 {
                     RuntimeHelpers.PrepareConstrainedRegions();
                     try
                     {
                         goto Label_0325;
                     }
                     finally
                     {
                         flag = Microsoft.Win32.NativeMethods.CreateProcess(null, new StringBuilder(cmd), null, null, true, 0, lpEnvironment, currentDir, startupinfo, lpProcessInformation);
                         if ((lpProcessInformation.hProcess != IntPtr.Zero) && (lpProcessInformation.hProcess != Microsoft.Win32.NativeMethods.INVALID_HANDLE_VALUE))
                         {
                             processHandle.InitialSetHandle(lpProcessInformation.hProcess);
                         }
                         if ((lpProcessInformation.hThread != IntPtr.Zero) && (lpProcessInformation.hThread != Microsoft.Win32.NativeMethods.INVALID_HANDLE_VALUE))
                         {
                             handle2.InitialSetHandle(lpProcessInformation.hThread);
                         }
                     }
                 }
                 flag = SafeUserTokenHandle.DuplicateTokenEx(userToken, 0xf01ff, null, 2, 1, out hNewToken);
                 if (flag)
                 {
                     RuntimeHelpers.PrepareConstrainedRegions();
                     try
                     {
                     }
                     finally
                     {
                         flag = Microsoft.Win32.NativeMethods.CreateProcessAsUser(hNewToken, null, cmd, null, null, true, 0, new HandleRef(null, lpEnvironment), currentDir, startupinfo, lpProcessInformation);
                         if ((lpProcessInformation.hProcess != IntPtr.Zero) && (lpProcessInformation.hProcess != Microsoft.Win32.NativeMethods.INVALID_HANDLE_VALUE))
                         {
                             processHandle.InitialSetHandle(lpProcessInformation.hProcess);
                         }
                         if ((lpProcessInformation.hThread != IntPtr.Zero) && (lpProcessInformation.hThread != Microsoft.Win32.NativeMethods.INVALID_HANDLE_VALUE))
                         {
                             handle2.InitialSetHandle(lpProcessInformation.hThread);
                         }
                     }
                 }
             }
         }
         finally
         {
             numRef = null;
         }
     }
     finally
     {
         if ((!flag && (hNewToken != null)) && !hNewToken.IsInvalid)
         {
             hNewToken.Close();
             hNewToken = null;
         }
         stream.Close();
         stream2.Close();
     }
 Label_0325:
     if (flag)
     {
         try
         {
             bool flag2;
             ProcessWaitHandle handle4 = null;
             try
             {
                 handle4 = new ProcessWaitHandle(processHandle);
                 flag2 = handle4.WaitOne(0x927c0, false);
             }
             finally
             {
                 if (handle4 != null)
                 {
                     handle4.Close();
                 }
             }
             if (!flag2)
             {
                 throw new ExternalException(SR.GetString("ExecTimeout", new object[] { cmd }), 0x102);
             }
             int exitCode = 0x103;
             if (!Microsoft.Win32.NativeMethods.GetExitCodeProcess(processHandle, out exitCode))
             {
                 throw new ExternalException(SR.GetString("ExecCantGetRetCode", new object[] { cmd }), Marshal.GetLastWin32Error());
             }
             return exitCode;
         }
         finally
         {
             processHandle.Close();
             handle2.Close();
             if ((hNewToken != null) && !hNewToken.IsInvalid)
             {
                 hNewToken.Close();
             }
         }
     }
     int error = Marshal.GetLastWin32Error();
     if (error == 8)
     {
         throw new OutOfMemoryException();
     }
     Win32Exception inner = new Win32Exception(error);
     ExternalException exception2 = new ExternalException(SR.GetString("ExecCantExec", new object[] { cmd }), inner);
     throw exception2;
 }