Commit 05c88fa6 authored by Dmitry Timoshkov's avatar Dmitry Timoshkov Committed by Alexandre Julliard

Make FindResource and FindResourceEx fully windows compatible.

parent a3fcb47f
...@@ -218,6 +218,7 @@ extern void NE_DllProcessAttach( HMODULE16 hModule ); ...@@ -218,6 +218,7 @@ extern void NE_DllProcessAttach( HMODULE16 hModule );
HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD size ); HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD size );
/* loader/pe_resource.c */ /* loader/pe_resource.c */
extern HRSRC PE_FindResourceW(HMODULE,LPCWSTR,LPCWSTR);
extern HRSRC PE_FindResourceExW(HMODULE,LPCWSTR,LPCWSTR,WORD); extern HRSRC PE_FindResourceExW(HMODULE,LPCWSTR,LPCWSTR,WORD);
extern DWORD PE_SizeofResource(HRSRC); extern DWORD PE_SizeofResource(HRSRC);
extern HGLOBAL PE_LoadResource(HMODULE,HRSRC); extern HGLOBAL PE_LoadResource(HMODULE,HRSRC);
......
...@@ -117,12 +117,18 @@ PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA( PIMAGE_RESOURCE_DIRECTORY resdirptr, ...@@ -117,12 +117,18 @@ PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA( PIMAGE_RESOURCE_DIRECTORY resdirptr,
/********************************************************************** /**********************************************************************
* PE_FindResourceExW * PE_FindResourceExW
*
* FindResourceExA/W does search in the following order:
* 1. Exact specified language
* 2. Language with neutral sublanguage
* 3. Neutral language with neutral sublanguage
* 4. Neutral language with default sublanguage
*/ */
HANDLE PE_FindResourceExW( HMODULE hmod, LPCWSTR name, LPCWSTR type, WORD lang ) HRSRC PE_FindResourceExW( HMODULE hmod, LPCWSTR name, LPCWSTR type, WORD lang )
{ {
PIMAGE_RESOURCE_DIRECTORY resdirptr = get_resdir(hmod); PIMAGE_RESOURCE_DIRECTORY resdirptr = get_resdir(hmod);
DWORD root; DWORD root;
HANDLE result; HRSRC result;
if (!resdirptr) return 0; if (!resdirptr) return 0;
...@@ -131,17 +137,99 @@ HANDLE PE_FindResourceExW( HMODULE hmod, LPCWSTR name, LPCWSTR type, WORD lang ) ...@@ -131,17 +137,99 @@ HANDLE PE_FindResourceExW( HMODULE hmod, LPCWSTR name, LPCWSTR type, WORD lang )
return 0; return 0;
if ((resdirptr = GetResDirEntryW(resdirptr, name, root, FALSE)) == NULL) if ((resdirptr = GetResDirEntryW(resdirptr, name, root, FALSE)) == NULL)
return 0; return 0;
/* 1. Exact specified language */
result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE); result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE);
/* Try with only the primary language set */
if (!result) if (!result)
{ {
lang = MAKELANGID(PRIMARYLANGID(lang), SUBLANG_DEFAULT); /* 2. Language with neutral sublanguage */
lang = MAKELANGID(PRIMARYLANGID(lang), SUBLANG_NEUTRAL);
result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE);
}
if (!result)
{
/* 3. Neutral language with neutral sublanguage */
lang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE); result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE);
} }
/* Try LANG_NEUTRAL, too */
if(!result) if (!result)
return (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)0, root, TRUE); {
/* 4. Neutral language with default sublanguage */
lang = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);
result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE);
}
return result;
}
/**********************************************************************
* PE_FindResourceW
*
* Load[String]/[Icon]/[Menu]/[etc.] does use FindResourceA/W.
* FindResourceA/W does search in the following order:
* 1. Neutral language with neutral sublanguage
* 2. Neutral language with default sublanguage
* 3. Current locale lang id
* 4. Current locale lang id with neutral sublanguage
* 5. (!) LANG_ENGLISH, SUBLANG_DEFAULT
* 6. Return first in the list
*/
HRSRC PE_FindResourceW( HMODULE hmod, LPCWSTR name, LPCWSTR type )
{
PIMAGE_RESOURCE_DIRECTORY resdirptr = get_resdir(hmod);
DWORD root;
HRSRC result;
WORD lang;
if (!resdirptr) return 0;
root = (DWORD) resdirptr;
if ((resdirptr = GetResDirEntryW(resdirptr, type, root, FALSE)) == NULL)
return 0;
if ((resdirptr = GetResDirEntryW(resdirptr, name, root, FALSE)) == NULL)
return 0;
/* 1. Neutral language with neutral sublanguage */
lang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE);
if (!result)
{
/* 2. Neutral language with default sublanguage */
lang = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);
result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE);
}
if (!result)
{
/* 3. Current locale lang id */
lang = LANGIDFROMLCID(GetUserDefaultLCID());
result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE);
}
if (!result)
{
/* 4. Current locale lang id with neutral sublanguage */
lang = MAKELANGID(PRIMARYLANGID(lang), SUBLANG_NEUTRAL);
result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE);
}
if (!result)
{
/* 5. (!) LANG_ENGLISH, SUBLANG_DEFAULT */
lang = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT);
result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE);
}
if (!result)
{
/* 6. Return first in the list */
result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)0, root, TRUE);
}
return result; return result;
} }
......
...@@ -194,7 +194,14 @@ static HRSRC RES_FindResource2( HMODULE hModule, LPCSTR type, ...@@ -194,7 +194,14 @@ static HRSRC RES_FindResource2( HMODULE hModule, LPCSTR type,
else else
nameStr = (LPWSTR)name; nameStr = (LPWSTR)name;
hRsrc = PE_FindResourceExW( hModule, nameStr, typeStr, lang ); /* Here is the real difference between FindResouce and FindResourceEx */
if(lang == MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL) ||
lang == MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT) ||
lang == MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT) ||
lang == MAKELANGID(LANG_NEUTRAL, 3)) /* FIXME: real name? */
hRsrc = PE_FindResourceW( hModule, nameStr, typeStr );
else
hRsrc = PE_FindResourceExW( hModule, nameStr, typeStr, lang );
if ( HIWORD( type ) && !bUnicode ) if ( HIWORD( type ) && !bUnicode )
HeapFree( GetProcessHeap(), 0, typeStr ); HeapFree( GetProcessHeap(), 0, typeStr );
...@@ -319,7 +326,7 @@ HRSRC16 WINAPI FindResource16( HMODULE16 hModule, SEGPTR name, SEGPTR type ) ...@@ -319,7 +326,7 @@ HRSRC16 WINAPI FindResource16( HMODULE16 hModule, SEGPTR name, SEGPTR type )
LPCSTR typeStr = HIWORD(type)? PTR_SEG_TO_LIN(type) : (LPCSTR)type; LPCSTR typeStr = HIWORD(type)? PTR_SEG_TO_LIN(type) : (LPCSTR)type;
return RES_FindResource( hModule, typeStr, nameStr, return RES_FindResource( hModule, typeStr, nameStr,
GetSystemDefaultLangID(), FALSE, TRUE ); MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), FALSE, TRUE );
} }
/********************************************************************** /**********************************************************************
...@@ -328,7 +335,7 @@ HRSRC16 WINAPI FindResource16( HMODULE16 hModule, SEGPTR name, SEGPTR type ) ...@@ -328,7 +335,7 @@ HRSRC16 WINAPI FindResource16( HMODULE16 hModule, SEGPTR name, SEGPTR type )
HANDLE WINAPI FindResourceA( HMODULE hModule, LPCSTR name, LPCSTR type ) HANDLE WINAPI FindResourceA( HMODULE hModule, LPCSTR name, LPCSTR type )
{ {
return RES_FindResource( hModule, type, name, return RES_FindResource( hModule, type, name,
GetSystemDefaultLangID(), FALSE, FALSE ); MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), FALSE, FALSE );
} }
/********************************************************************** /**********************************************************************
...@@ -357,7 +364,7 @@ HRSRC WINAPI FindResourceExW( HMODULE hModule, ...@@ -357,7 +364,7 @@ HRSRC WINAPI FindResourceExW( HMODULE hModule,
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type) HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
{ {
return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name, return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name,
GetSystemDefaultLangID(), TRUE, FALSE ); MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), TRUE, FALSE );
} }
/********************************************************************** /**********************************************************************
......
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