Skip to content
Snippets Groups Projects
Commit 255bf171 authored by Juergen Schmied's avatar Juergen Schmied Committed by Alexandre Julliard
Browse files

New file, some helper functions for icon cache.

Implemented ExtractIconEx; moved SHMapPIDLToSystemImageListIndex,
Shell_GetImageList in this file.
parent 62c4f3d0
No related branches found
No related tags found
No related merge requests found
/*
* shell icon cache (SIC)
*
*
*/
#include <string.h>
#include "windows.h"
#include "neexe.h"
#include "cursoricon.h"
#include "module.h"
#include "heap.h"
#include "debug.h"
#include "sysmetrics.h"
#include "winversion.h"
#include "shell.h"
#include "shlobj.h"
#include "pidl.h"
#include "shell32_main.h"
#pragma pack(1)
typedef struct
{
BYTE bWidth; /* Width, in pixels, of the image */
BYTE bHeight; /* Height, in pixels, of the image */
BYTE bColorCount; /* Number of colors in image (0 if >=8bpp) */
BYTE bReserved; /* Reserved ( must be 0) */
WORD wPlanes; /* Color Planes */
WORD wBitCount; /* Bits per pixel */
DWORD dwBytesInRes; /* How many bytes in this resource? */
DWORD dwImageOffset; /* Where in the file is this image? */
} icoICONDIRENTRY, *LPicoICONDIRENTRY;
typedef struct
{
WORD idReserved; /* Reserved (must be 0) */
WORD idType; /* Resource Type (1 for icons) */
WORD idCount; /* How many images? */
icoICONDIRENTRY idEntries[1]; /* An entry for each image (idCount of 'em) */
} icoICONDIR, *LPicoICONDIR;
#pragma pack(4)
/*************************************************************************
* SHELL_GetResourceTable
*/
static DWORD SHELL_GetResourceTable(HFILE32 hFile,LPBYTE *retptr)
{ IMAGE_DOS_HEADER mz_header;
char magic[4];
int size;
TRACE(shell,"\n");
*retptr = NULL;
_llseek32( hFile, 0, SEEK_SET );
if ((_lread32(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) || (mz_header.e_magic != IMAGE_DOS_SIGNATURE))
{ if (mz_header.e_cblp == 1) /* .ICO file ? */
{ *retptr = (LPBYTE)-1; /* ICONHEADER.idType, must be 1 */
return 1;
}
else
return 0; /* failed */
}
_llseek32( hFile, mz_header.e_lfanew, SEEK_SET );
if (_lread32( hFile, magic, sizeof(magic) ) != sizeof(magic))
return 0;
_llseek32( hFile, mz_header.e_lfanew, SEEK_SET);
if (*(DWORD*)magic == IMAGE_NT_SIGNATURE)
return IMAGE_NT_SIGNATURE;
if (*(WORD*)magic == IMAGE_OS2_SIGNATURE)
{ IMAGE_OS2_HEADER ne_header;
LPBYTE pTypeInfo = (LPBYTE)-1;
if (_lread32(hFile,&ne_header,sizeof(ne_header))!=sizeof(ne_header))
return 0;
if (ne_header.ne_magic != IMAGE_OS2_SIGNATURE)
return 0;
size = ne_header.rname_tab_offset - ne_header.resource_tab_offset;
if( size > sizeof(NE_TYPEINFO) )
{ pTypeInfo = (BYTE*)HeapAlloc( GetProcessHeap(), 0, size);
if( pTypeInfo )
{ _llseek32(hFile, mz_header.e_lfanew+ne_header.resource_tab_offset, SEEK_SET);
if( _lread32( hFile, (char*)pTypeInfo, size) != size )
{ HeapFree( GetProcessHeap(), 0, pTypeInfo);
pTypeInfo = NULL;
}
}
}
*retptr = pTypeInfo;
return IMAGE_OS2_SIGNATURE;
}
return 0; /* failed */
}
/*************************************************************************
* SHELL_LoadResource
*/
static HGLOBAL16 SHELL_LoadResource(HINSTANCE32 hInst, HFILE32 hFile, NE_NAMEINFO* pNInfo, WORD sizeShift)
{ BYTE* ptr;
HGLOBAL16 handle = DirectResAlloc( hInst, 0x10, (DWORD)pNInfo->length << sizeShift);
TRACE(shell,"\n");
if( (ptr = (BYTE*)GlobalLock16( handle )) )
{ _llseek32( hFile, (DWORD)pNInfo->offset << sizeShift, SEEK_SET);
_lread32( hFile, (char*)ptr, pNInfo->length << sizeShift);
return handle;
}
return 0;
}
/*************************************************************************
* ICO_LoadIcon
*/
static HGLOBAL16 ICO_LoadIcon(HINSTANCE32 hInst, HFILE32 hFile, LPicoICONDIRENTRY lpiIDE)
{ BYTE* ptr;
HGLOBAL16 handle = DirectResAlloc( hInst, 0x10, lpiIDE->dwBytesInRes);
TRACE(shell,"\n");
if( (ptr = (BYTE*)GlobalLock16( handle )) )
{ _llseek32( hFile, lpiIDE->dwImageOffset, SEEK_SET);
_lread32( hFile, (char*)ptr, lpiIDE->dwBytesInRes);
return handle;
}
return 0;
}
/*************************************************************************
* ICO_GetIconDirectory
*
* Read .ico file and build phony ICONDIR struct for GetIconID
*/
static HGLOBAL16 ICO_GetIconDirectory(HINSTANCE32 hInst, HFILE32 hFile, LPicoICONDIR* lplpiID )
{ WORD id[3]; /* idReserved, idType, idCount */
LPicoICONDIR lpiID;
int i;
TRACE(shell,"\n");
_llseek32( hFile, 0, SEEK_SET );
if( _lread32(hFile,(char*)id,sizeof(id)) != sizeof(id) )
return 0;
/* check .ICO header
*
* - see http://www.microsoft.com/win32dev/ui/icons.htm
*/
if( id[0] || id[1] != 1 || !id[2] )
return 0;
i = id[2]*sizeof(icoICONDIRENTRY) + sizeof(id);
lpiID = (LPicoICONDIR)HeapAlloc( GetProcessHeap(), 0, i);
if( _lread32(hFile,(char*)lpiID->idEntries,i) == i )
{ HGLOBAL16 handle = DirectResAlloc( 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];
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;
}
*lplpiID = lpiID;
return handle;
}
}
/* fail */
HeapFree( GetProcessHeap(), 0, lpiID);
return 0;
}
/*************************************************************************
* InternalExtractIcon [SHELL.39]
*
* This abortion is called directly by Progman
* fixme: the icon section is broken (don't have a handle for
* ICO_GetIconDirectory....)
*
*/
#define ICO_INVALID_FILE 1
#define ICO_NO_ICONS 0
HGLOBAL32 WINAPI ICO_ExtractIconEx(LPCSTR lpszExeFileName, HICON32* RetPtr, UINT32 nIconIndex, UINT32 n, UINT32 cxDesired, UINT32 cyDesired )
{ HGLOBAL32 hRet = ICO_NO_ICONS;
LPBYTE pData;
OFSTRUCT ofs;
DWORD sig;
HFILE32 hFile = OpenFile32( lpszExeFileName, &ofs, OF_READ );
UINT16 iconDirCount = 0,iconCount = 0;
LPBYTE peimage;
HANDLE32 fmapping;
TRACE(shell,"(file %s,start %d,extract %d\n", lpszExeFileName, nIconIndex, n);
if( hFile == HFILE_ERROR32 || !n )
return ICO_INVALID_FILE;
sig = SHELL_GetResourceTable(hFile,&pData);
/* 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;
LPicoICONDIR lpiID = NULL;
if( pData == (BYTE*)-1 )
{ hIcon = ICO_GetIconDirectory(0, hFile, &lpiID); /* check for .ICO file */
if( hIcon )
{ iconDirCount = 1; iconCount = lpiID->idCount;
}
}
else while( pTInfo->type_id && !(pIconStorage && pIconDir) )
{ if( pTInfo->type_id == NE_RSCTYPE_GROUP_ICON ) /* find icon directory and icon repository */
{ iconDirCount = pTInfo->count;
pIconDir = ((NE_NAMEINFO*)(pTInfo + 1));
TRACE(shell,"\tfound directory - %i icon families\n", iconDirCount);
}
if( pTInfo->type_id == NE_RSCTYPE_ICON )
{ iconCount = pTInfo->count;
pIconStorage = ((NE_NAMEINFO*)(pTInfo + 1));
TRACE(shell,"\ttotal icons - %i\n", iconCount);
}
pTInfo = (NE_TYPEINFO *)((char*)(pTInfo+1)+pTInfo->count*sizeof(NE_NAMEINFO));
}
if( (pIconStorage && pIconDir) || lpiID ) /* load resources and create icons */
{ if( nIconIndex == (UINT16)-1 )
{ RetPtr[0] = iconDirCount;
}
else if( nIconIndex < iconDirCount )
{ UINT16 i, icon;
if( n > iconDirCount - nIconIndex )
n = iconDirCount - nIconIndex;
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] = GetIconID( hIcon, 3 );
GlobalFree16(hIcon);
}
for( icon = nIconIndex; icon < nIconIndex + n; icon++ )
{ hIcon = 0;
if( lpiID )
{ hIcon = ICO_LoadIcon( 0, hFile, lpiID->idEntries + RetPtr[icon-nIconIndex]);
}
else
{ for( i = 0; i < iconCount; i++ )
{ if( pIconStorage[i].id == (RetPtr[icon-nIconIndex] | 0x8000) )
{ hIcon = SHELL_LoadResource( 0, hFile, pIconStorage + i,*(WORD*)pData );
}
}
}
if( hIcon )
{ RetPtr[icon-nIconIndex] = LoadIconHandler( hIcon, TRUE );
}
else
{ RetPtr[icon-nIconIndex] = 0;
}
}
}
}
if( lpiID )
HeapFree( GetProcessHeap(), 0, lpiID);
else
HeapFree( GetProcessHeap(), 0, pData);
}
/* end ico file */
/* exe/dll */
if( sig == IMAGE_NT_SIGNATURE)
{ LPBYTE idata,igdata;
PIMAGE_DOS_HEADER dheader;
PIMAGE_NT_HEADERS pe_header;
PIMAGE_SECTION_HEADER pe_sections;
PIMAGE_RESOURCE_DIRECTORY rootresdir,iconresdir,icongroupresdir;
PIMAGE_RESOURCE_DATA_ENTRY idataent,igdataent;
PIMAGE_RESOURCE_DIRECTORY_ENTRY xresent;
int i,j;
if ( !(fmapping = CreateFileMapping32A(hFile,NULL,PAGE_READONLY|SEC_COMMIT,0,0,NULL)))
{ WARN(shell,"failed to create filemap.\n"); /* FIXME, INVALID_HANDLE_VALUE? */
hRet = ICO_INVALID_FILE;
goto end_2; /* failure */
}
if ( !(peimage = MapViewOfFile(fmapping,FILE_MAP_READ,0,0,0)))
{ WARN(shell,"failed to mmap filemap.\n");
hRet = ICO_INVALID_FILE;
goto end_2; /* failure */
}
dheader = (PIMAGE_DOS_HEADER)peimage;
pe_header = (PIMAGE_NT_HEADERS)(peimage+dheader->e_lfanew); /* it is a pe header, SHELL_GetResourceTable checked that */
pe_sections = (PIMAGE_SECTION_HEADER)(((char*)pe_header)+sizeof(*pe_header)); /* probably makes problems with short PE headers...*/
rootresdir = NULL;
for (i=0;i<pe_header->FileHeader.NumberOfSections;i++)
{ if (pe_sections[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
continue;
/* FIXME: doesn't work when the resources are not in a seperate section */
if (pe_sections[i].VirtualAddress == pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress)
{ rootresdir = (PIMAGE_RESOURCE_DIRECTORY)((char*)peimage+pe_sections[i].PointerToRawData);
break;
}
}
if (!rootresdir)
{ WARN(shell,"haven't found section for resource directory.\n");
goto end_4; /* failure */
}
/* search the group icon dir*/
if (!(icongroupresdir = GetResDirEntryW(rootresdir,RT_GROUP_ICON32W, (DWORD)rootresdir,FALSE)))
{ WARN(shell,"No Icongroupresourcedirectory!\n");
goto end_4; /* failure */
}
iconDirCount = icongroupresdir->NumberOfNamedEntries+icongroupresdir->NumberOfIdEntries;
/* number of icons requested */
if( nIconIndex == -1 )
{ hRet = iconDirCount;
goto end_3; /* success */
}
if (nIconIndex >= iconDirCount)
{ WARN(shell,"nIconIndex %d is larger than iconDirCount %d\n",nIconIndex,iconDirCount);
goto end_4; /* failure */
}
xresent = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(icongroupresdir+1); /* caller just wanted the number of entries */
if( n > iconDirCount - nIconIndex ) /* assure we don't get too much ... */
{ n = iconDirCount - nIconIndex;
}
xresent = xresent+nIconIndex; /* starting from specified index ... */
for (i=0;i<n;i++,xresent++)
{ PIMAGE_RESOURCE_DIRECTORY resdir;
/* go down this resource entry, name */
resdir = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)rootresdir+(xresent->u2.s.OffsetToDirectory));
/* default language (0) */
resdir = GetResDirEntryW(resdir,(LPWSTR)0,(DWORD)rootresdir,TRUE);
igdataent = (PIMAGE_RESOURCE_DATA_ENTRY)resdir;
/* lookup address in mapped image for virtual address */
igdata = NULL;
for (j=0;j<pe_header->FileHeader.NumberOfSections;j++)
{ if (igdataent->OffsetToData < pe_sections[j].VirtualAddress)
continue;
if (igdataent->OffsetToData+igdataent->Size > pe_sections[j].VirtualAddress+pe_sections[j].SizeOfRawData)
continue;
igdata = peimage+(igdataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData);
}
if (!igdata)
{ WARN(shell,"no matching real address for icongroup!\n");
goto end_4; /* failure */
}
RetPtr[i] = LookupIconIdFromDirectoryEx32(igdata, TRUE, cxDesired, cyDesired, LR_DEFAULTCOLOR);
}
if (!(iconresdir=GetResDirEntryW(rootresdir,RT_ICON32W,(DWORD)rootresdir,FALSE)))
{ WARN(shell,"No Iconresourcedirectory!\n");
goto end_4; /* failure */
}
for (i=0;i<n;i++)
{ PIMAGE_RESOURCE_DIRECTORY xresdir;
xresdir = GetResDirEntryW(iconresdir,(LPWSTR)(DWORD)RetPtr[i],(DWORD)rootresdir,FALSE);
xresdir = GetResDirEntryW(xresdir,(LPWSTR)0,(DWORD)rootresdir,TRUE);
idataent = (PIMAGE_RESOURCE_DATA_ENTRY)xresdir;
idata = NULL;
/* map virtual to address in image */
for (j=0;j<pe_header->FileHeader.NumberOfSections;j++)
{ if (idataent->OffsetToData < pe_sections[j].VirtualAddress)
continue;
if (idataent->OffsetToData+idataent->Size > pe_sections[j].VirtualAddress+pe_sections[j].SizeOfRawData)
continue;
idata = peimage+(idataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData);
}
if (!idata)
{ WARN(shell,"no matching real address found for icondata!\n");
RetPtr[i]=0;
continue;
}
RetPtr[i] = CreateIconFromResourceEx32(idata,idataent->Size,TRUE,0x00030000, cxDesired, cyDesired, LR_DEFAULTCOLOR);
}
hRet = RetPtr[0]; /* return first icon */
goto end_3; /* sucess */
}
hRet = ICO_INVALID_FILE;
goto end_1; /* unknown filetype */
/* cleaning up (try & catch would be nicer:-) ) */
end_4: hRet = 0; /* failure */
end_3: UnmapViewOfFile(peimage); /* success */
end_2: CloseHandle(fmapping);
end_1: _lclose32( hFile);
return hRet;
}
/********************** THE ICON CACHE ********************************/
HIMAGELIST ShellSmallIconList = 0;
HIMAGELIST ShellBigIconList = 0;
HDPA hdpa=0;
typedef struct
{ LPSTR sSourceFile; /* file icon is from */
DWORD dwSourceIndex; /* index within the file */
DWORD dwListIndex; /* index within the iconlist */
} SIC_ENTRY, * LPSIC_ENTRY;
/*****************************************************************************
* SIC_CompareEntrys (internal)
* NOTES
* Callback for DPA_Search
*/
static INT32 SIC_CompareEntrys( LPVOID p1, LPVOID p2, LPARAM lparam)
{ TRACE(shell,"%p %p\n", p1, p2);
if (((LPSIC_ENTRY)p1)->dwSourceIndex != ((LPSIC_ENTRY)p2)->dwSourceIndex) /* first the faster one*/
return 1;
if (strcmp(((LPSIC_ENTRY)p1)->sSourceFile,((LPSIC_ENTRY)p2)->sSourceFile))
return 1;
return 0;
}
/*****************************************************************************
* SIC_Add (internal)
*/
INT32 WINAPI SIC_AddIcon (LPSTR sSourceFile, DWORD dwSourceIndex, HICON32 hSmallIcon, HICON32 hBigIcon)
{ LPSIC_ENTRY lpsice;
INT32 index;
TRACE(shell,"%s %li\n", sSourceFile, dwSourceIndex);
lpsice = (LPSIC_ENTRY) SHAlloc (sizeof (SIC_ENTRY));
lpsice->sSourceFile = HEAP_strdupA (GetProcessHeap(),0,sSourceFile);
lpsice->dwSourceIndex = dwSourceIndex;
/* index = pDPA_Search (hdpa, lpsice, -1, SIC_CompareEntrys, 0, 0);
if ( -1 != index )
{ TRACE(shell, "-- allready inserted\n");
SHFree(lpsice);
return index;
}
*/
index = pDPA_InsertPtr(hdpa, 0x7fff, lpsice);
if ( -1 == index )
{ SHFree(lpsice);
return -1;
}
lpsice->dwListIndex = pImageList_GetImageCount(ShellSmallIconList)+1;
pImageList_AddIcon (ShellSmallIconList, hSmallIcon);
pImageList_AddIcon (ShellBigIconList, hBigIcon);
return index;
}
/*****************************************************************************
* SIC_GetIcon (internal)
* NOTES
* look in the cache for a proper icon. if not available the icon is taken
* from the file and cached
*/
HICON32 WINAPI SIC_GetIcon (LPSTR sSourceFile, DWORD dwSourceIndex, BOOL32 bSmallIcon )
{ LPSIC_ENTRY lpsice;
INT32 index;
HICON32 hSmallIcon, hBigIcon;
TRACE(shell,"%s %li\n", sSourceFile, dwSourceIndex);
lpsice = (LPSIC_ENTRY) SHAlloc (sizeof (SIC_ENTRY));
lpsice->sSourceFile = HEAP_strdupA (GetProcessHeap(),0,sSourceFile);
lpsice->dwSourceIndex = dwSourceIndex;
index = pDPA_Search (hdpa, lpsice, -1, SIC_CompareEntrys, 0, 0);
if ( -1 != index )
{ TRACE(shell, "-- found\n");
SHFree (lpsice);
index = ((LPSIC_ENTRY)pDPA_GetPtr(hdpa, index))->dwListIndex;
if (bSmallIcon)
return pImageList_GetIcon(ShellSmallIconList, index, ILD_NORMAL);
return pImageList_GetIcon(ShellBigIconList, index, ILD_NORMAL);
}
/*
index = pDPA_InsertPtr(hdpa, 0x7fff, lpsice);
if ( -1 == index )
{ SHFree(lpsice);
}
lpsice->hSmallIcon = hSmallIcon;
lpsice->hBigIcon = hBigIcon;
pImageList_AddIcon (ShellSmallIconList, hSmallIcon);
pImageList_AddIcon (ShellBigIconList, hBigIcon);
*/
return 0;
}
/*****************************************************************************
* SIC_Initialize (internal)
* NOTES
* hack to load the resources from the shell32.dll under a different dll name
* will be removed when the resource-compiler is ready
*/
BOOL32 WINAPI SIC_Initialize(void)
{ CHAR szShellPath[MAX_PATH];
HGLOBAL32 hSmRet, hLgRet;
HICON32 *pSmRet, *pLgRet;
UINT32 index;
TRACE(shell,"\n");
if (hdpa) /* already initialized?*/
return TRUE;
hdpa = pDPA_Create(16);
if (!hdpa)
{ return(FALSE);
}
GetWindowsDirectory32A(szShellPath,MAX_PATH);
PathAddBackslash32A(szShellPath);
strcat(szShellPath,"system\\shell32.dll");
hSmRet = GlobalAlloc32( GMEM_FIXED | GMEM_ZEROINIT, sizeof(HICON32)*40);
hLgRet = GlobalAlloc32( GMEM_FIXED | GMEM_ZEROINIT, sizeof(HICON32)*40);
pSmRet = (HICON32*)GlobalLock32(hSmRet);
pLgRet = (HICON32*)GlobalLock32(hLgRet);
ExtractIconEx32A ( szShellPath, 0, pLgRet, pSmRet, 40 );
ShellSmallIconList = pImageList_Create(16,16,ILC_COLORDDB | ILC_MASK,0,0x20);
ShellBigIconList = pImageList_Create(32,32,ILC_COLORDDB | ILC_MASK,0,0x20);
for (index=0; index<40; index++)
{ if (! pSmRet[index] )
{ MSG("*** failure loading resources from %s\n", szShellPath );
MSG("*** this is a hack for loading the internal and external dll at the same time\n");
MSG("*** you can ignore it but you will miss some icons in win95 dialogs\n\n");
break;
}
SIC_AddIcon (szShellPath, index, pSmRet[index], pLgRet[index]);
}
GlobalUnlock32(hLgRet);
GlobalFree32(hLgRet);
GlobalUnlock32(hSmRet);
GlobalFree32(hSmRet);
TRACE(shell,"hIconSmall=%p hIconBig=%p\n",ShellSmallIconList, ShellBigIconList);
return TRUE;
}
/*************************************************************************
* Shell_GetImageList [SHELL32.71]
*
* PARAMETERS
* imglist[1|2] [OUT] pointer which recive imagelist handles
*
*/
DWORD WINAPI Shell_GetImageList(HIMAGELIST * imglist1,HIMAGELIST * imglist2)
{ TRACE(shell,"(%p,%p)\n",imglist1,imglist2);
if (imglist1)
{ *imglist1=ShellBigIconList;
}
if (imglist2)
{ *imglist2=ShellSmallIconList;
}
return TRUE;
}
/*************************************************************************
* SHMapPIDLToSystemImageListIndex [SHELL32.77]
*
* PARAMETERS
* x pointer to an instance of IShellFolder
*
* NOTES
* first hack
*
*/
DWORD WINAPI SHMapPIDLToSystemImageListIndex(LPSHELLFOLDER sh,LPITEMIDLIST pidl,DWORD z)
{ LPITEMIDLIST pidltemp = ILFindLastID(pidl);
FIXME(shell,"(SF=%p,pidl=%p,%08lx):stub.\n",sh,pidl,z);
if (_ILIsMyComputer(pidltemp))
{ return 20;
}
else if (_ILIsDrive (pidltemp))
{ return 8;
}
else if (_ILIsFolder (pidltemp))
{ return 3;
}
else
{ return 1;
}
}
/*************************************************************************
* ExtracticonEx32 [shell32.189]
*/
HICON32 WINAPI ExtractIconEx32AW ( LPVOID lpszFile, INT32 nIconIndex, HICON32 * phiconLarge, HICON32 * phiconSmall, UINT32 nIcons )
{ if (VERSION_OsIsUnicode())
return ExtractIconEx32W ( lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
return ExtractIconEx32A ( lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
}
/*************************************************************************
* ExtracticonEx32A [shell32.190]
* RETURNS
* 0 no icon found
* 1 file is not valid
* HICON32 handle of a icon (phiconLarge/Small == NULL)
*/
HICON32 WINAPI ExtractIconEx32A ( LPSTR lpszFile, INT32 nIconIndex, HICON32 * phiconLarge, HICON32 * phiconSmall, UINT32 nIcons )
{ HICON32 ret=0;
TRACE(shell,"file=%s idx=%i %p %p num=%i\n", lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons );
if (nIconIndex==-1) /* Number of icons requested */
return ICO_ExtractIconEx(lpszFile, NULL, -1, 0, 0, 0 );
if (phiconLarge)
{ ret = ICO_ExtractIconEx(lpszFile, phiconLarge, nIconIndex, nIcons, 32, 32 );
if ( nIcons==1)
{ ret = phiconLarge[0];
}
}
/* if no pointers given and one icon expected, return the handle directly*/
if (!phiconLarge && ! phiconSmall && nIcons==1 )
phiconSmall = &ret;
if (phiconSmall)
{ ret = ICO_ExtractIconEx(lpszFile, phiconSmall, nIconIndex, nIcons, 16, 16 );
if ( nIcons==1 )
{ ret = phiconLarge[0];
}
}
return ret;
}
/*************************************************************************
* ExtracticonEx32W [shell32.191]
*/
HICON32 WINAPI ExtractIconEx32W ( LPWSTR lpszFile, INT32 nIconIndex, HICON32 * phiconLarge, HICON32 * phiconSmall, UINT32 nIcons )
{ LPSTR sFile;
DWORD ret;
TRACE(shell,"file=%s idx=%i %p %p num=%i\n", debugstr_w(lpszFile), nIconIndex, phiconLarge, phiconSmall, nIcons );
sFile = HEAP_strdupWtoA (GetProcessHeap(),0,lpszFile);
ret = ExtractIconEx32A ( sFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
HeapFree(GetProcessHeap(),0,sFile);
return ret;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment