Commit 81800b1f authored by Alexandre Julliard's avatar Alexandre Julliard

Use a binary search to find entries in resource directories.

Fixed GetResDirEntryA/W prototypes.
parent cc7abe1f
......@@ -791,10 +791,10 @@ HGLOBAL16 WINAPI InternalExtractIcon16(HINSTANCE16 hInstance,
PIMAGE_DOS_HEADER dheader;
PIMAGE_NT_HEADERS pe_header;
PIMAGE_SECTION_HEADER pe_sections;
PIMAGE_RESOURCE_DIRECTORY rootresdir,iconresdir,icongroupresdir;
PIMAGE_RESOURCE_DATA_ENTRY idataent,igdataent;
const IMAGE_RESOURCE_DIRECTORY *rootresdir,*iconresdir,*icongroupresdir;
const IMAGE_RESOURCE_DATA_ENTRY *idataent,*igdataent;
int i,j;
PIMAGE_RESOURCE_DIRECTORY_ENTRY xresent;
const IMAGE_RESOURCE_DIRECTORY_ENTRY *xresent;
CURSORICONDIR **cids;
fmapping = CreateFileMappingA(hFile,NULL,PAGE_READONLY|SEC_COMMIT,0,0,NULL);
......@@ -836,7 +836,7 @@ HGLOBAL16 WINAPI InternalExtractIcon16(HINSTANCE16 hInstance,
goto end_4; /* failure */
}
icongroupresdir = GetResDirEntryW(rootresdir,RT_GROUP_ICONW, (DWORD)rootresdir,FALSE);
icongroupresdir = GetResDirEntryW(rootresdir,RT_GROUP_ICONW, rootresdir,FALSE);
if (!icongroupresdir)
{ WARN("No Icongroupresourcedirectory!\n");
......@@ -870,14 +870,15 @@ HGLOBAL16 WINAPI InternalExtractIcon16(HINSTANCE16 hInstance,
xresent = xresent+nIconIndex;
for (i=0;i<n;i++,xresent++)
{ CURSORICONDIR *cid;
PIMAGE_RESOURCE_DIRECTORY resdir;
{
CURSORICONDIR *cid;
const IMAGE_RESOURCE_DIRECTORY *resdir;
/* go down this resource entry, name */
resdir = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)rootresdir+(xresent->u2.s.OffsetToDirectory));
/* default language (0) */
resdir = GetResDirEntryW(resdir,(LPWSTR)0,(DWORD)rootresdir,TRUE);
resdir = GetResDirEntryW(resdir,(LPWSTR)0,rootresdir,TRUE);
igdataent = (PIMAGE_RESOURCE_DATA_ENTRY)resdir;
/* lookup address in mapped image for virtual address */
......@@ -901,7 +902,7 @@ HGLOBAL16 WINAPI InternalExtractIcon16(HINSTANCE16 hInstance,
RetPtr[i] = LookupIconIdFromDirectoryEx(igdata,TRUE,GetSystemMetrics(SM_CXICON),GetSystemMetrics(SM_CYICON),0);
}
iconresdir=GetResDirEntryW(rootresdir,RT_ICONW,(DWORD)rootresdir,FALSE);
iconresdir=GetResDirEntryW(rootresdir,RT_ICONW,rootresdir,FALSE);
if (!iconresdir)
{ WARN("No Iconresourcedirectory!\n");
......@@ -909,9 +910,10 @@ HGLOBAL16 WINAPI InternalExtractIcon16(HINSTANCE16 hInstance,
}
for (i=0;i<n;i++)
{ PIMAGE_RESOURCE_DIRECTORY xresdir;
xresdir = GetResDirEntryW(iconresdir,(LPWSTR)(DWORD)RetPtr[i],(DWORD)rootresdir,FALSE);
xresdir = GetResDirEntryW(xresdir,(LPWSTR)0,(DWORD)rootresdir,TRUE);
{
const IMAGE_RESOURCE_DIRECTORY *xresdir;
xresdir = GetResDirEntryW(iconresdir,(LPWSTR)(DWORD)RetPtr[i],rootresdir,FALSE);
xresdir = GetResDirEntryW(xresdir,(LPWSTR)0,rootresdir,TRUE);
idataent = (PIMAGE_RESOURCE_DATA_ENTRY)xresdir;
idata = NULL;
......
......@@ -178,7 +178,7 @@ static BYTE * ICO_GetIconDirectory( LPBYTE peimage, LPicoICONDIR* lplpiID, ULONG
* returns
* failure:0; success: icon handle or nr of icons (nIconIndex-1)
*/
static HRESULT WINAPI ICO_ExtractIconExW(
static HRESULT ICO_ExtractIconExW(
LPCWSTR lpszExeFileName,
HICON * RetPtr,
INT nIconIndex,
......@@ -202,18 +202,20 @@ static HRESULT WINAPI ICO_ExtractIconExW(
/* Map the file */
fmapping = CreateFileMappingA( hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL );
CloseHandle( hFile );
if (!fmapping)
{
WARN("CreateFileMapping error %ld\n", GetLastError() );
goto end_1;
return hRet;
}
if ( !(peimage = MapViewOfFile(fmapping,FILE_MAP_READ,0,0,0)))
{
WARN("MapViewOfFile error %ld\n", GetLastError() );
goto end_2;
CloseHandle( fmapping );
return hRet;
}
CloseHandle( fmapping );
sig = USER32_GetResourceTable(peimage,&pData);
......@@ -303,9 +305,9 @@ static HRESULT WINAPI ICO_ExtractIconExW(
PIMAGE_DOS_HEADER dheader;
PIMAGE_NT_HEADERS pe_header;
PIMAGE_SECTION_HEADER pe_sections;
PIMAGE_RESOURCE_DIRECTORY rootresdir,iconresdir,icongroupresdir;
PIMAGE_RESOURCE_DATA_ENTRY idataent,igdataent;
PIMAGE_RESOURCE_DIRECTORY_ENTRY xresent;
const IMAGE_RESOURCE_DIRECTORY *rootresdir,*iconresdir,*icongroupresdir;
const IMAGE_RESOURCE_DATA_ENTRY *idataent,*igdataent;
const IMAGE_RESOURCE_DIRECTORY_ENTRY *xresent;
int i,j;
dheader = (PIMAGE_DOS_HEADER)peimage;
......@@ -329,14 +331,14 @@ static HRESULT WINAPI ICO_ExtractIconExW(
if (!rootresdir)
{
WARN("haven't found section for resource directory.\n");
goto end_3; /* failure */
goto end; /* failure */
}
/* search for the group icon directory */
if (!(icongroupresdir = GetResDirEntryW(rootresdir, RT_GROUP_ICONW, (DWORD)rootresdir, FALSE)))
if (!(icongroupresdir = GetResDirEntryW(rootresdir, RT_GROUP_ICONW, rootresdir, FALSE)))
{
WARN("No Icongroupresourcedirectory!\n");
goto end_3; /* failure */
goto end; /* failure */
}
iconDirCount = icongroupresdir->NumberOfNamedEntries + icongroupresdir->NumberOfIdEntries;
......@@ -344,7 +346,7 @@ static HRESULT WINAPI ICO_ExtractIconExW(
if( nIcons == 0 )
{
hRet = iconDirCount;
goto end_3; /* success */
goto end; /* success */
}
if( nIconIndex < 0 )
......@@ -367,7 +369,7 @@ static HRESULT WINAPI ICO_ExtractIconExW(
if (nIconIndex < 0)
{
WARN("resource id %d not found\n", iId);
goto end_3; /* failure */
goto end; /* failure */
}
}
else
......@@ -376,7 +378,7 @@ static HRESULT WINAPI ICO_ExtractIconExW(
if (nIconIndex >= iconDirCount)
{
WARN("nIconIndex %d is larger than iconDirCount %d\n",nIconIndex,iconDirCount);
goto end_3; /* failure */
goto end; /* failure */
}
}
......@@ -389,13 +391,13 @@ static HRESULT WINAPI ICO_ExtractIconExW(
for (i=0; i < nIcons; i++,xresent++)
{
PIMAGE_RESOURCE_DIRECTORY resdir;
const IMAGE_RESOURCE_DIRECTORY *resdir;
/* go down this resource entry, name */
resdir = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)rootresdir+(xresent->u2.s.OffsetToDirectory));
/* default language (0) */
resdir = GetResDirEntryW(resdir,(LPWSTR)0,(DWORD)rootresdir,TRUE);
resdir = GetResDirEntryW(resdir,(LPWSTR)0,rootresdir,TRUE);
igdataent = (PIMAGE_RESOURCE_DATA_ENTRY)resdir;
/* lookup address in mapped image for virtual address */
......@@ -413,22 +415,22 @@ static HRESULT WINAPI ICO_ExtractIconExW(
if (!igdata)
{
WARN("no matching real address for icongroup!\n");
goto end_3; /* failure */
goto end; /* failure */
}
RetPtr[i] = (HICON)LookupIconIdFromDirectoryEx(igdata, TRUE, cxDesired, cyDesired, LR_DEFAULTCOLOR);
}
if (!(iconresdir=GetResDirEntryW(rootresdir,RT_ICONW,(DWORD)rootresdir,FALSE)))
if (!(iconresdir=GetResDirEntryW(rootresdir,RT_ICONW,rootresdir,FALSE)))
{
WARN("No Iconresourcedirectory!\n");
goto end_3; /* failure */
goto end; /* failure */
}
for (i=0; i<nIcons; i++)
{
PIMAGE_RESOURCE_DIRECTORY xresdir;
xresdir = GetResDirEntryW(iconresdir,(LPWSTR)(DWORD)RetPtr[i],(DWORD)rootresdir,FALSE);
xresdir = GetResDirEntryW(xresdir,(LPWSTR)0,(DWORD)rootresdir,TRUE);
const IMAGE_RESOURCE_DIRECTORY *xresdir;
xresdir = GetResDirEntryW(iconresdir,(LPWSTR)(DWORD)RetPtr[i],rootresdir,FALSE);
xresdir = GetResDirEntryW(xresdir,(LPWSTR)0,rootresdir,TRUE);
idataent = (PIMAGE_RESOURCE_DATA_ENTRY)xresdir;
idata = NULL;
......@@ -450,12 +452,9 @@ static HRESULT WINAPI ICO_ExtractIconExW(
RetPtr[i] = (HICON) CreateIconFromResourceEx(idata,idataent->Size,TRUE,0x00030000, cxDesired, cyDesired, LR_DEFAULTCOLOR);
}
hRet = S_OK; /* return first icon */
goto end_3; /* sucess */
} /* if(sig == IMAGE_NT_SIGNATURE) */
end_3: UnmapViewOfFile(peimage); /* success */
end_2: CloseHandle(fmapping);
end_1: _lclose( hFile);
end: UnmapViewOfFile(peimage); /* success */
return hRet;
}
......@@ -509,7 +508,7 @@ HRESULT WINAPI PrivateExtractIconsW (
HRESULT WINAPI PrivateExtractIconsA (
LPCSTR lpstrFile,
DWORD nIndex,
INT nIndex,
DWORD sizeX,
DWORD sizeY,
HICON * phicon,
......@@ -520,7 +519,7 @@ HRESULT WINAPI PrivateExtractIconsA (
DWORD ret;
LPWSTR lpwstrFile = HEAP_strdupAtoW(GetProcessHeap(), 0, lpstrFile);
FIXME_(icon)("%s 0x%08lx 0x%08lx 0x%08lx %p 0x%08lx 0x%08x 0x%08lx stub\n",
FIXME_(icon)("%s 0x%08x 0x%08lx 0x%08lx %p 0x%08lx 0x%08x 0x%08lx stub\n",
lpstrFile, nIndex, sizeX, sizeY, phicon, w, nIcons, y );
ret = PrivateExtractIconsW(lpwstrFile, nIndex, sizeX, sizeY, phicon, w, nIcons, y);
......
......@@ -122,9 +122,9 @@ static BOOL find_pe_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid,
PIMAGE_SECTION_HEADER sections;
LPBYTE resSection;
DWORD resSectionSize;
DWORD resDir;
PIMAGE_RESOURCE_DIRECTORY resPtr;
PIMAGE_RESOURCE_DATA_ENTRY resData;
const void *resDir;
const IMAGE_RESOURCE_DIRECTORY *resPtr;
const IMAGE_RESOURCE_DATA_ENTRY *resData;
int i, nSections;
......@@ -189,8 +189,7 @@ static BOOL find_pe_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid,
}
/* Find resource */
resDir = (DWORD)resSection +
(resDataDir->VirtualAddress - sections[i].VirtualAddress);
resDir = resSection + (resDataDir->VirtualAddress - sections[i].VirtualAddress);
resPtr = (PIMAGE_RESOURCE_DIRECTORY)resDir;
resPtr = GetResDirEntryA( resPtr, typeid, resDir, FALSE );
......
......@@ -223,8 +223,10 @@ extern HRSRC PE_FindResourceW(HMODULE,LPCWSTR,LPCWSTR);
extern HRSRC PE_FindResourceExW(HMODULE,LPCWSTR,LPCWSTR,WORD);
extern DWORD PE_SizeofResource(HRSRC);
extern HGLOBAL PE_LoadResource(HMODULE,HRSRC);
extern PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA(PIMAGE_RESOURCE_DIRECTORY,LPCSTR,DWORD,BOOL);
extern PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY,LPCWSTR,DWORD,BOOL);
extern const IMAGE_RESOURCE_DIRECTORY *GetResDirEntryA(const IMAGE_RESOURCE_DIRECTORY*,
LPCSTR,LPCVOID,BOOL);
extern const IMAGE_RESOURCE_DIRECTORY *GetResDirEntryW(const IMAGE_RESOURCE_DIRECTORY*,
LPCWSTR,LPCVOID,BOOL);
/* loader/pe_image.c */
extern WINE_MODREF *PE_LoadLibraryExA(LPCSTR, DWORD);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment