views:

2076

answers:

2

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?

+7  A: 

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;
}
Andrei Belogortseff
For the IsVista function (and more details on GetElevationType), see Andrei's blog post: http://www.softblog.com/2008-02/vista-tools/
Bradley Grainger
+8  A: 

For those of us working in C#, in the Windows SDK there is a "UACDemo" application as a part of the "Cross Technology Samples". They find if the current user is an administrator using this method:

private bool IsAdministrator
{
    get
    {
        WindowsIdentity wi = WindowsIdentity.GetCurrent();
        WindowsPrincipal wp = new WindowsPrincipal(wi);

        return wp.IsInRole(WindowsBuiltInRole.Administrator);
    }
}

(Note: I refactored the original code to be a property, rather than an "if" statement)

Aydsman
Question, will this do domain security? (MYDOMAIN\Administrators) Or is this the local security only?
mattlant
WindowsBuiltInRole.Administrator is the local admin group
Ryan
If your domain account is a local administrator for that machine, or a domain administrator - it will be in that local group by default, afaik.
Oskar Duveborn
It's better to use just new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole
abatishchev