// // lcidtoname_downlevel.cpp // // Copyright (c) Microsoft Corporation. All rights reserved. // // Definitions of wrappers for the Windows XP API functions that are not available on // all supported operating system versions. // #include namespace { // Map of LCID to locale name. struct LcidToLocaleName { LCID lcid; wchar_t* localeName; }; // Map of locale name to an index. struct LocaleNameIndex { wchar_t* name; int index; }; // Map of LCID to locale name for Windows XP. // Data in this table has been obtained from National Language Support (NLS) API Reference at // http://msdn.microsoft.com/en-us/goglobal/bb896001.aspx // The table is sorted to improve search performance. static const LcidToLocaleName LcidToLocaleNameTable[] = { { 0x0001, L"ar" }, { 0x0002, L"bg" }, { 0x0003, L"ca" }, { 0x0004, L"zh-CHS" }, { 0x0005, L"cs" }, { 0x0006, L"da" }, { 0x0007, L"de" }, { 0x0008, L"el" }, { 0x0009, L"en" }, { 0x000A, L"es" }, { 0x000B, L"fi" }, { 0x000C, L"fr" }, { 0x000D, L"he" }, { 0x000E, L"hu" }, { 0x000F, L"is" }, { 0x0010, L"it" }, { 0x0011, L"ja" }, { 0x0012, L"ko" }, { 0x0013, L"nl" }, { 0x0014, L"no" }, { 0x0015, L"pl" }, { 0x0016, L"pt" }, { 0x0018, L"ro" }, { 0x0019, L"ru" }, { 0x001A, L"hr" }, { 0x001B, L"sk" }, { 0x001C, L"sq" }, { 0x001D, L"sv" }, { 0x001E, L"th" }, { 0x001F, L"tr" }, { 0x0020, L"ur" }, { 0x0021, L"id" }, { 0x0022, L"uk" }, { 0x0023, L"be" }, { 0x0024, L"sl" }, { 0x0025, L"et" }, { 0x0026, L"lv" }, { 0x0027, L"lt" }, { 0x0029, L"fa" }, { 0x002A, L"vi" }, { 0x002B, L"hy" }, { 0x002C, L"az" }, { 0x002D, L"eu" }, { 0x002F, L"mk" }, { 0x0036, L"af" }, { 0x0037, L"ka" }, { 0x0038, L"fo" }, { 0x0039, L"hi" }, { 0x003E, L"ms" }, { 0x003F, L"kk" }, { 0x0040, L"ky" }, { 0x0041, L"sw" }, { 0x0043, L"uz" }, { 0x0044, L"tt" }, { 0x0046, L"pa" }, { 0x0047, L"gu" }, { 0x0049, L"ta" }, { 0x004A, L"te" }, { 0x004B, L"kn" }, { 0x004E, L"mr" }, { 0x004F, L"sa" }, { 0x0050, L"mn" }, { 0x0056, L"gl" }, { 0x0057, L"kok" }, { 0x005A, L"syr" }, { 0x0065, L"div" }, { 0x007f, L"" }, { 0x0401, L"ar-SA" }, { 0x0402, L"bg-BG" }, { 0x0403, L"ca-ES" }, { 0x0404, L"zh-TW" }, { 0x0405, L"cs-CZ" }, { 0x0406, L"da-DK" }, { 0x0407, L"de-DE" }, { 0x0408, L"el-GR" }, { 0x0409, L"en-US" }, { 0x040B, L"fi-FI" }, { 0x040C, L"fr-FR" }, { 0x040D, L"he-IL" }, { 0x040E, L"hu-HU" }, { 0x040F, L"is-IS" }, { 0x0410, L"it-IT" }, { 0x0411, L"ja-JP" }, { 0x0412, L"ko-KR" }, { 0x0413, L"nl-NL" }, { 0x0414, L"nb-NO" }, { 0x0415, L"pl-PL" }, { 0x0416, L"pt-BR" }, { 0x0418, L"ro-RO" }, { 0x0419, L"ru-RU" }, { 0x041A, L"hr-HR" }, { 0x041B, L"sk-SK" }, { 0x041C, L"sq-AL" }, { 0x041D, L"sv-SE" }, { 0x041E, L"th-TH" }, { 0x041F, L"tr-TR" }, { 0x0420, L"ur-PK" }, { 0x0421, L"id-ID" }, { 0x0422, L"uk-UA" }, { 0x0423, L"be-BY" }, { 0x0424, L"sl-SI" }, { 0x0425, L"et-EE" }, { 0x0426, L"lv-LV" }, { 0x0427, L"lt-LT" }, { 0x0429, L"fa-IR" }, { 0x042A, L"vi-VN" }, { 0x042B, L"hy-AM" }, { 0x042C, L"az-AZ-Latn" }, { 0x042D, L"eu-ES" }, { 0x042F, L"mk-MK" }, { 0x0432, L"tn-ZA" }, { 0x0434, L"xh-ZA" }, { 0x0435, L"zu-ZA" }, { 0x0436, L"af-ZA" }, { 0x0437, L"ka-GE" }, { 0x0438, L"fo-FO" }, { 0x0439, L"hi-IN" }, { 0x043A, L"mt-MT" }, { 0x043B, L"se-NO" }, { 0x043E, L"ms-MY" }, { 0x043F, L"kk-KZ" }, { 0x0440, L"ky-KG" }, { 0x0441, L"sw-KE" }, { 0x0443, L"uz-UZ-Latn" }, { 0x0444, L"tt-RU" }, { 0x0445, L"bn-IN" }, { 0x0446, L"pa-IN" }, { 0x0447, L"gu-IN" }, { 0x0449, L"ta-IN" }, { 0x044A, L"te-IN" }, { 0x044B, L"kn-IN" }, { 0x044C, L"ml-IN" }, { 0x044E, L"mr-IN" }, { 0x044F, L"sa-IN" }, { 0x0450, L"mn-MN" }, { 0x0452, L"cy-GB" }, { 0x0456, L"gl-ES" }, { 0x0457, L"kok-IN" }, { 0x045A, L"syr-SY" }, { 0x0465, L"div-MV" }, { 0x046B, L"quz-BO" }, { 0x046C, L"ns-ZA" }, { 0x0481, L"mi-NZ" }, { 0x0801, L"ar-IQ" }, { 0x0804, L"zh-CN" }, { 0x0807, L"de-CH" }, { 0x0809, L"en-GB" }, { 0x080A, L"es-MX" }, { 0x080C, L"fr-BE" }, { 0x0810, L"it-CH" }, { 0x0813, L"nl-BE" }, { 0x0814, L"nn-NO" }, { 0x0816, L"pt-PT" }, { 0x081A, L"sr-SP-Latn" }, { 0x081D, L"sv-FI" }, { 0x082C, L"az-AZ-Cyrl" }, { 0x083B, L"se-SE" }, { 0x083E, L"ms-BN" }, { 0x0843, L"uz-UZ-Cyrl" }, { 0x086B, L"quz-EC" }, { 0x0C01, L"ar-EG" }, { 0x0C04, L"zh-HK" }, { 0x0C07, L"de-AT" }, { 0x0C09, L"en-AU" }, { 0x0C0A, L"es-ES" }, { 0x0C0C, L"fr-CA" }, { 0x0C1A, L"sr-SP-Cyrl" }, { 0x0C3B, L"se-FI" }, { 0x0C6B, L"quz-PE" }, { 0x1001, L"ar-LY" }, { 0x1004, L"zh-SG" }, { 0x1007, L"de-LU" }, { 0x1009, L"en-CA" }, { 0x100A, L"es-GT" }, { 0x100C, L"fr-CH" }, { 0x101A, L"hr-BA" }, { 0x103B, L"smj-NO" }, { 0x1401, L"ar-DZ" }, { 0x1404, L"zh-MO" }, { 0x1407, L"de-LI" }, { 0x1409, L"en-NZ" }, { 0x140A, L"es-CR" }, { 0x140C, L"fr-LU" }, { 0x141A, L"bs-BA-Latn" }, { 0x143B, L"smj-SE" }, { 0x1801, L"ar-MA" }, { 0x1809, L"en-IE" }, { 0x180A, L"es-PA" }, { 0x180C, L"fr-MC" }, { 0x181A, L"sr-BA-Latn" }, { 0x183B, L"sma-NO" }, { 0x1C01, L"ar-TN" }, { 0x1C09, L"en-ZA" }, { 0x1C0A, L"es-DO" }, { 0x1C1A, L"sr-BA-Cyrl" }, { 0x1C3B, L"sma-SE" }, { 0x2001, L"ar-OM" }, { 0x2009, L"en-JM" }, { 0x200A, L"es-VE" }, { 0x203B, L"sms-FI" }, { 0x2401, L"ar-YE" }, { 0x2409, L"en-CB" }, { 0x240A, L"es-CO" }, { 0x243B, L"smn-FI" }, { 0x2801, L"ar-SY" }, { 0x2809, L"en-BZ" }, { 0x280A, L"es-PE" }, { 0x2C01, L"ar-JO" }, { 0x2C09, L"en-TT" }, { 0x2C0A, L"es-AR" }, { 0x3001, L"ar-LB" }, { 0x3009, L"en-ZW" }, { 0x300A, L"es-EC" }, { 0x3401, L"ar-KW" }, { 0x3409, L"en-PH" }, { 0x340A, L"es-CL" }, { 0x3801, L"ar-AE" }, { 0x380A, L"es-UY" }, { 0x3C01, L"ar-BH" }, { 0x3C0A, L"es-PY" }, { 0x4001, L"ar-QA" }, { 0x400A, L"es-BO" }, { 0x440A, L"es-SV" }, { 0x480A, L"es-HN" }, { 0x4C0A, L"es-NI" }, { 0x500A, L"es-PR" }, { 0x7C04, L"zh-CHT" }, { 0x7C1A, L"sr" } }; // Map of locale name to an index in LcidToLocaleNameTable, for Windows XP. // Data in this table has been obtained from National Language Support (NLS) API Reference at // http://msdn.microsoft.com/en-us/goglobal/bb896001.aspx // The table is sorted to improve search performance. static const LocaleNameIndex LocaleNameToIndexTable[] = { { L"" , 66 }, { L"af" , 44 }, { L"af-za" , 113 }, { L"ar" , 0 }, { L"ar-ae" , 216 }, { L"ar-bh" , 218 }, { L"ar-dz" , 177 }, { L"ar-eg" , 160 }, { L"ar-iq" , 143 }, { L"ar-jo" , 207 }, { L"ar-kw" , 213 }, { L"ar-lb" , 210 }, { L"ar-ly" , 169 }, { L"ar-ma" , 185 }, { L"ar-om" , 196 }, { L"ar-qa" , 220 }, { L"ar-sa" , 67 }, { L"ar-sy" , 204 }, { L"ar-tn" , 191 }, { L"ar-ye" , 200 }, { L"az" , 41 }, { L"az-az-cyrl" , 155 }, { L"az-az-latn" , 107 }, { L"be" , 33 }, { L"be-by" , 99 }, { L"bg" , 1 }, { L"bg-bg" , 68 }, { L"bn-in" , 125 }, { L"bs-ba-latn" , 183 }, { L"ca" , 2 }, { L"ca-es" , 69 }, { L"cs" , 4 }, { L"cs-cz" , 71 }, { L"cy-gb" , 135 }, { L"da" , 5 }, { L"da-dk" , 72 }, { L"de" , 6 }, { L"de-at" , 162 }, { L"de-ch" , 145 }, { L"de-de" , 73 }, { L"de-li" , 179 }, { L"de-lu" , 171 }, { L"div" , 65 }, { L"div-mv" , 139 }, { L"el" , 7 }, { L"el-gr" , 74 }, { L"en" , 8 }, { L"en-au" , 163 }, { L"en-bz" , 205 }, { L"en-ca" , 172 }, { L"en-cb" , 201 }, { L"en-gb" , 146 }, { L"en-ie" , 186 }, { L"en-jm" , 197 }, { L"en-nz" , 180 }, { L"en-ph" , 214 }, { L"en-tt" , 208 }, { L"en-us" , 75 }, { L"en-za" , 192 }, { L"en-zw" , 211 }, { L"es" , 9 }, { L"es-ar" , 209 }, { L"es-bo" , 221 }, { L"es-cl" , 215 }, { L"es-co" , 202 }, { L"es-cr" , 181 }, { L"es-do" , 193 }, { L"es-ec" , 212 }, { L"es-es" , 164 }, { L"es-gt" , 173 }, { L"es-hn" , 223 }, { L"es-mx" , 147 }, { L"es-ni" , 224 }, { L"es-pa" , 187 }, { L"es-pe" , 206 }, { L"es-pr" , 225 }, { L"es-py" , 219 }, { L"es-sv" , 222 }, { L"es-uy" , 217 }, { L"es-ve" , 198 }, { L"et" , 35 }, { L"et-ee" , 101 }, { L"eu" , 42 }, { L"eu-es" , 108 }, { L"fa" , 38 }, { L"fa-ir" , 104 }, { L"fi" , 10 }, { L"fi-fi" , 76 }, { L"fo" , 46 }, { L"fo-fo" , 115 }, { L"fr" , 11 }, { L"fr-be" , 148 }, { L"fr-ca" , 165 }, { L"fr-ch" , 174 }, { L"fr-fr" , 77 }, { L"fr-lu" , 182 }, { L"fr-mc" , 188 }, { L"gl" , 62 }, { L"gl-es" , 136 }, { L"gu" , 55 }, { L"gu-in" , 127 }, { L"he" , 12 }, { L"he-il" , 78 }, { L"hi" , 47 }, { L"hi-in" , 116 }, { L"hr" , 24 }, { L"hr-ba" , 175 }, { L"hr-hr" , 90 }, { L"hu" , 13 }, { L"hu-hu" , 79 }, { L"hy" , 40 }, { L"hy-am" , 106 }, { L"id" , 31 }, { L"id-id" , 97 }, { L"is" , 14 }, { L"is-is" , 80 }, { L"it" , 15 }, { L"it-ch" , 149 }, { L"it-it" , 81 }, { L"ja" , 16 }, { L"ja-jp" , 82 }, { L"ka" , 45 }, { L"ka-ge" , 114 }, { L"kk" , 49 }, { L"kk-kz" , 120 }, { L"kn" , 58 }, { L"kn-in" , 130 }, { L"ko" , 17 }, { L"kok" , 63 }, { L"kok-in" , 137 }, { L"ko-kr" , 83 }, { L"ky" , 50 }, { L"ky-kg" , 121 }, { L"lt" , 37 }, { L"lt-lt" , 103 }, { L"lv" , 36 }, { L"lv-lv" , 102 }, { L"mi-nz" , 142 }, { L"mk" , 43 }, { L"mk-mk" , 109 }, { L"ml-in" , 131 }, { L"mn" , 61 }, { L"mn-mn" , 134 }, { L"mr" , 59 }, { L"mr-in" , 132 }, { L"ms" , 48 }, { L"ms-bn" , 157 }, { L"ms-my" , 119 }, { L"mt-mt" , 117 }, { L"nb-no" , 85 }, { L"nl" , 18 }, { L"nl-be" , 150 }, { L"nl-nl" , 84 }, { L"nn-no" , 151 }, { L"no" , 19 }, { L"ns-za" , 141 }, { L"pa" , 54 }, { L"pa-in" , 126 }, { L"pl" , 20 }, { L"pl-pl" , 86 }, { L"pt" , 21 }, { L"pt-br" , 87 }, { L"pt-pt" , 152 }, { L"quz-bo" , 140 }, { L"quz-ec" , 159 }, { L"quz-pe" , 168 }, { L"ro" , 22 }, { L"ro-ro" , 88 }, { L"ru" , 23 }, { L"ru-ru" , 89 }, { L"sa" , 60 }, { L"sa-in" , 133 }, { L"se-fi" , 167 }, { L"se-no" , 118 }, { L"se-se" , 156 }, { L"sk" , 25 }, { L"sk-sk" , 91 }, { L"sl" , 34 }, { L"sl-si" , 100 }, { L"sma-no" , 190 }, { L"sma-se" , 195 }, { L"smj-no" , 176 }, { L"smj-se" , 184 }, { L"smn-fi" , 203 }, { L"sms-fi" , 199 }, { L"sq" , 26 }, { L"sq-al" , 92 }, { L"sr" , 227 }, { L"sr-ba-cyrl" , 194 }, { L"sr-ba-latn" , 189 }, { L"sr-sp-cyrl" , 166 }, { L"sr-sp-latn" , 153 }, { L"sv" , 27 }, { L"sv-fi" , 154 }, { L"sv-se" , 93 }, { L"sw" , 51 }, { L"sw-ke" , 122 }, { L"syr" , 64 }, { L"syr-sy" , 138 }, { L"ta" , 56 }, { L"ta-in" , 128 }, { L"te" , 57 }, { L"te-in" , 129 }, { L"th" , 28 }, { L"th-th" , 94 }, { L"tn-za" , 110 }, { L"tr" , 29 }, { L"tr-tr" , 95 }, { L"tt" , 53 }, { L"tt-ru" , 124 }, { L"uk" , 32 }, { L"uk-ua" , 98 }, { L"ur" , 30 }, { L"ur-pk" , 96 }, { L"uz" , 52 }, { L"uz-uz-cyrl" , 158 }, { L"uz-uz-latn" , 123 }, { L"vi" , 39 }, { L"vi-vn" , 105 }, { L"xh-za" , 111 }, { L"zh-chs" , 3 }, { L"zh-cht" , 226 }, { L"zh-cn" , 144 }, { L"zh-hk" , 161 }, { L"zh-mo" , 178 }, { L"zh-sg" , 170 }, { L"zh-tw" , 70 }, { L"zu-za" , 112 } }; } // unnamed namespace // Maps input locale name to the index on LcidToLocaleNameTable static int GetTableIndexFromLocaleName(const wchar_t* localeName) throw() { LocaleNameIndex *localeNamesIndex = (LocaleNameIndex *) LocaleNameToIndexTable; int bottom = 0; int top = _countof(LocaleNameToIndexTable) - 1; while (bottom <= top) { int middle = (bottom + top) / 2; int testIndex = __ascii_wcsnicmp(localeName, localeNamesIndex[middle].name, LOCALE_NAME_MAX_LENGTH); if (testIndex == 0) return localeNamesIndex[middle].index; if (testIndex < 0) top = middle - 1; else bottom = middle + 1; } return -1; } // Maps input LCID to an index in LcidToLocaleNameTable static int GetTableIndexFromLcid(LCID lcid) throw() { int bottom = 0; int top = _countof(LcidToLocaleNameTable) - 1; while (bottom <= top) { int middle = (bottom + top) / 2; int testIndex = lcid - LcidToLocaleNameTable[middle].lcid; if (testIndex == 0) return middle; if (testIndex < 0) top = middle - 1; else bottom = middle + 1; } return -1; } extern "C" LCID __cdecl __acrt_DownlevelLocaleNameToLCID(LPCWSTR localeName) { int index; if (localeName == nullptr) return 0; index = GetTableIndexFromLocaleName(localeName); if (index < 0 || (index >= _countof(LcidToLocaleNameTable))) return 0; return LcidToLocaleNameTable[index].lcid; } extern "C" int __cdecl __acrt_DownlevelLCIDToLocaleName( LCID lcid, LPWSTR outLocaleName, int cchLocaleName ) { size_t count; wchar_t* buffer; int index; if (lcid == 0 || lcid == LOCALE_USER_DEFAULT || lcid == LOCALE_SYSTEM_DEFAULT) { return 0; } if ((outLocaleName == nullptr && cchLocaleName>0) || cchLocaleName < 0) { return 0; } index = GetTableIndexFromLcid(lcid); if (index < 0) return 0; buffer = LcidToLocaleNameTable[index].localeName; count = wcsnlen(buffer, LOCALE_NAME_MAX_LENGTH); if (cchLocaleName > 0) { if ((int)count >= cchLocaleName) return 0; _ERRCHECK(wcscpy_s(outLocaleName, cchLocaleName, buffer)); } return (int) count + 1; }