ReactOS  0.4.14-dev-98-gb0d4763
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  if (icon)
473  {
474  RetPtr[index] = icon;
475  iconCount = 1;
476  }
477 
478  if(cursorData != NULL)
479  HeapFree(GetProcessHeap(), 0, cursorData);
480  }
481  }
482 
483  }
484  ret = iconCount; /* return number of retrieved icons */
485  }
486 /* end ico file */
487 
488 /* exe/dll */
489  else if( sig == IMAGE_NT_SIGNATURE )
490  {
491  BYTE *idata, *igdata;
492  const IMAGE_RESOURCE_DIRECTORY *rootresdir, *iconresdir, *icongroupresdir;
493  const IMAGE_RESOURCE_DATA_ENTRY *idataent, *igdataent;
494  const IMAGE_RESOURCE_DIRECTORY_ENTRY *xresent;
495  ULONG size;
496  UINT i;
497 
499  if (!rootresdir)
500  {
501  WARN("haven't found section for resource directory.\n");
502  goto end;
503  }
504 
505  /* search for the group icon directory */
506  if (!(icongroupresdir = find_entry_by_id(rootresdir, LOWORD(RT_GROUP_ICON), rootresdir)))
507  {
508  WARN("No Icongroupresourcedirectory!\n");
509  goto end; /* failure */
510  }
511  iconDirCount = icongroupresdir->NumberOfNamedEntries + icongroupresdir->NumberOfIdEntries;
512 
513  /* only number of icons requested */
514  if( !pIconId )
515  {
516  ret = iconDirCount;
517  goto end; /* success */
518  }
519 
520  if( nIconIndex < 0 )
521  {
522  /* search resource id */
523  int n = 0;
524  int iId = abs(nIconIndex);
525  const IMAGE_RESOURCE_DIRECTORY_ENTRY* xprdeTmp = (const IMAGE_RESOURCE_DIRECTORY_ENTRY*)(icongroupresdir+1);
526 
527  while(n<iconDirCount && xprdeTmp)
528  {
529  if(xprdeTmp->Id == iId)
530  {
531  nIconIndex = n;
532  break;
533  }
534  n++;
535  xprdeTmp++;
536  }
537  if (nIconIndex < 0)
538  {
539  WARN("resource id %d not found\n", iId);
540  goto end; /* failure */
541  }
542  }
543  else
544  {
545  /* check nIconIndex to be in range */
546  if (nIconIndex >= iconDirCount)
547  {
548  WARN("nIconIndex %d is larger than iconDirCount %d\n",nIconIndex,iconDirCount);
549  goto end; /* failure */
550  }
551  }
552 
553  /* assure we don't get too much */
554  if( nIcons > iconDirCount - nIconIndex )
555  nIcons = iconDirCount - nIconIndex;
556 
557  /* starting from specified index */
558  xresent = (const IMAGE_RESOURCE_DIRECTORY_ENTRY*)(icongroupresdir+1) + nIconIndex;
559 
560  for (i=0; i < nIcons; i++,xresent++)
561  {
562  const IMAGE_RESOURCE_DIRECTORY *resdir;
563 
564  /* go down this resource entry, name */
565  resdir = (const IMAGE_RESOURCE_DIRECTORY *)((const char *)rootresdir + xresent->OffsetToDirectory);
566 
567  /* default language (0) */
568  resdir = find_entry_default(resdir,rootresdir);
569  igdataent = (const IMAGE_RESOURCE_DATA_ENTRY*)resdir;
570 
571  /* lookup address in mapped image for virtual address */
572  igdata = RtlImageRvaToVa(RtlImageNtHeader((HMODULE)peimage), (HMODULE)peimage, igdataent->OffsetToData, NULL);
573  if (!igdata)
574  {
575  FIXME("no matching real address for icongroup!\n");
576  goto end; /* failure */
577  }
578  pIconId[i] = LookupIconIdFromDirectoryEx(igdata, TRUE, cx1, cy1, flags);
579  if (cx2 && cy2) pIconId[++i] = LookupIconIdFromDirectoryEx(igdata, TRUE, cx2, cy2, flags);
580  }
581 
582  if (!(iconresdir=find_entry_by_id(rootresdir,LOWORD(RT_ICON),rootresdir)))
583  {
584  WARN("No Iconresourcedirectory!\n");
585  goto end; /* failure */
586  }
587 
588  for (i=0; i<nIcons; i++)
589  {
590  const IMAGE_RESOURCE_DIRECTORY *xresdir;
591  xresdir = find_entry_by_id(iconresdir, LOWORD(pIconId[i]), rootresdir);
592  if( !xresdir )
593  {
594  WARN("icon entry %d not found\n", LOWORD(pIconId[i]));
595  RetPtr[i]=0;
596  continue;
597  }
598  xresdir = find_entry_default(xresdir, rootresdir);
599  idataent = (const IMAGE_RESOURCE_DATA_ENTRY*)xresdir;
600 
601  idata = RtlImageRvaToVa(RtlImageNtHeader((HMODULE)peimage), (HMODULE)peimage, idataent->OffsetToData, NULL);
602  if (!idata)
603  {
604  WARN("no matching real address found for icondata!\n");
605  RetPtr[i]=0;
606  continue;
607  }
608  RetPtr[i] = CreateIconFromResourceEx(idata, idataent->Size, TRUE, 0x00030000, cx1, cy1, flags);
609  if (cx2 && cy2)
610  RetPtr[++i] = CreateIconFromResourceEx(idata, idataent->Size, TRUE, 0x00030000, cx2, cy2, flags);
611  }
612  ret = i; /* return number of retrieved icons */
613  } /* if(sig == IMAGE_NT_SIGNATURE) */
614 
615 end:
616  UnmapViewOfFile(peimage); /* success */
617  return ret;
618 }
619 
620 /***********************************************************************
621  * PrivateExtractIconsW [USER32.@]
622  *
623  * NOTES
624  * If HIWORD(sizeX) && HIWORD(sizeY) 2 * ((nIcons + 1) MOD 2) icons are
625  * returned, with the LOWORD size icon first and the HIWORD size icon
626  * second.
627  * Also the Windows equivalent does extract icons in a strange way if
628  * nIndex is negative. Our implementation treats a negative nIndex as
629  * looking for that resource identifier for the first icon to retrieve.
630  *
631  * FIXME:
632  * should also support 16 bit EXE + DLLs, cursor and animated cursor as
633  * well as bitmap files.
634  */
635 
637  LPCWSTR lpwstrFile,
638  int nIndex,
639  int sizeX,
640  int sizeY,
641  HICON * phicon, /* [out] pointer to array of nIcons HICON handles */
642  UINT* pIconId, /* [out] pointer to array of nIcons icon identifiers or NULL */
643  UINT nIcons, /* [in] number of icons to retrieve */
644  UINT flags ) /* [in] LR_* flags used by LoadImage */
645 {
646  TRACE("%s %d %dx%d %p %p %d 0x%08x\n",
647  debugstr_w(lpwstrFile), nIndex, sizeX, sizeY, phicon, pIconId, nIcons, flags);
648 
649  if ((nIcons & 1) && HIWORD(sizeX) && HIWORD(sizeY))
650  {
651  WARN("Uneven number %d of icons requested for small and large icons!\n", nIcons);
652  }
653  return ICO_ExtractIconExW(lpwstrFile, phicon, nIndex, nIcons, sizeX, sizeY, pIconId, flags);
654 }
655 
656 /***********************************************************************
657  * PrivateExtractIconsA [USER32.@]
658  */
659 
661  LPCSTR lpstrFile,
662  int nIndex,
663  int sizeX,
664  int sizeY,
665  HICON * phicon, /* [out] pointer to array of nIcons HICON handles */
666  UINT* piconid, /* [out] pointer to array of nIcons icon identifiers or NULL */
667  UINT nIcons, /* [in] number of icons to retrieve */
668  UINT flags ) /* [in] LR_* flags used by LoadImage */
669 {
670  UINT ret;
671  INT len = MultiByteToWideChar(CP_ACP, 0, lpstrFile, -1, NULL, 0);
672  LPWSTR lpwstrFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
673 #ifdef __REACTOS__
674  if (lpwstrFile == NULL)
675  return 0;
676 #endif
677 
678  MultiByteToWideChar(CP_ACP, 0, lpstrFile, -1, lpwstrFile, len);
679  ret = PrivateExtractIconsW(lpwstrFile, nIndex, sizeX, sizeY, phicon, piconid, nIcons, flags);
680 
681  HeapFree(GetProcessHeap(), 0, lpwstrFile);
682  return ret;
683 }
684 
685 /***********************************************************************
686  * PrivateExtractIconExW [USER32.@]
687  * NOTES
688  * if nIndex == -1 it returns the number of icons in any case !!!
689  */
691  LPCWSTR lpwstrFile,
692  int nIndex,
693  HICON * phIconLarge,
694  HICON * phIconSmall,
695  UINT nIcons )
696 {
697  DWORD cyicon, cysmicon, cxicon, cxsmicon;
698  UINT ret = 0;
699 
700  TRACE("%s %d %p %p %d\n",
701  debugstr_w(lpwstrFile),nIndex,phIconLarge, phIconSmall, nIcons);
702 
703  if (nIndex == -1)
704  /* get the number of icons */
705  return ICO_ExtractIconExW(lpwstrFile, NULL, 0, 0, 0, 0, NULL, LR_DEFAULTCOLOR);
706 
707  if (nIcons == 1 && phIconSmall && phIconLarge)
708  {
709  HICON hIcon[2];
710  cxicon = GetSystemMetrics(SM_CXICON);
711  cyicon = GetSystemMetrics(SM_CYICON);
712  cxsmicon = GetSystemMetrics(SM_CXSMICON);
713  cysmicon = GetSystemMetrics(SM_CYSMICON);
714 
715  ret = ICO_ExtractIconExW(lpwstrFile, hIcon, nIndex, 2, cxicon | (cxsmicon<<16),
716  cyicon | (cysmicon<<16), NULL, LR_DEFAULTCOLOR);
717  *phIconLarge = hIcon[0];
718  *phIconSmall = hIcon[1];
719  return ret;
720  }
721 
722  if (phIconSmall)
723  {
724  /* extract n small icons */
725  cxsmicon = GetSystemMetrics(SM_CXSMICON);
726  cysmicon = GetSystemMetrics(SM_CYSMICON);
727  ret = ICO_ExtractIconExW(lpwstrFile, phIconSmall, nIndex, nIcons, cxsmicon,
728  cysmicon, NULL, LR_DEFAULTCOLOR);
729  }
730  if (phIconLarge)
731  {
732  /* extract n large icons */
733  cxicon = GetSystemMetrics(SM_CXICON);
734  cyicon = GetSystemMetrics(SM_CYICON);
735  ret = ICO_ExtractIconExW(lpwstrFile, phIconLarge, nIndex, nIcons, cxicon,
736  cyicon, NULL, LR_DEFAULTCOLOR);
737  }
738  return ret;
739 }
740 
741 /***********************************************************************
742  * PrivateExtractIconExA [USER32.@]
743  */
745  LPCSTR lpstrFile,
746  int nIndex,
747  HICON * phIconLarge,
748  HICON * phIconSmall,
749  UINT nIcons )
750 {
751  UINT ret;
752  INT len = MultiByteToWideChar(CP_ACP, 0, lpstrFile, -1, NULL, 0);
753  LPWSTR lpwstrFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
754 #ifdef __REACTOS__
755  if (lpwstrFile == NULL)
756  return 0;
757 #endif
758 
759  TRACE("%s %d %p %p %d\n", lpstrFile, nIndex, phIconLarge, phIconSmall, nIcons);
760 
761  MultiByteToWideChar(CP_ACP, 0, lpstrFile, -1, lpwstrFile, len);
762  ret = PrivateExtractIconExW(lpwstrFile, nIndex, phIconLarge, phIconSmall, nIcons);
763  HeapFree(GetProcessHeap(), 0, lpwstrFile);
764  return ret;
765 }
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:398
WORD offset
Definition: typelib.c:84
UINT WINAPI PrivateExtractIconsW(LPCWSTR lpwstrFile, int nIndex, int sizeX, int sizeY, HICON *phicon, UINT *pIconId, UINT nIcons, UINT flags)
Definition: exticon.c:636
WORD idCount
Definition: exticon.c:53
#define MapViewOfFile
Definition: compat.h:402
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
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:690
#define WARN(fmt,...)
Definition: debug.h:111
DWORD dwFileSize
Definition: more.c:36
#define RtlImageRvaToVa
Definition: compat.h:458
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:391
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:56
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:52
#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:110
#define SM_CXICON
Definition: winuser.h:962
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:570
smooth NULL
Definition: ftsmooth.c:416
Definition: pedump.c:457
#define FILE_MAP_READ
Definition: compat.h:427
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:426
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:395
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:401
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:8
#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:460
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
unsigned char BYTE
Definition: mem.h:68
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
WORD length
Definition: typelib.c:85
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:95
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:94
#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:457
#define CreateFileW
Definition: compat.h:400
_Out_opt_ int * cx
Definition: commctrl.h:570
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:660
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:403
UINT WINAPI PrivateExtractIconExA(LPCSTR lpstrFile, int nIndex, HICON *phIconLarge, HICON *phIconSmall, UINT nIcons)
Definition: exticon.c:744
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:394
WORD wBitCount
Definition: exticon.c:44
DWORD Size
Definition: pedump.c:460