// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. //////////////////////////////////////////////////////////////////////////// // // File: downlevel.cpp // // // Purpose: functions that need to be emulated on downlevel platforms. // //////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #if defined(ENABLE_DOWNLEVEL_FOR_NLS) #ifndef LOCALE_SNAME #define LOCALE_SNAME 0x0000005c #endif #include "downlevel.h" #include "newapis.h" #include "utilcode.h" #include "sstring.h" #include "ex.h" #define LCID_AZ_CYRL_AZ 0x0082c // // Macro to check if more than one bit is set. // Returns 1 if more than one bit set, 0 otherwise. // #define MORE_THAN_ONE(f, bits) (((f & bits) - 1) & (f & bits)) struct LCIDEntry { LCID lcid; LPCWSTR wszName; }; // Known (ie: <= Vista) Name/LCID lookup table, sorted by LCID const static LCIDEntry s_lcids[]= { // Neutrals { 0x00001, W("ar") }, // Neutral Locale { 0x00002, W("bg") }, // Neutral Locale { 0x00003, W("ca") }, // Neutral Locale { 0x00004, W("zh-Hans") }, // Neutral Locale { 0x00005, W("cs") }, // Neutral Locale { 0x00006, W("da") }, // Neutral Locale { 0x00007, W("de") }, // Neutral Locale { 0x00008, W("el") }, // Neutral Locale { 0x00009, W("en") }, // Neutral Locale { 0x0000a, W("es") }, // Neutral Locale { 0x0000b, W("fi") }, // Neutral Locale { 0x0000c, W("fr") }, // Neutral Locale { 0x0000d, W("he") }, // Neutral Locale { 0x0000e, W("hu") }, // Neutral Locale { 0x0000f, W("is") }, // Neutral Locale { 0x00010, W("it") }, // Neutral Locale { 0x00011, W("ja") }, // Neutral Locale { 0x00012, W("ko") }, // Neutral Locale { 0x00013, W("nl") }, // Neutral Locale { 0x00014, W("no") }, // Neutral Locale { 0x00015, W("pl") }, // Neutral Locale { 0x00016, W("pt") }, // Neutral Locale { 0x00017, W("rm") }, // Neutral Locale { 0x00018, W("ro") }, // Neutral Locale { 0x00019, W("ru") }, // Neutral Locale { 0x0001a, W("hr") }, // Neutral Locale { 0x0001b, W("sk") }, // Neutral Locale { 0x0001c, W("sq") }, // Neutral Locale { 0x0001d, W("sv") }, // Neutral Locale { 0x0001e, W("th") }, // Neutral Locale { 0x0001f, W("tr") }, // Neutral Locale { 0x00020, W("ur") }, // Neutral Locale { 0x00021, W("id") }, // Neutral Locale { 0x00022, W("uk") }, // Neutral Locale { 0x00023, W("be") }, // Neutral Locale { 0x00024, W("sl") }, // Neutral Locale { 0x00025, W("et") }, // Neutral Locale { 0x00026, W("lv") }, // Neutral Locale { 0x00027, W("lt") }, // Neutral Locale { 0x00028, W("tg") }, // Neutral Locale { 0x00029, W("fa") }, // Neutral Locale { 0x0002a, W("vi") }, // Neutral Locale { 0x0002b, W("hy") }, // Neutral Locale { 0x0002c, W("az") }, // Neutral Locale { 0x0002d, W("eu") }, // Neutral Locale { 0x0002e, W("hsb") }, // Neutral Locale { 0x0002f, W("mk") }, // Neutral Locale { 0x00032, W("tn") }, // Neutral Locale { 0x00034, W("xh") }, // Neutral Locale { 0x00035, W("zu") }, // Neutral Locale { 0x00036, W("af") }, // Neutral Locale { 0x00037, W("ka") }, // Neutral Locale { 0x00038, W("fo") }, // Neutral Locale { 0x00039, W("hi") }, // Neutral Locale { 0x0003a, W("mt") }, // Neutral Locale { 0x0003b, W("se") }, // Neutral Locale { 0x0003c, W("ga") }, // Neutral Locale { 0x0003e, W("ms") }, // Neutral Locale { 0x0003f, W("kk") }, // Neutral Locale { 0x00040, W("ky") }, // Neutral Locale { 0x00041, W("sw") }, // Neutral Locale { 0x00042, W("tk") }, // Neutral Locale { 0x00043, W("uz") }, // Neutral Locale { 0x00044, W("tt") }, // Neutral Locale { 0x00045, W("bn") }, // Neutral Locale { 0x00046, W("pa") }, // Neutral Locale { 0x00047, W("gu") }, // Neutral Locale { 0x00048, W("or") }, // Neutral Locale { 0x00049, W("ta") }, // Neutral Locale { 0x0004a, W("te") }, // Neutral Locale { 0x0004b, W("kn") }, // Neutral Locale { 0x0004c, W("ml") }, // Neutral Locale { 0x0004d, W("as") }, // Neutral Locale { 0x0004e, W("mr") }, // Neutral Locale { 0x0004f, W("sa") }, // Neutral Locale { 0x00050, W("mn") }, // Neutral Locale { 0x00051, W("bo") }, // Neutral Locale { 0x00052, W("cy") }, // Neutral Locale { 0x00053, W("km") }, // Neutral Locale { 0x00054, W("lo") }, // Neutral Locale { 0x00056, W("gl") }, // Neutral Locale { 0x00057, W("kok") }, // Neutral Locale { 0x0005a, W("syr") }, // Neutral Locale { 0x0005b, W("si") }, // Neutral Locale { 0x0005d, W("iu") }, // Neutral Locale { 0x0005e, W("am") }, // Neutral Locale { 0x0005f, W("tzm") }, // Neutral Locale { 0x00061, W("ne") }, // Neutral Locale { 0x00062, W("fy") }, // Neutral Locale { 0x00063, W("ps") }, // Neutral Locale { 0x00064, W("fil") }, // Neutral Locale { 0x00065, W("dv") }, // Neutral Locale { 0x00068, W("ha") }, // Neutral Locale { 0x0006a, W("yo") }, // Neutral Locale { 0x0006b, W("quz") }, // Neutral Locale { 0x0006c, W("nso") }, // Neutral Locale { 0x0006d, W("ba") }, // Neutral Locale { 0x0006e, W("lb") }, // Neutral Locale { 0x0006f, W("kl") }, // Neutral Locale { 0x00070, W("ig") }, // Neutral Locale { 0x00078, W("ii") }, // Neutral Locale { 0x0007a, W("arn") }, // Neutral Locale { 0x0007c, W("moh") }, // Neutral Locale { 0x0007e, W("br") }, // Neutral Locale { 0x00080, W("ug") }, // Neutral Locale { 0x00081, W("mi") }, // Neutral Locale { 0x00082, W("oc") }, // Neutral Locale { 0x00083, W("co") }, // Neutral Locale { 0x00084, W("gsw") }, // Neutral Locale { 0x00085, W("sah") }, // Neutral Locale { 0x00086, W("qut") }, // Neutral Locale { 0x00087, W("rw") }, // Neutral Locale { 0x00088, W("wo") }, // Neutral Locale { 0x0008c, W("prs") }, // Neutral Locale // Specific Cultures { 0x00401, W("ar-SA") }, { 0x00402, W("bg-BG") }, { 0x00403, W("ca-ES") }, { 0x00404, W("zh-TW") }, { 0x00405, W("cs-CZ") }, { 0x00406, W("da-DK") }, { 0x00407, W("de-DE") }, { 0x00408, W("el-GR") }, { 0x00409, W("en-US") }, // es-ES_tradnl only gets used if specifically asked for because // GetCultures() won't return it. (It's not a real locale, its an alt sort) { 0x0040a, W("es-ES_tradnl") }, { 0x0040b, W("fi-FI") }, { 0x0040c, W("fr-FR") }, { 0x0040d, W("he-IL") }, { 0x0040e, W("hu-HU") }, { 0x0040f, W("is-IS") }, { 0x00410, W("it-IT") }, { 0x00411, W("ja-JP") }, { 0x00412, W("ko-KR") }, { 0x00413, W("nl-NL") }, { 0x00414, W("nb-NO") }, { 0x00415, W("pl-PL") }, { 0x00416, W("pt-BR") }, { 0x00417, W("rm-CH") }, { 0x00418, W("ro-RO") }, { 0x00419, W("ru-RU") }, { 0x0041a, W("hr-HR") }, { 0x0041b, W("sk-SK") }, { 0x0041c, W("sq-AL") }, { 0x0041d, W("sv-SE") }, { 0x0041e, W("th-TH") }, { 0x0041f, W("tr-TR") }, { 0x00420, W("ur-PK") }, { 0x00421, W("id-ID") }, { 0x00422, W("uk-UA") }, { 0x00423, W("be-BY") }, { 0x00424, W("sl-SI") }, { 0x00425, W("et-EE") }, { 0x00426, W("lv-LV") }, { 0x00427, W("lt-LT") }, { 0x00428, W("tg-Cyrl-TJ") }, { 0x00429, W("fa-IR") }, { 0x0042a, W("vi-VN") }, { 0x0042b, W("hy-AM") }, { 0x0042c, W("az-Latn-AZ") }, { 0x0042d, W("eu-ES") }, { 0x0042e, W("hsb-DE") }, { 0x0042f, W("mk-MK") }, { 0x00432, W("tn-ZA") }, { 0x00434, W("xh-ZA") }, { 0x00435, W("zu-ZA") }, { 0x00436, W("af-ZA") }, { 0x00437, W("ka-GE") }, { 0x00438, W("fo-FO") }, { 0x00439, W("hi-IN") }, { 0x0043a, W("mt-MT") }, { 0x0043b, W("se-NO") }, { 0x0043e, W("ms-MY") }, { 0x0043f, W("kk-KZ") }, { 0x00440, W("ky-KG") }, { 0x00441, W("sw-KE") }, { 0x00442, W("tk-TM") }, { 0x00443, W("uz-Latn-UZ") }, { 0x00444, W("tt-RU") }, { 0x00445, W("bn-IN") }, { 0x00446, W("pa-IN") }, { 0x00447, W("gu-IN") }, { 0x00448, W("or-IN") }, { 0x00449, W("ta-IN") }, { 0x0044a, W("te-IN") }, { 0x0044b, W("kn-IN") }, { 0x0044c, W("ml-IN") }, { 0x0044d, W("as-IN") }, { 0x0044e, W("mr-IN") }, { 0x0044f, W("sa-IN") }, { 0x00450, W("mn-MN") }, { 0x00451, W("bo-CN") }, { 0x00452, W("cy-GB") }, { 0x00453, W("km-KH") }, { 0x00454, W("lo-LA") }, { 0x00456, W("gl-ES") }, { 0x00457, W("kok-IN") }, { 0x0045a, W("syr-SY") }, { 0x0045b, W("si-LK") }, { 0x0045d, W("iu-Cans-CA") }, { 0x0045e, W("am-ET") }, { 0x00461, W("ne-NP") }, { 0x00462, W("fy-NL") }, { 0x00463, W("ps-AF") }, { 0x00464, W("fil-PH") }, { 0x00465, W("dv-MV") }, { 0x00468, W("ha-Latn-NG") }, { 0x0046a, W("yo-NG") }, { 0x0046b, W("quz-BO") }, { 0x0046c, W("nso-ZA") }, { 0x0046d, W("ba-RU") }, { 0x0046e, W("lb-LU") }, { 0x0046f, W("kl-GL") }, { 0x00470, W("ig-NG") }, { 0x00478, W("ii-CN") }, { 0x0047a, W("arn-CL") }, { 0x0047c, W("moh-CA") }, { 0x0047e, W("br-FR") }, { 0x00480, W("ug-CN") }, { 0x00481, W("mi-NZ") }, { 0x00482, W("oc-FR") }, { 0x00483, W("co-FR") }, { 0x00484, W("gsw-FR") }, { 0x00485, W("sah-RU") }, { 0x00486, W("qut-GT") }, { 0x00487, W("rw-RW") }, { 0x00488, W("wo-SN") }, { 0x0048c, W("prs-AF") }, { 0x00501, W("qps-ploc") }, { 0x005fe, W("qps-ploca") }, { 0x00801, W("ar-IQ") }, { 0x00804, W("zh-CN") }, { 0x00807, W("de-CH") }, { 0x00809, W("en-GB") }, { 0x0080a, W("es-MX") }, { 0x0080c, W("fr-BE") }, { 0x00810, W("it-CH") }, { 0x00813, W("nl-BE") }, { 0x00814, W("nn-NO") }, { 0x00816, W("pt-PT") }, { 0x0081a, W("sr-Latn-CS") }, { 0x0081d, W("sv-FI") }, { 0x0082c, W("az-Cyrl-AZ") }, { 0x0082e, W("dsb-DE") }, { 0x0083b, W("se-SE") }, { 0x0083c, W("ga-IE") }, { 0x0083e, W("ms-BN") }, { 0x00843, W("uz-Cyrl-UZ") }, { 0x00845, W("bn-BD") }, { 0x00850, W("mn-Mong-CN") }, { 0x0085d, W("iu-Latn-CA") }, { 0x0085f, W("tzm-Latn-DZ") }, { 0x0086b, W("quz-EC") }, { 0x009ff, W("qps-plocm") }, { 0x00c01, W("ar-EG") }, { 0x00c04, W("zh-HK") }, { 0x00c07, W("de-AT") }, { 0x00c09, W("en-AU") }, { 0x00c0a, W("es-ES") }, { 0x00c0c, W("fr-CA") }, { 0x00c1a, W("sr-Cyrl-CS") }, { 0x00c3b, W("se-FI") }, { 0x00c6b, W("quz-PE") }, { 0x01001, W("ar-LY") }, { 0x01004, W("zh-SG") }, { 0x01007, W("de-LU") }, { 0x01009, W("en-CA") }, { 0x0100a, W("es-GT") }, { 0x0100c, W("fr-CH") }, { 0x0101a, W("hr-BA") }, { 0x0103b, W("smj-NO") }, { 0x01401, W("ar-DZ") }, { 0x01404, W("zh-MO") }, { 0x01407, W("de-LI") }, { 0x01409, W("en-NZ") }, { 0x0140a, W("es-CR") }, { 0x0140c, W("fr-LU") }, { 0x0141a, W("bs-Latn-BA") }, { 0x0143b, W("smj-SE") }, { 0x01801, W("ar-MA") }, { 0x01809, W("en-IE") }, { 0x0180a, W("es-PA") }, { 0x0180c, W("fr-MC") }, { 0x0181a, W("sr-Latn-BA") }, { 0x0183b, W("sma-NO") }, { 0x01c01, W("ar-TN") }, { 0x01c09, W("en-ZA") }, { 0x01c0a, W("es-DO") }, { 0x01c1a, W("sr-Cyrl-BA") }, { 0x01c3b, W("sma-SE") }, { 0x02001, W("ar-OM") }, { 0x02009, W("en-JM") }, { 0x0200a, W("es-VE") }, { 0x0201a, W("bs-Cyrl-BA") }, { 0x0203b, W("sms-FI") }, { 0x02401, W("ar-YE") }, { 0x02409, W("en-029") }, { 0x0240a, W("es-CO") }, { 0x0243b, W("smn-FI") }, { 0x02801, W("ar-SY") }, { 0x02809, W("en-BZ") }, { 0x0280a, W("es-PE") }, { 0x02c01, W("ar-JO") }, { 0x02c09, W("en-TT") }, { 0x02c0a, W("es-AR") }, { 0x03001, W("ar-LB") }, { 0x03009, W("en-ZW") }, { 0x0300a, W("es-EC") }, { 0x03401, W("ar-KW") }, { 0x03409, W("en-PH") }, { 0x0340a, W("es-CL") }, { 0x03801, W("ar-AE") }, { 0x0380a, W("es-UY") }, { 0x03c01, W("ar-BH") }, { 0x03c0a, W("es-PY") }, { 0x04001, W("ar-QA") }, { 0x04009, W("en-IN") }, { 0x0400a, W("es-BO") }, { 0x04409, W("en-MY") }, { 0x0440a, W("es-SV") }, { 0x04809, W("en-SG") }, { 0x0480a, W("es-HN") }, { 0x04c0a, W("es-NI") }, { 0x0500a, W("es-PR") }, { 0x0540a, W("es-US") }, // Multiple neutrals { 0x0781a, W("bs") }, // Neutral Locale { 0x07c04, W("zh-Hant") }, // Neutral Locale { 0x07c1a, W("sr") }, // Neutral Locale // Alt Sorts { 0x1007f, W("x-IV_mathan") }, { 0x10407, W("de-DE_phoneb") }, { 0x1040e, W("hu-HU_technl") }, { 0x10437, W("ka-GE_modern") }, { 0x20804, W("zh-CN_stroke") }, { 0x21004, W("zh-SG_stroke") }, { 0x21404, W("zh-MO_stroke") }, { 0x30404, W("zh-TW_pronun") }, { 0x40411, W("ja-JP_radstr") } // TODO: Turkic? (Necessary ?) }; // Known (ie: <= Vista) Name/LCID lookup table, sorted by Name const static LCIDEntry s_names[]= { { 0x00036, W("af") }, // Neutral Locale { 0x00436, W("af-ZA") }, { 0x0005e, W("am") }, // Neutral Locale { 0x0045e, W("am-ET") }, { 0x00001, W("ar") }, // Neutral Locale { 0x03801, W("ar-AE") }, { 0x03c01, W("ar-BH") }, { 0x01401, W("ar-DZ") }, { 0x00c01, W("ar-EG") }, { 0x00801, W("ar-IQ") }, { 0x02c01, W("ar-JO") }, { 0x03401, W("ar-KW") }, { 0x03001, W("ar-LB") }, { 0x01001, W("ar-LY") }, { 0x01801, W("ar-MA") }, { 0x02001, W("ar-OM") }, { 0x04001, W("ar-QA") }, { 0x00401, W("ar-SA") }, { 0x02801, W("ar-SY") }, { 0x01c01, W("ar-TN") }, { 0x02401, W("ar-YE") }, { 0x0007a, W("arn") }, // Neutral Locale { 0x0047a, W("arn-CL") }, { 0x0004d, W("as") }, // Neutral Locale { 0x0044d, W("as-IN") }, { 0x0002c, W("az") }, // Neutral Locale { 0x0082c, W("az-Cyrl-AZ") }, { 0x0042c, W("az-Latn-AZ") }, { 0x0006d, W("ba") }, // Neutral Locale { 0x0046d, W("ba-RU") }, { 0x00023, W("be") }, // Neutral Locale { 0x00423, W("be-BY") }, { 0x00002, W("bg") }, // Neutral Locale { 0x00402, W("bg-BG") }, { 0x00045, W("bn") }, // Neutral Locale { 0x00845, W("bn-BD") }, { 0x00445, W("bn-IN") }, { 0x00051, W("bo") }, // Neutral Locale { 0x00451, W("bo-CN") }, { 0x0007e, W("br") }, // Neutral Locale { 0x0047e, W("br-FR") }, { 0x0781a, W("bs") }, // Neutral Locale { 0x0201a, W("bs-Cyrl-BA") }, { 0x0141a, W("bs-Latn-BA") }, { 0x00003, W("ca") }, // Neutral Locale { 0x00403, W("ca-ES") }, { 0x00083, W("co") }, // Neutral Locale { 0x00483, W("co-FR") }, { 0x00005, W("cs") }, // Neutral Locale { 0x00405, W("cs-CZ") }, { 0x00052, W("cy") }, // Neutral Locale { 0x00452, W("cy-GB") }, { 0x00006, W("da") }, // Neutral Locale { 0x00406, W("da-DK") }, { 0x00007, W("de") }, // Neutral Locale { 0x00c07, W("de-AT") }, { 0x00807, W("de-CH") }, { 0x00407, W("de-DE") }, { 0x10407, W("de-DE_phoneb") }, // Alternate Sort { 0x01407, W("de-LI") }, { 0x01007, W("de-LU") }, { 0x0082e, W("dsb-DE") }, { 0x00065, W("dv") }, // Neutral Locale { 0x00465, W("dv-MV") }, { 0x00008, W("el") }, // Neutral Locale { 0x00408, W("el-GR") }, { 0x00009, W("en") }, // Neutral Locale { 0x02409, W("en-029") }, { 0x00c09, W("en-AU") }, { 0x02809, W("en-BZ") }, { 0x01009, W("en-CA") }, { 0x00809, W("en-GB") }, { 0x01809, W("en-IE") }, { 0x04009, W("en-IN") }, { 0x02009, W("en-JM") }, { 0x04409, W("en-MY") }, { 0x01409, W("en-NZ") }, { 0x03409, W("en-PH") }, { 0x04809, W("en-SG") }, { 0x02c09, W("en-TT") }, { 0x00409, W("en-US") }, { 0x01c09, W("en-ZA") }, { 0x03009, W("en-ZW") }, { 0x0000a, W("es") }, // Neutral Locale { 0x02c0a, W("es-AR") }, { 0x0400a, W("es-BO") }, { 0x0340a, W("es-CL") }, { 0x0240a, W("es-CO") }, { 0x0140a, W("es-CR") }, { 0x01c0a, W("es-DO") }, { 0x0300a, W("es-EC") }, { 0x00c0a, W("es-ES") }, // es-ES_tradnl only gets used if specifically asked for because // GetCultures() won't return it. (It's not a real locale, its an alt sort) { 0x0040a, W("es-ES_tradnl") }, { 0x0100a, W("es-GT") }, { 0x0480a, W("es-HN") }, { 0x0080a, W("es-MX") }, { 0x04c0a, W("es-NI") }, { 0x0180a, W("es-PA") }, { 0x0280a, W("es-PE") }, { 0x0500a, W("es-PR") }, { 0x03c0a, W("es-PY") }, { 0x0440a, W("es-SV") }, { 0x0540a, W("es-US") }, { 0x0380a, W("es-UY") }, { 0x0200a, W("es-VE") }, { 0x00025, W("et") }, // Neutral Locale { 0x00425, W("et-EE") }, { 0x0002d, W("eu") }, // Neutral Locale { 0x0042d, W("eu-ES") }, { 0x00029, W("fa") }, // Neutral Locale { 0x00429, W("fa-IR") }, { 0x0000b, W("fi") }, // Neutral Locale { 0x0040b, W("fi-FI") }, { 0x00064, W("fil") }, // Neutral Locale { 0x00464, W("fil-PH") }, { 0x00038, W("fo") }, // Neutral Locale { 0x00438, W("fo-FO") }, { 0x0000c, W("fr") }, // Neutral Locale { 0x0080c, W("fr-BE") }, { 0x00c0c, W("fr-CA") }, { 0x0100c, W("fr-CH") }, { 0x0040c, W("fr-FR") }, { 0x0140c, W("fr-LU") }, { 0x0180c, W("fr-MC") }, { 0x00062, W("fy") }, // Neutral Locale { 0x00462, W("fy-NL") }, { 0x0003c, W("ga") }, // Neutral Locale { 0x0083c, W("ga-IE") }, { 0x00056, W("gl") }, // Neutral Locale { 0x00456, W("gl-ES") }, { 0x00084, W("gsw") }, // Neutral Locale { 0x00484, W("gsw-FR") }, { 0x00047, W("gu") }, // Neutral Locale { 0x00447, W("gu-IN") }, { 0x00068, W("ha") }, // Neutral Locale { 0x00468, W("ha-Latn-NG") }, { 0x0000d, W("he") }, // Neutral Locale { 0x0040d, W("he-IL") }, { 0x00039, W("hi") }, // Neutral Locale { 0x00439, W("hi-IN") }, { 0x0001a, W("hr") }, // Neutral Locale { 0x0101a, W("hr-BA") }, { 0x0041a, W("hr-HR") }, { 0x0002e, W("hsb") }, // Neutral Locale { 0x0042e, W("hsb-DE") }, { 0x0000e, W("hu") }, // Neutral Locale { 0x0040e, W("hu-HU") }, { 0x1040e, W("hu-HU_technl") }, // Alternate Sort { 0x0002b, W("hy") }, // Neutral Locale { 0x0042b, W("hy-AM") }, { 0x00021, W("id") }, // Neutral Locale { 0x00421, W("id-ID") }, { 0x00070, W("ig") }, // Neutral Locale { 0x00470, W("ig-NG") }, { 0x00078, W("ii") }, // Neutral Locale { 0x00478, W("ii-CN") }, { 0x0000f, W("is") }, // Neutral Locale { 0x0040f, W("is-IS") }, { 0x00010, W("it") }, // Neutral Locale { 0x00810, W("it-CH") }, { 0x00410, W("it-IT") }, { 0x0005d, W("iu") }, // Neutral Locale { 0x0045d, W("iu-Cans-CA") }, { 0x0085d, W("iu-Latn-CA") }, { 0x00011, W("ja") }, // Neutral Locale { 0x00411, W("ja-JP") }, { 0x40411, W("ja-JP_radstr") }, // Alternate Sort { 0x00037, W("ka") }, // Neutral Locale { 0x00437, W("ka-GE") }, { 0x10437, W("ka-GE_modern") }, // Alternate Sort { 0x0003f, W("kk") }, // Neutral Locale { 0x0043f, W("kk-KZ") }, { 0x0006f, W("kl") }, // Neutral Locale { 0x0046f, W("kl-GL") }, { 0x00053, W("km") }, // Neutral Locale { 0x00453, W("km-KH") }, { 0x0004b, W("kn") }, // Neutral Locale { 0x0044b, W("kn-IN") }, { 0x00012, W("ko") }, // Neutral Locale { 0x00412, W("ko-KR") }, { 0x00057, W("kok") }, // Neutral Locale { 0x00457, W("kok-IN") }, { 0x00040, W("ky") }, // Neutral Locale { 0x00440, W("ky-KG") }, { 0x0006e, W("lb") }, // Neutral Locale { 0x0046e, W("lb-LU") }, { 0x00054, W("lo") }, // Neutral Locale { 0x00454, W("lo-LA") }, { 0x00027, W("lt") }, // Neutral Locale { 0x00427, W("lt-LT") }, { 0x00026, W("lv") }, // Neutral Locale { 0x00426, W("lv-LV") }, { 0x00081, W("mi") }, // Neutral Locale { 0x00481, W("mi-NZ") }, { 0x0002f, W("mk") }, // Neutral Locale { 0x0042f, W("mk-MK") }, { 0x0004c, W("ml") }, // Neutral Locale { 0x0044c, W("ml-IN") }, { 0x00050, W("mn") }, // Neutral Locale { 0x00450, W("mn-MN") }, { 0x00850, W("mn-Mong-CN") }, { 0x0007c, W("moh") }, // Neutral Locale { 0x0047c, W("moh-CA") }, { 0x0004e, W("mr") }, // Neutral Locale { 0x0044e, W("mr-IN") }, { 0x0003e, W("ms") }, // Neutral Locale { 0x0083e, W("ms-BN") }, { 0x0043e, W("ms-MY") }, { 0x0003a, W("mt") }, // Neutral Locale { 0x0043a, W("mt-MT") }, { 0x00414, W("nb-NO") }, { 0x00061, W("ne") }, // Neutral Locale { 0x00461, W("ne-NP") }, { 0x00013, W("nl") }, // Neutral Locale { 0x00813, W("nl-BE") }, { 0x00413, W("nl-NL") }, { 0x00814, W("nn-NO") }, { 0x00014, W("no") }, // Neutral Locale { 0x0006c, W("nso") }, // Neutral Locale { 0x0046c, W("nso-ZA") }, { 0x00082, W("oc") }, // Neutral Locale { 0x00482, W("oc-FR") }, { 0x00048, W("or") }, // Neutral Locale { 0x00448, W("or-IN") }, { 0x00046, W("pa") }, // Neutral Locale { 0x00446, W("pa-IN") }, { 0x00015, W("pl") }, // Neutral Locale { 0x00415, W("pl-PL") }, { 0x0008c, W("prs") }, // Neutral Locale { 0x0048c, W("prs-AF") }, { 0x00063, W("ps") }, // Neutral Locale { 0x00463, W("ps-AF") }, { 0x00016, W("pt") }, // Neutral Locale { 0x00416, W("pt-BR") }, { 0x00816, W("pt-PT") }, { 0x00501, W("qps-ploc") }, { 0x005fe, W("qps-ploca") }, { 0x009ff, W("qps-plocm") }, { 0x00086, W("qut") }, // Neutral Locale { 0x00486, W("qut-GT") }, { 0x0006b, W("quz") }, // Neutral Locale { 0x0046b, W("quz-BO") }, { 0x0086b, W("quz-EC") }, { 0x00c6b, W("quz-PE") }, { 0x00017, W("rm") }, // Neutral Locale { 0x00417, W("rm-CH") }, { 0x00018, W("ro") }, // Neutral Locale { 0x00418, W("ro-RO") }, { 0x00019, W("ru") }, // Neutral Locale { 0x00419, W("ru-RU") }, { 0x00087, W("rw") }, // Neutral Locale { 0x00487, W("rw-RW") }, { 0x0004f, W("sa") }, // Neutral Locale { 0x0044f, W("sa-IN") }, { 0x00085, W("sah") }, // Neutral Locale { 0x00485, W("sah-RU") }, { 0x0003b, W("se") }, // Neutral Locale { 0x00c3b, W("se-FI") }, { 0x0043b, W("se-NO") }, { 0x0083b, W("se-SE") }, { 0x0005b, W("si") }, // Neutral Locale { 0x0045b, W("si-LK") }, { 0x0001b, W("sk") }, // Neutral Locale { 0x0041b, W("sk-SK") }, { 0x00024, W("sl") }, // Neutral Locale { 0x00424, W("sl-SI") }, { 0x0183b, W("sma-NO") }, { 0x01c3b, W("sma-SE") }, { 0x0103b, W("smj-NO") }, { 0x0143b, W("smj-SE") }, { 0x0243b, W("smn-FI") }, { 0x0203b, W("sms-FI") }, { 0x0001c, W("sq") }, // Neutral Locale { 0x0041c, W("sq-AL") }, { 0x07c1a, W("sr") }, // Neutral Locale { 0x01c1a, W("sr-Cyrl-BA") }, { 0x00c1a, W("sr-Cyrl-CS") }, { 0x0181a, W("sr-Latn-BA") }, { 0x0081a, W("sr-Latn-CS") }, { 0x0001d, W("sv") }, // Neutral Locale { 0x0081d, W("sv-FI") }, { 0x0041d, W("sv-SE") }, { 0x00041, W("sw") }, // Neutral Locale { 0x00441, W("sw-KE") }, { 0x0005a, W("syr") }, // Neutral Locale { 0x0045a, W("syr-SY") }, { 0x00049, W("ta") }, // Neutral Locale { 0x00449, W("ta-IN") }, { 0x0004a, W("te") }, // Neutral Locale { 0x0044a, W("te-IN") }, { 0x00028, W("tg") }, // Neutral Locale { 0x00428, W("tg-Cyrl-TJ") }, { 0x0001e, W("th") }, // Neutral Locale { 0x0041e, W("th-TH") }, { 0x00042, W("tk") }, // Neutral Locale { 0x00442, W("tk-TM") }, { 0x00032, W("tn") }, // Neutral Locale { 0x00432, W("tn-ZA") }, { 0x0001f, W("tr") }, // Neutral Locale { 0x0041f, W("tr-TR") }, { 0x00044, W("tt") }, // Neutral Locale { 0x00444, W("tt-RU") }, { 0x0005f, W("tzm") }, // Neutral Locale { 0x0085f, W("tzm-Latn-DZ") }, { 0x00080, W("ug") }, // Neutral Locale { 0x00480, W("ug-CN") }, { 0x00022, W("uk") }, // Neutral Locale { 0x00422, W("uk-UA") }, { 0x00020, W("ur") }, // Neutral Locale { 0x00420, W("ur-PK") }, { 0x00043, W("uz") }, // Neutral Locale { 0x00843, W("uz-Cyrl-UZ") }, { 0x00443, W("uz-Latn-UZ") }, { 0x0002a, W("vi") }, // Neutral Locale { 0x0042a, W("vi-VN") }, { 0x00088, W("wo") }, // Neutral Locale { 0x00488, W("wo-SN") }, { 0x1007f, W("x-IV_mathan") }, // Alternate Sort { 0x00034, W("xh") }, // Neutral Locale { 0x00434, W("xh-ZA") }, { 0x0006a, W("yo") }, // Neutral Locale { 0x0046a, W("yo-NG") }, { 0x00804, W("zh-CN") }, { 0x20804, W("zh-CN_stroke") }, // Alternate Sort { 0x00004, W("zh-Hans") }, // Neutral Locale { 0x07c04, W("zh-Hant") }, // Neutral Locale { 0x00c04, W("zh-HK") }, { 0x01404, W("zh-MO") }, { 0x21404, W("zh-MO_stroke") }, // Alternate Sort { 0x01004, W("zh-SG") }, { 0x21004, W("zh-SG_stroke") }, // Alternate Sort { 0x00404, W("zh-TW") }, { 0x30404, W("zh-TW_pronun") }, // Alternate Sort { 0x00035, W("zu") }, // Neutral Locale { 0x00435, W("zu-ZA") } }; // This is the data from l_intl.nls as released for XP for the uppercase table. // This is used for casing with OrdinalCompareStringIgnoreCase // since XP is the only scenario that needs data and the only data that it needs // is uppercasing, we duplicate the table here. const static WORD s_pUppercaseIndexTableXP[] = { 0x0110, 0x0120, 0x0130, 0x0140, 0x0150, 0x0160, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0170, 0x0180, 0x0100, 0x0190, 0x0100, 0x0100, 0x01a0, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x01b0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01d0, 0x01e0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01f0, 0x0200, 0x0210, 0x0220, 0x0230, 0x0240, 0x0250, 0x0260, 0x0270, 0x0280, 0x0290, 0x02a0, 0x02b0, 0x02c0, 0x02d0, 0x02e0, 0x02f0, 0x0300, 0x0310, 0x0320, 0x01c0, 0x01c0, 0x01c0, 0x0330, 0x0340, 0x0350, 0x0360, 0x0370, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x0380, 0x0390, 0x03a0, 0x03b0, 0x03c0, 0x03d0, 0x03e0, 0x01c0, 0x01c0, 0x01c0, 0x03f0, 0x0400, 0x0410, 0x0420, 0x0430, 0x0440, 0x0450, 0x0460, 0x0470, 0x0480, 0x0490, 0x04a0, 0x04b0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x04c0, 0x04d0, 0x04e0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x04f0, 0x0500, 0x0510, 0x0520, 0x0530, 0x0540, 0x0550, 0x0560, 0x0570, 0x0580, 0x0590, 0x05a0, 0x05b0, 0x05c0, 0x05d0, 0x05e0, 0x05f0, 0x0600, 0x0610, 0x0620, 0x0630, 0x0640, 0x0650, 0x0660, 0x01c0, 0x01c0, 0x01c0, 0x0670, 0x01c0, 0x0680, 0x0690, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x06a0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x06b0, 0x06c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x06d0, 0x06e0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x0000, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x0079, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfffe, 0x0000, 0x0000, 0xfffe, 0x0000, 0x0000, 0xfffe, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0xffb1, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0xfffe, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xff2e, 0xff32, 0x0000, 0xff33, 0xff33, 0x0000, 0xff36, 0x0000, 0xff35, 0x0000, 0x0000, 0x0000, 0x0000, 0xff33, 0x0000, 0x0000, 0xff31, 0x0000, 0x0000, 0x0000, 0x0000, 0xff2f, 0xff2d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xff2d, 0x0000, 0x0000, 0xff2b, 0x0000, 0x0000, 0xff2a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xff26, 0x0000, 0x0000, 0x0000, 0x0000, 0xff26, 0x0000, 0xff27, 0xff27, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xff25, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffda, 0xffdb, 0xffdb, 0xffdb, 0x0000, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe1, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffc0, 0xffc1, 0xffc1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x0000, 0xffb0, 0xffb0, 0xffb0, 0xffb0, 0xffb0, 0xffb0, 0xffb0, 0xffb0, 0xffb0, 0xffb0, 0xffb0, 0xffb0, 0x0000, 0xffb0, 0xffb0, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0000, 0x0008, 0x0000, 0x0008, 0x0000, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x004a, 0x004a, 0x0056, 0x0056, 0x0056, 0x0056, 0x0064, 0x0064, 0x0080, 0x0080, 0x0070, 0x0070, 0x007e, 0x007e, 0x0000, 0x0000, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0007, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; // This is the data from casing.nls as released for Win2K3/XP for the lowercase table. // This is used for casing when linguistic casing is needed // since Win2K3/XP is the only scenario that needs data, we duplicate the table here. // It does NOT contain Turkic I exception behavior const static WORD s_pLowercaseIndexTableLinguisticXP[] = { 0x0110, 0x0120, 0x0130, 0x0140, 0x0150, 0x0160, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0170, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0180, 0x0190, 0x0100, 0x01a0, 0x0100, 0x0100, 0x01b0, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x01c0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01e0, 0x01f0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x0200, 0x0210, 0x01d0, 0x01d0, 0x0220, 0x0230, 0x0240, 0x0250, 0x0260, 0x0270, 0x0280, 0x0290, 0x02a0, 0x02b0, 0x02c0, 0x02d0, 0x02e0, 0x02f0, 0x0300, 0x0310, 0x0320, 0x0330, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x0340, 0x0350, 0x0360, 0x01d0, 0x01d0, 0x0370, 0x0380, 0x01d0, 0x0390, 0x03a0, 0x03b0, 0x01d0, 0x01d0, 0x01d0, 0x03c0, 0x03d0, 0x03e0, 0x03f0, 0x0400, 0x0410, 0x0420, 0x0430, 0x0440, 0x0450, 0x01d0, 0x01d0, 0x01d0, 0x0460, 0x0470, 0x0480, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x0490, 0x04a0, 0x04b0, 0x01d0, 0x01d0, 0x01d0, 0x04c0, 0x04d0, 0x04e0, 0x04f0, 0x0500, 0x0510, 0x0520, 0x0530, 0x0540, 0x0550, 0x0560, 0x0570, 0x0580, 0x0590, 0x05a0, 0x05b0, 0x05c0, 0x05d0, 0x05e0, 0x05f0, 0x0600, 0x0610, 0x0620, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x0630, 0x0640, 0x0650, 0x0660, 0x0670, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x0680, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x0690, 0x06a0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x06b0, 0x06c0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0000, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0xff39, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0xff87, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x00d2, 0x0001, 0x0000, 0x0001, 0x0000, 0x00ce, 0x0001, 0x0000, 0x00cd, 0x00cd, 0x0001, 0x0000, 0x0000, 0x004f, 0x00ca, 0x00cb, 0x0001, 0x0000, 0x00cd, 0x00cf, 0x0000, 0x00d3, 0x00d1, 0x0001, 0x0000, 0x0000, 0x0000, 0x00d3, 0x00d5, 0x0000, 0x00d6, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0000, 0x0001, 0x0000, 0x00da, 0x0000, 0x0000, 0x0001, 0x0000, 0x00da, 0x0001, 0x0000, 0x00d9, 0x00d9, 0x0001, 0x0000, 0x0001, 0x0000, 0x00db, 0x0001, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0002, 0x0001, 0x0000, 0x0002, 0x0001, 0x0000, 0x0002, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0000, 0x0002, 0x0001, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0026, 0x0000, 0x0025, 0x0025, 0x0025, 0x0000, 0x0040, 0x0000, 0x003f, 0x003f, 0x0000, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0000, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfff3, 0xfffa, 0xfff7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0000, 0x0050, 0x0050, 0x0050, 0x0050, 0x0050, 0x0050, 0x0050, 0x0050, 0x0050, 0x0050, 0x0050, 0x0050, 0x0000, 0x0050, 0x0050, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfff8, 0x0000, 0xfff8, 0x0000, 0xfff8, 0x0000, 0xfff8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfff8, 0xfff8, 0xffb6, 0xffb6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffaa, 0xffaa, 0xffaa, 0xffaa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfff8, 0xfff8, 0xff9c, 0xff9c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfff8, 0xfff8, 0xff90, 0xff90, 0xfff9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xff80, 0xff80, 0xff82, 0xff82, 0x0000, 0x0000, 0x0000, 0x0000, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x001a, 0x0000, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; // This is the data from casing.nls as released for Win2K3/XP for the uppercase table. // This is used for casing when linguistic casing is needed // since Win2K3/XP is the only scenario that needs data, we duplicate the table here. // It does NOT contain Turkic I exception behavior const static WORD s_pUppercaseIndexTableLinguisticXP[] = { 0x0110, 0x0120, 0x0130, 0x0140, 0x0150, 0x0160, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0170, 0x0180, 0x0100, 0x0190, 0x0100, 0x0100, 0x01a0, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x01b0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01d0, 0x01e0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01f0, 0x0200, 0x0210, 0x0220, 0x0230, 0x0240, 0x0250, 0x0260, 0x0270, 0x0280, 0x0290, 0x02a0, 0x02b0, 0x02c0, 0x02d0, 0x02e0, 0x02f0, 0x0300, 0x0310, 0x0320, 0x01c0, 0x01c0, 0x01c0, 0x0330, 0x0340, 0x0350, 0x0360, 0x0370, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x0380, 0x0390, 0x03a0, 0x03b0, 0x03c0, 0x03d0, 0x03e0, 0x01c0, 0x01c0, 0x01c0, 0x03f0, 0x0400, 0x0410, 0x0420, 0x0430, 0x0440, 0x0450, 0x0460, 0x0470, 0x0480, 0x0490, 0x04a0, 0x04b0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x04c0, 0x04d0, 0x04e0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x04f0, 0x0500, 0x0510, 0x0520, 0x0530, 0x0540, 0x0550, 0x0560, 0x0570, 0x0580, 0x0590, 0x05a0, 0x05b0, 0x05c0, 0x05d0, 0x05e0, 0x05f0, 0x0600, 0x0610, 0x0620, 0x0630, 0x0640, 0x0650, 0x0660, 0x01c0, 0x01c0, 0x01c0, 0x0670, 0x01c0, 0x0680, 0x0690, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x06a0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x06b0, 0x06c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x06d0, 0x06e0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x0000, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x0079, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xff18, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0xfffe, 0x0000, 0xffff, 0xfffe, 0x0000, 0xffff, 0xfffe, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0xffb1, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0xffff, 0xfffe, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xff2e, 0xff32, 0x0000, 0xff33, 0xff33, 0x0000, 0xff36, 0x0000, 0xff35, 0x0000, 0x0000, 0x0000, 0x0000, 0xff33, 0x0000, 0x0000, 0xff31, 0x0000, 0x0000, 0x0000, 0x0000, 0xff2f, 0xff2d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xff2d, 0x0000, 0x0000, 0xff2b, 0x0000, 0x0000, 0xff2a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xff26, 0x0000, 0x0000, 0x0000, 0x0000, 0xff26, 0x0000, 0xff27, 0xff27, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xff25, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x001a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffda, 0xffdb, 0xffdb, 0xffdb, 0xfffb, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe1, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffc0, 0xffc1, 0xffc1, 0x0000, 0xffc2, 0xffc7, 0x0000, 0x0000, 0x0000, 0xffd1, 0xffca, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0xffaa, 0xffb0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x0000, 0xffb0, 0xffb0, 0xffb0, 0xffb0, 0xffb0, 0xffb0, 0xffb0, 0xffb0, 0xffb0, 0xffb0, 0xffb0, 0xffb0, 0x0000, 0xffb0, 0xffb0, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0xffd0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0000, 0x0008, 0x0000, 0x0008, 0x0000, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x004a, 0x004a, 0x0056, 0x0056, 0x0056, 0x0056, 0x0064, 0x0064, 0x0080, 0x0080, 0x0070, 0x0070, 0x007e, 0x007e, 0x0000, 0x0000, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0007, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0xffe6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; static CRITSEC_COOKIE g_pDownlevelNlsCrst = NULL; static void DelayCreateCriticalSection() { // Lazily allocate a Crst to serialize update access to the info structure. // Carefully synchronize to ensure we don't leak a Crst in race conditions. if (g_pDownlevelNlsCrst == NULL) { CRITSEC_COOKIE pCrst = ClrCreateCriticalSection(CrstNls, (CrstFlags)(CRST_UNSAFE_COOPGC)); if (InterlockedCompareExchangeT(&g_pDownlevelNlsCrst, pCrst, NULL) != NULL) { ClrDeleteCriticalSection(pCrst); } } } static void NormalizeCultureName(SString& sName) { for (SString::Iterator i = sName.Begin(); i[0] != W('\0'); ++i) { sName.Replace(i,towlower(i[0])); } } static inline BOOL IsTurkicILcid(LCID lcid) { return (PRIMARYLANGID(lcid) == LANG_TURKISH || (PRIMARYLANGID(lcid) == LANG_AZERI && lcid != LCID_AZ_CYRL_AZ)); } namespace DownLevel { int GetSystemDefaultLocaleName(__out_ecount(cchLocaleName) LPWSTR lpLocaleName, __in int cchLocaleName) { LCID lcid=GetSystemDefaultLCID(); if (lcid == 0) return 0; return NewApis::LCIDToLocaleName(lcid,lpLocaleName,cchLocaleName,0); }; // Xp returns lcid 0x0404 (zh-TW) for GetUserDefaultUILanguage and GetSystemDefaultUILanguage // on a CHH sku (expected 0x0c04) as well as a CHT sku (as expected) inline LCID WorkAroundXpTaiwanHongKongBug(LCID lcid) { const LCID LANGID_ZH_TW = 0x0404; const LCID LANGID_ZH_HK = 0x0c04; if(lcid == LANGID_ZH_TW && !NewApis::IsZhTwSku()) { lcid = LANGID_ZH_HK; } return lcid; } DWORD GetUserPreferredUILanguages (__in DWORD dwFlags, __out PULONG pulNumLanguages, __out_ecount_opt(*pcchLanguagesBuffer) PWSTR pwszLanguagesBuffer, __in PULONG pcchLanguagesBuffer) { _ASSERTE(dwFlags==MUI_LANGUAGE_NAME); LCID lcid=GetUserDefaultUILanguage(); if (lcid == 0) return 0; lcid = WorkAroundXpTaiwanHongKongBug(lcid); WCHAR wszBuffer[LOCALE_NAME_MAX_LENGTH]; if (NewApis::LCIDToLocaleName(lcid, wszBuffer, NumItems(wszBuffer), 0) == 0) return 0; SIZE_T sLen=wcslen(wszBuffer)+2; ULONG uLen = (ULONG)sLen; if (uLen != sLen) { SetLastError(ERROR_ARITHMETIC_OVERFLOW); return 0; } *pulNumLanguages=1; if (pwszLanguagesBuffer == NULL) { *pcchLanguagesBuffer=uLen; return 1; } if (sLen > *pcchLanguagesBuffer) { *pcchLanguagesBuffer=uLen; SetLastError(ERROR_BUFFER_OVERFLOW); return 0; } *pcchLanguagesBuffer=uLen; wcscpy_s(pwszLanguagesBuffer, sLen, wszBuffer); pwszLanguagesBuffer[sLen-1]=W('\0'); SetLastError(0); return 1; } int GetUserDefaultLocaleName(__out_ecount(cchLocaleName) LPWSTR lpLocaleName, __in int cchLocaleName) { LCID lcid=GetUserDefaultLCID(); if (lcid == 0) return 0; return NewApis::LCIDToLocaleName(lcid,lpLocaleName,cchLocaleName,0); } int GetDateFormatEx(__in LPCWSTR lpLocaleName, __in DWORD dwFlags, __in_opt CONST SYSTEMTIME* lpDate, __in_opt LPCWSTR lpFormat, __out_ecount(cchDate) LPWSTR lpDateStr, __in int cchDate, __in_opt LPCWSTR lpCalendar) { _ASSERTE(lpCalendar==NULL); LCID lcid=NewApis::LocaleNameToLCID(lpLocaleName,0); if (lcid == 0) return 0; return GetDateFormatW(lcid, dwFlags, lpDate, lpFormat, lpDateStr, cchDate); } int GetLocaleInfoEx (__in LPCWSTR lpLocaleName, __in LCTYPE LCType, __out_ecount_opt(cchData) LPWSTR lpLCData, __in int cchData) { _ASSERTE((lpLCData == NULL && cchData == 0) || (lpLCData != NULL && cchData > 0)); // Note that this'll return neutral LCIDs LCID lcid=NewApis::LocaleNameToLCID(lpLocaleName,0); if (lcid == 0) return 0; int iRetCode = 0; // Special casing LOCALE_SPARENT to do Uplevel fallback. if ( (LCType & ~LOCALE_NOUSEROVERRIDE) == LOCALE_SPARENT ) { // OS doesn't know some LCTypes iRetCode = UplevelFallback::GetLocaleInfoEx(lpLocaleName, lcid, LCType, lpLCData, cchData); } else { iRetCode=GetLocaleInfoW(lcid,LCType,lpLCData,cchData); if (iRetCode == 0 && GetLastError() == ERROR_INVALID_FLAGS) { // OS doesn't know some LCTypes iRetCode = UplevelFallback::GetLocaleInfoEx(lpLocaleName, lcid, LCType, lpLCData, cchData); } } return iRetCode; }; // // TurkishCompareStringIgnoreCase // In downlevel platforms CompareString doesn't support Turkish I comparison. TurkishCompareStringIgnoreCase is to work around for this. // In Turkish and Azeri cultures: // ToUpper(i) = u0130 (Upper case I with dot above it) // ToLower(I) = u0131 (Lower case i with no dot above). // Toupper(i) != I // ToLower(I) != i // TurkishCompareStringIgnoreCase will scan the input strings and convert every i to u0130 and every I to u0131 and then call // the system CompareString. // if lpString1 not include i, I, u0130, and u0131 then we'll just call the system CompareString otherwise we'll scan the lpString2 // to detect if we need to do the conversions mentioned above. // #define TURKISH_CAPITAL_I_DOT_ABOVE ((WCHAR) 0x0130) #define TURKISH_LOWERCASE_DOTLESS_I ((WCHAR) 0x0131) #define LATIN_LOWERCASE_I_DOT_ABOVE ('i') #define LATIN_CAPITAL_DOTLESS_I ('I') int TurkishCompareStringIgnoreCase(LCID lcid, DWORD dwCmpFlags, LPCWSTR lpString1, int cchCount1, LPCWSTR lpString2, int cchCount2) { int str1Index = 0; int str2Index = 0; BOOL fScanStr2 = FALSE; for (str1Index=0; str1Index= cchCount1) { if (!fScanStr2) { return ::CompareStringW(lcid, dwCmpFlags, lpString1, cchCount1, lpString2, cchCount2); } for (str2Index=0; str2Index= cchCount2) { return ::CompareStringW(lcid, dwCmpFlags, lpString1, cchCount1, lpString2, cchCount2); } } NewArrayHolder pBuffer = new WCHAR[cchCount1 + cchCount2]; if (str1Index>0) { memcpy_s(pBuffer, cchCount1 * sizeof(WCHAR), lpString1, str1Index * sizeof(WCHAR)); } for (; str1Index0) { memcpy_s(&pBuffer[cchCount1], cchCount2 * sizeof(WCHAR), lpString2, str2Index * sizeof(WCHAR)); } for (; str2Index> 8]; value = table[value + ((wch >> 4) & 0xf)]; value = table[value + (wch & 0xf)]; return (wch + (int)((short)value)); } // since this should only be run on XP, we just use the same table as XP __inline WCHAR ToUpperXP(WCHAR wch) { return MapCase(s_pUppercaseIndexTableXP, wch); } INT32 CompareOrdinalIgnoreCaseHelper(__in_ecount(count) DWORD* strAChars, __in_ecount(count) DWORD* strBChars, int count) { if( count == 0) return 0; int temp = 0; _ASSERTE( count >0); // Only go through fast code path if two strings have the same alignment if (((size_t)strAChars & 3) == ((size_t)strBChars & 3)) { int unalignedBytesA = (size_t)strAChars & 3; _ASSERTE(unalignedBytesA == 0 || unalignedBytesA == 2); // First try to make the strings aligned at DWORD boundary. if( unalignedBytesA != 0 ) { LPWSTR ptr1 = (LPWSTR)strAChars; LPWSTR ptr2 = (LPWSTR)strBChars; if (*ptr1 != *ptr2) { temp = ((int)ToUpperXP(*ptr1) - (int)ToUpperXP(*ptr2)); if( temp != 0) { return temp; } } --count; strAChars = (DWORD *)(ptr1 + 1); strBChars = (DWORD *)(ptr2 + 1); } // Loop comparing a DWORD at a time. while (count >= 2) { _ASSERTE(IS_ALIGNED((size_t)strAChars, 4) && IS_ALIGNED((size_t)strBChars, 4)); if ((*strAChars - *strBChars) != 0) { LPCWSTR ptr1 = (WCHAR*)strAChars; LPCWSTR ptr2 = (WCHAR*)strBChars; if (*ptr1 != *ptr2) { temp = ((int)ToUpperXP(*ptr1) - (int)ToUpperXP(*ptr2)); } if (temp != 0) { return (temp); } temp = (int)ToUpperXP(*(ptr1+1)) - (int)ToUpperXP(*(ptr2+1)); if (temp != 0) { return (temp); } } ++strBChars; ++strAChars; count -= 2; } } // We can exit the loop when we see two different DWORDs and one of them contains surrogate // or they are equal after case conversion. // We can also exit the loop when there is no or only one character left. if( count == 0) { return 0; } // we need to handle one special case here. Say we have two strings like: // A HS1 LS1 HS2 LS2 or A HS1 LS1 // A HS1 LS2 HS2 LS2 or A HS1 NS // we need to go back a char to decide the order LPCWSTR pwStrB = (LPWSTR)strBChars; LPCWSTR pwStrA = (LPWSTR)strAChars; temp = 0; while ((count--) > 0) { WCHAR charA = *pwStrA++; WCHAR charB = *pwStrB++; if( charA != charB) { charA = ToUpperXP(charA); charB = ToUpperXP(charB); temp = (int)charA - (int)charB; if (temp != 0) { return (temp); } } } return 0; } int CompareStringOrdinal(__in_ecount(cchCount1) LPCWSTR string1, __in int cchCount1, __in_ecount(cchCount2) LPCWSTR string2, __in int cchCount2, __in BOOL bIgnoreCase) { // This should only happen for IgnoreCase == true. The rest are hard coded if (!bIgnoreCase) { return 0; } DWORD *strAChars, *strBChars; strAChars = (DWORD*)string1; strBChars = (DWORD*)string2; // If the strings are the same length, compare exactly the right # of chars. // If they are different, compare the shortest # + 1 (the '\0'). int count = cchCount1; if( count > cchCount2) count = cchCount2; INT32 ret = CompareOrdinalIgnoreCaseHelper(strAChars, strBChars, count); if( ret == 0) { ret = cchCount1 - cchCount2; } if (ret > 0) { return CSTR_GREATER_THAN; } if (ret < 0) { return CSTR_LESS_THAN; } return CSTR_EQUAL; } inline bool HasOnlyUppercaseOrLowercaseFlag(__in DWORD flags) { if(((flags & (LCMAP_UPPERCASE | LCMAP_LOWERCASE))== 0) || MORE_THAN_ONE(flags, LCMAP_UPPERCASE) || MORE_THAN_ONE(flags, LCMAP_LOWERCASE)) { return false; } return true; } int TurkicICasing( __in DWORD flags, __in_ecount(cchSrc) LPCWSTR source, __in int cchSrc, __out_ecount(cchDest) LPWSTR destination, __in int cchDest) { _ASSERTE(source != NULL); _ASSERTE(cchSrc > 0); _ASSERTE(destination != NULL); _ASSERTE(cchSrc == cchDest); _ASSERTE(HasOnlyUppercaseOrLowercaseFlag(flags)); const WORD * table; WCHAR dottedI, mappedDottedI; WCHAR dotlessI, mappedDotlessI; if ((flags & LCMAP_UPPERCASE) != 0) { table = s_pUppercaseIndexTableLinguisticXP; dottedI = LATIN_LOWERCASE_I_DOT_ABOVE; mappedDottedI = TURKISH_CAPITAL_I_DOT_ABOVE; dotlessI = TURKISH_LOWERCASE_DOTLESS_I; mappedDotlessI = LATIN_CAPITAL_DOTLESS_I; } else { table = s_pLowercaseIndexTableLinguisticXP; dottedI = TURKISH_CAPITAL_I_DOT_ABOVE; mappedDottedI = LATIN_LOWERCASE_I_DOT_ABOVE; dotlessI = LATIN_CAPITAL_DOTLESS_I; mappedDotlessI = TURKISH_LOWERCASE_DOTLESS_I; } for (int i = 0; i < cchSrc && i < cchDest; ++i) { if (source[i] == dottedI) { destination[i] = mappedDottedI; } else if (source[i] == dotlessI) { destination[i] = mappedDotlessI; } else { destination[i] = MapCase(table, source[i]); } } return cchSrc; } int DefaultLinguisticCasing( __in DWORD flags, __in_ecount(cchSrc) LPCWSTR source, __in int cchSrc, __out_ecount(cchDest) LPWSTR destination, __in int cchDest) { _ASSERTE(source != NULL); _ASSERTE(cchSrc > 0); _ASSERTE(destination != NULL); _ASSERTE(cchSrc == cchDest); _ASSERTE(HasOnlyUppercaseOrLowercaseFlag(flags)); const WORD * table; if ((flags & LCMAP_UPPERCASE) != 0) { table = s_pUppercaseIndexTableLinguisticXP; } else { table = s_pLowercaseIndexTableLinguisticXP; } for (int i = 0; i < cchSrc && i < cchDest; ++i) { destination[i] = MapCase(table, source[i]); } return cchSrc; } __success(return != 0) int LinguisticCaseString(__in LCID lcid,__in DWORD flags, __in_ecount(cchSrc) const WCHAR * source, __in int cchSrc, __out_ecount_opt(cchDest) WCHAR * destination, __in int cchDest) { _ASSERTE(lcid != 0); if ( (cchSrc == 0) || (cchDest < 0) || (source == NULL) || ((cchDest != 0) && (destination == NULL)) ) { SetLastError(ERROR_INVALID_PARAMETER); return (0); } if(!HasOnlyUppercaseOrLowercaseFlag(flags)) { SetLastError(ERROR_INVALID_FLAGS); return (0); } if(cchSrc < 0) { cchSrc = (int)wcslen(source); } if(destination == NULL) { return cchSrc; } if(IsTurkicILcid(lcid)) { return TurkicICasing(flags, source, cchSrc, destination, cchDest); } else { return DefaultLinguisticCasing(flags, source, cchSrc, destination, cchDest); } } #ifdef _MSC_VER // Get rid of size OACR requirement. #pragma warning(push) #pragma warning(disable:25057) #endif int LCMapStringEx(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags, __in_ecount(cchSrc) LPCWSTR lpSrcStr, __in int cchSrc, __out_xcount_opt(cchDest) LPWSTR lpDestStr, __in int cchDest, __in_opt LPNLSVERSIONINFO lpVersionInformation, __in_opt LPVOID lpReserved, __in_opt LPARAM lParam) #ifdef _MSC_VER #pragma warning(pop) #endif { LCID lcid=NewApis::LocaleNameToLCID(lpLocaleName,0); if (lcid == 0) return 0; // Need to remap flags to get rid of Vista flags and replace with downlevel flags // (not used at this moment) if ((dwMapFlags & LINGUISTIC_IGNOREDIACRITIC)!=0) { dwMapFlags -= LINGUISTIC_IGNOREDIACRITIC; dwMapFlags |= NORM_IGNORENONSPACE; } if ((dwMapFlags & LINGUISTIC_IGNORECASE)!=0) { dwMapFlags -= LINGUISTIC_IGNORECASE; dwMapFlags |= NORM_IGNORECASE; } dwMapFlags &= (~NORM_LINGUISTIC_CASING); // START WORK_AROUND_WIN2K3_LCMAPSTRING_BUG if((dwMapFlags & LCMAP_LINGUISTIC_CASING) != 0 && (dwMapFlags & (LCMAP_UPPERCASE | LCMAP_LOWERCASE)) != 0) { dwMapFlags &= (~LCMAP_LINGUISTIC_CASING); return LinguisticCaseString(lcid, dwMapFlags, lpSrcStr, cchSrc, lpDestStr, cchDest); } // END WORK_AROUND_WIN2K3_LCMAPSTRING_BUG return ::LCMapStringW(lcid,dwMapFlags, lpSrcStr, cchSrc, lpDestStr, cchDest); } int FindNLSStringEx(__in LPCWSTR lpLocaleName, __in DWORD dwFindNLSStringFlags, __in_ecount(cchSource) LPCWSTR lpStringSource, __in int cchSource, __in_ecount(cchValue) LPCWSTR lpStringValue, __in int cchValue, __out_opt LPINT pcchFound, __in_opt LPNLSVERSIONINFO lpVersionInformation, __in_opt LPVOID lpReserved, __in_opt LPARAM lParam) { int retValue = -1; if (lpLocaleName == NULL || lpStringSource == NULL || lpStringValue == NULL) { return retValue; } if (dwFindNLSStringFlags & (FIND_ENDSWITH | FIND_FROMEND)) { retValue = NewApis::LastIndexOfString(lpLocaleName, lpStringSource, cchSource, lpStringValue, cchValue, (int) dwFindNLSStringFlags & FIND_NLS_STRING_FLAGS_NEGATION, dwFindNLSStringFlags & FIND_ENDSWITH); } else { retValue = NewApis::IndexOfString(lpLocaleName, lpStringSource, cchSource, lpStringValue, cchValue, (int) dwFindNLSStringFlags & FIND_NLS_STRING_FLAGS_NEGATION, dwFindNLSStringFlags & FIND_STARTSWITH); } return retValue; } // Mac and Windows <= Windows XP // Note: "Function" is unused, always handles sorting for now // Note: "dwFlags" is unused, we don't have flags for now // Note: "lpVersionInfo" is unused, we always presume the current version BOOL IsNLSDefinedString(NLS_FUNCTION Function, DWORD dwFlags, LPNLSVERSIONINFOEX lpVersionInfo, LPCWSTR pString, int nStringLen ) { // Ported downlevel code from comnlsinfo.cpp CQuickBytes buffer; buffer.AllocThrows(16); int ich = 0; while(ich < nStringLen) { WCHAR wch = pString[ich]; int dwBufSize=NewApis::LCMapStringEx(W("en-US"),LCMAP_SORTKEY|SORT_STRINGSORT,pString+ich,1,(LPWSTR)buffer.Ptr(), (int)(buffer.Size()/sizeof(WCHAR)),NULL,NULL,0); if (dwBufSize == 0) { buffer.AllocThrows(buffer.Size()*2); continue; // try again } if (LPBYTE(buffer.Ptr())[0] == 0x1) // no weight { // // Check for the NULL case and formatting characters case. Not // defined but valid. // switch(wch) { case 0x0000: // NULL case 0x0640: // TATWEEL case 0x180b: // MONGOLIAN FVS 1 case 0x180c: // MONGOLIAN FVS 2 case 0x180d: // MONGOLIAN FVS 3 case 0x180e: // MONGOLIAN VOWEL SEPERATOR case 0x200c: // ZWNJ case 0x200d: // ZWJ case 0x200e: // LRM case 0x200f: // RLM case 0x202a: // LRE case 0x202b: // RLE case 0x202c: // PDF case 0x202d: // LRO case 0x202e: // RLO case 0x206a: // ISS case 0x206b: // SSS case 0x206c: // IAFS case 0x206d: // AAFS case 0x206e: // NATIONAL DS case 0x206f: // NOMINAL DS case 0xfeff: // ZWNBSP case 0xfff9: // IAA case 0xfffa: // IAS case 0xfffb: // IAT case 0xfffc: // ORC case 0xfffd: // RC ich++; continue; default: return (FALSE); } } // // Eliminate Private Use characters. They are defined but cannot be considered // valid because AD-style apps should not use them in identifiers. // if ((wch >= PRIVATE_USE_BEGIN) && (wch <= PRIVATE_USE_END)) { return (FALSE); } // // Eliminate invalid surogates pairs or single surrogates. Basically, all invalid // high surrogates have aleady been filtered (above) since they are unsortable. // All that is left is to check for standalone low surrogates and valid high // surrogates without corresponding low surrogates. // if ((wch >= LOW_SURROGATE_START) && (wch <= LOW_SURROGATE_END)) { // Leading low surrogate return (FALSE); } else if ((wch >= HIGH_SURROGATE_START) && (wch <= HIGH_SURROGATE_END)) { // Leading high surrogate if ( ((ich + 1) < nStringLen) && // Surrogates not the last character (pString[ich+1] >= LOW_SURROGATE_START) && (pString[ich+1] <= LOW_SURROGATE_END)) // Low surrogate { // Valid surrogates pair, High followed by a low surrogate. Skip the pair! ich++; } else { // High surrogate without low surrogate, so exit. return (FALSE); } } ich++; } return (TRUE); } int GetCalendarInfoEx(__in LPCWSTR lpLocaleName, __in CALID Calendar, __in_opt LPCWSTR pReserved, __in CALTYPE CalType, __out_ecount_opt(cchData) LPWSTR lpCalData, __in int cchData, __out_opt LPDWORD lpValue) { _ASSERTE((lpCalData == NULL && cchData == 0) || (lpCalData != NULL && cchData > 0)); if ((CalType & CAL_RETURN_NUMBER)) { // If CAL_RETURN_NUMBER, lpValue must be non-null and lpCalData must be null _ASSERTE((lpValue != NULL) && (lpCalData == NULL)); } LCID lcid=NewApis::LocaleNameToLCID(lpLocaleName,0); // zh-HK has English month/day names in older OS's, so we need to fix that (pre-Vista OS's) if (lcid == 0x0c04 && Calendar == CAL_GREGORIAN && ((CalType >= CAL_SDAYNAME1 && CalType <= CAL_SABBREVMONTHNAME13) || (CalType >= CAL_SSHORTESTDAYNAME1 && CalType <= CAL_SSHORTESTDAYNAME7))) { // zh-TW has the English names for those month/day name values lcid = 0x0404; } if (lcid == 0) return 0; return ::GetCalendarInfoW(lcid, Calendar, CalType, lpCalData, cchData, lpValue ); } namespace LegacyCallbacks { LPARAM lDateFormatParam = NULL; DATEFMT_ENUMPROCEXEX realDateCallback = NULL; BOOL CALLBACK EnumDateFormatsProcWrapper(__in_z LPTSTR lpDateFormatString, __in CALID Calendar) { if (realDateCallback != NULL && lDateFormatParam != NULL) return realDateCallback(lpDateFormatString, Calendar, lDateFormatParam); // Didn't have the globals, fail return false; }; BOOL EnumDateFormatsExEx(DATEFMT_ENUMPROCEXEX lpDateFmtEnumProcExEx, LPCWSTR lpLocaleName, DWORD dwFlags, LPARAM lParam) { LCID lcid=NewApis::LocaleNameToLCID(lpLocaleName,0); if (lcid == 0) return 0; DelayCreateCriticalSection(); BOOL ret = false; { CRITSEC_Holder sCrstHolder(g_pDownlevelNlsCrst); // Store our real callback and lParam lDateFormatParam = lParam; realDateCallback = lpDateFmtEnumProcExEx; ret = EnumDateFormatsExW(EnumDateFormatsProcWrapper, lcid, dwFlags); } return ret; }; LPARAM lTimeFormatParam = NULL; TIMEFMT_ENUMPROCEX realTimeCallback = NULL; BOOL CALLBACK EnumTimeFormatsProcWrapper(__in_z LPTSTR lpTimeFormatString) { if (realTimeCallback != NULL && lTimeFormatParam != NULL) return realTimeCallback(lpTimeFormatString, lTimeFormatParam); // Didn't have the globals, fail return false; }; BOOL EnumTimeFormatsEx(TIMEFMT_ENUMPROCEX lpTimeFmtEnumProcEx, LPCWSTR lpLocaleName, DWORD dwFlags, LPARAM lParam) { LCID lcid=NewApis::LocaleNameToLCID(lpLocaleName,0); if (lcid == 0) return 0; DelayCreateCriticalSection(); BOOL ret = false; { CRITSEC_Holder sCrstHolder(g_pDownlevelNlsCrst); // Store our real callback and lParam lTimeFormatParam = lParam; realTimeCallback = lpTimeFmtEnumProcEx; ret = EnumTimeFormatsW(EnumTimeFormatsProcWrapper, lcid, dwFlags); } return ret; }; LPARAM lCalendarInfoParam = NULL; CALINFO_ENUMPROCEXEX realCalendarInfoCallback = NULL; BOOL CALLBACK EnumCalendarInfoProcWrapper(__in_z LPTSTR lpCalendarInfoString, __in CALID Calendar) { if (realCalendarInfoCallback != NULL && lCalendarInfoParam != NULL) return realCalendarInfoCallback(lpCalendarInfoString, Calendar, NULL, lCalendarInfoParam); // Didn't have the globals, fail return false; }; BOOL EnumCalendarInfoExEx(CALINFO_ENUMPROCEXEX pCalInfoEnumProcExEx, LPCWSTR lpLocaleName, CALID Calendar, LPCWSTR lpReserved, CALTYPE CalType, LPARAM lParam) { LCID lcid=NewApis::LocaleNameToLCID(lpLocaleName,0); if (lcid == 0) return 0; DelayCreateCriticalSection(); BOOL ret = false; { CRITSEC_Holder sCrstHolder(g_pDownlevelNlsCrst); // Store our real callback and lParam lCalendarInfoParam = lParam; realCalendarInfoCallback = pCalInfoEnumProcExEx; ret = EnumCalendarInfoExW(EnumCalendarInfoProcWrapper, lcid, Calendar, CalType); } return ret; }; } // This is where we fudge data the OS doesn't know (even on Vista) namespace UplevelFallback { // Some properties are unknown to downlevel OS's (pre windows 7), so synthesize them // Pass in LCID if calling from the downlevel APIs. // Note that Vista gets here for neutrals as well as specifics // The only neutral Vista properties we support are SNAME, SPARENT & INEUTRAL (which assumes its a locale) // if lpLCData is NULL, caller wants required size to be returned. So we check before assigning and return // buffer size. int GetLocaleInfoEx(__in LPCWSTR lpLocaleName, __in LCID lcid, __in LCTYPE LCType, __out_ecount_opt(cchData) LPWSTR lpLCData, __in int cchData) { _ASSERTE((lpLCData == NULL && cchData == 0) || (lpLCData != NULL && cchData > 0)); LPCWSTR useString = NULL; WCHAR buffer[80]; // We don't differentiate user overrides for these types LCType &= ~LOCALE_NOUSEROVERRIDE; // TODO: NLS Arrowhead -Find better ways of handling these properties: // Right now we'll just fill them in with constant data switch (LCType) { case LOCALE_SPERCENT: // Percent symbol useString = W("%"); break; case LOCALE_IPOSITIVEPERCENT | LOCALE_RETURN_NUMBER: // Positive percent format if (lpLCData) { *((DWORD*)lpLCData) = 0; } return 2; case LOCALE_INEGATIVEPERCENT | LOCALE_RETURN_NUMBER: // Negative percent format if (lpLCData) { *((DWORD*)lpLCData) = 0; } return 2; case LOCALE_SPERMILLE: // Per mille symbol useString = W("\x2030"); break; case LOCALE_SSHORTTIME: // Short time format (default) // CultureData synthesizes short time from long time case LOCALE_SENGLISHDISPLAYNAME: // English display name (ie: Fijiian (Fiji)) case LOCALE_SNATIVEDISPLAYNAME: // Native dispaly name (ie: Deutsch (Deutschland)) // native & english names are built more easily in managed code //case LOCALE_SMONTHDAY: // month/day format //we get month/day patterns from the calendar data. This would be override, but that's not assigned // TODO: NLS Arrowhead - in windows 7 if we add overrides break; case LOCALE_IREADINGLAYOUT | LOCALE_RETURN_NUMBER: // Is Right To Left? // Use the RTL bit in the font signature LOCALESIGNATURE LocSig; if (NewApis::GetLocaleInfoEx( lpLocaleName, LOCALE_FONTSIGNATURE, (LPWSTR)&LocSig, sizeof(LocSig) / sizeof(WCHAR) ) == sizeof(LocSig) / sizeof(WCHAR)) { // Got the locale signature information, get the isrtl bit 123 to see if its RTL. if (lpLCData) { *((DWORD*)lpLCData) = ((LocSig.lsUsb[3] & 0x0800) != 0) ? 1 : 0; } return 2; } // Failed, just return 0 return 0; case LOCALE_SNAME: // If we don't have an LCID, find one, this is < Vista or neutrals if (lcid == 0) lcid = NewApis::LocaleNameToLCID(lpLocaleName,0); // Make sure windows recognizes this LCID, or that its zh-Hant, sr, or bs if (GetLocaleInfoW(lcid, LOCALE_IDIGITS | LOCALE_RETURN_NUMBER, NULL, 0) == 0 && lcid != 0x7c04 && lcid != 0x7c1a && lcid != 0x781a) { // Not a real locale, fail, don't fail for neutrals zh-Hant, sr, or bs. return 0; } // Convert name to LCID (so we get pretty name) if (lcid != 0) return NewApis::LCIDToLocaleName(lcid, lpLCData, cchData, 0); else return 0; case LOCALE_INEUTRAL | LOCALE_RETURN_NUMBER: // If its XP/Win2K3 or lower, then the lcid can tell us if (lcid != 0) { if (lpLCData) *((DWORD*)lpLCData) = ((lcid < 0x0400 || lcid > 0x7000) && (lcid < 0x10000)) ? 1 : 0; return 2; } // Vista or Win2K8 fail for neutrals // Note this assumes that neutral or not it is a valid locale. if (NewApis::GetLocaleInfoEx(lpLocaleName, LOCALE_IDIGITS | LOCALE_RETURN_NUMBER, NULL, 0) == 0) { // Failed, its a neutral // Note, we assumed it is a valid locale. (Caller lookind in our name/lcid tables undoubtedly) if (lpLCData) *((DWORD*)lpLCData) = 1; } else { // Succeeded, its not neutral if (lpLCData) *((DWORD*)lpLCData) = 0; } // Return "success" return 2; case LOCALE_SPARENT: // Should only get here for neutrals or downlevel // Downlevel only needs work if its not neutral if (lcid != 0) { // Downlevel // If its a neutral LCID then its "" Invariant if ((lcid < 0x0400 || lcid > 0x7000) && (lcid < 0x10000)) { useString = W(""); } else { // Parent is same as LCID & 0x3ff, except for a few cases switch (lcid) { case 0x0404: // zh-TW case 0x0c04: // zh-HK case 0x1404: // zh-MO lcid = 0x7c04; // zh-Hant break; case 0x081a: // sr-Latn-CS case 0x0c1a: // sr-Cryl-CS lcid = 0x7c1a; // sr break; case 0x201a: // bs-Cyrl-BA case 0x141a: // bs-Latn-BA lcid = 0x781a; // bs break; default: lcid &= 0x03ff; break; } // Get the name from LCIDToName if (NewApis::LCIDToLocaleName(lcid, buffer, NumItems(buffer), 0)) { useString = buffer; } } } else { // Neutral on Vista / W2K8. Always "" Invariant // or neutral LCID useString = W(""); } break; case LOCALE_SNAN: useString = W("NaN"); break; case LOCALE_SPOSINFINITY: useString = W("Infinity"); break; case LOCALE_SNEGINFINITY: useString = W("-Infinity"); break; } // Return number already returned, so we should have a string, else its unknown if (useString == NULL) return 0; // Copy our string to the output & return int size = (int)(wcslen(useString) + 1); // if cchData is 0, then caller wants us to return size if (size > cchData && cchData != 0) return 0; if (lpLCData) { memcpy(lpLCData, useString, size * sizeof(WCHAR)); } return size; } LPCWSTR const arabicSuperShortDayNames[] = { W("\x0646"), // Day name for Monday W("\x062b"), W("\x0631"), W("\x062e"), W("\x062c"), W("\x0633"), W("\x062d") // Day name for Sunday }; LPCWSTR const chineseSuperShortDayNames[] = { W("\x4e00"), // Day name for Monday W("\x4e8c"), W("\x4e09"), W("\x56db"), W("\x4e94"), W("\x516d"), W("\x65e5") // Day name for Sunday }; LPCWSTR const hebrewSuperShortDayNames[] = { W("\x05d1"), // Day name for Monday W("\x05d2"), W("\x05d3"), W("\x05d4"), W("\x05d5"), W("\x05e9"), W("\x05d0") // Day name for Sunday }; LPCWSTR const mongolianSuperShortDayNames[] = { W("\x0414\x0430"), // Day name for Monday W("\x041c\x044f"), W("\x041b\x0445"), W("\x041f\x04af"), W("\x0411\x0430"), W("\x0411\x044f"), W("\x041d\x044f") // Day name for Sunday }; int GetCalendarInfoEx(__in_opt LPCWSTR lpLocaleName, __in CALID Calendar, __in_opt LPCWSTR pReserved, __in CALTYPE CalType, __out_ecount_opt(cchData) LPWSTR lpCalData, __in int cchData, __out_opt LPDWORD lpValue) { _ASSERTE((lpCalData == NULL && cchData == 0) || (lpCalData != NULL && cchData > 0)); if ((CalType & CAL_RETURN_NUMBER)) { // If CAL_RETURN_NUMBER, lpValue must be non-null and lpCalData must be null _ASSERTE((lpValue != NULL) && (lpCalData == NULL)); } // We don't differentiate user overrides for these types CalType &= ~CAL_NOUSEROVERRIDE; LCID lcid=NewApis::LocaleNameToLCID(lpLocaleName,0); int ret = 0; LPCWSTR pUseString = W(""); LPCWSTR const *pDays = NULL; // // The requested info is a string. // // NOTE: Genitive names will skip this and just return empty strings // not much we can do for those. switch (CalType) { case CAL_SMONTHDAY: // Special cases for older locales with names that can't be truncated pUseString = W("MMMM dd"); // Special case for CJK locales if ((lcid & 0x3ff) == 0x11 || // Japanese (lcid & 0x3ff) == 0x04) // Chinese { // Japanese & Chinese pUseString = W("M'\x6708'd'\x65e5'"); } else if ((lcid & 0x3ff) == 0x012) // Korean { // Korean pUseString = W("M'\xc6d4' d'\xc77c'"); } break; case CAL_SSHORTESTDAYNAME1: case CAL_SSHORTESTDAYNAME2: case CAL_SSHORTESTDAYNAME3: case CAL_SSHORTESTDAYNAME4: case CAL_SSHORTESTDAYNAME5: case CAL_SSHORTESTDAYNAME6: case CAL_SSHORTESTDAYNAME7: // Special cases for older locales with names that can't be truncated // Arabic if (((lcid & 0x3ff) == 0x01) && (Calendar == CAL_GREGORIAN || Calendar == CAL_HIJRI || Calendar == CAL_UMALQURA)) pDays = arabicSuperShortDayNames; // Chinese if (((lcid & 0x3ff) == 0x04) && (Calendar == CAL_GREGORIAN || Calendar == CAL_TAIWAN)) pDays = chineseSuperShortDayNames; // Hebrew if (((lcid & 0x3ff) == 0x0d) && (Calendar == CAL_GREGORIAN || Calendar == CAL_HEBREW)) pDays = hebrewSuperShortDayNames; // Mongolian if ((lcid & 0x3ff) == 0x50) pDays = mongolianSuperShortDayNames; if (pDays) { // If we have a special case string then use that pUseString = pDays[CalType - CAL_SSHORTESTDAYNAME1]; } else { // If lpCalData is null they just want the size // NOTE: We actually always know the size so we never ask. if (lpCalData == NULL) { ret = 5; } else { ret = NewApis::GetCalendarInfoEx(lpLocaleName, Calendar, pReserved, CAL_SABBREVDAYNAME1 + (CalType - CAL_SSHORTESTDAYNAME1), lpCalData, cchData, lpValue); if (ret > 0) { if (ret > 3) { // Just get the first two character, and NULL-terminate it. PREFIX_ASSUME(3 < cchData); // we can assume this; otherwise call would have failed lpCalData[3] = W('\0'); ret = 3; } } } // Done return ret; } break; default: // // Not a CALTYPE that this function provides. Just returns 0. // return 0; break; } // If we have a special case string, copy to the output & return ret = (int)(wcslen(pUseString) + 1); if (lpCalData && cchData >= ret) { // If they wanted string (not just count), then return it memcpy(lpCalData, pUseString, ret * sizeof(WCHAR)); } return ret; } // Handle the to titlecaseflag int LCMapStringEx(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags, __in_ecount(cchSrc) LPCWSTR lpSrcStr, __in int cchSrc, __out_ecount_opt(cchDest) LPWSTR lpDestStr, __in int cchDest, __in_opt LPNLSVERSIONINFO lpVersionInformation, __in_opt LPVOID lpReserved, __in_opt LPARAM lParam) { // We only know about the title case flag... if (dwMapFlags != LCMAP_TITLECASE) { return 0; } // Should be unused, we'll just workaround it to upper case in case there's a real problem // Just call NewAPIs with the upper case flag return NewApis::LCMapStringEx(lpLocaleName, LCMAP_UPPERCASE, lpSrcStr, cchSrc, lpDestStr, cchDest, lpVersionInformation, lpReserved, lParam); } } static int __cdecl compareLcidToLCIDEntry ( const void *key, const void *value) { LCID lcid=*((LCID*)key); LCIDEntry* entry=(LCIDEntry*)value; return lcid-entry->lcid; } int LCIDToLocaleName(__in LCID Locale, __out_ecount_opt(cchName) LPWSTR lpName, __in int cchName, __in DWORD dwFlags) { _ASSERTE((lpName == NULL && cchName == 0) || (lpName != NULL && cchName > 0)); if (Locale==LOCALE_INVARIANT) { if (lpName != NULL) { *lpName=0; } return 1; } LCIDEntry* entry=(LCIDEntry*)bsearch(&Locale,s_lcids,NumItems(s_lcids),sizeof(*s_lcids),compareLcidToLCIDEntry); if (entry == NULL) { //_ASSERTE(entry); return 0; } int length = 0; if (cchName > 0) { PREFIX_ASSUME(lpName != NULL); // checked above, but prefix can't figure it out wcscpy_s(lpName,cchName,entry->wszName); length = (int)wcslen(entry->wszName) + 1; } return length; } LCID LocaleNameToLCID(__in LPCWSTR lpName, __in DWORD dwFlags) { if (lpName == NULL || *lpName==0) { return LOCALE_INVARIANT; } // Try the last one first, just in case static int cachedEntry = 0; PREFIX_ASSUME(cachedEntry < NumItems(s_names)); int test = VolatileLoad(&cachedEntry); if (_wcsicmp(lpName, s_names[test].wszName) == 0) { _ASSERTE(s_names[test].lcid != 0); return s_names[test].lcid; } // Just do a binary lookup for the name int iBottom =0; int iTop = NumItems(s_names) - 1; while (iBottom <= iTop) { int iMiddle = (iBottom + iTop) / 2; int result = _wcsicmp(lpName, s_names[iMiddle].wszName); if (result == 0) { _ASSERTE(s_names[iMiddle].lcid != 0); cachedEntry = iMiddle; return s_names[iMiddle].lcid; } if (result < 0) { // pLocaleName was < s_names[iMiddle] iTop = iMiddle - 1; } else { // pLocaleName was > s_names[iMiddle] iBottom = iMiddle + 1; } } // Failed, return 0 return 0; } // Fallback for pre windows 7 machines int ResolveLocaleName(__in LPCWSTR lpNameToResolve, __in_ecount_opt(cchLocaleName) LPWSTR lpLocaleName, __in int cchLocaleName) { PWSTR pSpecific = NULL; int retVal = 0; // Doesn't matter for mac, for windows map the name to LCID, then ask for LOCALE_ILANGUAGE to map the // LCID to a specific (legacy GetLocaleInfo behavior), then map the LCID to a name LCID lcid = LocaleNameToLCID(lpNameToResolve, 0); DWORD specific; // Some neutrals have specific values that downlevel OS's can't provide easily: retVal = 2; switch (lcid) { case 0x0004: specific = 0x0804; break; // zh-Hans::zh-CN::0804 case 0x000a: specific = 0x0c0a; break; // es::es-ES::0c0a case 0x003c: specific = 0x083c; break; // ga::ga-IE::083c case 0x005d: specific = 0x085d; break; // iu::iu-Latn-CA:085d case 0x005f: specific = 0x085f; break; // tzm::tzm-Latn-DZ:085f case 0x703b: specific = 0x243b; break; // smn::smn-FI::243b case 0x743b: specific = 0x203b; break; // sms::sms-FI::203b case 0x7804: specific = 0x0804; break; // zh::zh-CN::0804 case 0x7814: specific = 0x0814; break; // nn::nn-NO::0814 case 0x781a: specific = 0x141a; break; // bs::bs-Latn-BA:141a case 0x783b: specific = 0x1c3b; break; // sma::sma-SE::1c3b case 0x7c04: specific = 0x0c04; break; // zh-Hant::zh-HK::0c04 case 0x7c1a: specific = 0x081a; break; // sr::sr-Latn-CS:081a (this changes in win7) case 0x7c2e: specific = 0x082e; break; // dsb::dsb-DE::082e case 0x7c3b: specific = 0x143b; break; // smj::smj-SE::143b default: // Note this won't call our Downlevel API with the undesired LOCALE_ILANGUAGE retVal = GetLocaleInfoW(lcid, LOCALE_ILANGUAGE | LOCALE_RETURN_NUMBER, (LPWSTR)&specific, sizeof(specific)/sizeof(WCHAR)); break; } if (retVal > 0) { retVal = LCIDToLocaleName(specific, lpLocaleName, cchLocaleName, 0); if (retVal > 0) return retVal; } // If we didn't have a specific, then use the locale name passed in if (!pSpecific) { pSpecific = (PWSTR)lpNameToResolve; } // Copy our string to the output & return int size = (int)(wcslen(pSpecific) + 1); if (size > cchLocaleName) return 0; memcpy(lpLocaleName, pSpecific, size * sizeof(WCHAR)); return size; } BOOL GetThreadPreferredUILanguages(__in DWORD dwFlags, __out PULONG pulNumLanguages, __out_ecount_opt(*pcchLanguagesBuffer) PWSTR pwszLanguagesBuffer, __inout PULONG pcchLanguagesBuffer) { const WCHAR str[]=W("\0"); ULONG nBufSize=*pcchLanguagesBuffer; *pcchLanguagesBuffer=NumItems(str); if (nBufSize == 0 && pwszLanguagesBuffer == NULL) { return TRUE; } if(nBufSize