From 05c88fa66474003f4831b6bb217d4a54a17ded06 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Fri, 11 Aug 2000 12:50:56 +0000 Subject: [PATCH] Make FindResource and FindResourceEx fully windows compatible. --- include/module.h | 1 + loader/pe_resource.c | 102 ++++++++++++++++++++++++++++++++++++++++--- loader/resource.c | 15 +++++-- 3 files changed, 107 insertions(+), 11 deletions(-) diff --git a/include/module.h b/include/module.h index 20b0d09ae5e..12568b5185b 100644 --- a/include/module.h +++ b/include/module.h @@ -218,6 +218,7 @@ extern void NE_DllProcessAttach( HMODULE16 hModule ); HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD size ); /* loader/pe_resource.c */ +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); diff --git a/loader/pe_resource.c b/loader/pe_resource.c index 878d5e1ea4a..94d16cd3b12 100644 --- a/loader/pe_resource.c +++ b/loader/pe_resource.c @@ -117,12 +117,18 @@ PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA( PIMAGE_RESOURCE_DIRECTORY resdirptr, /********************************************************************** * 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); DWORD root; - HANDLE result; + HRSRC result; if (!resdirptr) return 0; @@ -131,17 +137,99 @@ HANDLE PE_FindResourceExW( HMODULE hmod, LPCWSTR name, LPCWSTR type, WORD lang ) return 0; if ((resdirptr = GetResDirEntryW(resdirptr, name, root, FALSE)) == NULL) return 0; + + /* 1. Exact specified language */ result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE); - /* Try with only the primary language set */ 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); } - /* Try LANG_NEUTRAL, too */ - if(!result) - return (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)0, root, TRUE); + + if (!result) + { + /* 3. Neutral language with neutral sublanguage */ + lang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL); + result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE); + } + + if (!result) + { + /* 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; } diff --git a/loader/resource.c b/loader/resource.c index 512c2eac222..cec6f6c5413 100644 --- a/loader/resource.c +++ b/loader/resource.c @@ -194,7 +194,14 @@ static HRSRC RES_FindResource2( HMODULE hModule, LPCSTR type, else 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 ) HeapFree( GetProcessHeap(), 0, typeStr ); @@ -319,7 +326,7 @@ HRSRC16 WINAPI FindResource16( HMODULE16 hModule, SEGPTR name, SEGPTR type ) LPCSTR typeStr = HIWORD(type)? PTR_SEG_TO_LIN(type) : (LPCSTR)type; 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 ) HANDLE WINAPI FindResourceA( HMODULE hModule, LPCSTR name, LPCSTR type ) { 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, HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type) { return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name, - GetSystemDefaultLangID(), TRUE, FALSE ); + MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), TRUE, FALSE ); } /**********************************************************************