Resubmission of RtlLCIDToCultureName patch, fixed based on Alexandre's advice.
Signed-off-by: Mark Harmstone mark@harmstone.com --- dlls/ntdll/locale.c | 200 ++++++++++++++++++++++++++++++++++++++++++ dlls/ntdll/ntdll.spec | 1 + 2 files changed, 201 insertions(+)
diff --git a/dlls/ntdll/locale.c b/dlls/ntdll/locale.c index b3a225a30c3..1251e247d07 100644 --- a/dlls/ntdll/locale.c +++ b/dlls/ntdll/locale.c @@ -126,6 +126,27 @@ static NTSTATUS load_string( ULONG id, LANGID lang, WCHAR *buffer, ULONG len ) }
+static NTSTATUS load_string_us( ULONG id, LANGID lang, PUNICODE_STRING us ) +{ + const IMAGE_RESOURCE_DATA_ENTRY *data; + LDR_RESOURCE_INFO info; + NTSTATUS status; + WCHAR *p; + int i; + + info.Type = 6; /* RT_STRING */ + info.Name = (id >> 4) + 1; + info.Language = lang; + if ((status = LdrFindResource_U( kernel32_handle, &info, 3, &data ))) return status; + p = (WCHAR *)((char *)kernel32_handle + data->OffsetToData); + for (i = 0; i < (id & 0x0f); i++) p += *p + 1; + if (*p >= us->MaximumLength / sizeof(WCHAR)) return STATUS_BUFFER_TOO_SMALL; + us->Length = *p * sizeof(WCHAR); + memcpy( us->Buffer, p + 1, us->Length ); + return STATUS_SUCCESS; +} + + static DWORD mbtowc_size( const CPTABLEINFO *info, LPCSTR str, UINT len ) { DWORD res; @@ -1936,3 +1957,182 @@ NTSTATUS WINAPI RtlIdnToUnicode( DWORD flags, const WCHAR *src, INT srclen, WCHA *dstlen = out; return STATUS_SUCCESS; } + + +/****************************************************************************** + * RtlLCIDToCultureName (NTDLL.@) + */ +BOOLEAN WINAPI RtlLCIDToCultureName( LCID lcid, PUNICODE_STRING string ) +{ + NTSTATUS status; + + /* kernel32 doesn't store information about primary languages */ + + static const struct { + unsigned int lang; + const WCHAR *name; + } primary_langs[] = + { + { LANG_ARABIC, L"ar" }, + { LANG_BULGARIAN, L"bg" }, + { LANG_CATALAN, L"ca" }, + { LANG_CHINESE, L"zh-Hans" }, + { LANG_CZECH, L"cs" }, + { LANG_DANISH, L"da" }, + { LANG_GERMAN, L"de" }, + { LANG_GREEK, L"el" }, + { LANG_ENGLISH, L"en" }, + { LANG_SPANISH, L"es" }, + { LANG_FINNISH, L"fi" }, + { LANG_FRENCH, L"fr" }, + { LANG_HEBREW, L"he" }, + { LANG_HUNGARIAN, L"hu" }, + { LANG_ICELANDIC, L"is" }, + { LANG_ITALIAN, L"it" }, + { LANG_JAPANESE, L"ja" }, + { LANG_KOREAN, L"ko" }, + { LANG_DUTCH, L"nl" }, + { LANG_NORWEGIAN, L"no" }, + { LANG_POLISH, L"pl" }, + { LANG_PORTUGUESE, L"pt" }, + { LANG_ROMANSH, L"rm" }, + { LANG_ROMANIAN, L"ro" }, + { LANG_RUSSIAN, L"ru" }, + { LANG_CROATIAN, L"hr" }, + { LANG_SLOVAK, L"sk" }, + { LANG_ALBANIAN, L"sq" }, + { LANG_SWEDISH, L"sv" }, + { LANG_THAI, L"th" }, + { LANG_TURKISH, L"tr" }, + { LANG_URDU, L"ur" }, + { LANG_INDONESIAN, L"id" }, + { LANG_UKRAINIAN, L"uk" }, + { LANG_BELARUSIAN, L"be" }, + { LANG_SLOVENIAN, L"sl" }, + { LANG_ESTONIAN, L"et" }, + { LANG_LATVIAN, L"lv" }, + { LANG_LITHUANIAN, L"lt" }, + { LANG_TAJIK, L"tg" }, + { LANG_PERSIAN, L"fa" }, + { LANG_VIETNAMESE, L"vi" }, + { LANG_ARMENIAN, L"hy" }, + { LANG_AZERBAIJANI, L"az" }, + { LANG_BASQUE, L"eu" }, + { LANG_LOWER_SORBIAN, L"hsb" }, + { LANG_MACEDONIAN, L"mk" }, + { LANG_TSWANA, L"tn" }, + { LANG_XHOSA, L"xh" }, + { LANG_ZULU, L"zu" }, + { LANG_AFRIKAANS, L"af" }, + { LANG_GEORGIAN, L"ka" }, + { LANG_FAEROESE, L"fo" }, + { LANG_HINDI, L"hi" }, + { LANG_MALTESE, L"mt" }, + { LANG_SAMI, L"se" }, + { LANG_IRISH, L"ga" }, + { LANG_MALAY, L"ms" }, + { LANG_KAZAK, L"kk" }, + { LANG_KYRGYZ, L"ky" }, + { LANG_SWAHILI, L"sw" }, + { LANG_TURKMEN, L"tk" }, + { LANG_UZBEK, L"uz" }, + { LANG_TATAR, L"tt" }, + { LANG_BENGALI, L"bn" }, + { LANG_PUNJABI, L"pa" }, + { LANG_GUJARATI, L"gu" }, + { LANG_ODIA, L"or" }, + { LANG_TAMIL, L"ta" }, + { LANG_TELUGU, L"te" }, + { LANG_KANNADA, L"kn" }, + { LANG_MALAYALAM, L"ml" }, + { LANG_ASSAMESE, L"as" }, + { LANG_MARATHI, L"mr" }, + { LANG_SANSKRIT, L"sa" }, + { LANG_MONGOLIAN, L"mn" }, + { LANG_TIBETAN, L"bo" }, + { LANG_WELSH, L"cy" }, + { LANG_KHMER, L"km" }, + { LANG_LAO, L"lo" }, + { LANG_GALICIAN, L"gl" }, + { LANG_KONKANI, L"kok" }, + { LANG_MANIPURI, L"mni" }, + { LANG_SINDHI, L"sd" }, + { LANG_SYRIAC, L"syr" }, + { LANG_SINHALESE, L"si" }, + { LANG_INUKTITUT, L"iu" }, + { LANG_AMHARIC, L"am" }, + { LANG_TAMAZIGHT, L"tzm" }, + { LANG_NEPALI, L"ne" }, + { LANG_FRISIAN, L"fy" }, + { LANG_PASHTO, L"ps" }, + { LANG_FILIPINO, L"fil" }, + { LANG_DIVEHI, L"dv" }, + { LANG_HAUSA, L"ha" }, + { LANG_YORUBA, L"yo" }, + { LANG_QUECHUA, L"quz" }, + { LANG_SOTHO, L"nso" }, + { LANG_BASHKIR, L"ba" }, + { LANG_LUXEMBOURGISH, L"lb" }, + { LANG_GREENLANDIC, L"kl" }, + { LANG_IGBO, L"ig" }, + { LANG_YI, L"ii" }, + { LANG_MAPUDUNGUN, L"arn" }, + { LANG_MOHAWK, L"moh" }, + { LANG_BRETON, L"br" }, + { LANG_INVARIANT, L"" }, + { LANG_UIGHUR, L"ug" }, + { LANG_MAORI, L"mi" }, + { LANG_OCCITAN, L"oc" }, + { LANG_CORSICAN, L"co" }, + { LANG_ALSATIAN, L"gsw" }, + { LANG_SAKHA, L"sah" }, + { LANG_KINYARWANDA, L"rw" }, + { LANG_WOLOF, L"wo" }, + { LANG_DARI, L"prs" }, + { 0, NULL } + }; + + if (lcid == 0) + return FALSE; + else if (lcid == LOCALE_USER_DEFAULT) + { + status = NtQueryDefaultLocale(TRUE, &lcid); + if (!NT_SUCCESS(status)) + return FALSE; + } + else if (lcid == LOCALE_SYSTEM_DEFAULT) + { + status = NtQueryDefaultLocale(FALSE, &lcid); + if (!NT_SUCCESS(status)) + return FALSE; + } + + if (SUBLANGID(lcid) == SUBLANG_NEUTRAL) + { + unsigned int i = 0; + + while (primary_langs[i].lang != 0) + { + if (primary_langs[i].lang == PRIMARYLANGID(lcid)) + { + size_t len = wcslen( primary_langs[i].name ); + + if (string->MaximumLength < len * sizeof(WCHAR)) + return FALSE; + + string->Length = len * sizeof(WCHAR); + memcpy( string->Buffer, primary_langs[i].name, string->Length ); + + return TRUE; + } + + i++; + } + + return FALSE; + } + + status = load_string_us( LOCALE_SNAME, lcid, string ); + + return NT_SUCCESS(status) ? TRUE : FALSE; +} diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index c8622ba21f4..d27aaf1da58 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -827,6 +827,7 @@ @ stdcall -arch=win32 -ret64 RtlLargeIntegerShiftRight(int64 long) @ stdcall -arch=win32 -ret64 RtlLargeIntegerSubtract(int64 int64) @ stdcall RtlLargeIntegerToChar(ptr long long ptr) +@ stdcall RtlLCIDToCultureName(long ptr) @ stdcall RtlLeaveCriticalSection(ptr) @ stdcall RtlLengthRequiredSid(long) @ stdcall RtlLengthSecurityDescriptor(ptr)