Module: wine Branch: master Commit: 1e52895ef71dfef32d12287e3186f7d3b323c233 URL: https://source.winehq.org/git/wine.git/?a=commit;h=1e52895ef71dfef32d12287e3...
Author: Alexandre Julliard julliard@winehq.org Date: Tue Jun 7 15:58:22 2022 +0200
kernelbase: Implement IsNLSDefinedString().
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/kernel32/kernel32.spec | 2 +- dlls/kernel32/tests/locale.c | 52 +++++++++++++++++++++++++++++++++++++++++ dlls/kernelbase/kernelbase.spec | 2 +- dlls/kernelbase/locale.c | 41 ++++++++++++++++++++++++++++++++ include/winnls.h | 1 + tools/winedump/nls.c | 2 +- 6 files changed, 97 insertions(+), 3 deletions(-)
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index 418aa8f1c92..556156686f2 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -989,7 +989,7 @@ @ stdcall -import IsDBCSLeadByteEx(long long) @ stdcall -import IsDebuggerPresent() @ stub -i386 IsLSCallback -# @ stub IsNLSDefinedString +@ stdcall -import IsNLSDefinedString(long long ptr wstr long) @ stdcall -import IsNormalizedString(long wstr long) @ stdcall -import IsProcessInJob(long long ptr) @ stdcall -import IsProcessorFeaturePresent(long) diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c index 0edbe388720..9bd922dff98 100644 --- a/dlls/kernel32/tests/locale.c +++ b/dlls/kernel32/tests/locale.c @@ -95,6 +95,7 @@ static INT (WINAPI *pFindStringOrdinal)(DWORD, LPCWSTR lpStringSource, INT, LPCW static BOOL (WINAPI *pGetNLSVersion)(NLS_FUNCTION,LCID,NLSVERSIONINFO*); static BOOL (WINAPI *pGetNLSVersionEx)(NLS_FUNCTION,LPCWSTR,NLSVERSIONINFOEX*); static DWORD (WINAPI *pIsValidNLSVersion)(NLS_FUNCTION,LPCWSTR,NLSVERSIONINFOEX*); +static BOOL (WINAPI *pIsNLSDefinedString)(NLS_FUNCTION,DWORD,NLSVERSIONINFO*,const WCHAR *,int); 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*); @@ -146,6 +147,7 @@ static void InitFunctionPointers(void) X(GetNLSVersion); X(GetNLSVersionEx); X(IsValidNLSVersion); + X(IsNLSDefinedString);
mod = GetModuleHandleA("kernelbase"); X(NlsValidateLocale); @@ -7750,6 +7752,56 @@ static void test_NLSVersion(void) ok( GetLastError() == 0xdeadbeef, "wrong error %lu\n", GetLastError() ); } else win_skip( "IsValidNLSVersion not available\n" ); + + if (pIsNLSDefinedString) + { + SetLastError( 0xdeadbeef ); + info.dwNLSVersionInfoSize = sizeof(info); + ret = pIsNLSDefinedString( COMPARE_STRING, 0, (NLSVERSIONINFO *)&info, L"A", 1 ); + if (ret) + ok( GetLastError() == 0xdeadbeef, "wrong error %lu\n", GetLastError() ); + else + ok( broken( GetLastError() == ERROR_INSUFFICIENT_BUFFER ), /* win7 */ + "wrong error %lu\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + info.dwNLSVersionInfoSize = sizeof(info) + 1; + ret = pIsNLSDefinedString( COMPARE_STRING, 0, (NLSVERSIONINFO *)&info, L"A", 1 ); + ok( !ret, "IsNLSDefinedString succeeded\n" ); + ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %lu\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + info.dwNLSVersionInfoSize = offsetof( NLSVERSIONINFO, dwEffectiveId ); + ret = pIsNLSDefinedString( COMPARE_STRING, 0, (NLSVERSIONINFO *)&info, L"A", 1 ); + ok( ret, "IsNLSDefinedString failed err %lu\n", GetLastError() ); + ok( GetLastError() == 0xdeadbeef, "wrong error %lu\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + ret = pIsNLSDefinedString( 2, 0, (NLSVERSIONINFO *)&info, L"A", 1 ); + ok( !ret, "IsNLSDefinedString succeeded\n" ); + ok( GetLastError() == ERROR_INVALID_FLAGS, "wrong error %lu\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + ret = pIsNLSDefinedString( COMPARE_STRING, 0, (NLSVERSIONINFO *)&info, L"ABC", -10 ); + ok( ret, "IsNLSDefinedString failed err %lu\n", GetLastError() ); + ok( GetLastError() == 0xdeadbeef, "wrong error %lu\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + ret = pIsNLSDefinedString( COMPARE_STRING, 0, (NLSVERSIONINFO *)&info, L"ABC", -1 ); + ok( ret, "IsNLSDefinedString failed err %lu\n", GetLastError() ); + ok( GetLastError() == 0xdeadbeef, "wrong error %lu\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + ret = pIsNLSDefinedString( COMPARE_STRING, 0, (NLSVERSIONINFO *)&info, L"\xd800", 1 ); + ok( !ret, "IsNLSDefinedString failed err %lu\n", GetLastError() ); + ok( GetLastError() == 0xdeadbeef, "wrong error %lu\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + ret = pIsNLSDefinedString( COMPARE_STRING, 0, (NLSVERSIONINFO *)&info, L"\xd800", -20 ); + ok( !ret, "IsNLSDefinedString failed err %lu\n", GetLastError() ); + ok( GetLastError() == 0xdeadbeef, "wrong error %lu\n", GetLastError() ); + } + else win_skip( "IsNLSDefinedString not available\n" ); }
static void test_locale_nls(void) diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index d4b5b5d3eb8..1296757b29a 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -892,7 +892,7 @@ # @ stub IsEnclaveTypeSupported # @ stub IsGlobalizationUserSettingsKeyRedirected @ stdcall IsInternetESCEnabled() -@ stub IsNLSDefinedString +@ stdcall IsNLSDefinedString(long long ptr wstr long) @ stdcall IsNormalizedString(long wstr long) # @ stub IsProcessCritical @ stdcall IsProcessInJob(long long ptr) diff --git a/dlls/kernelbase/locale.c b/dlls/kernelbase/locale.c index 4b00ed90408..6995209e30c 100644 --- a/dlls/kernelbase/locale.c +++ b/dlls/kernelbase/locale.c @@ -6430,6 +6430,47 @@ BOOL WINAPI DECLSPEC_HOTPATCH IsValidLocaleName( const WCHAR *locale ) }
+/****************************************************************************** + * IsNLSDefinedString (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH IsNLSDefinedString( NLS_FUNCTION func, DWORD flags, NLSVERSIONINFO *info, + const WCHAR *str, int len ) +{ + int i; + + if (func != COMPARE_STRING) + { + SetLastError( ERROR_INVALID_FLAGS ); + return FALSE; + } + if (info) + { + if (info->dwNLSVersionInfoSize != sizeof(*info) && + (info->dwNLSVersionInfoSize != offsetof( NLSVERSIONINFO, dwEffectiveId ))) + { + SetLastError( ERROR_INSUFFICIENT_BUFFER ); + return FALSE; + } + } + + if (len < 0) len = lstrlenW( str ) + 1; + + for (i = 0; i < len; i++) + { + if (is_private_use_area_char( str[i] )) return FALSE; + if (IS_LOW_SURROGATE( str[i] )) return FALSE; + if (IS_HIGH_SURROGATE( str[i] )) + { + if (++i == len) return FALSE; + if (!IS_LOW_SURROGATE( str[i] )) return FALSE; + continue; + } + if (!(get_char_type( CT_CTYPE1, str[i] ) & C1_DEFINED)) return FALSE; + } + return TRUE; +} + + /****************************************************************************** * IsValidNLSVersion (kernelbase.@) */ diff --git a/include/winnls.h b/include/winnls.h index e095cbcda89..d7d3d316509 100644 --- a/include/winnls.h +++ b/include/winnls.h @@ -964,6 +964,7 @@ WINNORMALIZEAPI INT WINAPI IdnToNameprepUnicode(DWORD,LPCWSTR,INT,LPWSTR,INT) WINNORMALIZEAPI INT WINAPI IdnToUnicode(DWORD,LPCWSTR,INT,LPWSTR,INT); WINBASEAPI BOOL WINAPI IsDBCSLeadByte(BYTE); WINBASEAPI BOOL WINAPI IsDBCSLeadByteEx(UINT,BYTE); +WINBASEAPI BOOL WINAPI IsNLSDefinedString(NLS_FUNCTION,DWORD,NLSVERSIONINFO*,LPCWSTR,INT); WINNORMALIZEAPI BOOL WINAPI IsNormalizedString(NORM_FORM,LPCWSTR,INT); WINBASEAPI BOOL WINAPI IsValidCodePage(UINT); WINBASEAPI BOOL WINAPI IsValidLanguageGroup(LGRPID,DWORD); diff --git a/tools/winedump/nls.c b/tools/winedump/nls.c index ab628517362..b52518604c8 100644 --- a/tools/winedump/nls.c +++ b/tools/winedump/nls.c @@ -110,7 +110,7 @@ struct ctype static const char *get_ctype( const struct ctype *ctype ) { static char buffer[100]; - static const char *c1[] = { "up ", "lo ", "dg ", "sp ", "pt ", "cl ", "bl ", "xd ", "al " }; + static const char *c1[] = { "up ", "lo ", "dg ", "sp ", "pt ", "cl ", "bl ", "xd ", "al " , "df "}; static const char *c2[] = { " ", "L ", "R ", "EN", "ES", "ET", "AN", "CS", "B ", "S ", "WS", "ON" }; static const char *c3[] = { "ns ", "di ", "vo ", "sy ", "ka ", "hi ", "hw ", "fw ",