Exemple #1
0
        public static Win32NativeEnvironmentBlock Create(byte[] environmentData)
        {
            var eb = new Win32NativeEnvironmentBlock(environmentData.Length);

            RuntimeHelpers.PrepareConstrainedRegions();
            try { } finally {
                IntPtr ptr = Marshal.AllocHGlobal(environmentData.Length);
                eb.SetHandle(ptr);
                Marshal.Copy(environmentData, 0, ptr, environmentData.Length);
            }

            return(eb);
        }
Exemple #2
0
 public Win32NativeEnvironmentBlock GetNativeEnvironmentBlock()
 {
     return(Win32NativeEnvironmentBlock.Create(ToByteArray()));
 }
Exemple #3
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));
            }
        }