Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storage location of yellow-blue shield icon

Tags:

windows

icons

uac

Where, in Windows, is this Yellow-Blue Windows Security Icon icon stored? I need to use it in a TaskDialog emulation for XP and am having a hard time tracking it down.

It's not in shell32.dll, explorer.exe, ieframe.dll or wmploc.dll (as these contain a lot of icons commonly used in Windows).

Edit: For clarification, I am emulating a certain type of dialog in XP. The icon is (most likely) not present there. So I want to extract it from the library that holds it in Windows 7. I am extending an existing implementation of this emulation and want to provide a full feature set.

like image 585
Oliver Salzburg Avatar asked May 09 '10 19:05

Oliver Salzburg


People also ask

What is the blue and yellow shield on my computer?

The blue and yellow shield that shows on that icon is the UAC shield that is being placed on a desktop icon if the program requires permission from the user to run for the accounts protection. This is to prevent other users in accessing the program using their account.

How do I get rid of the blue and yellow shield on my icons?

1. Right click on the icon having the yellow and blue shield icon and then click on “Properties“. 2. Go to “Shortcut” tab and then click on “Change icon” to change the icon on your computer.

Why does my icon have a shield on it?

If you notice an application icon or system icon with a blue and yellow shield (Icon overlay) at the corner, it means that the applications need to run with administrator privileges. When you run such an application, you will get a UAC prompt.


2 Answers

The shield icon is located in the file C:\Windows\System32\imageres.dll (at least, in my copy of English 32-bit Windows 7). There are several versions of the shield icon there, including the blue and yellow version you have above (icon 78).

like image 103
Michael Petrotta Avatar answered Sep 21 '22 08:09

Michael Petrotta


I wanted to point it out explicitly.

You are supposed to put a shield on UI elements that will trigger an elevation: MSDN: Step 4: Redesign Your UI for UAC Compatibility.

Of course, you don't have to go spelunking around DLLs to extract images (although it certainly does make it easier at design time when you can design your design with a design time interface).

Microsoft provides a couple of supported (and therefore guaranteed) ways that you can get ahold of the shield icon at runtime:

  • Add a shield icon to the user interface?:

    • Extract a small icon

      SHSTOCKICONINFO sii;
      sii.cbSize = sizeof(sii);
      SHGetStockIconInfo(SIID_SHIELD, SHGSI_ICON | SHGSI_SMALLICON, &sii);
      hiconShield  = sii.hIcon;
      
    • Extract a large icon

      SHSTOCKICONINFO sii;
      sii.cbSize = sizeof(sii);
      SHGetStockIconInfo(SIID_SHIELD, SHGSI_ICON | SHGSI_LARGEICON, &sii);
      hiconShield  = sii.hIcon;
      
    • Extract an icon of custom size

      SHSTOCKICONINFO sii;
      sii.cbSize = sizeof(sii);
      SHGetStockIconInfo(SIID_SHIELD, SHGSI_ICONLOCATION, &sii);
      hiconShield  = ExtractIconEx(sii. ...);
      
  • Add a Shield Icon to a Button

    Button_SetElevationRequiredState(hwndButton, TRUE);
    

The article forgot to mention LoadIcon:

hIconShield = LoadIcon(0, IDI_SHIELD);

Although LoadIcon has been "superseded" by LoadImage:

hIconShield = LoadImage(0, IDI_SHIELD, IMAGE_ICON, desiredWith, desiredHeight, LR_SHARED); //passing LR_SHARED causes size to be ignored. And you must pass LR_SHARED

Loading the size you want - by avoiding shared images

In order to avoid loading a "shared" version of the icon, you have to load the icon directly out of the file.

We all know that the shield exists in user32.dll as resource id 106:

| Icon             | Standard Icon ID  | Real Resource ID |
|------------------|-------------------|------------------|
| IDI_APPLICATION  | 32512             | 100              |
| IDI_QUESTION     | 32514             | 102              |
| IDI_WINLOGO      | 32517             | 105              |
| IDI_WARNING      | 32515             | 101              |
| IDI_ERROR        | 32513             | 103              |
| IDI_INFORMATION  | 32516             | 104              |
| IDI_SHIELD       | 32518             | 106              |

That was undocumented spellunking.

SHGetStockIconInfo can give us the actual, current, guaranteed to change in the future, path and index:

TSHStockIconInfo sii;
ZeroMemory(@sii, SizeOf(sii));
sii.cbSize := SizeOf(sii);
SHGetStockIconInfo(SIID_SHIELD, SHGSI_ICONLOCATION, {var}sii);

resulting in:

  • sii.szPath: C:\WINDOWS\System32\imageres.dll
  • sii.iIcon: -78

You can load this image for the size you desire using LoadImage:

HMODULE hmod := LoadLibrary(sii.szPath);
Integer nIconIndex := Abs(sii.iIcon); //-78 --> 78
ico = LoadImage(hmod, MAKEINTRESOURCE(nIconIndex), IMAGE_ICON, 256, 256, 0);

Another slightly easier way is to use SHDefExtractIcon:

HICON GetStockIcon(DWORD StockIconID, Integer IconSize)
{
    HRESULT hr;

    TSHStockIconInfo sii;
    ZeroMemory(@sii, SizeOf(sii));
    sii.cbSize := SizeOf(sii);
    hr = SHGetStockIconInfo(SIID_SHIELD, SHGSI_ICONLOCATION, {var}sii);
    OleCheck(hr);

    HICON ico;
    hr = SHDefExtractIcon(sii.szPath, sii.iIcon, 0, ref ico, null, IconSize);
    OleCheck(hr);

    return ico;
}

It does the loading for you, and it handles the negative icon index (and the secret meaning that has):

HICON shieldIcon = GetStockIcon(SIID_SHIELD, 256);

Personally, i then use WIC to wrap that into a IWICBitmap:

IWICBitmap GetStockWicBitmap(DWORD StockIconID, Integer IconSize)
{
   HICON ico = GetStockIcon(StockIconID, IconSize);

   IWICBitmap bitmap;
   IWICImagingFactory factory = new WICImagingFactory();
   HRESULT hr = factory.CreateBitmapFromHICON(ico, out bitmap);
   OleCheck(hr);

   return bitmap;
}

and so:

IWICBitmap bmp = GetStockWicBitmap(SIID_SHIELD, 256);

Now that you have the bitmap, at runtime, do with it what you want.

Small and Large

The problem with ExtractIconEx is that you're again stuck with the two shell sizes:

  • "small" (i.e. GetSystemMetrics(SM_CXSMICON))
  • "large" (i.e. GetSystemMetrics(SM_CXICON))

Loading icons is something that is quite a dark art in Windows:

  • LoadIcon
  • LoadImage
  • LoadImage(..., LR_SHARED)
  • ExtractIcon
  • ExtractIconEx
  • IExtractImage
  • SHDefExtractIcon
  • SHGetFileInfo(..., SHGFI_ICON, ...);
  • SHGetFileInfo(..., SHGFI_SYSICONINDEX, ...);
  • SHGetFileInfo(..., SHGFI_ICONLOCATION, ...);
  • IThumbnailProvider

Icons available through SHGetStockIconInfo

Microsoft gives a handy page that gives an example, and description, of all the stock icons.

  • SHSTOCKICONID (archive)

And the 256px shield icon (as of Windows 10):

enter image description here

like image 38
Ian Boyd Avatar answered Sep 22 '22 08:09

Ian Boyd