- reorganised icon extracing from files

- made extracting from ne and ico files working
- IPersistFile interface for IExtractIcon
This commit is contained in:
Juergen Schmied 1999-04-11 11:50:41 +00:00 committed by Alexandre Julliard
parent a9e93b35cf
commit d00653237b
5 changed files with 353 additions and 163 deletions

View File

@ -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);
*piIndex = (int) SHMapPIDLToSystemImageListIndex(0, This->pidl,0);
*pwFlags = GIL_NOTFILENAME;
TRACE (shell,"(%p) (flags=%u %p %u %p %p)\n", This, uFlags, szIconFile, cchMax, piIndex, pwFlags);
WARN (shell,"-- %x\n",*piIndex);
if (pwFlags)
*pwFlags = 0;
return NOERROR;
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;
}
}
}
}
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 */
};

View File

@ -1,8 +1,6 @@
/*
* shell icon cache (SIC)
*
* FIXME
* since dll geting never unloaded the iconcache will never be freed
*/
#include <string.h>
#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 )
{ 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))
@ -569,7 +597,7 @@ BOOL SIC_Initialize(void)
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);
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);
}
/*************************************************************************

View File

@ -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;
}
TRACE(shell,"-- %p->(%p)\n",shellfolder, *shellfolder);
if (pdesktopfolder)
{ *shellfolder = pdesktopfolder;
IShellFolder_AddRef(pdesktopfolder);
}
else
{ *shellfolder=NULL;
}
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);
@ -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 */

View File

@ -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 */

View File

@ -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