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); } }
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); }
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; }