- Timestamp:
- Oct 22, 1999, 3:35:21 PM (26 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/shell32/iconcache.cpp
r1215 r1399 1 /* $Id: iconcache.cpp,v 1.2 1999-10-09 11:17:00 sandervl Exp $ */ 1 /* $Id: iconcache.cpp,v 1.3 1999-10-22 13:35:21 phaller Exp $ */ 2 2 3 /* 3 * shell icon cache (SIC) 4 * 5 */ 4 * Win32 SHELL32 for OS/2 5 * 6 * Copyright 1999 Patrick Haller (haller@zebra.fh-weingarten.de) 7 * Project Odin Software License can be found in LICENSE.TXT 8 * 9 * shell icon cache (SIC) 10 * 11 */ 12 13 14 /***************************************************************************** 15 * Includes * 16 *****************************************************************************/ 17 6 18 #include <string.h> 7 19 #include <odin.h> 20 #include <odinwrap.h> 21 #include <os2sel.h> 8 22 9 23 #define ICOM_CINTERFACE 1 … … 29 43 #include <misc.h> 30 44 31 DEFAULT_DEBUG_CHANNEL(shell) 45 46 ODINDEBUGCHANNEL(SHELL32-ICONCACHE) 32 47 33 48 #include "pshpack1.h" 49 #include "poppack.h" 50 51 52 /***************************************************************************** 53 * Structures * 54 *****************************************************************************/ 34 55 35 56 typedef struct 36 57 { 37 BYTE bWidth; /* Width, in pixels, of the image 38 BYTE bHeight; /* Height, in pixels, of the image 58 BYTE bWidth; /* Width, in pixels, of the image */ 59 BYTE bHeight; /* Height, in pixels, of the image */ 39 60 BYTE bColorCount; /* Number of colors in image (0 if >=8bpp) */ 40 BYTE bReserved; /* Reserved ( must be 0) 41 WORD wPlanes; /* Color Planes 42 WORD wBitCount; /* Bits per pixel 43 DWORD dwBytesInRes; /* How many bytes in this resource? 44 DWORD dwImageOffset; /* Where in the file is this image? 61 BYTE bReserved; /* Reserved ( must be 0) */ 62 WORD wPlanes; /* Color Planes */ 63 WORD wBitCount; /* Bits per pixel */ 64 DWORD dwBytesInRes; /* How many bytes in this resource? */ 65 DWORD dwImageOffset; /* Where in the file is this image? */ 45 66 } icoICONDIRENTRY, *LPicoICONDIRENTRY; 46 67 … … 53 74 } icoICONDIR, *LPicoICONDIR; 54 75 55 #include "poppack.h"56 57 76 #if 0 58 static void dumpIcoDirEnty ( LP icoICONDIRENTRY entry )59 { 60 TRACE("width = 0x%08x height = 0x%08x\n", entry->bWidth, entry->bHeight);61 TRACE("colors = 0x%08x planes = 0x%08x\n", entry->bColorCount, entry->wPlanes);62 TRACE("bitcount = 0x%08x bytesinres = 0x%08lx offset = 0x%08lx\n",63 entry->wBitCount, entry->dwBytesInRes, entry->dwImageOffset);64 } 65 static void dumpIcoDir ( LP icoICONDIR entry )66 { 67 TRACE("type = 0x%08x count = 0x%08x\n", entry->idType, entry->idCount);77 static void dumpIcoDirEnty ( LPICONDIRENTRY entry ) 78 { 79 dprintf(("SHELL32:Iconcache width = 0x%08x height = 0x%08x\n", entry->bWidth, entry->bHeight)); 80 dprintf(("SHELL32:Iconcache colors = 0x%08x planes = 0x%08x\n", entry->bColorCount, entry->wPlanes)); 81 dprintf(("SHELL32:Iconcache bitcount = 0x%08x bytesinres = 0x%08lx offset = 0x%08lx\n", 82 entry->wBitCount, entry->dwBytesInRes, entry->dwImageOffset)); 83 } 84 static void dumpIcoDir ( LPICONDIR entry ) 85 { 86 dprintf(("SHELL32:Iconcache type = 0x%08x count = 0x%08x\n", entry->idType, entry->idCount)); 68 87 } 69 88 #endif 70 89 71 90 72 HDPA 73 static CRITICAL_SECTION 74 75 76 77 /************************************************************************* 78 * 91 HDPA sic_hdpa = 0; 92 static CRITICAL_SECTION SHELL32_SicCS; 93 94 95 96 /************************************************************************* 97 * SHELL_GetResourceTable 79 98 */ 80 99 static DWORD SHELL_GetResourceTable(HFILE hFile, LPBYTE *retptr) 81 { IMAGE_DOS_HEADERmz_header;82 charmagic[4];83 intsize;84 85 TRACE("0x%08x %p\n", hFile, retptr);86 87 88 89 90 { if (mz_header.e_cblp == 1)/* .ICO file ? */91 { *retptr = (LPBYTE)-1;/* ICONHEADER.idType, must be 1 */92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 { IMAGE_OS2_HEADERne_header;109 LPBYTEpTypeInfo = (LPBYTE)-1;110 111 112 113 114 115 116 117 100 { IMAGE_DOS_HEADER mz_header; 101 char magic[4]; 102 int size; 103 104 dprintf(("SHELL32:Iconcache 0x%08x SHELL_GetResourceTable %p\n", hFile, retptr)); 105 106 *retptr = NULL; 107 _llseek( hFile, 0, SEEK_SET ); 108 if ((_lread(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) || (mz_header.e_magic != IMAGE_DOS_SIGNATURE)) 109 { if (mz_header.e_cblp == 1) /* .ICO file ? */ 110 { *retptr = (LPBYTE)-1; /* ICONHEADER.idType, must be 1 */ 111 return 1; 112 } 113 else 114 return 0; /* failed */ 115 } 116 _llseek( hFile, mz_header.e_lfanew, SEEK_SET ); 117 118 if (_lread( hFile, magic, sizeof(magic) ) != sizeof(magic)) 119 return 0; 120 121 _llseek( hFile, mz_header.e_lfanew, SEEK_SET); 122 123 if (*(DWORD*)magic == IMAGE_NT_SIGNATURE) 124 return IMAGE_NT_SIGNATURE; 125 126 if (*(WORD*)magic == IMAGE_OS2_SIGNATURE) 127 { IMAGE_OS2_HEADER ne_header; 128 LPBYTE pTypeInfo = (LPBYTE)-1; 129 130 if (_lread(hFile,&ne_header,sizeof(ne_header))!=sizeof(ne_header)) 131 return 0; 132 133 if (ne_header.ne_magic != IMAGE_OS2_SIGNATURE) 134 return 0; 135 136 size = ne_header.rname_tab_offset - ne_header.resource_tab_offset; 118 137 119 138 //@@@PH no NE support 120 139 #if 0 121 122 123 124 125 126 127 128 129 130 140 if( size > sizeof(NE_TYPEINFO) ) 141 { pTypeInfo = (BYTE*)HeapAlloc( GetProcessHeap(), 0, size); 142 if( pTypeInfo ) 143 { _llseek(hFile, mz_header.e_lfanew+ne_header.resource_tab_offset, SEEK_SET); 144 if( _lread( hFile, (char*)pTypeInfo, size) != size ) 145 { HeapFree( GetProcessHeap(), 0, pTypeInfo); 146 pTypeInfo = NULL; 147 } 148 } 149 } 131 150 #endif 132 151 133 134 135 136 137 } 138 /************************************************************************* 139 * 152 *retptr = pTypeInfo; 153 return IMAGE_OS2_SIGNATURE; 154 } 155 return 0; /* failed */ 156 } 157 /************************************************************************* 158 * SHELL_LoadResource 140 159 */ 141 160 //@@@PH no NE support 142 161 #if 0 143 162 static BYTE * SHELL_LoadResource( HFILE hFile, NE_NAMEINFO* pNInfo, WORD sizeShift, ULONG *uSize) 144 { 145 146 TRACE("0x%08x %p 0x%08x\n", hFile, pNInfo, sizeShift);147 148 149 150 151 152 153 154 163 { BYTE* ptr; 164 165 dprintf(("SHELL32:Iconcache SHELL_LoadResource 0x%08x %p 0x%08x\n", hFile, pNInfo, sizeShift)); 166 167 *uSize = (DWORD)pNInfo->length << sizeShift; 168 if( (ptr = (BYTE*)HeapAlloc(GetProcessHeap(),0, *uSize) )) 169 { _llseek( hFile, (DWORD)pNInfo->offset << sizeShift, SEEK_SET); 170 _lread( hFile, (char*)ptr, pNInfo->length << sizeShift); 171 return ptr; 172 } 173 return 0; 155 174 } 156 175 #endif … … 160 179 */ 161 180 static BYTE * ICO_LoadIcon( HFILE hFile, LPicoICONDIRENTRY lpiIDE, ULONG *uSize) 162 { 163 164 TRACE("0x%08x %p\n", hFile, lpiIDE);165 166 167 168 169 170 171 172 173 181 { BYTE* ptr; 182 183 dprintf(("SHELL32:Iconcache ICO_LoadIcon 0x%08x %p\n", hFile, lpiIDE)); 184 185 *uSize = lpiIDE->dwBytesInRes; 186 if( (ptr = (BYTE*)HeapAlloc(GetProcessHeap(),0, *uSize)) ) 187 { _llseek( hFile, lpiIDE->dwImageOffset, SEEK_SET); 188 _lread( hFile, (char*)ptr, lpiIDE->dwBytesInRes); 189 return ptr; 190 } 191 192 return 0; 174 193 } 175 194 … … 180 199 * see http://www.microsoft.com/win32dev/ui/icons.htm 181 200 */ 182 #define HEADER_SIZE 183 #define HEADER_SIZE_FILE 201 #define HEADER_SIZE (sizeof(CURSORICONDIR) - sizeof (CURSORICONDIRENTRY)) 202 #define HEADER_SIZE_FILE (sizeof(icoICONDIR) - sizeof (icoICONDIRENTRY)) 184 203 185 204 static BYTE * ICO_GetIconDirectory( HFILE hFile, LPicoICONDIR* lplpiID, ULONG *uSize ) 186 { CURSORICONDIR lpcid;/* icon resource in resource-dir format */187 LPicoICONDIR lpiID;/* icon resource in file format */188 inti;189 190 TRACE("0x%08x %p\n", hFile, lplpiID);191 192 193 194 195 196 197 198 199 200 201 202 203 { CURSORICONDIR * lpID;/* icon resource in resource format */204 205 206 207 208 lpID->idReserved= lpiID->idReserved = 0;209 lpID->idType= lpiID->idType = 1;210 lpID->idCount= lpiID->idCount = lpcid.idCount;211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 } 227 228 /************************************************************************* 229 * InternalExtractIcon[SHELL.39]205 { CURSORICONDIR lpcid; /* icon resource in resource-dir format */ 206 LPicoICONDIR lpiID; /* icon resource in file format */ 207 int i; 208 209 dprintf(("SHELL32:Iconcache ICO_GetIconDirectory 0x%08x %p\n", hFile, lplpiID)); 210 211 _llseek( hFile, 0, SEEK_SET ); 212 if( _lread(hFile,(char*)&lpcid, HEADER_SIZE_FILE) != HEADER_SIZE_FILE ) 213 return 0; 214 215 if( lpcid.idReserved || (lpcid.idType != 1) || (!lpcid.idCount) ) 216 return 0; 217 218 i = lpcid.idCount * sizeof(icoICONDIRENTRY); 219 lpiID = (LPicoICONDIR)HeapAlloc( GetProcessHeap(), 0, HEADER_SIZE_FILE + i); 220 221 if( _lread(hFile,(char*)lpiID->idEntries,i) == i ) 222 { CURSORICONDIR * lpID; /* icon resource in resource format */ 223 *uSize = lpcid.idCount * sizeof(CURSORICONDIRENTRY) + HEADER_SIZE; 224 if( (lpID = (CURSORICONDIR*)HeapAlloc(GetProcessHeap(),0, *uSize) )) 225 { 226 /* copy the header */ 227 lpID->idReserved = lpiID->idReserved = 0; 228 lpID->idType = lpiID->idType = 1; 229 lpID->idCount = lpiID->idCount = lpcid.idCount; 230 231 /* copy the entrys */ 232 for( i=0; i < lpiID->idCount; i++ ) 233 { memcpy((void*)&(lpID->idEntries[i]),(void*)&(lpiID->idEntries[i]), sizeof(CURSORICONDIRENTRY) - 2); 234 lpID->idEntries[i].wResId = i; 235 } 236 237 *lplpiID = lpiID; 238 return (BYTE *)lpID; 239 } 240 } 241 /* fail */ 242 243 HeapFree( GetProcessHeap(), 0, lpiID); 244 return 0; 245 } 246 247 /************************************************************************* 248 * InternalExtractIcon [SHELL.39] 230 249 * 231 250 * This abortion is called directly by Progman … … 234 253 * 235 254 */ 236 #define ICO_INVALID_FILE 237 #define ICO_NO_ICONS 255 #define ICO_INVALID_FILE 1 256 #define ICO_NO_ICONS 0 238 257 239 258 HGLOBAL WINAPI ICO_ExtractIconEx(LPCSTR lpszExeFileName, HICON * RetPtr, UINT nIconIndex, UINT n, UINT cxDesired, UINT cyDesired ) … … 245 264 // @@@PH turned off 246 265 #if 0 247 { HGLOBALhRet = ICO_NO_ICONS;248 LPBYTEpData;249 OFSTRUCTofs;250 DWORDsig;251 HFILEhFile = OpenFile( lpszExeFileName, &ofs, OF_READ );252 UINT16iconDirCount = 0,iconCount = 0;253 LPBYTEpeimage;254 HANDLEfmapping;255 ULONGuSize;256 257 TRACE("(file %s,start %d,extract %d\n", lpszExeFileName, nIconIndex, n);258 259 260 261 262 266 { HGLOBAL hRet = ICO_NO_ICONS; 267 LPBYTE pData; 268 OFSTRUCT ofs; 269 DWORD sig; 270 HFILE hFile = OpenFile( lpszExeFileName, &ofs, OF_READ ); 271 UINT16 iconDirCount = 0,iconCount = 0; 272 LPBYTE peimage; 273 HANDLE fmapping; 274 ULONG uSize; 275 276 dprintf(("SHELL32:Iconcache ICO_ExtractIconEx (file %s,start %d,extract %d\n", lpszExeFileName, nIconIndex, n)); 277 278 if( hFile == HFILE_ERROR || !n ) 279 return ICO_INVALID_FILE; 280 281 sig = SHELL_GetResourceTable(hFile,&pData); 263 282 264 283 //@@@PH no NE support 265 284 #if 0 266 285 /* ico file */ 267 268 { BYTE*pCIDir = 0;269 NE_TYPEINFO*pTInfo = (NE_TYPEINFO*)(pData + 2);270 NE_NAMEINFO*pIconStorage = NULL;271 NE_NAMEINFO*pIconDir = NULL;272 LPicoICONDIRlpiID = NULL;273 274 TRACE("-- OS2/icon Signature (0x%08lx)\n", sig);275 276 277 { pCIDir = ICO_GetIconDirectory(hFile, &lpiID, &uSize);/* check for .ICO file */278 279 280 TRACE("-- icon found %p 0x%08lx 0x%08x 0x%08x\n", pCIDir, uSize, iconDirCount, iconCount);281 282 283 284 { if( pTInfo->type_id == NE_RSCTYPE_GROUP_ICON )/* find icon directory and icon repository */285 286 287 TRACE("\tfound directory - %i icon families\n", iconDirCount);288 289 290 291 292 TRACE("\ttotal icons - %i\n", iconCount);293 294 295 296 297 if( (pIconStorage && pIconDir) || lpiID )/* load resources and create icons */298 299 300 301 302 303 304 305 306 307 308 309 if( lpiID == NULL )/* *.ico */310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 286 if( sig==IMAGE_OS2_SIGNATURE || sig==1 ) /* .ICO file */ 287 { BYTE *pCIDir = 0; 288 NE_TYPEINFO *pTInfo = (NE_TYPEINFO*)(pData + 2); 289 NE_NAMEINFO *pIconStorage = NULL; 290 NE_NAMEINFO *pIconDir = NULL; 291 LPicoICONDIR lpiID = NULL; 292 293 dprintf(("SHELL32:Iconcache -- OS2/icon Signature (0x%08lx)\n", sig)); 294 295 if( pData == (BYTE*)-1 ) 296 { pCIDir = ICO_GetIconDirectory(hFile, &lpiID, &uSize); /* check for .ICO file */ 297 if( pCIDir ) 298 { iconDirCount = 1; iconCount = lpiID->idCount; 299 dprintf(("SHELL32:Iconcache -- icon found %p 0x%08lx 0x%08x 0x%08x\n", pCIDir, uSize, iconDirCount, iconCount)); 300 } 301 } 302 else while( pTInfo->type_id && !(pIconStorage && pIconDir) ) 303 { if( pTInfo->type_id == NE_RSCTYPE_GROUP_ICON ) /* find icon directory and icon repository */ 304 { iconDirCount = pTInfo->count; 305 pIconDir = ((NE_NAMEINFO*)(pTInfo + 1)); 306 dprintf(("SHELL32:Iconcache \tfound directory - %i icon families\n", iconDirCount)); 307 } 308 if( pTInfo->type_id == NE_RSCTYPE_ICON ) 309 { iconCount = pTInfo->count; 310 pIconStorage = ((NE_NAMEINFO*)(pTInfo + 1)); 311 dprintf(("SHELL32:Iconcache \ttotal icons - %i\n", iconCount)); 312 } 313 pTInfo = (NE_TYPEINFO *)((char*)(pTInfo+1)+pTInfo->count*sizeof(NE_NAMEINFO)); 314 } 315 316 if( (pIconStorage && pIconDir) || lpiID ) /* load resources and create icons */ 317 { if( nIconIndex == (UINT16)-1 ) 318 { RetPtr[0] = iconDirCount; 319 } 320 else if( nIconIndex < iconDirCount ) 321 { UINT16 i, icon; 322 if( n > iconDirCount - nIconIndex ) 323 n = iconDirCount - nIconIndex; 324 325 for( i = nIconIndex; i < nIconIndex + n; i++ ) 326 { /* .ICO files have only one icon directory */ 327 328 if( lpiID == NULL ) /* *.ico */ 329 pCIDir = SHELL_LoadResource( hFile, pIconDir + i, *(WORD*)pData, &uSize ); 330 RetPtr[i-nIconIndex] = pLookupIconIdFromDirectoryEx( pCIDir, TRUE, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), 0); 331 HeapFree(GetProcessHeap(), 0, pCIDir); 332 } 333 334 for( icon = nIconIndex; icon < nIconIndex + n; icon++ ) 335 { pCIDir = NULL; 336 if( lpiID ) 337 { pCIDir = ICO_LoadIcon( hFile, lpiID->idEntries + RetPtr[icon-nIconIndex], &uSize); 338 } 339 else 340 { for( i = 0; i < iconCount; i++ ) 341 { if( pIconStorage[i].id == (RetPtr[icon-nIconIndex] | 0x8000) ) 342 { pCIDir = SHELL_LoadResource( hFile, pIconStorage + i,*(WORD*)pData, &uSize ); 343 } 344 } 345 } 346 if( pCIDir ) 347 { RetPtr[icon-nIconIndex] = (HICON) pCreateIconFromResourceEx(pCIDir,uSize,TRUE,0x00030000, cxDesired, cyDesired, LR_DEFAULTCOLOR); 348 } 349 else 350 { RetPtr[icon-nIconIndex] = 0; 351 } 352 } 353 } 354 } 355 if( lpiID ) 356 HeapFree( GetProcessHeap(), 0, lpiID); 357 else 358 HeapFree( GetProcessHeap(), 0, pData); 359 } 341 360 /* end ico file */ 342 361 #endif 343 362 344 363 /* exe/dll */ 345 346 { LPBYTEidata,igdata;347 PIMAGE_DOS_HEADERdheader;348 PIMAGE_NT_HEADERSpe_header;349 PIMAGE_SECTION_HEADERpe_sections;350 PIMAGE_RESOURCE_DIRECTORYrootresdir,iconresdir,icongroupresdir;351 PIMAGE_RESOURCE_DATA_ENTRYidataent,igdataent;352 PIMAGE_RESOURCE_DIRECTORY_ENTRYxresent;353 inti,j;354 355 356 { WARN("failed to create filemap.\n");/* FIXME, INVALID_HANDLE_VALUE? */357 358 goto end_2;/* failure */359 360 361 362 363 364 goto end_2;/* failure */365 366 367 368 pe_header = (PIMAGE_NT_HEADERS)(peimage+dheader->e_lfanew);/* it is a pe header, SHELL_GetResourceTable checked that */369 pe_sections = (PIMAGE_SECTION_HEADER)(((char*)pe_header)+sizeof(*pe_header));/* probably makes problems with short PE headers...*/370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 goto end_4;/* failure */385 364 if( sig == IMAGE_NT_SIGNATURE) 365 { LPBYTE idata,igdata; 366 PIMAGE_DOS_HEADER dheader; 367 PIMAGE_NT_HEADERS pe_header; 368 PIMAGE_SECTION_HEADER pe_sections; 369 PIMAGE_RESOURCE_DIRECTORY rootresdir,iconresdir,icongroupresdir; 370 PIMAGE_RESOURCE_DATA_ENTRY idataent,igdataent; 371 PIMAGE_RESOURCE_DIRECTORY_ENTRY xresent; 372 int i,j; 373 374 if ( !(fmapping = CreateFileMappingA(hFile,NULL,PAGE_READONLY|SEC_COMMIT,0,0,NULL))) 375 { WARN("failed to create filemap.\n"); /* FIXME, INVALID_HANDLE_VALUE? */ 376 hRet = ICO_INVALID_FILE; 377 goto end_2; /* failure */ 378 } 379 380 if ( !(peimage = (BYTE*)MapViewOfFile(fmapping,FILE_MAP_READ,0,0,0))) 381 { WARN("failed to mmap filemap.\n"); 382 hRet = ICO_INVALID_FILE; 383 goto end_2; /* failure */ 384 } 385 386 dheader = (PIMAGE_DOS_HEADER)peimage; 387 pe_header = (PIMAGE_NT_HEADERS)(peimage+dheader->e_lfanew); /* it is a pe header, SHELL_GetResourceTable checked that */ 388 pe_sections = (PIMAGE_SECTION_HEADER)(((char*)pe_header)+sizeof(*pe_header)); /* probably makes problems with short PE headers...*/ 389 rootresdir = NULL; 390 391 for (i=0;i<pe_header->FileHeader.NumberOfSections;i++) 392 { if (pe_sections[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) 393 continue; 394 /* FIXME: doesn't work when the resources are not in a seperate section */ 395 if (pe_sections[i].VirtualAddress == pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress) 396 { rootresdir = (PIMAGE_RESOURCE_DIRECTORY)((char*)peimage+pe_sections[i].PointerToRawData); 397 break; 398 } 399 } 400 401 if (!rootresdir) 402 { WARN("haven't found section for resource directory.\n"); 403 goto end_4; /* failure */ 404 } 386 405 /* search the group icon dir*/ 387 388 389 goto end_4;/* failure */390 391 406 if (!(icongroupresdir = GetResDirEntryW(rootresdir,RT_GROUP_ICONW, (DWORD)rootresdir,FALSE))) 407 { WARN("No Icongroupresourcedirectory!\n"); 408 goto end_4; /* failure */ 409 } 410 iconDirCount = icongroupresdir->NumberOfNamedEntries+icongroupresdir->NumberOfIdEntries; 392 411 393 412 /* number of icons requested */ 394 395 396 goto end_3;/* success */397 398 399 400 401 goto end_4;/* failure */402 403 404 xresent = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(icongroupresdir+1);/* caller just wanted the number of entries */405 406 if( n > iconDirCount - nIconIndex )/* assure we don't get too much ... */407 408 409 410 xresent = xresent+nIconIndex;/* starting from specified index ... */411 412 413 { PIMAGE_RESOURCE_DIRECTORYresdir;414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 goto end_4;/* failure */436 437 438 439 440 441 442 goto end_4;/* failure */443 444 445 446 { PIMAGE_RESOURCE_DIRECTORYxresdir;447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 hRet = RetPtr[0];/* return first icon */468 goto end_3;/* sucess */469 470 471 goto end_1;/* unknown filetype */413 if( nIconIndex == -1 ) 414 { hRet = iconDirCount; 415 goto end_3; /* success */ 416 } 417 418 if (nIconIndex >= iconDirCount) 419 { WARN("nIconIndex %d is larger than iconDirCount %d\n",nIconIndex,iconDirCount); 420 goto end_4; /* failure */ 421 } 422 423 xresent = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(icongroupresdir+1); /* caller just wanted the number of entries */ 424 425 if( n > iconDirCount - nIconIndex ) /* assure we don't get too much ... */ 426 { n = iconDirCount - nIconIndex; 427 } 428 429 xresent = xresent+nIconIndex; /* starting from specified index ... */ 430 431 for (i=0;i<n;i++,xresent++) 432 { PIMAGE_RESOURCE_DIRECTORY resdir; 433 434 /* go down this resource entry, name */ 435 resdir = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)rootresdir+(xresent->u2.s.OffsetToDirectory)); 436 437 /* default language (0) */ 438 resdir = GetResDirEntryW(resdir,(LPWSTR)0,(DWORD)rootresdir,TRUE); 439 igdataent = (PIMAGE_RESOURCE_DATA_ENTRY)resdir; 440 441 /* lookup address in mapped image for virtual address */ 442 igdata = NULL; 443 444 for (j=0;j<pe_header->FileHeader.NumberOfSections;j++) 445 { if (igdataent->OffsetToData < pe_sections[j].VirtualAddress) 446 continue; 447 if (igdataent->OffsetToData+igdataent->Size > pe_sections[j].VirtualAddress+pe_sections[j].SizeOfRawData) 448 continue; 449 igdata = peimage+(igdataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData); 450 } 451 452 if (!igdata) 453 { WARN("no matching real address for icongroup!\n"); 454 goto end_4; /* failure */ 455 } 456 RetPtr[i] = (HICON)pLookupIconIdFromDirectoryEx(igdata, TRUE, cxDesired, cyDesired, LR_DEFAULTCOLOR); 457 } 458 459 if (!(iconresdir=GetResDirEntryW(rootresdir,RT_ICONW,(DWORD)rootresdir,FALSE))) 460 { WARN("No Iconresourcedirectory!\n"); 461 goto end_4; /* failure */ 462 } 463 464 for (i=0;i<n;i++) 465 { PIMAGE_RESOURCE_DIRECTORY xresdir; 466 xresdir = GetResDirEntryW(iconresdir,(LPWSTR)(DWORD)RetPtr[i],(DWORD)rootresdir,FALSE); 467 xresdir = GetResDirEntryW(xresdir,(LPWSTR)0,(DWORD)rootresdir,TRUE); 468 idataent = (PIMAGE_RESOURCE_DATA_ENTRY)xresdir; 469 idata = NULL; 470 471 /* map virtual to address in image */ 472 for (j=0;j<pe_header->FileHeader.NumberOfSections;j++) 473 { if (idataent->OffsetToData < pe_sections[j].VirtualAddress) 474 continue; 475 if (idataent->OffsetToData+idataent->Size > pe_sections[j].VirtualAddress+pe_sections[j].SizeOfRawData) 476 continue; 477 idata = peimage+(idataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData); 478 } 479 if (!idata) 480 { WARN("no matching real address found for icondata!\n"); 481 RetPtr[i]=0; 482 continue; 483 } 484 RetPtr[i] = (HICON) pCreateIconFromResourceEx(idata,idataent->Size,TRUE,0x00030000, cxDesired, cyDesired, LR_DEFAULTCOLOR); 485 } 486 hRet = RetPtr[0]; /* return first icon */ 487 goto end_3; /* sucess */ 488 } 489 hRet = ICO_INVALID_FILE; 490 goto end_1; /* unknown filetype */ 472 491 473 492 /* cleaning up (try & catch would be nicer:-) ) */ 474 end_4: hRet = 0;/* failure */475 end_3: UnmapViewOfFile(peimage);/* success */476 end_2: 477 end_1: 478 493 end_4: hRet = 0; /* failure */ 494 end_3: UnmapViewOfFile(peimage); /* success */ 495 end_2: CloseHandle(fmapping); 496 end_1: _lclose( hFile); 497 return hRet; 479 498 } 480 499 #endif … … 485 504 486 505 typedef struct 487 { LPCSTR sSourceFile;/* file (not path!) containing the icon */488 DWORD dwSourceIndex;/* index within the file, if it is a resoure ID it will be negated */489 DWORD dwListIndex;/* index within the iconlist */490 DWORD dwFlags;/* GIL_* flags */491 506 { LPCSTR sSourceFile; /* file (not path!) containing the icon */ 507 DWORD dwSourceIndex; /* index within the file, if it is a resoure ID it will be negated */ 508 DWORD dwListIndex; /* index within the iconlist */ 509 DWORD dwFlags; /* GIL_* flags */ 510 DWORD dwAccessTime; 492 511 } SIC_ENTRY, * LPSIC_ENTRY; 493 512 494 513 /***************************************************************************** 495 * SIC_CompareEntrys 514 * SIC_CompareEntrys [called by comctl32.dll] 496 515 * 497 516 * NOTES … … 499 518 */ 500 519 INT CALLBACK SIC_CompareEntrys( LPVOID p1, LPVOID p2, LPARAM lparam) 501 { TRACE("%p %p\n", p1, p2);502 503 504 505 506 507 508 509 520 { dprintf(("SHELL32:Iconcache SIC_CompareEntrys %p %p\n", p1, p2)); 521 522 if (((LPSIC_ENTRY)p1)->dwSourceIndex != ((LPSIC_ENTRY)p2)->dwSourceIndex) /* first the faster one*/ 523 return 1; 524 525 if (strcmp(((LPSIC_ENTRY)p1)->sSourceFile,((LPSIC_ENTRY)p2)->sSourceFile)) 526 return 1; 527 528 return 0; 510 529 } 511 530 /***************************************************************************** 512 * SIC_IconAppend 531 * SIC_IconAppend [internal] 513 532 * 514 533 * NOTES … … 516 535 */ 517 536 static INT SIC_IconAppend (LPCSTR sSourceFile, INT dwSourceIndex, HICON hSmallIcon, HICON hBigIcon) 518 { 519 520 521 TRACE("%s %i %x %x\n", sSourceFile, dwSourceIndex, hSmallIcon ,hBigIcon);522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 FIXME("iconlists out of sync 0x%x 0x%x\n", index, index1);544 545 546 547 548 549 550 return ret; 537 { LPSIC_ENTRY lpsice; 538 INT ret, index, index1; 539 540 dprintf(("SHELL32:Iconcache SIC_IconAppend %s %i %x %x\n", sSourceFile, dwSourceIndex, hSmallIcon ,hBigIcon)); 541 542 lpsice = (LPSIC_ENTRY) SHAlloc (sizeof (SIC_ENTRY)); 543 544 lpsice->sSourceFile = HEAP_strdupA (GetProcessHeap(), 0, PathFindFilenameA(sSourceFile)); 545 lpsice->dwSourceIndex = dwSourceIndex; 546 547 EnterCriticalSection(&SHELL32_SicCS); 548 549 index = pDPA_InsertPtr(sic_hdpa, 0x7fff, lpsice); 550 if ( INVALID_INDEX == index ) 551 { 552 SHFree(lpsice); 553 ret = INVALID_INDEX; 554 } 555 else 556 { 557 index = pImageList_AddIcon (ShellSmallIconList, hSmallIcon); 558 index1= pImageList_AddIcon (ShellBigIconList, hBigIcon); 559 560 if (index!=index1) 561 { 562 dprintf(("iconlists out of sync 0x%x 0x%x\n", index, index1)); 563 } 564 lpsice->dwListIndex = index; 565 ret = lpsice->dwListIndex; 566 } 567 568 LeaveCriticalSection(&SHELL32_SicCS); 569 return ret; 551 570 } 552 571 /**************************************************************************** 553 * SIC_LoadIcon 572 * SIC_LoadIcon [internal] 554 573 * 555 574 * NOTES … … 557 576 */ 558 577 static INT SIC_LoadIcon (LPCSTR sSourceFile, INT dwSourceIndex) 559 { HICONhiconLarge=0;560 HICONhiconSmall=0;561 562 563 564 565 566 567 568 WARN("failure loading icon %i from %s (%x %x)\n", dwSourceIndex, sSourceFile, hiconLarge, hiconSmall);569 570 571 return SIC_IconAppend (sSourceFile, dwSourceIndex, hiconSmall, hiconLarge); 578 { HICON hiconLarge=0; 579 HICON hiconSmall=0; 580 581 ICO_ExtractIconEx(sSourceFile, &hiconLarge, dwSourceIndex, 1, 32, 32 ); 582 ICO_ExtractIconEx(sSourceFile, &hiconSmall, dwSourceIndex, 1, 16, 16 ); 583 584 585 if ( !hiconLarge || !hiconSmall) 586 { 587 dprintf(("failure loading icon %i from %s (%x %x)\n", dwSourceIndex, sSourceFile, hiconLarge, hiconSmall)); 588 return -1; 589 } 590 return SIC_IconAppend (sSourceFile, dwSourceIndex, hiconSmall, hiconLarge); 572 591 } 573 592 /***************************************************************************** 574 * SIC_GetIconIndex 593 * SIC_GetIconIndex [internal] 575 594 * 576 595 * Parameters 577 * sSourceFile [IN]filename of file containing the icon578 * index [IN]index/resID (negated) in this file596 * sSourceFile [IN] filename of file containing the icon 597 * index [IN] index/resID (negated) in this file 579 598 * 580 599 * NOTES … … 583 602 */ 584 603 INT SIC_GetIconIndex (LPCSTR sSourceFile, INT dwSourceIndex ) 585 { 586 587 588 TRACE("%s %i\n", sSourceFile, dwSourceIndex);589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 TRACE("-- found\n");607 608 609 610 611 604 { SIC_ENTRY sice; 605 INT ret, index = INVALID_INDEX; 606 607 dprintf(("SHELL32:Iconcache SIC_GetIconIndex %s %i\n", sSourceFile, dwSourceIndex)); 608 609 sice.sSourceFile = PathFindFilenameA(sSourceFile); 610 sice.dwSourceIndex = dwSourceIndex; 611 612 EnterCriticalSection(&SHELL32_SicCS); 613 614 if (NULL != pDPA_GetPtr (sic_hdpa, 0)) 615 { 616 index = pDPA_Search (sic_hdpa, &sice, -1L, (PFNDPACOMPARE)SIC_CompareEntrys, 0, 0); 617 } 618 619 if ( INVALID_INDEX == index ) 620 { 621 ret = SIC_LoadIcon (sSourceFile, dwSourceIndex); 622 } 623 else 624 { 625 dprintf(("SHELL32:Iconcache -- found\n")); 626 ret = ((LPSIC_ENTRY)pDPA_GetPtr(sic_hdpa, index))->dwListIndex; 627 } 628 629 LeaveCriticalSection(&SHELL32_SicCS); 630 return ret; 612 631 } 613 632 /**************************************************************************** 614 * SIC_LoadIcon 633 * SIC_LoadIcon [internal] 615 634 * 616 635 * NOTES … … 618 637 */ 619 638 static HICON WINE_UNUSED SIC_GetIcon (LPCSTR sSourceFile, INT dwSourceIndex, BOOL bSmallIcon ) 620 { 621 622 TRACE("%s %i\n", sSourceFile, dwSourceIndex);623 624 625 626 627 628 629 630 631 632 633 634 639 { INT index; 640 641 dprintf(("SHELL32:Iconcache SIC_GetIcon %s %i\n", sSourceFile, dwSourceIndex)); 642 643 index = SIC_GetIconIndex(sSourceFile, dwSourceIndex); 644 645 if (INVALID_INDEX == index) 646 { 647 return INVALID_INDEX; 648 } 649 650 if (bSmallIcon) 651 return pImageList_GetIcon(ShellSmallIconList, index, ILD_NORMAL); 652 return pImageList_GetIcon(ShellBigIconList, index, ILD_NORMAL); 653 635 654 } 636 655 /***************************************************************************** 637 * SIC_Initialize 656 * SIC_Initialize [internal] 638 657 * 639 658 * NOTES … … 643 662 BOOL SIC_Initialize(void) 644 663 { 645 HICONhSm, hLg;646 UINTindex;647 648 TRACE("\n");649 650 if (sic_hdpa)/* already initialized?*/651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 TRACE("hIconSmall=%p hIconBig=%p\n",ShellSmallIconList, ShellBigIconList);682 683 664 HICON hSm, hLg; 665 UINT index; 666 667 dprintf(("SHELL32:Iconcache SIC_Initialize\n")); 668 669 if (sic_hdpa) /* already initialized?*/ 670 return TRUE; 671 672 InitializeCriticalSection(&SHELL32_SicCS); 673 674 sic_hdpa = pDPA_Create(16); 675 676 if (!sic_hdpa) 677 { 678 return(FALSE); 679 } 680 681 ShellSmallIconList = pImageList_Create(16,16,ILC_COLORDDB | ILC_MASK,0,0x20); 682 ShellBigIconList = pImageList_Create(32,32,ILC_COLORDDB | ILC_MASK,0,0x20); 683 684 pImageList_SetBkColor(ShellSmallIconList, GetSysColor(COLOR_WINDOW)); 685 pImageList_SetBkColor(ShellBigIconList, GetSysColor(COLOR_WINDOW)); 686 687 for (index=1; index<39; index++) 688 { 689 hSm = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(index), IMAGE_ICON, 16, 16,LR_SHARED); 690 hLg = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(index), IMAGE_ICON, 32, 32,LR_SHARED); 691 692 if(!hSm) 693 { 694 hSm = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(0), IMAGE_ICON, 16, 16,LR_SHARED); 695 hLg = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(0), IMAGE_ICON, 32, 32,LR_SHARED); 696 } 697 SIC_IconAppend ("shell32.dll", index, hSm, hLg); 698 } 699 700 dprintf(("SHELL32:Iconcache hIconSmall=%p hIconBig=%p\n",ShellSmallIconList, ShellBigIconList)); 701 702 return TRUE; 684 703 } 685 704 /************************************************************************* … … 690 709 void SIC_Destroy(void) 691 710 { 692 693 694 695 TRACE("\n");696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 } 713 /************************************************************************* 714 * Shell_GetImageList 711 LPSIC_ENTRY lpsice; 712 int i; 713 714 dprintf(("SHELL32:Iconcache SIC_Destroy\n")); 715 716 EnterCriticalSection(&SHELL32_SicCS); 717 718 if (sic_hdpa && NULL != pDPA_GetPtr (sic_hdpa, 0)) 719 { 720 for (i=0; i < pDPA_GetPtrCount(sic_hdpa); ++i) 721 { 722 lpsice = (LPSIC_ENTRY)pDPA_GetPtr(sic_hdpa, i); 723 SHFree(lpsice); 724 } 725 pDPA_Destroy(sic_hdpa); 726 } 727 728 sic_hdpa = NULL; 729 730 LeaveCriticalSection(&SHELL32_SicCS); 731 } 732 /************************************************************************* 733 * Shell_GetImageList [SHELL32.71] 715 734 * 716 735 * PARAMETERS … … 718 737 * 719 738 */ 720 BOOL WINAPI Shell_GetImageList(HIMAGELIST * lpBigList, HIMAGELIST * lpSmallList) 721 { TRACE("(%p,%p)\n",lpBigList,lpSmallList); 722 if (lpBigList) 723 { *lpBigList = ShellBigIconList; 724 } 725 if (lpSmallList) 726 { *lpSmallList = ShellSmallIconList; 727 } 728 729 return TRUE; 730 } 731 /************************************************************************* 732 * PidlToSicIndex [INTERNAL] 739 740 ODINFUNCTION2(BOOL,Shell_GetImageList,HIMAGELIST*, lpBigList, 741 HIMAGELIST*, lpSmallList) 742 { 743 if (lpBigList) 744 { *lpBigList = ShellBigIconList; 745 } 746 if (lpSmallList) 747 { *lpSmallList = ShellSmallIconList; 748 } 749 750 return TRUE; 751 } 752 /************************************************************************* 753 * PidlToSicIndex [INTERNAL] 733 754 * 734 755 * PARAMETERS 735 * sh [IN]IShellFolder736 * pidl[IN]737 * 738 * pIndex [OUT]index within the SIC756 * sh [IN] IShellFolder 757 * pidl [IN] 758 * bBigIcon [IN] 759 * pIndex [OUT] index within the SIC 739 760 * 740 761 */ 741 762 BOOL PidlToSicIndex (IShellFolder * sh, LPITEMIDLIST pidl, BOOL bBigIcon, UINT * pIndex) 742 { 743 IExtractIcon*ei;744 char szIconFile[MAX_PATH];/* file containing the icon */745 INT iSourceIndex;/* index or resID(negated) in this file */746 BOOLret = FALSE;747 UINTdwFlags = 0;748 749 TRACE("sf=%p pidl=%p\n", sh, pidl);750 751 752 753 754 755 756 757 758 759 760 if (INVALID_INDEX == *pIndex)/* default icon when failed */761 762 763 764 765 } 766 767 /************************************************************************* 768 * SHMapPIDLToSystemImageListIndex 763 { 764 IExtractIcon *ei; 765 char szIconFile[MAX_PATH]; /* file containing the icon */ 766 INT iSourceIndex; /* index or resID(negated) in this file */ 767 BOOL ret = FALSE; 768 UINT dwFlags = 0; 769 770 dprintf(("SHELL32:Iconcache PidlToSicIndex sf=%p pidl=%p\n", sh, pidl)); 771 772 if (SUCCEEDED (IShellFolder_GetUIObjectOf(sh, 0, 1, &pidl, &IID_IExtractIconA, 0, (void **)&ei))) 773 { 774 if (NOERROR==IExtractIconA_GetIconLocation(ei, 0, szIconFile, MAX_PATH, &iSourceIndex, &dwFlags)) 775 { *pIndex = SIC_GetIconIndex(szIconFile, iSourceIndex); 776 ret = TRUE; 777 } 778 IExtractIconA_Release(ei); 779 } 780 781 if (INVALID_INDEX == *pIndex) /* default icon when failed */ 782 *pIndex = 1; 783 784 return ret; 785 786 } 787 788 /************************************************************************* 789 * SHMapPIDLToSystemImageListIndex [SHELL32.77] 769 790 * 770 791 * PARAMETERS 771 * sh [IN] pointer to an instance of IShellFolder 772 * pidl [IN] 773 * pIndex [OUT][OPTIONAL] SIC index for big icon 774 * 775 */ 776 UINT WINAPI SHMapPIDLToSystemImageListIndex(LPSHELLFOLDER sh, LPITEMIDLIST pidl, UINT * pIndex) 777 { 778 UINT Index; 779 780 TRACE("(SF=%p,pidl=%p,%p)\n",sh,pidl,pIndex); 781 pdump(pidl); 782 783 if (pIndex) 784 PidlToSicIndex ( sh, pidl, 1, pIndex); 785 PidlToSicIndex ( sh, pidl, 0, &Index); 786 return Index; 787 } 788 789 /************************************************************************* 790 * Shell_GetCachedImageIndex [SHELL32.72] 791 * 792 */ 793 INT WINAPI Shell_GetCachedImageIndexA(LPCSTR szPath, INT nIndex, BOOL bSimulateDoc) 794 { 795 WARN("(%s,%08x,%08x) semi-stub.\n",debugstr_a(szPath), nIndex, bSimulateDoc); 796 return SIC_GetIconIndex(szPath, nIndex); 797 } 798 799 INT WINAPI Shell_GetCachedImageIndexW(LPCWSTR szPath, INT nIndex, BOOL bSimulateDoc) 800 { INT ret; 801 LPSTR sTemp = HEAP_strdupWtoA (GetProcessHeap(),0,szPath); 802 803 WARN("(%s,%08x,%08x) semi-stub.\n",debugstr_w(szPath), nIndex, bSimulateDoc); 804 805 ret = SIC_GetIconIndex(sTemp, nIndex); 806 HeapFree(GetProcessHeap(),0,sTemp); 807 return ret; 808 } 809 810 INT WINAPI Shell_GetCachedImageIndexAW(LPCVOID szPath, INT nIndex, BOOL bSimulateDoc) 811 { if( VERSION_OsIsUnicode()) 812 return Shell_GetCachedImageIndexW((LPWSTR)szPath, nIndex, bSimulateDoc); 813 return Shell_GetCachedImageIndexA((LPSTR)szPath, nIndex, bSimulateDoc); 814 } 815 816 /************************************************************************* 817 * ExtracticonExAW [shell32.189] 818 */ 819 HICON WINAPI ExtractIconExAW ( LPCVOID lpszFile, INT nIconIndex, HICON * phiconLarge, HICON * phiconSmall, UINT nIcons ) 820 { if (VERSION_OsIsUnicode()) 821 return ExtractIconExW ( (LPWSTR)lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons); 822 return ExtractIconExA ( (LPSTR)lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons); 823 } 824 /************************************************************************* 825 * ExtracticonExA [shell32.190] 792 * sh [IN] pointer to an instance of IShellFolder 793 * pidl [IN] 794 * pIndex [OUT][OPTIONAL] SIC index for big icon 795 * 796 */ 797 798 ODINFUNCTION3(UINT,SHMapPIDLToSystemImageListIndex,LPSHELLFOLDER, sh, 799 LPITEMIDLIST, pidl, 800 UINT*, pIndex) 801 { 802 UINT Index; 803 804 pdump(pidl); 805 806 if (pIndex) 807 PidlToSicIndex ( sh, pidl, 1, pIndex); 808 PidlToSicIndex ( sh, pidl, 0, &Index); 809 return Index; 810 } 811 812 /************************************************************************* 813 * Shell_GetCachedImageIndex [SHELL32.72] 814 * 815 */ 816 ODINFUNCTION3(INT,Shell_GetCachedImageIndexA,LPCSTR,szPath, 817 INT, nIndex, 818 BOOL, bSimulateDoc) 819 { 820 dprintf(("(%s,%08x,%08x) semi-stub.\n",debugstr_a(szPath), nIndex, bSimulateDoc)); 821 return SIC_GetIconIndex(szPath, nIndex); 822 } 823 824 ODINFUNCTION3(INT,Shell_GetCachedImageIndexW,LPCWSTR, szPath, 825 INT, nIndex, 826 BOOL, bSimulateDoc) 827 { INT ret; 828 LPSTR sTemp = HEAP_strdupWtoA (GetProcessHeap(),0,szPath); 829 830 dprintf(("(%s,%08x,%08x) semi-stub.\n",debugstr_w(szPath), nIndex, bSimulateDoc)); 831 832 ret = SIC_GetIconIndex(sTemp, nIndex); 833 HeapFree(GetProcessHeap(),0,sTemp); 834 return ret; 835 } 836 837 ODINFUNCTION3(INT,Shell_GetCachedImageIndexAW,LPCVOID, szPath, 838 INT, nIndex, 839 BOOL, bSimulateDoc) 840 { if( VERSION_OsIsUnicode()) 841 return Shell_GetCachedImageIndexW((LPWSTR)szPath, nIndex, bSimulateDoc); 842 return Shell_GetCachedImageIndexA((LPSTR)szPath, nIndex, bSimulateDoc); 843 } 844 845 /************************************************************************* 846 * ExtracticonExAW [shell32.189] 847 */ 848 849 ODINFUNCTION5(HICON,ExtractIconExAW,LPCVOID, lpszFile, 850 INT, nIconIndex, 851 HICON*, phiconLarge, 852 HICON*, phiconSmall, 853 UINT, nIcons) 854 { if (VERSION_OsIsUnicode()) 855 return ExtractIconExW ( (LPWSTR)lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons); 856 return ExtractIconExA ( (LPSTR)lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons); 857 } 858 /************************************************************************* 859 * ExtracticonExA [shell32.190] 826 860 * RETURNS 827 861 * 0 no icon found … … 829 863 * HICON handle of a icon (phiconLarge/Small == NULL) 830 864 */ 831 HICON WINAPI ExtractIconExA ( LPCSTR lpszFile, INT nIconIndex, HICON * phiconLarge, HICON * phiconSmall, UINT nIcons ) 832 { HICON ret=0; 833 834 TRACE("file=%s idx=%i %p %p num=%i\n", lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons ); 835 836 if (nIconIndex==-1) /* Number of icons requested */ 837 return ICO_ExtractIconEx(lpszFile, NULL, -1, 0, 0, 0 ); 838 839 840 if (phiconLarge) 841 { ret = ICO_ExtractIconEx(lpszFile, phiconLarge, nIconIndex, nIcons, 32, 32 ); 842 if ( nIcons==1) 843 { ret = phiconLarge[0]; 844 } 845 } 846 847 /* if no pointers given and one icon expected, return the handle directly*/ 848 if (!phiconLarge && ! phiconSmall && nIcons==1 ) 849 phiconSmall = &ret; 850 851 if (phiconSmall) 852 { ret = ICO_ExtractIconEx(lpszFile, phiconSmall, nIconIndex, nIcons, 16, 16 ); 853 if ( nIcons==1 ) 854 { ret = phiconSmall[0]; 855 } 856 } 857 858 return ret; 859 } 860 /************************************************************************* 861 * ExtracticonExW [shell32.191] 862 */ 863 HICON WINAPI ExtractIconExW ( LPCWSTR lpszFile, INT nIconIndex, HICON * phiconLarge, HICON * phiconSmall, UINT nIcons ) 864 { LPSTR sFile; 865 DWORD ret; 866 867 TRACE("file=%s idx=%i %p %p num=%i\n", debugstr_w(lpszFile), nIconIndex, phiconLarge, phiconSmall, nIcons ); 868 869 sFile = HEAP_strdupWtoA (GetProcessHeap(),0,lpszFile); 870 ret = ExtractIconExA ( sFile, nIconIndex, phiconLarge, phiconSmall, nIcons); 871 HeapFree(GetProcessHeap(),0,sFile); 872 return ret; 873 } 865 866 ODINFUNCTION5(HICON,ExtractIconExA, LPCSTR, lpszFile, 867 INT, nIconIndex, 868 HICON*, phiconLarge, 869 HICON*, phiconSmall, 870 UINT, nIcons) 871 { HICON ret=0; 872 873 dprintf(("SHELL32:Iconcache file=%s idx=%i %p %p num=%i\n", lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons )); 874 875 if (nIconIndex==-1) /* Number of icons requested */ 876 return ICO_ExtractIconEx(lpszFile, NULL, -1, 0, 0, 0 ); 877 878 879 if (phiconLarge) 880 { ret = ICO_ExtractIconEx(lpszFile, phiconLarge, nIconIndex, nIcons, 32, 32 ); 881 if ( nIcons==1) 882 { ret = phiconLarge[0]; 883 } 884 } 885 886 /* if no pointers given and one icon expected, return the handle directly*/ 887 if (!phiconLarge && ! phiconSmall && nIcons==1 ) 888 phiconSmall = &ret; 889 890 if (phiconSmall) 891 { ret = ICO_ExtractIconEx(lpszFile, phiconSmall, nIconIndex, nIcons, 16, 16 ); 892 if ( nIcons==1 ) 893 { ret = phiconSmall[0]; 894 } 895 } 896 897 return ret; 898 } 899 /************************************************************************* 900 * ExtracticonExW [shell32.191] 901 */ 902 ODINFUNCTION5(HICON,ExtractIconExW,LPCWSTR, lpszFile, 903 INT, nIconIndex, 904 HICON*, phiconLarge, 905 HICON*, phiconSmall, 906 UINT, nIcons) 907 { LPSTR sFile; 908 DWORD ret; 909 910 dprintf(("SHELL32:Iconcache file=%s idx=%i %p %p num=%i\n", debugstr_w(lpszFile), nIconIndex, phiconLarge, phiconSmall, nIcons )); 911 912 sFile = HEAP_strdupWtoA (GetProcessHeap(),0,lpszFile); 913 ret = ExtractIconExA ( sFile, nIconIndex, phiconLarge, phiconSmall, nIcons); 914 HeapFree(GetProcessHeap(),0,sFile); 915 return ret; 916 }
Note:
See TracChangeset
for help on using the changeset viewer.