AdjustTokenPrivileges (advapi32)
Last changed: -91.119.3.204

.
Summary
Enables or disables privileges in a specified access token

C# Signature:

// Use this signature if you want the previous state information returned
[DllImport("advapi32.dll", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool AdjustTokenPrivileges(IntPtr TokenHandle,
   [MarshalAs(UnmanagedType.Bool)]bool DisableAllPrivileges,
   ref TOKEN_PRIVILEGES NewState,
   UInt32 BufferLengthInBytes,
   ref TOKEN_PRIVILEGES PreviousState,
   out UInt32 ReturnLengthInBytes);

C# Alternative Signature:

// Use this signature if you do not want the previous state
[DllImport("advapi32.dll", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool AdjustTokenPrivileges(IntPtr TokenHandle,
   [MarshalAs(UnmanagedType.Bool)]bool DisableAllPrivileges,
   ref TOKEN_PRIVILEGES NewState,
   UInt32 Zero,
   IntPtr Null1,
   IntPtr Null2);

VB Signature:

' Use this signature if you want the previous state information returned
<DllImport("advapi32.dll", SetLastError:=True)> _
Private Function AdjustTokenPrivileges( _
    ByVal TokenHandle As IntPtr, _
    ByVal DisableAllPrivileges As Boolean, _
    ByRef NewState As TOKEN_PRIVILEGES, _
    ByVal BufferLengthInBytes As Integer, _
    ByRef PreviousState As TOKEN_PRIVILEGES, _
    ByRef ReturnLengthInBytes As Integer _
  ) As Boolean
End Function

VB Alternative Signature:

' Use this signature if you do not want the previous state
<DllImport("advapi32.dll", SetLastError:=True)> _
Private Function AdjustTokenPrivileges( _
    ByVal TokenHandle As IntPtr, _
    ByVal DisableAllPrivileges As Boolean, _
    ByRef NewState As TOKEN_PRIVILEGES, _
    ByVal Zero As Integer, _
    ByVal Null1 As IntPtr, _
    ByVal Null2 As IntPtr _
  ) As Boolean
End Function

(alternate/older style)

Declare Function AdjustTokenPrivileges Lib "advapi32.dll" (
    ByVal TokenHandle As IntPtr, _
    ByVal DisableAllPrivileges As Boolean, _
    ByRef NewState As TOKEN_PRIVILEGES, _
    ByVal BufferLength As Integer, _
    ByRef PreviousState As TOKEN_PRIVILEGES, _
    ByRef ReturnLength As IntPtr _
) As Boolean

User-Defined Types:

TOKEN_PRIVILEGES

...and you may also need

LUID

LUID_AND_ATTRIBUTES

Notes:

None.

Tips & Tricks:

C#

    If SetLastError is set to true, get the error with this.
        int lastError = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
        Console.Error.WriteLine("NativeErr: " + lastError);
    Then use Error lookup tool for troubleshooting it can be downloaded from MS, ''Err.exe'' I think...

C# Sample Code:

  //This snippet is tested on WinXP and Vista, only needed in Vista when using SetTimeZoneInformation
  Public Class AdjPriv()
  {

    [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
    internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
    ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);

    [DllImport("kernel32.dll", ExactSpelling = true)]
    internal static extern IntPtr GetCurrentProcess();

    [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
    internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr
    phtok);

    [DllImport("advapi32.dll", SetLastError = true)]
    internal static extern bool LookupPrivilegeValue(string host, string name,
    ref long pluid);

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    internal struct TokPriv1Luid
    {
        public int Count;
        public long Luid;
        public int Attr;
    }

    internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
    internal const int TOKEN_QUERY = 0x00000008;
    internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
    internal const string SE_TIME_ZONE_NAMETEXT = "SeTimeZonePrivilege"; //http://msdn.microsoft.com/en-us/library/bb530716(VS.85).aspx

    private bool SetPriv()
    {
        try
        {
        bool retVal;
        TokPriv1Luid tp;
        IntPtr hproc = GetCurrentProcess();
        IntPtr htok = IntPtr.Zero;
        retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
        tp.Count = 1;
        tp.Luid = 0;
        tp.Attr = SE_PRIVILEGE_ENABLED;
        retVal = LookupPrivilegeValue(null, SE_TIME_ZONE_NAMETEXT, ref tp.Luid);
        retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
        return retVal;
        }
        catch (Exception ex)
        {
        throw;
        return false;
        }

    }
  }

C# Sample Code 2 (With full error handling):

   //Enable a privilege by implementing the following line in your code:
   Privileges.EnablePrivilege(SecurityEntity.SE_SHUTDOWN_NAME);

   //Needed code:
   public static class Privileges
   {
      public static void EnablePrivilege(SecurityEntity securityEntity)
      {
     if (!Enum.IsDefined(typeof(SecurityEntity), securityEntity))
        throw new InvalidEnumArgumentException("securityEntity", (int)securityEntity, typeof(SecurityEntity));

     var securityEntityValue = GetSecurityEntityValue(securityEntity);
     try
     {
        var locallyUniqueIdentifier = new NativeMethods.LUID();

        if (NativeMethods.LookupPrivilegeValue(null, securityEntityValue, ref locallyUniqueIdentifier))
        {
           var TOKEN_PRIVILEGES = new NativeMethods.TOKEN_PRIVILEGES();
           TOKEN_PRIVILEGES.PrivilegeCount = 1;
           TOKEN_PRIVILEGES.Attributes = NativeMethods.SE_PRIVILEGE_ENABLED;
           TOKEN_PRIVILEGES.Luid = locallyUniqueIdentifier;

           var tokenHandle = IntPtr.Zero;
           try
           {
          var currentProcess = NativeMethods.GetCurrentProcess();
          if (NativeMethods.OpenProcessToken(currentProcess, NativeMethods.TOKEN_ADJUST_PRIVILEGES | NativeMethods.TOKEN_QUERY, out tokenHandle))
          {
             if (NativeMethods.AdjustTokenPrivileges(tokenHandle, false,
                                 ref TOKEN_PRIVILEGES,
1024, IntPtr.Zero, IntPtr.Zero))              {
            var lastError = Marshal.GetLastWin32Error();
            if (lastError == NativeMethods.ERROR_NOT_ALL_ASSIGNED)
            {
               var win32Exception = new Win32Exception();
               throw new InvalidOperationException("AdjustTokenPrivileges failed.", win32Exception);
            }
             }
             else
             {
            var win32Exception = new Win32Exception();
            throw new InvalidOperationException("AdjustTokenPrivileges failed.", win32Exception);
             }
          }
          else
          {
             var win32Exception = new Win32Exception();

             var exceptionMessage = string.Format(CultureInfo.InvariantCulture,
                                 "OpenProcessToken failed. CurrentProcess: {0}",
                                 currentProcess.ToInt32());

             throw new InvalidOperationException(exceptionMessage, win32Exception);
          }
           }
           finally
           {
          if (tokenHandle != IntPtr.Zero)
             NativeMethods.CloseHandle(tokenHandle);
           }
        }
        else
        {
           var win32Exception = new Win32Exception();

           var exceptionMessage = string.Format(CultureInfo.InvariantCulture,
                               "LookupPrivilegeValue failed. SecurityEntityValue: {0}",
                               securityEntityValue);

           throw new InvalidOperationException(exceptionMessage, win32Exception);
        }
     }
     catch (Exception e)
     {
        var exceptionMessage = string.Format(CultureInfo.InvariantCulture,
                         "GrandPrivilege failed. SecurityEntity: {0}",
                         securityEntityValue);

        throw new InvalidOperationException(exceptionMessage, e);
     }
      }

      /// <summary>
      /// Gets the security entity value.
      /// </summary>
      /// <param name="securityEntity">The security entity.</param>
      private static string GetSecurityEntityValue(SecurityEntity securityEntity)
      {
     switch (securityEntity)
     {
        case SecurityEntity.SE_ASSIGNPRIMARYTOKEN_NAME:
           return "SeAssignPrimaryTokenPrivilege";
        case SecurityEntity.SE_AUDIT_NAME:
           return "SeAuditPrivilege";
        case SecurityEntity.SE_BACKUP_NAME:
           return "SeBackupPrivilege";
        case SecurityEntity.SE_CHANGE_NOTIFY_NAME:
           return "SeChangeNotifyPrivilege";
        case SecurityEntity.SE_CREATE_GLOBAL_NAME:
           return "SeCreateGlobalPrivilege";
        case SecurityEntity.SE_CREATE_PAGEFILE_NAME:
           return "SeCreatePagefilePrivilege";
        case SecurityEntity.SE_CREATE_PERMANENT_NAME:
           return "SeCreatePermanentPrivilege";
        case SecurityEntity.SE_CREATE_SYMBOLIC_LINK_NAME:
           return "SeCreateSymbolicLinkPrivilege";
        case SecurityEntity.SE_CREATE_TOKEN_NAME:
           return "SeCreateTokenPrivilege";
        case SecurityEntity.SE_DEBUG_NAME:
           return "SeDebugPrivilege";
        case SecurityEntity.SE_ENABLE_DELEGATION_NAME:
           return "SeEnableDelegationPrivilege";
        case SecurityEntity.SE_IMPERSONATE_NAME:
           return "SeImpersonatePrivilege";
        case SecurityEntity.SE_INC_BASE_PRIORITY_NAME:
           return "SeIncreaseBasePriorityPrivilege";
        case SecurityEntity.SE_INCREASE_QUOTA_NAME:
           return "SeIncreaseQuotaPrivilege";
        case SecurityEntity.SE_INC_WORKING_SET_NAME:
           return "SeIncreaseWorkingSetPrivilege";
        case SecurityEntity.SE_LOAD_DRIVER_NAME:
           return "SeLoadDriverPrivilege";
        case SecurityEntity.SE_LOCK_MEMORY_NAME:
           return "SeLockMemoryPrivilege";
        case SecurityEntity.SE_MACHINE_ACCOUNT_NAME:
           return "SeMachineAccountPrivilege";
        case SecurityEntity.SE_MANAGE_VOLUME_NAME:
           return "SeManageVolumePrivilege";
        case SecurityEntity.SE_PROF_SINGLE_PROCESS_NAME:
           return "SeProfileSingleProcessPrivilege";
        case SecurityEntity.SE_RELABEL_NAME:
           return "SeRelabelPrivilege";
        case SecurityEntity.SE_REMOTE_SHUTDOWN_NAME:
           return "SeRemoteShutdownPrivilege";
        case SecurityEntity.SE_RESTORE_NAME:
           return "SeRestorePrivilege";
        case SecurityEntity.SE_SECURITY_NAME:
           return "SeSecurityPrivilege";
        case SecurityEntity.SE_SHUTDOWN_NAME:
           return "SeShutdownPrivilege";
        case SecurityEntity.SE_SYNC_AGENT_NAME:
           return "SeSyncAgentPrivilege";
        case SecurityEntity.SE_SYSTEM_ENVIRONMENT_NAME:
           return "SeSystemEnvironmentPrivilege";
        case SecurityEntity.SE_SYSTEM_PROFILE_NAME:
           return "SeSystemProfilePrivilege";
        case SecurityEntity.SE_SYSTEMTIME_NAME:
           return "SeSystemtimePrivilege";
        case SecurityEntity.SE_TAKE_OWNERSHIP_NAME:
           return "SeTakeOwnershipPrivilege";
        case SecurityEntity.SE_TCB_NAME:
           return "SeTcbPrivilege";
        case SecurityEntity.SE_TIME_ZONE_NAME:
           return "SeTimeZonePrivilege";
        case SecurityEntity.SE_TRUSTED_CREDMAN_ACCESS_NAME:
           return "SeTrustedCredManAccessPrivilege";
        case SecurityEntity.SE_UNDOCK_NAME:
           return "SeUndockPrivilege";
        default:
           throw new ArgumentOutOfRangeException(typeof(SecurityEntity).Name);
     }
      }
   }

   public enum SecurityEntity
   {
      SE_CREATE_TOKEN_NAME,
      SE_ASSIGNPRIMARYTOKEN_NAME,
      SE_LOCK_MEMORY_NAME,
      SE_INCREASE_QUOTA_NAME,
      SE_UNSOLICITED_INPUT_NAME,
      SE_MACHINE_ACCOUNT_NAME,
      SE_TCB_NAME,
      SE_SECURITY_NAME,
      SE_TAKE_OWNERSHIP_NAME,
      SE_LOAD_DRIVER_NAME,
      SE_SYSTEM_PROFILE_NAME,
      SE_SYSTEMTIME_NAME,
      SE_PROF_SINGLE_PROCESS_NAME,
      SE_INC_BASE_PRIORITY_NAME,
      SE_CREATE_PAGEFILE_NAME,
      SE_CREATE_PERMANENT_NAME,
      SE_BACKUP_NAME,
      SE_RESTORE_NAME,
      SE_SHUTDOWN_NAME,
      SE_DEBUG_NAME,
      SE_AUDIT_NAME,
      SE_SYSTEM_ENVIRONMENT_NAME,
      SE_CHANGE_NOTIFY_NAME,
      SE_REMOTE_SHUTDOWN_NAME,
      SE_UNDOCK_NAME,
      SE_SYNC_AGENT_NAME,
      SE_ENABLE_DELEGATION_NAME,
      SE_MANAGE_VOLUME_NAME,
      SE_IMPERSONATE_NAME,
      SE_CREATE_GLOBAL_NAME,
      SE_CREATE_SYMBOLIC_LINK_NAME,
      SE_INC_WORKING_SET_NAME,
      SE_RELABEL_NAME,
      SE_TIME_ZONE_NAME,
      SE_TRUSTED_CREDMAN_ACCESS_NAME
   }

   internal static class NativeMethods
   {
      [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
      [return: MarshalAs(UnmanagedType.Bool)]
      internal static extern bool LookupPrivilegeValue(string lpsystemname, string lpname, [MarshalAs(UnmanagedType.Struct)] ref LUID lpLuid);

      [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
      [return: MarshalAs(UnmanagedType.Bool)]
      internal static extern bool AdjustTokenPrivileges(IntPtr tokenhandle,
                               [MarshalAs(UnmanagedType.Bool)] bool disableAllPrivileges,
                               [MarshalAs(UnmanagedType.Struct)]ref TOKEN_PRIVILEGES newstate,
                               uint bufferlength, IntPtr previousState, IntPtr returnlength);

      internal const int SE_PRIVILEGE_ENABLED = 0x00000002;

      internal const int ERROR_NOT_ALL_ASSIGNED = 1300;

      internal const UInt32 STANDARD_RIGHTS_REQUIRED = 0x000F0000;
      internal const UInt32 STANDARD_RIGHTS_READ = 0x00020000;
      internal const UInt32 TOKEN_ASSIGN_PRIMARY = 0x0001;
      internal const UInt32 TOKEN_DUPLICATE = 0x0002;
      internal const UInt32 TOKEN_IMPERSONATE = 0x0004;
      internal const UInt32 TOKEN_QUERY = 0x0008;
      internal const UInt32 TOKEN_QUERY_SOURCE = 0x0010;
      internal const UInt32 TOKEN_ADJUST_PRIVILEGES = 0x0020;
      internal const UInt32 TOKEN_ADJUST_GROUPS = 0x0040;
      internal const UInt32 TOKEN_ADJUST_DEFAULT = 0x0080;
      internal const UInt32 TOKEN_ADJUST_SESSIONID = 0x0100;
      internal const UInt32 TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY);
      internal const UInt32 TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED |
                          TOKEN_ASSIGN_PRIMARY |
                          TOKEN_DUPLICATE |
                          TOKEN_IMPERSONATE |
                          TOKEN_QUERY |
                          TOKEN_QUERY_SOURCE |
                          TOKEN_ADJUST_PRIVILEGES |
                          TOKEN_ADJUST_GROUPS |
                          TOKEN_ADJUST_DEFAULT |
                          TOKEN_ADJUST_SESSIONID);

      [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
      internal static extern IntPtr GetCurrentProcess();

      [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
      [return: MarshalAs(UnmanagedType.Bool)]
      internal static extern bool OpenProcessToken(IntPtr processHandle,
                          uint desiredAccesss,
                          out IntPtr tokenHandle);

      [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
      [return: MarshalAs(UnmanagedType.Bool)]
      internal static extern Boolean CloseHandle(IntPtr hObject);

      [StructLayout(LayoutKind.Sequential)]
      internal struct LUID
      {
     internal Int32 LowPart;
     internal UInt32 HighPart;
      }

      [StructLayout(LayoutKind.Sequential)]
      internal struct TOKEN_PRIVILEGES
      {
     internal Int32 PrivilegeCount;
     internal LUID Luid;
     internal Int32 Attributes;
      }
   }

VB.Net Sample Code:

    'This routine enables the Shutdown privilege for the current process,
    'which is necessary if you want to call ExitWindowsEx.

    Const ANYSIZE_ARRAY As Integer = 1
    Const TOKEN_QUERY As Integer = &H8
    Const TOKEN_ADJUST_PRIVILEGES As Integer = &H20
    Const SE_SHUTDOWN_NAME As String = "SeShutdownPrivilege"
    Const SE_PRIVILEGE_ENABLED As Integer = &H2

    <StructLayout(LayoutKind.Sequential)> _
    Private Structure LUID
        Public LowPart As UInt32
        Public HighPart As UInt32
    End Structure

    <StructLayout(LayoutKind.Sequential)> _
    Private Structure LUID_AND_ATTRIBUTES
        Public Luid As LUID
        Public Attributes As UInt32
    End Structure

    <StructLayout(LayoutKind.Sequential)> _
    Private Structure TOKEN_PRIVILEGES
        Public PrivilegeCount As UInt32
        <MarshalAs(UnmanagedType.ByValArray, SizeConst:=ANYSIZE_ARRAY)> _
        Public Privileges() As LUID_AND_ATTRIBUTES
    End Structure

    <DllImport("advapi32.dll", SetLastError:=True)> _
    Private Function LookupPrivilegeValue( _
     ByVal lpSystemName As String, _
     ByVal lpName As String, _
     ByRef lpLuid As LUID _
      ) As Boolean
    End Function

    <DllImport("advapi32.dll", SetLastError:=True)> _
    Private Function OpenProcessToken( _
     ByVal ProcessHandle As IntPtr, _
     ByVal DesiredAccess As Integer, _
     ByRef TokenHandle As IntPtr _
      ) As Boolean
    End Function

    <DllImport("kernel32.dll", SetLastError:=True)> _
    Private Function CloseHandle(ByVal hHandle As IntPtr) As Boolean
    End Function

    <DllImport("advapi32.dll", SetLastError:=True)> _
    Private Function AdjustTokenPrivileges( _
       ByVal TokenHandle As IntPtr, _
       ByVal DisableAllPrivileges As Boolean, _
       ByRef NewState As TOKEN_PRIVILEGES, _
       ByVal BufferLength As Integer, _
       ByRef PreviousState As TOKEN_PRIVILEGES, _
       ByRef ReturnLength As IntPtr _
     ) As Boolean
    End Function

    Public Sub AcquireShutdownPrivilege()

        Dim lastWin32Error As Integer = 0

        'Get the LUID that corresponds to the Shutdown privilege, if it exists.
        Dim luid_Shutdown As LUID
        If Not LookupPrivilegeValue(Nothing, SE_SHUTDOWN_NAME, luid_Shutdown) Then
            lastWin32Error = Marshal.GetLastWin32Error()
            Throw New System.ComponentModel.Win32Exception(lastWin32Error, _
             "LookupPrivilegeValue failed with error " & lastWin32Error.ToString & ".")
        End If

        'Get the current process's token.
        Dim hProc As IntPtr = Process.GetCurrentProcess().Handle
        Dim hToken As IntPtr
        If Not OpenProcessToken(hProc, TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, hToken) Then
            lastWin32Error = Marshal.GetLastWin32Error()
            Throw New System.ComponentModel.Win32Exception(lastWin32Error, _
             "OpenProcessToken failed with error " & lastWin32Error.ToString & ".")
        End If

        Try

            'Set up a LUID_AND_ATTRIBUTES structure containing the Shutdown privilege, marked as enabled.
            Dim luaAttr As New LUID_AND_ATTRIBUTES
            luaAttr.Luid = luid_Shutdown
            luaAttr.Attributes = SE_PRIVILEGE_ENABLED

            'Set up a TOKEN_PRIVILEGES structure containing only the shutdown privilege.
            Dim newState As New TOKEN_PRIVILEGES
            newState.PrivilegeCount = 1
            newState.Privileges = New LUID_AND_ATTRIBUTES() {luaAttr}

            'Set up a TOKEN_PRIVILEGES structure for the returned (modified) privileges.
            Dim prevState As TOKEN_PRIVILEGES = New TOKEN_PRIVILEGES
            ReDim prevState.Privileges(CInt(newState.PrivilegeCount))

            'Apply the TOKEN_PRIVILEGES structure to the current process's token.
            Dim returnLength As IntPtr
            If Not AdjustTokenPrivileges(hToken, False, newState, Marshal.SizeOf(prevState), prevState, returnLength) Then
                lastWin32Error = Marshal.GetLastWin32Error()
                Throw New System.ComponentModel.Win32Exception(lastWin32Error, _
                 "AdjustTokenPrivileges failed with error " & lastWin32Error.ToString & ".")
            End If

        Finally
            CloseHandle(hToken)
        End Try

    End Sub

Alternative Managed API:

Do you know one? Please contribute it!

Documentation