- use get_best_icon_file_entry's magic to find the correct icon in ICO_ExtractIconExW - thanks Jérôme!
- add cursor files support for PrivateExtractIcon(Ex)

svn path=/trunk/; revision=65303
This commit is contained in:
Kamil Hornicek
2014-11-06 23:28:28 +00:00
parent fad60e6ee8
commit a25ff6fb7e
2 changed files with 71 additions and 13 deletions
+44 -12
View File
@@ -44,6 +44,16 @@ static void dumpIcoDir ( LPicoICONDIR entry )
}
#endif
#ifndef WINE
DWORD get_best_icon_file_offset(const LPBYTE dir,
DWORD dwFileSize,
int cxDesired,
int cyDesired,
BOOL bIcon,
DWORD fuLoad,
POINT *ptHotSpot);
#endif
/**********************************************************************
* find_entry_by_id
*
@@ -99,10 +109,10 @@ static DWORD USER32_GetResourceTable(LPBYTE peimage,DWORD pesize,LPBYTE *retptr)
if (mz_header->e_magic != IMAGE_DOS_SIGNATURE)
{
if (mz_header->e_cblp == 1) /* .ICO file ? */
if (mz_header->e_cblp == 1 || mz_header->e_cblp == 2) /* .ICO or .CUR file ? */
{
*retptr = (LPBYTE)-1; /* ICONHEADER.idType, must be 1 */
return 1;
return mz_header->e_cblp;
}
else
return 0; /* failed */
@@ -361,36 +371,58 @@ static UINT ICO_ExtractIconExW(
}
}
#else
if (sig == 1) /* .ICO file */
if (sig == 1 || sig == 2) /* .ICO or .CUR file */
{
TRACE("-- icon Signature (0x%08x)\n", sig);
if (pData == (BYTE*)-1)
{
INT dataOffset;
LPICONIMAGE entry;
CURSORICONDIR *lpcid = (CURSORICONDIR*)peimage;
INT cx[2] = {cx1, cx2}, cy[2] = {cy1, cy2};
INT index;
if (lpcid->idType != 1)
return 0;
for(index = 0; index < 2; index++)
{
dataOffset = LookupIconIdFromDirectoryEx(peimage, TRUE, cx[index], cy[index], flags);
DWORD dataOffset;
LPBYTE imageData;
POINT hotSpot;
LPICONIMAGE entry;
dataOffset = get_best_icon_file_offset(peimage, fsizel, cx[index], cy[index], sig == 1, flags, sig == 1 ? NULL : &hotSpot);
if (dataOffset)
{
HICON icon;
entry = (LPICONIMAGE)(peimage + dataOffset);
icon = CreateIconFromResourceEx(peimage + dataOffset, entry->icHeader.biSizeImage, TRUE, 0x00030000, cx[index], cy[index], flags);
WORD *cursorData = NULL;
imageData = peimage + dataOffset;
entry = (LPICONIMAGE)(imageData);
if(sig == 2)
{
/* we need to prepend the bitmap data with hot spots for CreateIconFromResourceEx */
cursorData = HeapAlloc(GetProcessHeap(), 0, entry->icHeader.biSizeImage + 2 * sizeof(WORD));
if(!cursorData)
continue;
cursorData[0] = hotSpot.x;
cursorData[1] = hotSpot.y;
memcpy(cursorData + 2, imageData, entry->icHeader.biSizeImage);
imageData = (LPBYTE)cursorData;
}
icon = CreateIconFromResourceEx(imageData, entry->icHeader.biSizeImage, sig == 1, 0x00030000, cx[index], cy[index], flags);
if (icon)
{
RetPtr[index] = icon;
iconCount = 1;
}
if(cursorData != NULL)
HeapFree(GetProcessHeap(), 0, cursorData);
}
}
@@ -436,7 +436,6 @@ typedef struct
#include "poppack.h"
static
const CURSORICONFILEDIRENTRY*
get_best_icon_file_entry(
_In_ const CURSORICONFILEDIR* dir,
@@ -522,6 +521,33 @@ get_best_icon_file_entry(
/* We found it */
return &dir->idEntries[i-1];
}
DWORD
get_best_icon_file_offset(
_In_ const LPBYTE dir,
_In_ DWORD dwFileSize,
_In_ int cxDesired,
_In_ int cyDesired,
_In_ BOOL bIcon,
_In_ DWORD fuLoad,
_Out_ POINT *ptHotSpot
)
{
const CURSORICONFILEDIRENTRY *entry;
entry = get_best_icon_file_entry((CURSORICONFILEDIR *) dir, dwFileSize, cxDesired, cyDesired, bIcon, fuLoad);
if(ptHotSpot)
{
ptHotSpot->x = entry->xHotspot;
ptHotSpot->y = entry->yHotspot;
}
if(entry)
return entry->dwDIBOffset;
return 0;
}