Ejemplo n.º 1
0
        public void Run()
        {
            IntPtr primaryToken = GetCurrentUserToken();

            if (primaryToken == IntPtr.Zero)
            {
                return;
            }
            NativeMethods.STARTUPINFO StartupInfo = new NativeMethods.STARTUPINFO();
            processInfo_   = new NativeMethods.PROCESS_INFORMATION();
            StartupInfo.cb = Marshal.SizeOf(StartupInfo);

            NativeMethods.SECURITY_ATTRIBUTES Security1 = new NativeMethods.SECURITY_ATTRIBUTES();
            NativeMethods.SECURITY_ATTRIBUTES Security2 = new NativeMethods.SECURITY_ATTRIBUTES();

            string command = "\"" + processPath_ + "\"";

            if ((arguments_ != null) && (arguments_.Length != 0))
            {
                command += " " + arguments_;
            }

            IntPtr lpEnvironment = IntPtr.Zero;
            bool   resultEnv     = NativeMethods.CreateEnvironmentBlock(out lpEnvironment, primaryToken, false);

            if (resultEnv != true)
            {
                int nError = NativeMethods.GetLastError();
            }

            NativeMethods.CreateProcessAsUser(primaryToken, null, command, ref Security1, ref Security2, false, NativeMethods.CREATE_NO_WINDOW | NativeMethods.NORMAL_PRIORITY_CLASS | NativeMethods.CREATE_UNICODE_ENVIRONMENT, lpEnvironment, null, ref StartupInfo, out processInfo_);

            NativeMethods.DestroyEnvironmentBlock(lpEnvironment);
            NativeMethods.CloseHandle(primaryToken);
        }
Ejemplo n.º 2
0
        private static int CreateProcessAsUser(string executablePath, string commandLine, string workingDirectory, IntPtr userToken)
        {
            using (AutoDisposeHandle environmentVariables = CreateEnvironmentBlock(userToken))
            {
                if (environmentVariables == null)
                {
                    return(-1);
                }

                NativeMethods.STARTUPINFO startupInformation = new NativeMethods.STARTUPINFO();
                startupInformation.length     = Marshal.SizeOf(typeof(NativeMethods.STARTUPINFO));
                startupInformation.desktop    = "Winsta0\\Default";
                startupInformation.showWindow = (short)NativeMethods.WindowShowStyle.ShowNoActivate;
                NativeMethods.PROCESS_INFORMATION processInformation = new NativeMethods.PROCESS_INFORMATION();
                try
                {
                    bool result = NativeMethods.CreateProcessAsUser
                                  (
                        userToken,
                        executablePath,
                        commandLine,
                        IntPtr.Zero,
                        IntPtr.Zero,
                        false,
                        (uint)(NativeMethods.CreateProcessFlags.DETACHED_PROCESS | NativeMethods.CreateProcessFlags.CREATE_UNICODE_ENVIRONMENT),
                        environmentVariables,
                        workingDirectory,
                        ref startupInformation,
                        ref processInformation
                                  );
                    if (!result)
                    {
                        Win32Helper.ThrowLastWin32Error("Unable to start process \"" + executablePath + "\"");
                    }
                    return(processInformation.processID);
                }
                finally
                {
                    if (processInformation.processHandle != IntPtr.Zero)
                    {
                        try
                        {
                            NativeMethods.CloseHandle(processInformation.processHandle);
                        }
                        catch { }
                    }
                    if (processInformation.threadHandle != IntPtr.Zero)
                    {
                        try
                        {
                            NativeMethods.CloseHandle(processInformation.threadHandle);
                        }
                        catch { }
                    }
                }
            }
        }
Ejemplo n.º 3
0
        public static void LaunchProcessAsUser(string app, string args, IntPtr token)
        {
            IntPtr primaryToken = IntPtr.Zero;

            var securityAttrs = new NativeMethods.SECURITY_ATTRIBUTES();

            //ZeroMemory(sa, (uint)Marshal.SizeOf(sa));
            securityAttrs.nLength              = (uint)Marshal.SizeOf(securityAttrs);
            securityAttrs.bInheritHandle       = false;
            securityAttrs.lpSecurityDescriptor = IntPtr.Zero;

            var startupInfo = new NativeMethods.STARTUPINFO();

            //ZeroMemory(si, (uint)Marshal.SizeOf(si));
            startupInfo.cb = (uint)Marshal.SizeOf(startupInfo);

            bool retdup = NativeMethods.DuplicateTokenEx(token, NativeMethods.TOKEN_ASSIGN_PRIMARY | NativeMethods.TOKEN_DUPLICATE | NativeMethods.TOKEN_QUERY, ref securityAttrs,
                                                         (int)NativeMethods.SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, (int)NativeMethods.TOKEN_TYPE.TokenPrimary,
                                                         ref primaryToken);

            if (!retdup)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error(), "Unable to duplicate the current user's token.");
            }

            try
            {
                IntPtr UserEnvironment;
                bool   retenviron = NativeMethods.CreateEnvironmentBlock(out UserEnvironment, token, false);
                if (!retenviron)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error(), "Unable to create user environment.");
                }

                try
                {
                    string cmd      = $"\"{app}\" {args}";
                    bool   retimper = NativeMethods.CreateProcessAsUser(primaryToken, null, cmd, ref securityAttrs, ref securityAttrs, false, NativeMethods.CREATE_UNICODE_ENVIRONMENT, UserEnvironment, null, ref startupInfo, out var processInfo);
                    if (!retimper)
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error(), "Unable to impersonate. Command was: " + cmd);
                    }
                    NativeMethods.CloseHandle(processInfo.hThread);
                    NativeMethods.CloseHandle(processInfo.hProcess);
                }
                finally
                {
                    NativeMethods.DestroyEnvironmentBlock(UserEnvironment);
                }
            }
            finally
            {
                NativeMethods.CloseHandle(primaryToken);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Initializes a new instance of the BrokerProcess class
        /// </summary>
        /// <param name="brokerFileName">indicating the broker file name</param>
        /// <param name="environments">indicating the environments</param>
        public BrokerProcess(string brokerFileName, NameValueConfigurationCollection environments)
        {
            this.startupInfo    = new NativeMethods.STARTUPINFO();
            this.startupInfo.cb = Marshal.SizeOf(typeof(NativeMethods.STARTUPINFO));
            this.processInfo    = new NativeMethods.PROCESS_INFORMATION();

            string        path        = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            string        fileName    = Path.Combine(path, brokerFileName);
            StringBuilder commandLine = null;

            TraceHelper.TraceEvent(TraceEventType.Information, "[BrokerProcess] Start broker process, FileName = {0}", fileName);

            IntPtr environmentPtr;

            if (environments != null)
            {
                this.environmentHandle = GCHandle.Alloc(ToByteArray(environments), GCHandleType.Pinned);
                environmentPtr         = this.environmentHandle.AddrOfPinnedObject();
            }
            else
            {
                environmentPtr = IntPtr.Zero;
            }

            if (!NativeMethods.CreateProcess(fileName, commandLine, IntPtr.Zero, IntPtr.Zero, true, creationFlags, environmentPtr, path, ref this.startupInfo, out this.processInfo))
            {
                int errorCode = Marshal.GetLastWin32Error();
                TraceHelper.TraceEvent(TraceEventType.Error, "[BrokerProcess] Start broker process failed: {0}", errorCode);
                ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_FailedToStartBrokerServiceProcess, SR.FailedToStartBrokerServiceProcess, errorCode.ToString());
            }

            SafeWaitHandle handle = new SafeWaitHandle(this.processInfo.hProcess, false);

            if (handle.IsClosed || handle.IsInvalid)
            {
                TraceHelper.TraceEvent(TraceEventType.Error, "[BrokerProcess] Start broker process failed because the process handle is invalid or closed.");
                ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_FailedToStartBrokerServiceProcess, SR.FailedToStartBrokerServiceProcess, "Handle is invalid or closed");
            }

            string uniqueWaitHandleName = BuildUniqueWaitHandle(this.Id, out this.readyWaitHandle);

            WaitOrTimerCallback brokerProcessReadyCallback = new ThreadHelper <object>(new WaitOrTimerCallback(this.BrokerProcessReadyCallback)).WaitOrTimerCallbackRoot;
            WaitOrTimerCallback processExitCallback        = new ThreadHelper <object>(new WaitOrTimerCallback(this.ProcessExitCallback)).WaitOrTimerCallbackRoot;

            this.exitWaitHandle = new ManualResetEvent(false);
            this.exitWaitHandle.SafeWaitHandle = handle;

            // Register broker process exit callback
            ThreadPool.RegisterWaitForSingleObject(this.exitWaitHandle, processExitCallback, null, -1, true);

            // Register callback to be raised when broker process opened service host and is ready to initialize.
            ThreadPool.RegisterWaitForSingleObject(this.readyWaitHandle, brokerProcessReadyCallback, null, readyTimeout, true);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// ユーザーセッションでコマンドを実行する
        /// </summary>
        /// <param name="commandline">実行したいコマンド</param>
        /// <exception cref="InvalidOperationException"></exception>
        public static void CreateProcessAsUser(string commandline)
        {
            var sessionId = NativeMethods.WTSGetActiveConsoleSessionId();

            IntPtr hPToken       = IntPtr.Zero;
            var    hUserTokenDup = IntPtr.Zero;

            var ret = NativeMethods.WTSQueryUserToken(sessionId, out hPToken);

            var sa = new NativeMethods.SECURITY_ATTRIBUTES();

            sa.nLength = Marshal.SizeOf(sa);

            if (!NativeMethods.DuplicateTokenEx(hPToken, NativeMethods.TOKEN_ALL_ACCESS, ref sa, NativeMethods.SECURITY_IMPERSONATION_LEVEL.SecurityDelegation, NativeMethods.TOKEN_TYPE.TokenPrimary, out hUserTokenDup))
            {
                NativeMethods.CloseHandle(hPToken);
                throw new InvalidOperationException();
            }

            var si = new NativeMethods.STARTUPINFO()
            {
                cb          = Marshal.SizeOf(sa),
                lpDesktop   = @"winsta0\default",
                wShowWindow = 0,//SW_HIDE
                dwFlags     = NativeMethods.STARTF_USESHOWWINDOW,
            };

            var creationFlags = NativeMethods.CREATE_UNICODE_ENVIRONMENT;
            var env           = IntPtr.Zero;

            // アクティブユーザのセッションを設定します
            var ret2 = NativeMethods.SetTokenInformation(hUserTokenDup, NativeMethods.TOKEN_INFORMATION_CLASS.TokenSessionId, ref sessionId, sizeof(NativeMethods.TOKEN_INFORMATION_CLASS));

            // 環境変数を設定
            if (!NativeMethods.CreateEnvironmentBlock(out env, hUserTokenDup, true))
            {
                env = IntPtr.Zero;
            }

            NativeMethods.PROCESS_INFORMATION pi = new NativeMethods.PROCESS_INFORMATION();

            NativeMethods.CreateProcessAsUser(hUserTokenDup, IntPtr.Zero, commandline, IntPtr.Zero, IntPtr.Zero, false, creationFlags, env, IntPtr.Zero, ref si, out pi);

            NativeMethods.DestroyEnvironmentBlock(env);
        }
Ejemplo n.º 6
0
        private void StartProcess()
        {
            uint id = (uint)NativeMethods.WTSGetActiveConsoleSessionId();

            IntPtr token;
            bool   ok = NativeMethods.WTSQueryUserToken(id, out token);

            NativeMethods.SECURITY_ATTRIBUTES security = new NativeMethods.SECURITY_ATTRIBUTES();
            security.nLength = Marshal.SizeOf(typeof(NativeMethods.SECURITY_ATTRIBUTES));
            if (!NativeMethods.DuplicateTokenEx(token, NativeMethods.ACCESS_MASK.MAXIMUM_ALLOWED, ref security,
                                                NativeMethods.SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, NativeMethods.TOKEN_TYPE.TokenPrimary, out tokenCopy))
            {
                throw new Exception("Can't create duplicate token");
            }

            if (ok)
            {
                NativeMethods.CloseHandle(token);
            }

            if (!NativeMethods.CreateEnvironmentBlock(out environment, tokenCopy, false))
            {
                throw new Exception("Can't create environment block");
            }

            security = new NativeMethods.SECURITY_ATTRIBUTES();
            NativeMethods.STARTUPINFO startupInfo = new NativeMethods.STARTUPINFO();
            startupInfo.dwFlags     = 1;
            startupInfo.wShowWindow = 1;
            startupInfo.lpDesktop   = "winsta0\\default";

            string        location = Assembly.GetEntryAssembly().Location;
            StringBuilder cmd      = new StringBuilder();

            cmd.AppendFormat("\"{0}\" {1}", location, EMBEDDING);

            string directory = Path.GetDirectoryName(location);

            if (!NativeMethods.CreateProcessAsUser(tokenCopy, null, cmd, ref security, ref security, false,
                                                   NativeMethods.CREATE_UNICODE_ENVIRONMENT, environment, directory, ref startupInfo, out processInfo))
            {
                throw new Exception("Can't create process as a user. Error: " + Marshal.GetLastWin32Error());
            }
        }
Ejemplo n.º 7
0
        public void Start()
        {
            NativeMethods.STARTUPINFO startInfo = default(NativeMethods.STARTUPINFO);
            startInfo.cb          = Marshal.SizeOf(startInfo);
            startInfo.dwFlags     = NativeMethods.STARTF_USE_SHOWWINDOW;
            startInfo.wShowWindow = NativeMethods.SW_HIDE;

            string commandLine = String.Format(ProxyProcessManager.POWERSHELL_COMMAND_LINE, Assembly.GetExecutingAssembly().Location, this.commandPipeName);

            NativeMethods.PROCESS_INFORMATION procInfo;
            if (!NativeMethods.CreateProcess(null, commandLine, IntPtr.Zero, IntPtr.Zero, false, NativeMethods.CREATE_NEW_CONSOLE, IntPtr.Zero, null, ref startInfo, out procInfo))
            {
                throw new Win32Exception();
            }

            NativeMethods.CloseHandle(procInfo.hProcess);
            NativeMethods.CloseHandle(procInfo.hThread);
            this.proxyProcess = Process.GetProcessById(procInfo.dwProcessId);
            this.commandPipe.WaitForConnection();
        }
Ejemplo n.º 8
0
        /// <include file='doc\Executor.uex' path='docs/doc[@for="Executor.ExecWaitWithCapture3"]/*' />
        /// <devdoc>
        ///    <para>[To be supplied.]</para>
        /// </devdoc>
        internal static int ExecWaitWithCapture(IntPtr userToken, string cmd, string currentDir, TempFileCollection tempFiles, ref string outputName, ref string errorName, string trueCmdLine)
        {
            IntSecurity.UnmanagedCode.Demand();

            IntPtr output;
            IntPtr 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;

            NativeMethods.PROCESS_INFORMATION pi = new NativeMethods.PROCESS_INFORMATION();
            IntPtr   primaryToken      = IntPtr.Zero;
            GCHandle environmentHandle = new GCHandle();

            try {
                // Output the command line...
                // Make sure the FileStream doesn't own the handle
                FileStream   outputStream = new FileStream(output, FileAccess.ReadWrite, false /*ownsHandle*/);
                StreamWriter sw           = new StreamWriter(outputStream, 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();
                outputStream.Close();

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

                si.cb         = Marshal.SizeOf(si);
                si.dwFlags    = NativeMethods.STARTF_USESTDHANDLES;
                si.hStdOutput = output;
                si.hStdError  = error;
                si.hStdInput  = UnsafeNativeMethods.GetStdHandle(NativeMethods.STD_INPUT_HANDLE);

                //
                // Prepare the environment
                //
                Hashtable environment = new Hashtable();

                // 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.Add("_ClrRestrictSecAttributes", "1");

                // set up the environment block parameter
                IntPtr environmentPtr   = (IntPtr)0;
                byte[] environmentBytes = EnvironmentToByteArray(environment);
                environmentHandle = GCHandle.Alloc(environmentBytes, GCHandleType.Pinned);
                environmentPtr    = environmentHandle.AddrOfPinnedObject();

                if (userToken == IntPtr.Zero)
                {
                    success = UnsafeNativeMethods.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);
                }
                else
                {
                    throw new NotSupportedException();
                }
            }
            finally {
                // free environment block
                if (environmentHandle.IsAllocated)
                {
                    environmentHandle.Free();
                }

                // Close the file handles
                UnsafeNativeMethods.CloseHandle(output);
                UnsafeNativeMethods.CloseHandle(error);
            }

            if (success)
            {
                try {
                    int ret = SafeNativeMethods.WaitForSingleObject(pi.hProcess, 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 (!UnsafeNativeMethods.GetExitCodeProcess(pi.hProcess, ref status))
                    {
                        throw new ExternalException(SR.GetString(SR.ExecCantGetRetCode, cmd), Marshal.GetLastWin32Error());
                    }

                    retValue = status;
                }
                finally {
                    UnsafeNativeMethods.CloseHandle(pi.hThread);
                    UnsafeNativeMethods.CloseHandle(pi.hProcess);

                    if (primaryToken != IntPtr.Zero)
                    {
                        UnsafeNativeMethods.CloseHandle(primaryToken);
                    }
                }
            }
            else
            {
                throw new ExternalException(SR.GetString(SR.ExecCantExec, cmd), Marshal.GetLastWin32Error());
            }

            return(retValue);
        }
Ejemplo n.º 9
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);
        }
Ejemplo n.º 10
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);
        }
Ejemplo n.º 11
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;
 }
Ejemplo n.º 12
0
        public static Win32Process StartProcessAsUser(WindowsIdentity winIdentity, string applicationName, string commandLine, string workingDirectory, Win32NativeEnvironmentBlock environment, out Stream stdin, out Stream stdout, out Stream stderror)
        {
            NativeMethods.STARTUPINFO si = new NativeMethods.STARTUPINFO();
            si.cb = Marshal.SizeOf(typeof(NativeMethods.STARTUPINFO));

            /*
             * When a process is started using CreateProcessAsUser function, the process will be started into a windowstation
             * and desktop combination based on the value of lpDesktop in the STARTUPINFO structure parameter:
             * lpDesktop = "<windowsta>\<desktop>"; the system will try to start the process into that windowstation and desktop.
             * lpDesktop = NULL; the system will try to use the same windowstation and desktop as the calling process if the system is associated with the interactive windowstation.
             * lpDesktop = <somevalue>; the system will create a new windowstation and desktop that you cannot see.
             * lpDesktop = ""; it will either create a new windowstation and desktop that you cannot see, or if one has been created by means of a prior call by using the same access token, the existing windowstation and desktop will be used.
             */
            si.lpDesktop = "";

            IntPtr stdinRead, stdinWrite, stdoutRead, stdoutWrite, stderrorRead, stderrorWrite;

            NativeMethods.SECURITY_ATTRIBUTES sa = default(NativeMethods.SECURITY_ATTRIBUTES);
            sa.nLength = Marshal.SizeOf(sa);
            sa.lpSecurityDescriptor = IntPtr.Zero;
            sa.bInheritHandle       = true;

            if (!NativeMethods.CreatePipe(out stdinRead, out stdinWrite, ref sa, 0))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            if (!NativeMethods.SetHandleInformation(stdinWrite, NativeMethods.HANDLE_FLAGS.INHERIT, NativeMethods.HANDLE_FLAGS.None))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            if (!NativeMethods.CreatePipe(out stdoutRead, out stdoutWrite, ref sa, 0))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            if (!NativeMethods.SetHandleInformation(stdoutRead, NativeMethods.HANDLE_FLAGS.INHERIT, NativeMethods.HANDLE_FLAGS.None))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            if (!NativeMethods.CreatePipe(out stderrorRead, out stderrorWrite, ref sa, 0))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            if (!NativeMethods.SetHandleInformation(stderrorRead, NativeMethods.HANDLE_FLAGS.INHERIT, NativeMethods.HANDLE_FLAGS.None))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            si.dwFlags    = NativeMethods.STARTF_USESTDHANDLES;
            si.hStdInput  = stdinRead;
            si.hStdOutput = stdoutWrite;
            si.hStdError  = stderrorWrite;

            NativeMethods.SECURITY_ATTRIBUTES processAttr = CreateSecurityAttributes(winIdentity == null ? WellKnownSidType.AuthenticatedUserSid : WellKnownSidType.NetworkServiceSid);
            NativeMethods.SECURITY_ATTRIBUTES threadAttr  = CreateSecurityAttributes(winIdentity == null ? WellKnownSidType.AuthenticatedUserSid : WellKnownSidType.NetworkServiceSid);

            lock (_createProcessLock) {
                NativeMethods.PROCESS_INFORMATION pi;
                NativeMethods.ErrorModes          oldErrorMode = NativeMethods.SetErrorMode(NativeMethods.ErrorModes.SEM_FAILCRITICALERRORS);
                try {
                    if (winIdentity == null)
                    {
                        if (!NativeMethods.CreateProcess(applicationName, commandLine, ref processAttr, ref threadAttr, true,
                                                         (uint)(NativeMethods.CREATE_PROCESS_FLAGS.CREATE_UNICODE_ENVIRONMENT | NativeMethods.CREATE_PROCESS_FLAGS.CREATE_NO_WINDOW),
                                                         environment.NativeEnvironmentBlock,
                                                         workingDirectory,
                                                         ref si,
                                                         out pi))
                        {
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                        }
                    }
                    else
                    {
                        if (!NativeMethods.CreateProcessAsUser(
                                winIdentity.Token, applicationName, commandLine, ref processAttr, ref threadAttr, true,
                                (uint)(NativeMethods.CREATE_PROCESS_FLAGS.CREATE_UNICODE_ENVIRONMENT | NativeMethods.CREATE_PROCESS_FLAGS.CREATE_NO_WINDOW),
                                environment.NativeEnvironmentBlock,
                                workingDirectory,
                                ref si,
                                out pi))
                        {
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                        }
                    }

                    stdin    = new FileStream(new SafeFileHandle(stdinWrite, true), FileAccess.Write, 0x1000, false);
                    stdout   = new FileStream(new SafeFileHandle(stdoutRead, true), FileAccess.Read, 0x1000, false);
                    stderror = new FileStream(new SafeFileHandle(stderrorRead, true), FileAccess.Read, 0x1000, false);
                } finally {
                    NativeMethods.SetErrorMode(oldErrorMode);

                    if (processAttr.lpSecurityDescriptor != IntPtr.Zero)
                    {
                        Marshal.FreeHGlobal(processAttr.lpSecurityDescriptor);
                    }

                    if (threadAttr.lpSecurityDescriptor != IntPtr.Zero)
                    {
                        Marshal.FreeHGlobal(threadAttr.lpSecurityDescriptor);
                    }
                }

                return(new Win32Process(pi));
            }
        }
Ejemplo n.º 13
0
        private static void StartProcessWithLogonNetOnly(ProcessStartInfo startInfo, bool waitForExit)
        {
            if (startInfo.UseShellExecute)
            {
                throw new InvalidOperationException("UseShellExecute must be false.");
            }

            if (startInfo.LoadUserProfile)
            {
                throw new InvalidOperationException("LoadUserProfile cannot be used.");
            }

            if (string.IsNullOrEmpty(startInfo.UserName))
            {
                throw new InvalidOperationException("UserName is empty.");
            }

            var cmdLine              = BuildCommandLine(startInfo.FileName, startInfo.Arguments);
            var lpStartupInfo        = new NativeMethods.STARTUPINFO();
            var lpProcessInformation = new NativeMethods.PROCESS_INFORMATION();

            int creationFlags = 0;

            if (startInfo.CreateNoWindow)
            {
                creationFlags |= 0x8000000;
            }

            IntPtr zero = IntPtr.Zero;

            string workingDirectory = startInfo.WorkingDirectory;

            if (string.IsNullOrEmpty(workingDirectory))
            {
                workingDirectory = Environment.CurrentDirectory;
            }

            NativeMethods.LogonFlags logonFlags = NativeMethods.LogonFlags.LOGON_NETCREDENTIALS_ONLY;   //NetOnly;

            IntPtr passwordPrt = IntPtr.Zero;

            try
            {
                if (startInfo.Password == null)
                {
                    passwordPrt = Marshal.StringToCoTaskMemUni(string.Empty);
                }
                else
                {
                    passwordPrt = Marshal.SecureStringToCoTaskMemUnicode(startInfo.Password);
                }

                int  error = 0;
                bool flag  = NativeMethods.CreateProcessWithLogonW(startInfo.UserName, startInfo.Domain, passwordPrt, logonFlags, null, cmdLine, creationFlags, zero, workingDirectory, lpStartupInfo, lpProcessInformation);
                if (!flag)
                {
                    error = Marshal.GetLastWin32Error();
                }

                if (!flag)
                {
                    if (error != 0xc1 && error != 0xd8)
                    {
                        throw new Win32Exception(error);
                    }
                    throw new Win32Exception(error, "Invalid Application");
                }
            }
            finally
            {
                if (passwordPrt != IntPtr.Zero)
                {
                    Marshal.ZeroFreeCoTaskMemUnicode(passwordPrt);
                }
            }

            if (waitForExit)
            {
                NativeMethods.WaitForSingleObject(lpProcessInformation.hProcess, 0xFFFFFFFF);
            }
        }
        public Tuple <bool, int> CreateProcessAsUser(IntPtr hUserToken, string appFileName, string appArgs)
        {
            try
            {
                // Identify user from access token.
                WindowsIdentity userId = new WindowsIdentity(hUserToken);
                _logger.Log("Create process for: " + userId.Name + " [" + appFileName + " " + appArgs + "].");
                userId.Dispose();

                // Obtain duplicated user token (elevated if UAC is turned on/enabled).
                IntPtr hDuplicateToken = new WindowsHelper(_logger).DuplicateToken(hUserToken);

                // Initialize process info and startup info.
                NativeMethods.PROCESS_INFORMATION pi = new NativeMethods.PROCESS_INFORMATION();
                NativeMethods.STARTUPINFO         si = new NativeMethods.STARTUPINFO();
                si.cb        = Marshal.SizeOf(si);
                si.lpDesktop = "winsta0\\default";
                NativeMethods.SECURITY_ATTRIBUTES lpProcessAttributes = new NativeMethods.SECURITY_ATTRIBUTES();
                NativeMethods.SECURITY_ATTRIBUTES lpThreadAttributes  = new NativeMethods.SECURITY_ATTRIBUTES();
                IntPtr hEnvironment = IntPtr.Zero;

                if (!NativeMethods.CreateEnvironmentBlock(out hEnvironment, hDuplicateToken, true))
                {
                    _logger.Log("Unable to create environment block [CreateEnvironmentBlock=" + Marshal.GetLastWin32Error().ToString() + "].", Logger.MsgType.WARN);
                }

                if (!NativeMethods.CreateProcessAsUser(
                        hDuplicateToken,
                        null,
                        appFileName + " " + appArgs,
                        ref lpProcessAttributes,
                        ref lpThreadAttributes,
                        false,
                        (uint)NativeMethods.CreateProcessFlags.NORMAL_PRIORITY_CLASS |
                        (uint)NativeMethods.CreateProcessFlags.CREATE_UNICODE_ENVIRONMENT |
                        (uint)NativeMethods.CreateProcessFlags.CREATE_NEW_CONSOLE,
                        hEnvironment,
                        Path.GetDirectoryName(appFileName),
                        ref si,
                        out pi))
                {
                    _logger.Log("Unable to create user process [CreateProcessAsUser="******"].", Logger.MsgType.ERROR);

                    Marshal.FreeHGlobal(hDuplicateToken);
                    Marshal.FreeHGlobal(hEnvironment);
                    Marshal.FreeHGlobal(hUserToken);
                    return(new Tuple <bool, int>(false, -1));
                }
                else
                {
                    _logger.Log("Created new process: " + pi.dwProcessId.ToString() + "/" + appFileName + " " + appArgs);
                    var newProcess = Process.GetProcessById(pi.dwProcessId);

                    try
                    {
                        // For UI apps, wait for idle state, before continuing.
                        newProcess.WaitForInputIdle(2000);
                    }
                    catch (InvalidOperationException)
                    {
                        // Must be a non-UI app, just give it a sec to start.
                        Thread.Sleep(1000);
                    }

                    newProcess.Dispose();
                    Marshal.FreeHGlobal(hDuplicateToken);
                    Marshal.FreeHGlobal(hEnvironment);
                    Marshal.FreeHGlobal(hUserToken);
                    return(new Tuple <bool, int>(true, pi.dwProcessId));
                }
            }
            catch (Exception e)
            {
                _logger.Log(e, "Failed to create process as user.");
                return(new Tuple <bool, int>(false, -1));
            }
        }
        public bool CreateProcessAsUser(WindowsIdentity userId, string appFileName, string appArgs)
        {
            try
            {
                _logger.Log("Create process for: " + userId.Name);
                List <Tuple <uint, string> > userSessions = new WindowsHelper(_logger).GetUserSessions();
                int sessionId = -1;

                foreach (Tuple <uint, string> logonSession in userSessions)
                {
                    if (logonSession.Item2.ToLower().Equals(userId.Name.ToLower()))
                    {
                        sessionId = (int)logonSession.Item1;
                        break;
                    }
                }

                if (sessionId == -1)
                {
                    _logger.Log("Failed to match any/existing logon session with user [" + userId.Name + "].", Logger.MsgType.ERROR);
                    return(false);
                }

                if (!NativeMethods.WTSQueryUserToken((uint)sessionId, out IntPtr hUserToken))
                {
                    _logger.Log("Failed to query user token [WTSQueryUserToken=" + Marshal.GetLastWin32Error().ToString() + "].", Logger.MsgType.ERROR);
                    return(false);
                }

                // Obtain duplicated user token (elevated if UAC is turned on/enabled).
                IntPtr hDuplicateToken = new WindowsHelper(_logger).DuplicateToken(hUserToken, (uint)sessionId);
                Marshal.FreeHGlobal(hUserToken);

                // Initialize process info and startup info.
                NativeMethods.PROCESS_INFORMATION pi = new NativeMethods.PROCESS_INFORMATION();
                NativeMethods.STARTUPINFO         si = new NativeMethods.STARTUPINFO();
                si.cb        = Marshal.SizeOf(si);
                si.lpDesktop = "winsta0\\default";
                NativeMethods.SECURITY_ATTRIBUTES lpProcessAttributes = new NativeMethods.SECURITY_ATTRIBUTES();
                NativeMethods.SECURITY_ATTRIBUTES lpThreadAttributes  = new NativeMethods.SECURITY_ATTRIBUTES();
                IntPtr hEnvironment = IntPtr.Zero;

                if (!NativeMethods.CreateEnvironmentBlock(out hEnvironment, hDuplicateToken, true))
                {
                    _logger.Log("Unable to create environment block [CreateEnvironmentBlock=" + Marshal.GetLastWin32Error().ToString() + "].", Logger.MsgType.WARN);
                }

                if (!NativeMethods.CreateProcessAsUser(
                        hDuplicateToken,
                        null,
                        appFileName + " " + appArgs,
                        ref lpProcessAttributes,
                        ref lpThreadAttributes,
                        false,
                        (uint)NativeMethods.CreateProcessFlags.NORMAL_PRIORITY_CLASS |
                        (uint)NativeMethods.CreateProcessFlags.CREATE_UNICODE_ENVIRONMENT |
                        (uint)NativeMethods.CreateProcessFlags.CREATE_NEW_CONSOLE,
                        hEnvironment,
                        Path.GetDirectoryName(appFileName),
                        ref si,
                        out pi))
                {
                    _logger.Log("ERROR: Unable to create user process [CreateProcessAsUser="******"].");
                    return(false);
                }
                else
                {
                    _logger.Log("Created new process: " + pi.dwProcessId.ToString() + "/" + appFileName + " " + appArgs);
                    var newProcess = Process.GetProcessById(pi.dwProcessId);

                    try
                    {
                        // For UI apps, wait for idle state, before continuing.
                        newProcess.WaitForInputIdle(2000);
                    }
                    catch (InvalidOperationException)
                    {
                        // Must be a non-UI app, just give it a sec to start.
                        Thread.Sleep(1000);
                    }

                    return(true);
                }
            }
            catch (Exception e)
            {
                _logger.Log(e, "Failed to create process as user.");
                return(false);
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// If HpcServiceHost is launched to run a pre/post task, launch the pre/post task
        /// </summary>
        private static bool RunPrePostTask(ref uint exitCode)
        {
            bool   prePostTaskExists      = false;
            string prePostTaskCommandLine = Environment.GetEnvironmentVariable(Constant.PrePostTaskCommandLineEnvVar);

            // Check if pre/post task exists
            prePostTaskExists = !string.IsNullOrEmpty(prePostTaskCommandLine);

            // if so run it
            if (prePostTaskExists)
            {
                string serviceWorkingDirectory = null;

                // Working directory is the service assembly's directory. If we are on Azure, change to the service package's dir. If
                //  not on azure use service assemblies directory from service config which is passed to svchost via env var so we dont
                //  need to read the svc config file again on every CN (which is slow)
                if (SoaHelper.IsOnAzure())
                {
                    serviceWorkingDirectory = Utility.GetServiceLocalCacheFullPath();
                }
                else
                {
                    serviceWorkingDirectory = Environment.ExpandEnvironmentVariables(
                        Environment.GetEnvironmentVariable(Constant.PrePostTaskOnPremiseWorkingDirEnvVar));
                }

                NativeMethods.STARTUPINFO startupInfo = new NativeMethods.STARTUPINFO();
                startupInfo.cb = Marshal.SizeOf(typeof(NativeMethods.STARTUPINFO));

                NativeMethods.PROCESS_INFORMATION processInfo = new NativeMethods.PROCESS_INFORMATION();

                StringBuilder commandLine = new StringBuilder();

                // Run command from comspec (like node manager babysitter) to ensure env vars are expanded and command runs as if launched from node manager
                commandLine.AppendFormat("\"{0}\" /S /c \"{1}\"", Environment.GetEnvironmentVariable("ComSpec"), prePostTaskCommandLine);

                TraceHelper.TraceInfo(
                    jobId,
                    "Executing '{0}'",
                    prePostTaskCommandLine);

                // Start the task
                bool ret = NativeMethods.CreateProcess(null,
                                                       commandLine,
                                                       IntPtr.Zero,
                                                       IntPtr.Zero,
                                                       true,
                                                       NativeMethods.CREATE_UNICODE_ENVIRONMENT,
                                                       IntPtr.Zero,
                                                       serviceWorkingDirectory,
                                                       ref startupInfo,
                                                       out processInfo);

                // If CreateProcess succeeded
                if (ret)
                {
                    using (SafeWaitHandle processHandle = new SafeWaitHandle(processInfo.hProcess, true))
                        using (SafeWaitHandle threadHandle = new SafeWaitHandle(processInfo.hThread, true))
                        {
                            if (processHandle.IsClosed || processHandle.IsInvalid)
                            {
                                TraceHelper.TraceError(
                                    jobId,
                                    "Process handle is invalid or closed. Task commandline = {0}",
                                    commandLine);

                                exitCode = 1;
                                return(true);
                            }

                            // Wait for task to complete
                            NativeMethods.WaitForSingleObject(processInfo.hProcess, Timeout.Infinite);

                            // Trace the results
                            NativeMethods.GetExitCodeProcess(new SafeProcessHandle(processInfo.hProcess, false), out exitCode);

                            TraceHelper.TraceInfo(
                                jobId,
                                "ExitCode = {0}",
                                exitCode);
                        }
                }
                else
                {
                    int errorCode = Marshal.GetLastWin32Error();

                    TraceHelper.TraceError(
                        jobId,
                        "Cannot start pre/post task: '{0}'. Exit code = {1}",
                        prePostTaskCommandLine, errorCode);

                    exitCode = (uint)errorCode;
                }
            }

            return(prePostTaskExists);
        }
Ejemplo n.º 17
0
        private bool StartWithCreateProcess(ProcessStartInfo startInfo)
        {
            if (startInfo.RedirectStandardInput)
            {
                throw new InvalidOperationException("Standard input redirect not allowed");
            }

            if (startInfo.RedirectStandardOutput)
            {
                throw new InvalidOperationException("Standard output redirect not allowed");
            }

            if (startInfo.RedirectStandardError)
            {
                throw new InvalidOperationException("Standard error redirect not allowed");
            }

            //Cannot start a new process and store its handle if the object has been disposed, since finalization has been suppressed.
            if (this._Disposed)
            {
                throw new ObjectDisposedException(GetType().Name);
            }

            StringBuilder commandLine = BuildCommandLine(startInfo.FileName, startInfo.Arguments);

            NativeMethods.STARTUPINFO         startupInfo = new NativeMethods.STARTUPINFO();
            NativeMethods.PROCESS_INFORMATION processInfo = new NativeMethods.PROCESS_INFORMATION();

            bool retVal;
            int  errorCode = 0;

            // set up the creation flags paramater
            int creationFlags = 0;

            if (startInfo.CreateNoWindow)
            {
                creationFlags          |= (int)NativeMethods.CreateProcessFlags.CREATE_NO_WINDOW;
                startupInfo.dwFlags     = NativeMethods.STARTF_USESHOWWINDOW;
                startupInfo.wShowWindow = (short)NativeMethods.SW_HIDE;
            }
            else
            {
                creationFlags |= (int)NativeMethods.CreateProcessFlags.CREATE_NEW_CONSOLE;
                switch (startInfo.WindowStyle)
                {
                case ProcessWindowStyle.Maximized:
                    startupInfo.dwFlags     = NativeMethods.STARTF_USESHOWWINDOW;
                    startupInfo.wShowWindow = (short)NativeMethods.SW_MAXIMIZE;
                    break;

                case ProcessWindowStyle.Minimized:
                    startupInfo.dwFlags     = NativeMethods.STARTF_USESHOWWINDOW;
                    startupInfo.wShowWindow = (short)NativeMethods.SW_MINIMIZE;
                    break;

                case ProcessWindowStyle.Hidden:
                    startupInfo.dwFlags     = NativeMethods.STARTF_USESHOWWINDOW;
                    startupInfo.wShowWindow = (short)NativeMethods.SW_HIDE;
                    break;
                }
            }

            string workingDirectory = startInfo.WorkingDirectory;

            if (workingDirectory == string.Empty)
            {
                workingDirectory = ProcessUtils.StartupPath;
            }

            RuntimeHelpers.PrepareConstrainedRegions();
            try { }
            finally
            {
                retVal = NativeMethods.CreateProcess(
                    null,                   // we don't need this since all the info is in commandLine
                    commandLine.ToString(), // pointer to the command line string
                    IntPtr.Zero,            // pointer to process security attributes, we don't need to inheriat the handle
                    IntPtr.Zero,            // pointer to thread security attributes
                    true,                   // handle inheritance flag
                    creationFlags,          // creation flags
                    IntPtr.Zero,            // pointer to new environment block
                    workingDirectory,       // pointer to current directory name
                    ref startupInfo,        // pointer to STARTUPINFO
                    out processInfo         // pointer to PROCESS_INFORMATION
                    );
                if (!retVal)
                {
                    errorCode = Marshal.GetLastWin32Error();
                }
            }
            if (!retVal)
            {
                if (errorCode == NativeMethods.ERROR_BAD_EXE_FORMAT)
                {
                    throw new Win32Exception(errorCode, "Invalid application");
                }
                throw new Win32Exception(errorCode);
            }


            bool ret = false;

            if (processInfo.hProcess != (IntPtr)0 && processInfo.hProcess != (IntPtr)NativeMethods.INVALID_HANDLE_VALUE)
            {
                _ProcessHandle     = processInfo.hProcess;
                _HaveProcessHandle = true;
                if (processInfo.hThread != (IntPtr)0 && processInfo.hThread != (IntPtr)NativeMethods.INVALID_HANDLE_VALUE)
                {
                    NativeMethods.CloseHandle(processInfo.hThread);
                }
                ret = true;
            }

            return(ret);
        }