Module: wine Branch: master Commit: ba40509f90ac45a78a4eee018a5b19162aaded9f URL: http://source.winehq.org/git/wine.git/?a=commit;h=ba40509f90ac45a78a4eee018a...
Author: Hans Leidekker hans@codeweavers.com Date: Thu Jun 6 19:30:05 2013 +0200
user32: Fix icon extraction from non-native PE executables.
---
dlls/user32/exticon.c | 87 +++++++++--------------------------------------- 1 files changed, 17 insertions(+), 70 deletions(-)
diff --git a/dlls/user32/exticon.c b/dlls/user32/exticon.c index 5b9d681..0dbbef1 100644 --- a/dlls/user32/exticon.c +++ b/dlls/user32/exticon.c @@ -420,47 +420,19 @@ static UINT ICO_ExtractIconExW( /* exe/dll */ else 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 %d bytes, real size is %d)\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))) @@ -529,24 +501,8 @@ static UINT ICO_ExtractIconExW( 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 %d, have offset %d), 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 */ @@ -573,18 +529,9 @@ static UINT ICO_ExtractIconExW( } xresdir = find_entry_default(xresdir, rootresdir); 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;