kernelbase: Implement GetNLSVersion/GetNLSVersionEx().
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
3795484e81
commit
86522976c9
|
@ -724,6 +724,8 @@
|
|||
@ stdcall -import GetModuleHandleExA(long ptr ptr)
|
||||
@ stdcall -import GetModuleHandleExW(long ptr ptr)
|
||||
@ stdcall -import GetModuleHandleW(wstr)
|
||||
@ stdcall -import GetNLSVersion(long long ptr)
|
||||
@ stdcall -import GetNLSVersionEx(long wstr ptr)
|
||||
# @ stub GetNamedPipeAttribute
|
||||
# @ stub GetNamedPipeClientComputerNameA
|
||||
# @ stub GetNamedPipeClientComputerNameW
|
||||
|
@ -738,8 +740,6 @@
|
|||
@ stdcall -arch=x86_64 GetNextUmsListItem(ptr)
|
||||
@ stub GetNextVDMCommand
|
||||
@ stub GetNlsSectionName
|
||||
# @ stub GetNLSVersion
|
||||
# @ stub GetNLSVersionEx
|
||||
# @ stub GetNumaAvailableMemory
|
||||
@ stdcall GetNumaAvailableMemoryNode(long ptr)
|
||||
@ stdcall GetNumaAvailableMemoryNodeEx(long ptr)
|
||||
|
|
|
@ -85,6 +85,8 @@ static LANGID (WINAPI *pSetThreadUILanguage)(LANGID);
|
|||
static LANGID (WINAPI *pGetThreadUILanguage)(VOID);
|
||||
static INT (WINAPI *pNormalizeString)(NORM_FORM, LPCWSTR, INT, LPWSTR, INT);
|
||||
static INT (WINAPI *pFindStringOrdinal)(DWORD, LPCWSTR lpStringSource, INT, LPCWSTR, INT, BOOL);
|
||||
static BOOL (WINAPI *pGetNLSVersion)(NLS_FUNCTION,LCID,NLSVERSIONINFO*);
|
||||
static BOOL (WINAPI *pGetNLSVersionEx)(NLS_FUNCTION,LPCWSTR,NLSVERSIONINFOEX*);
|
||||
static NTSTATUS (WINAPI *pRtlNormalizeString)(ULONG, LPCWSTR, INT, LPWSTR, INT*);
|
||||
static NTSTATUS (WINAPI *pRtlIsNormalizedString)(ULONG, LPCWSTR, INT, BOOLEAN*);
|
||||
static NTSTATUS (WINAPI *pNtGetNlsSectionPtr)(ULONG,ULONG,void*,void**,SIZE_T*);
|
||||
|
@ -125,6 +127,8 @@ static void InitFunctionPointers(void)
|
|||
X(GetThreadUILanguage);
|
||||
X(NormalizeString);
|
||||
X(FindStringOrdinal);
|
||||
X(GetNLSVersion);
|
||||
X(GetNLSVersionEx);
|
||||
|
||||
mod = GetModuleHandleA("ntdll");
|
||||
X(RtlUpcaseUnicodeChar);
|
||||
|
@ -6633,6 +6637,134 @@ static void test_SpecialCasing(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void test_NLSVersion(void)
|
||||
{
|
||||
static const GUID guid_null = { 0 };
|
||||
static const GUID guid_def = { 0x000000001, 0x57ee, 0x1e5c, {0x00,0xb4,0xd0,0x00,0x0b,0xb1,0xe1,0x1e}};
|
||||
static const GUID guid_fr = { 0x000000003, 0x57ee, 0x1e5c, {0x00,0xb4,0xd0,0x00,0x0b,0xb1,0xe1,0x1e}};
|
||||
static const GUID guid_ja = { 0x000000046, 0x57ee, 0x1e5c, {0x00,0xb4,0xd0,0x00,0x0b,0xb1,0xe1,0x1e}};
|
||||
BOOL ret;
|
||||
NLSVERSIONINFOEX info;
|
||||
|
||||
if (!pGetNLSVersion)
|
||||
{
|
||||
win_skip( "GetNLSVersion not available\n" );
|
||||
return;
|
||||
}
|
||||
SetLastError( 0xdeadbeef );
|
||||
memset( &info, 0xcc, sizeof(info) );
|
||||
info.dwNLSVersionInfoSize = sizeof(info);
|
||||
ret = pGetNLSVersion( COMPARE_STRING, MAKELANGID( LANG_FRENCH, SUBLANG_FRENCH_CANADIAN ),
|
||||
(NLSVERSIONINFO *)&info );
|
||||
ok( ret, "GetNLSVersion failed err %u\n", GetLastError() );
|
||||
ok( info.dwEffectiveId == MAKELANGID( LANG_FRENCH, SUBLANG_FRENCH_CANADIAN ),
|
||||
"wrong id %x\n", info.dwEffectiveId );
|
||||
ok( IsEqualIID( &info.guidCustomVersion, &guid_fr ) ||
|
||||
broken( IsEqualIID( &info.guidCustomVersion, &guid_null )), /* <= win7 */
|
||||
"wrong guid %s\n", debugstr_guid(&info.guidCustomVersion) );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
info.dwNLSVersionInfoSize = 8;
|
||||
ret = pGetNLSVersion( COMPARE_STRING, LOCALE_USER_DEFAULT, (NLSVERSIONINFO *)&info );
|
||||
ok( !ret, "GetNLSVersion succeeded\n" );
|
||||
ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %u\n", GetLastError() );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
info.dwNLSVersionInfoSize = sizeof(info);
|
||||
ret = pGetNLSVersion( 2, LOCALE_USER_DEFAULT, (NLSVERSIONINFO *)&info );
|
||||
ok( !ret, "GetNLSVersion succeeded\n" );
|
||||
ok( GetLastError() == ERROR_INVALID_FLAGS, "wrong error %u\n", GetLastError() );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
info.dwNLSVersionInfoSize = sizeof(info);
|
||||
ret = pGetNLSVersion( COMPARE_STRING, 0xdeadbeef, (NLSVERSIONINFO *)&info );
|
||||
ok( !ret, "GetNLSVersion succeeded\n" );
|
||||
ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
|
||||
|
||||
if (pGetNLSVersionEx)
|
||||
{
|
||||
SetLastError( 0xdeadbeef );
|
||||
memset( &info, 0xcc, sizeof(info) );
|
||||
info.dwNLSVersionInfoSize = sizeof(info);
|
||||
ret = pGetNLSVersionEx( COMPARE_STRING, L"ja-JP", &info );
|
||||
ok( ret, "GetNLSVersionEx failed err %u\n", GetLastError() );
|
||||
ok( info.dwEffectiveId == MAKELANGID( LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN ),
|
||||
"wrong id %x\n", info.dwEffectiveId );
|
||||
ok( IsEqualIID( &info.guidCustomVersion, &guid_ja ) ||
|
||||
broken( IsEqualIID( &info.guidCustomVersion, &guid_null )), /* <= win7 */
|
||||
"wrong guid %s\n", debugstr_guid(&info.guidCustomVersion) );
|
||||
trace( "version %08x %08x %08x %s\n", info.dwNLSVersion, info.dwDefinedVersion, info.dwEffectiveId,
|
||||
debugstr_guid(&info.guidCustomVersion) );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
memset( &info, 0xcc, sizeof(info) );
|
||||
info.dwNLSVersionInfoSize = sizeof(info);
|
||||
ret = pGetNLSVersionEx( COMPARE_STRING, L"fr", &info );
|
||||
ok( !ret == !pIsValidLocaleName(L"fr"), "GetNLSVersionEx doesn't match IsValidLocaleName\n" );
|
||||
if (ret)
|
||||
{
|
||||
ok( info.dwEffectiveId == MAKELANGID( LANG_FRENCH, SUBLANG_DEFAULT ),
|
||||
"wrong id %x\n", info.dwEffectiveId );
|
||||
ok( IsEqualIID( &info.guidCustomVersion, &guid_fr ) ||
|
||||
broken( IsEqualIID( &info.guidCustomVersion, &guid_null )), /* <= win7 */
|
||||
"wrong guid %s\n", debugstr_guid(&info.guidCustomVersion) );
|
||||
}
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
info.dwNLSVersionInfoSize = sizeof(info) - 1;
|
||||
ret = pGetNLSVersionEx( COMPARE_STRING, L"en-US", &info );
|
||||
ok( !ret, "GetNLSVersionEx succeeded\n" );
|
||||
ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %u\n", GetLastError() );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
memset( &info, 0xcc, sizeof(info) );
|
||||
info.dwNLSVersionInfoSize = offsetof( NLSVERSIONINFO, dwEffectiveId );
|
||||
ret = pGetNLSVersionEx( COMPARE_STRING, L"en-US", &info );
|
||||
ok( ret, "GetNLSVersionEx failed err %u\n", GetLastError() );
|
||||
ok( info.dwEffectiveId == 0xcccccccc, "wrong id %x\n", info.dwEffectiveId );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
info.dwNLSVersionInfoSize = sizeof(info);
|
||||
ret = pGetNLSVersionEx( 2, L"en-US", &info );
|
||||
ok( !ret, "GetNLSVersionEx succeeded\n" );
|
||||
ok( GetLastError() == ERROR_INVALID_FLAGS, "wrong error %u\n", GetLastError() );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
info.dwNLSVersionInfoSize = sizeof(info);
|
||||
ret = pGetNLSVersionEx( COMPARE_STRING, L"foobar", &info );
|
||||
ok( !ret, "GetNLSVersionEx succeeded\n" );
|
||||
ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
memset( &info, 0xcc, sizeof(info) );
|
||||
info.dwNLSVersionInfoSize = sizeof(info);
|
||||
ret = pGetNLSVersionEx( COMPARE_STRING, L"zz-XX", &info );
|
||||
if (!ret) ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
|
||||
ok( !ret == !pIsValidLocaleName(L"zz-XX"), "GetNLSVersionEx doesn't match IsValidLocaleName\n" );
|
||||
if (ret)
|
||||
{
|
||||
ok( info.dwEffectiveId == LOCALE_CUSTOM_UNSPECIFIED, "wrong id %x\n", info.dwEffectiveId );
|
||||
ok( IsEqualIID( &info.guidCustomVersion, &guid_def ),
|
||||
"wrong guid %s\n", debugstr_guid(&info.guidCustomVersion) );
|
||||
}
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
memset( &info, 0xcc, sizeof(info) );
|
||||
info.dwNLSVersionInfoSize = sizeof(info);
|
||||
ret = pGetNLSVersionEx( COMPARE_STRING, LOCALE_NAME_INVARIANT, &info );
|
||||
ok( ret, "GetNLSVersionEx failed err %u\n", GetLastError() );
|
||||
if (ret)
|
||||
{
|
||||
ok( info.dwEffectiveId == LOCALE_INVARIANT, "wrong id %x\n", info.dwEffectiveId );
|
||||
ok( IsEqualIID( &info.guidCustomVersion, &guid_def ) ||
|
||||
broken( IsEqualIID( &info.guidCustomVersion, &guid_null )), /* <= win7 */
|
||||
"wrong guid %s\n", debugstr_guid(&info.guidCustomVersion) );
|
||||
}
|
||||
else ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
|
||||
}
|
||||
else win_skip( "GetNLSVersionEx not available\n" );
|
||||
}
|
||||
|
||||
START_TEST(locale)
|
||||
{
|
||||
InitFunctionPointers();
|
||||
|
@ -6682,6 +6814,7 @@ START_TEST(locale)
|
|||
test_SetThreadUILanguage();
|
||||
test_NormalizeString();
|
||||
test_SpecialCasing();
|
||||
test_NLSVersion();
|
||||
/* this requires collation table patch to make it MS compatible */
|
||||
if (0) test_sorting();
|
||||
}
|
||||
|
|
|
@ -565,8 +565,8 @@
|
|||
@ stdcall GetModuleHandleExW(long ptr ptr)
|
||||
@ stdcall GetModuleHandleW(wstr)
|
||||
# @ stub GetModuleInformation
|
||||
@ stub GetNLSVersion
|
||||
@ stub GetNLSVersionEx
|
||||
@ stdcall GetNLSVersion(long long ptr)
|
||||
@ stdcall GetNLSVersionEx(long wstr ptr)
|
||||
@ stub GetNamedLocaleHashNode
|
||||
@ stub GetNamedPipeAttribute
|
||||
@ stub GetNamedPipeClientComputerNameW
|
||||
|
|
|
@ -4260,6 +4260,60 @@ INT WINAPI DECLSPEC_HOTPATCH GetLocaleInfoEx( const WCHAR *locale, LCTYPE info,
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* GetNLSVersion (kernelbase.@)
|
||||
*/
|
||||
BOOL WINAPI DECLSPEC_HOTPATCH GetNLSVersion( NLS_FUNCTION func, LCID lcid, NLSVERSIONINFO *info )
|
||||
{
|
||||
WCHAR locale[LOCALE_NAME_MAX_LENGTH];
|
||||
|
||||
if (info->dwNLSVersionInfoSize < offsetof( NLSVERSIONINFO, dwEffectiveId ))
|
||||
{
|
||||
SetLastError( ERROR_INSUFFICIENT_BUFFER );
|
||||
return FALSE;
|
||||
}
|
||||
if (!LCIDToLocaleName( lcid, locale, LOCALE_NAME_MAX_LENGTH, LOCALE_ALLOW_NEUTRAL_NAMES ))
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return FALSE;
|
||||
}
|
||||
return GetNLSVersionEx( func, locale, (NLSVERSIONINFOEX *)info );
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* GetNLSVersionEx (kernelbase.@)
|
||||
*/
|
||||
BOOL WINAPI DECLSPEC_HOTPATCH GetNLSVersionEx( NLS_FUNCTION func, const WCHAR *locale,
|
||||
NLSVERSIONINFOEX *info )
|
||||
{
|
||||
LCID lcid = 0;
|
||||
|
||||
if (func != COMPARE_STRING)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_FLAGS );
|
||||
return FALSE;
|
||||
}
|
||||
if (info->dwNLSVersionInfoSize < sizeof(*info) &&
|
||||
(info->dwNLSVersionInfoSize != offsetof( NLSVERSIONINFO, dwEffectiveId )))
|
||||
{
|
||||
SetLastError( ERROR_INSUFFICIENT_BUFFER );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!(lcid = LocaleNameToLCID( locale, 0 ))) return FALSE;
|
||||
|
||||
info->dwNLSVersion = info->dwDefinedVersion = sort.version;
|
||||
if (info->dwNLSVersionInfoSize >= sizeof(*info))
|
||||
{
|
||||
const struct sortguid *sortid = get_language_sort( locale );
|
||||
info->dwEffectiveId = lcid;
|
||||
info->guidCustomVersion = sortid ? sortid->id : default_sort_guid;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* GetOEMCP (kernelbase.@)
|
||||
*/
|
||||
|
|
|
@ -735,6 +735,8 @@ typedef struct _nlsversioninfo {
|
|||
DWORD dwNLSVersionInfoSize;
|
||||
DWORD dwNLSVersion;
|
||||
DWORD dwDefinedVersion;
|
||||
DWORD dwEffectiveId;
|
||||
GUID guidCustomVersion;
|
||||
} NLSVERSIONINFO, *LPNLSVERSIONINFO;
|
||||
|
||||
typedef struct _nlsversioninfoex {
|
||||
|
@ -745,6 +747,9 @@ typedef struct _nlsversioninfoex {
|
|||
GUID guidCustomVersion;
|
||||
} NLSVERSIONINFOEX, *LPNLSVERSIONINFOEX;
|
||||
|
||||
enum SYSNLS_FUNCTION { COMPARE_STRING = 1 };
|
||||
typedef DWORD NLS_FUNCTION;
|
||||
|
||||
/* Define a bunch of callback types */
|
||||
|
||||
typedef BOOL (CALLBACK *CALINFO_ENUMPROCEXEX)(LPWSTR,CALID,LPWSTR,LPARAM);
|
||||
|
@ -913,6 +918,8 @@ WINBASEAPI INT WINAPI GetLocaleInfoA(LCID,LCTYPE,LPSTR,INT);
|
|||
WINBASEAPI INT WINAPI GetLocaleInfoW(LCID,LCTYPE,LPWSTR,INT);
|
||||
#define GetLocaleInfo WINELIB_NAME_AW(GetLocaleInfo)
|
||||
WINBASEAPI INT WINAPI GetLocaleInfoEx(LPCWSTR,LCTYPE,LPWSTR,INT);
|
||||
WINBASEAPI BOOL WINAPI GetNLSVersion(NLS_FUNCTION,LCID,NLSVERSIONINFO*);
|
||||
WINBASEAPI BOOL WINAPI GetNLSVersionEx(NLS_FUNCTION,LPCWSTR,NLSVERSIONINFOEX*);
|
||||
WINBASEAPI INT WINAPI GetNumberFormatA(LCID,DWORD,LPCSTR,const NUMBERFMTA*,LPSTR,INT);
|
||||
WINBASEAPI INT WINAPI GetNumberFormatW(LCID,DWORD,LPCWSTR,const NUMBERFMTW*,LPWSTR,INT);
|
||||
#define GetNumberFormat WINELIB_NAME_AW(GetNumberFormat)
|
||||
|
|
Loading…
Reference in New Issue