Sync to Wine-0_9_2:
authorGé van Geldorp <ge@gse.nl>
Fri, 25 Nov 2005 23:49:10 +0000 (23:49 +0000)
committerGé van Geldorp <ge@gse.nl>
Fri, 25 Nov 2005 23:49:10 +0000 (23:49 +0000)
Francois Gouget <fgouget@free.fr>
- Remove spaces before '\n' in traces.
Dmitry Timoshkov <dmitry@codeweavers.com>
- Unconditionally fall back to ANSI DDE APIs in ShellExecute if current
  emulated Windows version is Win9x, Excel refuses to communicate with a
  unicode client in win9x mode.
Martin Fuchs <martin-fuchs@gmx.net>
- SHGetFileInfoW(): handle SHGFI_LINKOVERLAY and SHGFI_OVERLAYINDEX.
- SHMapPIDLToSystemImageListIndex(): determine overlay flag for
  PidlToSicIndex() and return -1 in error cases.
- Read shell overlay icon settings from registry to allow icon
  overrides.
Markus Amsler <markus.amsler@oribi.org>
- Markus Amsler <markus.amsler@oribi.org>
  Improve c2man Documented-Total count. Changes:
- add missing description
- add missing returns section
- complete missing A/W pairs
- reformate comments, to match c2man requirements
Ge van Geldorp <gvg@reactos.org>
- Hack around missing icons

svn path=/trunk/; revision=19593

reactos/lib/shell32/brsfolder.c
reactos/lib/shell32/iconcache.c
reactos/lib/shell32/shell32_main.c
reactos/lib/shell32/shell32_main.h
reactos/lib/shell32/shellpath.c
reactos/lib/shell32/shfldr_desktop.c
reactos/lib/shell32/shfldr_mycomp.c

index 54a48b1..af65d66 100644 (file)
@@ -679,11 +679,11 @@ LPITEMIDLIST WINAPI SHBrowseForFolderW (LPBROWSEINFOW lpbi)
     info.lpBrowseInfo = lpbi;
     info.hwndTreeView = NULL;
 
-    hr = CoInitialize(NULL);
+    hr = OleInitialize(NULL);
     r = DialogBoxParamW( shell32_hInstance, swBrowseTemplateName, lpbi->hwndOwner,
                         BrsFolderDlgProc, (LPARAM)&info );
     if (SUCCEEDED(hr)) 
-        CoUninitialize();
+        OleUninitialize();
     if (!r)
         return NULL;
 
index 1d54196..3efefcf 100644 (file)
@@ -96,6 +96,9 @@ static INT CALLBACK SIC_CompareEntries( LPVOID p1, LPVOID p2, LPARAM lparam)
        return 0;
 }
 
+/* declare SIC_LoadOverlayIcon() */
+static int SIC_LoadOverlayIcon(int idx);
+
 /*****************************************************************************
  * SIC_OverlayShortcutImage                    [internal]
  *
@@ -103,7 +106,7 @@ static INT CALLBACK SIC_CompareEntries( LPVOID p1, LPVOID p2, LPARAM lparam)
  *  Creates a new icon as a copy of the passed-in icon, overlayed with a
  *  shortcut image. 
  */
-static HICON SIC_OverlayShortcutImage(HICON SourceIcon)
+static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large)
 {      ICONINFO SourceIconInfo, ShortcutIconInfo, TargetIconInfo;
        HICON ShortcutIcon, TargetIcon;
        BITMAP SourceBitmapInfo, ShortcutBitmapInfo;
@@ -115,15 +118,28 @@ static HICON SIC_OverlayShortcutImage(HICON SourceIcon)
          OldShortcutBitmap = NULL,
          OldTargetBitmap = NULL;
 
+       static int s_imgListIdx = -1;
+
        /* Get information about the source icon and shortcut overlay */
        if (! GetIconInfo(SourceIcon, &SourceIconInfo)
            || 0 == GetObjectW(SourceIconInfo.hbmColor, sizeof(BITMAP), &SourceBitmapInfo))
        {
          return NULL;
        }
-       ShortcutIcon = LoadImageW(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_SHORTCUT),
-                                 IMAGE_ICON, SourceBitmapInfo.bmWidth, SourceBitmapInfo.bmWidth,
-                                 LR_SHARED);
+
+       /* search for the shortcut icon only once */
+       if (s_imgListIdx == -1)
+           s_imgListIdx = SIC_LoadOverlayIcon(-IDI_SHELL_SHORTCUT);
+
+       if (s_imgListIdx != -1)
+       {
+           if (large)
+               ShortcutIcon = ImageList_GetIcon(ShellBigIconList, s_imgListIdx, ILD_TRANSPARENT);
+           else
+               ShortcutIcon = ImageList_GetIcon(ShellSmallIconList, s_imgListIdx, ILD_TRANSPARENT);
+       } else
+           ShortcutIcon = NULL;
+
        if (NULL == ShortcutIcon
            || ! GetIconInfo(ShortcutIcon, &ShortcutIconInfo)
            || 0 == GetObjectW(ShortcutIconInfo.hbmColor, sizeof(BITMAP), &ShortcutBitmapInfo))
@@ -313,8 +329,8 @@ static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags)
 
        if (0 != (dwFlags & GIL_FORSHORTCUT))
        {
-         hiconLargeShortcut = SIC_OverlayShortcutImage(hiconLarge);
-         hiconSmallShortcut = SIC_OverlayShortcutImage(hiconSmall);
+         hiconLargeShortcut = SIC_OverlayShortcutImage(hiconLarge, TRUE);
+         hiconSmallShortcut = SIC_OverlayShortcutImage(hiconSmall, FALSE);
          if (NULL != hiconLargeShortcut && NULL != hiconSmallShortcut)
          {
            hiconLarge = hiconLargeShortcut;
@@ -456,6 +472,52 @@ void SIC_Destroy(void)
        LeaveCriticalSection(&SHELL32_SicCS);
 }
 
+/*****************************************************************************
+ * SIC_LoadOverlayIcon                 [internal]
+ *
+ * Load a shell overlay icon and return its icon cache index.
+ */
+static int SIC_LoadOverlayIcon(int idx)
+{
+       WCHAR buffer[1024], wszIdx[8];
+       HKEY hKeyShellIcons;
+       LPCWSTR iconPath;
+       int iconIdx;
+
+       static const WCHAR wszShellIcons[] = {
+           'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
+           'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+           'E','x','p','l','o','r','e','r','\\','S','h','e','l','l',' ','I','c','o','n','s',0
+       }; 
+       static const WCHAR wszNumFmt[] = {'%','d',0};
+
+       iconPath = swShell32Name;       /* default: load icon from shell32.dll */
+       iconIdx = idx;
+
+       if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszShellIcons, 0, KEY_READ, &hKeyShellIcons) == ERROR_SUCCESS)
+       {
+           DWORD count = sizeof(buffer);
+
+           sprintfW(wszIdx, wszNumFmt, idx);
+
+           /* read icon path and index */
+           if (RegQueryValueExW(hKeyShellIcons, wszIdx, NULL, NULL, (LPBYTE)buffer, &count) == ERROR_SUCCESS)
+           {
+               LPWSTR p = strchrW(buffer, ',');
+
+               if (p)
+                   *p++ = 0;
+
+               iconPath = buffer;
+               iconIdx = atoiW(p);
+           }
+
+           RegCloseKey(hKeyShellIcons);
+       }
+
+       return SIC_LoadIcon(iconPath, iconIdx, 0);
+}
+
 /*************************************************************************
  * Shell_GetImageList                  [SHELL32.71]
  *
@@ -494,29 +556,15 @@ BOOL PidlToSicIndex (
 {
        IExtractIconW   *ei;
        WCHAR           szIconFile[MAX_PATH];   /* file containing the icon */
-       char            szTemp[MAX_PATH];
        INT             iSourceIndex;           /* index or resID(negated) in this file */
        BOOL            ret = FALSE;
        UINT            dwFlags = 0;
-       HKEY            keyCls;
        int             iShortcutDefaultIndex = INVALID_INDEX;
 
        TRACE("sf=%p pidl=%p %s\n", sh, pidl, bBigIcon?"Big":"Small");
 
        if (SUCCEEDED (IShellFolder_GetUIObjectOf(sh, 0, 1, &pidl, &IID_IExtractIconW, 0, (void **)&ei)))
        {
-         if (_ILGetExtension(pidl, szTemp, MAX_PATH) &&
-             HCR_MapTypeToValueA(szTemp, szTemp, MAX_PATH, TRUE))
-         {
-           if (ERROR_SUCCESS == RegOpenKeyExA(HKEY_CLASSES_ROOT, szTemp, 0, KEY_QUERY_VALUE, &keyCls))
-           {
-             if (ERROR_SUCCESS == RegQueryValueExA(keyCls, "IsShortcut", NULL, NULL, NULL, NULL))
-             {
-               uFlags |= GIL_FORSHORTCUT;
-             }
-             RegCloseKey(keyCls);
-           }
-         }
          if (SUCCEEDED(IExtractIconW_GetIconLocation(ei, uFlags, szIconFile, MAX_PATH, &iSourceIndex, &dwFlags)))
          {
            *pIndex = SIC_GetIconIndex(szIconFile, iSourceIndex, uFlags);
@@ -560,15 +608,19 @@ int WINAPI SHMapPIDLToSystemImageListIndex(
        int *pIndex)
 {
        int Index;
+       UINT uGilFlags = 0;
 
        TRACE("(SF=%p,pidl=%p,%p)\n",sh,pidl,pIndex);
        pdump(pidl);
 
+       if (SHELL_IsShortcut(pidl))
+           uGilFlags |= GIL_FORSHORTCUT;
+
        if (pIndex)
-           if (!PidlToSicIndex ( sh, pidl, 1, 0, pIndex))
-               *pIndex = -1;      
+           if (!PidlToSicIndex ( sh, pidl, 1, uGilFlags, pIndex))
+               *pIndex = -1;
 
-       if (!PidlToSicIndex ( sh, pidl, 0, 0, &Index))
+       if (!PidlToSicIndex ( sh, pidl, 0, uGilFlags, &Index))
            return -1;
 
        return Index;
index 82aaca1..83b9c2d 100644 (file)
@@ -297,6 +297,32 @@ static DWORD shgfi_get_exe_type(LPCWSTR szFullPath)
     return 0;
 }
 
+/*************************************************************************
+ * SHELL_IsShortcut            [internal]
+ *
+ * Decide if an item id list points to a shell shortcut
+ */
+BOOL SHELL_IsShortcut(LPCITEMIDLIST pidlLast)
+{
+    char szTemp[MAX_PATH];
+    HKEY keyCls;
+    BOOL ret = FALSE;
+
+    if (_ILGetExtension(pidlLast, szTemp, MAX_PATH) &&
+          HCR_MapTypeToValueA(szTemp, szTemp, MAX_PATH, TRUE))
+    {
+        if (ERROR_SUCCESS == RegOpenKeyExA(HKEY_CLASSES_ROOT, szTemp, 0, KEY_QUERY_VALUE, &keyCls))
+        {
+          if (ERROR_SUCCESS == RegQueryValueExA(keyCls, "IsShortcut", NULL, NULL, NULL, NULL))
+            ret = TRUE;
+
+          RegCloseKey(keyCls);
+        }
+    }
+
+    return ret;
+}
+
 #define SHGFI_KNOWN_FLAGS \
     (SHGFI_SMALLICON | SHGFI_OPENICON | SHGFI_SHELLICONSIZE | SHGFI_PIDL | \
      SHGFI_USEFILEATTRIBUTES | SHGFI_ADDOVERLAYS | SHGFI_OVERLAYINDEX | \
@@ -320,6 +346,7 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
     LPITEMIDLIST    pidlLast = NULL, pidl = NULL;
     HRESULT hr = S_OK;
     BOOL IconNotYetLoaded=TRUE;
+    UINT uGilFlags = 0;
 
     TRACE("%s fattr=0x%lx sfi=%p(attr=0x%08lx) size=0x%x flags=0x%x\n",
           (flags & SHGFI_PIDL)? "pidl" : debugstr_w(path), dwFileAttributes,
@@ -458,15 +485,21 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
     }
 
     /* ### icons ###*/
-    if (flags & SHGFI_ADDOVERLAYS)
-        FIXME("SHGFI_ADDOVERLAYS unhandled\n");
+    if (flags & SHGFI_OPENICON)
+        uGilFlags |= GIL_OPENICON;
+
+    if (flags & SHGFI_LINKOVERLAY)
+        uGilFlags |= GIL_FORSHORTCUT;
+    else if ((flags&SHGFI_ADDOVERLAYS) ||
+             (flags&(SHGFI_ICON|SHGFI_SMALLICON))==SHGFI_ICON)
+    {
+        if (SHELL_IsShortcut(pidlLast))
+            uGilFlags |= GIL_FORSHORTCUT;
+    }
 
     if (flags & SHGFI_OVERLAYINDEX)
         FIXME("SHGFI_OVERLAYINDEX unhandled\n");
 
-    if (flags & SHGFI_LINKOVERLAY)
-        FIXME("set icon to link, stub\n");
-
     if (flags & SHGFI_SELECTED)
         FIXME("set icon to selected, stub\n");
 
@@ -483,12 +516,11 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
                &uDummy, (LPVOID*)&pei);
         if (SUCCEEDED(hr))
         {
-            hr = IExtractIconW_GetIconLocation(pei, 
-                    (flags & SHGFI_OPENICON)? GIL_OPENICON : 0,
+            hr = IExtractIconW_GetIconLocation(pei, uGilFlags,
                     szLocation, MAX_PATH, &iIndex, &uFlags);
             psfi->iIcon = iIndex;
 
-            if (uFlags != GIL_NOTFILENAME)
+            if (!(uFlags & GIL_NOTFILENAME))
                 lstrcpyW (psfi->szDisplayName, szLocation);
             else
                 ret = FALSE;
@@ -550,7 +582,7 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
         else
         {
             if (!(PidlToSicIndex(psfParent, pidlLast, !(flags & SHGFI_SMALLICON),
-                (flags & SHGFI_OPENICON)? GIL_OPENICON : 0, &(psfi->iIcon))))
+                uGilFlags, &(psfi->iIcon))))
             {
                 ret = FALSE;
             }
index a95d67f..c67fa7f 100644 (file)
@@ -227,4 +227,7 @@ extern const GUID CLSID_UnixDosFolder;
 /* Default shell folder value registration */
 HRESULT SHELL_RegisterShellFolders(void);
 
+/* Detect Shell Links */
+BOOL SHELL_IsShortcut(LPCITEMIDLIST);
+
 #endif
index 2064601..27a5b13 100644 (file)
@@ -1586,7 +1586,7 @@ end:
  */
 HRESULT WINAPI SHGetFolderPathW(
        HWND hwndOwner,    /* [I] owner window */
-       int nFolder,       /* [I] CSIDL identifing the folder */
+       int nFolder,       /* [I] CSIDL identifying the folder */
        HANDLE hToken,     /* [I] access token */
        DWORD dwFlags,     /* [I] which path to return */
        LPWSTR pszPath)    /* [O] converted path */
index af7b5b2..800a857 100644 (file)
@@ -271,36 +271,37 @@ static BOOL CreateDesktopEnumList(IEnumIDList *list, DWORD dwFlags)
     if (dwFlags & SHCONTF_FOLDERS)
     {
         HKEY hkey;
-        LONG r;
+        UINT i;
 
         /* create the pidl for This item */
         ret = AddToEnumList(list, _ILCreateMyComputer());
 
-        r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Desktop_NameSpaceW,
-                          0, KEY_READ, &hkey);
-        if (ret && ERROR_SUCCESS == r)
-        {
-            WCHAR iid[50];
-            int i=0;
-            BOOL moreKeys = TRUE;
-
-            while (ret && moreKeys)
+        for (i=0; i<2; i++) {
+            if (ret && !RegOpenKeyExW(i == 0 ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
+                                      Desktop_NameSpaceW, 0, KEY_READ, &hkey))
             {
-                DWORD size;
+                WCHAR iid[50];
+                int i=0;
 
-                size = sizeof (iid);
-                r = RegEnumKeyExW(hkey, i, iid, &size, 0, NULL, NULL, NULL);
-                if (ERROR_SUCCESS == r)
+                while (ret)
                 {
-                    ret = AddToEnumList(list, _ILCreateGuidFromStrW(iid));
-                    i++;
+                    DWORD size;
+                    LONG r;
+
+                    size = sizeof (iid);
+                    r = RegEnumKeyExW(hkey, i, iid, &size, 0, NULL, NULL, NULL);
+                    if (ERROR_SUCCESS == r)
+                    {
+                        ret = AddToEnumList(list, _ILCreateGuidFromStrW(iid));
+                        i++;
+                    }
+                    else if (ERROR_NO_MORE_ITEMS == r)
+                        break;
+                    else
+                        ret = FALSE;
                 }
-                else if (ERROR_NO_MORE_ITEMS == r)
-                    moreKeys = FALSE;
-                else
-                    ret = FALSE;
+                RegCloseKey(hkey);
             }
-            RegCloseKey(hkey);
         }
     }
 
index ec137ce..b9b51b7 100644 (file)
@@ -274,6 +274,7 @@ static BOOL CreateMyCompEnumList(IEnumIDList *list, DWORD dwFlags)
         WCHAR wszDriveName[] = {'A', ':', '\\', '\0'};
         DWORD dwDrivemap = GetLogicalDrives();
         HKEY hkey;
+        UINT i;
 
         while (ret && wszDriveName[0]<='Z')
         {
@@ -284,32 +285,34 @@ static BOOL CreateMyCompEnumList(IEnumIDList *list, DWORD dwFlags)
         }
 
         TRACE("-- (%p)-> enumerate (mycomputer shell extensions)\n",list);
-        if (ret && !RegOpenKeyExW(HKEY_LOCAL_MACHINE, MyComputer_NameSpaceW,
-         0, KEY_READ, &hkey))
-        {
-            WCHAR iid[50];
-            int i=0;
-
-            while (ret)
+        for (i=0; i<2; i++) {
+            if (ret && !RegOpenKeyExW(i == 0 ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
+                                      MyComputer_NameSpaceW, 0, KEY_READ, &hkey))
             {
-                DWORD size;
-                LONG r;
+                WCHAR iid[50];
+                int i=0;
 
-                size = sizeof(iid) / sizeof(iid[0]);
-                r = RegEnumKeyExW(hkey, i, iid, &size, 0, NULL, NULL, NULL);
-                if (ERROR_SUCCESS == r)
+                while (ret)
                 {
-                    /* FIXME: shell extensions, shouldn't the type be
-                     * PT_SHELLEXT? */
-                    ret = AddToEnumList(list, _ILCreateGuidFromStrW(iid));
-                    i++;
+                    DWORD size;
+                    LONG r;
+
+                    size = sizeof(iid) / sizeof(iid[0]);
+                    r = RegEnumKeyExW(hkey, i, iid, &size, 0, NULL, NULL, NULL);
+                    if (ERROR_SUCCESS == r)
+                    {
+                        /* FIXME: shell extensions, shouldn't the type be
+                         * PT_SHELLEXT? */
+                        ret = AddToEnumList(list, _ILCreateGuidFromStrW(iid));
+                        i++;
+                    }
+                    else if (ERROR_NO_MORE_ITEMS == r)
+                        break;
+                    else
+                        ret = FALSE;
                 }
-                else if (ERROR_NO_MORE_ITEMS == r)
-                    break;
-                else
-                    ret = FALSE;
+                RegCloseKey(hkey);
             }
-            RegCloseKey(hkey);
         }
     }
     return ret;