What programmers must know about Vista

Source: Internet
Author: User

Introduction

User Account Control or UAC for short. you 've seen the screenshots and maybe even tried it in action. the screen turns dark and you can only interact with a single dialog: it asks for your Administrative Consent to perform some sort of action. A few clicks later it happens again. what is going on in the background and why? What do you have to keep in mind when developing for Vista?

Microsoft is trying to address a pretty serious problem with UAC. most people (including reset ate users) are using Windows XP with an administrative account. this leads to clueless users opening suspect email attachments, which leads to malware being propagated very quickly with little resistance. the solution? Don't let users run software as administrators, doesn't when they really have.

UAC-the concept

There are two main types of user accounts in Vista: "Limited" and "Administrator ". there are two subtypes of administrators: "filtered" and "real ". finally, there are two subtypes of "real" Administrators: "Built-in" and "domain ". these three groups (Limited users,Filtered AdministratorsAndReal Administrators) Are all handled differently in Vista. (Note that I am oversimplifying this. "Demi-Administrators" like Backup Operators are handled in much the same way as filtered administrators .)

  • Real AdministratorsDon't have anything to worry about. if you buy a new PC with Vista pre-installed and enable the built-in Administrator Account (blocked by default) then log in with this user, you will not be pestered with UAC prompts. you're a full-blown admin all the time. the same goes for domain administrators. if the PC you're logging in to is a member of a domain and you're using a domain administrator account you're running asReal AdministratorAll the time. Note that both practices (using the built-in admin account or running as a domain administrator) are stronugly discouraged for everyday use.

  • TheLimited usersAre at the other end of the spectrum and their life is pretty simple too. in fact, it got significantly better with UAC. previusly when a program was started by a lowly limited user but needed administrative access, it gotACCESS_DENIEDError from windows and that was the end of it. Now the system is smart enough to tell you ahead of time, before the acess denied error occurs, that this software will require administrative privileges.Limited UserWill be able to enter the password for an administrative account, elevate the process in question to the Administrator's level, and continue working. note that this requires knowledge of an actual admin password-or a flesh and blood administrator at your beck and call.


    A limited user attempting to change the time: Credentials prompt
    (Click to enlarge)
  • Finally, the controversialFiltered Administrators. These are the guys causing all the problems, running as admin when they don't really have to-so they get special treatment. if you are an administrator on the local PC only (a member of the local Administrators Group) then your account will be subjected to the antics of UAC. you will from time to time get prompted for confirmation, just likeLimited usersDo-but at least you will not have to type a password. You can just choose the affirmative answer and let everything continue under your own user account.


    A filtered administrator attempting to change the time: consent prompt
    (Click to enlarge)

So the idea is to leave the big guys (Real Administrators) Alone, put up roadblocks so the meddlesomeFiltered AdministratorsDon't spread a virus every time they try to look at a picture of a naked woman, and almost as a side-effect, do something really useful for the little guys,Limited users.

How it works

So what's going on under the hood? Well, for real administrators, nothing special. they barely notice a thing. for limited users, it's really just a glorified version of the old RunAs command: The software hungry for elevated privileges will actually be run in the context of the administrator whose credentials were supplied. for filtered administrators, however, things are a quite different:

When a filtered Administrator logs in, Winlogon prepares the full token with all the nice group memberships and default privileges, just like it did in Windows XP. the next thing it does though is somewhat unpleasant: it creates a copy of the token, strips out a set of privileges and sets the Administrators group Sid to deny mode-specific tively rendering the user a non-administrator in the context of this token.

Winlogon then proceeds to launch the Windows shell with the filtered token therefore running it in the context of a non-administrator. every program launched from the shell subsequently will run in a non-Administrator context. the real administrator token is guarded strongly by UAC, and the only way to launch a process in the elevated context is to confirm an elevation dialog.

Well, that, and inheritance of course. since child processes always inherit the parent's access token (unless the parent explicitly overrides this by, say, calling createprocessasuser) the children of an elevated process will also be elevated. if you launch an elevated command prompt (right click the launch .exe icon and select "Run as administrator") You're free to start any other process from there, and those new processes will of course inherit the parent process 'Access token-which happens to come with full admin privileges.

Below is a screenshot between strating the difference between an elevated token and a filtered token. the specified .exe on the left was launched with "Run as administrator", the one on the right with a plain old double-click.


Elevated and filtered tokens
(Click to enlarge)

Elevation

How does Vista know when it needs to elevate a process? Well, it doesn' t justElevate a process. Not a running one, that is. it needs to know about elevation before a process is started. once a process has been assigned an access token and has been started, its fate has pretty much been sealed. it is either an elevated process or it is not.

You can elevate a process in two ways. One isMark itFor Elevation in its manifest. if you choose to do this, Vista will always follow the rules set forth in the manifest. below is a simple manifest-you're probably familiar with the part I 've de-emphasized. the part in bold is new for Vista though-and Microsoft requires this <trustinfo/> section to be present in every application aspiring to the designed for Windows Vista logo.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">        <dependency>                <dependentAssembly>                        <assemblyIdentity                                type="win32"                                name="Microsoft.Windows.Common-Controls"                                version="6.0.0.0"                                processorArchitecture="X86"                                publicKeyToken="6595b64144ccf1df"                                language="*"                        />                </dependentAssembly>        </dependency>        <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">                <security>                        <requestedPrivileges>                                <requestedExecutionLevel                                        level="asInvoker"                                        uiAccess="false"/>                        </requestedPrivileges>                </security>        </trustInfo></assembly>

Note: You must be careful when you add this section. A "malformed" <trustinfo/> section will cause XP or Windows 2003 to Bluescreen, as evidenced by this Microsoft KB document. the manifest in the above format is fine-it seems that the ms_asmv3: * prefixes shown in the KB article are the issue. just be careful when using the vs2005 manifest tool. as far as I know nobody produced an honest-to-God "this is exactly what's bluescreening XP" explanation yet.

The real deal isRequestedexecutionlevelTag. If the "level" attribute is setAsinvoker, No automatic elevation will take place and the process will run with the same parent process 'credentials. IfRequestedexecutionlevelIs setRequireadministrator, Elevation will be required andFiltered AdministratorsWill have to click through a consent dialog whileLimited usersWill receive an admin credentials prompt. Finally, ifRequestedexecutionleveIs setHighestavailable, Elevation will take place if it is possible to do so with the current user's credentials. if the user is an administrator (or has had his token "split", such as a backup operator wowould) the process will be elevated after a consent dialog is accepted by the user. no elevation dialog will appear if the user is a limited user and the process will run as ifAsinvokerHad been specified.

If you do not know at compile-time whether or not your application will need to be elevated, or if your application can work when not elevated but can provide extra functionality when elevated, there is a way to request elevation from Windows programmatically. not from the process that you want elevated of course-but a launcher can call shellexecuteex like this:

SHELLEXECUTEINFO sei = {0};sei.cbSize = sizeof(sei);sei.hwnd = g_hWnd;sei.lpVerb = L"runas";sei.lpFile = L"MyApp.exe";sei.lpParameters = szParams;sei.lpDirectory = g_szPath;sei.nShow = SW_SHOWNORMAL;ShellExecuteEx(&sei);

The entirely non-intuitive "RunAs" verb will cause UAC to elevate the application that's about to be launched. shellexecuteex will not return until the UAC dialog is dismissed. "RunAs" is the equivalent of level = "requireadministrator" in that it will cause elevation both for an administrator and a limited user. there is no verb equivalent for level = "highestavailable ". you can emulate the latter by examining your process 'token and acting accordingly. if there is no "Administrators" group Sid present then you're running as a limited user, so just omit the "RunAs" verb.

A word of warning: CreateProcess and its variants will always fail if a non-elevated application attempts to launch another application whose manifest requires elevation. getlasterror will return 740 (error_elevation_required) in this case. when this is a possibility and you don't need the fine control over process creation that CreateProcess provides, use ShellExecute instead.

You can also elevate out-of-process COM objects. there have been talks of a cocreateasadmin function but it never became a reality. you can, however, achieve elevation using a moniker. microsoft recommeds something like the following:

HRESULT CreateElevatedComObject(HWND hwnd,                                 REFCLSID rclsid,                                 REFIID riid,                                 __out void ** ppv){    BIND_OPTS3 bo;    WCHAR  wszCLSID[50];    WCHAR  wszMonikerName[300];    StringFromGUID2(rclsid, wszCLSID, cntof(wszCLSID));     HRESULT hr = StringCchPrintf(wszMonikerName,                                  cntof(wszMonikerName)),                                  L"Elevation:Administrator!new:%s",                                  wszCLSID);    if (FAILED(hr))        return hr;    memset(&bo, 0, sizeof(bo));    bo.cbStruct = sizeof(bo);    bo.hwnd = hwnd;    bo.dwClassContext  = CLSCTX_LOCAL_SERVER;    return CoGetObject(wszMonikerName, &bo, riid, ppv);}//// Where://#define cntof(a) (sizeof(a)/sizeof(a[0]))

Command-line applications shoshould generally be markedAsinvoker. It is possible to elevate a command-line program (and Vista will do it happily) but these will always run in their own new window which is a bit of a usability issue.

Gui considerations

You will see the shield icon sprinkled liberally throughout the Vista user interface. buttons have it, context menus have it, even application icons have it overlaid on themselves automatically by the shell if the manifest requires elevation. you will want to follow suit of course. if pressing a button, clicking a hyperlink or choosing a menu item will cause UAC to prompt the user for elevation, you shocould Add the shield icon to your UI.


Shields abound
(Click to enlarge)

Remember, Vista does not know when the result of a user action might require elevation, so it is your job to refactor your user interface and put code that requires elevation into either a different executable that you invoke with lexecuteex, or a COM object that you invoke by calling createelevatedcomobject.

The Vista engieers have made it fairly easy to add the shield icon to most UI elements:

  • Buttons

    This is very easy. A simple sendmessage call will do:

    SendMessage(GetDlgItem(hWnd, IDOK), BCM_SETSHIELD, 0, TRUE);

    Or you can use the new macro that essential does the same thing:

    Button_SetElevationRequiredState(hwndButton, fRequired);

    Unfortunately you cannot mark a button element in a dialog resource to include the shield icon. You'll have to write code in your wm_initdialog handler to take care of it.

  • Syslink/hyperlink

    Layout an idi_shield icon next to the UI element in the resource editor.

  • Shell context menus

    Defcm (icontextmenu) has had support for icons for quite some time now. Use that.

  • Popup menus

    I really wish for something as (almost) elegant as the buttons scenario, but nope. You'll have to load the shield icon yourself:

    // SHSTOCKICONINFO and SHGetStockIconInfo are new to // shell32.dll in Vista.SHSTOCKICONINFO sii = {0};sii.cbSize = sizeof(sii);SHGetStockIconInfo(SIID_SHIELD, SHGFI_ICON | SHGFI_SMALLICON, &sii);g_hShieldIcon = sii.hIcon;

    Then you'll have to assign it to a menu item:

    MENUITEMINFO mii = {0};mii.cbSize = sizeof(mii);mii.fMask = MIIM_BITMAP | MIIM_DATA;mii.hbmpItem = HBMMENU_CALLBACK;mii.dwItemData = (ULONG_PTR)g_hShieldIcon;SetMenuItemInfo(g_hMenu, ID_MY_COMMAND, FALSE, &mii);

    And finally, do the drawing too:

    case WM_MEASUREITEM:    {        LPMEASUREITEMSTRUCT pms = (LPMEASUREITEMSTRUCT)lParam;        if (pms->CtlType == ODT_MENU) {            pms->itemWidth  = 16;            pms->itemHeight = 16;            return TRUE;        }     }    break;case WM_DRAWITEM:     {       LPDRAWITEMSTRUCT pds = (LPDRAWITEMSTRUCT)lParam;       if (pds->CtlType == ODT_MENU) {           DrawIconEx(pds->hDC, pds->rcItem.left - 15,                pds->rcItem.top,                (HICON)pds->itemData,                16, 16, 0, NULL, DI_NORMAL);           return TRUE;       }    }    break; 

Other considerations

Following are a few semi-random collection of insights and tips.

  • INTERACTIVE SERVICESAre gone for good. services all run in Terminal Server session 0. the console is never attached to this session. therefore you can never, ever display a GUI from a service anymore. the whole thing was sort of broken in XP and 2003 already, what with remote desktop and Fast User Switching steering the console session away from session 0 pretty quickly, this just made it official. implement your GUI in a separate process and use com or some other sort of IPC to talk to your service. if you just need a simple user notification, use wtssendmessage.

  • Administrative SharesAre hosed.
    net use //vistabox/c$ /user:joe@vistabox

    This used to be a big timesaver and not much of a security risk-but if "Joe" isFiltered AdministratorThis will never work. Well, you can hack into the registry, like this:

    [HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/Policies/system]"LocalAccountTokenFilterPolicy"=dword:00000000   0 - build filtered token (Remote UAC enabled - default)   1 - build elevated token (Remote UAC disabled)

    This appears pretty uugly though. apparently the issue is that "Joe" wocould be a candidate for elevation, but there's no way to throw up an elevation prompt since this is a network logon, so the filtered token is used.

  • LogonuserCan also surprise you when it is called onFiltered AdministratorAccount. If you useLOGON32_LOGON_INTERACTIVELogon type the returned token will be filtered. UseLOGON32_LOGON_NETWORK_CLEARTEXTOr something similar in this case.
  • Remote RegistryIs inaccessible by default. the "Remote Registry" service is set to "Manual" Start instead of "automatic ". when you attempt to connect to the registry on a vista computer (no matter what User Account type you use) regconnectregistry will fail with error 53 (ERROR_BAD_NETPATH). You can always enable the Service remotely as long as RPC is enabled (and it is, by default) So this is just an annoyance.
  • DiscrepanciesBetween Microsoft's documentation and the real world (according to Vista build 5728 ). there are quire a few of these, but the main one seems to be that while the docs claim that domain administrators wocould be treatedReal AdministratorsOn a domain member computer, this is not the case. only the two built-in administrator accounts (the one in the local Sam and the one in the domain) are free from UAC prompts (or can access administrative shares ), A simple membership in the domain Administrators Group won't change this.

 

Article transferred from: http://writeblog.csdn.net/PostEdit.aspx

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.