diff --git a/dlls/shell32/folders.c b/dlls/shell32/folders.c index 06f70f025e1..32efd6c9b0b 100644 --- a/dlls/shell32/folders.c +++ b/dlls/shell32/folders.c @@ -22,13 +22,17 @@ */ typedef struct -{ ICOM_VTABLE(IExtractIconA)* lpvtbl; - DWORD ref; - LPITEMIDLIST pidl; +{ ICOM_VTABLE(IExtractIconA)* lpvtbl; + DWORD ref; + ICOM_VTABLE(IPersistFile)* lpvtblPersistFile; + LPITEMIDLIST pidl; } IExtractIconAImpl; static struct ICOM_VTABLE(IExtractIconA) eivt; +static struct ICOM_VTABLE(IPersistFile) pfvt; +#define _IPersistFile_Offset ((int)(&(((IExtractIconAImpl*)0)->lpvtblPersistFile))) +#define _ICOM_THIS_From_IPersistFile(class, name) class* This = (class*)(((void*)name)-_IPersistFile_Offset); /************************************************************************** * IExtractIconA_Constructor @@ -39,7 +43,8 @@ IExtractIconA* IExtractIconA_Constructor(LPCITEMIDLIST pidl) ei=(IExtractIconAImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IExtractIconAImpl)); ei->ref=1; - ei->lpvtbl=&eivt; + ei->lpvtbl = &eivt; + ei->lpvtblPersistFile = &pfvt; ei->pidl=ILClone(pidl); pdump(pidl); @@ -61,10 +66,13 @@ static HRESULT WINAPI IExtractIconA_fnQueryInterface( IExtractIconA * iface, REF *ppvObj = NULL; - if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/ + if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/ { *ppvObj = This; } - else if(IsEqualIID(riid, &IID_IExtractIconA)) /*IExtractIcon*/ + else if(IsEqualIID(riid, &IID_IPersistFile)) /*IExtractIcon*/ + { *ppvObj = (IPersistFile*)&(This->lpvtblPersistFile); + } + else if(IsEqualIID(riid, &IID_IExtractIconA)) /*IExtractIcon*/ { *ppvObj = (IExtractIconA*)This; } @@ -112,18 +120,81 @@ static ULONG WINAPI IExtractIconA_fnRelease(IExtractIconA * iface) /************************************************************************** * IExtractIconA_GetIconLocation */ -static HRESULT WINAPI IExtractIconA_fnGetIconLocation(IExtractIconA * iface, UINT uFlags, LPSTR szIconFile, UINT cchMax, int * piIndex, UINT * pwFlags) +static HRESULT WINAPI IExtractIconA_fnGetIconLocation( + IExtractIconA * iface, + UINT uFlags, + LPSTR szIconFile, + UINT cchMax, + int * piIndex, + UINT * pwFlags) { ICOM_THIS(IExtractIconAImpl,iface); - WARN (shell,"(%p) (flags=%u file=%s max=%u %p %p) semi-stub\n", This, uFlags, szIconFile, cchMax, piIndex, pwFlags); + char sTemp[MAX_PATH]; + DWORD ret = S_FALSE, dwNr; + LPITEMIDLIST pSimplePidl = ILFindLastID(This->pidl); + + TRACE (shell,"(%p) (flags=%u %p %u %p %p)\n", This, uFlags, szIconFile, cchMax, piIndex, pwFlags); - *piIndex = (int) SHMapPIDLToSystemImageListIndex(0, This->pidl,0); - *pwFlags = GIL_NOTFILENAME; + if (pwFlags) + *pwFlags = 0; - WARN (shell,"-- %x\n",*piIndex); + if (_ILIsDesktop(pSimplePidl)) + { strncpy(szIconFile, "shell32.dll", cchMax); + *piIndex = 34; + ret = NOERROR; + } + else if (_ILIsMyComputer(pSimplePidl)) + { if (HCR_GetDefaultIcon("CLSID\\{20D04FE0-3AEA-1069-A2D8-08002B30309D}", sTemp, MAX_PATH, &dwNr)) + { strncpy(szIconFile, sTemp, cchMax); + *piIndex = dwNr; + } + else + { strncpy(szIconFile, "shell32.dll", cchMax); + *piIndex = 15; + } + ret = NOERROR; + } + else if (_ILIsDrive (pSimplePidl)) + { if (HCR_GetDefaultIcon("Drive", sTemp, MAX_PATH, &dwNr)) + { strncpy(szIconFile, sTemp, cchMax); + *piIndex = dwNr; + } + else + { strncpy(szIconFile, "shell32.dll", cchMax); + *piIndex = 8; + } + ret = NOERROR; + } + else if (_ILIsFolder (pSimplePidl)) + { if (HCR_GetDefaultIcon("Folder", sTemp, MAX_PATH, &dwNr)) + { strncpy(szIconFile, sTemp, cchMax); + *piIndex = dwNr; + } + else + { strncpy(szIconFile, "shell32.dll", cchMax); + *piIndex = 3; + } + ret = NOERROR; + } + else + { if (_ILGetExtension (pSimplePidl, sTemp, MAX_PATH)) /* object is file */ + { if ( HCR_MapTypeToValue(sTemp, sTemp, MAX_PATH)) + { if (HCR_GetDefaultIcon(sTemp, sTemp, MAX_PATH, &dwNr)) + { if (!strcmp("%1",sTemp)) /* icon is in the file */ + { _ILGetPidlPath(This->pidl, sTemp, MAX_PATH); + dwNr = 0; + } + strncpy(szIconFile, sTemp, cchMax); + *piIndex = dwNr; + ret = NOERROR; + } + } + } + } - return NOERROR; + TRACE (shell,"-- %s %x\n", debugstr_a(szIconFile), *piIndex); + return ret; } /************************************************************************** * IExtractIconA_Extract @@ -132,10 +203,14 @@ static HRESULT WINAPI IExtractIconA_fnExtract(IExtractIconA * iface, LPCSTR pszF { ICOM_THIS(IExtractIconAImpl,iface); - FIXME (shell,"(%p) (file=%s index=%u %p %p size=%u) semi-stub\n", This, pszFile, nIconIndex, phiconLarge, phiconSmall, nIconSize); + FIXME (shell,"(%p) (file=%p index=%u %p %p size=%u) semi-stub\n", This, pszFile, nIconIndex, phiconLarge, phiconSmall, nIconSize); + + if (phiconLarge) + *phiconLarge = pImageList_GetIcon(ShellBigIconList, nIconIndex, ILD_TRANSPARENT); + + if (phiconSmall) + *phiconSmall = pImageList_GetIcon(ShellSmallIconList, nIconIndex, ILD_TRANSPARENT); - *phiconLarge = pImageList_GetIcon(ShellBigIconList, nIconIndex, ILD_TRANSPARENT); - *phiconSmall = pImageList_GetIcon(ShellSmallIconList, nIconIndex, ILD_TRANSPARENT); return S_OK; } @@ -146,3 +221,80 @@ static struct ICOM_VTABLE(IExtractIconA) eivt = IExtractIconA_fnGetIconLocation, IExtractIconA_fnExtract }; + +/************************************************************************ + * IEIPersistFile_QueryInterface (IUnknown) + */ +static HRESULT WINAPI IEIPersistFile_fnQueryInterface( + IPersistFile *iface, + REFIID iid, + LPVOID *ppvObj) +{ + _ICOM_THIS_From_IPersistFile(IExtractIconA, iface); + + return IShellFolder_QueryInterface((IExtractIconA*)This, iid, ppvObj); +} + +/************************************************************************ + * IEIPersistFile_AddRef (IUnknown) + */ +static ULONG WINAPI IEIPersistFile_fnAddRef( + IPersistFile *iface) +{ + _ICOM_THIS_From_IPersistFile(IExtractIconA, iface); + + return IExtractIconA_AddRef((IExtractIconA*)This); +} + +/************************************************************************ + * IEIPersistFile_Release (IUnknown) + */ +static ULONG WINAPI IEIPersistFile_fnRelease( + IPersistFile *iface) +{ + _ICOM_THIS_From_IPersistFile(IExtractIconA, iface); + + return IExtractIconA_Release((IExtractIconA*)This); +} + +/************************************************************************ + * IEIPersistFile_GetClassID (IPersist) + */ +static HRESULT WINAPI IEIPersistFile_fnGetClassID( + const IPersistFile *iface, + LPCLSID lpClassId) +{ + CLSID StdFolderID = { 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; + + if (lpClassId==NULL) + return E_POINTER; + + memcpy(lpClassId, &StdFolderID, sizeof(StdFolderID)); + + return S_OK; +} + +/************************************************************************ + * IEIPersistFile_Load (IPersistFile) + */ +static HRESULT WINAPI IEIPersistFile_fnLoad(IPersistFile* iface, LPCOLESTR pszFileName, DWORD dwMode) +{ + _ICOM_THIS_From_IPersistFile(IExtractIconA, iface); + FIXME(shell,"%p\n", This); + return E_NOTIMPL; + +} + +static struct ICOM_VTABLE(IPersistFile) pfvt = +{ + IEIPersistFile_fnQueryInterface, + IEIPersistFile_fnAddRef, + IEIPersistFile_fnRelease, + IEIPersistFile_fnGetClassID, + (void *) 0xdeadbeef /* IEIPersistFile_fnIsDirty */, + IEIPersistFile_fnLoad, + (void *) 0xdeadbeef /* IEIPersistFile_fnSave */, + (void *) 0xdeadbeef /* IEIPersistFile_fnSaveCompleted */, + (void *) 0xdeadbeef /* IEIPersistFile_fnGetCurFile */ +}; + diff --git a/dlls/shell32/iconcache.c b/dlls/shell32/iconcache.c index a00a8409fc2..0623de17f3c 100644 --- a/dlls/shell32/iconcache.c +++ b/dlls/shell32/iconcache.c @@ -1,8 +1,6 @@ /* * shell icon cache (SIC) * - * FIXME - * since dll geting never unloaded the iconcache will never be freed */ #include #include "wine/winuser16.h" @@ -35,23 +33,36 @@ typedef struct typedef struct { - WORD idReserved; /* Reserved (must be 0) */ - WORD idType; /* Resource Type (1 for icons) */ - WORD idCount; /* How many images? */ + WORD idReserved; /* Reserved (must be 0) */ + WORD idType; /* Resource Type (RES_ICON or RES_CURSOR) */ + WORD idCount; /* How many images */ icoICONDIRENTRY idEntries[1]; /* An entry for each image (idCount of 'em) */ } icoICONDIR, *LPicoICONDIR; #pragma pack(4) +#if 0 +static void dumpIcoDirEnty ( LPicoICONDIRENTRY entry ) +{ + TRACE (shell, "width = 0x%08x height = 0x%08x\n", entry->bWidth, entry->bHeight); + TRACE (shell, "colors = 0x%08x planes = 0x%08x\n", entry->bColorCount, entry->wPlanes); + TRACE (shell, "bitcount = 0x%08x bytesinres = 0x%08lx offset = 0x%08lx\n", + entry->wBitCount, entry->dwBytesInRes, entry->dwImageOffset); +} +static void dumpIcoDir ( LPicoICONDIR entry ) +{ + TRACE (shell, "type = 0x%08x count = 0x%08x\n", entry->idType, entry->idCount); +} +#endif /************************************************************************* * SHELL_GetResourceTable */ -static DWORD SHELL_GetResourceTable(HFILE hFile,LPBYTE *retptr) +static DWORD SHELL_GetResourceTable(HFILE hFile, LPBYTE *retptr) { IMAGE_DOS_HEADER mz_header; char magic[4]; int size; - TRACE(shell,"\n"); + TRACE(shell,"0x%08x %p\n", hFile, retptr); *retptr = NULL; _llseek( hFile, 0, SEEK_SET ); @@ -103,16 +114,16 @@ static DWORD SHELL_GetResourceTable(HFILE hFile,LPBYTE *retptr) /************************************************************************* * SHELL_LoadResource */ -static HGLOBAL16 SHELL_LoadResource(HINSTANCE hInst, HFILE hFile, NE_NAMEINFO* pNInfo, WORD sizeShift) +static BYTE * SHELL_LoadResource( HFILE hFile, NE_NAMEINFO* pNInfo, WORD sizeShift, ULONG *uSize) { BYTE* ptr; - HGLOBAL16 handle = DirectResAlloc16( hInst, 0x10, (DWORD)pNInfo->length << sizeShift); - TRACE(shell,"\n"); + TRACE(shell,"0x%08x %p 0x%08x\n", hFile, pNInfo, sizeShift); - if( (ptr = (BYTE*)GlobalLock16( handle )) ) + *uSize = (DWORD)pNInfo->length << sizeShift; + if( (ptr = (BYTE*)HeapAlloc(GetProcessHeap(),0, *uSize) )) { _llseek( hFile, (DWORD)pNInfo->offset << sizeShift, SEEK_SET); _lread( hFile, (char*)ptr, pNInfo->length << sizeShift); - return handle; + return ptr; } return 0; } @@ -120,58 +131,65 @@ static HGLOBAL16 SHELL_LoadResource(HINSTANCE hInst, HFILE hFile, NE_NAMEINFO* p /************************************************************************* * ICO_LoadIcon */ -static HGLOBAL16 ICO_LoadIcon(HINSTANCE hInst, HFILE hFile, LPicoICONDIRENTRY lpiIDE) +static BYTE * ICO_LoadIcon( HFILE hFile, LPicoICONDIRENTRY lpiIDE, ULONG *uSize) { BYTE* ptr; - HGLOBAL16 handle = DirectResAlloc16( hInst, 0x10, lpiIDE->dwBytesInRes); - TRACE(shell,"\n"); - if( (ptr = (BYTE*)GlobalLock16( handle )) ) + + TRACE(shell,"0x%08x %p\n", hFile, lpiIDE); + + *uSize = lpiIDE->dwBytesInRes; + if( (ptr = (BYTE*)HeapAlloc(GetProcessHeap(),0, *uSize)) ) { _llseek( hFile, lpiIDE->dwImageOffset, SEEK_SET); _lread( hFile, (char*)ptr, lpiIDE->dwBytesInRes); - return handle; + return ptr; } + return 0; } /************************************************************************* * ICO_GetIconDirectory * - * Read .ico file and build phony ICONDIR struct for GetIconID + * Reads .ico file and build phony ICONDIR struct + * see http://www.microsoft.com/win32dev/ui/icons.htm */ -static HGLOBAL16 ICO_GetIconDirectory(HINSTANCE hInst, HFILE hFile, LPicoICONDIR* lplpiID ) -{ WORD id[3]; /* idReserved, idType, idCount */ - LPicoICONDIR lpiID; +#define HEADER_SIZE (sizeof(CURSORICONDIR) - sizeof (CURSORICONDIRENTRY)) +#define HEADER_SIZE_FILE (sizeof(icoICONDIR) - sizeof (icoICONDIRENTRY)) + +static BYTE * ICO_GetIconDirectory( HFILE hFile, LPicoICONDIR* lplpiID, ULONG *uSize ) +{ CURSORICONDIR lpcid; /* icon resource in resource-dir format */ + LPicoICONDIR lpiID; /* icon resource in file format */ int i; - TRACE(shell,"\n"); + TRACE(shell,"0x%08x %p\n", hFile, lplpiID); + _llseek( hFile, 0, SEEK_SET ); - if( _lread(hFile,(char*)id,sizeof(id)) != sizeof(id) ) + if( _lread(hFile,(char*)&lpcid, HEADER_SIZE_FILE) != HEADER_SIZE_FILE ) return 0; - /* check .ICO header - * - * - see http://www.microsoft.com/win32dev/ui/icons.htm - */ - - if( id[0] || id[1] != 1 || !id[2] ) + if( lpcid.idReserved || (lpcid.idType != 1) || (!lpcid.idCount) ) return 0; - i = id[2]*sizeof(icoICONDIRENTRY) + sizeof(id); - - lpiID = (LPicoICONDIR)HeapAlloc( GetProcessHeap(), 0, i); + i = lpcid.idCount * sizeof(icoICONDIRENTRY); + lpiID = (LPicoICONDIR)HeapAlloc( GetProcessHeap(), 0, HEADER_SIZE_FILE + i); if( _lread(hFile,(char*)lpiID->idEntries,i) == i ) - { HGLOBAL16 handle = DirectResAlloc16( hInst, 0x10,id[2]*sizeof(ICONDIRENTRY) + sizeof(id) ); - if( handle ) - { CURSORICONDIR* lpID = (CURSORICONDIR*)GlobalLock16( handle ); - lpID->idReserved = lpiID->idReserved = id[0]; - lpID->idType = lpiID->idType = id[1]; - lpID->idCount = lpiID->idCount = id[2]; + { CURSORICONDIR * lpID; /* icon resource in resource format */ + *uSize = lpcid.idCount * sizeof(CURSORICONDIRENTRY) + HEADER_SIZE; + if( (lpID = (CURSORICONDIR*)HeapAlloc(GetProcessHeap(),0, *uSize) )) + { + /* copy the header */ + lpID->idReserved = lpiID->idReserved = 0; + lpID->idType = lpiID->idType = 1; + lpID->idCount = lpiID->idCount = lpcid.idCount; + + /* copy the entrys */ for( i=0; i < lpiID->idCount; i++ ) - { memcpy((void*)(lpID->idEntries + i),(void*)(lpiID->idEntries + i), sizeof(ICONDIRENTRY) - 2); - lpID->idEntries[i].icon.wResId = i; + { memcpy((void*)&(lpID->idEntries[i]),(void*)&(lpiID->idEntries[i]), sizeof(CURSORICONDIRENTRY) - 2); + lpID->idEntries[i].wResId = i; } + *lplpiID = lpiID; - return handle; + return (BYTE *)lpID; } } /* fail */ @@ -199,7 +217,8 @@ HGLOBAL WINAPI ICO_ExtractIconEx(LPCSTR lpszExeFileName, HICON * RetPtr, UINT nI HFILE hFile = OpenFile( lpszExeFileName, &ofs, OF_READ ); UINT16 iconDirCount = 0,iconCount = 0; LPBYTE peimage; - HANDLE fmapping; + HANDLE fmapping; + ULONG uSize; TRACE(shell,"(file %s,start %d,extract %d\n", lpszExeFileName, nIconIndex, n); @@ -210,16 +229,19 @@ HGLOBAL WINAPI ICO_ExtractIconEx(LPCSTR lpszExeFileName, HICON * RetPtr, UINT nI /* ico file */ if( sig==IMAGE_OS2_SIGNATURE || sig==1 ) /* .ICO file */ - { HICON16 hIcon = 0; - NE_TYPEINFO* pTInfo = (NE_TYPEINFO*)(pData + 2); - NE_NAMEINFO* pIconStorage = NULL; - NE_NAMEINFO* pIconDir = NULL; + { BYTE *pCIDir = 0; + NE_TYPEINFO *pTInfo = (NE_TYPEINFO*)(pData + 2); + NE_NAMEINFO *pIconStorage = NULL; + NE_NAMEINFO *pIconDir = NULL; LPicoICONDIR lpiID = NULL; + TRACE(shell,"-- OS2/icon Signature (0x%08lx)\n", sig); + if( pData == (BYTE*)-1 ) - { hIcon = ICO_GetIconDirectory(0, hFile, &lpiID); /* check for .ICO file */ - if( hIcon ) - { iconDirCount = 1; iconCount = lpiID->idCount; + { pCIDir = ICO_GetIconDirectory(hFile, &lpiID, &uSize); /* check for .ICO file */ + if( pCIDir ) + { iconDirCount = 1; iconCount = lpiID->idCount; + TRACE(shell,"-- icon found %p 0x%08lx 0x%08x 0x%08x\n", pCIDir, uSize, iconDirCount, iconCount); } } else while( pTInfo->type_id && !(pIconStorage && pIconDir) ) @@ -248,26 +270,26 @@ HGLOBAL WINAPI ICO_ExtractIconEx(LPCSTR lpszExeFileName, HICON * RetPtr, UINT nI for( i = nIconIndex; i < nIconIndex + n; i++ ) { /* .ICO files have only one icon directory */ - if( lpiID == NULL ) - hIcon = SHELL_LoadResource( 0, hFile, pIconDir + i, *(WORD*)pData ); - RetPtr[i-nIconIndex] = GetIconID16( hIcon, 3 ); - GlobalFree16(hIcon); - } + if( lpiID == NULL ) /* *.ico */ + pCIDir = SHELL_LoadResource( hFile, pIconDir + i, *(WORD*)pData, &uSize ); + RetPtr[i-nIconIndex] = pLookupIconIdFromDirectoryEx( pCIDir, TRUE, SYSMETRICS_CXICON, SYSMETRICS_CYICON, 0); + HeapFree(GetProcessHeap(), 0, pCIDir); + } for( icon = nIconIndex; icon < nIconIndex + n; icon++ ) - { hIcon = 0; + { pCIDir = NULL; if( lpiID ) - { hIcon = ICO_LoadIcon( 0, hFile, lpiID->idEntries + RetPtr[icon-nIconIndex]); + { pCIDir = ICO_LoadIcon( hFile, lpiID->idEntries + RetPtr[icon-nIconIndex], &uSize); } else { for( i = 0; i < iconCount; i++ ) { if( pIconStorage[i].id == (RetPtr[icon-nIconIndex] | 0x8000) ) - { hIcon = SHELL_LoadResource( 0, hFile, pIconStorage + i,*(WORD*)pData ); + { pCIDir = SHELL_LoadResource( hFile, pIconStorage + i,*(WORD*)pData, &uSize ); } } } - if( hIcon ) - { RetPtr[icon-nIconIndex] = LoadIconHandler16( hIcon, TRUE ); + if( pCIDir ) + { RetPtr[icon-nIconIndex] = (HICON) pCreateIconFromResourceEx(pCIDir,uSize,TRUE,0x00030000, cxDesired, cyDesired, LR_DEFAULTCOLOR); } else { RetPtr[icon-nIconIndex] = 0; @@ -427,9 +449,11 @@ HDPA hdpa=0; #define INVALID_INDEX -1 typedef struct -{ LPCSTR sSourceFile; /* file icon is from */ - DWORD dwSourceIndex; /* index within the file */ +{ LPCSTR sSourceFile; /* file (not path!) containing the icon */ + DWORD dwSourceIndex; /* index within the file, if it is a resoure ID it will be negated */ DWORD dwListIndex; /* index within the iconlist */ + DWORD dwFlags; /* GIL_* flags */ + DWORD dwAccessTime; } SIC_ENTRY, * LPSIC_ENTRY; /***************************************************************************** @@ -463,7 +487,7 @@ static INT SIC_IconAppend (LPCSTR sSourceFile, INT dwSourceIndex, HICON hSmallIc lpsice = (LPSIC_ENTRY) SHAlloc (sizeof (SIC_ENTRY)); - lpsice->sSourceFile = HEAP_strdupA (GetProcessHeap(),0,sSourceFile); + lpsice->sSourceFile = HEAP_strdupA (GetProcessHeap(), 0, PathFindFilenameA(sSourceFile)); lpsice->dwSourceIndex = dwSourceIndex; index = pDPA_InsertPtr(hdpa, 0x7fff, lpsice); @@ -506,6 +530,10 @@ static INT SIC_LoadIcon (LPCSTR sSourceFile, INT dwSourceIndex) /***************************************************************************** * SIC_GetIconIndex [internal] * + * Parameters + * sSourceFile [IN] filename of file containing the icon + * index [IN] index/resID (negated) in this file + * * NOTES * look in the cache for a proper icon. if not available the icon is taken * from the file and cached @@ -516,7 +544,7 @@ INT SIC_GetIconIndex (LPCSTR sSourceFile, INT dwSourceIndex ) TRACE(shell,"%s %i\n", sSourceFile, dwSourceIndex); - sice.sSourceFile = sSourceFile; + sice.sSourceFile = PathFindFilenameA(sSourceFile); sice.dwSourceIndex = dwSourceIndex; if (NULL != pDPA_GetPtr (hdpa, 0)) @@ -563,13 +591,13 @@ BOOL SIC_Initialize(void) HGLOBAL hSmRet, hLgRet; HICON *pSmRet, *pLgRet; UINT index; - + TRACE(shell,"\n"); if (hdpa) /* already initialized?*/ return TRUE; - hdpa = pDPA_Create(16); + hdpa = pDPA_Create(16); if (!hdpa) { return(FALSE); @@ -621,8 +649,8 @@ void SIC_Destroy(void) int i; if (hdpa && NULL != pDPA_GetPtr (hdpa, 0)) - { for (i=0; i < DPA_GetPtrCount(hdpa); ++i) - { lpsice = DPA_GetPtr(hdpa, i); + { for (i=0; i < pDPA_GetPtrCount(hdpa); ++i) + { lpsice = pDPA_GetPtr(hdpa, i); SHFree(lpsice); } pDPA_Destroy(hdpa); @@ -635,7 +663,7 @@ void SIC_Destroy(void) * imglist[1|2] [OUT] pointer which recive imagelist handles * */ -DWORD WINAPI Shell_GetImageList(HIMAGELIST * lpBigList, HIMAGELIST * lpSmallList) +BOOL WINAPI Shell_GetImageList(HIMAGELIST * lpBigList, HIMAGELIST * lpSmallList) { TRACE(shell,"(%p,%p)\n",lpBigList,lpSmallList); if (lpBigList) { *lpBigList = ShellBigIconList; @@ -646,89 +674,87 @@ DWORD WINAPI Shell_GetImageList(HIMAGELIST * lpBigList, HIMAGELIST * lpSmallList return TRUE; } +/************************************************************************* + * PidlToSicIndex [INTERNAL] + * + * PARAMETERS + * sh [IN] IShellFolder + * pidl [IN] + * bBigIcon [IN] + * pIndex [OUT] index within the SIC + * + */ +BOOL PidlToSicIndex (IShellFolder * sh, LPITEMIDLIST pidl, BOOL bBigIcon, UINT * pIndex) +{ + IExtractIcon *ei; + char szIconFile[MAX_PATH]; /* file containing the icon */ + INT iSourceIndex; /* index or resID(negated) in this file */ + BOOL ret = FALSE; + UINT dwFlags = 0; + + if (SUCCEEDED (IShellFolder_GetUIObjectOf(sh, 0, 1, &pidl, &IID_IExtractIconA, 0, (void **)&ei))) + { + if (SUCCEEDED (IExtractIconA_GetIconLocation(ei, 0, szIconFile, MAX_PATH, &iSourceIndex, &dwFlags))) + { *pIndex = SIC_GetIconIndex(szIconFile, iSourceIndex); + ret = TRUE; + } + IExtractIconA_Release(ei); + } + + if (INVALID_INDEX == *pIndex) /* default icon when failed */ + *pIndex = 1; + + return ret; + +} /************************************************************************* * SHMapPIDLToSystemImageListIndex [SHELL32.77] * * PARAMETERS - * x pointer to an instance of IShellFolder - * - * NOTES - * calls Release on the ShellFolder - * FIXME: should get the icon by calling GetUIObjectOf(sh) + * sh [IN] pointer to an instance of IShellFolder + * pidl [IN] + * pIndex [OUT][OPTIONAL] SIC index for big icon * */ -DWORD WINAPI SHMapPIDLToSystemImageListIndex(LPSHELLFOLDER sh,LPITEMIDLIST pidl,DWORD z) -{ char sTemp[MAX_PATH]; - DWORD dwNr, ret = INVALID_INDEX; - LPITEMIDLIST pidltemp = ILFindLastID(pidl); +UINT WINAPI SHMapPIDLToSystemImageListIndex(LPSHELLFOLDER sh, LPITEMIDLIST pidl, UINT * pIndex) +{ + UINT Index; - WARN(shell,"(SF=%p,pidl=%p,0x%08lx)\n",sh,pidl,z); + WARN(shell,"(SF=%p,pidl=%p,%p)\n",sh,pidl,index); pdump(pidl); - -/* if (sh) - IShellFolder_Release(sh); -*/ - if (_ILIsDesktop(pidltemp)) - { return 34; - } - else if (_ILIsMyComputer(pidltemp)) - { if (HCR_GetDefaultIcon("CLSID\\{20D04FE0-3AEA-1069-A2D8-08002B30309D}", sTemp, MAX_PATH, &dwNr)) - { ret = SIC_GetIconIndex(sTemp, dwNr); - return (( INVALID_INDEX == ret) ? 15 : ret); - } - } - else if (_ILIsDrive (pidltemp)) - { if (HCR_GetDefaultIcon("Drive", sTemp, MAX_PATH, &dwNr)) - { ret = SIC_GetIconIndex(sTemp, dwNr); - return (( INVALID_INDEX == ret) ? 8 : ret); - } - } - else if (_ILIsFolder (pidltemp)) - { if (HCR_GetDefaultIcon("Folder", sTemp, MAX_PATH, &dwNr)) - { ret = SIC_GetIconIndex(sTemp, dwNr); - return (( INVALID_INDEX == ret) ? 3 : ret); - } - } - - if (_ILGetExtension (pidltemp, sTemp, MAX_PATH)) /* object is file */ - { if ( HCR_MapTypeToValue(sTemp, sTemp, MAX_PATH)) - { if (HCR_GetDefaultIcon(sTemp, sTemp, MAX_PATH, &dwNr)) - { if (!strcmp("%1",sTemp)) /* icon is in the file */ - { _ILGetPidlPath(pidl, sTemp, MAX_PATH); - dwNr = 0; - } - ret = SIC_GetIconIndex(sTemp, dwNr); - } - } - } - return (( INVALID_INDEX == ret) ? 1 : ret); + + if (pIndex) + PidlToSicIndex ( sh, pidl, 1, pIndex); + PidlToSicIndex ( sh, pidl, 0, &Index); + return Index; } /************************************************************************* * Shell_GetCachedImageIndex [SHELL32.72] * */ -INT WINAPI Shell_GetCachedImageIndexA(LPCSTR szPath, INT nIndex, DWORD z) -{ WARN(shell,"(%s,%08x,%08lx) semi-stub.\n",debugstr_a(szPath),nIndex,z); +INT WINAPI Shell_GetCachedImageIndexA(LPCSTR szPath, INT nIndex, BOOL bSimulateDoc) +{ + WARN(shell,"(%s,%08x,%08x) semi-stub.\n",debugstr_a(szPath), nIndex, bSimulateDoc); return SIC_GetIconIndex(szPath, nIndex); } -INT WINAPI Shell_GetCachedImageIndexW(LPCWSTR szPath, INT nIndex, DWORD z) +INT WINAPI Shell_GetCachedImageIndexW(LPCWSTR szPath, INT nIndex, BOOL bSimulateDoc) { INT ret; - LPSTR sTemp = HEAP_strdupWtoA (GetProcessHeap(),0,szPath); + LPSTR sTemp = HEAP_strdupWtoA (GetProcessHeap(),0,szPath); - WARN(shell,"(%s,%08x,%08lx) semi-stub.\n",debugstr_w(szPath),nIndex,z); + WARN(shell,"(%s,%08x,%08x) semi-stub.\n",debugstr_w(szPath), nIndex, bSimulateDoc); ret = SIC_GetIconIndex(sTemp, nIndex); HeapFree(GetProcessHeap(),0,sTemp); - return ret; + return ret; } -INT WINAPI Shell_GetCachedImageIndexAW(LPCVOID szPath, INT nIndex, DWORD z) +INT WINAPI Shell_GetCachedImageIndexAW(LPCVOID szPath, INT nIndex, BOOL bSimulateDoc) { if( VERSION_OsIsUnicode()) - return Shell_GetCachedImageIndexW(szPath, nIndex, z); - return Shell_GetCachedImageIndexA(szPath, nIndex, z); + return Shell_GetCachedImageIndexW(szPath, nIndex, bSimulateDoc); + return Shell_GetCachedImageIndexA(szPath, nIndex, bSimulateDoc); } /************************************************************************* diff --git a/dlls/shell32/shell32_main.c b/dlls/shell32/shell32_main.c index 05bdb201df5..3bfd339a51d 100644 --- a/dlls/shell32/shell32_main.c +++ b/dlls/shell32/shell32_main.c @@ -219,10 +219,14 @@ DWORD WINAPI SHGetFileInfoA(LPCSTR path,DWORD dwFileAttributes, } if (flags & SHGFI_SYSICONINDEX) - { if (!pPidlTemp) + { IShellFolder * sf; + if (!pPidlTemp) { pPidlTemp = ILCreateFromPathA (szTemp); } - psfi->iIcon = SHMapPIDLToSystemImageListIndex (NULL, pPidlTemp, 0); + if (SUCCEEDED (SHGetDesktopFolder (&sf))) + { psfi->iIcon = SHMapPIDLToSystemImageListIndex (sf, pPidlTemp, 0); + IShellFolder_Release(sf); + } TRACE(shell,"-- SYSICONINDEX %i\n", psfi->iIcon); if (flags & SHGFI_SMALLICON) @@ -401,30 +405,30 @@ UINT WINAPI SHAppBarMessage(DWORD msg, PAPPBARDATA data) LPSHELLFOLDER pdesktopfolder=NULL; DWORD WINAPI SHGetDesktopFolder(LPSHELLFOLDER *shellfolder) -{ HRESULT hres = E_OUTOFMEMORY; - LPCLASSFACTORY lpclf; +{ HRESULT hres = E_OUTOFMEMORY; + LPCLASSFACTORY lpclf; TRACE(shell,"%p->(%p)\n",shellfolder,*shellfolder); - if (pdesktopfolder) { - hres = NOERROR; - } else { - lpclf = IClassFactory_Constructor(); - /* fixme: the buildin IClassFactory_Constructor is at the moment only - for rclsid=CLSID_ShellDesktop, so we get the right Interface (jsch)*/ - if(lpclf) { - hres = IClassFactory_CreateInstance(lpclf,NULL,(REFIID)&IID_IShellFolder, (void*)&pdesktopfolder); - IClassFactory_Release(lpclf); + if (pdesktopfolder) + { hres = NOERROR; + } + else + { lpclf = IClassFactory_Constructor(); + if(lpclf) + { hres = IClassFactory_CreateInstance(lpclf,NULL,(REFIID)&IID_IShellFolder, (void*)&pdesktopfolder); + IClassFactory_Release(lpclf); } - } + } - if (pdesktopfolder) { - *shellfolder = pdesktopfolder; - pdesktopfolder->lpvtbl->fnAddRef(pdesktopfolder); - } else { - *shellfolder=NULL; + if (pdesktopfolder) + { *shellfolder = pdesktopfolder; + IShellFolder_AddRef(pdesktopfolder); + } + else + { *shellfolder=NULL; } - TRACE(shell,"-- %p->(%p)\n",shellfolder, *shellfolder); + TRACE(shell,"-- %p->(%p)\n",shellfolder, *shellfolder); return hres; } @@ -1044,6 +1048,7 @@ void (WINAPI* pDLLInitComctl)(LPVOID); INT (WINAPI* pImageList_AddIcon) (HIMAGELIST himl, HICON hIcon); INT (WINAPI* pImageList_ReplaceIcon) (HIMAGELIST, INT, HICON); HIMAGELIST (WINAPI * pImageList_Create) (INT,INT,UINT,INT,INT); +BOOL (WINAPI* pImageList_Draw) (HIMAGELIST himl, int i, HDC hdcDest, int x, int y, UINT fStyle); HICON (WINAPI * pImageList_GetIcon) (HIMAGELIST, INT, UINT); INT (WINAPI* pImageList_GetImageCount)(HIMAGELIST); @@ -1056,6 +1061,7 @@ BOOL (WINAPI* pDPA_Sort) (const HDPA, PFNDPACOMPARE, LPARAM); LPVOID (WINAPI* pDPA_GetPtr) (const HDPA, INT); BOOL (WINAPI* pDPA_Destroy) (const HDPA); INT (WINAPI *pDPA_Search) (const HDPA, LPVOID, INT, PFNDPACOMPARE, LPARAM, UINT); +LPVOID (WINAPI *pDPA_DeletePtr) (const HDPA hdpa, INT i); /* user32 */ HICON (WINAPI *pLookupIconIdFromDirectoryEx)(LPBYTE dir, BOOL bIcon, INT width, INT height, UINT cFlag); @@ -1078,7 +1084,7 @@ BOOL WINAPI Shell32LibMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) TRACE(shell,"0x%x 0x%lx %p\n", hinstDLL, fdwReason, fImpLoad); shell32_hInstance = hinstDLL; - + switch (fdwReason) { case DLL_PROCESS_ATTACH: if (!bShell32IsInitialized) @@ -1094,6 +1100,7 @@ BOOL WINAPI Shell32LibMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) pImageList_ReplaceIcon=(void*)GetProcAddress(hComctl32,"ImageList_ReplaceIcon"); pImageList_GetIcon=(void*)GetProcAddress(hComctl32,"ImageList_GetIcon"); pImageList_GetImageCount=(void*)GetProcAddress(hComctl32,"ImageList_GetImageCount"); + pImageList_Draw=(void*)GetProcAddress(hComctl32,"ImageList_Draw"); /* imports by ordinal, pray that it works*/ pCOMCTL32_Alloc=(void*)GetProcAddress(hComctl32, (LPCSTR)71L); @@ -1102,6 +1109,7 @@ BOOL WINAPI Shell32LibMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) pDPA_Destroy=(void*)GetProcAddress(hComctl32, (LPCSTR)329L); pDPA_GetPtr=(void*)GetProcAddress(hComctl32, (LPCSTR)332L); pDPA_InsertPtr=(void*)GetProcAddress(hComctl32, (LPCSTR)334L); + pDPA_DeletePtr=(void*)GetProcAddress(hComctl32, (LPCSTR)336L); pDPA_Sort=(void*)GetProcAddress(hComctl32, (LPCSTR)338L); pDPA_Search=(void*)GetProcAddress(hComctl32, (LPCSTR)339L); /* user32 */ diff --git a/dlls/shell32/shell32_main.h b/dlls/shell32/shell32_main.h index 5416d9ca467..45f14499eb8 100644 --- a/dlls/shell32/shell32_main.h +++ b/dlls/shell32/shell32_main.h @@ -8,6 +8,7 @@ #include "imagelist.h" #include "commctrl.h" #include "shell.h" +#include "docobj.h" #include "wine/obj_shellfolder.h" #include "wine/obj_dataobject.h" @@ -31,6 +32,7 @@ extern void (WINAPI* pDLLInitComctl)(LPVOID); extern INT (WINAPI* pImageList_AddIcon) (HIMAGELIST himl, HICON hIcon); extern INT (WINAPI* pImageList_ReplaceIcon) (HIMAGELIST, INT, HICON); extern HIMAGELIST (WINAPI* pImageList_Create) (INT,INT,UINT,INT,INT); +extern BOOL (WINAPI* pImageList_Draw) (HIMAGELIST himl, int i, HDC hdcDest, int x, int y, UINT fStyle); extern HICON (WINAPI* pImageList_GetIcon) (HIMAGELIST, INT, UINT); extern INT (WINAPI* pImageList_GetImageCount)(HIMAGELIST); @@ -43,6 +45,8 @@ extern BOOL (WINAPI* pDPA_Sort) (const HDPA, PFNDPACOMPARE, LPARAM); extern LPVOID (WINAPI* pDPA_GetPtr) (const HDPA, INT); extern BOOL (WINAPI* pDPA_Destroy) (const HDPA); extern INT (WINAPI* pDPA_Search) (const HDPA, LPVOID, INT, PFNDPACOMPARE, LPARAM, UINT); +extern LPVOID (WINAPI* pDPA_DeletePtr) (const HDPA hdpa, INT i); +#define pDPA_GetPtrCount(hdpa) (*(INT*)(hdpa)) extern HICON (WINAPI *pLookupIconIdFromDirectoryEx)(LPBYTE dir, BOOL bIcon, INT width, INT height, UINT cFlag); extern HICON (WINAPI *pCreateIconFromResourceEx)(LPBYTE bits,UINT cbSize, BOOL bIcon, DWORD dwVersion, INT width, INT height,UINT cFlag); @@ -63,7 +67,7 @@ LPITEMIDLIST WINAPI ILCreateFromPathA(LPSTR path); LPITEMIDLIST WINAPI ILCreateFromPathW(LPWSTR path); LPITEMIDLIST WINAPI ILCreateFromPathAW(LPVOID path); -DWORD WINAPI Shell_GetImageList(HIMAGELIST * lpBigList, HIMAGELIST * lpSmallList); +BOOL WINAPI Shell_GetImageList(HIMAGELIST * lpBigList, HIMAGELIST * lpSmallList); HRESULT WINAPI StrRetToStrN (LPVOID dest, DWORD len, LPSTRRET src, LPITEMIDLIST pidl); /* Iconcache */ diff --git a/include/shlobj.h b/include/shlobj.h index 0f4c870e186..b93dbf16049 100644 --- a/include/shlobj.h +++ b/include/shlobj.h @@ -113,7 +113,7 @@ extern void IDLList_Destructor(LPIDLLIST me); typedef GUID SHELLVIEWID; #define SV_CLASS_NAME ("SHELLDLL_DefView") -DWORD WINAPI SHMapPIDLToSystemImageListIndex(LPSHELLFOLDER sh,LPITEMIDLIST pidl,DWORD z); +UINT WINAPI SHMapPIDLToSystemImageListIndex(LPSHELLFOLDER sh, LPITEMIDLIST pidl, UINT * pIndex); /**************************************************************************** * IShellIcon interface