Check if the current user is an Administrator

From NSIS Wiki

Author: CancerFace (talk, contrib)


NSIS forum thread

Contents

[edit] Description

I wanted to have the option of checking if a user belongs to the adminisrator's group without using a special plugin. This can be achieved using API calls with the System plugin.

[edit] Macros

The first macro works only in Windows 2000, XP and 2003 while the second one also works in NT

[edit] Usage

Use the following code in your NSIS installer to find out if the user invoking it belongs to the administrator's group:

!insertmacro IsUserAdmin $0
; $0 = 1 if the user belongs to the administrator's group
; $0 = 0 if not
; $0 = -1 if there was an error (only for the 1st Macro)

[edit] Macro 1 (2k/XP/2k3)

!macro IsUserAdmin RESULT
 !define Index "Line${__LINE__}"
   StrCpy ${RESULT} 0
   System::Call '*(&i1 0,&i4 0,&i1 5)i.r0'
   System::Call 'advapi32::AllocateAndInitializeSid(i r0,i 2,i 32,i 544,i 0,i 0,i 0,i 0,i 0, \
   i 0,*i .R0)i.r5'
   System::Free $0
   System::Call 'advapi32::CheckTokenMembership(i n,i R0,*i .R1)i.r5'
   StrCmp $5 0 ${Index}_Error
   StrCpy ${RESULT} $R1
   Goto ${Index}_End
 ${Index}_Error:
   StrCpy ${RESULT} -1
 ${Index}_End:
   System::Call 'advapi32::FreeSid(i R0)i.r5'
 !undef Index
!macroend

[edit] Macro 2 (NT/2k/XP/2k3) - doesn't work!

!define TOKEN_READ   0x00020008
!define TokenGroups  2
 
!macro IsUserAdmin RESULT
 !define Index "Line${__LINE__}"
 StrCpy ${RESULT} 0
 
 # Construct the SID for the Admin group - (S-1-5-32-544 for administrators) put in $R4
  System::Call "*(&i1 0,&i4 0,&i1 5)i.r0"
  System::Call  "advapi32::AllocateAndInitializeSid(i r0,i 2,i 32,i 544,i 0,i 0,i 0,i 0,i 0,\
  i 0,*i .R4)i.r5"
  System::Free $0
 
 # Get a psuedo-handle of the current process and place it on R0
  System::Call 'kernel32::GetCurrentProcess()i.R0'
 
 # Open the Token from the psuedo process and place the handle on R1
  System::Call 'advapi32::OpenProcessToken(i R0,i ${TOKEN_READ},*i .R1)i.R9'
 
 # Get info from the token and place it in $R2 (the size goes to $R3)
  System::Call 'advapi32::GetTokenInformation(i R1,i ${TokenGroups},*i .R2,i 0,*i .R3)i.R9'
  System::Alloc $R3
   Pop $R2
  System::Call 'advapi32::GetTokenInformation(i R1,i ${TokenGroups},i R2,i $R3,*i .R3)i.R9'
 
 # Check how many TOKEN_GROUPS elements are in $R2 (place the number in $R5)
  System::Call '*$R2(i.R5,i.R6)'
 
 # Compare the SID structures
  StrCpy $1 0
 
 ${Index}_Start:
  StrCmp $1 $R5 ${Index}_Stop
  System::Call 'advapi32::EqualSid(i R4,i R6)i.R9'
  StrCmp $R9 "" ${Index}_Increment
  StrCmp $R9 0 +1 +3
  StrCpy ${RESULT} 0
   Goto ${Index}_Increment
  StrCpy ${RESULT} 1
  System::Call 'advapi32::FreeSid(i R6)i.R8'
   Goto ${Index}_Stop
 ${Index}_Increment:
  System::Call 'advapi32::GetLengthSid(i R6)i.R9'
  System::Call 'advapi32::FreeSid(i R6)i.R8'
  IntOp $R6 $R6 + $R9
  IntOp $1 $1 + 1
  Goto ${Index}_Start
 
 ${Index}_Stop:
 # Close the token handle
  System::Call 'kernel32::CloseHandle(i R1)i.R9'
 
 # cleanup
  System::Call 'advapi32::FreeSid(i R4)i.r5'
  System::Free $R2
  System::Free 0
 
 !undef Index
!macroend

[edit] Resources and Links

API Functions used:



Personal tools
donate