# UAC plug-in

`

    Interactive User (MediumIL)        Admin user(HighIL)
    +++[Setup.exe]++++++++++++++       +++[Setup.exe]++++++++++++++
    +                          +       +                          +
    + ***[.OnInit]************ +       + ***[.OnInit]************ +
    + * UAC::RunElevated >---+-+------>+ *                      * +
    + * NSIS.Quit()          * +       + *                      * +
    + ************************ +       + ***********||*********** +
    +                          +       +            ||            +
    +                          +       +            \/            +
    + ***[Sections]*********** +       + ***[Sections]*********** +
    + *                      * +    /--+-+-< UAC::Exec          * +
    + ************************ +    |  + ************************ +
    +                          +    |  +                          +
    +  Win32.CreateProcess() <-+----/  +                          +
    +                          +       +                          +
    ++++++++++++++++++++++++++++       ++++++++++++++++++++++++++++

`

## Contents

- Plugin Functions
- Language support
- Known Issues
- Glossary

## Plugin Functions

Every function will try to emulate the basic NSIS instruction (of similar name) when UAC::RunElevated has not "succeeded" or running on a system that does not support elevation (Win9x/NT4)

UAC::RunElevated
Parameters: |
Returns: |
$0 | Win32 error code (0 on success, 1223 if user aborted elevation dialog, anything else should be treated as a fatal error)
$1 | If $0==0:
0 | UAC is not supported by the OS
1 | Started a elevated child process, the current process should act like a wrapper (Call Quit without any further processing)
2 | The process is already running @ HighIL (Member of admin group)
3 | You should call RunElevated again (This can happen if a user without admin priv. is used in the runas dialog)
$2 | If $0==0 && $1==1: ExitCode of the elevated fork process (The NSIS errlvl is also set)
$3 | If $0==0: 1 if the user is a member of the admin group or 0 otherwise
Description: | Allows non-admin/UAC.LUA users to re-spawn the installer as another user and UAC.Admin users to elevate.

UAC::Unload
Parameters: |
Returns: |
Description: | Cleanup, you must call this function in .OnInstFailed, .onUserAbort and .OnInstSuccess

UAC::Exec
Parameters: | <INT:ShowWindow> <STR:App> <STR:Parameters> <STR:WorkingDir>
Returns: |
$0 | Win32 error code, 0 on success (ErrorFlag is also set on error)

UAC::ExecWait
Parameters: | <INT:ShowWindow> <STR:App> <STR:Parameters> <STR:WorkingDir>
Returns: |
$0 | Win32 error code, 0 on success (ErrorFlag is also set on error)
$1 | Exitcode of new process

UAC::ShellExec
Parameters: | <STR:Verb> <INT:ShowWindow> <STR:App> <STR:Parameters> <STR:WorkingDir>
Returns: |
$0 | Win32 error code, 0 on success (ErrorFlag is also set on error)

UAC::ShellExecWait
Parameters: | <STR:Verb> <INT:ShowWindow> <STR:App> <STR:Parameters> <STR:WorkingDir>
Returns: |
$0 | Win32 error code, 0 on success (ErrorFlag is also set on error)
$1 | Exitcode of new process

UAC::IsAdmin
Parameters: |
Returns: | $0 (BOOL) result
Description: | Check current thread/process token for a non-deny admin group SID entry

UAC::ExecCodeSegment
Parameters: | <INT:NSISFunctionAddress>
Returns: | [None] (ErrorFlag is set on error)
Description: | Calls NSIS function in LUA/outer instance (If you use instructions that alter the UI or the stack/variables in the code segment (StrCpy,Push/Pop/Exch,DetailPrint etc.) they will affect the hidden wrapper installer and not "your" installer instance)

UAC::StackPush
Parameters: | <STR:String>
Returns: | [None] (ErrorFlag is set on error)
Description: | Push to outer instance stack (For use with UAC::ExecCodeSegment)

UAC::GetOuterHwnd
Parameters: |
Returns: | $0 HWNDPARENT of outer instance
Description: | For use with ${UAC.RunElevatedAndProcessMessages}

UAC::SupportsUAC
Parameters: |
Returns: | $0 !=0 if supported
Description: | Check if the OS supports UAC (And the user has UAC turned on) This function only tests if UAC is active, will return 0 on NT5 even though runas is implemented on those platforms, will also return 0 on NT6+ if UAC is off. You should only call this function during testing, NOT to determine if you can call UAC::RunElevated

UAC::GetElevationType
Parameters: |
Returns: |
$0 | TOKEN_ELEVATION_TYPE:
0 | Unsupported/Failed (ErrorFlag is also set)
1 | TokenElevationTypeDefault: User is not using a split token (UAC disabled)
2 | TokenElevationTypeFull: UAC enabled, the (current) process is elevated
3 | TokenElevationTypeLimited: UAC enabled, the process is not elevated

## Language support

If the plugin is built with FEAT_CUSTOMRUNASDLG_TRANSLATE (Enabled by default), you can extract a file named UAC.LNG to $pluginsdir. It is a ini file with the following sections:

    [MyRunAsCfg]
    ;Set to 1 to disable the radio button
    DisableCurrUserOpt=
    ;Set to 1 to hide the radio button
    HideCurrUserOpt=

    [MyRunAsStrings]
    DlgTitle=Hello There!
    HelpText=Just do your thing!
    ;Label for current user radio button, %s is replaced with result of GetUserNameEx(NameSamCompatible,...)
    OptCurrUser=Self service (%s)
    OptOtherUser=Run as someone:
    UserName=Who:
    Pwd=PIN:
    OK=Okey!
    Cancel=No Way

## Known Issues

- UACPI.KI#1: DetailPrint in outer process is ignored
- UACPI.KI#2: Elevation can fail if the installer is located on a remote share that requires authentication

## Glossary

- AAM: Admin Approval Mode
- IL: Integrity level (Part of the new MIC/WIC security levels added to NT6)
- LUA: Limited/Least-privilege User Account
- MIC: Mandatory Integrity Controls (Now known as WIC)
- UAC: User Account Control (Part of the UAP umbrella)
- UAP: User Account Protection
- WIC: Windows Integrity Controls
- Win32 error code: Standard windows error codes, ERROR_???