ReactOS  0.4.15-dev-321-g2d9b385
exticon.c
Go to the documentation of this file.
1 /*
2  * icon extracting
3  *
4  * taken and slightly changed from shell
5  * this should replace the icon extraction code in shell32 and shell16 once
6  * it needs a serious test for compliance with the native API
7  *
8  * Copyright 2000 Juergen Schmied
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #include <user32.h>
26 
27 #ifndef ARRAY_SIZE
28 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
29 #endif
30 
31 /* Start of Hack section */
32 
34 
35 #include <pshpack1.h>
36 
37 typedef struct
38 {
39  BYTE bWidth; /* Width, in pixels, of the image */
40  BYTE bHeight; /* Height, in pixels, of the image */
41  BYTE bColorCount; /* Number of colors in image (0 if >=8bpp) */
42  BYTE bReserved; /* Reserved ( must be 0) */
43  WORD wPlanes; /* Color Planes */
44  WORD wBitCount; /* Bits per pixel */
45  DWORD dwBytesInRes; /* How many bytes in this resource? */
46  DWORD dwImageOffset; /* Where in the file is this image? */
48 
49 typedef struct
50 {
51  WORD idReserved; /* Reserved (must be 0) */
52  WORD idType; /* Resource Type (RES_ICON or RES_CURSOR) */
53  WORD idCount; /* How many images */
54  icoICONDIRENTRY idEntries[1]; /* An entry for each image (idCount of 'em) */
56 
57 typedef struct
58 {
59  WORD offset;
60  WORD length;
61  WORD flags;
62  WORD id;
63  WORD handle;
64  WORD usage;
65 } NE_NAMEINFO;
66 
67 typedef struct
68 {
69  WORD type_id;
70  WORD count;
71  DWORD resloader;
72 } NE_TYPEINFO;
73 
74 #define NE_RSCTYPE_ICON 0x8003
75 #define NE_RSCTYPE_GROUP_ICON 0x800e
76 
77 #include <poppack.h>
78 
79 #if 0
80 static void dumpIcoDirEnty ( LPicoICONDIRENTRY entry )
81 {
82  TRACE("width = 0x%08x height = 0x%08x\n", entry->bWidth, entry->bHeight);
83  TRACE("colors = 0x%08x planes = 0x%08x\n", entry->bColorCount, entry->wPlanes);
84  TRACE("bitcount = 0x%08x bytesinres = 0x%08lx offset = 0x%08lx\n",
85  entry->wBitCount, entry->dwBytesInRes, entry->dwImageOffset);
86 }
87 static void dumpIcoDir ( LPicoICONDIR entry )
88 {
89  TRACE("type = 0x%08x count = 0x%08x\n", entry->idType, entry->idCount);
90 }
91 #endif
92 
93 #ifndef WINE
96  int cxDesired,
97  int cyDesired,
98  BOOL bIcon,
99  DWORD fuLoad,
100  POINT *ptHotSpot);
101 #endif
102 
103 /**********************************************************************
104  * find_entry_by_id
105  *
106  * Find an entry by id in a resource directory
107  * Copied from loader/pe_resource.c (FIXME: should use exported resource functions)
108  */
110  WORD id, const void *root )
111 {
113  int min, max, pos;
114 
115  entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1);
116  min = dir->NumberOfNamedEntries;
117  max = min + dir->NumberOfIdEntries - 1;
118  while (min <= max)
119  {
120  pos = (min + max) / 2;
121  if (entry[pos].Id == id)
122  return (const IMAGE_RESOURCE_DIRECTORY *)((const char *)root + entry[pos].OffsetToDirectory);
123  if (entry[pos].Id > id) max = pos - 1;
124  else min = pos + 1;
125  }
126  return NULL;
127 }
128 
129 /**********************************************************************
130  * find_entry_default
131  *
132  * Find a default entry in a resource directory
133  * Copied from loader/pe_resource.c (FIXME: should use exported resource functions)
134  */
136  const void *root )
137 {
139  entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1);
140  return (const IMAGE_RESOURCE_DIRECTORY *)((const char *)root + entry->OffsetToDirectory);
141 }
142 
143 /*************************************************************************
144  * USER32_GetResourceTable
145  */
146 static DWORD USER32_GetResourceTable(LPBYTE peimage,DWORD pesize,LPBYTE *retptr)
147 {
148  IMAGE_DOS_HEADER * mz_header;
149 
150  TRACE("%p %p\n", peimage, retptr);
151 
152  *retptr = NULL;
153 
154  mz_header = (IMAGE_DOS_HEADER*) peimage;
155 
156  if (mz_header->e_magic != IMAGE_DOS_SIGNATURE)
157  {
158  if (mz_header->e_cblp == 1 || mz_header->e_cblp == 2) /* .ICO or .CUR file ? */
159  {
160  *retptr = (LPBYTE)-1; /* ICONHEADER.idType, must be 1 */
161  return mz_header->e_cblp;
162  }
163  else
164  return 0; /* failed */
165  }
166  if (mz_header->e_lfanew >= pesize) {
167  return 0; /* failed, happens with PKZIP DOS Exes for instance. */
168  }
169  if (*((DWORD*)(peimage + mz_header->e_lfanew)) == IMAGE_NT_SIGNATURE )
170  return IMAGE_NT_SIGNATURE;
171 
172  if (*((WORD*)(peimage + mz_header->e_lfanew)) == IMAGE_OS2_SIGNATURE )
173  {
174  IMAGE_OS2_HEADER * ne_header;
175 
176  ne_header = (IMAGE_OS2_HEADER*)(peimage + mz_header->e_lfanew);
177 
178  if (ne_header->ne_magic != IMAGE_OS2_SIGNATURE)
179  return 0;
180 
181  if( (ne_header->ne_restab - ne_header->ne_rsrctab) <= sizeof(NE_TYPEINFO) )
182  *retptr = (LPBYTE)-1;
183  else
184  *retptr = peimage + mz_header->e_lfanew + ne_header->ne_rsrctab;
185 
186  return IMAGE_OS2_SIGNATURE;
187  }
188  return 0; /* failed */
189 }
190 /*************************************************************************
191  * USER32_LoadResource
192  */
193 static BYTE * USER32_LoadResource( LPBYTE peimage, NE_NAMEINFO* pNInfo, WORD sizeShift, ULONG *uSize)
194 {
195  TRACE("%p %p 0x%08x\n", peimage, pNInfo, sizeShift);
196 
197  *uSize = (DWORD)pNInfo->length << sizeShift;
198  return peimage + ((DWORD)pNInfo->offset << sizeShift);
199 }
200 
201 /*************************************************************************
202  * ICO_LoadIcon
203  */
204 static BYTE * ICO_LoadIcon( LPBYTE peimage, LPicoICONDIRENTRY lpiIDE, ULONG *uSize)
205 {
206  TRACE("%p %p\n", peimage, lpiIDE);
207 
208  *uSize = lpiIDE->dwBytesInRes;
209  return peimage + lpiIDE->dwImageOffset;
210 }
211 
212 /*************************************************************************
213  * ICO_GetIconDirectory
214  *
215  * Reads .ico file and build phony ICONDIR struct
216  */
217 static BYTE * ICO_GetIconDirectory( LPBYTE peimage, LPicoICONDIR* lplpiID, ULONG *uSize )
218 {
219  CURSORICONDIR * lpcid; /* icon resource in resource-dir format */
220  CURSORICONDIR * lpID; /* icon resource in resource format */
221  int i;
222 
223  TRACE("%p %p\n", peimage, lplpiID);
224 
225  lpcid = (CURSORICONDIR*)peimage;
226 
227  if( lpcid->idReserved || (lpcid->idType != 1) || (!lpcid->idCount) )
228  return 0;
229 
230  /* allocate the phony ICONDIR structure */
231  *uSize = FIELD_OFFSET(CURSORICONDIR, idEntries[lpcid->idCount]);
232  if( (lpID = HeapAlloc(GetProcessHeap(),0, *uSize) ))
233  {
234  /* copy the header */
235  lpID->idReserved = lpcid->idReserved;
236  lpID->idType = lpcid->idType;
237  lpID->idCount = lpcid->idCount;
238 
239  /* copy the entries */
240  for( i=0; i < lpcid->idCount; i++ )
241  {
242  memcpy(&lpID->idEntries[i], &lpcid->idEntries[i], sizeof(CURSORICONDIRENTRY) - 2);
243  lpID->idEntries[i].wResId = i;
244  }
245 
246  *lplpiID = (LPicoICONDIR)peimage;
247  return (BYTE *)lpID;
248  }
249  return 0;
250 }
251 
252 /*************************************************************************
253  * ICO_ExtractIconExW [internal]
254  *
255  * NOTES
256  * nIcons = 0: returns number of Icons in file
257  *
258  * returns
259  * invalid file: -1
260  * failure:0;
261  * success: number of icons in file (nIcons = 0) or nr of icons retrieved
262  */
264  LPCWSTR lpszExeFileName,
265  HICON * RetPtr,
266  INT nIconIndex,
267  UINT nIcons,
268  UINT cxDesired,
269  UINT cyDesired,
270  UINT *pIconId,
271  UINT flags)
272 {
273  UINT ret = 0;
274  UINT cx1, cx2, cy1, cy2;
275  LPBYTE pData;
276  DWORD sig;
277  HANDLE hFile;
278  UINT16 iconDirCount = 0,iconCount = 0;
279  LPBYTE peimage;
280  HANDLE fmapping;
281  DWORD fsizeh,fsizel;
282 #ifdef __REACTOS__
283  WCHAR szExpandedExePath[MAX_PATH];
284 #endif
285  WCHAR szExePath[MAX_PATH];
286  DWORD dwSearchReturn;
287 
288  TRACE("%s, %d, %d %p 0x%08x\n", debugstr_w(lpszExeFileName), nIconIndex, nIcons, pIconId, flags);
289 
290 #ifdef __REACTOS__
291  if (RetPtr)
292  *RetPtr = NULL;
293 
294  if (ExpandEnvironmentStringsW(lpszExeFileName, szExpandedExePath, ARRAY_SIZE(szExpandedExePath)))
295  lpszExeFileName = szExpandedExePath;
296 #endif
297 
298  dwSearchReturn = SearchPathW(NULL, lpszExeFileName, NULL, ARRAY_SIZE(szExePath), szExePath, NULL);
299  if ((dwSearchReturn == 0) || (dwSearchReturn > ARRAY_SIZE(szExePath)))
300  {
301  WARN("File %s not found or path too long\n", debugstr_w(lpszExeFileName));
302  return -1;
303  }
304 
306  if (hFile == INVALID_HANDLE_VALUE) return ret;
307  fsizel = GetFileSize(hFile,&fsizeh);
308 
309  /* Map the file */
310  fmapping = CreateFileMappingW(hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
312  if (!fmapping)
313  {
314  WARN("CreateFileMapping error %ld\n", GetLastError() );
315  return 0xFFFFFFFF;
316  }
317 
318  if (!(peimage = MapViewOfFile(fmapping, FILE_MAP_READ, 0, 0, 0)))
319  {
320  WARN("MapViewOfFile error %ld\n", GetLastError() );
321  CloseHandle(fmapping);
322  return 0xFFFFFFFF;
323  }
324  CloseHandle(fmapping);
325 
326  cx1 = LOWORD(cxDesired);
327  cx2 = HIWORD(cxDesired);
328  cy1 = LOWORD(cyDesired);
329  cy2 = HIWORD(cyDesired);
330 
331  if (pIconId) /* Invalidate first icon identifier */
332  *pIconId = 0xFFFFFFFF;
333 
334  if (!pIconId) /* if no icon identifier array present use the icon handle array as intermediate storage */
335  pIconId = (UINT*)RetPtr;
336 
337  sig = USER32_GetResourceTable(peimage, fsizel, &pData);
338 
339 /* NE exe/dll */
340  if (sig==IMAGE_OS2_SIGNATURE)
341  {
342  BYTE *pCIDir = 0;
343  NE_TYPEINFO *pTInfo = (NE_TYPEINFO*)(pData + 2);
344  NE_NAMEINFO *pIconStorage = NULL;
345  NE_NAMEINFO *pIconDir = NULL;
346  LPicoICONDIR lpiID = NULL;
347  ULONG uSize = 0;
348 
349  TRACE("-- OS2/icon Signature (0x%08x)\n", sig);
350 
351  if (pData == (BYTE*)-1)
352  {
353  pCIDir = ICO_GetIconDirectory(peimage, &lpiID, &uSize); /* check for .ICO file */
354  if (pCIDir)
355  {
356  iconDirCount = 1; iconCount = lpiID->idCount;
357  TRACE("-- icon found %p 0x%08x 0x%08x 0x%08x\n", pCIDir, uSize, iconDirCount, iconCount);
358  }
359  }
360  else while (pTInfo->type_id && !(pIconStorage && pIconDir))
361  {
362  if (pTInfo->type_id == NE_RSCTYPE_GROUP_ICON) /* find icon directory and icon repository */
363  {
364  iconDirCount = pTInfo->count;
365  pIconDir = ((NE_NAMEINFO*)(pTInfo + 1));
366  TRACE("\tfound directory - %i icon families\n", iconDirCount);
367  }
368  if (pTInfo->type_id == NE_RSCTYPE_ICON)
369  {
370  iconCount = pTInfo->count;
371  pIconStorage = ((NE_NAMEINFO*)(pTInfo + 1));
372  TRACE("\ttotal icons - %i\n", iconCount);
373  }
374  pTInfo = (NE_TYPEINFO *)((char*)(pTInfo+1)+pTInfo->count*sizeof(NE_NAMEINFO));
375  }
376 
377  if ((pIconStorage && pIconDir) || lpiID) /* load resources and create icons */
378  {
379  if (nIcons == 0)
380  {
381  ret = iconDirCount;
382  if (lpiID) /* *.ico file, deallocate heap pointer*/
383  HeapFree(GetProcessHeap(), 0, pCIDir);
384  }
385  else if (nIconIndex < iconDirCount)
386  {
387  UINT16 i, icon;
388  if (nIcons > iconDirCount - nIconIndex)
389  nIcons = iconDirCount - nIconIndex;
390 
391  for (i = 0; i < nIcons; i++)
392  {
393  /* .ICO files have only one icon directory */
394  if (lpiID == NULL) /* not *.ico */
395  pCIDir = USER32_LoadResource(peimage, pIconDir + i + nIconIndex, *(WORD*)pData, &uSize);
396  pIconId[i] = LookupIconIdFromDirectoryEx(pCIDir, TRUE, cx1, cy1, flags);
397  if (cx2 && cy2) pIconId[++i] = LookupIconIdFromDirectoryEx(pCIDir, TRUE, cx2, cy2, flags);
398  }
399  if (lpiID) /* *.ico file, deallocate heap pointer*/
400  HeapFree(GetProcessHeap(), 0, pCIDir);
401 
402  for (icon = 0; icon < nIcons; icon++)
403  {
404  pCIDir = NULL;
405  if (lpiID)
406  pCIDir = ICO_LoadIcon(peimage, lpiID->idEntries + (int)pIconId[icon], &uSize);
407  else
408  for (i = 0; i < iconCount; i++)
409  if (pIconStorage[i].id == ((int)pIconId[icon] | 0x8000) )
410  pCIDir = USER32_LoadResource(peimage, pIconStorage + i, *(WORD*)pData, &uSize);
411 
412  if (pCIDir)
413  {
414  RetPtr[icon] = CreateIconFromResourceEx(pCIDir, uSize, TRUE, 0x00030000,
415  cx1, cy1, flags);
416  if (cx2 && cy2)
417  RetPtr[++icon] = CreateIconFromResourceEx(pCIDir, uSize, TRUE, 0x00030000,
418  cx2, cy2, flags);
419  }
420  else
421  RetPtr[icon] = 0;
422  }
423  ret = icon; /* return number of retrieved icons */
424  }
425  }
426  }
427  else
428  if (sig == 1 || sig == 2) /* .ICO or .CUR file */
429  {
430  TRACE("-- icon Signature (0x%08x)\n", sig);
431 
432  if (pData == (BYTE*)-1)
433  {
434  INT cx[2] = {cx1, cx2}, cy[2] = {cy1, cy2};
435  INT index;
436 
437  for(index = 0; index < (cx2 || cy2 ? 2 : 1); index++)
438  {
439  DWORD dataOffset;
440  LPBYTE imageData;
441  POINT hotSpot;
443 
444  dataOffset = get_best_icon_file_offset(peimage, fsizel, cx[index], cy[index], sig == 1, flags, sig == 1 ? NULL : &hotSpot);
445 
446  if (dataOffset)
447  {
448  HICON icon;
449  WORD *cursorData = NULL;
450 
451  imageData = peimage + dataOffset;
452  entry = (LPICONIMAGE)(imageData);
453 
454  if(sig == 2)
455  {
456  /* we need to prepend the bitmap data with hot spots for CreateIconFromResourceEx */
457  cursorData = HeapAlloc(GetProcessHeap(), 0, entry->icHeader.biSizeImage + 2 * sizeof(WORD));
458 
459  if(!cursorData)
460  continue;
461 
462  cursorData[0] = hotSpot.x;
463  cursorData[1] = hotSpot.y;
464 
465  memcpy(cursorData + 2, imageData, entry->icHeader.biSizeImage);
466 
467  imageData = (LPBYTE)cursorData;
468  }
469 
470  icon = CreateIconFromResourceEx(imageData, entry->icHeader.biSizeImage, sig == 1, 0x00030000, cx[index], cy[index], flags);
471 
472  HeapFree(GetProcessHeap(), 0, cursorData);
473 
474  if (icon)
475  {
476  if (RetPtr)
477  RetPtr[index] = icon;
478  else
479  DestroyIcon(icon);
480 
481  iconCount = 1;
482  break;
483  }
484  }
485  }
486  }
487  ret = iconCount; /* return number of retrieved icons */
488  }
489 /* end ico file */
490 
491 /* exe/dll */
492  else if( sig == IMAGE_NT_SIGNATURE )
493  {
494  BYTE *idata, *igdata;
495  const IMAGE_RESOURCE_DIRECTORY *rootresdir, *iconresdir, *icongroupresdir;
496  const IMAGE_RESOURCE_DATA_ENTRY *idataent, *igdataent;
497  const IMAGE_RESOURCE_DIRECTORY_ENTRY *xresent;
498  ULONG size;
499  UINT i;
500 
502  if (!rootresdir)
503  {
504  WARN("haven't found section for resource directory.\n");
505  goto end;
506  }
507 
508  /* search for the group icon directory */
509  if (!(icongroupresdir = find_entry_by_id(rootresdir, LOWORD(RT_GROUP_ICON), rootresdir)))
510  {
511  WARN("No Icongroupresourcedirectory!\n");
512  goto end; /* failure */
513  }
514  iconDirCount = icongroupresdir->NumberOfNamedEntries + icongroupresdir->NumberOfIdEntries;
515 
516  /* only number of icons requested */
517  if( !pIconId )
518  {
519  ret = iconDirCount;
520  goto end; /* success */
521  }
522 
523  if( nIconIndex < 0 )
524  {
525  /* search resource id */
526  int n = 0;
527  int iId = abs(nIconIndex);
528  const IMAGE_RESOURCE_DIRECTORY_ENTRY* xprdeTmp = (const IMAGE_RESOURCE_DIRECTORY_ENTRY*)(icongroupresdir+1);
529 
530  while(n<iconDirCount && xprdeTmp)
531  {
532  if(xprdeTmp->Id == iId)
533  {
534  nIconIndex = n;
535  break;
536  }
537  n++;
538  xprdeTmp++;
539  }
540  if (nIconIndex < 0)
541  {
542  WARN("resource id %d not found\n", iId);
543  goto end; /* failure */
544  }
545  }
546  else
547  {
548  /* check nIconIndex to be in range */
549  if (nIconIndex >= iconDirCount)
550  {
551  WARN("nIconIndex %d is larger than iconDirCount %d\n",nIconIndex,iconDirCount);
552  goto end; /* failure */
553  }
554  }
555 
556  /* assure we don't get too much */
557  if( nIcons > iconDirCount - nIconIndex )
558  nIcons = iconDirCount - nIconIndex;
559 
560  /* starting from specified index */
561  xresent = (const IMAGE_RESOURCE_DIRECTORY_ENTRY*)(icongroupresdir+1) + nIconIndex;
562 
563  for (i=0; i < nIcons; i++,xresent++)
564  {
565  const IMAGE_RESOURCE_DIRECTORY *resdir;
566 
567  /* go down this resource entry, name */
568  resdir = (const IMAGE_RESOURCE_DIRECTORY *)((const char *)rootresdir + xresent->OffsetToDirectory);
569 
570  /* default language (0) */
571  resdir = find_entry_default(resdir,rootresdir);
572  igdataent = (const IMAGE_RESOURCE_DATA_ENTRY*)resdir;
573 
574  /* lookup address in mapped image for virtual address */
575  igdata = RtlImageRvaToVa(RtlImageNtHeader((HMODULE)peimage), (HMODULE)peimage, igdataent->OffsetToData, NULL);
576  if (!igdata)
577  {
578  FIXME("no matching real address for icongroup!\n");
579  goto end; /* failure */
580  }
581  pIconId[i] = LookupIconIdFromDirectoryEx(igdata, TRUE, cx1, cy1, flags);
582  if (cx2 && cy2) pIconId[++i] = LookupIconIdFromDirectoryEx(igdata, TRUE, cx2, cy2, flags);
583  }
584 
585  if (!(iconresdir=find_entry_by_id(rootresdir,LOWORD(RT_ICON),rootresdir)))
586  {
587  WARN("No Iconresourcedirectory!\n");
588  goto end; /* failure */
589  }
590 
591  for (i=0; i<nIcons; i++)
592  {
593  const IMAGE_RESOURCE_DIRECTORY *xresdir;
594  xresdir = find_entry_by_id(iconresdir, LOWORD(pIconId[i]), rootresdir);
595  if( !xresdir )
596  {
597  WARN("icon entry %d not found\n", LOWORD(pIconId[i]));
598  RetPtr[i]=0;
599  continue;
600  }
601  xresdir = find_entry_default(xresdir, rootresdir);
602  idataent = (const IMAGE_RESOURCE_DATA_ENTRY*)xresdir;
603 
604  idata = RtlImageRvaToVa(RtlImageNtHeader((HMODULE)peimage), (HMODULE)peimage, idataent->OffsetToData, NULL);
605  if (!idata)
606  {
607  WARN("no matching real address found for icondata!\n");
608  RetPtr[i]=0;
609  continue;
610  }
611  RetPtr[i] = CreateIconFromResourceEx(idata, idataent->Size, TRUE, 0x00030000, cx1, cy1, flags);
612  if (cx2 && cy2)
613  RetPtr[++i] = CreateIconFromResourceEx(idata, idataent->Size, TRUE, 0x00030000, cx2, cy2, flags);
614  }
615  ret = i; /* return number of retrieved icons */
616  } /* if(sig == IMAGE_NT_SIGNATURE) */
617 
618 end:
619  UnmapViewOfFile(peimage); /* success */
620  return ret;
621 }
622 
623 /***********************************************************************
624  * PrivateExtractIconsW [USER32.@]
625  *
626  * NOTES
627  * If HIWORD(sizeX) && HIWORD(sizeY) 2 * ((nIcons + 1) MOD 2) icons are
628  * returned, with the LOWORD size icon first and the HIWORD size icon
629  * second.
630  * Also the Windows equivalent does extract icons in a strange way if
631  * nIndex is negative. Our implementation treats a negative nIndex as
632  * looking for that resource identifier for the first icon to retrieve.
633  *
634  * FIXME:
635  * should also support 16 bit EXE + DLLs, cursor and animated cursor as
636  * well as bitmap files.
637  */
638 
640  LPCWSTR lpwstrFile,
641  int nIndex,
642  int sizeX,
643  int sizeY,
644  HICON * phicon, /* [out] pointer to array of nIcons HICON handles */
645  UINT* pIconId, /* [out] pointer to array of nIcons icon identifiers or NULL */
646  UINT nIcons, /* [in] number of icons to retrieve */
647  UINT flags ) /* [in] LR_* flags used by LoadImage */
648 {
649  TRACE("%s %d %dx%d %p %p %d 0x%08x\n",
650  debugstr_w(lpwstrFile), nIndex, sizeX, sizeY, phicon, pIconId, nIcons, flags);
651 
652  if ((nIcons & 1) && HIWORD(sizeX) && HIWORD(sizeY))
653  {
654  WARN("Uneven number %d of icons requested for small and large icons!\n", nIcons);
655  }
656  return ICO_ExtractIconExW(lpwstrFile, phicon, nIndex, nIcons, sizeX, sizeY, pIconId, flags);
657 }
658 
659 /***********************************************************************
660  * PrivateExtractIconsA [USER32.@]
661  */
662 
664  LPCSTR lpstrFile,
665  int nIndex,
666  int sizeX,
667  int sizeY,
668  HICON * phicon, /* [out] pointer to array of nIcons HICON handles */
669  UINT* piconid, /* [out] pointer to array of nIcons icon identifiers or NULL */
670  UINT nIcons, /* [in] number of icons to retrieve */
671  UINT flags ) /* [in] LR_* flags used by LoadImage */
672 {
673  UINT ret;
674  INT len = MultiByteToWideChar(CP_ACP, 0, lpstrFile, -1, NULL, 0);
675  LPWSTR lpwstrFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
676 #ifdef __REACTOS__
677  if (lpwstrFile == NULL)
678  return 0;
679 #endif
680 
681  MultiByteToWideChar(CP_ACP, 0, lpstrFile, -1, lpwstrFile, len);
682  ret = PrivateExtractIconsW(lpwstrFile, nIndex, sizeX, sizeY, phicon, piconid, nIcons, flags);
683 
684  HeapFree(GetProcessHeap(), 0, lpwstrFile);
685  return ret;
686 }
687 
688 /***********************************************************************
689  * PrivateExtractIconExW [USER32.@]
690  * NOTES
691  * if nIndex == -1 it returns the number of icons in any case !!!
692  */
694  LPCWSTR lpwstrFile,
695  int nIndex,
696  HICON * phIconLarge,
697  HICON * phIconSmall,
698  UINT nIcons )
699 {
700  DWORD cyicon, cysmicon, cxicon, cxsmicon;
701  UINT ret = 0;
702 
703  TRACE("%s %d %p %p %d\n",
704  debugstr_w(lpwstrFile),nIndex,phIconLarge, phIconSmall, nIcons);
705 
706  if (nIndex == -1)
707  /* get the number of icons */
708  return ICO_ExtractIconExW(lpwstrFile, NULL, 0, 0, 0, 0, NULL, LR_DEFAULTCOLOR);
709 
710  if (nIcons == 1 && phIconSmall && phIconLarge)
711  {
712  HICON hIcon[2];
713  cxicon = GetSystemMetrics(SM_CXICON);
714  cyicon = GetSystemMetrics(SM_CYICON);
715  cxsmicon = GetSystemMetrics(SM_CXSMICON);
716  cysmicon = GetSystemMetrics(SM_CYSMICON);
717 
718  ret = ICO_ExtractIconExW(lpwstrFile, hIcon, nIndex, 2, cxicon | (cxsmicon<<16),
719  cyicon | (cysmicon<<16), NULL, LR_DEFAULTCOLOR);
720  *phIconLarge = hIcon[0];
721  *phIconSmall = hIcon[1];
722  return ret;
723  }
724 
725  if (phIconSmall)
726  {
727  /* extract n small icons */
728  cxsmicon = GetSystemMetrics(SM_CXSMICON);
729  cysmicon = GetSystemMetrics(SM_CYSMICON);
730  ret = ICO_ExtractIconExW(lpwstrFile, phIconSmall, nIndex, nIcons, cxsmicon,
731  cysmicon, NULL, LR_DEFAULTCOLOR);
732  }
733  if (phIconLarge)
734  {
735  /* extract n large icons */
736  cxicon = GetSystemMetrics(SM_CXICON);
737  cyicon = GetSystemMetrics(SM_CYICON);
738  ret = ICO_ExtractIconExW(lpwstrFile, phIconLarge, nIndex, nIcons, cxicon,
739  cyicon, NULL, LR_DEFAULTCOLOR);
740  }
741  return ret;
742 }
743 
744 /***********************************************************************
745  * PrivateExtractIconExA [USER32.@]
746  */
748  LPCSTR lpstrFile,
749  int nIndex,
750  HICON * phIconLarge,
751  HICON * phIconSmall,
752  UINT nIcons )
753 {
754  UINT ret;
755  INT len = MultiByteToWideChar(CP_ACP, 0, lpstrFile, -1, NULL, 0);
756  LPWSTR lpwstrFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
757 #ifdef __REACTOS__
758  if (lpwstrFile == NULL)
759  return 0;
760 #endif
761 
762  TRACE("%s %d %p %p %d\n", lpstrFile, nIndex, phIconLarge, phIconSmall, nIcons);
763 
764  MultiByteToWideChar(CP_ACP, 0, lpstrFile, -1, lpwstrFile, len);
765  ret = PrivateExtractIconExW(lpwstrFile, nIndex, phIconLarge, phIconSmall, nIcons);
766  HeapFree(GetProcessHeap(), 0, lpwstrFile);
767  return ret;
768 }
BYTE bHeight
Definition: exticon.c:40
#define abs(i)
Definition: fconv.c:206
DWORD get_best_icon_file_offset(const LPBYTE dir, DWORD dwFileSize, int cxDesired, int cyDesired, BOOL bIcon, DWORD fuLoad, POINT *ptHotSpot)
#define max(a, b)
Definition: svc.c:63
#define RT_GROUP_ICON
Definition: pedump.c:375
static HICON
Definition: imagelist.c:84
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:407
WORD offset
Definition: typelib.c:81
UINT WINAPI PrivateExtractIconsW(LPCWSTR lpwstrFile, int nIndex, int sizeX, int sizeY, HICON *phicon, UINT *pIconId, UINT nIcons, UINT flags)
Definition: exticon.c:639
WORD idCount
Definition: exticon.c:53
#define MapViewOfFile
Definition: compat.h:411
BYTE bColorCount
Definition: exticon.c:41
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
int WINAPI LookupIconIdFromDirectoryEx(_In_reads_bytes_(sizeof(NEWHEADER)) PBYTE, _In_ BOOL, _In_ int, _In_ int, _In_ UINT)
WORD idCount
Definition: ntusrtyp.h:101
ULONG OffsetToDirectory
Definition: ntimage.h:194
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2022
WORD idType
Definition: exticon.c:52
#define CP_ACP
Definition: compat.h:99
GLuint GLuint GLsizei count
Definition: gl.h:1545
UINT WINAPI PrivateExtractIconExW(LPCWSTR lpwstrFile, int nIndex, HICON *phIconLarge, HICON *phIconSmall, UINT nIcons)
Definition: exticon.c:693
#define WARN(fmt,...)
Definition: debug.h:112
DWORD dwFileSize
Definition: more.c:36
#define RtlImageRvaToVa
Definition: compat.h:467
struct _ICONIMAGE * LPICONIMAGE
GLintptr offset
Definition: glext.h:5920
GLdouble n
Definition: glext.h:7729
#define ARRAY_SIZE(x)
Definition: exticon.c:28
#define INVALID_HANDLE_VALUE
Definition: compat.h:400
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define SM_CYSMICON
Definition: winuser.h:1003
GLuint GLuint end
Definition: gl.h:1545
#define DWORD
Definition: nt_native.h:44
int32_t INT
Definition: typedefs.h:57
static BYTE * ICO_LoadIcon(LPBYTE peimage, LPicoICONDIRENTRY lpiIDE, ULONG *uSize)
Definition: exticon.c:204
#define FILE_SHARE_READ
Definition: compat.h:125
DWORD Id
WORD idReserved
Definition: ntusrtyp.h:99
DWORD dwImageOffset
Definition: exticon.c:46
#define IMAGE_DOS_SIGNATURE
Definition: pedump.c:89
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned char * LPBYTE
Definition: typedefs.h:53
#define SEC_COMMIT
Definition: mmtypes.h:99
unsigned int BOOL
Definition: ntddk_ex.h:94
WINE_DEFAULT_DEBUG_CHANNEL(icon)
#define debugstr_w
Definition: kernel32.h:32
#define FIXME(fmt,...)
Definition: debug.h:111
#define SM_CXICON
Definition: winuser.h:962
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:581
smooth NULL
Definition: ftsmooth.c:416
Definition: pedump.c:457
#define FILE_MAP_READ
Definition: compat.h:436
GLuint index
Definition: glext.h:6031
unsigned int dir
Definition: maze.c:112
const char * LPCSTR
Definition: xmlstorage.h:183
#define OPEN_EXISTING
Definition: compat.h:435
BYTE bReserved
Definition: exticon.c:42
#define IMAGE_NT_SIGNATURE
Definition: pedump.c:93
DWORD OffsetToData
Definition: pedump.c:459
#define NE_RSCTYPE_ICON
Definition: exticon.c:74
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
#define GetProcessHeap()
Definition: compat.h:404
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define CreateFileMappingW(a, b, c, d, e, f)
Definition: compat.h:410
static UINT ICO_ExtractIconExW(LPCWSTR lpszExeFileName, HICON *RetPtr, INT nIconIndex, UINT nIcons, UINT cxDesired, UINT cyDesired, UINT *pIconId, UINT flags)
Definition: exticon.c:263
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:6
#define RT_ICON
Definition: pedump.c:365
unsigned short WORD
Definition: ntddk_ex.h:93
int WINAPI GetSystemMetrics(_In_ int)
unsigned long DWORD
Definition: ntddk_ex.h:95
HICON WINAPI CreateIconFromResourceEx(_In_reads_bytes_(dwResSize) PBYTE presbits, _In_ DWORD dwResSize, _In_ BOOL fIcon, _In_ DWORD dwVer, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT Flags)
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:481
WORD idReserved
Definition: exticon.c:51
GLbitfield flags
Definition: glext.h:7161
type_id
#define SM_CXSMICON
Definition: winuser.h:1002
USHORT Id
Definition: ntimage.h:189
int ret
#define SM_CYICON
Definition: winuser.h:963
#define index(s, c)
Definition: various.h:29
#define RtlImageDirectoryEntryToData
Definition: compat.h:469
GLsizeiptr const GLvoid GLenum usage
Definition: glext.h:5919
uint32_t entry
Definition: isohybrid.c:63
#define NE_RSCTYPE_GROUP_ICON
Definition: exticon.c:75
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
#define IMAGE_OS2_SIGNATURE
Definition: pedump.c:90
static const IMAGE_RESOURCE_DIRECTORY * find_entry_default(const IMAGE_RESOURCE_DIRECTORY *dir, const void *root)
Definition: exticon.c:135
#define GENERIC_READ
Definition: compat.h:124
_In_ HANDLE hFile
Definition: mswsock.h:90
unsigned char BYTE
Definition: xxhash.c:193
WORD length
Definition: typelib.c:82
DWORD WINAPI SearchPathW(IN LPCWSTR lpPath OPTIONAL, IN LPCWSTR lpFileName, IN LPCWSTR lpExtension OPTIONAL, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart OPTIONAL)
Definition: path.c:1297
Definition: pedump.c:413
static BYTE * ICO_GetIconDirectory(LPBYTE peimage, LPicoICONDIR *lplpiID, ULONG *uSize)
Definition: exticon.c:217
WORD count
Definition: typelib.c:92
static const IMAGE_RESOURCE_DIRECTORY * find_entry_by_id(const IMAGE_RESOURCE_DIRECTORY *dir, WORD id, const void *root)
Definition: exticon.c:109
HICON hIcon
Definition: msconfig.c:44
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
unsigned short UINT16
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
WORD type_id
Definition: typelib.c:91
#define PAGE_READONLY
Definition: compat.h:127
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
DWORD dwBytesInRes
Definition: exticon.c:45
#define MultiByteToWideChar
Definition: compat.h:100
#define RtlImageNtHeader
Definition: compat.h:466
#define CreateFileW
Definition: compat.h:409
_Out_opt_ int * cx
Definition: commctrl.h:581
static DWORD USER32_GetResourceTable(LPBYTE peimage, DWORD pesize, LPBYTE *retptr)
Definition: exticon.c:146
CURSORICONDIRENTRY idEntries[1]
Definition: ntusrtyp.h:102
#define HIWORD(l)
Definition: typedefs.h:246
unsigned int ULONG
Definition: retypes.h:1
GLenum GLuint id
Definition: glext.h:5579
UINT WINAPI PrivateExtractIconsA(LPCSTR lpstrFile, int nIndex, int sizeX, int sizeY, HICON *phicon, UINT *piconid, UINT nIcons, UINT flags)
Definition: exticon.c:663
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define IMAGE_DIRECTORY_ENTRY_RESOURCE
Definition: pedump.c:261
struct icoICONDIR * LPicoICONDIR
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1827
static BYTE * USER32_LoadResource(LPBYTE peimage, NE_NAMEINFO *pNInfo, WORD sizeShift, ULONG *uSize)
Definition: exticon.c:193
#define LR_DEFAULTCOLOR
Definition: winuser.h:1077
#define UnmapViewOfFile
Definition: compat.h:412
UINT WINAPI PrivateExtractIconExA(LPCSTR lpstrFile, int nIndex, HICON *phIconLarge, HICON *phIconSmall, UINT nIcons)
Definition: exticon.c:747
icoICONDIRENTRY idEntries[1]
Definition: exticon.c:54
WORD wPlanes
Definition: exticon.c:43
#define LOWORD(l)
Definition: pedump.c:82
struct icoICONDIRENTRY * LPicoICONDIRENTRY
#define HeapFree(x, y, z)
Definition: compat.h:403
WORD wBitCount
Definition: exticon.c:44
DWORD Size
Definition: pedump.c:460