示例#1
0
        public static System.Diagnostics.Process StartProcessWithToken(IntPtr token, string appName, string cmdLine)
        {
            IntPtr environmentBlock = IntPtr.Zero;

            try
            {
                // Default nil security attribute
                SafeNativeMethods.SECURITY_ATTRIBUTES defSec = new SafeNativeMethods.SECURITY_ATTRIBUTES();
                defSec.nLength = Marshal.SizeOf(defSec);
                defSec.lpSecurityDescriptor = IntPtr.Zero;
                defSec.bInheritHandle       = 0;

                // Create an environment block
                if (!SafeNativeMethods.CreateEnvironmentBlock(ref environmentBlock, token, false))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error(), "CreateEnvironmentBlock");
                }

                // Now we can finally get into the business at hand and setup our process info
                SafeNativeMethods.STARTUPINFO startInfo = new SafeNativeMethods.STARTUPINFO();
                startInfo.cb          = Marshal.SizeOf(startInfo);
                startInfo.wShowWindow = 0;
                startInfo.lpDesktop   = "Winsta0\\Default"; // TBD: Support other desktops?

                SafeNativeMethods.PROCESS_INFORMATION procInfo = new SafeNativeMethods.PROCESS_INFORMATION();

                if (!SafeNativeMethods.CreateProcessAsUser(token, appName, cmdLine,
                                                           ref defSec, ref defSec, false, SafeNativeMethods.CREATE_UNICODE_ENVIRONMENT,
                                                           environmentBlock, null, ref startInfo, out procInfo))
                {
                    int lastError = Marshal.GetLastWin32Error();
                    throw new Win32Exception(lastError, "CreateProcessAsUser");
                }

                // We made it, process is running! Closing our handles to it ensures it doesn't orphan,
                // then we just use its pid to return a process object
                SafeNativeMethods.CloseHandle(procInfo.hProcess);
                SafeNativeMethods.CloseHandle(procInfo.hThread);

                return(System.Diagnostics.Process.GetProcessById((int)procInfo.dwProcessId));
            }
            finally
            {
                SafeNativeMethods.CloseHandle(environmentBlock);
            }
        }
示例#2
0
        public static System.Diagnostics.Process StartProcessWithToken(IntPtr token, string cmdLine)
        {
            IntPtr environmentBlock = IntPtr.Zero;

            try
            {
                // Default nil security attribute
                SafeNativeMethods.SECURITY_ATTRIBUTES defSec = new SafeNativeMethods.SECURITY_ATTRIBUTES();
                defSec.nLength = Marshal.SizeOf(defSec);
                defSec.lpSecurityDescriptor = IntPtr.Zero;
                defSec.bInheritHandle = 0;

                // Create an environment block
                if (!SafeNativeMethods.CreateEnvironmentBlock(ref environmentBlock, token, false))
                    throw new Win32Exception(Marshal.GetLastWin32Error(), "CreateEnvironmentBlock");

                // Now we can finally get into the business at hand and setup our process info
                SafeNativeMethods.STARTUPINFO startInfo = new SafeNativeMethods.STARTUPINFO();
                startInfo.cb = Marshal.SizeOf(startInfo);
                startInfo.wShowWindow = 0;
                startInfo.lpDesktop = "Winsta0\\Default";   // TBD: Support other desktops?

                SafeNativeMethods.PROCESS_INFORMATION procInfo = new SafeNativeMethods.PROCESS_INFORMATION();
                if (!SafeNativeMethods.CreateProcessAsUser(token, null, cmdLine,
                                    ref defSec, ref defSec, false, SafeNativeMethods.CREATE_UNICODE_ENVIRONMENT,
                                    environmentBlock, null, ref startInfo, out procInfo))
                {
                    int lastError = Marshal.GetLastWin32Error();
                    throw new Win32Exception(lastError, "CreateProcessAsUser");
                }

                // We made it, process is running! Closing our handles to it ensures it doesn't orphan,
                //  then we just use its pid to return a process object
                SafeNativeMethods.CloseHandle(procInfo.hProcess);
                SafeNativeMethods.CloseHandle(procInfo.hThread);

                return System.Diagnostics.Process.GetProcessById((int)procInfo.dwProcessId);
            }
            finally
            {
                SafeNativeMethods.CloseHandle(environmentBlock);
            }
        }
        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);
        }
示例#4
0
 private bool StartWithCreateProcess(ProcessStartInfo startInfo)
 {
     if (startInfo.StandardOutputEncoding != null && !startInfo.RedirectStandardOutput)
     {
         throw new InvalidOperationException("StandardOutputEncodingNotAllowed");
     }
     if (startInfo.StandardErrorEncoding != null && !startInfo.RedirectStandardError)
     {
         throw new InvalidOperationException("StandardErrorEncodingNotAllowed");
     }
     StringBuilder stringBuilder = Process2.BuildCommandLine(startInfo.FileName, startInfo.Arguments);
     NativeMethods.STARTUPINFO sTARTUPINFO = new NativeMethods.STARTUPINFO();
     SafeNativeMethods.PROCESS_INFORMATION pROCESS_INFORMATION = new SafeNativeMethods.PROCESS_INFORMATION();
     SafeProcessHandle safeProcessHandle = new SafeProcessHandle();
     SafeThreadHandle safeThreadHandle = new SafeThreadHandle();
     int num = 0;
     SafeFileHandle handle = null;
     SafeFileHandle handle2 = null;
     SafeFileHandle handle3 = null;
     GCHandle gCHandle = default(GCHandle);
     lock (Process2.s_CreateProcessLock)
     {
         try
         {
             if (startInfo.RedirectStandardInput || startInfo.RedirectStandardOutput || startInfo.RedirectStandardError)
             {
                 if (startInfo.RedirectStandardInput)
                 {
                     CreatePipe(out handle, out sTARTUPINFO.hStdInput, true);
                 }
                 else
                 {
                     sTARTUPINFO.hStdInput = new SafeFileHandle(NativeMethods.GetStdHandle(-10), false);
                 }
                 if (startInfo.RedirectStandardOutput)
                 {
                     CreatePipe(out handle2, out sTARTUPINFO.hStdOutput, false);
                 }
                 else
                 {
                     sTARTUPINFO.hStdOutput = new SafeFileHandle(NativeMethods.GetStdHandle(-11), false);
                 }
                 if (startInfo.RedirectStandardError)
                 {
                     CreatePipe(out handle3, out sTARTUPINFO.hStdError, false);
                 }
                 else
                 {
                     sTARTUPINFO.hStdError = sTARTUPINFO.hStdOutput;
                 }
                 sTARTUPINFO.dwFlags = 256;
             }
             int num2 = 0;
             if (startInfo.CreateNoWindow)
             {
                 num2 |= 134217728;
             }
             IntPtr intPtr = (IntPtr)0;
             //if (startInfo.environmentVariables != null)
             //{
             //    bool unicode = false;
             //    if (ProcessManager.IsNt)
             //    {
             //        num2 |= 1024;
             //        unicode = true;
             //    }
             //    byte[] value = EnvironmentBlock.ToByteArray(startInfo.environmentVariables, unicode);
             //    gCHandle = GCHandle.Alloc(value, GCHandleType.Pinned);
             //    intPtr = gCHandle.AddrOfPinnedObject();
             //}
             string text = startInfo.WorkingDirectory;
             if (text == string.Empty)
             {
                 text = Environment.CurrentDirectory;
             }
             bool flag2;
             //if (startInfo.UserName.Length != 0)
             //{
             //    NativeMethods.LogonFlags logonFlags = (NativeMethods.LogonFlags)0;
             //    if (startInfo.LoadUserProfile)
             //    {
             //        logonFlags = NativeMethods.LogonFlags.LOGON_WITH_PROFILE;
             //    }
             //    IntPtr intPtr2 = IntPtr.Zero;
             //    try
             //    {
             //        if (startInfo.Password == null)
             //        {
             //            intPtr2 = Marshal.StringToCoTaskMemUni(string.Empty);
             //        }
             //        else
             //        {
             //            intPtr2 = Marshal.SecureStringToCoTaskMemUnicode(startInfo.Password);
             //        }
             //        RuntimeHelpers.PrepareConstrainedRegions();
             //        try
             //        {
             //        }
             //        finally
             //        {
             //            flag2 = NativeMethods.CreateProcessWithLogonW(startInfo.UserName, startInfo.Domain, intPtr2, logonFlags, null, stringBuilder, num2, intPtr, text, sTARTUPINFO, pROCESS_INFORMATION);
             //            if (!flag2)
             //            {
             //                num = Marshal.GetLastWin32Error();
             //            }
             //            if (pROCESS_INFORMATION.hProcess != (IntPtr)0 && pROCESS_INFORMATION.hProcess != NativeMethods.INVALID_HANDLE_VALUE)
             //            {
             //                safeProcessHandle.InitialSetHandle(pROCESS_INFORMATION.hProcess);
             //            }
             //            if (pROCESS_INFORMATION.hThread != (IntPtr)0 && pROCESS_INFORMATION.hThread != NativeMethods.INVALID_HANDLE_VALUE)
             //            {
             //                safeThreadHandle.InitialSetHandle(pROCESS_INFORMATION.hThread);
             //            }
             //        }
             //        if (flag2)
             //        {
             //            goto IL_3B9;
             //        }
             //        if (num == 193 || num == 216)
             //        {
             //            throw new Win32Exception(num, SR.GetString("InvalidApplication"));
             //        }
             //        throw new Win32Exception(num);
             //    }
             //    finally
             //    {
             //        if (intPtr2 != IntPtr.Zero)
             //        {
             //            Marshal.ZeroFreeCoTaskMemUnicode(intPtr2);
             //        }
             //    }
             //}
             RuntimeHelpers.PrepareConstrainedRegions();
             try
             {
             }
             finally
             {
                 flag2 = NativeMethods.CreateProcess(null, stringBuilder, null, null, true, num2, intPtr, text, sTARTUPINFO, pROCESS_INFORMATION);
                 if (!flag2)
                 {
                     num = Marshal.GetLastWin32Error();
                 }
                 if (pROCESS_INFORMATION.hProcess != (IntPtr)0 && pROCESS_INFORMATION.hProcess != NativeMethods.INVALID_HANDLE_VALUE)
                 {
                     safeProcessHandle.InitialSetHandle(pROCESS_INFORMATION.hProcess);
                 }
                 if (pROCESS_INFORMATION.hThread != (IntPtr)0 && pROCESS_INFORMATION.hThread != NativeMethods.INVALID_HANDLE_VALUE)
                 {
                     safeThreadHandle.InitialSetHandle(pROCESS_INFORMATION.hThread);
                 }
             }
             if (!flag2)
             {
                 if (num == 193 || num == 216)
                 {
                     throw new Win32Exception(num, "InvalidApplication");
                 }
                 throw new Win32Exception(num);
             }
         }
         finally
         {
             if (gCHandle.IsAllocated)
             {
                 gCHandle.Free();
             }
             sTARTUPINFO.Dispose();
         }
     }
     if (startInfo.RedirectStandardInput)
     {
         standardInput = new StreamWriter(new FileStream(handle, FileAccess.Write, 4096, false), Console.InputEncoding, 4096);
         standardInput.AutoFlush = true;
     }
     if (startInfo.RedirectStandardOutput)
     {
         Encoding encoding = (startInfo.StandardOutputEncoding != null) ? startInfo.StandardOutputEncoding : Console.OutputEncoding;
         standardOutput = new StreamReader(new FileStream(handle2, FileAccess.Read, 4096, false), encoding, true, 4096);
     }
     if (startInfo.RedirectStandardError)
     {
         Encoding encoding2 = (startInfo.StandardErrorEncoding != null) ? startInfo.StandardErrorEncoding : Console.OutputEncoding;
         standardError = new StreamReader(new FileStream(handle3, FileAccess.Read, 4096, false), encoding2, true, 4096);
     }
     bool result = false;
     if (!safeProcessHandle.IsInvalid)
     {
         SetProcessHandle(safeProcessHandle);
         SetProcessId(pROCESS_INFORMATION.dwProcessId);
         safeThreadHandle.Close();
         result = true;
     }
     return result;
 }