Search
Module:
Directory

   Desktop Functions:

   Smart Device Functions:


Show Recent Changes
Subscribe (RSS)
Misc. Pages
Comments
FAQ
Helpful Tools
Playground
Suggested Reading
Website TODO List
Download Visual Studio Add-In

AdjustTokenPrivileges (advapi32)
 
.
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

Please edit this page!

Do you have...

  • helpful tips or sample code to share for using this API in managed code?
  • corrections to the existing content?
  • variations of the signature you want to share?
  • additional languages you want to include?

Select "Edit This Page" on the right hand toolbar and edit it! Or add new pages containing supporting types needed for this API (structures, delegates, and more).

 
Access PInvoke.net directly from VS:
Terms of Use
Find References
Show Printable Version
Revisions