/************************************************************************ * IEIPersistFile_Release (IUnknown) */ static ULONG WINAPI IEIPersistFile_fnRelease( IPersistFile *iface) { IExtractIconW *This = impl_from_IPersistFile(iface); return IExtractIconW_Release(This); }
/************************************************************************* * PidlToSicIndex [INTERNAL] * * PARAMETERS * sh [IN] IShellFolder * pidl [IN] * bBigIcon [IN] * uFlags [IN] GIL_* * pIndex [OUT] index within the SIC * */ BOOL PidlToSicIndex ( IShellFolder * sh, LPCITEMIDLIST pidl, BOOL bBigIcon, UINT uFlags, int * pIndex) { IExtractIconW *ei; WCHAR szIconFile[MAX_PATH]; /* file containing the icon */ INT iSourceIndex; /* index or resID(negated) in this file */ BOOL ret = FALSE; UINT dwFlags = 0; int iShortcutDefaultIndex = INVALID_INDEX; TRACE("sf=%p pidl=%p %s\n", sh, pidl, bBigIcon?"Big":"Small"); InitOnceExecuteOnce( &sic_init_once, SIC_Initialize, NULL, NULL ); if (SUCCEEDED (IShellFolder_GetUIObjectOf(sh, 0, 1, &pidl, &IID_IExtractIconW, 0, (void **)&ei))) { if (SUCCEEDED(IExtractIconW_GetIconLocation(ei, uFlags, szIconFile, MAX_PATH, &iSourceIndex, &dwFlags))) { *pIndex = SIC_GetIconIndex(szIconFile, iSourceIndex, uFlags); ret = TRUE; } IExtractIconW_Release(ei); } if (INVALID_INDEX == *pIndex) /* default icon when failed */ { if (0 == (uFlags & GIL_FORSHORTCUT)) { *pIndex = 0; } else { if (INVALID_INDEX == iShortcutDefaultIndex) { iShortcutDefaultIndex = SIC_LoadIcon(swShell32Name, 0, GIL_FORSHORTCUT); } *pIndex = (INVALID_INDEX != iShortcutDefaultIndex ? iShortcutDefaultIndex : 0); } } return ret; }
static BOOL create_combobox_item(IShellFolder *folder, LPCITEMIDLIST pidl, IImageList *icon_list, COMBOBOXEXITEMW *item) { STRRET strret; HRESULT hres; IExtractIconW *extract_icon; UINT reserved; WCHAR icon_file[MAX_PATH]; INT icon_index; UINT icon_flags; HICON icon; strret.uType=STRRET_WSTR; hres = IShellFolder_GetDisplayNameOf(folder,pidl,SHGDN_FORADDRESSBAR,&strret); if(FAILED(hres)) { WINE_WARN("Could not get name for pidl\n"); return FALSE; } switch(strret.uType) { case STRRET_WSTR: item->pszText = strret.u.pOleStr; break; default: WINE_FIXME("Unimplemented STRRET type:%u\n",strret.uType); break; } hres = IShellFolder_GetUIObjectOf(folder,NULL,1,&pidl,&IID_IExtractIconW, &reserved,(void**)&extract_icon); if(SUCCEEDED(hres)) { item->mask |= CBEIF_IMAGE; IExtractIconW_GetIconLocation(extract_icon,GIL_FORSHELL,icon_file, sizeof(icon_file)/sizeof(WCHAR), &icon_index,&icon_flags); IExtractIconW_Extract(extract_icon,icon_file,icon_index,NULL,&icon,20); item->iImage = ImageList_AddIcon((HIMAGELIST)icon_list,icon); IExtractIconW_Release(extract_icon); } else { item->mask &= ~CBEIF_IMAGE; WINE_WARN("Could not get an icon for %s\n",wine_dbgstr_w(item->pszText)); } return TRUE; }
/************************************************************************* * SHGetFileInfoW [SHELL32.@] * */ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes, SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags ) { WCHAR szLocation[MAX_PATH], szFullPath[MAX_PATH]; int iIndex; DWORD_PTR ret = TRUE; DWORD dwAttributes = 0; IShellFolder * psfParent = NULL; IExtractIconW * pei = NULL; LPITEMIDLIST pidlLast = NULL, pidl = NULL; HRESULT hr = S_OK; BOOL IconNotYetLoaded=TRUE; UINT uGilFlags = 0; HIMAGELIST big_icons, small_icons; TRACE("%s fattr=0x%x sfi=%p(attr=0x%08x) size=0x%x flags=0x%x\n", (flags & SHGFI_PIDL)? "pidl" : debugstr_w(path), dwFileAttributes, psfi, psfi->dwAttributes, sizeofpsfi, flags); if (!path) return FALSE; /* windows initializes these values regardless of the flags */ if (psfi != NULL) { psfi->szDisplayName[0] = '\0'; psfi->szTypeName[0] = '\0'; psfi->iIcon = 0; } if (!(flags & SHGFI_PIDL)) { /* SHGetFileInfo should work with absolute and relative paths */ if (PathIsRelativeW(path)) { GetCurrentDirectoryW(MAX_PATH, szLocation); PathCombineW(szFullPath, szLocation, path); } else { lstrcpynW(szFullPath, path, MAX_PATH); } } if (flags & SHGFI_EXETYPE) { if (flags != SHGFI_EXETYPE) return 0; return shgfi_get_exe_type(szFullPath); } /* * psfi is NULL normally to query EXE type. If it is NULL, none of the * below makes sense anyway. Windows allows this and just returns FALSE */ if (psfi == NULL) return FALSE; /* * translate the path into a pidl only when SHGFI_USEFILEATTRIBUTES * is not specified. * The pidl functions fail on not existing file names */ if (flags & SHGFI_PIDL) { pidl = ILClone((LPCITEMIDLIST)path); } else if (!(flags & SHGFI_USEFILEATTRIBUTES)) { hr = SHILCreateFromPathW(szFullPath, &pidl, &dwAttributes); } if ((flags & SHGFI_PIDL) || !(flags & SHGFI_USEFILEATTRIBUTES)) { /* get the parent shellfolder */ if (pidl) { hr = SHBindToParent( pidl, &IID_IShellFolder, (LPVOID*)&psfParent, (LPCITEMIDLIST*)&pidlLast ); if (SUCCEEDED(hr)) pidlLast = ILClone(pidlLast); ILFree(pidl); } else { ERR("pidl is null!\n"); return FALSE; } } /* get the attributes of the child */ if (SUCCEEDED(hr) && (flags & SHGFI_ATTRIBUTES)) { if (!(flags & SHGFI_ATTR_SPECIFIED)) { psfi->dwAttributes = 0xffffffff; } if (psfParent) IShellFolder_GetAttributesOf( psfParent, 1, (LPCITEMIDLIST*)&pidlLast, &(psfi->dwAttributes) ); } /* get the displayname */ if (SUCCEEDED(hr) && (flags & SHGFI_DISPLAYNAME)) { if (flags & SHGFI_USEFILEATTRIBUTES && !(flags & SHGFI_PIDL)) { lstrcpyW (psfi->szDisplayName, PathFindFileNameW(szFullPath)); } else { STRRET str; hr = IShellFolder_GetDisplayNameOf( psfParent, pidlLast, SHGDN_INFOLDER, &str); StrRetToStrNW (psfi->szDisplayName, MAX_PATH, &str, pidlLast); } } /* get the type name */ if (SUCCEEDED(hr) && (flags & SHGFI_TYPENAME)) { static const WCHAR szFile[] = { 'F','i','l','e',0 }; static const WCHAR szDashFile[] = { '-','f','i','l','e',0 }; if (!(flags & SHGFI_USEFILEATTRIBUTES) || (flags & SHGFI_PIDL)) { char ftype[80]; _ILGetFileType(pidlLast, ftype, 80); MultiByteToWideChar(CP_ACP, 0, ftype, -1, psfi->szTypeName, 80 ); } else { if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) strcatW (psfi->szTypeName, szFile); else { WCHAR sTemp[64]; lstrcpyW(sTemp,PathFindExtensionW(szFullPath)); if (!( HCR_MapTypeToValueW(sTemp, sTemp, 64, TRUE) && HCR_MapTypeToValueW(sTemp, psfi->szTypeName, 80, FALSE ))) { lstrcpynW (psfi->szTypeName, sTemp, 64); strcatW (psfi->szTypeName, szDashFile); } } } } /* ### icons ###*/ Shell_GetImageLists( &big_icons, &small_icons ); 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_SELECTED) FIXME("set icon to selected, stub\n"); if (flags & SHGFI_SHELLICONSIZE) FIXME("set icon to shell size, stub\n"); /* get the iconlocation */ if (SUCCEEDED(hr) && (flags & SHGFI_ICONLOCATION )) { UINT uDummy,uFlags; if (flags & SHGFI_USEFILEATTRIBUTES && !(flags & SHGFI_PIDL)) { if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { lstrcpyW(psfi->szDisplayName, swShell32Name); psfi->iIcon = -IDI_SHELL_FOLDER; } else { WCHAR* szExt; static const WCHAR p1W[] = {'%','1',0}; WCHAR sTemp [MAX_PATH]; szExt = PathFindExtensionW(szFullPath); TRACE("szExt=%s\n", debugstr_w(szExt)); if ( szExt && HCR_MapTypeToValueW(szExt, sTemp, MAX_PATH, TRUE) && HCR_GetDefaultIconW(sTemp, sTemp, MAX_PATH, &psfi->iIcon)) { if (lstrcmpW(p1W, sTemp)) strcpyW(psfi->szDisplayName, sTemp); else { /* the icon is in the file */ strcpyW(psfi->szDisplayName, szFullPath); } } else ret = FALSE; } } else { hr = IShellFolder_GetUIObjectOf(psfParent, 0, 1, (LPCITEMIDLIST*)&pidlLast, &IID_IExtractIconW, &uDummy, (LPVOID*)&pei); if (SUCCEEDED(hr)) { hr = IExtractIconW_GetIconLocation(pei, uGilFlags, szLocation, MAX_PATH, &iIndex, &uFlags); if (uFlags & GIL_NOTFILENAME) ret = FALSE; else { lstrcpyW (psfi->szDisplayName, szLocation); psfi->iIcon = iIndex; } IExtractIconW_Release(pei); } } } /* get icon index (or load icon)*/ if (SUCCEEDED(hr) && (flags & (SHGFI_ICON | SHGFI_SYSICONINDEX))) { if (flags & SHGFI_USEFILEATTRIBUTES && !(flags & SHGFI_PIDL)) { WCHAR sTemp [MAX_PATH]; WCHAR * szExt; int icon_idx=0; lstrcpynW(sTemp, szFullPath, MAX_PATH); if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) psfi->iIcon = SIC_GetIconIndex(swShell32Name, -IDI_SHELL_FOLDER, 0); else { static const WCHAR p1W[] = {'%','1',0}; psfi->iIcon = 0; szExt = PathFindExtensionW(sTemp); if ( szExt && HCR_MapTypeToValueW(szExt, sTemp, MAX_PATH, TRUE) && HCR_GetDefaultIconW(sTemp, sTemp, MAX_PATH, &icon_idx)) { if (!lstrcmpW(p1W,sTemp)) /* icon is in the file */ strcpyW(sTemp, szFullPath); if (flags & SHGFI_SYSICONINDEX) { psfi->iIcon = SIC_GetIconIndex(sTemp,icon_idx,0); if (psfi->iIcon == -1) psfi->iIcon = 0; } else { UINT ret; if (flags & SHGFI_SMALLICON) ret = PrivateExtractIconsW( sTemp,icon_idx, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), &psfi->hIcon, 0, 1, 0); else ret = PrivateExtractIconsW( sTemp, icon_idx, GetSystemMetrics( SM_CXICON), GetSystemMetrics( SM_CYICON), &psfi->hIcon, 0, 1, 0); if (ret != 0 && ret != (UINT)-1) { IconNotYetLoaded=FALSE; psfi->iIcon = icon_idx; } } } } } else { if (!(PidlToSicIndex(psfParent, pidlLast, !(flags & SHGFI_SMALLICON), uGilFlags, &(psfi->iIcon)))) { ret = FALSE; } } if (ret && (flags & SHGFI_SYSICONINDEX)) { if (flags & SHGFI_SMALLICON) ret = (DWORD_PTR)small_icons; else ret = (DWORD_PTR)big_icons; } } /* icon handle */ if (SUCCEEDED(hr) && (flags & SHGFI_ICON) && IconNotYetLoaded) { if (flags & SHGFI_SMALLICON) psfi->hIcon = ImageList_GetIcon( small_icons, psfi->iIcon, ILD_NORMAL); else psfi->hIcon = ImageList_GetIcon( big_icons, psfi->iIcon, ILD_NORMAL); } if (flags & ~SHGFI_KNOWN_FLAGS) FIXME("unknown flags %08x\n", flags & ~SHGFI_KNOWN_FLAGS); if (psfParent) IShellFolder_Release(psfParent); if (hr != S_OK) ret = FALSE; SHFree(pidlLast); TRACE ("icon=%p index=0x%08x attr=0x%08x name=%s type=%s ret=0x%08lx\n", psfi->hIcon, psfi->iIcon, psfi->dwAttributes, debugstr_w(psfi->szDisplayName), debugstr_w(psfi->szTypeName), ret); return ret; }
/************************************************************************** * IExtractIconA::Release */ static ULONG WINAPI IExtractIconA_fnRelease(IExtractIconA * iface) { IExtractIconWImpl *This = impl_from_IExtractIconA(iface); return IExtractIconW_Release(&This->IExtractIconW_iface); }