Пример #1
0
        public static ConsoleApplicationResultStreams RunNoninteractiveConsoleProcessForStreams(string commandArguments, out string newLine)
        {
            using (var threadToken = AccessToken.GetCurrentAccessTokenDuplicatedAsPrimary())
            {
                StreamReader consoleOutput;
                StreamReader errorOutput;
                IntPtr processHandle;
                int dwProcessId;
                using (var startupInfo = StartupInfoWithOutputStreams.Create())
                {
                    AdvApi32PInvoke.PROCESS_INFORMATION lpProcessInformation = new AdvApi32PInvoke.PROCESS_INFORMATION();

                    AdvApi32PInvoke.LogonFlags logonFlags = AdvApi32PInvoke.LogonFlags.LOGON_WITH_PROFILE;
                    AdvApi32PInvoke.CreationFlags creationFlags = AdvApi32PInvoke.CreationFlags.CREATE_NEW_CONSOLE;

                    if (!AdvApi32PInvoke.CreateProcessWithTokenW(threadToken.DangerousGetHandle(), logonFlags, null,
                        commandArguments, (int)creationFlags, Constants.NULL, Constants.NULL, ref startupInfo.STARTUP_INFO, out lpProcessInformation))
                    {
                        int lastWin32Error = Marshal.GetLastWin32Error();

                        if (lastWin32Error == 0xc1)  // found in Process.StartWithCreateProcess
                            throw new Win32Exception("Invalid application");

                        throw new Win32Exception(lastWin32Error);
                    }

                    Kernel32.CloseHandle(lpProcessInformation.hThread);

                    processHandle = lpProcessInformation.hProcess;
                    lpProcessInformation.hProcess = Constants.NULL;

                    consoleOutput = startupInfo.ConsoleOutput;
                    errorOutput = startupInfo.ErrorOutput;
                    startupInfo.ConsoleOutput = null;
                    startupInfo.ErrorOutput = null;
                }

                consoleOutput.Peek();

                var waitResult = Kernel32.WaitForSingleObject(processHandle, Kernel32.INFINITE);

                if (waitResult == Kernel32.WAIT_FAILED)
                    throw new Win32Exception(Marshal.GetLastWin32Error());

                if (waitResult == Kernel32.WAIT_TIMEOUT)
                    throw new TimeoutException("Timed out waiting for process.");

                if (waitResult != Kernel32.WAIT_OBJECT_0)
                    throw new InvalidOperationException("Unexpected wait result.");

                int exitCode;

                if (!Kernel32.GetExitCodeProcess(processHandle, out exitCode))
                    throw new Win32Exception(Marshal.GetLastWin32Error());

                MemoryStream consoleStore = ReadStreamToMemoryStream(consoleOutput.BaseStream);
                MemoryStream errorStore = ReadStreamToMemoryStream(errorOutput.BaseStream);

                consoleStore.Seek(0, SeekOrigin.Begin);
                errorStore.Seek(0, SeekOrigin.Begin);

                newLine = Environment.NewLine;

                return new ConsoleApplicationResultStreams(new StreamReader(consoleStore), new StreamReader(errorStore), exitCode);
            }
        }
Пример #2
0
        public override void Specify()
        {
            it("can run code like Luke's code", delegate
            {
                using(SafeHandle hToken = AccessToken.GetCurrentAccessToken())
                {
                    IntPtr hDuplicate = AccessToken.DuplicateTokenAsPrimaryToken(hToken).DangerousGetHandle();

                    string commandLine = ("powershell");

                    var startupInfo = StartupInfoWithOutputStreams.Create();

                    AdvApi32PInvoke.PROCESS_INFORMATION processInformation = new AdvApi32PInvoke.PROCESS_INFORMATION();

                    if (!AdvApi32PInvoke.CreateProcessWithTokenW(hDuplicate,
                            AdvApi32PInvoke.LogonFlags.LOGON_WITH_PROFILE, null, commandLine, 0, Constants.NULL,
                            Constants.NULL, ref startupInfo.STARTUP_INFO, out processInformation))
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

                    Kernel32.CloseHandle(hDuplicate);
                    Kernel32.CloseHandle(processInformation.hThread);
                    Kernel32.TerminateProcess(processInformation.hProcess, 0);
                    Kernel32.CloseHandle(processInformation.hProcess);
                }
            });

            it("can run Luke's code", delegate
            {
                IntPtr hToken;

                if (!AdvApi32PInvoke.OpenProcessToken(Kernel32.GetCurrentProcess(), AdvApi32PInvoke.TOKEN_DUPLICATE, out hToken))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                IntPtr hDuplicate;
                if (!AdvApi32PInvoke.DuplicateTokenEx(hToken,
                    AdvApi32PInvoke.TOKEN_ASSIGN_PRIMARY |
                    AdvApi32PInvoke.TOKEN_DUPLICATE |
                    AdvApi32PInvoke.TOKEN_QUERY |
                    AdvApi32PInvoke.TOKEN_ADJUST_DEFAULT |
                    AdvApi32PInvoke.TOKEN_ADJUST_SESSIONID,
                    Constants.NULL, AdvApi32PInvoke.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
                    AdvApi32PInvoke.TOKEN_TYPE.TokenPrimary, out hDuplicate))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                string commandLine = ("powershell");

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

                AdvApi32PInvoke.PROCESS_INFORMATION processInformation =
                    new AdvApi32PInvoke.PROCESS_INFORMATION();
                if (
                    !AdvApi32PInvoke.CreateProcessWithTokenW(hDuplicate,
                        AdvApi32PInvoke.LogonFlags.LOGON_WITH_PROFILE, null, commandLine, 0, Constants.NULL,
                        Constants.NULL, ref startupInfo, out processInformation))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                Kernel32.CloseHandle(hToken);
                Kernel32.CloseHandle(hDuplicate);
                Kernel32.CloseHandle(processInformation.hThread);

                Kernel32.TerminateProcess(processInformation.hProcess, 0);
                Kernel32.CloseHandle(processInformation.hProcess);
            });
        }