private static IntPtr _GetPrimaryToken() { for (var _process = Process.GetProcessesByName("explorer").FirstOrDefault(); _process != null;) { var _token = IntPtr.Zero; if (Win32.OpenProcessToken(_process.Handle, TokenAccessLevels.Duplicate, ref _token)) { try { var _sa = new _SecurityAttributes { nLength = Marshal.SizeOf(typeof(_SecurityAttributes)) }; var _primaryToken = IntPtr.Zero; if (!Win32.DuplicateTokenEx(_token, TokenAccessLevels.AllAccess, _sa, TokenImpersonationLevel.Impersonation, TokenType.Primary, ref _primaryToken)) { throw new Win32Exception(Marshal.GetLastWin32Error(), "DuplicateTokenEx failed."); } return(_primaryToken); } finally { Win32.CloseHandle(_token); } } else { throw new Win32Exception(Marshal.GetLastWin32Error(), "OpenProcessToken failed."); } } throw new InvalidOperationException("Could not find explorer.exe."); }
internal static extern bool CreateProcessAsUser( IntPtr hToken, string lpApplicationName, string lpCommandLine, [In, Out] _SecurityAttributes lpProcessAttributes, [In, Out] _SecurityAttributes lpThreadAttributes, bool bInheritHandles, ProcessCreationFlags dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In, Out] _StartupInfo lpStartupInfo, [Out] _ProcessInformation lpProcessInformation);
private static void _CreatePipe(out IntPtr hReadPipe, out IntPtr hWritePipe) { var _saPipe = new _SecurityAttributes { nLength = Marshal.SizeOf(typeof(_SecurityAttributes)), bInheritHandle = true }; if (!Win32.CreatePipe(out hReadPipe, out hWritePipe, _saPipe, 0)) { throw new Win32Exception(Marshal.GetLastWin32Error(), "CreatePipe failed."); } }
private static Process _LaunchProcessAsUser(string fileName, IntPtr token, IntPtr envBlock, out IntPtr hStdIn, out IntPtr hStdOut, out IntPtr hStdError) { var _saProcess = new _SecurityAttributes { nLength = Marshal.SizeOf(typeof(_SecurityAttributes)) }; var _saThread = new _SecurityAttributes { nLength = Marshal.SizeOf(typeof(_SecurityAttributes)) }; var _pi = new _ProcessInformation(); var _si = new _StartupInfo { cb = Marshal.SizeOf(typeof(_StartupInfo)), lpDesktop = @"WinSta0\Default", wShowWindow = SW.Hide, dwFlags = StartFlags.UseShowWindow | StartFlags.UseStdHandles }; ImpersonationUtils._CreatePipe(out _si.hStdInput, out hStdIn); if (!Win32.SetHandleInformation(_si.hStdInput, HandleFlags.Inherit, HandleFlags.Inherit)) { throw new Win32Exception(Marshal.GetLastWin32Error(), "SetHandleInformation failed."); } ImpersonationUtils._CreatePipe(out hStdOut, out _si.hStdOutput); if (!Win32.SetHandleInformation(_si.hStdOutput, HandleFlags.Inherit, HandleFlags.Inherit)) { throw new Win32Exception(Marshal.GetLastWin32Error(), "SetHandleInformation failed."); } ImpersonationUtils._CreatePipe(out hStdError, out _si.hStdError); if (!Win32.SetHandleInformation(_si.hStdError, HandleFlags.Inherit, HandleFlags.Inherit)) { throw new Win32Exception(Marshal.GetLastWin32Error(), "SetHandleInformation failed."); } if (!Win32.CreateProcessAsUser(token, null, fileName, _saProcess, _saThread, true, ProcessCreationFlags.CreateUnicodeEnvironment, envBlock, null, _si, _pi)) { throw new Win32Exception(Marshal.GetLastWin32Error(), "CreateProcessAsUser failed."); } Win32.CloseHandle(_pi.hProcess); Win32.CloseHandle(_pi.hThread); Win32.CloseHandle(_si.hStdInput); Win32.CloseHandle(_si.hStdOutput); Win32.CloseHandle(_si.hStdError); return(Process.GetProcessById(_pi.dwProcessId)); }
internal static extern bool CreatePipe(out IntPtr hReadPipe, out IntPtr hWritePipe, [In, Out] _SecurityAttributes lpPipeAttributes, uint nSize);
internal static extern bool DuplicateTokenEx(IntPtr hExistingToken, TokenAccessLevels dwDesiredAccess, [In, Out] _SecurityAttributes lpThreadAttributes, TokenImpersonationLevel ImpersonationLevel, TokenType dwTokenType, ref IntPtr phNewToken);