kernel32: Move some locale functions to kernelbase.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2019-11-21 10:55:35 +01:00
parent fd588a22b7
commit 2cbb6f8d34
4 changed files with 226 additions and 296 deletions

View File

@ -248,7 +248,7 @@
@ stub ConsoleSubst
@ stdcall -import ContinueDebugEvent(long long long)
# @ stub ConvertCalDateTimeToSystemTime
@ stdcall ConvertDefaultLocale (long)
@ stdcall -import ConvertDefaultLocale (long)
@ stdcall -import ConvertFiberToThread()
# @ stub ConvertNLSDayOfWeekToWin32DayOfWeek
# @ stub ConvertSystemTimeToCalDateTime
@ -537,7 +537,7 @@
@ stub FreeVirtualBuffer
@ stdcall -import GenerateConsoleCtrlEvent(long long)
@ stdcall -i386 -private Get16DLLAddress(long str) krnl386.exe16.Get16DLLAddress
@ stdcall GetACP()
@ stdcall -import GetACP()
@ stdcall GetActiveProcessorCount(long)
@ stdcall GetActiveProcessorGroupCount()
# @ stub GetApplicationRecoveryCallback
@ -703,9 +703,9 @@
@ stdcall -import GetLastError()
@ stub GetLinguistLangSize
@ stdcall -import GetLocalTime(ptr)
@ stdcall GetLocaleInfoA(long long ptr long)
@ stdcall -import GetLocaleInfoA(long long ptr long)
@ stdcall GetLocaleInfoW(long long ptr long)
@ stdcall GetLocaleInfoEx(wstr long ptr long)
@ stdcall -import GetLocaleInfoEx(wstr long ptr long)
@ stdcall GetLogicalDriveStringsA(long ptr)
@ stdcall GetLogicalDriveStringsW(long ptr)
@ stdcall GetLogicalDrives()
@ -758,7 +758,7 @@
@ stdcall GetNumberOfConsoleFonts()
@ stdcall -import GetNumberOfConsoleInputEvents(long ptr)
@ stdcall GetNumberOfConsoleMouseButtons(ptr)
@ stdcall GetOEMCP()
@ stdcall -import GetOEMCP()
@ stdcall -import GetOverlappedResult(long ptr ptr long)
@ stdcall GetUserPreferredUILanguages(long ptr ptr ptr)
@ stdcall GetPackageFullName(long ptr ptr)
@ -991,8 +991,8 @@
# @ stub IsValidCalDateTime
@ stdcall IsValidCodePage(long)
@ stdcall -import IsValidLanguageGroup(long long)
@ stdcall IsValidLocale(long long)
@ stdcall IsValidLocaleName(wstr)
@ stdcall -import IsValidLocale(long long)
@ stdcall -import IsValidLocaleName(wstr)
# @ stub IsValidUILanguage
@ stdcall -import IsWow64Process(ptr ptr)
@ stdcall K32EmptyWorkingSet(long)
@ -1061,7 +1061,7 @@
@ stdcall LocalShrink(long long)
@ stdcall LocalSize(long)
@ stdcall -import LocalUnlock(long)
@ stdcall LocaleNameToLCID(wstr long)
@ stdcall -import LocaleNameToLCID(wstr long)
# @ stub LocateXStateFeature
@ stdcall -import LockFile(long long long long long)
@ stdcall -import LockFileEx(long long long long long ptr)

View File

@ -443,20 +443,6 @@ BOOL WINAPI GetUserPreferredUILanguages( DWORD flags, ULONG *count, WCHAR *buffe
return get_dummy_preferred_ui_language( flags, count, buffer, size );
}
/***********************************************************************
* LocaleNameToLCID (KERNEL32.@)
*/
LCID WINAPI LocaleNameToLCID( LPCWSTR name, DWORD flags )
{
LCID lcid;
if (!name) return GetUserDefaultLCID();
if (!set_ntstatus( RtlLocaleNameToLcid( name, &lcid, 2 ))) return 0;
if (!(flags & LOCALE_ALLOW_NEUTRAL_NAMES)) lcid = ConvertDefaultLocale( lcid );
return lcid;
}
/******************************************************************************
* get_locale_registry_value
*
@ -589,83 +575,6 @@ static INT get_registry_locale_info( struct registry_value *registry_value, LPWS
}
/******************************************************************************
* GetLocaleInfoA (KERNEL32.@)
*
* Get information about an aspect of a locale.
*
* PARAMS
* lcid [I] LCID of the locale
* lctype [I] LCTYPE_ flags from "winnls.h"
* buffer [O] Destination for the information
* len [I] Length of buffer in characters
*
* RETURNS
* Success: The size of the data requested. If buffer is non-NULL, it is filled
* with the information.
* Failure: 0. Use GetLastError() to determine the cause.
*
* NOTES
* - LOCALE_NEUTRAL is equal to LOCALE_SYSTEM_DEFAULT
* - The string returned is NUL terminated, except for LOCALE_FONTSIGNATURE,
* which is a bit string.
*/
INT WINAPI GetLocaleInfoA( LCID lcid, LCTYPE lctype, LPSTR buffer, INT len )
{
WCHAR *bufferW;
INT lenW, ret;
TRACE( "(lcid=0x%x,lctype=0x%x,%p,%d)\n", lcid, lctype, buffer, len );
if (len < 0 || (len && !buffer))
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
if (((lctype & ~LOCALE_LOCALEINFOFLAGSMASK) == LOCALE_SSHORTTIME) ||
(lctype & LOCALE_RETURN_GENITIVE_NAMES))
{
SetLastError( ERROR_INVALID_FLAGS );
return 0;
}
if (!len) buffer = NULL;
if (!(lenW = GetLocaleInfoW( lcid, lctype, NULL, 0 ))) return 0;
if (!(bufferW = HeapAlloc( GetProcessHeap(), 0, lenW * sizeof(WCHAR) )))
{
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return 0;
}
if ((ret = GetLocaleInfoW( lcid, lctype, bufferW, lenW )))
{
if ((lctype & LOCALE_RETURN_NUMBER) ||
((lctype & ~LOCALE_LOCALEINFOFLAGSMASK) == LOCALE_FONTSIGNATURE))
{
/* it's not an ASCII string, just bytes */
ret *= sizeof(WCHAR);
if (buffer)
{
if (ret <= len) memcpy( buffer, bufferW, ret );
else
{
SetLastError( ERROR_INSUFFICIENT_BUFFER );
ret = 0;
}
}
}
else
{
UINT codepage = CP_ACP;
if (!(lctype & LOCALE_USE_CP_ACP)) codepage = get_lcid_codepage( lcid );
ret = WideCharToMultiByte( codepage, 0, bufferW, ret, buffer, len, NULL, NULL );
}
}
HeapFree( GetProcessHeap(), 0, bufferW );
return ret;
}
static int get_value_base_by_lctype( LCTYPE lctype )
{
return lctype == LOCALE_ILANGUAGE || lctype == LOCALE_IDEFAULTLANGUAGE ? 16 : 10;
@ -811,39 +720,6 @@ INT WINAPI GetLocaleInfoW( LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len )
return ret;
}
/******************************************************************************
* GetLocaleInfoEx (KERNEL32.@)
*/
INT WINAPI GetLocaleInfoEx(LPCWSTR locale, LCTYPE info, LPWSTR buffer, INT len)
{
LCID lcid = LocaleNameToLCID(locale, 0);
TRACE("%s, lcid=0x%x, 0x%x\n", debugstr_w(locale), lcid, info);
if (!lcid) return 0;
/* special handling for neutral locale names */
if (locale && strlenW(locale) == 2)
{
switch (info & ~LOCALE_LOCALEINFOFLAGSMASK)
{
case LOCALE_SNAME:
if (len && len < 3)
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return 0;
}
if (len) strcpyW(buffer, locale);
return 3;
case LOCALE_SPARENT:
if (len) buffer[0] = 0;
return 1;
}
}
return GetLocaleInfoW(lcid, info, buffer, len);
}
/******************************************************************************
* SetLocaleInfoA [KERNEL32.@]
*
@ -986,24 +862,6 @@ BOOL WINAPI SetLocaleInfoW( LCID lcid, LCTYPE lctype, LPCWSTR data )
}
/******************************************************************************
* GetACP (KERNEL32.@)
*
* Get the current Ansi code page Id for the system.
*
* PARAMS
* None.
*
* RETURNS
* The current Ansi code page identifier for the system.
*/
UINT WINAPI GetACP(void)
{
assert( ansi_cptable );
return ansi_cptable->info.codepage;
}
/******************************************************************************
* SetCPGlobal (KERNEL32.@)
*
@ -1025,24 +883,6 @@ UINT WINAPI SetCPGlobal( UINT acp )
}
/***********************************************************************
* GetOEMCP (KERNEL32.@)
*
* Get the current OEM code page Id for the system.
*
* PARAMS
* None.
*
* RETURNS
* The current OEM code page identifier for the system.
*/
UINT WINAPI GetOEMCP(void)
{
assert( oem_cptable );
return oem_cptable->info.codepage;
}
/***********************************************************************
* IsValidCodePage (KERNEL32.@)
*
@ -1722,97 +1562,6 @@ INT WINAPI WideCharToMultiByte( UINT page, DWORD flags, LPCWSTR src, INT srclen,
}
/******************************************************************************
* ConvertDefaultLocale (KERNEL32.@)
*
* Convert a default locale identifier into a real identifier.
*
* PARAMS
* lcid [I] LCID identifier of the locale to convert
*
* RETURNS
* lcid unchanged, if not a default locale or its sublanguage is
* not SUBLANG_NEUTRAL.
* GetSystemDefaultLCID(), if lcid == LOCALE_SYSTEM_DEFAULT.
* GetUserDefaultLCID(), if lcid == LOCALE_USER_DEFAULT or LOCALE_NEUTRAL.
* Otherwise, lcid with sublanguage changed to SUBLANG_DEFAULT.
*/
LCID WINAPI ConvertDefaultLocale( LCID lcid )
{
switch (lcid)
{
case LOCALE_INVARIANT:
return lcid; /* keep as-is */
case LOCALE_SYSTEM_DEFAULT:
return GetSystemDefaultLCID();
case LOCALE_USER_DEFAULT:
case LOCALE_NEUTRAL:
return GetUserDefaultLCID();
case MAKELANGID( LANG_CHINESE, SUBLANG_NEUTRAL ):
case MAKELANGID( LANG_CHINESE, 0x1e ):
return MAKELANGID( LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED );
case MAKELANGID( LANG_CHINESE, 0x1f ):
return MAKELANGID( LANG_CHINESE, SUBLANG_CHINESE_HONGKONG );
case MAKELANGID( LANG_SPANISH, SUBLANG_NEUTRAL ):
return MAKELANGID( LANG_SPANISH, SUBLANG_SPANISH_MODERN );
case MAKELANGID( LANG_IRISH, SUBLANG_NEUTRAL ):
return MAKELANGID( LANG_IRISH, SUBLANG_IRISH_IRELAND );
case MAKELANGID( LANG_BENGALI, SUBLANG_NEUTRAL ):
return MAKELANGID( LANG_BENGALI, SUBLANG_BENGALI_BANGLADESH );
case MAKELANGID( LANG_SINDHI, SUBLANG_NEUTRAL ):
return MAKELANGID( LANG_SINDHI, SUBLANG_SINDHI_AFGHANISTAN );
case MAKELANGID( LANG_INUKTITUT, SUBLANG_NEUTRAL ):
return MAKELANGID( LANG_INUKTITUT, SUBLANG_INUKTITUT_CANADA_LATIN );
case MAKELANGID( LANG_TAMAZIGHT, SUBLANG_NEUTRAL ):
return MAKELANGID( LANG_TAMAZIGHT, SUBLANG_TAMAZIGHT_ALGERIA_LATIN );
case MAKELANGID( LANG_FULAH, SUBLANG_NEUTRAL ):
return MAKELANGID( LANG_FULAH, SUBLANG_FULAH_SENEGAL );
case MAKELANGID( LANG_TIGRINYA, SUBLANG_NEUTRAL ):
return MAKELANGID( LANG_TIGRINYA, SUBLANG_TIGRINYA_ERITREA );
default:
/* Replace SUBLANG_NEUTRAL with SUBLANG_DEFAULT */
if (SUBLANGID(lcid) == SUBLANG_NEUTRAL && SORTIDFROMLCID(lcid) == SORT_DEFAULT)
lcid = MAKELANGID( PRIMARYLANGID(lcid), SUBLANG_DEFAULT );
break;
}
return lcid;
}
/******************************************************************************
* IsValidLocale (KERNEL32.@)
*
* Determine if a locale is valid.
*
* PARAMS
* lcid [I] LCID of the locale to check
* flags [I] LCID_SUPPORTED = Valid, LCID_INSTALLED = Valid and installed on the system
*
* RETURNS
* TRUE, if lcid is valid,
* FALSE, otherwise.
*
* NOTES
* Wine does not currently make the distinction between supported and installed. All
* languages supported are installed by default.
*/
BOOL WINAPI IsValidLocale( LCID lcid, DWORD flags )
{
/* check if language is registered in the kernel32 resources */
return FindResourceExW( kernel32_handle, (LPWSTR)RT_STRING,
(LPCWSTR)LOCALE_ILANGUAGE, LANGIDFROMLCID(lcid)) != 0;
}
/******************************************************************************
* IsValidLocaleName (KERNEL32.@)
*/
BOOL WINAPI IsValidLocaleName( LPCWSTR locale )
{
LCID lcid;
return !RtlLocaleNameToLcid( locale, &lcid, 2 );
}
/******************************************************************************
* GetStringTypeW (KERNEL32.@)
*

View File

@ -159,7 +159,7 @@
@ stdcall CompareStringW(long long wstr long wstr long) kernel32.CompareStringW
@ stdcall ConnectNamedPipe(long ptr)
@ stdcall ContinueDebugEvent(long long long)
@ stdcall ConvertDefaultLocale(long) kernel32.ConvertDefaultLocale
@ stdcall ConvertDefaultLocale(long)
@ stdcall ConvertFiberToThread()
@ stdcall ConvertThreadToFiber(ptr)
@ stdcall ConvertThreadToFiberEx(ptr long)
@ -402,7 +402,7 @@
@ stdcall FreeUserPhysicalPages(long ptr ptr)
@ stdcall GenerateConsoleCtrlEvent(long long)
# @ stub GenerateGPNotificationInternal
@ stdcall GetACP() kernel32.GetACP
@ stdcall GetACP()
@ stdcall GetAcceptLanguagesA(ptr ptr)
@ stdcall GetAcceptLanguagesW(ptr ptr)
@ stdcall GetAce(ptr long ptr)
@ -541,8 +541,8 @@
@ stdcall GetLastError() kernelbase_GetLastError
@ stdcall GetLengthSid(ptr)
@ stdcall GetLocalTime(ptr)
@ stdcall GetLocaleInfoA(long long ptr long) kernel32.GetLocaleInfoA
@ stdcall GetLocaleInfoEx(wstr long ptr long) kernel32.GetLocaleInfoEx
@ stdcall GetLocaleInfoA(long long ptr long)
@ stdcall GetLocaleInfoEx(wstr long ptr long)
@ stub GetLocaleInfoHelper
@ stdcall GetLocaleInfoW(long long ptr long) kernel32.GetLocaleInfoW
@ stdcall GetLogicalDriveStringsW(long ptr) kernel32.GetLogicalDriveStringsW
@ -580,7 +580,7 @@
@ stdcall GetNumberFormatEx(wstr long wstr ptr ptr long) kernel32.GetNumberFormatEx
@ stdcall GetNumberFormatW(long long wstr ptr ptr long) kernel32.GetNumberFormatW
@ stdcall GetNumberOfConsoleInputEvents(long ptr)
@ stdcall GetOEMCP() kernel32.GetOEMCP
@ stdcall GetOEMCP()
# @ stub GetOsManufacturingMode
# @ stub GetOsSafeBootMode
@ stdcall GetOverlappedResult(long ptr ptr long)
@ -876,8 +876,8 @@
@ stdcall IsValidAcl(ptr)
@ stdcall IsValidCodePage(long) kernel32.IsValidCodePage
@ stdcall IsValidLanguageGroup(long long)
@ stdcall IsValidLocale(long long) kernel32.IsValidLocale
@ stdcall IsValidLocaleName(wstr) kernel32.IsValidLocaleName
@ stdcall IsValidLocale(long long)
@ stdcall IsValidLocaleName(wstr)
# @ stub IsValidNLSVersion
@ stub IsValidRelativeSecurityDescriptor
@ stdcall IsValidSecurityDescriptor(ptr)
@ -938,7 +938,7 @@
@ stdcall LocalLock(long)
@ stdcall LocalReAlloc(long long long)
@ stdcall LocalUnlock(long)
@ stdcall LocaleNameToLCID(wstr long) kernel32.LocaleNameToLCID
@ stdcall LocaleNameToLCID(wstr long)
# @ stub LocateXStateFeature
@ stdcall LockFile(long long long long long)
@ stdcall LockFileEx(long long long long long ptr)

View File

@ -4,9 +4,9 @@
* Copyright 1995 Martin von Loewis
* Copyright 1998 David Lee Lambert
* Copyright 2000 Julio César Gázquez
* Copyright 2002 Alexandre Julliard for CodeWeavers
* Copyright 2003 Jon Griffiths
* Copyright 2005 Dmitry Timoshkov
* Copyright 2002, 2019 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -161,6 +161,17 @@ void init_locale(void)
}
static UINT get_lcid_codepage( LCID lcid, ULONG flags )
{
UINT ret = CP_ACP;
if (!(flags & LOCALE_USE_CP_ACP) && lcid != GetSystemDefaultLCID())
GetLocaleInfoW( lcid, LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
(WCHAR *)&ret, sizeof(ret)/sizeof(WCHAR) );
return ret;
}
/* Note: the Internal_ functions are not documented. The number of parameters
* should be correct, but their exact meaning may not.
*/
@ -517,6 +528,51 @@ INT WINAPI DECLSPEC_HOTPATCH CompareStringOrdinal( const WCHAR *str1, INT len1,
}
/******************************************************************************
* ConvertDefaultLocale (kernelbase.@)
*/
LCID WINAPI DECLSPEC_HOTPATCH ConvertDefaultLocale( LCID lcid )
{
switch (lcid)
{
case LOCALE_INVARIANT:
return lcid; /* keep as-is */
case LOCALE_SYSTEM_DEFAULT:
return GetSystemDefaultLCID();
case LOCALE_USER_DEFAULT:
case LOCALE_NEUTRAL:
return GetUserDefaultLCID();
case MAKELANGID( LANG_CHINESE, SUBLANG_NEUTRAL ):
case MAKELANGID( LANG_CHINESE, 0x1e ):
return MAKELANGID( LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED );
case MAKELANGID( LANG_CHINESE, 0x1f ):
return MAKELANGID( LANG_CHINESE, SUBLANG_CHINESE_HONGKONG );
case MAKELANGID( LANG_SPANISH, SUBLANG_NEUTRAL ):
return MAKELANGID( LANG_SPANISH, SUBLANG_SPANISH_MODERN );
case MAKELANGID( LANG_IRISH, SUBLANG_NEUTRAL ):
return MAKELANGID( LANG_IRISH, SUBLANG_IRISH_IRELAND );
case MAKELANGID( LANG_BENGALI, SUBLANG_NEUTRAL ):
return MAKELANGID( LANG_BENGALI, SUBLANG_BENGALI_BANGLADESH );
case MAKELANGID( LANG_SINDHI, SUBLANG_NEUTRAL ):
return MAKELANGID( LANG_SINDHI, SUBLANG_SINDHI_AFGHANISTAN );
case MAKELANGID( LANG_INUKTITUT, SUBLANG_NEUTRAL ):
return MAKELANGID( LANG_INUKTITUT, SUBLANG_INUKTITUT_CANADA_LATIN );
case MAKELANGID( LANG_TAMAZIGHT, SUBLANG_NEUTRAL ):
return MAKELANGID( LANG_TAMAZIGHT, SUBLANG_TAMAZIGHT_ALGERIA_LATIN );
case MAKELANGID( LANG_FULAH, SUBLANG_NEUTRAL ):
return MAKELANGID( LANG_FULAH, SUBLANG_FULAH_SENEGAL );
case MAKELANGID( LANG_TIGRINYA, SUBLANG_NEUTRAL ):
return MAKELANGID( LANG_TIGRINYA, SUBLANG_TIGRINYA_ERITREA );
default:
/* Replace SUBLANG_NEUTRAL with SUBLANG_DEFAULT */
if (SUBLANGID(lcid) == SUBLANG_NEUTRAL && SORTIDFROMLCID(lcid) == SORT_DEFAULT)
lcid = MAKELANGID( PRIMARYLANGID(lcid), SUBLANG_DEFAULT );
break;
}
return lcid;
}
/******************************************************************************
* EnumCalendarInfoW (kernelbase.@)
*/
@ -777,36 +833,11 @@ INT WINAPI DECLSPEC_HOTPATCH FindStringOrdinal( DWORD flag, const WCHAR *src, IN
/******************************************************************************
* IsValidLanguageGroup (kernelbase.@)
* GetACP (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH IsValidLanguageGroup( LGRPID id, DWORD flags )
UINT WINAPI GetACP(void)
{
static const WCHAR format[] = { '%','x',0 };
WCHAR name[10], value[10];
DWORD type, value_len = sizeof(value);
BOOL ret = FALSE;
HKEY key;
if (RegOpenKeyExW( nls_key, L"Language Groups", 0, KEY_READ, &key )) return FALSE;
swprintf( name, ARRAY_SIZE(name), format, id );
if (!RegQueryValueExW( key, name, NULL, &type, (BYTE *)value, &value_len ) && type == REG_SZ)
ret = (flags & LGRPID_SUPPORTED) || wcstoul( value, NULL, 10 );
RegCloseKey( key );
return ret;
}
/***********************************************************************
* LCIDToLocaleName (kernelbase.@)
*/
INT WINAPI DECLSPEC_HOTPATCH LCIDToLocaleName( LCID lcid, LPWSTR name, INT count, DWORD flags )
{
static int once;
if (flags && !once++) FIXME( "unsupported flags %x\n", flags );
return GetLocaleInfoW( lcid, LOCALE_SNAME | LOCALE_NOUSEROVERRIDE, name, count );
return ansi_cp;
}
@ -1003,6 +1034,87 @@ INT WINAPI DECLSPEC_HOTPATCH GetCalendarInfoEx( const WCHAR *locale, CALID calen
}
/******************************************************************************
* GetLocaleInfoA (kernelbase.@)
*/
INT WINAPI DECLSPEC_HOTPATCH GetLocaleInfoA( LCID lcid, LCTYPE lctype, char *buffer, INT len )
{
WCHAR *bufferW;
INT lenW, ret;
TRACE( "lcid=0x%x lctype=0x%x %p %d\n", lcid, lctype, buffer, len );
if (len < 0 || (len && !buffer))
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
if (LOWORD(lctype) == LOCALE_SSHORTTIME || (lctype & LOCALE_RETURN_GENITIVE_NAMES))
{
SetLastError( ERROR_INVALID_FLAGS );
return 0;
}
if (LOWORD(lctype) == LOCALE_FONTSIGNATURE || (lctype & LOCALE_RETURN_NUMBER))
return GetLocaleInfoW( lcid, lctype, (WCHAR *)buffer, len / sizeof(WCHAR) ) * sizeof(WCHAR);
if (!(lenW = GetLocaleInfoW( lcid, lctype, NULL, 0 ))) return 0;
if (!(bufferW = RtlAllocateHeap( GetProcessHeap(), 0, lenW * sizeof(WCHAR) )))
{
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return 0;
}
ret = GetLocaleInfoW( lcid, lctype, bufferW, lenW );
if (ret) ret = WideCharToMultiByte( get_lcid_codepage( lcid, lctype ), 0,
bufferW, ret, buffer, len, NULL, NULL );
RtlFreeHeap( GetProcessHeap(), 0, bufferW );
return ret;
}
/******************************************************************************
* GetLocaleInfoEx (kernelbase.@)
*/
INT WINAPI DECLSPEC_HOTPATCH GetLocaleInfoEx( const WCHAR *locale, LCTYPE info, WCHAR *buffer, INT len )
{
LCID lcid = LocaleNameToLCID( locale, 0 );
TRACE( "%s lcid=0x%x 0x%x\n", debugstr_w(locale), lcid, info );
if (!lcid) return 0;
/* special handling for neutral locale names */
if (locale && lstrlenW( locale ) == 2)
{
switch (LOWORD( info ))
{
case LOCALE_SNAME:
if (len && len < 3)
{
SetLastError( ERROR_INSUFFICIENT_BUFFER );
return 0;
}
if (len) lstrcpyW( buffer, locale );
return 3;
case LOCALE_SPARENT:
if (len) buffer[0] = 0;
return 1;
}
}
return GetLocaleInfoW( lcid, info, buffer, len );
}
/******************************************************************************
* GetOEMCP (kernelbase.@)
*/
UINT WINAPI GetOEMCP(void)
{
return oem_cp;
}
/***********************************************************************
* GetSystemDefaultLCID (kernelbase.@)
*/
@ -1094,6 +1206,75 @@ BOOL WINAPI DECLSPEC_HOTPATCH IsNormalizedString( NORM_FORM form, const WCHAR *s
}
/******************************************************************************
* IsValidLanguageGroup (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH IsValidLanguageGroup( LGRPID id, DWORD flags )
{
WCHAR name[10], value[10];
DWORD type, value_len = sizeof(value);
BOOL ret = FALSE;
HKEY key;
if (RegOpenKeyExW( nls_key, L"Language Groups", 0, KEY_READ, &key )) return FALSE;
swprintf( name, ARRAY_SIZE(name), L"%x", id );
if (!RegQueryValueExW( key, name, NULL, &type, (BYTE *)value, &value_len ) && type == REG_SZ)
ret = (flags & LGRPID_SUPPORTED) || wcstoul( value, NULL, 10 );
RegCloseKey( key );
return ret;
}
/******************************************************************************
* IsValidLocale (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH IsValidLocale( LCID lcid, DWORD flags )
{
/* check if language is registered in the kernel32 resources */
return FindResourceExW( kernel32_handle, (LPWSTR)RT_STRING,
ULongToPtr( (LOCALE_ILANGUAGE >> 4) + 1 ), LANGIDFROMLCID(lcid)) != 0;
}
/******************************************************************************
* IsValidLocaleName (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH IsValidLocaleName( const WCHAR *locale )
{
LCID lcid;
return !RtlLocaleNameToLcid( locale, &lcid, 2 );
}
/***********************************************************************
* LCIDToLocaleName (kernelbase.@)
*/
INT WINAPI DECLSPEC_HOTPATCH LCIDToLocaleName( LCID lcid, WCHAR *name, INT count, DWORD flags )
{
static int once;
if (flags && !once++) FIXME( "unsupported flags %x\n", flags );
return GetLocaleInfoW( lcid, LOCALE_SNAME | LOCALE_NOUSEROVERRIDE, name, count );
}
/***********************************************************************
* LocaleNameToLCID (kernelbase.@)
*/
LCID WINAPI DECLSPEC_HOTPATCH LocaleNameToLCID( const WCHAR *name, DWORD flags )
{
LCID lcid;
if (!name) return GetUserDefaultLCID();
if (!set_ntstatus( RtlLocaleNameToLcid( name, &lcid, 2 ))) return 0;
if (!(flags & LOCALE_ALLOW_NEUTRAL_NAMES)) lcid = ConvertDefaultLocale( lcid );
return lcid;
}
/******************************************************************************
* NormalizeString (kernelbase.@)
*/