Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++ C
Hey Friends
 
Is it possible somehow to determine whether any application is running as Administrator
 
on my Desktop using Win32 API or some other API ?
 
Something like
 
EnumProcess (enumFunc); and for each process check whether i do
 
enumFunc()
{
if(I am Running as Administrator)
{
TRACE("Found It\n");
}
 
}
Regards
Posted 12-Feb-13 3:50am
Comments
GeekBond at 12-Feb-13 9:59am
   
Do you want to check only for your application or for others running on the pc?
vikrant kpr at 12-Feb-13 10:00am
   
other applications
José Amílcar Ferreira Casimiro at 12-Feb-13 10:05am
   
Use OpenProcessToken to get the token (obviously), then GetTokenInformation with the TokenOwner flag to get the SID of the owner. Then you can use LookupAccountSid to get the username.
vikrant kpr at 12-Feb-13 10:21am
   
i guess this will fail if i am using this on a computer with only one user account (who is admin) and launches an application using right click and run as administrator
José Amílcar Ferreira Casimiro at 12-Feb-13 10:26am
   
Did you check the sample code for the LookupAccountSid? http://msdn.microsoft.com/en-us/library/aa379554(v=vs.85).aspx
vikrant kpr at 13-Feb-13 0:24am
   
checked the code and it seems like i am not asking the question properly.
I am Admin of my PC.
My EXE can be launched normally or by right clicking on the application and clicking on Run as Administrator
I need to distinguish between whether i am running an application normally or by clicking on Run as Administrator.
 
The Sample Code simply tells whether the user who has launched the application is admin or not
Sergey Alexandrovich Kryukov at 12-Feb-13 14:20pm
   
It was an interesting question, my 5.
—SA
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

What you want, looks something like this:
HRESULT CheckIfIsUserAdmin(BOOL *pIsAdmin)
{
    int b;
    HANDLE hProcess = NULL;
    HANDLE hProcessToken = NULL;
    HANDLE hLinkedToken = NULL;
    BOOL fIsAdmin = FALSE;
    DWORD dwLength = 0;
    OSVERSIONINFO osver = {sizeof(OSVERSIONINFO)};
    HRESULT hr = S_OK;
 
    *pIsAdmin = FALSE;
 
    hProcess = GetCurrentProcess();
    if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken))
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto Exit;
    }
 
    char AdminSID[SECURITY_MAX_SID_SIZE];
    dwLength = sizeof(AdminSID);
    if(!CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, &AdminSID, &dwLength)) 
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto Exit;
    } 
 
    if (!CheckTokenMembership( NULL, &AdminSID, &fIsAdmin)) 
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto Exit;
    }
 
    if (fIsAdmin) 
    {
        *pIsAdmin = TRUE;
        goto Exit;
    }
 
    if (!GetVersionEx(&osver))
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto Exit;
    }
 
    if (osver.dwMajorVersion < 6) 
    {
        goto Exit;        
    }
 
    // Code to handle admin SID filtering in Vista and above
    if (!GetTokenInformation(hProcessToken, TokenLinkedToken,
                                (VOID*) &hLinkedToken, sizeof(HANDLE), &dwLength) )
    {
        b = GetLastError();
        if( b == ERROR_NO_SUCH_LOGON_SESSION ||  b == ERROR_PRIVILEGE_NOT_HELD)
        {
            goto Exit;
        }
 
        hr = HRESULT_FROM_WIN32(b);
        goto Exit;
    } 
 
    if (!CheckTokenMembership(hLinkedToken, &AdminSID, &fIsAdmin))
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto Exit;
    }
 
    if (fIsAdmin)
    {
        *pIsAdmin = TRUE;
    }
 
Exit:
    if (hProcess) 
    {
        CloseHandle(hProcess);
    }
 
    if (hProcessToken)
    {
        CloseHandle(hProcessToken);
    }
 
    if (hLinkedToken)
    {
        CloseHandle(hLinkedToken);
    }
 
    return hr;
}
If the current token does not contain the administrator SID, that does not always mean that the current user is not an admininistrator since for Vista and above the default is to filter the admininistrator SID on the tokens for members of the administrator group.
 
So, we need to call GetTokenInformation to retrieve the linked token, and then call CheckTokenMembership once more on the liked token to check for the unfiltered admininistrator SID.
 
Best regards
Espen Harlinn
  Permalink  
Comments
Sergey Alexandrovich Kryukov at 12-Feb-13 14:19pm
   
Very nice, a 5.
(I was wondering: who has asked this pretty tricky question?)
—SA
Espen Harlinn at 12-Feb-13 14:37pm
   
Thank you, Sergey :-D
vikrant kpr at 13-Feb-13 0:10am
   
i could not have imagined this way in my wildest dreams and yes thanks a ton. it will take me some time to understand all this :-)
Thanks a ton.
vikrant kpr at 13-Feb-13 0:26am
   
Checked the code and it seems like i am not asking the question properly.
 
I am Admin of my PC.
 
My EXE can be launched normally or by right clicking on the application and clicking on Run as Administrator
 
I need to distinguish between whether i am running an application normally or by clicking on Run as Administrator.
 
The Sample Code simply tells whether the user who has launched the application is admin or not.
 
Sample Scenario:
 
Now when my application is launched normally even though i am admin, the application cannot create a directory in c:\windows on windows 7 or windows 8
 
However when my Application is launched by doing a right click and clicking on run as Administrator, it can create a directory in c:\windows
Espen Harlinn at 13-Feb-13 4:23am
   
You can then look at either or both the TokenElevationType or TokenElevation token property, like:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb530718(v=vs.85).aspx
 
DWORD infoLen;
TOKEN_ELEVATION_TYPE elevationType;
GetTokenInformation(hToken, TokenElevationType,
&elevationType, sizeof(elevationType), &infoLen)
 
http://msdn.microsoft.com/en-us/library/windows/desktop/bb530717(v=vs.85).aspx
TOKEN_ELEVATION elevation;
GetTokenInformation(hToken, TokenElevation,&elevation,
sizeof(elevation), &infoLen)
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

Here is my "me too" answer, based on KB #Q118626:
 
//-------------------------------------------------------------------------
// This function checks the token of the calling thread to see if the caller
// belongs to the Administrators group.
//
// Return Value:
//   TRUE if the caller is an administrator on the local machine.
//   Otherwise, FALSE.
// --------------------------------------------------------------------------
// Based on code from KB #Q118626, at http://support.microsoft.com/kb/118626
BOOL IsCurrentUserLocalAdministrator()
{
    BOOL   fReturn         = FALSE;
    DWORD  dwStatus        = 0;
    DWORD  dwAccessMask    = 0;
    DWORD  dwAccessDesired = 0;
    DWORD  dwACLSize       = 0;
    DWORD  dwStructureSize = sizeof(PRIVILEGE_SET);
    PACL   pACL            = NULL;
    PSID   psidAdmin       = NULL;
 
    HANDLE hToken              = NULL;
    HANDLE hImpersonationToken = NULL;
 
    PRIVILEGE_SET   ps = {0};
    GENERIC_MAPPING GenericMapping = {0};
 
    PSECURITY_DESCRIPTOR     psdAdmin           = NULL;
    SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;
 
    // Determine if the current thread is running as a user that is a member 
    // of the local admins group.  To do this, create a security descriptor 
    // that has a DACL which has an ACE that allows only local administrators 
    // access.  Then, call AccessCheck with the current thread's token and
    // the security descriptor.  It will say whether the user could access an
    // object if it had that security descriptor.  Note: you do not need to
    // actually create the object.  Just checking access against the
    // security descriptor alone will be sufficient.

    const DWORD ACCESS_READ  = 1;
    const DWORD ACCESS_WRITE = 2;
 
    __try
    {
        // AccessCheck() requires an impersonation token.  We first get a 
        // primary token and then create a duplicate impersonation token.
        // The impersonation token is not actually assigned to the thread, but
        // is used in the call to AccessCheck.  Thus, this function itself never
        // impersonates, but does use the identity of the thread.  If the thread
        // was impersonating already, this function uses that impersonation 
        // context.
        if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE|TOKEN_QUERY, TRUE, &hToken))
        {
            if (GetLastError() != ERROR_NO_TOKEN)
                __leave;
 
            if (!OpenProcessToken(GetCurrentProcess(), 
                TOKEN_DUPLICATE|TOKEN_QUERY, &hToken))
                __leave;
        }
 
        if (!DuplicateToken (hToken, SecurityImpersonation, &hImpersonationToken))
            __leave;
 
        // Create the binary representation of the well-known SID that
        // represents the local administrators group.  Then create the 
        // security descriptor and DACL with an ACE that allows only local
        // admins access.  After that, perform the access check.  This will
        // determine whether the current user is a local admin.
        if (!AllocateAndInitializeSid(&SystemSidAuthority, 2,
            SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
            0, 0, 0, 0, 0, 0, &psidAdmin))
            __leave;
 
        psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
        if (psdAdmin == NULL)
            __leave;
 
        if (!InitializeSecurityDescriptor(psdAdmin, SECURITY_DESCRIPTOR_REVISION))
            __leave;
 
        // Compute size needed for the ACL.
        dwACLSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) +
            GetLengthSid(psidAdmin) - sizeof(DWORD);
 
        pACL = (PACL)LocalAlloc(LPTR, dwACLSize);
        if (pACL == NULL)
            __leave;
 
        if (!InitializeAcl(pACL, dwACLSize, ACL_REVISION2))
            __leave;
 
        dwAccessMask= ACCESS_READ | ACCESS_WRITE;
 
        if (!AddAccessAllowedAce(pACL, ACL_REVISION2, dwAccessMask, psidAdmin))
            __leave;
 
        if (!SetSecurityDescriptorDacl(psdAdmin, TRUE, pACL, FALSE))
            __leave;
 
        // AccessCheck validates a security descriptor somewhat; set the group
        // and owner so that enough of the security descriptor is filled out to
        // make AccessCheck happy.

        SetSecurityDescriptorGroup(psdAdmin, psidAdmin, FALSE);
        SetSecurityDescriptorOwner(psdAdmin, psidAdmin, FALSE);
 
        if (!IsValidSecurityDescriptor(psdAdmin))
            __leave;
 
        dwAccessDesired = ACCESS_READ;
 
        // Initialize GenericMapping structure even though you
        // do not use generic rights.
        GenericMapping.GenericRead    = ACCESS_READ;
        GenericMapping.GenericWrite   = ACCESS_WRITE;
        GenericMapping.GenericExecute = 0;
        GenericMapping.GenericAll     = ACCESS_READ | ACCESS_WRITE;
 
        if (!AccessCheck(psdAdmin, hImpersonationToken, dwAccessDesired,
            &GenericMapping, &ps, &dwStructureSize, &dwStatus,
            &fReturn))
        {
            fReturn = FALSE;
            __leave;
        }
    }
    __finally
    {
        // Clean up.
        if (pACL)
            LocalFree(pACL);
        if (psdAdmin)
            LocalFree(psdAdmin);
        if (psidAdmin)
            FreeSid(psidAdmin);
        if (hImpersonationToken)
            CloseHandle (hImpersonationToken);
        if (hToken)
            CloseHandle (hToken);
    }
 
    return fReturn;
}
  Permalink  
Comments
vikrant kpr at 13-Feb-13 1:11am
   
H.Brydon
 
You hit the Bulls Eye :-)
 
Thanks a ton buddy.
 

Hello All
 
Thanks to all of you Guys
 
Without your Help Visual C++ Would be Dead
 
You all have made my Day and i thank you from my heart.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 Sarvesh Kumar Gupta 228
1 CHill60 200
2 DamithSL 153
3 OriginalGriff 138
4 Sergey Alexandrovich Kryukov 133


Advertise | Privacy | Mobile
Web02 | 2.8.140709.1 | Last Updated 13 Feb 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid