AutoUpdater.NET icon indicating copy to clipboard operation
AutoUpdater.NET copied to clipboard

Application is Running Admin Mode ?

Open pc8181 opened this issue 5 years ago • 10 comments

Hi,

after extracted my application is running as Administrator mode because zip extractor is running as admin so that my application also as same privileges but want to execute normal mode

how can i execute my application without admin privileges after zip extraction ?

i will get an another error in web browser this site is not secure ....

Thanks

pc8181 avatar Jun 26 '19 13:06 pc8181

Hi, I am having the same problem. My users are not privileged, so the zip upgrade prompts for a privileged username/password to perform the upgrade (as it should). However, when the application is restarted, it still runs under the privileged user account, rather than the original users account. The user then needs to remember to shut the application down again and restart it. Many times they forget, and then a whole host of functions stop working including our email reporting of problems in the event log. I would be useful if the application restarts under the current user account, rather than the privileged users account.

Thanks

NeilMJohnson avatar Oct 09 '19 18:10 NeilMJohnson

Write piece of code in your application that checks if application is run as administrator:

public static bool IsAdministrator()
{
       WindowsIdentity identity = WindowsIdentity.GetCurrent();
       WindowsPrincipal principal = new WindowsPrincipal(identity);
       return principal.IsInRole(WindowsBuiltInRole.Administrator);
}

Then if it returns true just use code from Jonathan.Peppers:

if(IsAdministrator())
{
       ProcessAsUser.Launch(Process.GetCurrentProcess().MainModule.FileName);
       //Your exit code such as Environment.Exit() should go here
}

Jonathan.Peppers also explained how it works:

Actually looking at my sample, it grabs the user token from explorer.exe, so you don't need username/password.

That above should solve your problem, you can also use ProcessStartInfo to run the app under user that you want but then you need to know username and password or you could grab the primary token and environment block from the process that you like and change private static bool LaunchProcessAsUser(string cmdLine, IntPtr token, IntPtr envBlock) from private to public and call it with correct arguments.

But be careful, if explorer.exe is run as another user, not current user, then program will run under the user that explorer.exe is running.

DjordjeMandic avatar Oct 09 '19 22:10 DjordjeMandic

Hi Djordje, thanks for your reply. I had tried something like this, but my application is in VB and is a Single Instance Application. Therefore, the Launch does not work, as I immediately ends, before I can close my current instance. It would be useful if the ZIP Extractor did this for me, otherwise I am going to have to write another program that handles the restart, so the application will get started twice, rather than once.

Neil

NeilMJohnson avatar Oct 10 '19 22:10 NeilMJohnson

@NeilMJohnson Well add a little startup delay about 200ms to allow old process to exit. Im also using it with single instance application (mutex used to check if app is already running) and it has no problems restarting itself. Clone the repo then and modify the start method by replacing it with ProcessAsUser.Launch(string path). It can be written in vb easily. Its all .NET

DjordjeMandic avatar Oct 12 '19 00:10 DjordjeMandic

I all, maybe I lost some piece of code but I don't really understand how to update the application as administrator but restarting it without admin rights. Can someone please help me to get this fixed? @DjordjeMandic - I cannot see where in AutoUpdater I should place this code you mentioned. Any help would kindly be appreciated. Best regards, Alex

AlexBrunnerACAG avatar Aug 21 '20 08:08 AlexBrunnerACAG

@AlexBrunnerACAG put it at begging of ur program. let that be the first thing it does

DjordjeMandic avatar Sep 07 '20 05:09 DjordjeMandic

Hi my friends,

I got it setup and running.

Thanks a lot for your support.

Best regards, Alex

Freundliche Grüsse

Alex Brunner CTO, Head of Software Development, Partner Dipl. Wirtschaftsinformatiker HF [email protected]mailto:[email protected] [cid:[email protected]] ALL CONSULTING AG Schuppisstrasse 10 9016 St. Gallen www.all-consulting.chhttp://www.all-consulting.ch/

Zentrale Fax

+41 848 733 733 +41 848 733 734

8306 Brüttisellen / Fabrikweg 2 3018 Bern / Morgenstrasse 129 6002 Luzern / BUSINESS HUB LUZERN Reusseggstrasse 9

Wir begleiten Sie bei der Digitalisierung Ihrer Geschäftsprozesse - bitte kontaktieren Sie unshttps://all-consulting.ch/geschaeftstellen/standorte-ch-karte/hauptsitz-st-gallen/


Dieses E-Mail wurde durch aktuellste Technologien über mehrere Instanzen auf Viren und Malware geprüft. Der Inhalt dieses E-Mails ist vertraulich. Das E-Mail ist nur für den Adressaten bestimmt. Wenn Sie nicht der beabsichtigte Empfänger sind, sollten Sie uns so schnell als möglich benachrichtigen und dieses E-Mail löschen. In diesem Fall ist es Ihnen nicht gestattet, dieses E-Mail und/oder dessen Inhalt Dritten bekannt zu geben, zu kopieren, oder anderweitig zu verwenden. Widerhandlung ist strafbar.

Von: Djordje [email protected] Gesendet: Montag, 7. September 2020 07:04 An: ravibpatel/AutoUpdater.NET [email protected] Cc: Brunner, Alex [email protected]; Mention [email protected] Betreff: Re: [ravibpatel/AutoUpdater.NET] Application is Running Admin Mode ? (#284)

@AlexBrunnerACAGhttps://github.com/AlexBrunnerACAG put it at begging of ur program. let that be the first thing it does

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/ravibpatel/AutoUpdater.NET/issues/284#issuecomment-688037142, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AJN2WA4C7QYM2Q4OPVOTUR3SERSSTANCNFSM4H3SBHUQ.

AlexBrunnerACAG avatar Sep 07 '20 05:09 AlexBrunnerACAG

Hi @DjordjeMandic

I have tried to get the restart running for many days now. I am not able to do that because it isn't as simple as you mentioned.

Restarting an application with normal privileges, if it is running with elevated privileges, seems to be a very hard task to do. You have to take care of all the environment settings like UAC as well.

I would really appreciate if AutoUpdater.NET would be able to do that out of the box.

Best regards, Alex

AlexBrunnerACAG avatar Oct 29 '20 09:10 AlexBrunnerACAG

@AlexBrunnerACAG Try this solution from github. I'm not the creator neither the participant in source code of this library.

DjordjeMandic avatar Oct 29 '20 14:10 DjordjeMandic

Hi @DjordjeMandic

You are my hero. Based on you hint I was able to implement the behavior. Thank you very much.

To help others implementing this I will add the complete code here. I also added support for arguments which is very important for us.

The entry point:

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    /// <param name="args">Command line arguments</param>
    [STAThread]
    public static void Main(string[] args)
    {
      Dnx.DnxCommon.LoggerManager logger = new Dnx.DnxCommon.LoggerManager();

      List<string> argList = new List<string>(args);

      // detect forced restart to prevent from endless restarting attempts
      bool isRestarting =
        argList.Contains("restart") ||
        argList.Contains("/restart");

      // check for elevated process scenario at regular startup - starting with having the debugger attached is always an elevated process; thus we have to take care of the debugger
      if (!isRestarting &&
        !Debugger.IsAttached && 
        HelpDeskWinFormsLibrary.UACHelper.IsProcessElevated)
      {
        argList.Add("/restart");
        logger.Warn("Application Restart", "Application running as elevated process. Restarting as desktop user process...", true);

        ProcessSupport.RunAsDesktopUser(Process.GetCurrentProcess().MainModule.FileName, argList.ToArray());
      }
      else
      {
        if (isRestarting) logger.Warn("Application Restart", "Application successfuly restarted and running as desktop user process.", true);
        
        AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

        ACAG.Utility.AutoUpdater.AutoUpdaterHandler.Instance.CheckForUpdate(true);

        using (ApplicationTemplate applicationTemplate = new ApplicationTemplate())
        {
          applicationTemplate.RunApplication(args);
        }
      }
    }

The UACHelper class:

  /// <summary>
  /// UAC helper
  /// </summary>
  public static class UACHelper
  {
    /// <summary>
    /// The uac registry key
    /// </summary>
    private const string uacRegistryKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
    /// <summary>
    /// The uac registry value
    /// </summary>
    private const string uacRegistryValue = "EnableLUA";

    /// <summary>
    /// The standard rights read
    /// </summary>
    private static uint STANDARD_RIGHTS_READ = 0x00020000;
    /// <summary>
    /// The token query
    /// </summary>
    private static uint TOKEN_QUERY = 0x0008;
    /// <summary>
    /// The token read
    /// </summary>
    private static uint TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY);

    /// <summary>
    /// Opens the process token.
    /// </summary>
    /// <param name="ProcessHandle">The process handle.</param>
    /// <param name="DesiredAccess">The desired access.</param>
    /// <param name="TokenHandle">The token handle.</param>
    /// <returns></returns>
    [DllImport("advapi32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);

    /// <summary>
    /// Closes the handle.
    /// </summary>
    /// <param name="hObject">The h object.</param>
    /// <returns></returns>
    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool CloseHandle(IntPtr hObject);

    /// <summary>
    /// Gets the token information.
    /// </summary>
    /// <param name="TokenHandle">The token handle.</param>
    /// <param name="TokenInformationClass">The token information class.</param>
    /// <param name="TokenInformation">The token information.</param>
    /// <param name="TokenInformationLength">Length of the token information.</param>
    /// <param name="ReturnLength">Length of the return.</param>
    /// <returns></returns>
    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool GetTokenInformation(IntPtr TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, IntPtr TokenInformation, uint TokenInformationLength, out uint ReturnLength);

    /// <summary>
    /// TOKEN_INFORMATION_CLASS
    /// </summary>
    public enum TOKEN_INFORMATION_CLASS
    {
      /// <summary>
      /// The token user
      /// </summary>
      TokenUser = 1,
      /// <summary>
      /// The token groups
      /// </summary>
      TokenGroups,
      /// <summary>
      /// The token privileges
      /// </summary>
      TokenPrivileges,
      /// <summary>
      /// The token owner
      /// </summary>
      TokenOwner,
      /// <summary>
      /// The token primary group
      /// </summary>
      TokenPrimaryGroup,
      /// <summary>
      /// The token default dacl
      /// </summary>
      TokenDefaultDacl,
      /// <summary>
      /// The token source
      /// </summary>
      TokenSource,
      /// <summary>
      /// The token type
      /// </summary>
      TokenType,
      /// <summary>
      /// The token impersonation level
      /// </summary>
      TokenImpersonationLevel,
      /// <summary>
      /// The token statistics
      /// </summary>
      TokenStatistics,
      /// <summary>
      /// The token restricted sids
      /// </summary>
      TokenRestrictedSids,
      /// <summary>
      /// The token session identifier
      /// </summary>
      TokenSessionId,
      /// <summary>
      /// The token groups and privileges
      /// </summary>
      TokenGroupsAndPrivileges,
      /// <summary>
      /// The token session reference
      /// </summary>
      TokenSessionReference,
      /// <summary>
      /// The token sand box inert
      /// </summary>
      TokenSandBoxInert,
      /// <summary>
      /// The token audit policy
      /// </summary>
      TokenAuditPolicy,
      /// <summary>
      /// The token origin
      /// </summary>
      TokenOrigin,
      /// <summary>
      /// The token elevation type
      /// </summary>
      TokenElevationType,
      /// <summary>
      /// The token linked token
      /// </summary>
      TokenLinkedToken,
      /// <summary>
      /// The token elevation
      /// </summary>
      TokenElevation,
      /// <summary>
      /// The token has restrictions
      /// </summary>
      TokenHasRestrictions,
      /// <summary>
      /// The token access information
      /// </summary>
      TokenAccessInformation,
      /// <summary>
      /// The token virtualization allowed
      /// </summary>
      TokenVirtualizationAllowed,
      /// <summary>
      /// The token virtualization enabled
      /// </summary>
      TokenVirtualizationEnabled,
      /// <summary>
      /// The token integrity level
      /// </summary>
      TokenIntegrityLevel,
      /// <summary>
      /// The token UI access
      /// </summary>
      TokenUIAccess,
      /// <summary>
      /// The token mandatory policy
      /// </summary>
      TokenMandatoryPolicy,
      /// <summary>
      /// The token logon sid
      /// </summary>
      TokenLogonSid,
      /// <summary>
      /// The maximum token information class
      /// </summary>
      MaxTokenInfoClass
    }

    /// <summary>
    /// TOKEN_ELEVATION_TYPE
    /// </summary>
    public enum TOKEN_ELEVATION_TYPE
    {
      /// <summary>
      /// The token elevation type default
      /// </summary>
      TokenElevationTypeDefault = 1,
      /// <summary>
      /// The token elevation type full
      /// </summary>
      TokenElevationTypeFull,
      /// <summary>
      /// The token elevation type limited
      /// </summary>
      TokenElevationTypeLimited
    }

    /// <summary>
    /// Gets a value indicating whether this instance is uac enabled.
    /// </summary>
    /// <value>
    ///   <c>true</c> if this instance is uac enabled; otherwise, <c>false</c>.
    /// </value>
    public static bool IsUacEnabled
    {
      get
      {
        using (RegistryKey uacKey = Registry.LocalMachine.OpenSubKey(uacRegistryKey, false))
        {
          bool result = uacKey.GetValue(uacRegistryValue).Equals(1);
          return result;
        }
      }
    }

    /// <summary>
    /// Gets a value indicating whether this instance is process elevated.
    /// </summary>
    /// <value>
    ///   <c>true</c> if this instance is process elevated; otherwise, <c>false</c>.
    /// </value>
    /// <exception cref="ApplicationException">
    /// Could not get process token.  Win32 Error Code: " +
    ///                                            Marshal.GetLastWin32Error()
    /// or
    /// Unable to determine the current elevation.
    /// </exception>
    public static bool IsProcessElevated
    {
      get
      {
        if (IsUacEnabled)
        {
          IntPtr tokenHandle = IntPtr.Zero;
          if (!OpenProcessToken(Process.GetCurrentProcess().Handle, TOKEN_READ, out tokenHandle))
          {
            throw new ApplicationException("Could not get process token.  Win32 Error Code: " +
                                           Marshal.GetLastWin32Error());
          }

          try
          {
            TOKEN_ELEVATION_TYPE elevationResult = TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault;

            int elevationResultSize = Marshal.SizeOf((int)elevationResult);
            uint returnedSize = 0;
            IntPtr elevationTypePtr = Marshal.AllocHGlobal(elevationResultSize);
            try
            {
              bool success = GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS.TokenElevationType, elevationTypePtr, (uint)elevationResultSize, out returnedSize); 
              if (success)
              {
                elevationResult = (TOKEN_ELEVATION_TYPE)Marshal.ReadInt32(elevationTypePtr);
                bool isProcessAdmin = elevationResult == TOKEN_ELEVATION_TYPE.TokenElevationTypeFull;
                return isProcessAdmin;
              }
              else
              {
                int lastError = Marshal.GetLastWin32Error();

                var error = new Win32Exception(Marshal.GetLastWin32Error()).Message;
                throw new ApplicationException("Unable to determine the current elevation.");
              }
            }
            finally
            {
              if (elevationTypePtr != IntPtr.Zero)
                Marshal.FreeHGlobal(elevationTypePtr);
            }
          }
          finally
          {
            if (tokenHandle != IntPtr.Zero)
              CloseHandle(tokenHandle);
          }
        }
        else
        {
          WindowsIdentity identity = WindowsIdentity.GetCurrent();
          WindowsPrincipal principal = new WindowsPrincipal(identity);
          bool result = principal.IsInRole(WindowsBuiltInRole.Administrator)
                     || principal.IsInRole(0x200); //Domain Administrator
          return result;
        }
      }
    }
  }

And the class ProcessSupport:

  /// <summary>
  /// ProcessSupport
  /// </summary>
  public static class ProcessSupport
  {
    /// <summary>
    /// Runs as desktop user.
    /// </summary>
    /// <param name="fileName">Name of the file.</param>
    /// <param name="args">The arguments.</param>
    /// <exception cref="ArgumentException">Value cannot be null or whitespace. - fileName</exception>
    public static void RunAsDesktopUser(string fileName, params string[] args)
    {
      if (string.IsNullOrWhiteSpace(fileName))
        throw new ArgumentException("Value cannot be null or whitespace.", nameof(fileName));

      // To start process as shell user you will need to carry out these steps:
      // 1. Enable the SeIncreaseQuotaPrivilege in your current token
      // 2. Get an HWND representing the desktop shell (GetShellWindow)
      // 3. Get the Process ID(PID) of the process associated with that window(GetWindowThreadProcessId)
      // 4. Open that process(OpenProcess)
      // 5. Get the access token from that process (OpenProcessToken)
      // 6. Make a primary token with that token(DuplicateTokenEx)
      // 7. Start the new process with that primary token(CreateProcessWithTokenW)

      var hProcessToken = IntPtr.Zero;
      // Enable SeIncreaseQuotaPrivilege in this process.  (This won't work if current process is not elevated.)
      try
      {
        var process = GetCurrentProcess();
        if (!OpenProcessToken(process, 0x0020, ref hProcessToken))
          return;

        var tkp = new TOKEN_PRIVILEGES
        {
          PrivilegeCount = 1,
          Privileges = new LUID_AND_ATTRIBUTES[1]
        };

        if (!LookupPrivilegeValue(null, "SeIncreaseQuotaPrivilege", ref tkp.Privileges[0].Luid))
          return;

        tkp.Privileges[0].Attributes = 0x00000002;

        if (!AdjustTokenPrivileges(hProcessToken, false, ref tkp, 0, IntPtr.Zero, IntPtr.Zero))
          return;
      }
      finally
      {
        if (hProcessToken != IntPtr.Zero) CloseHandle(hProcessToken);
      }

      // Get an HWND representing the desktop shell.
      // CAVEATS:  This will fail if the shell is not running (crashed or terminated), or the default shell has been
      // replaced with a custom shell.  This also won't return what you probably want if Explorer has been terminated and
      // restarted elevated.
      var hwnd = GetShellWindow();
      if (hwnd == IntPtr.Zero)
        return;

      var hShellProcess = IntPtr.Zero;
      var hShellProcessToken = IntPtr.Zero;
      var hPrimaryToken = IntPtr.Zero;
      try
      {
        // Get the PID of the desktop shell process.
        uint dwPID;
        if (GetWindowThreadProcessId(hwnd, out dwPID) == 0)
          return;

        // Open the desktop shell process in order to query it (get the token)
        hShellProcess = OpenProcess(ProcessAccessFlags.QueryInformation, false, dwPID);
        if (hShellProcess == IntPtr.Zero)
          return;

        // Get the process token of the desktop shell.
        if (!OpenProcessToken(hShellProcess, 0x0002, ref hShellProcessToken))
          return;

        var dwTokenRights = 395U;

        // Duplicate the shell's process token to get a primary token.
        // Based on experimentation, this is the minimal set of rights required for CreateProcessWithTokenW (contrary to current documentation).
        if (!DuplicateTokenEx(hShellProcessToken, dwTokenRights, IntPtr.Zero, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, TOKEN_TYPE.TokenPrimary, out hPrimaryToken))
          return;

        // Prepare arguments
        string arguments = string.Empty;
        string delimiter = string.Empty;
        foreach (var arg in args)
        {
          arguments += delimiter;
          arguments += arg;

          delimiter = " ";
        }

        string command = fileName + " " + arguments;

        // Start the target process with the new token.
        var si = new STARTUPINFO();
        var pi = new PROCESS_INFORMATION();
        bool result = CreateProcessWithTokenW(
               hPrimaryToken,
               0,
               null,
               command,
               0,
               IntPtr.Zero,
               Path.GetDirectoryName(fileName),
               ref si,
               out pi);
        if (!result)
        {
          int error = Marshal.GetLastWin32Error();
          var ex = new Win32Exception(error);
          var errorMessage = ex.Message;
          string message = $"CreateProcessWithTokenW Error: {error} - {errorMessage}";
          throw ex;
        }
      }
      finally
      {
        if (hShellProcessToken != IntPtr.Zero) CloseHandle(hShellProcessToken);
        if (hPrimaryToken != IntPtr.Zero) CloseHandle(hPrimaryToken);
        if (hShellProcess != IntPtr.Zero) CloseHandle(hShellProcess);
      }

    }

    #region Interop

    /// <summary>
    /// TOKEN_PRIVILEGES
    /// </summary>
    private struct TOKEN_PRIVILEGES
    {
      /// <summary>
      /// The privilege count
      /// </summary>
      public UInt32 PrivilegeCount;
      /// <summary>
      /// The privileges
      /// </summary>
      [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
      public LUID_AND_ATTRIBUTES[] Privileges;
    }

    /// <summary>
    /// LUID_AND_ATTRIBUTES
    /// </summary>
    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    private struct LUID_AND_ATTRIBUTES
    {
      /// <summary>
      /// The luid
      /// </summary>
      public LUID Luid;
      /// <summary>
      /// The attributes
      /// </summary>
      public UInt32 Attributes;
    }

    /// <summary>
    /// LUID
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    private struct LUID
    {
      /// <summary>
      /// The low part
      /// </summary>
      public uint LowPart;
      /// <summary>
      /// The high part
      /// </summary>
      public int HighPart;
    }

    /// <summary>
    /// ProcessAccessFlags
    /// </summary>
    [Flags]
    private enum ProcessAccessFlags : uint
    {
      /// <summary>
      /// All
      /// </summary>
      All = 0x001F0FFF,
      /// <summary>
      /// The terminate
      /// </summary>
      Terminate = 0x00000001,
      /// <summary>
      /// The create thread
      /// </summary>
      CreateThread = 0x00000002,
      /// <summary>
      /// The virtual memory operation
      /// </summary>
      VirtualMemoryOperation = 0x00000008,
      /// <summary>
      /// The virtual memory read
      /// </summary>
      VirtualMemoryRead = 0x00000010,
      /// <summary>
      /// The virtual memory write
      /// </summary>
      VirtualMemoryWrite = 0x00000020,
      /// <summary>
      /// The duplicate handle
      /// </summary>
      DuplicateHandle = 0x00000040,
      /// <summary>
      /// The create process
      /// </summary>
      CreateProcess = 0x000000080,
      /// <summary>
      /// The set quota
      /// </summary>
      SetQuota = 0x00000100,
      /// <summary>
      /// The set information
      /// </summary>
      SetInformation = 0x00000200,
      /// <summary>
      /// The query information
      /// </summary>
      QueryInformation = 0x00000400,
      /// <summary>
      /// The query limited information
      /// </summary>
      QueryLimitedInformation = 0x00001000,
      /// <summary>
      /// The synchronize
      /// </summary>
      Synchronize = 0x00100000
    }

    /// <summary>
    /// SECURITY_IMPERSONATION_LEVEL
    /// </summary>
    private enum SECURITY_IMPERSONATION_LEVEL
    {
      /// <summary>
      /// The security anonymous
      /// </summary>
      SecurityAnonymous,
      /// <summary>
      /// The security identification
      /// </summary>
      SecurityIdentification,
      /// <summary>
      /// The security impersonation
      /// </summary>
      SecurityImpersonation,
      /// <summary>
      /// The security delegation
      /// </summary>
      SecurityDelegation
    }

    /// <summary>
    /// TOKEN_TYPE
    /// </summary>
    private enum TOKEN_TYPE
    {
      /// <summary>
      /// The token primary
      /// </summary>
      TokenPrimary = 1,
      /// <summary>
      /// The token impersonation
      /// </summary>
      TokenImpersonation
    }

    /// <summary>
    /// PROCESS_INFORMATION
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    private struct PROCESS_INFORMATION
    {
      /// <summary>
      /// The h process
      /// </summary>
      public IntPtr hProcess;
      /// <summary>
      /// The h thread
      /// </summary>
      public IntPtr hThread;
      /// <summary>
      /// The dw process identifier
      /// </summary>
      public int dwProcessId;
      /// <summary>
      /// The dw thread identifier
      /// </summary>
      public int dwThreadId;
    }

    /// <summary>
    /// STARTUPINFO
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    private struct STARTUPINFO
    {
      /// <summary>
      /// The cb
      /// </summary>
      public Int32 cb;
      /// <summary>
      /// The lp reserved
      /// </summary>
      public string lpReserved;
      /// <summary>
      /// The lp desktop
      /// </summary>
      public string lpDesktop;
      /// <summary>
      /// The lp title
      /// </summary>
      public string lpTitle;
      /// <summary>
      /// The dw x
      /// </summary>
      public Int32 dwX;
      /// <summary>
      /// The dw y
      /// </summary>
      public Int32 dwY;
      /// <summary>
      /// The dw x size
      /// </summary>
      public Int32 dwXSize;
      /// <summary>
      /// The dw y size
      /// </summary>
      public Int32 dwYSize;
      /// <summary>
      /// The dw x count chars
      /// </summary>
      public Int32 dwXCountChars;
      /// <summary>
      /// The dw y count chars
      /// </summary>
      public Int32 dwYCountChars;
      /// <summary>
      /// The dw fill attribute
      /// </summary>
      public Int32 dwFillAttribute;
      /// <summary>
      /// The dw flags
      /// </summary>
      public Int32 dwFlags;
      /// <summary>
      /// The w show window
      /// </summary>
      public Int16 wShowWindow;
      /// <summary>
      /// The cb reserved2
      /// </summary>
      public Int16 cbReserved2;
      /// <summary>
      /// The lp reserved2
      /// </summary>
      public IntPtr lpReserved2;
      /// <summary>
      /// The h standard input
      /// </summary>
      public IntPtr hStdInput;
      /// <summary>
      /// The h standard output
      /// </summary>
      public IntPtr hStdOutput;
      /// <summary>
      /// The h standard error
      /// </summary>
      public IntPtr hStdError;
    }

    /// <summary>
    /// Gets the current process.
    /// </summary>
    /// <returns></returns>
    [DllImport("kernel32.dll", ExactSpelling = true)]
    private static extern IntPtr GetCurrentProcess();

    /// <summary>
    /// Opens the process token.
    /// </summary>
    /// <param name="h">The h.</param>
    /// <param name="acc">The acc.</param>
    /// <param name="phtok">The phtok.</param>
    /// <returns></returns>
    [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
    private static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);

    /// <summary>
    /// Lookups the privilege value.
    /// </summary>
    /// <param name="host">The host.</param>
    /// <param name="name">The name.</param>
    /// <param name="pluid">The pluid.</param>
    /// <returns></returns>
    [DllImport("advapi32.dll", SetLastError = true)]
    private static extern bool LookupPrivilegeValue(string host, string name, ref LUID pluid);

    /// <summary>
    /// Adjusts the token privileges.
    /// </summary>
    /// <param name="htok">The htok.</param>
    /// <param name="disall">if set to <c>true</c> [disall].</param>
    /// <param name="newst">The newst.</param>
    /// <param name="len">The length.</param>
    /// <param name="prev">The previous.</param>
    /// <param name="relen">The relen.</param>
    /// <returns></returns>
    [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
    private static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, ref TOKEN_PRIVILEGES newst, int len, IntPtr prev, IntPtr relen);

    /// <summary>
    /// Closes the handle.
    /// </summary>
    /// <param name="hObject">The h object.</param>
    /// <returns></returns>
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool CloseHandle(IntPtr hObject);


    /// <summary>
    /// Gets the shell window.
    /// </summary>
    /// <returns></returns>
    [DllImport("user32.dll")]
    private static extern IntPtr GetShellWindow();

    /// <summary>
    /// Gets the window thread process identifier.
    /// </summary>
    /// <param name="hWnd">The h WND.</param>
    /// <param name="lpdwProcessId">The LPDW process identifier.</param>
    /// <returns></returns>
    [DllImport("user32.dll", SetLastError = true)]
    private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

    /// <summary>
    /// Opens the process.
    /// </summary>
    /// <param name="processAccess">The process access.</param>
    /// <param name="bInheritHandle">if set to <c>true</c> [b inherit handle].</param>
    /// <param name="processId">The process identifier.</param>
    /// <returns></returns>
    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, uint processId);

    /// <summary>
    /// Duplicates the token ex.
    /// </summary>
    /// <param name="hExistingToken">The h existing token.</param>
    /// <param name="dwDesiredAccess">The dw desired access.</param>
    /// <param name="lpTokenAttributes">The lp token attributes.</param>
    /// <param name="impersonationLevel">The impersonation level.</param>
    /// <param name="tokenType">Type of the token.</param>
    /// <param name="phNewToken">The ph new token.</param>
    /// <returns></returns>
    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern bool DuplicateTokenEx(IntPtr hExistingToken, uint dwDesiredAccess, IntPtr lpTokenAttributes, SECURITY_IMPERSONATION_LEVEL impersonationLevel, TOKEN_TYPE tokenType, out IntPtr phNewToken);

    /// <summary>
    /// Creates the process with token w.
    /// </summary>
    /// <param name="hToken">The h token.</param>
    /// <param name="dwLogonFlags">The dw logon flags.</param>
    /// <param name="lpApplicationName">Name of the lp application.</param>
    /// <param name="lpCommandLine">The lp command line.</param>
    /// <param name="dwCreationFlags">The dw creation flags.</param>
    /// <param name="lpEnvironment">The lp environment.</param>
    /// <param name="lpCurrentDirectory">The lp current directory.</param>
    /// <param name="lpStartupInfo">The lp startup information.</param>
    /// <param name="lpProcessInformation">The lp process information.</param>
    /// <returns></returns>
    [DllImport("advapi32", SetLastError = true, CharSet = CharSet.Unicode)]
    private static extern bool CreateProcessWithTokenW(IntPtr hToken, int dwLogonFlags, string lpApplicationName, string lpCommandLine, int dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);

    #endregion
  }

AlexBrunnerACAG avatar Nov 03 '20 12:11 AlexBrunnerACAG