summaryrefslogtreecommitdiff
path: root/src/inc/newapis.h
blob: dfe77a500021894e46258bfc374f056ea0cde333 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
// 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:    newapis.h
//


//
//  Purpose:  functions that need to be emulated on downlevel platforms.
//
////////////////////////////////////////////////////////////////////////////

#ifndef MUI_LANGUAGE_NAME
#define MUI_LANGUAGE_NAME 0
#endif

#ifndef CALINFO_ENUMPROCEXEX
typedef BOOL (CALLBACK* CALINFO_ENUMPROCEXEX)(LPWSTR, CALID, LPWSTR, LPARAM);
#endif

#ifndef DATEFMT_ENUMPROCEXEX
typedef BOOL (CALLBACK* DATEFMT_ENUMPROCEXEX)(LPWSTR, CALID, LPARAM);
#endif

#ifndef TIMEFMT_ENUMPROCEX
typedef BOOL (CALLBACK* TIMEFMT_ENUMPROCEX)(LPWSTR, LPARAM);
#endif

#ifndef LOCALE_ENUMPROCEX
typedef BOOL (CALLBACK* LOCALE_ENUMPROCEX)(LPWSTR, DWORD, LPARAM);
#endif

#if !defined(LPNLSVERSIONINFOEX)
#define LPNLSVERSIONINFOEX LPNLSVERSIONINFO
#endif

#ifndef COMPARE_OPTIONS_ORDINAL
#define COMPARE_OPTIONS_ORDINAL            0x40000000
#endif

#ifndef LINGUISTIC_IGNORECASE
#define LINGUISTIC_IGNORECASE 0x00000010  // linguistically appropriate 'ignore case'
#endif

#ifndef FIND_STARTSWITH
#define FIND_STARTSWITH  0x00100000       // see if value is at the beginning of source
#endif

#ifndef FIND_ENDSWITH
#define FIND_ENDSWITH   0x00200000        // see if value is at the end of source
#endif

#ifndef FIND_FROMSTART
#define FIND_FROMSTART  0x00400000       // look for value in source, starting at the beginning
#endif

#ifndef FIND_FROMEND
#define FIND_FROMEND  0x00800000        // look for value in source, starting at the end
#endif

#ifndef NORM_LINGUISTIC_CASING
#define NORM_LINGUISTIC_CASING    0x08000000  // use linguistic rules for casing
#endif

#ifndef LCMAP_LINGUISTIC_CASING
#define LCMAP_LINGUISTIC_CASING   0x01000000  // use linguistic rules for casing
#endif

#ifndef LCMAP_TITLECASE
#define LCMAP_TITLECASE           0x00000300  // Title Case Letters
#endif

#ifndef LCMAP_SORTHANDLE
#define LCMAP_SORTHANDLE   0x20000000
#endif

#ifndef LCMAP_HASH
#define LCMAP_HASH   0x00040000
#endif

#ifndef LOCALE_ALL
#define LOCALE_ALL                0                     // enumerate all named based locales
#endif // LOCALE_ALL

#ifndef LOCALE_WINDOWS
#define LOCALE_WINDOWS            0x00000001            // shipped locales and/or replacements for them
#endif // LOCALE_WINDOWS

#ifndef LOCALE_SUPPLEMENTAL
#define LOCALE_SUPPLEMENTAL       0x00000002            // supplemental locales only
#endif // LOCALE_SUPPLEMENTAL

#ifndef LOCALE_ALTERNATE_SORTS
#define LOCALE_ALTERNATE_SORTS    0x00000004            // alternate sort locales
#endif // LOCALE_ALTERNATE_SORTS

#ifndef LOCALE_NEUTRALDATA
#define LOCALE_NEUTRALDATA        0x00000010            // Locales that are "neutral" (language only, region data is default)
#endif // LOCALE_NEUTRALDATA

#ifndef LOCALE_SPECIFICDATA
#define LOCALE_SPECIFICDATA       0x00000020            // Locales that contain language and region data
#endif // LOCALE_SPECIFICDATA

#ifndef LOCALE_INEUTRAL
#define LOCALE_INEUTRAL           0x00000071            // Returns 0 for specific cultures, 1 for neutral cultures.
#endif // LOCALE_INEUTRAL

#ifndef LOCALE_SSORTLOCALE
#define LOCALE_SSORTLOCALE        0x0000007b            // Name of locale to use for sorting/collation/casing behavior.
#endif // LOCALE_SSORTLOCALE

#ifndef LOCALE_RETURN_NUMBER
#define LOCALE_RETURN_NUMBER      0x20000000            // return number instead of string
#endif // LOCALE_RETURN_NUMBER

#ifndef LOCALE_ALLOW_NEUTRAL_NAMES
#define LOCALE_ALLOW_NEUTRAL_NAMES    0x08000000   //Flag to allow returning neutral names/lcids for name conversion
#endif // LOCALE_ALLOW_NEUTRAL_NAMES

#ifndef LOCALE_SNAME
#define LOCALE_SNAME                0x0000005c
#endif

#define FIND_NLS_STRING_FLAGS_NEGATION (~(FIND_STARTSWITH | FIND_ENDSWITH | FIND_FROMSTART | FIND_FROMEND))
#define CASING_BITS                    (NORM_LINGUISTIC_CASING | LINGUISTIC_IGNORECASE | NORM_IGNORECASE)


#ifndef __out_xcount_opt
#define __out_xcount_opt(var)
#endif

 // TODO: NLS Arrowhead -This isn't really right, custom locales could start with en- and have different sort behavior
 // IS_FAST_COMPARE_LOCALE is used to do the fast ordinal index of when having string of Lower Ansi codepoints
 // that less than 0x80. There are some locales that we cannot do optimization with, like Turkish and Azeri
 // because of Turkish I problem and Humgerian because of lower Ansi compressions.
#define IS_FAST_COMPARE_LOCALE(loc) \
    (wcsncmp(loc,W("tr-"),3)!=0 && wcsncmp(loc,W("az-"),3)!=0 && wcsncmp(loc,W("hu-"),3)!=0)

#define TURKISH_LOCALE_NAME             W("tr-TR")
#define AZERBAIJAN_LOCALE_NAME          W("az-Latn-AZ")
#define TURKISH_SORTING_LOCALE_NAME     W("tr-TR_turkic")
#define AZERBAIJAN_SORTING_LOCALE_NAME  W("az-Latn-AZ_turkic")

#define MUI_MERGE_SYSTEM_FALLBACK            0x10
#define MUI_MERGE_USER_FALLBACK              0x20


namespace NewApis
{
#if defined(FEATURE_CORESYSTEM)
    __inline bool IsWindows7Platform()
    {
        return true;
    }

    __inline bool IsVistaPlatform()
    {
        return false;
    }

    __inline BOOL IsZhTwSku()
    {
        return false;
    }

#else
    // Return true if we're on Windows 7 or up (ie: if we have neutral native support and sorting knows about versions)
    __inline bool IsWindows7Platform()
    {
        static int isRunningOnWindows7 = -1; // -1 notinitialized, 0 not running on Windows 7, other value means running on Windows 7

        if (isRunningOnWindows7 == -1)
        {
            OSVERSIONINFOEX sVer;
            ZeroMemory(&sVer, sizeof(OSVERSIONINFOEX));
            sVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
            sVer.dwMajorVersion = 6;
            sVer.dwMinorVersion = 1;
            sVer.dwPlatformId = VER_PLATFORM_WIN32_NT;

            DWORDLONG dwlConditionMask = 0;
            VER_SET_CONDITION(dwlConditionMask, CLR_VER_MAJORVERSION, VER_GREATER_EQUAL);
            VER_SET_CONDITION(dwlConditionMask, CLR_VER_MINORVERSION, VER_GREATER_EQUAL);
            VER_SET_CONDITION(dwlConditionMask, CLR_VER_PLATFORMID, VER_EQUAL);

            if(VerifyVersionInfo(&sVer, CLR_VER_MAJORVERSION|CLR_VER_MINORVERSION|CLR_VER_PLATFORMID, dwlConditionMask))
            {
                isRunningOnWindows7 = 1;
            }
            else
            {
                isRunningOnWindows7 = 0;
            }
        }

        return isRunningOnWindows7 == 1;
    }

    //
    // IsVistaPlatform return true if running on Vista and false if running on pre or post Vista
    //
    __inline BOOL IsVistaPlatform()
    {
        static int isRunningOnVista = -1; // -1 notinitialized, 0 not running on Vista, other value meanse running on Vista

        if (isRunningOnVista == -1)
        {
            OSVERSIONINFOEX sVer;
            ZeroMemory(&sVer, sizeof(OSVERSIONINFOEX));
            sVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
            sVer.dwMajorVersion = 6;
            sVer.dwMinorVersion = 0;
            sVer.dwPlatformId = VER_PLATFORM_WIN32_NT;

            DWORDLONG dwlConditionMask = 0;
            VER_SET_CONDITION(dwlConditionMask, CLR_VER_MAJORVERSION, VER_EQUAL);
            VER_SET_CONDITION(dwlConditionMask, CLR_VER_MINORVERSION, VER_EQUAL);
            VER_SET_CONDITION(dwlConditionMask, CLR_VER_PLATFORMID, VER_EQUAL);

            if(VerifyVersionInfo(&sVer, CLR_VER_MAJORVERSION|CLR_VER_MINORVERSION|CLR_VER_PLATFORMID, dwlConditionMask))
            {
                isRunningOnVista = 1;
            }
            else
            {
                isRunningOnVista = 0;
            }
        }

        return isRunningOnVista == 1;
    }


    __inline BOOL IsZhTwSku()
    {
        const INT32 LANGID_ZH_TW = 0x0404;
        LPCWSTR DEFAULT_REGION_NAME_0404 = W("\x53f0\x7063");

        if(::GetSystemDefaultUILanguage() == LANGID_ZH_TW)
        {
            WCHAR wszBuffer[32];
            int result = ::GetLocaleInfoW(LANGID_ZH_TW, LOCALE_SNATIVECTRYNAME, wszBuffer, 32);
            if (result)
            {
                if (wcsncmp(wszBuffer, DEFAULT_REGION_NAME_0404, 3) != 0)
                {
                    return true;
                } 
            }
        }
        return false;
    }
#endif // FEATURE_CORESYSTEM

    __inline BOOL NotLeakingFrameworkOnlyCultures(__in LPCWSTR lpLocaleName)
    {
        return wcscmp(lpLocaleName, W("zh-CHS")) != 0
            && wcscmp(lpLocaleName, W("zh-CHT")) != 0;
    }

    // System/user defaults
    __success(return == TRUE) BOOL
    GetUserPreferredUILanguages (__in DWORD dwFlags, __out PULONG pulNumLanguages, __out_ecount_opt(*pcchLanguagesBuffer) PWSTR pwszLanguagesBuffer, __in PULONG pcchLanguagesBuffer);

    __success(return > 0) int
    GetSystemDefaultLocaleName(__out_ecount(cchLocaleName) LPWSTR lpLocaleName, __in int cchLocaleName);

    __success(return != 0) int
    GetUserDefaultLocaleName(__out_ecount(cchLocaleName) LPWSTR lpLocaleName, __in int cchLocaleName);

    // Comparison functions (ala CompareInfo)
    int CompareStringEx(__in LPCWSTR lpLocaleName, __in DWORD dwCmpFlags, __in_ecount(cchCount1) LPCWSTR lpString1, __in int cchCount1, __in_ecount(cchCount2) LPCWSTR lpString2,
                                                __in int cchCount2, __in_opt LPNLSVERSIONINFO lpVersionInformation, __in_opt LPVOID lpReserved, __in_opt LPARAM lParam );

    int CompareStringOrdinal(__in_ecount(cchCount1) LPCWSTR lpString1, __in int cchCount1, __in_ecount(cchCount2) LPCWSTR lpString2, __in int cchCount2, __in BOOL bIgnoreCase);

    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 );

    LPWSTR GetLingusticLocaleName(__in LPWSTR pLocaleName, __in DWORD dwFlags);

    int IndexOfString(__in LPCWSTR lpLocaleName,
                      __in_ecount(cchCount1) LPCWSTR pString1,   // String to search in
                      __in int  cchCount1,                       // length of pString1
                      __in_ecount(cchCount2) LPCWSTR pString2,   // String we're looking for
                      __in int cchCount2,                        // length of pString2
                      __in DWORD dwFlags,                        // search flags
                      __in BOOL startWith);

    int LastIndexOfString(__in LPCWSTR lpLocaleName,
                            __in_ecount(cchCount1) LPCWSTR pString1,   // String to search in
                            __in int  cchCount1,                       // length of pString1
                            __in_ecount(cchCount2) LPCWSTR pString2,    // String we're looking for
                            __in int cchCount2,                        // length of pString2
                            __in DWORD dwFlags,
                            __in BOOL endWith);

    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);

    BOOL IsNLSDefinedString(__in NLS_FUNCTION Function, __in DWORD dwFlags, __in_opt LPNLSVERSIONINFOEX lpVersionInfo, __in LPCWSTR lpString, __in int cchStr );

    // Calendar and locale information
    __success(return != 0) 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 );

    __success(return != 0) int
    GetLocaleInfoEx (__in LPCWSTR lpLocaleName, __in LCTYPE LCType, __out_ecount_opt(cchData) LPWSTR lpLCData, __in int cchData);

    __success(return != 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);

    // Enumeration functions
    __success(return != 0) BOOL
    EnumDateFormatsExEx (DATEFMT_ENUMPROCEXEX lpDateFmtEnumProcExEx, LPCWSTR lpLocaleName, DWORD dwFlags, LPARAM lParam);
    __success(return != 0)
    BOOL EnumTimeFormatsEx(TIMEFMT_ENUMPROCEX lpTimeFmtEnumProcEx, LPCWSTR lpLocaleName,  DWORD dwFlags, LPARAM lParam);
    __success(return != 0)
    BOOL EnumCalendarInfoExEx(CALINFO_ENUMPROCEXEX pCalInfoEnumProcExEx, LPCWSTR lpLocaleName, CALID Calendar, CALTYPE CalType, LPARAM lParam);

    int LCIDToLocaleName(__in LCID Locale, __out_ecount_opt(cchName) LPWSTR lpName, __in int cchName, __in DWORD dwFlags);
    LCID LocaleNameToLCID(__in LPCWSTR lpName , __in DWORD dwFlags);

    int ResolveLocaleName(__in LPCWSTR lpNameToResolve, __in_ecount_opt(cchLocaleName) LPWSTR lpLocaleName, __in int cchLocaleName);

    __success(return == TRUE) BOOL
    GetThreadPreferredUILanguages(__in DWORD dwFlags,
                                       __out PULONG pulNumLanguages,
                                       __out_ecount_opt(*pcchLanguagesBuffer) PWSTR pwszLanguagesBuffer,
                                       __inout PULONG pcchLanguagesBuffer);

    BOOL WINAPI EnumSystemLocalesEx(__in LOCALE_ENUMPROCEX lpLocaleEnumProc,
                                    __in DWORD dwFlags,
                                    __in LPARAM lParam,
                                    __in_opt LPVOID lpReserved);

};