ntdll: Implement RtlLcidToLocaleName().
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
ea9a776d7d
commit
a2d44e89ea
|
@ -64,6 +64,7 @@ static INT (WINAPI *pLCMapStringEx)(LPCWSTR, DWORD, LPCWSTR, INT, LPWSTR, INT, L
|
|||
static LCID (WINAPI *pLocaleNameToLCID)(LPCWSTR, DWORD);
|
||||
static NTSTATUS (WINAPI *pRtlLocaleNameToLcid)(LPCWSTR, LCID *, DWORD);
|
||||
static BOOLEAN (WINAPI *pRtlIsValidLocaleName)(const WCHAR *,ULONG);
|
||||
static NTSTATUS (WINAPI *pRtlLcidToLocaleName)(LCID, UNICODE_STRING *,DWORD,BYTE);
|
||||
static INT (WINAPI *pLCIDToLocaleName)(LCID, LPWSTR, INT, DWORD);
|
||||
static BOOL (WINAPI *pIsValidLanguageGroup)(LGRPID, DWORD);
|
||||
static INT (WINAPI *pIdnToNameprepUnicode)(DWORD, LPCWSTR, INT, LPWSTR, INT);
|
||||
|
@ -147,6 +148,7 @@ static void InitFunctionPointers(void)
|
|||
X(RtlUpcaseUnicodeChar);
|
||||
X(RtlLocaleNameToLcid);
|
||||
X(RtlIsValidLocaleName);
|
||||
X(RtlLcidToLocaleName);
|
||||
X(RtlNormalizeString);
|
||||
X(RtlIsNormalizedString);
|
||||
X(NtGetNlsSectionPtr);
|
||||
|
@ -2866,6 +2868,96 @@ static void test_LocaleNameToLCID(void)
|
|||
}
|
||||
}
|
||||
else win_skip( "RtlLocaleNameToLcid not available\n" );
|
||||
|
||||
if (pRtlLcidToLocaleName)
|
||||
{
|
||||
WCHAR buffer[128], expect[128];
|
||||
UNICODE_STRING str;
|
||||
|
||||
str.Buffer = buffer;
|
||||
str.MaximumLength = sizeof( buffer );
|
||||
memset( buffer, 0xcc, sizeof(buffer) );
|
||||
|
||||
status = pRtlLcidToLocaleName( LOCALE_NEUTRAL, &str, 0, 0 );
|
||||
ok( status == STATUS_INVALID_PARAMETER_1, "wrong error %lx\n", status );
|
||||
status = pRtlLcidToLocaleName( LOCALE_NEUTRAL, &str, 2, 0 );
|
||||
ok( status == STATUS_INVALID_PARAMETER_1, "wrong error %lx\n", status );
|
||||
status = pRtlLcidToLocaleName( LOCALE_INVARIANT, NULL, 0, 0 );
|
||||
ok( status == STATUS_INVALID_PARAMETER_2, "wrong error %lx\n", status );
|
||||
|
||||
memset( buffer, 0xcc, sizeof(buffer) );
|
||||
status = pRtlLcidToLocaleName( MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), &str, 0, 0 );
|
||||
ok( status == STATUS_SUCCESS, "wrong error %lx\n", status );
|
||||
ok( !wcscmp( buffer, L"en-US" ), "wrong name %s\n", debugstr_w(buffer) );
|
||||
ok( str.Length == wcslen(buffer) * sizeof(WCHAR), "wrong len %u\n", str.Length );
|
||||
ok( str.MaximumLength == sizeof(buffer), "wrong max len %u\n", str.MaximumLength );
|
||||
|
||||
status = pRtlLcidToLocaleName( MAKELANGID(LANG_ENGLISH, SUBLANG_NEUTRAL), &str, 0, 0 );
|
||||
ok( status == STATUS_INVALID_PARAMETER_1, "wrong error %lx\n", status );
|
||||
|
||||
memset( buffer, 0xcc, sizeof(buffer) );
|
||||
status = pRtlLcidToLocaleName( MAKELANGID(LANG_ENGLISH, SUBLANG_NEUTRAL), &str, 2, 0 );
|
||||
ok( status == STATUS_SUCCESS, "wrong error %lx\n", status );
|
||||
ok( str.Length == wcslen(buffer) * sizeof(WCHAR), "wrong len %u\n", str.Length );
|
||||
ok( !wcscmp( buffer, L"en" ), "wrong name %s\n", debugstr_w(buffer) );
|
||||
|
||||
memset( buffer, 0xcc, sizeof(buffer) );
|
||||
status = pRtlLcidToLocaleName( 0x00010407, &str, 0, 0 );
|
||||
ok( status == STATUS_SUCCESS, "wrong error %lx\n", status );
|
||||
ok( str.Length == wcslen(buffer) * sizeof(WCHAR), "wrong len %u\n", str.Length );
|
||||
ok( !wcscmp( buffer, L"de-DE_phoneb" ), "wrong name %s\n", debugstr_w(buffer) );
|
||||
|
||||
memset( buffer, 0xcc, sizeof(buffer) );
|
||||
status = pRtlLcidToLocaleName( LOCALE_SYSTEM_DEFAULT, &str, 0, 0 );
|
||||
ok( status == STATUS_SUCCESS, "wrong error %lx\n", status );
|
||||
ok( str.Length == wcslen(buffer) * sizeof(WCHAR), "wrong len %u\n", str.Length );
|
||||
LCIDToLocaleName( GetSystemDefaultLCID(), expect, ARRAY_SIZE(expect), 0 );
|
||||
ok( !wcscmp( buffer, expect ), "wrong name %s / %s\n", debugstr_w(buffer), debugstr_w(expect) );
|
||||
|
||||
memset( buffer, 0xcc, sizeof(buffer) );
|
||||
status = pRtlLcidToLocaleName( LOCALE_USER_DEFAULT, &str, 0, 0 );
|
||||
ok( status == STATUS_SUCCESS, "wrong error %lx\n", status );
|
||||
ok( str.Length == wcslen(buffer) * sizeof(WCHAR), "wrong len %u\n", str.Length );
|
||||
LCIDToLocaleName( GetUserDefaultLCID(), expect, ARRAY_SIZE(expect), 0 );
|
||||
ok( !wcscmp( buffer, expect ), "wrong name %s / %s\n", debugstr_w(buffer), debugstr_w(expect) );
|
||||
|
||||
memset( buffer, 0xcc, sizeof(buffer) );
|
||||
status = pRtlLcidToLocaleName( LOCALE_INVARIANT, &str, 0, 0 );
|
||||
ok( status == STATUS_SUCCESS, "wrong error %lx\n", status );
|
||||
ok( str.Length == wcslen(buffer) * sizeof(WCHAR), "wrong len %u\n", str.Length );
|
||||
ok( !wcscmp( buffer, L"" ), "wrong name %s\n", debugstr_w(buffer) );
|
||||
|
||||
memset( buffer, 0xcc, sizeof(buffer) );
|
||||
status = pRtlLcidToLocaleName( LOCALE_CUSTOM_DEFAULT, &str, 0, 0 );
|
||||
ok( status == STATUS_SUCCESS, "wrong error %lx\n", status );
|
||||
ok( str.Length == wcslen(buffer) * sizeof(WCHAR), "wrong len %u\n", str.Length );
|
||||
LCIDToLocaleName( GetUserDefaultLCID(), expect, ARRAY_SIZE(expect), 0 );
|
||||
ok( !wcscmp( buffer, expect ), "wrong name %s / %s\n", debugstr_w(buffer), debugstr_w(expect) );
|
||||
|
||||
status = pRtlLcidToLocaleName( LOCALE_CUSTOM_UI_DEFAULT, &str, 0, 0 );
|
||||
ok( status == STATUS_SUCCESS || status == STATUS_UNSUCCESSFUL, "wrong error %lx\n", status );
|
||||
|
||||
status = pRtlLcidToLocaleName( LOCALE_CUSTOM_UNSPECIFIED, &str, 0, 0 );
|
||||
ok( status == STATUS_INVALID_PARAMETER_1, "wrong error %lx\n", status );
|
||||
|
||||
memset( buffer, 0xcc, sizeof(buffer) );
|
||||
str.Length = 0xbeef;
|
||||
str.MaximumLength = 5 * sizeof(WCHAR);
|
||||
status = pRtlLcidToLocaleName( 0x00010407, &str, 0, 0 );
|
||||
ok( status == STATUS_BUFFER_TOO_SMALL, "wrong error %lx\n", status );
|
||||
ok( str.Length == 0xbeef, "wrong len %u\n", str.Length );
|
||||
ok( str.MaximumLength == 5 * sizeof(WCHAR), "wrong len %u\n", str.MaximumLength );
|
||||
ok( buffer[0] == 0xcccc, "wrong name %s\n", debugstr_w(buffer) );
|
||||
|
||||
memset( &str, 0xcc, sizeof(str) );
|
||||
status = pRtlLcidToLocaleName( MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), &str, 0, 1 );
|
||||
ok( status == STATUS_SUCCESS, "wrong error %lx\n", status );
|
||||
ok( str.Length == wcslen(str.Buffer) * sizeof(WCHAR), "wrong len %u\n", str.Length );
|
||||
ok( str.MaximumLength == str.Length + sizeof(WCHAR), "wrong max len %u\n", str.MaximumLength );
|
||||
ok( !wcscmp( str.Buffer, L"en-US" ), "wrong name %s\n", debugstr_w(str.Buffer) );
|
||||
RtlFreeUnicodeString( &str );
|
||||
}
|
||||
else win_skip( "RtlLcidToLocaleName not available\n" );
|
||||
}
|
||||
|
||||
/* this requires collation table patch to make it MS compatible */
|
||||
|
|
|
@ -269,6 +269,21 @@ static const NLS_LOCALE_LCNAME_INDEX *find_lcname_entry( const WCHAR *name )
|
|||
}
|
||||
|
||||
|
||||
static const NLS_LOCALE_LCID_INDEX *find_lcid_entry( LCID lcid )
|
||||
{
|
||||
int min = 0, max = locale_table->nb_lcids - 1;
|
||||
|
||||
while (min <= max)
|
||||
{
|
||||
int pos = (min + max) / 2;
|
||||
if (lcid < lcids_index[pos].id) max = pos - 1;
|
||||
else if (lcid > lcids_index[pos].id) min = pos + 1;
|
||||
else return &lcids_index[pos];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static const NLS_LOCALE_DATA *get_locale_data( UINT idx )
|
||||
{
|
||||
ULONG offset = locale_table->locales_offset + idx * locale_table->locale_size;
|
||||
|
@ -1238,6 +1253,54 @@ BOOLEAN WINAPI RtlIsValidLocaleName( const WCHAR *name, ULONG flags )
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* RtlLcidToLocaleName (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI RtlLcidToLocaleName( LCID lcid, UNICODE_STRING *str, ULONG flags, BOOLEAN alloc )
|
||||
{
|
||||
const NLS_LOCALE_LCID_INDEX *entry;
|
||||
const WCHAR *name;
|
||||
ULONG len;
|
||||
|
||||
if (!str) return STATUS_INVALID_PARAMETER_2;
|
||||
|
||||
switch (lcid)
|
||||
{
|
||||
case LOCALE_USER_DEFAULT:
|
||||
NtQueryDefaultLocale( TRUE, &lcid );
|
||||
break;
|
||||
case LOCALE_SYSTEM_DEFAULT:
|
||||
case LOCALE_CUSTOM_DEFAULT:
|
||||
NtQueryDefaultLocale( FALSE, &lcid );
|
||||
break;
|
||||
case LOCALE_CUSTOM_UI_DEFAULT:
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
case LOCALE_CUSTOM_UNSPECIFIED:
|
||||
return STATUS_INVALID_PARAMETER_1;
|
||||
}
|
||||
|
||||
if (!(entry = find_lcid_entry( lcid ))) return STATUS_INVALID_PARAMETER_1;
|
||||
/* reject neutral locale unless flag 2 is set */
|
||||
if (!(flags & 2) && !get_locale_data( entry->idx )->inotneutral) return STATUS_INVALID_PARAMETER_1;
|
||||
|
||||
name = locale_strings + entry->name;
|
||||
len = *name++;
|
||||
|
||||
if (alloc)
|
||||
{
|
||||
if (!(str->Buffer = RtlAllocateHeap( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) )))
|
||||
return STATUS_NO_MEMORY;
|
||||
str->MaximumLength = (len + 1) * sizeof(WCHAR);
|
||||
}
|
||||
else if (str->MaximumLength < (len + 1) * sizeof(WCHAR)) return STATUS_BUFFER_TOO_SMALL;
|
||||
|
||||
wcscpy( str->Buffer, name );
|
||||
str->Length = len * sizeof(WCHAR);
|
||||
TRACE( "%04x -> %s\n", lcid, debugstr_us(str) );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* RtlLocaleNameToLcid (NTDLL.@)
|
||||
*/
|
||||
|
|
|
@ -843,6 +843,7 @@
|
|||
@ stdcall -arch=win32 -ret64 RtlLargeIntegerShiftRight(int64 long)
|
||||
@ stdcall -arch=win32 -ret64 RtlLargeIntegerSubtract(int64 int64)
|
||||
@ stdcall RtlLargeIntegerToChar(ptr long long ptr)
|
||||
@ stdcall RtlLcidToLocaleName(long ptr long long)
|
||||
@ stdcall RtlLeaveCriticalSection(ptr)
|
||||
@ stdcall RtlLengthRequiredSid(long)
|
||||
@ stdcall RtlLengthSecurityDescriptor(ptr)
|
||||
|
|
|
@ -4403,6 +4403,7 @@ NTSYSAPI BOOLEAN WINAPI RtlIsTextUnicode(LPCVOID,INT,INT *);
|
|||
NTSYSAPI BOOLEAN WINAPI RtlIsValidHandle(const RTL_HANDLE_TABLE *, const RTL_HANDLE *);
|
||||
NTSYSAPI BOOLEAN WINAPI RtlIsValidIndexHandle(const RTL_HANDLE_TABLE *, ULONG Index, RTL_HANDLE **);
|
||||
NTSYSAPI BOOLEAN WINAPI RtlIsValidLocaleName(const WCHAR*,ULONG);
|
||||
NTSYSAPI NTSTATUS WINAPI RtlLcidToLocaleName(LCID,UNICODE_STRING*,ULONG,BOOLEAN);
|
||||
NTSYSAPI NTSTATUS WINAPI RtlLeaveCriticalSection(RTL_CRITICAL_SECTION *);
|
||||
NTSYSAPI DWORD WINAPI RtlLengthRequiredSid(DWORD);
|
||||
NTSYSAPI ULONG WINAPI RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR);
|
||||
|
|
Loading…
Reference in New Issue