#include <stdio.h>
#include <windows.h>
#include <shlobj.h>                 
#pragma comment(lib, "shell32.lib") 

BOOL GetProcessElevation(TOKEN_ELEVATION_TYPE *pElevationType, BOOL &pIsAdmin)
{
    HANDLE hToken = NULL;
    BOOL bResult = FALSE;
    DWORD Size = 0;

    if ( !OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken) ) return FALSE;

    if ( GetTokenInformation(hToken, TokenElevationType, pElevationType, sizeof(TOKEN_ELEVATION_TYPE), &Size) )
    {
        char adminSID[SECURITY_MAX_SID_SIZE];
        Size = sizeof(adminSID);
       
        CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, &adminSID, &Size);

        if ( *pElevationType == TokenElevationTypeLimited )
        {
            HANDLE hUnfilteredToken = NULL;
            GetTokenInformation(hToken, TokenLinkedToken, (void *)&hUnfilteredToken, sizeof(HANDLE), &Size);
            if ( CheckTokenMembership(hUnfilteredToken, &adminSID, &pIsAdmin) ) bResult = TRUE;
           
            CloseHandle(hUnfilteredToken);
        }
        else
        {
            pIsAdmin = IsUserAnAdmin();
            bResult = TRUE;
        }
    }

    CloseHandle(hToken);
    return bResult;
}

int main(int argc, char **argv)
{
    TOKEN_ELEVATION_TYPE TockenType;
    BOOL isAdmin = FALSE;
    TCHAR UserID[0xFF] = {0};
    DWORD UserCount = _countof(UserID);
    GetUserName(UserID, &UserCount);

    if ( GetProcessElevation(&TockenType, isAdmin) )
    {
        if ( isAdmin )
            printf("%s 는 관리자입니다, ", UserID);
        else
            printf("%s 는 관리자가 아닙니다.", UserID);

        switch (TockenType)
        {
        case TokenElevationTypeDefault:
            printf("기본사용자");
            break;
        case TokenElevationTypeFull:
            printf("권한상승됨");
            break;
        case TokenElevationTypeLimited:
            printf("제한된 권한");
            break;
        }
    }

    return 0;
}