[PATCH 1/2] ntdll: Add RtlLCIDToCultureName.

Mark Harmstone mark at harmstone.com
Tue Apr 6 13:22:05 CDT 2021


Resubmission of RtlLCIDToCultureName patch, fixed based on Alexandre's
advice.

Signed-off-by: Mark Harmstone <mark at 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)
-- 
2.26.3




More information about the wine-devel mailing list