Rick Strahl's Weblog
Rick Strahl's FoxPro and Web Connection Weblog
White Papers | Products | Message Board | News |

Determining if a User is an Administrator


October 15, 2011 •

In Windows 7 (and Vista before it) it's become ever more important to run certain tasks under administrative privileges. With User Access Control in place there are a lot of things that applications can no longer do. While it's a good idea to follow Windows guidelines for file storage, registry access and general security requirements it's not uncommon for some applications to require you to go against those security settings.

User Access Control and 'Administrator' Accounts

Under Windows 7 and Vista new user accounts by default are created as Administrator accounts. However, if User Access Control (UAC) is enabled (which is it is by default), this Administrator account is more of a pseudo-Administrator account that doesn't have full rights at all. Instead if UAC is enabled and any task that requires administrative functionality is accessed the UAC prompt pops up to confirm the operation. Often you also see the UAC icon overlay over an icon that requires UAC overrides.

The above is annoying at times, but at least it lets you know when you need to raise your permissions to allow an administrative feature.

Unfortunately Windows isn't smart enough to detect all operations that require raised elevations. In our own applications in particular if you try to access say the installation folder that operation will either silently fail without UAC prompts, or - almost as bad - use some of Windows' redirection features to write data out in different locations.

The bottom line is if you're running with UAC on, you are not a real Administrator and a number of operations might fail.

One option to run as a true administrator is to turn UAC off completely. As soon as you do your account becomes a full Admin account with full rights to the machine.

How UAC affects you in Code

If you're building applications, it's actually vitally important that you either know about or take into considerations the account restrictions of UAC based access. You can't write data into installation directories, no HKLM registry write access, and a host of other things.

This can be especially problematic for older applications - it used to be quite common to host data files in the application's install folder for example. Even if you move that data out to a user specific folder like MyDocuments there may still be other tasks that don't fit that mold. For example, several of my apps have application updaters that check for new versions online and update the running application. That simply will not work under UAC.

Checking for Administrator

Ultimately in some situations it's very useful for your application to check whether it's running under a true Admin account. Luckily this is actually easily done. Here's some FoxPro code using a Windows API call:

************************************************************************
* wwUtils ::  IsAdmin
****************************************
***  Function: Determines whether user is an admin user by probing
***            access to HKLM registry key
***    Assume:
***      Pass:
***    Return:
************************************************************************
FUNCTION IsAdmin()
LOCAL loAPI, lcVal

DECLARE INTEGER IsUserAnAdmin IN Shell32
TRY
    lnResult = IsUserAnAdmin()
CATCH
    *** OLD OLD Version of Windows assume .T.
    lnResult = 1
ENDTRY
IF lnResult = 0
   RETURN .F.
ENDIF

RETURN .T.  
ENDFUNC
*  wwUtils ::  IsAdmin

With this function in place you can now check before tasks that require admin access and pop up a message if the user is not set up as an administrator.

For example, in Html Help Builder when I attempt to do a code update from the Web site I check and if the user is not an admin pop up a detailed dialog box:

*** Admin Prompt
   IF !IsAdmin()
TEXT TO RunAsAdminNote TEXTMERGE NOSHOW
<body style="font-family:verdana;font-size:10pt;top-margin:0" scroll="no">
<table><tr><td>
<img src="<< SYS(5)+CURDIR() >>bmp\images\alertIcon.gif" align="left" hspace="5">
<td><td align="center" valign="center"> 
<b style="font-size:12pt;color:maroon">Administrative Permissions Required</b>
</td><tr></table>
<hr style="color:darkblue;height:1pt;">
<p>
In order to download and install this Help Builder update you need to be
logged in as an Administrator.
<p>
You are currently <b>not logged</b> in as an Administrator.
<p>
To perform the Help Builder update, please exit the application
and restart it by using the Run As option and choosing a user
account that has Administrative priviliges from the
shortcut menu or from Windows Explorer (wwhelp.exe).
<p>
<b>What would you like to do?</b>
<ul><li> <b>Exit</b> Help Builder and show Help Builder install directory
<li> Just <b>Return</b> back to Help Builder
<li> Go ahead and <b>Try anyway</b> to update
<li> Get more information in the <b>Help</b> file
</ul>
</body>
ENDTEXT

    lcResult = MessageDisplay(RunAsAdminNote,"Help Builder Update",;
                                     "Exit,Return,Try anyway,Help",450,420,VARTYPE(goHelp) = "U")                        
    DO CASE 
      CASE lcResult = 2 OR lcResult < 1
        RETURN
      CASE lcResult = 1
        *** Update the version check date so it pops back up
        loConfig.dLastVersionCheck = DATE() - 60
        loConfig.Save()

        IF (VARTYPE(GoHelp) = "O")
            GoUrl(GetAppStartPath(),"RUNAS")
        ENDIF
        QUIT
      CASE lcResult = 4
        HELP ID 875
        RETURN
    ENDCASE
   ENDIF && IsAdmin


This lets the user know specifically what the problem is and optionally directs them to start Help Builder as an Administrator with the RunAs option off the start menu or from Explorer.

This is a nice and non-intrusive way to handle the limited rights issues. Users that are running with admin rights never see the dialog. Those that aren't see the dialog and are given detailed advice on how to work around the issue.

Now, the hard part is isolating the hopefully few parts of your application where this sort of thing is necessary. Alternately if your app always needs full admin rights you can pop this sort of thing up right on application startup and force users to run as administrators.

Posted in: FoxPro    Windows

Feedback for this Weblog Entry