📄 lang.c
字号:
if (cchCount1 < 0) cchCount1 = lstrlenW(lpString1);
if (cchCount2 < 0) cchCount2 = lstrlenW(lpString2);
String1.Length = String1.MaximumLength = cchCount1 * sizeof(WCHAR);
String1.Buffer = (LPWSTR)lpString1;
String2.Length = String2.MaximumLength = cchCount2 * sizeof(WCHAR);
String2.Buffer = (LPWSTR)lpString2;
if (dwCmpFlags & ~NORM_IGNORECASE)
{
DPRINT("CompareString: STUB flags - 0x%x\n", dwCmpFlags);
Result = compare_unicode_string(&String1, &String2, dwCmpFlags);
}
else
Result = RtlCompareUnicodeString(
&String1, &String2, dwCmpFlags & NORM_IGNORECASE);
if (Result) /* need to translate result */
return (Result < 0) ? CSTR_LESS_THAN : CSTR_GREATER_THAN;
return CSTR_EQUAL;
}
/*
* @implemented
*
* 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 STDCALL GetLocaleInfoA( LCID lcid, LCTYPE lctype, LPSTR buffer, INT len )
{
WCHAR *bufferW;
INT lenW, ret;
if (len < 0 || (len && !buffer))
{
SetLastError( ERROR_INVALID_PARAMETER );
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;
}
/*
* @implemented
*/
LANGID STDCALL
GetSystemDefaultLangID(VOID)
{
return LANGIDFROMLCID(GetSystemDefaultLCID());
}
/*
* @implemented
*/
LCID STDCALL
GetSystemDefaultLCID(VOID)
{
LCID lcid;
NtQueryDefaultLocale(FALSE, &lcid);
return lcid;
}
/*
* @implemented
*/
LANGID STDCALL
GetSystemDefaultUILanguage(VOID)
{
LANGID LanguageId;
NTSTATUS Status;
Status = NtQueryInstallUILanguage(&LanguageId);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return 0;
}
return LanguageId;
}
/*
* @implemented
*/
LCID STDCALL
GetThreadLocale(VOID)
{
return NtCurrentTeb()->CurrentLocale;
}
/*
* @implemented
*/
LANGID STDCALL
GetUserDefaultLangID(VOID)
{
return LANGIDFROMLCID(GetUserDefaultLCID());
}
/*
* @implemented
*/
LCID STDCALL
GetUserDefaultLCID(VOID)
{
LCID lcid;
NTSTATUS Status;
Status = NtQueryDefaultLocale(TRUE, &lcid);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return 0;
}
return lcid;
}
/*
* @implemented
*/
LANGID STDCALL
GetUserDefaultUILanguage(VOID)
{
LANGID LangId;
NTSTATUS Status;
Status = NtQueryDefaultUILanguage(&LangId);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return 0;
}
return LangId;
}
/*
* @unimplemented
*/
GEOID
STDCALL
GetUserGeoID(
GEOCLASS GeoClass)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
BOOL
STDCALL
IsValidLanguageGroup(
LGRPID LanguageGroup,
DWORD dwFlags)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/******************************************************************************
* IsValidLocale
*
* Determine if a locale is valid.
*
* PARAMS
* Locale [I] LCID of the locale to check
* dwFlags [I] LCID_SUPPORTED = Valid
* LCID_INSTALLED = Valid and installed on the system
*
* RETURN
* TRUE, if Locale is valid,
* FALSE, otherwise.
*
* @implemented
*/
BOOL STDCALL
IsValidLocale(LCID Locale,
DWORD dwFlags)
{
OBJECT_ATTRIBUTES ObjectAttributes;
PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
WCHAR ValueNameBuffer[9];
UNICODE_STRING KeyName;
UNICODE_STRING ValueName;
ULONG KeyInfoSize;
ULONG ReturnedSize;
HANDLE KeyHandle;
PWSTR ValueData;
NTSTATUS Status;
DPRINT("IsValidLocale() called\n");
if ((dwFlags & ~(LCID_SUPPORTED | LCID_INSTALLED)) ||
(dwFlags == (LCID_SUPPORTED | LCID_INSTALLED)))
{
DPRINT("Invalid flags: %lx\n", dwFlags);
return FALSE;
}
if (Locale & 0xFFFF0000)
{
RtlInitUnicodeString(&KeyName,
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Nls\\Locale\\Alternate Sorts");
}
else
{
RtlInitUnicodeString(&KeyName,
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Nls\\Locale");
}
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenKey(&KeyHandle,
KEY_QUERY_VALUE,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DPRINT("NtOpenKey() failed (Status %lx)\n", Status);
return FALSE;
}
swprintf(ValueNameBuffer, L"%08lx", (ULONG)Locale);
RtlInitUnicodeString(&ValueName, ValueNameBuffer);
KeyInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 4 * sizeof(WCHAR);
KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
KeyInfoSize);
if (KeyInfo == NULL)
{
DPRINT("RtlAllocateHeap() failed (Status %lx)\n", Status);
NtClose(KeyHandle);
return FALSE;
}
Status = NtQueryValueKey(KeyHandle,
&ValueName,
KeyValuePartialInformation,
KeyInfo,
KeyInfoSize,
&ReturnedSize);
NtClose(KeyHandle);
if (!NT_SUCCESS(Status))
{
DPRINT("NtQueryValueKey() failed (Status %lx)\n", Status);
RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
return FALSE;
}
if (dwFlags & LCID_SUPPORTED)
{
DPRINT("Locale is supported\n");
RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
return TRUE;
}
ValueData = (PWSTR)&KeyInfo->Data[0];
if ((dwFlags & LCID_INSTALLED) &&
(KeyInfo->Type == REG_SZ) &&
(KeyInfo->DataLength == 2 * sizeof(WCHAR)) &&
(ValueData[0] == L'1'))
{
DPRINT("Locale is supported and installed\n");
RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
return TRUE;
}
RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
DPRINT("IsValidLocale() called\n");
return FALSE;
}
/*
* @unimplemented
*/
int
STDCALL
LCMapStringA (
LCID Locale,
DWORD dwMapFlags,
LPCSTR lpSrcStr,
int cchSrc,
LPSTR lpDestStr,
int cchDest
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
int
STDCALL
LCMapStringW (
LCID Locale,
DWORD dwMapFlags,
LPCWSTR lpSrcStr,
int cchSrc,
LPWSTR lpDestStr,
int cchDest
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
BOOL
STDCALL
SetCalendarInfoA(
LCID Locale,
CALID Calendar,
CALTYPE CalType,
LPCSTR lpCalData)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
BOOL
STDCALL
SetCalendarInfoW(
LCID Locale,
CALID Calendar,
CALTYPE CalType,
LPCWSTR lpCalData)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
BOOL
STDCALL
SetLocaleInfoA (
LCID Locale,
LCTYPE LCType,
LPCSTR lpLCData
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @unimplemented
*/
BOOL
STDCALL
SetLocaleInfoW (
LCID Locale,
LCTYPE LCType,
LPCWSTR lpLCData
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/**********************************************************************
* @implemented
* RIPPED FROM WINE's dlls\kernel\locale.c rev 1.42
*
* SetThreadLocale (KERNEL32.@)
*
* Set the current threads locale.
*
* PARAMS
* lcid [I] LCID of the locale to set
*
* RETURNS
* Success: TRUE. The threads locale is set to lcid.
* Failure: FALSE. Use GetLastError() to determine the cause.
*
*/
BOOL WINAPI SetThreadLocale( LCID lcid )
{
DPRINT("SetThreadLocale(0x%04lX)\n", lcid);
lcid = ConvertDefaultLocale(lcid);
if (lcid != GetThreadLocale())
{
if (!IsValidLocale(lcid, LCID_SUPPORTED))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
NtCurrentTeb()->CurrentLocale = lcid;
/* FIXME: NtCurrentTeb()->code_page = get_lcid_codepage( lcid );
* Wine save the acp for easy/fast access, but ROS has no such Teb member.
* Maybe add this member to ros as well?
*/
/*
Lag test app for
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -