SHGetFileInfo - fix LargeIcon & add rel. path

Vitaliy Margolen wine-patch at kievinfo.com
Sat Mar 15 15:58:39 CST 2003


According to MSDN:
  pszPath - [in] Pointer to a buffer that contains the path and file name.
    Both absolute and _RELATIVE_ paths are valid.

Plus fix for getting Large Icon properly. SHGetFileInfo was always returning small icon.
Looking at what I found, I think this should be yet one more sanity check project that
does following:
  if (aConst == 0)
  Find all where (* & aConst)

For more details see patch.
FIY: SHGFI_LARGEICON = $00000000

Vitaliy Margolen

changelog:
  - make SHGetFileInfo handle relative paths
  - fix requests for large icons

Index: shell32_main.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shell32_main.c,v
retrieving revision 1.112
diff -u -r1.112 shell32_main.c
--- shell32_main.c      14 Jan 2003 23:43:42 -0000      1.112
+++ shell32_main.c      15 Mar 2003 21:44:50 -0000
@@ -209,7 +209,7 @@
                               SHFILEINFOA *psfi, UINT sizeofpsfi,
                               UINT flags )
 {
-       char szLocation[MAX_PATH];
+       char szLocation[MAX_PATH], szFullPath[MAX_PATH];
        int iIndex;
        DWORD ret = TRUE, dwAttributes = 0;
        IShellFolder * psfParent = NULL;
@@ -229,6 +229,16 @@
        psfi->szTypeName[0] = '\0';
        psfi->iIcon = 0;
 
+       if (!(flags & SHGFI_PIDL)){
+            // SHGitFileInfo should work with absolute and relative paths */
+            if (PathIsRelativeA(path)){
+                GetCurrentDirectoryA(MAX_PATH, szLocation);
+                PathCombineA(szFullPath, szLocation, path);
+            } else {
+                lstrcpynA(szFullPath, path, MAX_PATH);
+            }
+        }
+
        if (flags & SHGFI_EXETYPE) {
          BOOL status = FALSE;
          HANDLE hfile;
@@ -240,12 +250,12 @@
 
          if (flags != SHGFI_EXETYPE) return 0;
 
-         status = GetBinaryTypeA (path, &BinaryType);
+         status = GetBinaryTypeA (szFullPath, &BinaryType);
          if (!status) return 0;
          if ((BinaryType == SCS_DOS_BINARY)
                || (BinaryType == SCS_PIF_BINARY)) return 0x4d5a;
 
-         hfile = CreateFileA( path, GENERIC_READ, FILE_SHARE_READ,
+         hfile = CreateFileA( szFullPath, GENERIC_READ, FILE_SHARE_READ,
                NULL, OPEN_EXISTING, 0, 0 );
          if ( hfile == INVALID_HANDLE_VALUE ) return 0;
 
@@ -294,7 +304,7 @@
        if (flags & SHGFI_PIDL) {
            pidl = ILClone((LPCITEMIDLIST)path);
        } else if (!(flags & SHGFI_USEFILEATTRIBUTES)) {
-           hr = SHILCreateFromPathA(path, &pidl, &dwAttributes);
+           hr = SHILCreateFromPathA(szFullPath, &pidl, &dwAttributes);
        }
 
         if ((flags & SHGFI_PIDL) || !(flags & SHGFI_USEFILEATTRIBUTES))
@@ -324,7 +334,7 @@
        {
          if (flags & SHGFI_USEFILEATTRIBUTES)
          {
-           strcpy (psfi->szDisplayName, PathFindFileNameA(path));
+           strcpy (psfi->szDisplayName, PathFindFileNameA(szFullPath));
          }
          else
          {
@@ -346,7 +356,7 @@
                 else 
                 {
                    char sTemp[64];
-                   strcpy(sTemp,PathFindExtensionA(path));
+                   strcpy(sTemp,PathFindExtensionA(szFullPath));
                    if (!( HCR_MapTypeToValueA(sTemp, sTemp, 64, TRUE)
                         && HCR_MapTypeToValueA(sTemp, psfi->szTypeName, 80, FALSE )))
                    {
@@ -397,7 +407,7 @@
            char * szExt;
            DWORD dwNr=0;
 
-           lstrcpynA(sTemp, path, MAX_PATH);
+           lstrcpynA(sTemp, szFullPath, MAX_PATH);
 
             if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                psfi->iIcon = 2;
@@ -409,7 +419,7 @@
                    && HCR_GetDefaultIconA(sTemp, sTemp, MAX_PATH, &dwNr))
                {
                   if (!strcmp("%1",sTemp))            /* icon is in the file */
-                     strcpy(sTemp, path);
+                     strcpy(sTemp, szFullPath);
           
                   if (flags & SHGFI_SYSICONINDEX) 
                   {    
@@ -419,10 +429,10 @@
                   else 
                   {
                       IconNotYetLoaded=FALSE;
-                      PrivateExtractIconsA(sTemp,dwNr,(flags&SHGFI_LARGEICON) ? 
-                        GetSystemMetrics(SM_CXICON) : GetSystemMetrics(SM_CXSMICON),
-                        (flags&SHGFI_LARGEICON) ? GetSystemMetrics(SM_CYICON) :
-                        GetSystemMetrics(SM_CYSMICON), &psfi->hIcon,0,1,0);
+                      PrivateExtractIconsA(sTemp,dwNr,(flags & SHGFI_SMALLICON) ? 
+                        GetSystemMetrics(SM_CXSMICON) : GetSystemMetrics(SM_CXICON),
+                        (flags & SHGFI_SMALLICON) ? GetSystemMetrics(SM_CYSMICON) :
+                        GetSystemMetrics(SM_CYICON), &psfi->hIcon,0,1,0);
                       psfi->iIcon = dwNr;
                   }
                }
@@ -430,7 +440,7 @@
          }
          else
          {
-           if (!(PidlToSicIndex(psfParent, pidlLast, (flags & SHGFI_LARGEICON),
+           if (!(PidlToSicIndex(psfParent, pidlLast, !(flags & SHGFI_SMALLICON),
              (flags & SHGFI_OPENICON)? GIL_OPENICON : 0, &(psfi->iIcon))))
            {
              ret = FALSE;
@@ -438,13 +448,13 @@
          }
          if (ret)
          {
-           ret = (DWORD) ((flags & SHGFI_LARGEICON) ? ShellBigIconList : ShellSmallIconList);
+           ret = (DWORD) ((flags & SHGFI_SMALLICON) ? ShellSmallIconList : ShellBigIconList);
          }
        }
 
        /* icon handle */
        if (SUCCEEDED(hr) && (flags & SHGFI_ICON) && IconNotYetLoaded)
-         psfi->hIcon = ImageList_GetIcon((flags & SHGFI_LARGEICON) ? ShellBigIconList:ShellSmallIconList, psfi->iIcon, ILD_NORMAL);
+         psfi->hIcon = ImageList_GetIcon((flags & SHGFI_SMALLICON) ? ShellSmallIconList:ShellBigIconList, psfi->iIcon, ILD_NORMAL);
 
        if (flags & (SHGFI_UNKNOWN1 | SHGFI_UNKNOWN2 | SHGFI_UNKNOWN3))
          FIXME("unknown attribute!\n");




More information about the wine-patches mailing list