ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

iconcache.cpp
Go to the documentation of this file.
00001 /*
00002  *    shell icon cache (SIC)
00003  *
00004  * Copyright 1998, 1999 Juergen Schmied
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 
00021 #include <precomp.h>
00022 
00023 WINE_DEFAULT_DEBUG_CHANNEL(shell);
00024 
00025 /********************** THE ICON CACHE ********************************/
00026 
00027 #define INVALID_INDEX -1
00028 
00029 typedef struct
00030 {
00031     LPWSTR sSourceFile;    /* file (not path!) containing the icon */
00032     DWORD dwSourceIndex;    /* index within the file, if it is a resoure ID it will be negated */
00033     DWORD dwListIndex;    /* index within the iconlist */
00034     DWORD dwFlags;        /* GIL_* flags */
00035     DWORD dwAccessTime;
00036 } SIC_ENTRY, * LPSIC_ENTRY;
00037 
00038 static HDPA        sic_hdpa = 0;
00039 
00040 namespace
00041 {
00042 extern CRITICAL_SECTION SHELL32_SicCS;
00043 CRITICAL_SECTION_DEBUG critsect_debug =
00044 {
00045     0, 0, &SHELL32_SicCS,
00046     { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
00047       0, 0, { (DWORD_PTR)(__FILE__ ": SHELL32_SicCS") }
00048 };
00049 CRITICAL_SECTION SHELL32_SicCS = { &critsect_debug, -1, 0, 0, 0, 0 };
00050 }
00051 
00052 /*****************************************************************************
00053  * SIC_CompareEntries
00054  *
00055  * NOTES
00056  *  Callback for DPA_Search
00057  */
00058 static INT CALLBACK SIC_CompareEntries( LPVOID p1, LPVOID p2, LPARAM lparam)
00059 {    LPSIC_ENTRY e1 = (LPSIC_ENTRY)p1, e2 = (LPSIC_ENTRY)p2;
00060 
00061     TRACE("%p %p %8lx\n", p1, p2, lparam);
00062 
00063     /* Icons in the cache are keyed by the name of the file they are
00064      * loaded from, their resource index and the fact if they have a shortcut
00065      * icon overlay or not.
00066      */
00067     if (e1->dwSourceIndex != e2->dwSourceIndex || /* first the faster one */
00068         (e1->dwFlags & GIL_FORSHORTCUT) != (e2->dwFlags & GIL_FORSHORTCUT))
00069       return 1;
00070 
00071     if (wcsicmp(e1->sSourceFile,e2->sSourceFile))
00072       return 1;
00073 
00074     return 0;
00075 }
00076 
00077 /* declare SIC_LoadOverlayIcon() */
00078 static int SIC_LoadOverlayIcon(int icon_idx);
00079 
00080 /*****************************************************************************
00081  * SIC_OverlayShortcutImage            [internal]
00082  *
00083  * NOTES
00084  *  Creates a new icon as a copy of the passed-in icon, overlayed with a
00085  *  shortcut image.
00086  */
00087 static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large)
00088 {    ICONINFO SourceIconInfo, ShortcutIconInfo, TargetIconInfo;
00089     HICON ShortcutIcon, TargetIcon;
00090     BITMAP SourceBitmapInfo, ShortcutBitmapInfo;
00091     HDC SourceDC = NULL,
00092       ShortcutDC = NULL,
00093       TargetDC = NULL,
00094       ScreenDC = NULL;
00095     HBITMAP OldSourceBitmap = NULL,
00096       OldShortcutBitmap = NULL,
00097       OldTargetBitmap = NULL;
00098 
00099     static int s_imgListIdx = -1;
00100 
00101     /* Get information about the source icon and shortcut overlay */
00102     if (! GetIconInfo(SourceIcon, &SourceIconInfo)
00103         || 0 == GetObjectW(SourceIconInfo.hbmColor, sizeof(BITMAP), &SourceBitmapInfo))
00104     {
00105       return NULL;
00106     }
00107 
00108     /* search for the shortcut icon only once */
00109     if (s_imgListIdx == -1)
00110         s_imgListIdx = SIC_LoadOverlayIcon(- IDI_SHELL_SHORTCUT);
00111                            /* FIXME should use icon index 29 instead of the
00112                               resource id, but not all icons are present yet
00113                               so we can't use icon indices */
00114 
00115     if (s_imgListIdx != -1)
00116     {
00117         if (large)
00118             ShortcutIcon = ImageList_GetIcon(ShellBigIconList, s_imgListIdx, ILD_TRANSPARENT);
00119         else
00120             ShortcutIcon = ImageList_GetIcon(ShellSmallIconList, s_imgListIdx, ILD_TRANSPARENT);
00121     } else
00122         ShortcutIcon = NULL;
00123 
00124     if (NULL == ShortcutIcon
00125         || ! GetIconInfo(ShortcutIcon, &ShortcutIconInfo)
00126         || 0 == GetObjectW(ShortcutIconInfo.hbmColor, sizeof(BITMAP), &ShortcutBitmapInfo))
00127     {
00128       return NULL;
00129     }
00130 
00131     TargetIconInfo = SourceIconInfo;
00132     TargetIconInfo.hbmMask = NULL;
00133     TargetIconInfo.hbmColor = NULL;
00134 
00135     /* Setup the source, shortcut and target masks */
00136     SourceDC = CreateCompatibleDC(NULL);
00137     if (NULL == SourceDC) goto fail;
00138     OldSourceBitmap = (HBITMAP)SelectObject(SourceDC, SourceIconInfo.hbmMask);
00139     if (NULL == OldSourceBitmap) goto fail;
00140 
00141     ShortcutDC = CreateCompatibleDC(NULL);
00142     if (NULL == ShortcutDC) goto fail;
00143     OldShortcutBitmap = (HBITMAP)SelectObject(ShortcutDC, ShortcutIconInfo.hbmMask);
00144     if (NULL == OldShortcutBitmap) goto fail;
00145 
00146     TargetDC = CreateCompatibleDC(NULL);
00147     if (NULL == TargetDC) goto fail;
00148     TargetIconInfo.hbmMask = CreateCompatibleBitmap(TargetDC, SourceBitmapInfo.bmWidth,
00149                                                     SourceBitmapInfo.bmHeight);
00150     if (NULL == TargetIconInfo.hbmMask) goto fail;
00151     ScreenDC = GetDC(NULL);
00152     if (NULL == ScreenDC) goto fail;
00153     TargetIconInfo.hbmColor = CreateCompatibleBitmap(ScreenDC, SourceBitmapInfo.bmWidth,
00154                                                      SourceBitmapInfo.bmHeight);
00155     ReleaseDC(NULL, ScreenDC);
00156     if (NULL == TargetIconInfo.hbmColor) goto fail;
00157     OldTargetBitmap = (HBITMAP)SelectObject(TargetDC, TargetIconInfo.hbmMask);
00158     if (NULL == OldTargetBitmap) goto fail;
00159 
00160     /* Create the target mask by ANDing the source and shortcut masks */
00161     if (! BitBlt(TargetDC, 0, 0, SourceBitmapInfo.bmWidth, SourceBitmapInfo.bmHeight,
00162                  SourceDC, 0, 0, SRCCOPY) ||
00163         ! BitBlt(TargetDC, 0, SourceBitmapInfo.bmHeight - ShortcutBitmapInfo.bmHeight,
00164                  ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
00165                  ShortcutDC, 0, 0, SRCAND))
00166     {
00167       goto fail;
00168     }
00169 
00170     /* Setup the source and target xor bitmap */
00171     if (NULL == SelectObject(SourceDC, SourceIconInfo.hbmColor) ||
00172         NULL == SelectObject(TargetDC, TargetIconInfo.hbmColor))
00173     {
00174       goto fail;
00175     }
00176 
00177     /* Copy the source color bitmap to the target */
00178     if (! BitBlt(TargetDC, 0, 0, SourceBitmapInfo.bmWidth, SourceBitmapInfo.bmHeight,
00179                  SourceDC, 0, 0, SRCCOPY)) goto fail;
00180 
00181     /* Copy the source xor bitmap to the target and clear out part of it by using
00182        the shortcut mask */
00183     if (NULL == SelectObject(ShortcutDC, ShortcutIconInfo.hbmColor)) goto fail;
00184     if (!MaskBlt(TargetDC, 0, SourceBitmapInfo.bmHeight - ShortcutBitmapInfo.bmHeight,
00185                  ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
00186                  ShortcutDC, 0, 0, ShortcutIconInfo.hbmMask, 0, 0,
00187                  MAKEROP4(0xAA0000, SRCCOPY)))
00188     {
00189         goto fail;
00190     }
00191 
00192     /* Clean up, we're not goto'ing to 'fail' after this so we can be lazy and not set
00193        handles to NULL */
00194     SelectObject(TargetDC, OldTargetBitmap);
00195     DeleteObject(TargetDC);
00196     SelectObject(ShortcutDC, OldShortcutBitmap);
00197     DeleteObject(ShortcutDC);
00198     SelectObject(SourceDC, OldSourceBitmap);
00199     DeleteObject(SourceDC);
00200 
00201     /* Create the icon using the bitmaps prepared earlier */
00202     TargetIcon = CreateIconIndirect(&TargetIconInfo);
00203 
00204     /* CreateIconIndirect copies the bitmaps, so we can release our bitmaps now */
00205     DeleteObject(TargetIconInfo.hbmColor);
00206     DeleteObject(TargetIconInfo.hbmMask);
00207 
00208     return TargetIcon;
00209 
00210 fail:
00211     /* Clean up scratch resources we created */
00212     if (NULL != OldTargetBitmap) SelectObject(TargetDC, OldTargetBitmap);
00213     if (NULL != TargetIconInfo.hbmColor) DeleteObject(TargetIconInfo.hbmColor);
00214     if (NULL != TargetIconInfo.hbmMask) DeleteObject(TargetIconInfo.hbmMask);
00215     if (NULL != TargetDC) DeleteObject(TargetDC);
00216     if (NULL != OldShortcutBitmap) SelectObject(ShortcutDC, OldShortcutBitmap);
00217     if (NULL != ShortcutDC) DeleteObject(ShortcutDC);
00218     if (NULL != OldSourceBitmap) SelectObject(SourceDC, OldSourceBitmap);
00219     if (NULL != SourceDC) DeleteObject(SourceDC);
00220 
00221     return NULL;
00222 }
00223 
00224 /*****************************************************************************
00225  * SIC_IconAppend            [internal]
00226  *
00227  * NOTES
00228  *  appends an icon pair to the end of the cache
00229  */
00230 static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallIcon, HICON hBigIcon, DWORD dwFlags)
00231 {    LPSIC_ENTRY lpsice;
00232     INT ret, index, index1;
00233     WCHAR path[MAX_PATH];
00234     TRACE("%s %i %p %p\n", debugstr_w(sSourceFile), dwSourceIndex, hSmallIcon ,hBigIcon);
00235 
00236     lpsice = (LPSIC_ENTRY) SHAlloc (sizeof (SIC_ENTRY));
00237 
00238     GetFullPathNameW(sSourceFile, MAX_PATH, path, NULL);
00239     lpsice->sSourceFile = (LPWSTR)HeapAlloc( GetProcessHeap(), 0, (wcslen(path)+1)*sizeof(WCHAR) );
00240     wcscpy( lpsice->sSourceFile, path );
00241 
00242     lpsice->dwSourceIndex = dwSourceIndex;
00243     lpsice->dwFlags = dwFlags;
00244 
00245     EnterCriticalSection(&SHELL32_SicCS);
00246 
00247     index = DPA_InsertPtr(sic_hdpa, 0x7fff, lpsice);
00248     if ( INVALID_INDEX == index )
00249     {
00250       HeapFree(GetProcessHeap(), 0, lpsice->sSourceFile);
00251       SHFree(lpsice);
00252       ret = INVALID_INDEX;
00253     }
00254     else
00255     {
00256       index = ImageList_AddIcon (ShellSmallIconList, hSmallIcon);
00257       index1= ImageList_AddIcon (ShellBigIconList, hBigIcon);
00258 
00259       if (index!=index1)
00260       {
00261         FIXME("iconlists out of sync 0x%x 0x%x\n", index, index1);
00262       }
00263       lpsice->dwListIndex = index;
00264       ret = lpsice->dwListIndex;
00265     }
00266 
00267     LeaveCriticalSection(&SHELL32_SicCS);
00268     return ret;
00269 }
00270 /****************************************************************************
00271  * SIC_LoadIcon                [internal]
00272  *
00273  * NOTES
00274  *  gets small/big icon by number from a file
00275  */
00276 static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags)
00277 {    HICON    hiconLarge=0;
00278     HICON    hiconSmall=0;
00279     HICON     hiconLargeShortcut;
00280     HICON    hiconSmallShortcut;
00281 
00282 #if defined(__CYGWIN__) || defined (__MINGW32__) || defined(_MSC_VER)
00283     static UINT (WINAPI*PrivateExtractIconExW)(LPCWSTR,int,HICON*,HICON*,UINT) = NULL;
00284 
00285     if (!PrivateExtractIconExW) {
00286         HMODULE hUser32 = GetModuleHandleA("user32");
00287         PrivateExtractIconExW = (UINT(WINAPI*)(LPCWSTR,int,HICON*,HICON*,UINT)) GetProcAddress(hUser32, "PrivateExtractIconExW");
00288     }
00289 
00290         if (PrivateExtractIconExW)
00291         PrivateExtractIconExW(sSourceFile, dwSourceIndex, &hiconLarge, &hiconSmall, 1);
00292     else
00293 #endif
00294     {
00295         PrivateExtractIconsW(sSourceFile, dwSourceIndex, 32, 32, &hiconLarge, NULL, 1, 0);
00296         PrivateExtractIconsW(sSourceFile, dwSourceIndex, 16, 16, &hiconSmall, NULL, 1, 0);
00297     }
00298 
00299     if ( !hiconLarge ||  !hiconSmall)
00300     {
00301       WARN("failure loading icon %i from %s (%p %p)\n", dwSourceIndex, debugstr_w(sSourceFile), hiconLarge, hiconSmall);
00302       return -1;
00303     }
00304 
00305     if (0 != (dwFlags & GIL_FORSHORTCUT))
00306     {
00307       hiconLargeShortcut = SIC_OverlayShortcutImage(hiconLarge, TRUE);
00308       hiconSmallShortcut = SIC_OverlayShortcutImage(hiconSmall, FALSE);
00309       if (NULL != hiconLargeShortcut && NULL != hiconSmallShortcut)
00310       {
00311         hiconLarge = hiconLargeShortcut;
00312         hiconSmall = hiconSmallShortcut;
00313       }
00314       else
00315       {
00316         WARN("Failed to create shortcut overlayed icons\n");
00317         if (NULL != hiconLargeShortcut) DestroyIcon(hiconLargeShortcut);
00318         if (NULL != hiconSmallShortcut) DestroyIcon(hiconSmallShortcut);
00319         dwFlags &= ~ GIL_FORSHORTCUT;
00320       }
00321     }
00322 
00323     return SIC_IconAppend (sSourceFile, dwSourceIndex, hiconSmall, hiconLarge, dwFlags);
00324 }
00325 /*****************************************************************************
00326  * SIC_GetIconIndex            [internal]
00327  *
00328  * Parameters
00329  *    sSourceFile    [IN]    filename of file containing the icon
00330  *    index        [IN]    index/resID (negated) in this file
00331  *
00332  * NOTES
00333  *  look in the cache for a proper icon. if not available the icon is taken
00334  *  from the file and cached
00335  */
00336 INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags )
00337 {
00338     SIC_ENTRY sice;
00339     INT ret, index = INVALID_INDEX;
00340     WCHAR path[MAX_PATH];
00341 
00342     TRACE("%s %i\n", debugstr_w(sSourceFile), dwSourceIndex);
00343 
00344     GetFullPathNameW(sSourceFile, MAX_PATH, path, NULL);
00345     sice.sSourceFile = path;
00346     sice.dwSourceIndex = dwSourceIndex;
00347     sice.dwFlags = dwFlags;
00348 
00349     EnterCriticalSection(&SHELL32_SicCS);
00350 
00351     if (NULL != DPA_GetPtr (sic_hdpa, 0))
00352     {
00353       /* search linear from position 0*/
00354       index = DPA_Search (sic_hdpa, &sice, 0, SIC_CompareEntries, 0, 0);
00355     }
00356 
00357     if ( INVALID_INDEX == index )
00358     {
00359           ret = SIC_LoadIcon (sSourceFile, dwSourceIndex, dwFlags);
00360     }
00361     else
00362     {
00363       TRACE("-- found\n");
00364       ret = ((LPSIC_ENTRY)DPA_GetPtr(sic_hdpa, index))->dwListIndex;
00365     }
00366 
00367     LeaveCriticalSection(&SHELL32_SicCS);
00368     return ret;
00369 }
00370 /*****************************************************************************
00371  * SIC_Initialize            [internal]
00372  */
00373 BOOL SIC_Initialize(void)
00374 {
00375     HICON hSm = NULL, hLg = NULL;
00376     INT cx_small, cy_small;
00377     INT cx_large, cy_large;
00378     HDC hDC;
00379     INT bpp;
00380     DWORD ilMask;
00381 
00382     TRACE("Entered SIC_Initialize\n");
00383 
00384     if (sic_hdpa)
00385     {
00386         TRACE("Icon cache already initialized\n");
00387         return TRUE;
00388     }
00389 
00390     sic_hdpa = DPA_Create(16);
00391     if (!sic_hdpa)
00392     {
00393         return FALSE;
00394     }
00395 
00396     hDC = CreateICW(L"DISPLAY", NULL, NULL, NULL);
00397     if (!hDC)
00398     {
00399         ERR("Failed to create information context (error %d)\n", GetLastError());
00400         return FALSE;
00401     }
00402 
00403     bpp = GetDeviceCaps(hDC, BITSPIXEL);
00404     ReleaseDC(NULL, hDC);
00405 
00406     if (bpp <= 4)
00407         ilMask = ILC_COLOR4;
00408     else if (bpp <= 8)
00409         ilMask = ILC_COLOR8;
00410     else if (bpp <= 16)
00411         ilMask = ILC_COLOR16;
00412     else if (bpp <= 24)
00413         ilMask = ILC_COLOR24;
00414     else if (bpp <= 32)
00415         ilMask = ILC_COLOR32;
00416     else
00417         ilMask = ILC_COLOR;
00418 
00419     ilMask |= ILC_MASK;
00420 
00421     cx_small = GetSystemMetrics(SM_CXSMICON);
00422     cy_small = GetSystemMetrics(SM_CYSMICON);
00423     cx_large = GetSystemMetrics(SM_CXICON);
00424     cy_large = GetSystemMetrics(SM_CYICON);
00425 
00426     ShellSmallIconList = ImageList_Create(cx_small,
00427                                           cy_small,
00428                                           ilMask,
00429                                           100,
00430                                           100);
00431 
00432     ShellBigIconList = ImageList_Create(cx_large,
00433                                         cy_large,
00434                                         ilMask,
00435                                         100,
00436                                         100);
00437     if (ShellSmallIconList)
00438     {
00439         /* Load the document icon, which is used as the default if an icon isn't found. */
00440         hSm = (HICON)LoadImageW(shell32_hInstance,
00441                                 MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT),
00442                                 IMAGE_ICON,
00443                                 cx_small,
00444                                 cy_small,
00445                                 LR_SHARED | LR_DEFAULTCOLOR);
00446         if (!hSm)
00447         {
00448             ERR("Failed to load IDI_SHELL_DOCUMENT icon1!\n");
00449             return FALSE;
00450         }
00451     }
00452     else
00453     {
00454         ERR("Failed to load ShellSmallIconList\n");
00455         return FALSE;
00456     }
00457 
00458     if (ShellBigIconList)
00459     {
00460         hLg = (HICON)LoadImageW(shell32_hInstance,
00461                                 MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT),
00462                                 IMAGE_ICON,
00463                                 cx_large,
00464                                 cy_large,
00465                                 LR_SHARED | LR_DEFAULTCOLOR);
00466         if (!hLg)
00467         {
00468             ERR("Failed to load IDI_SHELL_DOCUMENT icon2!\n");
00469             DestroyIcon(hSm);
00470             return FALSE;
00471         }
00472     }
00473     else
00474     {
00475         ERR("Failed to load ShellBigIconList\n");
00476         return FALSE;
00477     }
00478 
00479     SIC_IconAppend(swShell32Name, IDI_SHELL_DOCUMENT-1, hSm, hLg, 0);
00480     SIC_IconAppend(swShell32Name, -IDI_SHELL_DOCUMENT, hSm, hLg, 0);
00481 
00482     TRACE("hIconSmall=%p hIconBig=%p\n",ShellSmallIconList, ShellBigIconList);
00483 
00484     return TRUE;
00485 }
00486 /*************************************************************************
00487  * SIC_Destroy
00488  *
00489  * frees the cache
00490  */
00491 static INT CALLBACK sic_free( LPVOID ptr, LPVOID lparam )
00492 {
00493     HeapFree(GetProcessHeap(), 0, ((LPSIC_ENTRY)ptr)->sSourceFile);
00494     SHFree(ptr);
00495     return TRUE;
00496 }
00497 
00498 void SIC_Destroy(void)
00499 {
00500     TRACE("\n");
00501 
00502     EnterCriticalSection(&SHELL32_SicCS);
00503 
00504     if (sic_hdpa) DPA_DestroyCallback(sic_hdpa, sic_free, NULL );
00505 
00506     sic_hdpa = NULL;
00507     ImageList_Destroy(ShellSmallIconList);
00508     ShellSmallIconList = 0;
00509     ImageList_Destroy(ShellBigIconList);
00510     ShellBigIconList = 0;
00511 
00512     LeaveCriticalSection(&SHELL32_SicCS);
00513     //DeleteCriticalSection(&SHELL32_SicCS); //static
00514 }
00515 
00516 /*****************************************************************************
00517  * SIC_LoadOverlayIcon            [internal]
00518  *
00519  * Load a shell overlay icon and return its icon cache index.
00520  */
00521 static int SIC_LoadOverlayIcon(int icon_idx)
00522 {
00523     WCHAR buffer[1024], wszIdx[8];
00524     HKEY hKeyShellIcons;
00525     LPCWSTR iconPath;
00526     int iconIdx;
00527 
00528     static const WCHAR wszShellIcons[] = {
00529         'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
00530         'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
00531         'E','x','p','l','o','r','e','r','\\','S','h','e','l','l',' ','I','c','o','n','s',0
00532     };
00533     static const WCHAR wszNumFmt[] = {'%','d',0};
00534 
00535     iconPath = swShell32Name;    /* default: load icon from shell32.dll */
00536     iconIdx = icon_idx;
00537 
00538     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszShellIcons, 0, KEY_READ, &hKeyShellIcons) == ERROR_SUCCESS)
00539     {
00540         DWORD count = sizeof(buffer);
00541 
00542         swprintf(wszIdx, wszNumFmt, icon_idx);
00543 
00544         /* read icon path and index */
00545         if (RegQueryValueExW(hKeyShellIcons, wszIdx, NULL, NULL, (LPBYTE)buffer, &count) == ERROR_SUCCESS)
00546         {
00547         LPWSTR p = wcschr(buffer, ',');
00548 
00549         if (p)
00550             *p++ = 0;
00551 
00552         iconPath = buffer;
00553         iconIdx = _wtoi(p);
00554         }
00555 
00556         RegCloseKey(hKeyShellIcons);
00557     }
00558 
00559     return SIC_LoadIcon(iconPath, iconIdx, 0);
00560 }
00561 
00562 /*************************************************************************
00563  * Shell_GetImageLists            [SHELL32.71]
00564  *
00565  * PARAMETERS
00566  *  imglist[1|2] [OUT] pointer which receives imagelist handles
00567  *
00568  */
00569 BOOL WINAPI Shell_GetImageLists(HIMAGELIST * lpBigList, HIMAGELIST * lpSmallList)
00570 {    TRACE("(%p,%p)\n",lpBigList,lpSmallList);
00571     if (lpBigList)
00572     { *lpBigList = ShellBigIconList;
00573     }
00574     if (lpSmallList)
00575     { *lpSmallList = ShellSmallIconList;
00576     }
00577 
00578     return TRUE;
00579 }
00580 /*************************************************************************
00581  * PidlToSicIndex            [INTERNAL]
00582  *
00583  * PARAMETERS
00584  *    sh    [IN]    IShellFolder
00585  *    pidl    [IN]
00586  *    bBigIcon [IN]
00587  *    uFlags    [IN]    GIL_*
00588  *    pIndex    [OUT]    index within the SIC
00589  *
00590  */
00591 BOOL PidlToSicIndex (
00592     IShellFolder * sh,
00593     LPCITEMIDLIST pidl,
00594     BOOL bBigIcon,
00595     UINT uFlags,
00596     int * pIndex)
00597 {
00598     CComPtr<IExtractIconW>        ei;
00599     WCHAR        szIconFile[MAX_PATH];    /* file containing the icon */
00600     INT        iSourceIndex;        /* index or resID(negated) in this file */
00601     BOOL        ret = FALSE;
00602     UINT        dwFlags = 0;
00603     int        iShortcutDefaultIndex = INVALID_INDEX;
00604 
00605     TRACE("sf=%p pidl=%p %s\n", sh, pidl, bBigIcon?"Big":"Small");
00606 
00607     if (SUCCEEDED (sh->GetUIObjectOf(0, 1, &pidl, IID_IExtractIconW, 0, (void **)&ei)))
00608     {
00609       if (SUCCEEDED(ei->GetIconLocation(uFlags, szIconFile, MAX_PATH, &iSourceIndex, &dwFlags)))
00610       {
00611         *pIndex = SIC_GetIconIndex(szIconFile, iSourceIndex, uFlags);
00612         ret = TRUE;
00613       }
00614     }
00615 
00616     if (INVALID_INDEX == *pIndex)    /* default icon when failed */
00617     {
00618       if (0 == (uFlags & GIL_FORSHORTCUT))
00619       {
00620         *pIndex = 0;
00621       }
00622       else
00623       {
00624         if (INVALID_INDEX == iShortcutDefaultIndex)
00625         {
00626           iShortcutDefaultIndex = SIC_LoadIcon(swShell32Name, 0, GIL_FORSHORTCUT);
00627         }
00628         *pIndex = (INVALID_INDEX != iShortcutDefaultIndex ? iShortcutDefaultIndex : 0);
00629       }
00630     }
00631 
00632     return ret;
00633 
00634 }
00635 
00636 /*************************************************************************
00637  * SHMapPIDLToSystemImageListIndex    [SHELL32.77]
00638  *
00639  * PARAMETERS
00640  *    sh    [IN]        pointer to an instance of IShellFolder
00641  *    pidl    [IN]
00642  *    pIndex    [OUT][OPTIONAL]    SIC index for big icon
00643  *
00644  */
00645 int WINAPI SHMapPIDLToSystemImageListIndex(
00646     IShellFolder *sh,
00647     LPCITEMIDLIST pidl,
00648     int *pIndex)
00649 {
00650     int Index;
00651     UINT uGilFlags = 0;
00652 
00653     TRACE("(SF=%p,pidl=%p,%p)\n",sh,pidl,pIndex);
00654     pdump(pidl);
00655 
00656     if (SHELL_IsShortcut(pidl))
00657         uGilFlags |= GIL_FORSHORTCUT;
00658 
00659     if (pIndex)
00660         if (!PidlToSicIndex ( sh, pidl, 1, uGilFlags, pIndex))
00661             *pIndex = -1;
00662 
00663     if (!PidlToSicIndex ( sh, pidl, 0, uGilFlags, &Index))
00664         return -1;
00665 
00666     return Index;
00667 }
00668 
00669 /*************************************************************************
00670  * SHMapIDListToImageListIndexAsync  [SHELL32.148]
00671  */
00672 EXTERN_C HRESULT WINAPI SHMapIDListToImageListIndexAsync(IShellTaskScheduler *pts, IShellFolder *psf,
00673                                                 LPCITEMIDLIST pidl, UINT flags,
00674                                                 PFNASYNCICONTASKBALLBACK pfn, void *pvData, void *pvHint,
00675                                                 int *piIndex, int *piIndexSel)
00676 {
00677     FIXME("(%p, %p, %p, 0x%08x, %p, %p, %p, %p, %p)\n",
00678             pts, psf, pidl, flags, pfn, pvData, pvHint, piIndex, piIndexSel);
00679     return E_FAIL;
00680 }
00681 
00682 /*************************************************************************
00683  * Shell_GetCachedImageIndex        [SHELL32.72]
00684  *
00685  */
00686 INT WINAPI Shell_GetCachedImageIndexA(LPCSTR szPath, INT nIndex, UINT bSimulateDoc)
00687 {
00688     INT ret, len;
00689     LPWSTR szTemp;
00690 
00691     WARN("(%s,%08x,%08x) semi-stub.\n",debugstr_a(szPath), nIndex, bSimulateDoc);
00692 
00693     len = MultiByteToWideChar( CP_ACP, 0, szPath, -1, NULL, 0 );
00694     szTemp = (LPWSTR)HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
00695     MultiByteToWideChar( CP_ACP, 0, szPath, -1, szTemp, len );
00696 
00697     ret = SIC_GetIconIndex( szTemp, nIndex, 0 );
00698 
00699     HeapFree( GetProcessHeap(), 0, szTemp );
00700 
00701     return ret;
00702 }
00703 
00704 INT WINAPI Shell_GetCachedImageIndexW(LPCWSTR szPath, INT nIndex, UINT bSimulateDoc)
00705 {
00706     WARN("(%s,%08x,%08x) semi-stub.\n",debugstr_w(szPath), nIndex, bSimulateDoc);
00707 
00708     return SIC_GetIconIndex(szPath, nIndex, 0);
00709 }
00710 
00711 EXTERN_C INT WINAPI Shell_GetCachedImageIndexAW(LPCVOID szPath, INT nIndex, BOOL bSimulateDoc)
00712 {    if( SHELL_OsIsUnicode())
00713       return Shell_GetCachedImageIndexW((LPCWSTR)szPath, nIndex, bSimulateDoc);
00714     return Shell_GetCachedImageIndexA((LPCSTR)szPath, nIndex, bSimulateDoc);
00715 }
00716 
00717 /*************************************************************************
00718  * ExtractIconExW            [SHELL32.@]
00719  * RETURNS
00720  *  0 no icon found
00721  *  -1 file is not valid
00722  *  or number of icons extracted
00723  */
00724 UINT WINAPI ExtractIconExW(LPCWSTR lpszFile, INT nIconIndex, HICON * phiconLarge, HICON * phiconSmall, UINT nIcons)
00725 {
00726     /* get entry point of undocumented function PrivateExtractIconExW() in user32 */
00727 #if defined(__CYGWIN__) || defined (__MINGW32__) || defined(_MSC_VER)
00728     static UINT (WINAPI*PrivateExtractIconExW)(LPCWSTR,int,HICON*,HICON*,UINT) = NULL;
00729 
00730     if (!PrivateExtractIconExW) {
00731         HMODULE hUser32 = GetModuleHandleA("user32");
00732         PrivateExtractIconExW = (UINT(WINAPI*)(LPCWSTR,int,HICON*,HICON*,UINT)) GetProcAddress(hUser32, "PrivateExtractIconExW");
00733 
00734         if (!PrivateExtractIconExW)
00735         return 0;
00736     }
00737 #endif
00738 
00739     TRACE("%s %i %p %p %i\n", debugstr_w(lpszFile), nIconIndex, phiconLarge, phiconSmall, nIcons);
00740 
00741     return PrivateExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
00742 }
00743 
00744 /*************************************************************************
00745  * ExtractIconExA            [SHELL32.@]
00746  */
00747 UINT WINAPI ExtractIconExA(LPCSTR lpszFile, INT nIconIndex, HICON * phiconLarge, HICON * phiconSmall, UINT nIcons)
00748 {
00749     UINT ret = 0;
00750     INT len = MultiByteToWideChar(CP_ACP, 0, lpszFile, -1, NULL, 0);
00751     LPWSTR lpwstrFile = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
00752 
00753     TRACE("%s %i %p %p %i\n", lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
00754 
00755     if (lpwstrFile)
00756     {
00757         MultiByteToWideChar(CP_ACP, 0, lpszFile, -1, lpwstrFile, len);
00758         ret = ExtractIconExW(lpwstrFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
00759         HeapFree(GetProcessHeap(), 0, lpwstrFile);
00760     }
00761     return ret;
00762 }
00763 
00764 /*************************************************************************
00765  *                ExtractAssociatedIconA (SHELL32.@)
00766  *
00767  * Return icon for given file (either from file itself or from associated
00768  * executable) and patch parameters if needed.
00769  */
00770 HICON WINAPI ExtractAssociatedIconA(HINSTANCE hInst, LPSTR lpIconPath, LPWORD lpiIcon)
00771 {
00772     HICON hIcon = NULL;
00773     INT len = MultiByteToWideChar(CP_ACP, 0, lpIconPath, -1, NULL, 0);
00774     /* Note that we need to allocate MAX_PATH, since we are supposed to fill
00775      * the correct executable if there is no icon in lpIconPath directly.
00776      * lpIconPath itself is supposed to be large enough, so make sure lpIconPathW
00777      * is large enough too. Yes, I am puking too.
00778      */
00779     LPWSTR lpIconPathW = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
00780 
00781     TRACE("%p %s %p\n", hInst, debugstr_a(lpIconPath), lpiIcon);
00782 
00783     if (lpIconPathW)
00784     {
00785         MultiByteToWideChar(CP_ACP, 0, lpIconPath, -1, lpIconPathW, len);
00786         hIcon = ExtractAssociatedIconW(hInst, lpIconPathW, lpiIcon);
00787         WideCharToMultiByte(CP_ACP, 0, lpIconPathW, -1, lpIconPath, MAX_PATH , NULL, NULL);
00788         HeapFree(GetProcessHeap(), 0, lpIconPathW);
00789     }
00790     return hIcon;
00791 }
00792 
00793 /*************************************************************************
00794  *                ExtractAssociatedIconW (SHELL32.@)
00795  *
00796  * Return icon for given file (either from file itself or from associated
00797  * executable) and patch parameters if needed.
00798  */
00799 HICON WINAPI ExtractAssociatedIconW(HINSTANCE hInst, LPWSTR lpIconPath, LPWORD lpiIcon)
00800 {
00801     HICON hIcon = NULL;
00802     WORD wDummyIcon = 0;
00803 
00804     TRACE("%p %s %p\n", hInst, debugstr_w(lpIconPath), lpiIcon);
00805 
00806     if(lpiIcon == NULL)
00807         lpiIcon = &wDummyIcon;
00808 
00809     hIcon = ExtractIconW(hInst, lpIconPath, *lpiIcon);
00810 
00811     if( hIcon < (HICON)2 )
00812     { if( hIcon == (HICON)1 ) /* no icons found in given file */
00813       { WCHAR tempPath[MAX_PATH];
00814         HINSTANCE uRet = FindExecutableW(lpIconPath,NULL,tempPath);
00815 
00816         if( uRet > (HINSTANCE)32 && tempPath[0] )
00817         { wcscpy(lpIconPath,tempPath);
00818           hIcon = ExtractIconW(hInst, lpIconPath, *lpiIcon);
00819           if( hIcon > (HICON)2 )
00820             return hIcon;
00821         }
00822       }
00823 
00824       if( hIcon == (HICON)1 )
00825         *lpiIcon = 2;   /* MSDOS icon - we found .exe but no icons in it */
00826       else
00827         *lpiIcon = 6;   /* generic icon - found nothing */
00828 
00829       if (GetModuleFileNameW(hInst, lpIconPath, MAX_PATH))
00830         hIcon = LoadIconW(hInst, MAKEINTRESOURCEW(*lpiIcon));
00831     }
00832     return hIcon;
00833 }
00834 
00835 /*************************************************************************
00836  *                ExtractAssociatedIconExW (SHELL32.@)
00837  *
00838  * Return icon for given file (either from file itself or from associated
00839  * executable) and patch parameters if needed.
00840  */
00841 EXTERN_C HICON WINAPI ExtractAssociatedIconExW(HINSTANCE hInst, LPWSTR lpIconPath, LPWORD lpiIconIdx, LPWORD lpiIconId)
00842 {
00843   FIXME("%p %s %p %p): stub\n", hInst, debugstr_w(lpIconPath), lpiIconIdx, lpiIconId);
00844   return 0;
00845 }
00846 
00847 /*************************************************************************
00848  *                ExtractAssociatedIconExA (SHELL32.@)
00849  *
00850  * Return icon for given file (either from file itself or from associated
00851  * executable) and patch parameters if needed.
00852  */
00853 EXTERN_C HICON WINAPI ExtractAssociatedIconExA(HINSTANCE hInst, LPSTR lpIconPath, LPWORD lpiIconIdx, LPWORD lpiIconId)
00854 {
00855   HICON ret;
00856   INT len = MultiByteToWideChar( CP_ACP, 0, lpIconPath, -1, NULL, 0 );
00857   LPWSTR lpwstrFile = (LPWSTR)HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
00858 
00859   TRACE("%p %s %p %p)\n", hInst, lpIconPath, lpiIconIdx, lpiIconId);
00860 
00861   MultiByteToWideChar( CP_ACP, 0, lpIconPath, -1, lpwstrFile, len );
00862   ret = ExtractAssociatedIconExW(hInst, lpwstrFile, lpiIconIdx, lpiIconId);
00863   HeapFree(GetProcessHeap(), 0, lpwstrFile);
00864   return ret;
00865 }
00866 
00867 
00868 /****************************************************************************
00869  * SHDefExtractIconW        [SHELL32.@]
00870  */
00871 HRESULT WINAPI SHDefExtractIconW(LPCWSTR pszIconFile, int iIndex, UINT uFlags,
00872                                  HICON* phiconLarge, HICON* phiconSmall, UINT nIconSize)
00873 {
00874     UINT ret;
00875     HICON hIcons[2];
00876     WARN("%s %d 0x%08x %p %p %d, semi-stub\n", debugstr_w(pszIconFile), iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
00877 
00878     ret = PrivateExtractIconsW(pszIconFile, iIndex, nIconSize, nIconSize, hIcons, NULL, 2, LR_DEFAULTCOLOR);
00879     /* FIXME: deal with uFlags parameter which contains GIL_ flags */
00880     if (ret == 0xFFFFFFFF)
00881       return E_FAIL;
00882     if (ret > 0) {
00883       if (phiconLarge)
00884         *phiconLarge = hIcons[0];
00885       else
00886         DestroyIcon(hIcons[0]);
00887       if (phiconSmall)
00888         *phiconSmall = hIcons[1];
00889       else
00890         DestroyIcon(hIcons[1]);
00891       return S_OK;
00892     }
00893     return S_FALSE;
00894 }
00895 
00896 /****************************************************************************
00897  * SHDefExtractIconA        [SHELL32.@]
00898  */
00899 HRESULT WINAPI SHDefExtractIconA(LPCSTR pszIconFile, int iIndex, UINT uFlags,
00900                                  HICON* phiconLarge, HICON* phiconSmall, UINT nIconSize)
00901 {
00902   HRESULT ret;
00903   INT len = MultiByteToWideChar(CP_ACP, 0, pszIconFile, -1, NULL, 0);
00904   LPWSTR lpwstrFile = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
00905 
00906   TRACE("%s %d 0x%08x %p %p %d\n", pszIconFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
00907 
00908   MultiByteToWideChar(CP_ACP, 0, pszIconFile, -1, lpwstrFile, len);
00909   ret = SHDefExtractIconW(lpwstrFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
00910   HeapFree(GetProcessHeap(), 0, lpwstrFile);
00911   return ret;
00912 }
00913 
00914 /****************************************************************************
00915  * SHGetIconOverlayIndexA    [SHELL32.@]
00916  *
00917  * Returns the index of the overlay icon in the system image list.
00918  */
00919 EXTERN_C INT WINAPI SHGetIconOverlayIndexA(LPCSTR pszIconPath, INT iIconIndex)
00920 {
00921   FIXME("%s, %d\n", debugstr_a(pszIconPath), iIconIndex);
00922 
00923   return -1;
00924 }
00925 
00926 /****************************************************************************
00927  * SHGetIconOverlayIndexW    [SHELL32.@]
00928  *
00929  * Returns the index of the overlay icon in the system image list.
00930  */
00931 EXTERN_C INT WINAPI SHGetIconOverlayIndexW(LPCWSTR pszIconPath, INT iIconIndex)
00932 {
00933   FIXME("%s, %d\n", debugstr_w(pszIconPath), iIconIndex);
00934 
00935   return -1;
00936 }

Generated on Thu May 24 2012 04:26:52 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.