Author: khornicek Date: Thu Nov 6 18:33:42 2014 New Revision: 65295 URL: http://svn.reactos.org/svn/reactos?rev=65295&view=rev Log: [USER32] - partially sync exticon.c with Wine 1.7.30
Modified: trunk/reactos/win32ss/user/user32/misc/exticon.c Modified: trunk/reactos/win32ss/user/user32/misc/exticon.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/user32/misc/exticon.c?rev=65295&r1=65294&r2=65295&view=diff ============================================================================== --- trunk/reactos/win32ss/user/user32/misc/exticon.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/user32/misc/exticon.c [iso-8859-1] Thu Nov 6 18:33:42 2014 @@ -112,7 +112,7 @@ } if (*((DWORD*)(peimage + mz_header->e_lfanew)) == IMAGE_NT_SIGNATURE ) return IMAGE_NT_SIGNATURE; -#if 0 +#ifdef WINE if (*((WORD*)(peimage + mz_header->e_lfanew)) == IMAGE_OS2_SIGNATURE ) { IMAGE_OS2_HEADER * ne_header; @@ -132,7 +132,7 @@ #endif return 0; /* failed */ } -#if 0 +#ifdef WINE /************************************************************************* * USER32_LoadResource */ @@ -160,9 +160,6 @@ * * Reads .ico file and build phony ICONDIR struct */ -#define HEADER_SIZE (sizeof(CURSORICONDIR) - sizeof (CURSORICONDIRENTRY)) -#define HEADER_SIZE_FILE (sizeof(icoICONDIR) - sizeof (icoICONDIRENTRY)) - static BYTE * ICO_GetIconDirectory( LPBYTE peimage, LPicoICONDIR* lplpiID, ULONG *uSize ) { CURSORICONDIR * lpcid; /* icon resource in resource-dir format */ @@ -177,7 +174,7 @@ return 0; /* allocate the phony ICONDIR structure */ - *uSize = lpcid->idCount * sizeof(CURSORICONDIRENTRY) + HEADER_SIZE; + *uSize = FIELD_OFFSET(CURSORICONDIR, idEntries[lpcid->idCount]); if( (lpID = HeapAlloc(GetProcessHeap(),0, *uSize) )) { /* copy the header */ @@ -188,7 +185,7 @@ /* copy the entries */ for( i=0; i < lpcid->idCount; i++ ) { - memcpy(&lpID->idEntries[i], &lpcid->idEntries[i], sizeof(CURSORICONDIRENTRY) - 2); + memcpy(&lpID->idEntries[i], &lpcid->idEntries[i], sizeof(CURSORICONDIRENTRY) - 2); lpID->idEntries[i].wResId = i; } @@ -274,8 +271,8 @@ sig = USER32_GetResourceTable(peimage, fsizel, &pData); +#ifdef WINE /* ico file or NE exe/dll*/ -#if 0 if (sig==IMAGE_OS2_SIGNATURE || sig==1) /* .ICO file */ { BYTE *pCIDir = 0; @@ -283,8 +280,9 @@ NE_NAMEINFO *pIconStorage = NULL; NE_NAMEINFO *pIconDir = NULL; LPicoICONDIR lpiID = NULL; - - TRACE("-- OS2/icon Signature (0x%08lx)\n", sig); + ULONG uSize = 0; + + TRACE("-- OS2/icon Signature (0x%08x)\n", sig); if (pData == (BYTE*)-1) { @@ -292,7 +290,7 @@ if (pCIDir) { iconDirCount = 1; iconCount = lpiID->idCount; - TRACE("-- icon found %p 0x%08lx 0x%08x 0x%08x\n", pCIDir, uSize, iconDirCount, iconCount); + TRACE("-- icon found %p 0x%08x 0x%08x 0x%08x\n", pCIDir, uSize, iconDirCount, iconCount); } } else while (pTInfo->type_id && !(pIconStorage && pIconDir)) @@ -317,7 +315,7 @@ if (nIcons == 0) { ret = iconDirCount; - if (lpiID && pCIDir) /* *.ico file, deallocate heap pointer*/ + if (lpiID) /* *.ico file, deallocate heap pointer*/ HeapFree(GetProcessHeap(), 0, pCIDir); } else if (nIconIndex < iconDirCount) @@ -331,9 +329,10 @@ /* .ICO files have only one icon directory */ if (lpiID == NULL) /* not *.ico */ pCIDir = USER32_LoadResource(peimage, pIconDir + i + nIconIndex, *(WORD*)pData, &uSize); - pIconId[i] = LookupIconIdFromDirectoryEx(pCIDir, TRUE, (i & 1) ? cx2 : cx1, (i & 1) ? cy2 : cy1, flags); + pIconId[i] = LookupIconIdFromDirectoryEx(pCIDir, TRUE, cx1, cy1, flags); + if (cx2 && cy2) pIconId[++i] = LookupIconIdFromDirectoryEx(pCIDir, TRUE, cx2, cy2, flags); } - if (lpiID && pCIDir) /* *.ico file, deallocate heap pointer*/ + if (lpiID) /* *.ico file, deallocate heap pointer*/ HeapFree(GetProcessHeap(), 0, pCIDir); for (icon = 0; icon < nIcons; icon++) @@ -347,8 +346,13 @@ pCIDir = USER32_LoadResource(peimage, pIconStorage + i, *(WORD*)pData, &uSize); if (pCIDir) - RetPtr[icon] = (HICON)CreateIconFromResourceEx(pCIDir, uSize, TRUE, 0x00030000, - (icon & 1) ? cx2 : cx1, (icon & 1) ? cy2 : cy1, flags); + { + RetPtr[icon] = CreateIconFromResourceEx(pCIDir, uSize, TRUE, 0x00030000, + cx1, cy1, flags); + if (cx2 && cy2) + RetPtr[++icon] = CreateIconFromResourceEx(pCIDir, uSize, TRUE, 0x00030000, + cx2, cy2, flags); + } else RetPtr[icon] = 0; } @@ -363,47 +367,19 @@ #endif if( sig == IMAGE_NT_SIGNATURE ) { - LPBYTE idata,igdata; - PIMAGE_DOS_HEADER dheader; - PIMAGE_NT_HEADERS pe_header; - PIMAGE_SECTION_HEADER pe_sections; - const IMAGE_RESOURCE_DIRECTORY *rootresdir,*iconresdir,*icongroupresdir; - const IMAGE_RESOURCE_DATA_ENTRY *idataent,*igdataent; - const IMAGE_RESOURCE_DIRECTORY_ENTRY *xresent; - UINT i, j; - - dheader = (PIMAGE_DOS_HEADER)peimage; - pe_header = (PIMAGE_NT_HEADERS)(peimage+dheader->e_lfanew); /* it is a pe header, USER32_GetResourceTable checked that */ - pe_sections = (PIMAGE_SECTION_HEADER)(((char*)pe_header) + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) - + pe_header->FileHeader.SizeOfOptionalHeader); - rootresdir = NULL; - - /* search for the root resource directory */ - for (i=0;i<pe_header->FileHeader.NumberOfSections;i++) - { - if (pe_sections[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) - continue; - if (fsizel < pe_sections[i].PointerToRawData+pe_sections[i].SizeOfRawData) { - FIXME("File %s too short (section is at %ld bytes, real size is %ld)\n", - debugstr_w(lpszExeFileName), - pe_sections[i].PointerToRawData+pe_sections[i].SizeOfRawData, - fsizel - ); - goto end; - } - /* FIXME: doesn't work when the resources are not in a separate section */ - if (pe_sections[i].VirtualAddress == pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress) - { - rootresdir = (PIMAGE_RESOURCE_DIRECTORY)(peimage+pe_sections[i].PointerToRawData); - break; - } - } - - if (!rootresdir) - { - WARN("haven't found section for resource directory.\n"); - goto end; /* failure */ - } + BYTE *idata, *igdata; + const IMAGE_RESOURCE_DIRECTORY *rootresdir, *iconresdir, *icongroupresdir; + const IMAGE_RESOURCE_DATA_ENTRY *idataent, *igdataent; + const IMAGE_RESOURCE_DIRECTORY_ENTRY *xresent; + ULONG size; + UINT i; + + rootresdir = RtlImageDirectoryEntryToData((HMODULE)peimage, FALSE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &size); + if (!rootresdir) + { + WARN("haven't found section for resource directory.\n"); + goto end; + } /* search for the group icon directory */ if (!(icongroupresdir = find_entry_by_id(rootresdir, LOWORD(RT_GROUP_ICON), rootresdir))) @@ -465,37 +441,21 @@ const IMAGE_RESOURCE_DIRECTORY *resdir; /* go down this resource entry, name */ - resdir = (const IMAGE_RESOURCE_DIRECTORY*)((const char *)rootresdir+(xresent->OffsetToDirectory)); + resdir = (const IMAGE_RESOURCE_DIRECTORY *)((const char *)rootresdir + xresent->OffsetToDirectory); /* default language (0) */ resdir = find_entry_default(resdir,rootresdir); igdataent = (const IMAGE_RESOURCE_DATA_ENTRY*)resdir; /* lookup address in mapped image for virtual address */ - igdata = NULL; - - for (j=0;j<pe_header->FileHeader.NumberOfSections;j++) - { - if (igdataent->OffsetToData < pe_sections[j].VirtualAddress) - continue; - if (igdataent->OffsetToData+igdataent->Size > pe_sections[j].VirtualAddress+pe_sections[j].SizeOfRawData) - continue; - - if (igdataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData+igdataent->Size > fsizel) { - FIXME("overflow in PE lookup (%s has len %ld, have offset %ld), short file?\n", debugstr_w(lpszExeFileName), fsizel, - igdataent->OffsetToData - pe_sections[j].VirtualAddress + pe_sections[j].PointerToRawData + igdataent->Size); - goto end; /* failure */ - } - igdata = peimage+(igdataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData); - } - - if (!igdata) + igdata = RtlImageRvaToVa(RtlImageNtHeader((HMODULE)peimage), (HMODULE)peimage, igdataent->OffsetToData, NULL); + if (!igdata) { FIXME("no matching real address for icongroup!\n"); goto end; /* failure */ } pIconId[i] = LookupIconIdFromDirectoryEx(igdata, TRUE, cx1, cy1, flags); - if (cx2 && cy2) pIconId[++i] = LookupIconIdFromDirectoryEx(igdata, TRUE, cx2, cy2, flags); + if (cx2 && cy2) pIconId[++i] = LookupIconIdFromDirectoryEx(igdata, TRUE, cx2, cy2, flags); } if (!(iconresdir=find_entry_by_id(rootresdir,LOWORD(RT_ICON),rootresdir))) @@ -508,32 +468,17 @@ { const IMAGE_RESOURCE_DIRECTORY *xresdir; xresdir = find_entry_by_id(iconresdir, LOWORD(pIconId[i]), rootresdir); - if (!xresdir) - { - WARN("icon entry %d not found\n", LOWORD(pIconId[i])); + if( !xresdir ) + { + WARN("icon entry %d not found\n", LOWORD(pIconId[i])); RetPtr[i]=0; continue; - } + } xresdir = find_entry_default(xresdir, rootresdir); - if (!xresdir) - { - WARN("icon entry %d not found\n", LOWORD(pIconId[i])); - RetPtr[i]=0; - continue; - } idataent = (const IMAGE_RESOURCE_DATA_ENTRY*)xresdir; - idata = NULL; - - /* map virtual to address in image */ - for (j=0;j<pe_header->FileHeader.NumberOfSections;j++) - { - if (idataent->OffsetToData < pe_sections[j].VirtualAddress) - continue; - if (idataent->OffsetToData+idataent->Size > pe_sections[j].VirtualAddress+pe_sections[j].SizeOfRawData) - continue; - idata = peimage+(idataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData); - } - if (!idata) + + idata = RtlImageRvaToVa(RtlImageNtHeader((HMODULE)peimage), (HMODULE)peimage, idataent->OffsetToData, NULL); + if (!idata) { WARN("no matching real address found for icondata!\n"); RetPtr[i]=0; @@ -644,7 +589,7 @@ cxsmicon = GetSystemMetrics(SM_CXSMICON); cysmicon = GetSystemMetrics(SM_CYSMICON); - ret = ICO_ExtractIconExW(lpwstrFile, hIcon, nIndex, 2, cxicon | (cxsmicon<<16), + ret = ICO_ExtractIconExW(lpwstrFile, hIcon, nIndex, 2, cxicon | (cxsmicon<<16), cyicon | (cysmicon<<16), NULL, LR_DEFAULTCOLOR); *phIconLarge = hIcon[0]; *phIconSmall = hIcon[1];