windows-7windows-vistauacelevation

How can I detect if my process is running UAC-elevated or not?


My Vista application needs to know whether the user has launched it "as administrator" (elevated) or as a standard user (non-elevated). How can I detect that at run time?


Solution

  • The following C++ function can do that:

    HRESULT GetElevationType( __out TOKEN_ELEVATION_TYPE * ptet );
    
    /*
    Parameters:
    
    ptet
        [out] Pointer to a variable that receives the elevation type of the current process.
    
        The possible values are:
    
        TokenElevationTypeDefault - This value indicates that either UAC is disabled, 
            or the process is started by a standard user (not a member of the Administrators group).
    
        The following two values can be returned only if both the UAC is enabled
        and the user is a member of the Administrator's group:
    
        TokenElevationTypeFull - the process is running elevated. 
    
        TokenElevationTypeLimited - the process is not running elevated.
    
    Return Values:
    
        If the function succeeds, the return value is S_OK. 
        If the function fails, the return value is E_FAIL. To get extended error information, call GetLastError().
    
    Implementation:
    */
    
    HRESULT GetElevationType( __out TOKEN_ELEVATION_TYPE * ptet )
    {
        if ( !IsVista() )
            return E_FAIL;
    
        HRESULT hResult = E_FAIL; // assume an error occurred
        HANDLE hToken   = NULL;
    
        if ( !::OpenProcessToken( 
                    ::GetCurrentProcess(), 
                    TOKEN_QUERY, 
                    &hToken ) )
        {
            return hResult;
        }
    
        DWORD dwReturnLength = 0;
    
        if ( ::GetTokenInformation(
                    hToken,
                    TokenElevationType,
                    ptet,
                    sizeof( *ptet ),
                    &dwReturnLength ) )
        {
                ASSERT( dwReturnLength == sizeof( *ptet ) );
                hResult = S_OK;
        }
    
        ::CloseHandle( hToken );
    
        return hResult;
    }