2 * shell icon cache (SIC)
9 #include "cursoricon.h"
13 #include "sysmetrics.h"
14 #include "winversion.h"
18 #include "shell32_main.h"
24 BYTE bWidth
; /* Width, in pixels, of the image */
25 BYTE bHeight
; /* Height, in pixels, of the image */
26 BYTE bColorCount
; /* Number of colors in image (0 if >=8bpp) */
27 BYTE bReserved
; /* Reserved ( must be 0) */
28 WORD wPlanes
; /* Color Planes */
29 WORD wBitCount
; /* Bits per pixel */
30 DWORD dwBytesInRes
; /* How many bytes in this resource? */
31 DWORD dwImageOffset
; /* Where in the file is this image? */
32 } icoICONDIRENTRY
, *LPicoICONDIRENTRY
;
36 WORD idReserved
; /* Reserved (must be 0) */
37 WORD idType
; /* Resource Type (1 for icons) */
38 WORD idCount
; /* How many images? */
39 icoICONDIRENTRY idEntries
[1]; /* An entry for each image (idCount of 'em) */
40 } icoICONDIR
, *LPicoICONDIR
;
44 /*************************************************************************
45 * SHELL_GetResourceTable
47 static DWORD
SHELL_GetResourceTable(HFILE32 hFile
,LPBYTE
*retptr
)
48 { IMAGE_DOS_HEADER mz_header
;
55 _llseek32( hFile
, 0, SEEK_SET
);
56 if ((_lread32(hFile
,&mz_header
,sizeof(mz_header
)) != sizeof(mz_header
)) || (mz_header
.e_magic
!= IMAGE_DOS_SIGNATURE
))
57 { if (mz_header
.e_cblp
== 1) /* .ICO file ? */
58 { *retptr
= (LPBYTE
)-1; /* ICONHEADER.idType, must be 1 */
62 return 0; /* failed */
64 _llseek32( hFile
, mz_header
.e_lfanew
, SEEK_SET
);
66 if (_lread32( hFile
, magic
, sizeof(magic
) ) != sizeof(magic
))
69 _llseek32( hFile
, mz_header
.e_lfanew
, SEEK_SET
);
71 if (*(DWORD
*)magic
== IMAGE_NT_SIGNATURE
)
72 return IMAGE_NT_SIGNATURE
;
74 if (*(WORD
*)magic
== IMAGE_OS2_SIGNATURE
)
75 { IMAGE_OS2_HEADER ne_header
;
76 LPBYTE pTypeInfo
= (LPBYTE
)-1;
78 if (_lread32(hFile
,&ne_header
,sizeof(ne_header
))!=sizeof(ne_header
))
81 if (ne_header
.ne_magic
!= IMAGE_OS2_SIGNATURE
)
84 size
= ne_header
.rname_tab_offset
- ne_header
.resource_tab_offset
;
86 if( size
> sizeof(NE_TYPEINFO
) )
87 { pTypeInfo
= (BYTE
*)HeapAlloc( GetProcessHeap(), 0, size
);
89 { _llseek32(hFile
, mz_header
.e_lfanew
+ne_header
.resource_tab_offset
, SEEK_SET
);
90 if( _lread32( hFile
, (char*)pTypeInfo
, size
) != size
)
91 { HeapFree( GetProcessHeap(), 0, pTypeInfo
);
97 return IMAGE_OS2_SIGNATURE
;
99 return 0; /* failed */
101 /*************************************************************************
104 static HGLOBAL16
SHELL_LoadResource(HINSTANCE32 hInst
, HFILE32 hFile
, NE_NAMEINFO
* pNInfo
, WORD sizeShift
)
106 HGLOBAL16 handle
= DirectResAlloc( hInst
, 0x10, (DWORD
)pNInfo
->length
<< sizeShift
);
110 if( (ptr
= (BYTE
*)GlobalLock16( handle
)) )
111 { _llseek32( hFile
, (DWORD
)pNInfo
->offset
<< sizeShift
, SEEK_SET
);
112 _lread32( hFile
, (char*)ptr
, pNInfo
->length
<< sizeShift
);
118 /*************************************************************************
121 static HGLOBAL16
ICO_LoadIcon(HINSTANCE32 hInst
, HFILE32 hFile
, LPicoICONDIRENTRY lpiIDE
)
123 HGLOBAL16 handle
= DirectResAlloc( hInst
, 0x10, lpiIDE
->dwBytesInRes
);
125 if( (ptr
= (BYTE
*)GlobalLock16( handle
)) )
126 { _llseek32( hFile
, lpiIDE
->dwImageOffset
, SEEK_SET
);
127 _lread32( hFile
, (char*)ptr
, lpiIDE
->dwBytesInRes
);
133 /*************************************************************************
134 * ICO_GetIconDirectory
136 * Read .ico file and build phony ICONDIR struct for GetIconID
138 static HGLOBAL16
ICO_GetIconDirectory(HINSTANCE32 hInst
, HFILE32 hFile
, LPicoICONDIR
* lplpiID
)
139 { WORD id
[3]; /* idReserved, idType, idCount */
144 _llseek32( hFile
, 0, SEEK_SET
);
145 if( _lread32(hFile
,(char*)id
,sizeof(id
)) != sizeof(id
) )
150 * - see http://www.microsoft.com/win32dev/ui/icons.htm
153 if( id
[0] || id
[1] != 1 || !id
[2] )
156 i
= id
[2]*sizeof(icoICONDIRENTRY
) + sizeof(id
);
158 lpiID
= (LPicoICONDIR
)HeapAlloc( GetProcessHeap(), 0, i
);
160 if( _lread32(hFile
,(char*)lpiID
->idEntries
,i
) == i
)
161 { HGLOBAL16 handle
= DirectResAlloc( hInst
, 0x10,id
[2]*sizeof(ICONDIRENTRY
) + sizeof(id
) );
163 { CURSORICONDIR
* lpID
= (CURSORICONDIR
*)GlobalLock16( handle
);
164 lpID
->idReserved
= lpiID
->idReserved
= id
[0];
165 lpID
->idType
= lpiID
->idType
= id
[1];
166 lpID
->idCount
= lpiID
->idCount
= id
[2];
167 for( i
=0; i
< lpiID
->idCount
; i
++ )
168 { memcpy((void*)(lpID
->idEntries
+ i
),(void*)(lpiID
->idEntries
+ i
), sizeof(ICONDIRENTRY
) - 2);
169 lpID
->idEntries
[i
].icon
.wResId
= i
;
177 HeapFree( GetProcessHeap(), 0, lpiID
);
181 /*************************************************************************
182 * InternalExtractIcon [SHELL.39]
184 * This abortion is called directly by Progman
185 * fixme: the icon section is broken (don't have a handle for
186 * ICO_GetIconDirectory....)
189 #define ICO_INVALID_FILE 1
190 #define ICO_NO_ICONS 0
192 HGLOBAL32 WINAPI
ICO_ExtractIconEx(LPCSTR lpszExeFileName
, HICON32
* RetPtr
, UINT32 nIconIndex
, UINT32 n
, UINT32 cxDesired
, UINT32 cyDesired
)
193 { HGLOBAL32 hRet
= ICO_NO_ICONS
;
197 HFILE32 hFile
= OpenFile32( lpszExeFileName
, &ofs
, OF_READ
);
198 UINT16 iconDirCount
= 0,iconCount
= 0;
202 TRACE(shell
,"(file %s,start %d,extract %d\n", lpszExeFileName
, nIconIndex
, n
);
204 if( hFile
== HFILE_ERROR32
|| !n
)
205 return ICO_INVALID_FILE
;
207 sig
= SHELL_GetResourceTable(hFile
,&pData
);
210 if( sig
==IMAGE_OS2_SIGNATURE
|| sig
==1 ) /* .ICO file */
212 NE_TYPEINFO
* pTInfo
= (NE_TYPEINFO
*)(pData
+ 2);
213 NE_NAMEINFO
* pIconStorage
= NULL
;
214 NE_NAMEINFO
* pIconDir
= NULL
;
215 LPicoICONDIR lpiID
= NULL
;
217 if( pData
== (BYTE
*)-1 )
218 { hIcon
= ICO_GetIconDirectory(0, hFile
, &lpiID
); /* check for .ICO file */
220 { iconDirCount
= 1; iconCount
= lpiID
->idCount
;
223 else while( pTInfo
->type_id
&& !(pIconStorage
&& pIconDir
) )
224 { if( pTInfo
->type_id
== NE_RSCTYPE_GROUP_ICON
) /* find icon directory and icon repository */
225 { iconDirCount
= pTInfo
->count
;
226 pIconDir
= ((NE_NAMEINFO
*)(pTInfo
+ 1));
227 TRACE(shell
,"\tfound directory - %i icon families\n", iconDirCount
);
229 if( pTInfo
->type_id
== NE_RSCTYPE_ICON
)
230 { iconCount
= pTInfo
->count
;
231 pIconStorage
= ((NE_NAMEINFO
*)(pTInfo
+ 1));
232 TRACE(shell
,"\ttotal icons - %i\n", iconCount
);
234 pTInfo
= (NE_TYPEINFO
*)((char*)(pTInfo
+1)+pTInfo
->count
*sizeof(NE_NAMEINFO
));
237 if( (pIconStorage
&& pIconDir
) || lpiID
) /* load resources and create icons */
238 { if( nIconIndex
== (UINT16
)-1 )
239 { RetPtr
[0] = iconDirCount
;
241 else if( nIconIndex
< iconDirCount
)
243 if( n
> iconDirCount
- nIconIndex
)
244 n
= iconDirCount
- nIconIndex
;
246 for( i
= nIconIndex
; i
< nIconIndex
+ n
; i
++ )
247 { /* .ICO files have only one icon directory */
250 hIcon
= SHELL_LoadResource( 0, hFile
, pIconDir
+ i
, *(WORD
*)pData
);
251 RetPtr
[i
-nIconIndex
] = GetIconID( hIcon
, 3 );
255 for( icon
= nIconIndex
; icon
< nIconIndex
+ n
; icon
++ )
258 { hIcon
= ICO_LoadIcon( 0, hFile
, lpiID
->idEntries
+ RetPtr
[icon
-nIconIndex
]);
261 { for( i
= 0; i
< iconCount
; i
++ )
262 { if( pIconStorage
[i
].id
== (RetPtr
[icon
-nIconIndex
] | 0x8000) )
263 { hIcon
= SHELL_LoadResource( 0, hFile
, pIconStorage
+ i
,*(WORD
*)pData
);
268 { RetPtr
[icon
-nIconIndex
] = LoadIconHandler( hIcon
, TRUE
);
271 { RetPtr
[icon
-nIconIndex
] = 0;
277 HeapFree( GetProcessHeap(), 0, lpiID
);
279 HeapFree( GetProcessHeap(), 0, pData
);
284 if( sig
== IMAGE_NT_SIGNATURE
)
285 { LPBYTE idata
,igdata
;
286 PIMAGE_DOS_HEADER dheader
;
287 PIMAGE_NT_HEADERS pe_header
;
288 PIMAGE_SECTION_HEADER pe_sections
;
289 PIMAGE_RESOURCE_DIRECTORY rootresdir
,iconresdir
,icongroupresdir
;
290 PIMAGE_RESOURCE_DATA_ENTRY idataent
,igdataent
;
291 PIMAGE_RESOURCE_DIRECTORY_ENTRY xresent
;
294 if ( !(fmapping
= CreateFileMapping32A(hFile
,NULL
,PAGE_READONLY
|SEC_COMMIT
,0,0,NULL
)))
295 { WARN(shell
,"failed to create filemap.\n"); /* FIXME, INVALID_HANDLE_VALUE? */
296 hRet
= ICO_INVALID_FILE
;
297 goto end_2
; /* failure */
300 if ( !(peimage
= MapViewOfFile(fmapping
,FILE_MAP_READ
,0,0,0)))
301 { WARN(shell
,"failed to mmap filemap.\n");
302 hRet
= ICO_INVALID_FILE
;
303 goto end_2
; /* failure */
306 dheader
= (PIMAGE_DOS_HEADER
)peimage
;
307 pe_header
= (PIMAGE_NT_HEADERS
)(peimage
+dheader
->e_lfanew
); /* it is a pe header, SHELL_GetResourceTable checked that */
308 pe_sections
= (PIMAGE_SECTION_HEADER
)(((char*)pe_header
)+sizeof(*pe_header
)); /* probably makes problems with short PE headers...*/
311 for (i
=0;i
<pe_header
->FileHeader
.NumberOfSections
;i
++)
312 { if (pe_sections
[i
].Characteristics
& IMAGE_SCN_CNT_UNINITIALIZED_DATA
)
314 /* FIXME: doesn't work when the resources are not in a seperate section */
315 if (pe_sections
[i
].VirtualAddress
== pe_header
->OptionalHeader
.DataDirectory
[IMAGE_DIRECTORY_ENTRY_RESOURCE
].VirtualAddress
)
316 { rootresdir
= (PIMAGE_RESOURCE_DIRECTORY
)((char*)peimage
+pe_sections
[i
].PointerToRawData
);
322 { WARN(shell
,"haven't found section for resource directory.\n");
323 goto end_4
; /* failure */
325 /* search the group icon dir*/
326 if (!(icongroupresdir
= GetResDirEntryW(rootresdir
,RT_GROUP_ICON32W
, (DWORD
)rootresdir
,FALSE
)))
327 { WARN(shell
,"No Icongroupresourcedirectory!\n");
328 goto end_4
; /* failure */
330 iconDirCount
= icongroupresdir
->NumberOfNamedEntries
+icongroupresdir
->NumberOfIdEntries
;
332 /* number of icons requested */
333 if( nIconIndex
== -1 )
334 { hRet
= iconDirCount
;
335 goto end_3
; /* success */
338 if (nIconIndex
>= iconDirCount
)
339 { WARN(shell
,"nIconIndex %d is larger than iconDirCount %d\n",nIconIndex
,iconDirCount
);
340 goto end_4
; /* failure */
343 xresent
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)(icongroupresdir
+1); /* caller just wanted the number of entries */
345 if( n
> iconDirCount
- nIconIndex
) /* assure we don't get too much ... */
346 { n
= iconDirCount
- nIconIndex
;
349 xresent
= xresent
+nIconIndex
; /* starting from specified index ... */
351 for (i
=0;i
<n
;i
++,xresent
++)
352 { PIMAGE_RESOURCE_DIRECTORY resdir
;
354 /* go down this resource entry, name */
355 resdir
= (PIMAGE_RESOURCE_DIRECTORY
)((DWORD
)rootresdir
+(xresent
->u2
.s
.OffsetToDirectory
));
357 /* default language (0) */
358 resdir
= GetResDirEntryW(resdir
,(LPWSTR
)0,(DWORD
)rootresdir
,TRUE
);
359 igdataent
= (PIMAGE_RESOURCE_DATA_ENTRY
)resdir
;
361 /* lookup address in mapped image for virtual address */
364 for (j
=0;j
<pe_header
->FileHeader
.NumberOfSections
;j
++)
365 { if (igdataent
->OffsetToData
< pe_sections
[j
].VirtualAddress
)
367 if (igdataent
->OffsetToData
+igdataent
->Size
> pe_sections
[j
].VirtualAddress
+pe_sections
[j
].SizeOfRawData
)
369 igdata
= peimage
+(igdataent
->OffsetToData
-pe_sections
[j
].VirtualAddress
+pe_sections
[j
].PointerToRawData
);
373 { WARN(shell
,"no matching real address for icongroup!\n");
374 goto end_4
; /* failure */
376 RetPtr
[i
] = LookupIconIdFromDirectoryEx32(igdata
, TRUE
, cxDesired
, cyDesired
, LR_DEFAULTCOLOR
);
379 if (!(iconresdir
=GetResDirEntryW(rootresdir
,RT_ICON32W
,(DWORD
)rootresdir
,FALSE
)))
380 { WARN(shell
,"No Iconresourcedirectory!\n");
381 goto end_4
; /* failure */
385 { PIMAGE_RESOURCE_DIRECTORY xresdir
;
386 xresdir
= GetResDirEntryW(iconresdir
,(LPWSTR
)(DWORD
)RetPtr
[i
],(DWORD
)rootresdir
,FALSE
);
387 xresdir
= GetResDirEntryW(xresdir
,(LPWSTR
)0,(DWORD
)rootresdir
,TRUE
);
388 idataent
= (PIMAGE_RESOURCE_DATA_ENTRY
)xresdir
;
391 /* map virtual to address in image */
392 for (j
=0;j
<pe_header
->FileHeader
.NumberOfSections
;j
++)
393 { if (idataent
->OffsetToData
< pe_sections
[j
].VirtualAddress
)
395 if (idataent
->OffsetToData
+idataent
->Size
> pe_sections
[j
].VirtualAddress
+pe_sections
[j
].SizeOfRawData
)
397 idata
= peimage
+(idataent
->OffsetToData
-pe_sections
[j
].VirtualAddress
+pe_sections
[j
].PointerToRawData
);
400 { WARN(shell
,"no matching real address found for icondata!\n");
404 RetPtr
[i
] = CreateIconFromResourceEx32(idata
,idataent
->Size
,TRUE
,0x00030000, cxDesired
, cyDesired
, LR_DEFAULTCOLOR
);
406 hRet
= RetPtr
[0]; /* return first icon */
407 goto end_3
; /* sucess */
409 hRet
= ICO_INVALID_FILE
;
410 goto end_1
; /* unknown filetype */
412 /* cleaning up (try & catch would be nicer:-) ) */
413 end_4
: hRet
= 0; /* failure */
414 end_3
: UnmapViewOfFile(peimage
); /* success */
415 end_2
: CloseHandle(fmapping
);
416 end_1
: _lclose32( hFile
);
420 /********************** THE ICON CACHE ********************************/
421 HIMAGELIST ShellSmallIconList
= 0;
422 HIMAGELIST ShellBigIconList
= 0;
426 { LPSTR sSourceFile
; /* file icon is from */
427 DWORD dwSourceIndex
; /* index within the file */
428 DWORD dwListIndex
; /* index within the iconlist */
429 } SIC_ENTRY
, * LPSIC_ENTRY
;
431 /*****************************************************************************
432 * SIC_CompareEntrys (internal)
434 * Callback for DPA_Search
436 static INT32
SIC_CompareEntrys( LPVOID p1
, LPVOID p2
, LPARAM lparam
)
437 { TRACE(shell
,"%p %p\n", p1
, p2
);
439 if (((LPSIC_ENTRY
)p1
)->dwSourceIndex
!= ((LPSIC_ENTRY
)p2
)->dwSourceIndex
) /* first the faster one*/
442 if (strcmp(((LPSIC_ENTRY
)p1
)->sSourceFile
,((LPSIC_ENTRY
)p2
)->sSourceFile
))
447 /*****************************************************************************
450 INT32 WINAPI
SIC_AddIcon (LPSTR sSourceFile
, DWORD dwSourceIndex
, HICON32 hSmallIcon
, HICON32 hBigIcon
)
451 { LPSIC_ENTRY lpsice
;
454 TRACE(shell
,"%s %li\n", sSourceFile
, dwSourceIndex
);
456 lpsice
= (LPSIC_ENTRY
) SHAlloc (sizeof (SIC_ENTRY
));
458 lpsice
->sSourceFile
= HEAP_strdupA (GetProcessHeap(),0,sSourceFile
);
459 lpsice
->dwSourceIndex
= dwSourceIndex
;
461 /* index = pDPA_Search (hdpa, lpsice, -1, SIC_CompareEntrys, 0, 0);
463 { TRACE(shell, "-- allready inserted\n");
468 index
= pDPA_InsertPtr(hdpa
, 0x7fff, lpsice
);
474 lpsice
->dwListIndex
= pImageList_GetImageCount(ShellSmallIconList
)+1;
476 pImageList_AddIcon (ShellSmallIconList
, hSmallIcon
);
477 pImageList_AddIcon (ShellBigIconList
, hBigIcon
);
482 /*****************************************************************************
483 * SIC_GetIcon (internal)
485 * look in the cache for a proper icon. if not available the icon is taken
486 * from the file and cached
488 HICON32 WINAPI
SIC_GetIcon (LPSTR sSourceFile
, DWORD dwSourceIndex
, BOOL32 bSmallIcon
)
489 { LPSIC_ENTRY lpsice
;
491 HICON32 hSmallIcon
, hBigIcon
;
493 TRACE(shell
,"%s %li\n", sSourceFile
, dwSourceIndex
);
495 lpsice
= (LPSIC_ENTRY
) SHAlloc (sizeof (SIC_ENTRY
));
497 lpsice
->sSourceFile
= HEAP_strdupA (GetProcessHeap(),0,sSourceFile
);
498 lpsice
->dwSourceIndex
= dwSourceIndex
;
500 index
= pDPA_Search (hdpa
, lpsice
, -1, SIC_CompareEntrys
, 0, 0);
503 { TRACE(shell
, "-- found\n");
506 index
= ((LPSIC_ENTRY
)pDPA_GetPtr(hdpa
, index
))->dwListIndex
;
508 return pImageList_GetIcon(ShellSmallIconList
, index
, ILD_NORMAL
);
509 return pImageList_GetIcon(ShellBigIconList
, index
, ILD_NORMAL
);
512 index = pDPA_InsertPtr(hdpa, 0x7fff, lpsice);
517 lpsice->hSmallIcon = hSmallIcon;
518 lpsice->hBigIcon = hBigIcon;
520 pImageList_AddIcon (ShellSmallIconList, hSmallIcon);
521 pImageList_AddIcon (ShellBigIconList, hBigIcon);
526 /*****************************************************************************
527 * SIC_Initialize (internal)
529 * hack to load the resources from the shell32.dll under a different dll name
530 * will be removed when the resource-compiler is ready
532 BOOL32 WINAPI
SIC_Initialize(void)
533 { CHAR szShellPath
[MAX_PATH
];
534 HGLOBAL32 hSmRet
, hLgRet
;
535 HICON32
*pSmRet
, *pLgRet
;
540 if (hdpa
) /* already initialized?*/
543 hdpa
= pDPA_Create(16);
549 GetWindowsDirectory32A(szShellPath
,MAX_PATH
);
550 PathAddBackslash32A(szShellPath
);
551 strcat(szShellPath
,"system\\shell32.dll");
553 hSmRet
= GlobalAlloc32( GMEM_FIXED
| GMEM_ZEROINIT
, sizeof(HICON32
)*40);
554 hLgRet
= GlobalAlloc32( GMEM_FIXED
| GMEM_ZEROINIT
, sizeof(HICON32
)*40);
556 pSmRet
= (HICON32
*)GlobalLock32(hSmRet
);
557 pLgRet
= (HICON32
*)GlobalLock32(hLgRet
);
559 ExtractIconEx32A ( szShellPath
, 0, pLgRet
, pSmRet
, 40 );
561 ShellSmallIconList
= pImageList_Create(16,16,ILC_COLORDDB
| ILC_MASK
,0,0x20);
562 ShellBigIconList
= pImageList_Create(32,32,ILC_COLORDDB
| ILC_MASK
,0,0x20);
564 for (index
=0; index
<40; index
++)
565 { if (! pSmRet
[index
] )
566 { MSG("*** failure loading resources from %s\n", szShellPath
);
567 MSG("*** this is a hack for loading the internal and external dll at the same time\n");
568 MSG("*** you can ignore it but you will miss some icons in win95 dialogs\n\n");
571 SIC_AddIcon (szShellPath
, index
, pSmRet
[index
], pLgRet
[index
]);
574 GlobalUnlock32(hLgRet
);
575 GlobalFree32(hLgRet
);
577 GlobalUnlock32(hSmRet
);
578 GlobalFree32(hSmRet
);
580 TRACE(shell
,"hIconSmall=%p hIconBig=%p\n",ShellSmallIconList
, ShellBigIconList
);
585 /*************************************************************************
586 * Shell_GetImageList [SHELL32.71]
589 * imglist[1|2] [OUT] pointer which recive imagelist handles
592 DWORD WINAPI
Shell_GetImageList(HIMAGELIST
* imglist1
,HIMAGELIST
* imglist2
)
593 { TRACE(shell
,"(%p,%p)\n",imglist1
,imglist2
);
595 { *imglist1
=ShellBigIconList
;
598 { *imglist2
=ShellSmallIconList
;
604 /*************************************************************************
605 * SHMapPIDLToSystemImageListIndex [SHELL32.77]
608 * x pointer to an instance of IShellFolder
614 DWORD WINAPI
SHMapPIDLToSystemImageListIndex(LPSHELLFOLDER sh
,LPITEMIDLIST pidl
,DWORD z
)
615 { LPITEMIDLIST pidltemp
= ILFindLastID(pidl
);
617 FIXME(shell
,"(SF=%p,pidl=%p,%08lx):stub.\n",sh
,pidl
,z
);
619 if (_ILIsMyComputer(pidltemp
))
622 else if (_ILIsDrive (pidltemp
))
625 else if (_ILIsFolder (pidltemp
))
633 /*************************************************************************
634 * ExtracticonEx32 [shell32.189]
636 HICON32 WINAPI
ExtractIconEx32AW ( LPVOID lpszFile
, INT32 nIconIndex
, HICON32
* phiconLarge
, HICON32
* phiconSmall
, UINT32 nIcons
)
637 { if (VERSION_OsIsUnicode())
638 return ExtractIconEx32W ( lpszFile
, nIconIndex
, phiconLarge
, phiconSmall
, nIcons
);
639 return ExtractIconEx32A ( lpszFile
, nIconIndex
, phiconLarge
, phiconSmall
, nIcons
);
641 /*************************************************************************
642 * ExtracticonEx32A [shell32.190]
645 * 1 file is not valid
646 * HICON32 handle of a icon (phiconLarge/Small == NULL)
648 HICON32 WINAPI
ExtractIconEx32A ( LPSTR lpszFile
, INT32 nIconIndex
, HICON32
* phiconLarge
, HICON32
* phiconSmall
, UINT32 nIcons
)
651 TRACE(shell
,"file=%s idx=%i %p %p num=%i\n", lpszFile
, nIconIndex
, phiconLarge
, phiconSmall
, nIcons
);
653 if (nIconIndex
==-1) /* Number of icons requested */
654 return ICO_ExtractIconEx(lpszFile
, NULL
, -1, 0, 0, 0 );
658 { ret
= ICO_ExtractIconEx(lpszFile
, phiconLarge
, nIconIndex
, nIcons
, 32, 32 );
660 { ret
= phiconLarge
[0];
664 /* if no pointers given and one icon expected, return the handle directly*/
665 if (!phiconLarge
&& ! phiconSmall
&& nIcons
==1 )
669 { ret
= ICO_ExtractIconEx(lpszFile
, phiconSmall
, nIconIndex
, nIcons
, 16, 16 );
671 { ret
= phiconLarge
[0];
677 /*************************************************************************
678 * ExtracticonEx32W [shell32.191]
680 HICON32 WINAPI
ExtractIconEx32W ( LPWSTR lpszFile
, INT32 nIconIndex
, HICON32
* phiconLarge
, HICON32
* phiconSmall
, UINT32 nIcons
)
684 TRACE(shell
,"file=%s idx=%i %p %p num=%i\n", debugstr_w(lpszFile
), nIconIndex
, phiconLarge
, phiconSmall
, nIcons
);
686 sFile
= HEAP_strdupWtoA (GetProcessHeap(),0,lpszFile
);
687 ret
= ExtractIconEx32A ( sFile
, nIconIndex
, phiconLarge
, phiconSmall
, nIcons
);
688 HeapFree(GetProcessHeap(),0,sFile
);