ReactOS 0.4.16-dev-1470-gfbd70c8
locale.c
Go to the documentation of this file.
1/*
2 * Locale support
3 *
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1998 David Lee Lambert
6 * Copyright 2000 Julio César Gázquez
7 * Copyright 2002 Alexandre Julliard for CodeWeavers
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include <k32.h>
25
26#define NDEBUG
27#include <debug.h>
29
30#include "lcformat_private.h"
31#ifdef __REACTOS__
32 #include "japanese.h"
33 #define strcasecmp _stricmp
34#endif
35
38
39#undef WINVER
40#define WINVER DLL_EXPORT_VERSION
41
42/* From winnls.h */
43#define LOCALE_NAME_USER_DEFAULT NULL
44
45#define REG_SZ 1
46extern int wine_fold_string(int flags, const WCHAR *src, int srclen, WCHAR *dst, int dstlen);
47extern int wine_get_sortkey(int flags, const WCHAR *src, int srclen, char *dst, int dstlen);
48extern int wine_compare_string(int flags, const WCHAR *str1, int len1, const WCHAR *str2, int len2);
49#ifdef __REACTOS__
51#else
53#endif
54#define NLSRC_OFFSET 5000 /* FIXME */
55
57
58#define LOCALE_LOCALEINFOFLAGSMASK (LOCALE_NOUSEROVERRIDE|LOCALE_USE_CP_ACP|\
59 LOCALE_RETURN_NUMBER|LOCALE_RETURN_GENITIVE_NAMES)
60#define MB_FLAGSMASK (MB_PRECOMPOSED|MB_COMPOSITE|MB_USEGLYPHCHARS|MB_ERR_INVALID_CHARS)
61#define WC_FLAGSMASK (WC_DISCARDNS|WC_SEPCHARS|WC_DEFAULTCHAR|WC_ERR_INVALID_CHARS|\
62 WC_COMPOSITECHECK|WC_NO_BEST_FIT_CHARS)
63
64/* current code pages */
65static const union cptable *ansi_cptable;
66static const union cptable *oem_cptable;
67static const union cptable *mac_cptable;
68static const union cptable *unix_cptable; /* NULL if UTF8 */
69
70static const WCHAR szLocaleKeyName[] = {
71 '\\','R','e','g','i','s','t','r','y','\\','M','a','c','h','i','n','e','\\','S','y','s','t','e','m','\\',
72 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
73 'C','o','n','t','r','o','l','\\','N','l','s','\\','L','o','c','a','l','e',0
74};
75
76static const WCHAR szLangGroupsKeyName[] = {
77 '\\','R','e','g','i','s','t','r','y','\\','M','a','c','h','i','n','e','\\','S','y','s','t','e','m','\\',
78 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
79 'C','o','n','t','r','o','l','\\','N','l','s','\\',
80 'L','a','n','g','u','a','g','e',' ','G','r','o','u','p','s',0
81};
82
83#if (WINVER >= 0x0600)
84/* Charset to codepage map, sorted by name. */
85static const struct charset_entry
86{
87 const char *charset_name;
89} charset_names[] =
90{
91 { "BIG5", 950 },
92 { "CP1250", 1250 },
93 { "CP1251", 1251 },
94 { "CP1252", 1252 },
95 { "CP1253", 1253 },
96 { "CP1254", 1254 },
97 { "CP1255", 1255 },
98 { "CP1256", 1256 },
99 { "CP1257", 1257 },
100 { "CP1258", 1258 },
101 { "CP932", 932 },
102 { "CP936", 936 },
103 { "CP949", 949 },
104 { "CP950", 950 },
105 { "EUCJP", 20932 },
106 { "GB2312", 936 },
107 { "IBM037", 37 },
108 { "IBM1026", 1026 },
109 { "IBM424", 424 },
110 { "IBM437", 437 },
111 { "IBM500", 500 },
112 { "IBM850", 850 },
113 { "IBM852", 852 },
114 { "IBM855", 855 },
115 { "IBM857", 857 },
116 { "IBM860", 860 },
117 { "IBM861", 861 },
118 { "IBM862", 862 },
119 { "IBM863", 863 },
120 { "IBM864", 864 },
121 { "IBM865", 865 },
122 { "IBM866", 866 },
123 { "IBM869", 869 },
124 { "IBM874", 874 },
125 { "IBM875", 875 },
126 { "ISO88591", 28591 },
127 { "ISO885910", 28600 },
128 { "ISO885913", 28603 },
129 { "ISO885914", 28604 },
130 { "ISO885915", 28605 },
131 { "ISO885916", 28606 },
132 { "ISO88592", 28592 },
133 { "ISO88593", 28593 },
134 { "ISO88594", 28594 },
135 { "ISO88595", 28595 },
136 { "ISO88596", 28596 },
137 { "ISO88597", 28597 },
138 { "ISO88598", 28598 },
139 { "ISO88599", 28599 },
140 { "KOI8R", 20866 },
141 { "KOI8U", 21866 },
142 { "UTF8", CP_UTF8 }
143};
144#endif
145
146
148{
149 WCHAR win_name[128]; /* Windows name ("en-US") */
150 WCHAR lang[128]; /* language ("en") (note: buffer contains the other strings too) */
151 WCHAR *country; /* country ("US") */
152 WCHAR *charset; /* charset ("UTF-8") for Unix format only */
153 WCHAR *script; /* script ("Latn") for Windows format only */
154 WCHAR *modifier; /* modifier or sort order */
155 LCID lcid; /* corresponding LCID */
156 int matches; /* number of elements matching LCID (0..4) */
157 UINT codepage; /* codepage corresponding to charset */
158};
159
160/* locale ids corresponding to the various Unix locale parameters */
170
171static const WCHAR iCalendarTypeW[] = {'i','C','a','l','e','n','d','a','r','T','y','p','e',0};
172static const WCHAR iCountryW[] = {'i','C','o','u','n','t','r','y',0};
173static const WCHAR iCurrDigitsW[] = {'i','C','u','r','r','D','i','g','i','t','s',0};
174static const WCHAR iCurrencyW[] = {'i','C','u','r','r','e','n','c','y',0};
175static const WCHAR iDateW[] = {'i','D','a','t','e',0};
176static const WCHAR iDigitsW[] = {'i','D','i','g','i','t','s',0};
177static const WCHAR iFirstDayOfWeekW[] = {'i','F','i','r','s','t','D','a','y','O','f','W','e','e','k',0};
178static const WCHAR iFirstWeekOfYearW[] = {'i','F','i','r','s','t','W','e','e','k','O','f','Y','e','a','r',0};
179static const WCHAR iLDateW[] = {'i','L','D','a','t','e',0};
180static const WCHAR iLZeroW[] = {'i','L','Z','e','r','o',0};
181static const WCHAR iMeasureW[] = {'i','M','e','a','s','u','r','e',0};
182static const WCHAR iNegCurrW[] = {'i','N','e','g','C','u','r','r',0};
183static const WCHAR iNegNumberW[] = {'i','N','e','g','N','u','m','b','e','r',0};
184static const WCHAR iPaperSizeW[] = {'i','P','a','p','e','r','S','i','z','e',0};
185static const WCHAR iTLZeroW[] = {'i','T','L','Z','e','r','o',0};
186static const WCHAR iTimePrefixW[] = {'i','T','i','m','e','P','r','e','f','i','x',0};
187static const WCHAR iTimeW[] = {'i','T','i','m','e',0};
188static const WCHAR s1159W[] = {'s','1','1','5','9',0};
189static const WCHAR s2359W[] = {'s','2','3','5','9',0};
190static const WCHAR sCountryW[] = {'s','C','o','u','n','t','r','y',0};
191static const WCHAR sCurrencyW[] = {'s','C','u','r','r','e','n','c','y',0};
192static const WCHAR sDateW[] = {'s','D','a','t','e',0};
193static const WCHAR sDecimalW[] = {'s','D','e','c','i','m','a','l',0};
194static const WCHAR sGroupingW[] = {'s','G','r','o','u','p','i','n','g',0};
195static const WCHAR sLanguageW[] = {'s','L','a','n','g','u','a','g','e',0};
196static const WCHAR sListW[] = {'s','L','i','s','t',0};
197static const WCHAR sLongDateW[] = {'s','L','o','n','g','D','a','t','e',0};
198static const WCHAR sMonDecimalSepW[] = {'s','M','o','n','D','e','c','i','m','a','l','S','e','p',0};
199static const WCHAR sMonGroupingW[] = {'s','M','o','n','G','r','o','u','p','i','n','g',0};
200static const WCHAR sMonThousandSepW[] = {'s','M','o','n','T','h','o','u','s','a','n','d','S','e','p',0};
201static const WCHAR sNativeDigitsW[] = {'s','N','a','t','i','v','e','D','i','g','i','t','s',0};
202static const WCHAR sNegativeSignW[] = {'s','N','e','g','a','t','i','v','e','S','i','g','n',0};
203static const WCHAR sPositiveSignW[] = {'s','P','o','s','i','t','i','v','e','S','i','g','n',0};
204static const WCHAR sShortDateW[] = {'s','S','h','o','r','t','D','a','t','e',0};
205static const WCHAR sThousandW[] = {'s','T','h','o','u','s','a','n','d',0};
206static const WCHAR sTimeFormatW[] = {'s','T','i','m','e','F','o','r','m','a','t',0};
207static const WCHAR sTimeW[] = {'s','T','i','m','e',0};
208static const WCHAR sYearMonthW[] = {'s','Y','e','a','r','M','o','n','t','h',0};
209static const WCHAR NumShapeW[] = {'N','u','m','s','h','a','p','e',0};
210
211static struct registry_value
212{
214 const WCHAR *name;
216} registry_values[] =
217{
228 { LOCALE_IPAPERSIZE, iPaperSizeW },
229 { LOCALE_ITIME, iTimeW },
230 { LOCALE_S1159, s1159W },
231 { LOCALE_S2359, s2359W },
233 { LOCALE_SDATE, sDateW },
236 { LOCALE_SLIST, sListW },
245 { LOCALE_STIME, sTimeW },
247 { LOCALE_SYEARMONTH, sYearMonthW },
248 /* The following are not listed under MSDN as supported,
249 * but seem to be used and also stored in the registry.
250 */
252 { LOCALE_IDATE, iDateW },
257 /* The following are used in XP and later */
258 { LOCALE_IDIGITSUBSTITUTION, NumShapeW },
262
263static RTL_CRITICAL_SECTION cache_section = { NULL, -1, 0, 0, 0, 0 };
264
265#ifndef __REACTOS__
266/* Copy Ascii string to Unicode without using codepages */
267static inline void strcpynAtoW( WCHAR *dst, const char *src, size_t n )
268{
269 while (n > 1 && *src)
270 {
271 *dst++ = (unsigned char)*src++;
272 n--;
273 }
274 if (n) *dst = 0;
275}
276
277static inline unsigned short get_table_entry( const unsigned short *table, WCHAR ch )
278{
279 return table[table[table[ch >> 8] + ((ch >> 4) & 0x0f)] + (ch & 0xf)];
280}
281#endif // !__REACTOS__
282
283/***********************************************************************
284 * get_lcid_codepage
285 *
286 * Retrieve the ANSI codepage for a given locale.
287 */
289{
290 UINT ret;
291 if (!GetLocaleInfoW( lcid, LOCALE_IDEFAULTANSICODEPAGE|LOCALE_RETURN_NUMBER, (WCHAR *)&ret,
292 sizeof(ret)/sizeof(WCHAR) )) ret = 0;
293 return ret;
294}
295
296#ifndef __REACTOS__
297/***********************************************************************
298 * get_codepage_table
299 *
300 * Find the table for a given codepage, handling CP_ACP etc. pseudo-codepages
301 */
302static const union cptable *get_codepage_table( unsigned int codepage )
303{
304 const union cptable *ret = NULL;
305
306 assert( ansi_cptable ); /* init must have been done already */
307
308 switch(codepage)
309 {
310 case CP_ACP:
311 return ansi_cptable;
312 case CP_OEMCP:
313 return oem_cptable;
314 case CP_MACCP:
315 return mac_cptable;
316 case CP_UTF7:
317 case CP_UTF8:
318 break;
319 case CP_THREAD_ACP:
320 if (NtCurrentTeb()->CurrentLocale == GetUserDefaultLCID()) return ansi_cptable;
321 codepage = get_lcid_codepage( NtCurrentTeb()->CurrentLocale );
322 if (!codepage) return ansi_cptable;
323 /* fall through */
324 default:
325 if (codepage == ansi_cptable->info.codepage) return ansi_cptable;
326 if (codepage == oem_cptable->info.codepage) return oem_cptable;
327 if (codepage == mac_cptable->info.codepage) return mac_cptable;
329 break;
330 }
331 return ret;
332}
333#endif // !__REACTOS__
334
335#if (WINVER >= 0x0600)
336#if 0 // See kernel32_vista
337/***********************************************************************
338 * charset_cmp (internal)
339 */
340static int charset_cmp( const void *name, const void *entry )
341{
342 const struct charset_entry *charset = entry;
343 return strcasecmp( name, charset->charset_name );
344}
345
346/***********************************************************************
347 * find_charset
348 */
349static UINT find_charset( const WCHAR *name )
350{
351 const struct charset_entry *entry;
352 char charset_name[16];
353 size_t i, j;
354
355 /* remove punctuation characters from charset name */
356 for (i = j = 0; name[i] && j < sizeof(charset_name)-1; i++)
357 if (isalnum((unsigned char)name[i])) charset_name[j++] = name[i];
358 charset_name[j] = 0;
359
360 entry = bsearch( charset_name, charset_names,
361 sizeof(charset_names)/sizeof(charset_names[0]),
362 sizeof(charset_names[0]), charset_cmp );
363 if (entry) return entry->codepage;
364 return 0;
365}
366#endif // 0 See kernel32_vista
367#endif // (WINVER >= 0x0600)
368
370{
371 switch (lang)
372 {
382 }
384 return lang;
385}
386
387#if (WINVER >= 0x0600)
388#if 0 // See kernel32_vista
389/***********************************************************************
390 * find_locale_id_callback
391 */
394{
395 struct locale_name *data = (struct locale_name *)lParam;
396 WCHAR buffer[128];
397 int matches = 0;
398 LCID lcid = MAKELCID( lang, SORT_DEFAULT ); /* FIXME: handle sort order */
399
400 if (PRIMARYLANGID(lang) == LANG_NEUTRAL) return TRUE; /* continue search */
401
402 /* first check exact name */
403 if (data->win_name[0] &&
405 buffer, sizeof(buffer)/sizeof(WCHAR) ))
406 {
407 if (!strcmpiW( data->win_name, buffer ))
408 {
409 matches = 4; /* everything matches */
410 goto done;
411 }
412 }
413
415 buffer, sizeof(buffer)/sizeof(WCHAR) ))
416 return TRUE;
417 if (strcmpiW( buffer, data->lang )) return TRUE;
418 matches++; /* language name matched */
419
420 if (data->script)
421 {
422 if (GetLocaleInfoW( lcid, LOCALE_SSCRIPTS | LOCALE_NOUSEROVERRIDE,
423 buffer, sizeof(buffer)/sizeof(WCHAR) ))
424 {
425 const WCHAR *p = buffer;
426 unsigned int len = strlenW( data->script );
427 while (*p)
428 {
429 if (!strncmpiW( p, data->script, len ) && (!p[len] || p[len] == ';')) break;
430 if (!(p = strchrW( p, ';'))) goto done;
431 p++;
432 }
433 if (!*p) goto done;
434 matches++; /* script matched */
435 }
436 }
437
438 if (data->country)
439 {
441 buffer, sizeof(buffer)/sizeof(WCHAR) ))
442 {
443 if (strcmpiW( buffer, data->country )) goto done;
444 matches++; /* country name matched */
445 }
446 }
447 else /* match default language */
448 {
449 LANGID def_lang = data->script ? lang : MAKELANGID( PRIMARYLANGID(lang), LANG_NEUTRAL );
450 if (lang == get_default_sublang( def_lang )) matches++;
451 }
452
453 if (data->codepage)
454 {
456 if (GetLocaleInfoW( lcid, LOCALE_IDEFAULTUNIXCODEPAGE | LOCALE_RETURN_NUMBER,
457 (LPWSTR)&unix_cp, sizeof(unix_cp)/sizeof(WCHAR) ))
458 {
459 if (unix_cp == data->codepage) matches++;
460 }
461 }
462
463 /* FIXME: check sort order */
464
465done:
466 if (matches > data->matches)
467 {
468 data->lcid = lcid;
469 data->matches = matches;
470 }
471 return (data->matches < 4); /* no need to continue for perfect match */
472}
473#endif // 0 See kernel32_vista
474
475/***********************************************************************
476 * parse_locale_name
477 *
478 * Parse a locale name into a struct locale_name, handling both Windows and Unix formats.
479 * Unix format is: lang[_country][.charset][@modifier]
480 * Windows format is: lang[-script][-country][_modifier]
481 */
482#if 0 // See kernel32_vista
483static void parse_locale_name( const WCHAR *str, struct locale_name *name )
484{
485 static const WCHAR sepW[] = {'-','_','.','@',0};
486 static const WCHAR winsepW[] = {'-','_',0};
487 static const WCHAR posixW[] = {'P','O','S','I','X',0};
488 static const WCHAR cW[] = {'C',0};
489 static const WCHAR latinW[] = {'l','a','t','i','n',0};
490 static const WCHAR latnW[] = {'-','L','a','t','n',0};
491 WCHAR *p;
492
493 TRACE("%s\n", debugstr_w(str));
494
495 name->country = name->charset = name->script = name->modifier = NULL;
497 name->matches = 0;
498 name->codepage = 0;
499 name->win_name[0] = 0;
500 lstrcpynW( name->lang, str, sizeof(name->lang)/sizeof(WCHAR) );
501
502 if (!*name->lang)
503 {
504 name->lcid = LOCALE_INVARIANT;
505 name->matches = 4;
506 return;
507 }
508
509 if (!(p = strpbrkW( name->lang, sepW )))
510 {
511 if (!strcmpW( name->lang, posixW ) || !strcmpW( name->lang, cW ))
512 {
513 name->matches = 4; /* perfect match for default English lcid */
514 return;
515 }
516 strcpyW( name->win_name, name->lang );
517 }
518 else if (*p == '-') /* Windows format */
519 {
520 strcpyW( name->win_name, name->lang );
521 *p++ = 0;
522 name->country = p;
523 if ((p = strpbrkW( p, winsepW )) && *p == '-')
524 {
525 *p++ = 0;
526 name->script = name->country;
527 name->country = p;
528 p = strpbrkW( p, winsepW );
529 }
530 if (p)
531 {
532 *p++ = 0;
533 name->modifier = p;
534 }
535 /* second value can be script or country, check length to resolve the ambiguity */
536 if (!name->script && strlenW( name->country ) == 4)
537 {
538 name->script = name->country;
539 name->country = NULL;
540 }
541 }
542 else /* Unix format */
543 {
544 if (*p == '_')
545 {
546 *p++ = 0;
547 name->country = p;
548 p = strpbrkW( p, sepW + 2 );
549 }
550 if (p && *p == '.')
551 {
552 *p++ = 0;
553 name->charset = p;
554 p = strchrW( p, '@' );
555 }
556 if (p)
557 {
558 *p++ = 0;
559 name->modifier = p;
560 }
561
562 if (name->charset)
563 name->codepage = find_charset( name->charset );
564
565 /* rebuild a Windows name if possible */
566
567 if (name->charset) goto done; /* can't specify charset in Windows format */
568 if (name->modifier && strcmpW( name->modifier, latinW ))
569 goto done; /* only Latn script supported for now */
570 strcpyW( name->win_name, name->lang );
571 if (name->modifier) strcatW( name->win_name, latnW );
572 if (name->country)
573 {
574 p = name->win_name + strlenW(name->win_name);
575 *p++ = '-';
576 strcpyW( p, name->country );
577 }
578 }
579done:
582}
583#endif // 0 See kernel32_vista
584#endif // (WINVER >= 0x0600)
585
586
587/***********************************************************************
588 * convert_default_lcid
589 *
590 * Get the default LCID to use for a given lctype in GetLocaleInfo.
591 */
593{
597 {
598 LCID default_id = 0;
599
600 switch(lctype & 0xffff)
601 {
602 case LOCALE_SSORTNAME:
603 default_id = lcid_LC_COLLATE;
604 break;
605
609 case LOCALE_IDEFAULTEBCDICCODEPAGE:
612 default_id = lcid_LC_CTYPE;
613 break;
614
616 case LOCALE_ICURRENCY:
618 case LOCALE_INEGCURR:
625 case LOCALE_SCURRENCY:
630 case LOCALE_SNATIVECURRNAME:
631 default_id = lcid_LC_MONETARY;
632 break;
633
634 case LOCALE_IDIGITS:
635 case LOCALE_IDIGITSUBSTITUTION:
636 case LOCALE_ILZERO:
638 case LOCALE_SDECIMAL:
639 case LOCALE_SGROUPING:
640 //case LOCALE_SNAN:
643 //case LOCALE_SNEGINFINITY:
644 //case LOCALE_SPOSINFINITY:
646 case LOCALE_STHOUSAND:
647 default_id = lcid_LC_NUMERIC;
648 break;
649
651 case LOCALE_ICENTURY:
652 case LOCALE_IDATE:
653 case LOCALE_IDAYLZERO:
656 case LOCALE_ILDATE:
657 case LOCALE_IMONLZERO:
659 case LOCALE_ITIME:
661 case LOCALE_ITLZERO:
662 case LOCALE_S1159:
663 case LOCALE_S2359:
684 case LOCALE_SDATE:
685 case LOCALE_SDAYNAME1:
686 case LOCALE_SDAYNAME2:
687 case LOCALE_SDAYNAME3:
688 case LOCALE_SDAYNAME4:
689 case LOCALE_SDAYNAME5:
690 case LOCALE_SDAYNAME6:
691 case LOCALE_SDAYNAME7:
692 //case LOCALE_SDURATION:
693 case LOCALE_SLONGDATE:
708 //case LOCALE_SSHORTESTDAYNAME1:
709 //case LOCALE_SSHORTESTDAYNAME2:
710 //case LOCALE_SSHORTESTDAYNAME3:
711 //case LOCALE_SSHORTESTDAYNAME4:
712 //case LOCALE_SSHORTESTDAYNAME5:
713 //case LOCALE_SSHORTESTDAYNAME6:
714 //case LOCALE_SSHORTESTDAYNAME7:
715 case LOCALE_STIME:
717 case LOCALE_SYEARMONTH:
718 default_id = lcid_LC_TIME;
719 break;
720
721 case LOCALE_IPAPERSIZE:
722 default_id = lcid_LC_PAPER;
723 break;
724
725 case LOCALE_IMEASURE:
726 default_id = lcid_LC_MEASUREMENT;
727 break;
728
729 case LOCALE_ICOUNTRY:
730 default_id = lcid_LC_TELEPHONE;
731 break;
732 }
733 if (default_id) lcid = default_id;
734 }
735 return ConvertDefaultLocale( lcid );
736}
737
738/***********************************************************************
739 * is_genitive_name_supported
740 *
741 * Determine could LCTYPE basically support genitive name form or not.
742 */
744{
745 switch(lctype & 0xffff)
746 {
760 return TRUE;
761 default:
762 return FALSE;
763 }
764}
765
766/***********************************************************************
767 * create_registry_key
768 *
769 * Create the Control Panel\\International registry key.
770 */
771static inline HANDLE create_registry_key(void)
772{
773 static const WCHAR cplW[] = {'C','o','n','t','r','o','l',' ','P','a','n','e','l',0};
774 static const WCHAR intlW[] = {'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
777 HANDLE cpl_key, hkey = 0;
778
779 if (RtlOpenCurrentUser( KEY_ALL_ACCESS, &hkey ) != STATUS_SUCCESS) return 0;
780
781 attr.Length = sizeof(attr);
782 attr.RootDirectory = hkey;
783 attr.ObjectName = &nameW;
784 attr.Attributes = 0;
785 attr.SecurityDescriptor = NULL;
786 attr.SecurityQualityOfService = NULL;
787 RtlInitUnicodeString( &nameW, cplW );
788
789 if (!NtCreateKey( &cpl_key, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL ))
790 {
791 NtClose( attr.RootDirectory );
792 attr.RootDirectory = cpl_key;
793 RtlInitUnicodeString( &nameW, intlW );
794 if (NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL )) hkey = 0;
795 }
796 NtClose( attr.RootDirectory );
797 return hkey;
798}
799
800
801#ifndef __REACTOS__
802/* update the registry settings for a given locale parameter */
803/* return TRUE if an update was needed */
805 const LCTYPE *values, UINT nb_values )
806{
807 static const WCHAR formatW[] = { '%','0','8','x',0 };
808 WCHAR bufferW[40];
810 DWORD count, i;
811
813 count = sizeof(bufferW);
815 {
817 LPCWSTR text = (LPCWSTR)info->Data;
818
819 if (strtoulW( text, NULL, 16 ) == lcid) return FALSE; /* already set correctly */
820 TRACE( "updating registry, locale %s changed %s -> %08x\n",
822 }
823 else TRACE( "updating registry, locale %s changed none -> %08x\n", debugstr_w(name), lcid );
824 sprintfW( bufferW, formatW, lcid );
825 NtSetValueKey( hkey, &nameW, 0, REG_SZ, bufferW, (strlenW(bufferW) + 1) * sizeof(WCHAR) );
826
827 for (i = 0; i < nb_values; i++)
828 {
830 sizeof(bufferW)/sizeof(WCHAR) );
831 SetLocaleInfoW( lcid, values[i], bufferW );
832 }
833 return TRUE;
834}
835
836
837/***********************************************************************
838 * LOCALE_InitRegistry
839 *
840 * Update registry contents on startup if the user locale has changed.
841 * This simulates the action of the Windows control panel.
842 */
844{
845 static const WCHAR acpW[] = {'A','C','P',0};
846 static const WCHAR oemcpW[] = {'O','E','M','C','P',0};
847 static const WCHAR maccpW[] = {'M','A','C','C','P',0};
848 static const WCHAR localeW[] = {'L','o','c','a','l','e',0};
849 static const WCHAR lc_ctypeW[] = { 'L','C','_','C','T','Y','P','E',0 };
850 static const WCHAR lc_monetaryW[] = { 'L','C','_','M','O','N','E','T','A','R','Y',0 };
851 static const WCHAR lc_numericW[] = { 'L','C','_','N','U','M','E','R','I','C',0 };
852 static const WCHAR lc_timeW[] = { 'L','C','_','T','I','M','E',0 };
853 static const WCHAR lc_measurementW[] = { 'L','C','_','M','E','A','S','U','R','E','M','E','N','T',0 };
854 static const WCHAR lc_telephoneW[] = { 'L','C','_','T','E','L','E','P','H','O','N','E',0 };
855 static const WCHAR lc_paperW[] = { 'L','C','_','P','A','P','E','R',0};
856 static const struct
857 {
860 } update_cp_values[] = {
862 { oemcpW, LOCALE_IDEFAULTCODEPAGE },
864 };
865 static const LCTYPE lc_messages_values[] = {
868 LOCALE_SLIST };
869 static const LCTYPE lc_monetary_values[] = {
878 static const LCTYPE lc_numeric_values[] = {
882 LOCALE_IDIGITSUBSTITUTION,
888 static const LCTYPE lc_time_values[] = {
902 LOCALE_SYEARMONTH,
903 LOCALE_IDATE };
904 static const LCTYPE lc_measurement_values[] = { LOCALE_IMEASURE };
905 static const LCTYPE lc_telephone_values[] = { LOCALE_ICOUNTRY };
906 static const LCTYPE lc_paper_values[] = { LOCALE_IPAPERSIZE };
907
909 WCHAR bufferW[80];
910 DWORD count, i;
911 HANDLE hkey;
913
914 if (!(hkey = create_registry_key()))
915 return; /* don't do anything if we can't create the registry key */
916
917 locale_update_registry( hkey, localeW, lcid_LC_MESSAGES, lc_messages_values,
918 sizeof(lc_messages_values)/sizeof(lc_messages_values[0]) );
919 locale_update_registry( hkey, lc_monetaryW, lcid_LC_MONETARY, lc_monetary_values,
920 sizeof(lc_monetary_values)/sizeof(lc_monetary_values[0]) );
921 locale_update_registry( hkey, lc_numericW, lcid_LC_NUMERIC, lc_numeric_values,
922 sizeof(lc_numeric_values)/sizeof(lc_numeric_values[0]) );
923 locale_update_registry( hkey, lc_timeW, lcid_LC_TIME, lc_time_values,
924 sizeof(lc_time_values)/sizeof(lc_time_values[0]) );
925 locale_update_registry( hkey, lc_measurementW, lcid_LC_MEASUREMENT, lc_measurement_values,
926 sizeof(lc_measurement_values)/sizeof(lc_measurement_values[0]) );
927 locale_update_registry( hkey, lc_telephoneW, lcid_LC_TELEPHONE, lc_telephone_values,
928 sizeof(lc_telephone_values)/sizeof(lc_telephone_values[0]) );
929 locale_update_registry( hkey, lc_paperW, lcid_LC_PAPER, lc_paper_values,
930 sizeof(lc_paper_values)/sizeof(lc_paper_values[0]) );
931
932 if (locale_update_registry( hkey, lc_ctypeW, lcid_LC_CTYPE, NULL, 0 ))
933 {
934 static const WCHAR codepageW[] =
935 {'\\','R','e','g','i','s','t','r','y','\\','M','a','c','h','i','n','e','\\','S','y','s','t','e','m','\\',
936 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
937 'C','o','n','t','r','o','l','\\','N','l','s','\\','C','o','d','e','p','a','g','e',0};
938
941 DWORD len = 14;
942
943 RtlInitUnicodeString( &nameW, codepageW );
945 while (codepageW[len])
946 {
947 nameW.Length = len * sizeof(WCHAR);
948 if (NtCreateKey( &nls_key, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL )) break;
949 NtClose( nls_key );
950 len++;
951 while (codepageW[len] && codepageW[len] != '\\') len++;
952 }
953 nameW.Length = len * sizeof(WCHAR);
954 if (!NtCreateKey( &nls_key, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL ))
955 {
956 for (i = 0; i < sizeof(update_cp_values)/sizeof(update_cp_values[0]); i++)
957 {
958 count = GetLocaleInfoW( lcid, update_cp_values[i].value | LOCALE_NOUSEROVERRIDE,
959 bufferW, sizeof(bufferW)/sizeof(WCHAR) );
960 RtlInitUnicodeString( &nameW, update_cp_values[i].name );
961 NtSetValueKey( nls_key, &nameW, 0, REG_SZ, bufferW, count * sizeof(WCHAR) );
962 }
963 NtClose( nls_key );
964 }
965 }
966
967 NtClose( hkey );
968}
969
970
971#ifdef __APPLE__
972/***********************************************************************
973 * get_mac_locale
974 *
975 * Return a locale identifier string reflecting the Mac locale, in a form
976 * that parse_locale_name() will understand. So, strip out unusual
977 * things like script, variant, etc. Or, rather, just construct it as
978 * <lang>[_<country>].UTF-8.
979 */
980static const char* get_mac_locale(void)
981{
982 static char mac_locale[50];
983
984 if (!mac_locale[0])
985 {
986 CFLocaleRef locale = CFLocaleCopyCurrent();
987 CFStringRef lang = CFLocaleGetValue( locale, kCFLocaleLanguageCode );
988 CFStringRef country = CFLocaleGetValue( locale, kCFLocaleCountryCode );
989 CFStringRef locale_string;
990
991 if (country)
992 locale_string = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@_%@"), lang, country);
993 else
994 locale_string = CFStringCreateCopy(NULL, lang);
995
996 CFStringGetCString(locale_string, mac_locale, sizeof(mac_locale), kCFStringEncodingUTF8);
997 strcat(mac_locale, ".UTF-8");
998
999 CFRelease(locale);
1000 CFRelease(locale_string);
1001 }
1002
1003 return mac_locale;
1004}
1005
1006
1007/***********************************************************************
1008 * has_env
1009 */
1010static BOOL has_env(const char* name)
1011{
1012 const char* value = getenv( name );
1013 return value && value[0];
1014}
1015#endif
1016
1017
1018/***********************************************************************
1019 * get_locale
1020 *
1021 * Get the locale identifier for a given category. On most platforms,
1022 * this is just a thin wrapper around setlocale(). On OS X, though, it
1023 * is common for the Mac locale settings to not be supported by the C
1024 * library. So, we sometimes override the result with the Mac locale.
1025 */
1026static const char* get_locale(int category, const char* category_name)
1027{
1028 const char* ret = setlocale(category, NULL);
1029
1030#ifdef __ANDROID__
1031 if (!strcmp(ret, "C"))
1032 {
1033 ret = getenv( category_name );
1034 if (!ret || !ret[0]) ret = getenv( "LC_ALL" );
1035 if (!ret || !ret[0]) ret = "C";
1036 }
1037#endif
1038
1039#ifdef __APPLE__
1040 /* If LC_ALL is set, respect it as a user override.
1041 If LC_* is set, respect it as a user override, except if it's LC_CTYPE
1042 and equal to UTF-8. That's because, when the Mac locale isn't supported
1043 by the C library, Terminal.app sets LC_CTYPE=UTF-8 and doesn't set LANG.
1044 parse_locale_name() doesn't handle that properly, so we override that
1045 with the Mac locale (which uses UTF-8 for the charset, anyway).
1046 Otherwise:
1047 For LC_MESSAGES, we override the C library because the user language
1048 setting is separate from the locale setting on which LANG was based.
1049 If the C library didn't get anything better from LANG than C or POSIX,
1050 override that. That probably means the Mac locale isn't supported by
1051 the C library. */
1052 if (!has_env( "LC_ALL" ) &&
1053 ((category == LC_CTYPE && !strcmp( ret, "UTF-8" )) ||
1054 (!has_env( category_name ) &&
1055 (category == LC_MESSAGES || !strcmp( ret, "C" ) || !strcmp( ret, "POSIX" )))))
1056 {
1057 const char* override = get_mac_locale();
1058
1059 if (category == LC_MESSAGES)
1060 {
1061 /* Retrieve the preferred language as chosen in System Preferences. */
1062 static char messages_locale[50];
1063
1064 if (!messages_locale[0])
1065 {
1066 CFArrayRef preferred_langs = CFLocaleCopyPreferredLanguages();
1067 if (preferred_langs && CFArrayGetCount( preferred_langs ))
1068 {
1069 CFStringRef preferred_lang = CFArrayGetValueAtIndex( preferred_langs, 0 );
1070 CFDictionaryRef components = CFLocaleCreateComponentsFromLocaleIdentifier( NULL, preferred_lang );
1071 if (components)
1072 {
1073 CFStringRef lang = CFDictionaryGetValue( components, kCFLocaleLanguageCode );
1074 CFStringRef country = CFDictionaryGetValue( components, kCFLocaleCountryCode );
1075 CFLocaleRef locale = NULL;
1076 CFStringRef locale_string;
1077
1078 if (!country)
1079 {
1080 locale = CFLocaleCopyCurrent();
1081 country = CFLocaleGetValue( locale, kCFLocaleCountryCode );
1082 }
1083
1084 if (country)
1085 locale_string = CFStringCreateWithFormat( NULL, NULL, CFSTR("%@_%@"), lang, country );
1086 else
1087 locale_string = CFStringCreateCopy( NULL, lang );
1088 CFStringGetCString( locale_string, messages_locale, sizeof(messages_locale), kCFStringEncodingUTF8 );
1089 strcat( messages_locale, ".UTF-8" );
1090
1091 CFRelease( locale_string );
1092 if (locale) CFRelease( locale );
1093 CFRelease( components );
1094 }
1095 }
1096 if (preferred_langs)
1097 CFRelease( preferred_langs );
1098 }
1099
1100 if (messages_locale[0])
1101 override = messages_locale;
1102 }
1103
1104 TRACE( "%s is %s; overriding with %s\n", category_name, debugstr_a(ret), debugstr_a(override) );
1105 ret = override;
1106 }
1107#endif
1108
1109 return ret;
1110}
1111
1112
1113/***********************************************************************
1114 * setup_unix_locales
1115 */
1117{
1118 struct locale_name locale_name;
1119 WCHAR buffer[128], ctype_buff[128];
1120 const char *locale;
1121 UINT unix_cp = 0;
1122
1123 if ((locale = get_locale( LC_CTYPE, "LC_CTYPE" )))
1124 {
1125 strcpynAtoW( ctype_buff, locale, sizeof(ctype_buff)/sizeof(WCHAR) );
1126 parse_locale_name( ctype_buff, &locale_name );
1129 }
1130 if (!lcid_LC_CTYPE) /* this one needs a default value */
1132
1133 TRACE( "got lcid %04x (%d matches) for LC_CTYPE=%s\n",
1135
1136#define GET_UNIX_LOCALE(cat) do \
1137 if ((locale = get_locale( cat, #cat ))) \
1138 { \
1139 strcpynAtoW( buffer, locale, sizeof(buffer)/sizeof(WCHAR) ); \
1140 if (!strcmpW( buffer, ctype_buff )) lcid_##cat = lcid_LC_CTYPE; \
1141 else { \
1142 parse_locale_name( buffer, &locale_name ); \
1143 lcid_##cat = locale_name.lcid; \
1144 TRACE( "got lcid %04x (%d matches) for " #cat "=%s\n", \
1145 locale_name.lcid, locale_name.matches, debugstr_a(locale) ); \
1146 } \
1147 } while (0)
1148
1150 GET_UNIX_LOCALE( LC_MESSAGES );
1154#ifdef LC_PAPER
1155 GET_UNIX_LOCALE( LC_PAPER );
1156#endif
1157#ifdef LC_MEASUREMENT
1158 GET_UNIX_LOCALE( LC_MEASUREMENT );
1159#endif
1160#ifdef LC_TELEPHONE
1161 GET_UNIX_LOCALE( LC_TELEPHONE );
1162#endif
1163
1164#undef GET_UNIX_LOCALE
1165
1166 return unix_cp;
1167}
1168#endif // !__REACTOS__
1169
1170
1171/***********************************************************************
1172 * GetUserDefaultLangID (KERNEL32.@)
1173 *
1174 * Get the default language Id for the current user.
1175 *
1176 * PARAMS
1177 * None.
1178 *
1179 * RETURNS
1180 * The current LANGID of the default language for the current user.
1181 */
1183{
1185}
1186
1187
1188/***********************************************************************
1189 * GetSystemDefaultLangID (KERNEL32.@)
1190 *
1191 * Get the default language Id for the system.
1192 *
1193 * PARAMS
1194 * None.
1195 *
1196 * RETURNS
1197 * The current LANGID of the default language for the system.
1198 */
1200{
1202}
1203
1204
1205/***********************************************************************
1206 * GetUserDefaultLCID (KERNEL32.@)
1207 *
1208 * Get the default locale Id for the current user.
1209 *
1210 * PARAMS
1211 * None.
1212 *
1213 * RETURNS
1214 * The current LCID of the default locale for the current user.
1215 */
1217{
1218 LCID lcid;
1220 return lcid;
1221}
1222
1223
1224/***********************************************************************
1225 * GetSystemDefaultLCID (KERNEL32.@)
1226 *
1227 * Get the default locale Id for the system.
1228 *
1229 * PARAMS
1230 * None.
1231 *
1232 * RETURNS
1233 * The current LCID of the default locale for the system.
1234 */
1236{
1237 LCID lcid;
1239 return lcid;
1240}
1241
1242#ifndef __REACTOS__
1243/***********************************************************************
1244 * GetSystemDefaultLocaleName (KERNEL32.@)
1245 */
1247{
1249 return LCIDToLocaleName(lcid, localename, len, 0);
1250}
1251
1253{
1254 LCTYPE type;
1255 int lsize;
1256
1257 FIXME("(0x%x %p %p %p) returning a dummy value (current locale)\n", flags, count, buffer, size);
1258
1259 if (flags & MUI_LANGUAGE_ID)
1261 else
1263
1265 if (!lsize)
1266 {
1267 /* keep last error from callee */
1268 return FALSE;
1269 }
1270 lsize++;
1271 if (!*size)
1272 {
1273 *size = lsize;
1274 *count = 1;
1275 return TRUE;
1276 }
1277
1278 if (lsize > *size)
1279 {
1281 return FALSE;
1282 }
1283
1285 {
1286 /* keep last error from callee */
1287 return FALSE;
1288 }
1289
1290 buffer[lsize-1] = 0;
1291 *size = lsize;
1292 *count = 1;
1293 TRACE("returned variable content: %d, \"%s\", %d\n", *count, debugstr_w(buffer), *size);
1294 return TRUE;
1295
1296}
1297
1298/***********************************************************************
1299 * GetSystemPreferredUILanguages (KERNEL32.@)
1300 */
1302{
1303 if (flags & ~(MUI_LANGUAGE_NAME | MUI_LANGUAGE_ID | MUI_MACHINE_LANGUAGE_SETTINGS))
1304 {
1306 return FALSE;
1307 }
1308 if ((flags & MUI_LANGUAGE_NAME) && (flags & MUI_LANGUAGE_ID))
1309 {
1311 return FALSE;
1312 }
1313 if (*size && !buffer)
1314 {
1316 return FALSE;
1317 }
1318
1320}
1321
1322/***********************************************************************
1323 * SetThreadPreferredUILanguages (KERNEL32.@)
1324 */
1326{
1327 FIXME( "%u, %p, %p\n", flags, buffer, count );
1328 return TRUE;
1329}
1330
1331/***********************************************************************
1332 * GetThreadPreferredUILanguages (KERNEL32.@)
1333 */
1335{
1336 FIXME( "%08x, %p, %p %p\n", flags, count, buf, size );
1338}
1339
1340#if (WINVER >= 0x0600)
1341/******************************************************************************
1342 * GetUserPreferredUILanguages (KERNEL32.@)
1343 */
1345{
1346 TRACE( "%u %p %p %p\n", flags, count, buffer, size );
1347
1348 if (flags & ~(MUI_LANGUAGE_NAME | MUI_LANGUAGE_ID))
1349 {
1351 return FALSE;
1352 }
1353 if ((flags & MUI_LANGUAGE_NAME) && (flags & MUI_LANGUAGE_ID))
1354 {
1356 return FALSE;
1357 }
1358 if (*size && !buffer)
1359 {
1361 return FALSE;
1362 }
1363
1365}
1366#endif // (WINVER >= 0x0600)
1367#endif // !__REACTOS__
1368
1369/***********************************************************************
1370 * GetUserDefaultUILanguage (KERNEL32.@)
1371 *
1372 * Get the default user interface language Id for the current user.
1373 *
1374 * PARAMS
1375 * None.
1376 *
1377 * RETURNS
1378 * The current LANGID of the default UI language for the current user.
1379 */
1381{
1382 LANGID lang;
1384 return lang;
1385}
1386
1387
1388/***********************************************************************
1389 * GetSystemDefaultUILanguage (KERNEL32.@)
1390 *
1391 * Get the default user interface language Id for the system.
1392 *
1393 * PARAMS
1394 * None.
1395 *
1396 * RETURNS
1397 * The current LANGID of the default UI language for the system. This is
1398 * typically the same language used during the installation process.
1399 */
1401{
1402 LANGID lang;
1404 return lang;
1405}
1406
1407#if (WINVER >= 0x0600)
1408#if 0 // See kernel32_vista
1409/***********************************************************************
1410 * LocaleNameToLCID (KERNEL32.@)
1411 */
1413{
1414 struct locale_name locale_name;
1415
1416 if (flags) FIXME( "unsupported flags %x\n", flags );
1417
1419 return GetUserDefaultLCID();
1420
1421 /* string parsing */
1422 parse_locale_name( name, &locale_name );
1423
1424 TRACE( "found lcid %x for %s, matches %d\n",
1426
1427 if (!locale_name.matches)
1428 {
1430 return 0;
1431 }
1432
1433 if (locale_name.matches == 1)
1434 WARN( "locale %s not recognized, defaulting to %s\n",
1436
1437 return locale_name.lcid;
1438}
1439#endif
1440
1441
1442#if 0 // See kernel32_vista
1443/***********************************************************************
1444 * LCIDToLocaleName (KERNEL32.@)
1445 */
1447{
1448 if (flags) FIXME( "unsupported flags %x\n", flags );
1449
1451}
1452#endif
1453#endif
1454
1455
1456/******************************************************************************
1457 * get_locale_registry_value
1458 *
1459 * Gets the registry value name and cache for a given lctype.
1460 */
1462{
1463 int i;
1464 for (i=0; i < sizeof(registry_values)/sizeof(registry_values[0]); i++)
1466 return &registry_values[i];
1467 return NULL;
1468}
1469
1470
1471/******************************************************************************
1472 * get_registry_locale_info
1473 *
1474 * Retrieve user-modified locale info from the registry.
1475 * Return length, 0 on error, -1 if not found.
1476 */
1478{
1479 DWORD size;
1480 INT ret;
1481 HANDLE hkey;
1485 static const int info_size = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
1486
1488
1490 {
1491 if (!(hkey = create_registry_key()))
1492 {
1494 return -1;
1495 }
1496
1498 size = info_size + len * sizeof(WCHAR);
1499
1500 if (!(info = HeapAlloc( GetProcessHeap(), 0, size )))
1501 {
1502 NtClose( hkey );
1505 return 0;
1506 }
1507
1509
1510 /* try again with a bigger buffer when we have to return the correct size */
1511 if (status == STATUS_BUFFER_OVERFLOW && !buffer && size > info_size)
1512 {
1514 if ((new_info = HeapReAlloc( GetProcessHeap(), 0, info, size )))
1515 {
1516 info = new_info;
1518 }
1519 }
1520
1521 NtClose( hkey );
1522
1523 if (!status)
1524 {
1525 INT length = (size - info_size) / sizeof(WCHAR);
1527
1528 if (!length || ((WCHAR *)&info->Data)[length-1])
1529 length++;
1530
1531 cached_value = HeapAlloc( GetProcessHeap(), 0, length * sizeof(WCHAR) );
1532
1533 if (!cached_value)
1534 {
1535 HeapFree( GetProcessHeap(), 0, info );
1538 return 0;
1539 }
1540
1541 memcpy( cached_value, info->Data, (length-1) * sizeof(WCHAR) );
1542 cached_value[length-1] = 0;
1543 HeapFree( GetProcessHeap(), 0, info );
1545 }
1546 else
1547 {
1549 {
1550 ret = (size - info_size) / sizeof(WCHAR);
1551 }
1553 {
1554 ret = -1;
1555 }
1556 else
1557 {
1559 ret = 0;
1560 }
1561 HeapFree( GetProcessHeap(), 0, info );
1563 return ret;
1564 }
1565 }
1566
1568
1569 if (buffer)
1570 {
1571 if (ret > len)
1572 {
1574 ret = 0;
1575 }
1576 else
1577 {
1579 }
1580 }
1581
1583
1584 return ret;
1585}
1586
1587
1588/******************************************************************************
1589 * GetLocaleInfoA (KERNEL32.@)
1590 *
1591 * Get information about an aspect of a locale.
1592 *
1593 * PARAMS
1594 * lcid [I] LCID of the locale
1595 * lctype [I] LCTYPE_ flags from "winnls.h"
1596 * buffer [O] Destination for the information
1597 * len [I] Length of buffer in characters
1598 *
1599 * RETURNS
1600 * Success: The size of the data requested. If buffer is non-NULL, it is filled
1601 * with the information.
1602 * Failure: 0. Use GetLastError() to determine the cause.
1603 *
1604 * NOTES
1605 * - LOCALE_NEUTRAL is equal to LOCALE_SYSTEM_DEFAULT
1606 * - The string returned is NUL terminated, except for LOCALE_FONTSIGNATURE,
1607 * which is a bit string.
1608 */
1610{
1611 WCHAR *bufferW;
1612 INT lenW, ret;
1613
1614 TRACE( "(lcid=0x%x,lctype=0x%x,%p,%d)\n", lcid, lctype, buffer, len );
1615
1616 if (len < 0 || (len && !buffer))
1617 {
1619 return 0;
1620 }
1623 {
1625 return 0;
1626 }
1627
1628 if (!len) buffer = NULL;
1629
1630 if (!(lenW = GetLocaleInfoW( lcid, lctype, NULL, 0 ))) return 0;
1631
1632 if (!(bufferW = HeapAlloc( GetProcessHeap(), 0, lenW * sizeof(WCHAR) )))
1633 {
1635 return 0;
1636 }
1637 if ((ret = GetLocaleInfoW( lcid, lctype, bufferW, lenW )))
1638 {
1639 if ((lctype & LOCALE_RETURN_NUMBER) ||
1641 {
1642 /* it's not an ASCII string, just bytes */
1643 ret *= sizeof(WCHAR);
1644 if (buffer)
1645 {
1646 if (ret <= len) memcpy( buffer, bufferW, ret );
1647 else
1648 {
1650 ret = 0;
1651 }
1652 }
1653 }
1654 else
1655 {
1658 ret = WideCharToMultiByte( codepage, 0, bufferW, ret, buffer, len, NULL, NULL );
1659 }
1660 }
1661 HeapFree( GetProcessHeap(), 0, bufferW );
1662 return ret;
1663}
1664
1666{
1667 return lctype == LOCALE_ILANGUAGE || lctype == LOCALE_IDEFAULTLANGUAGE ? 16 : 10;
1668}
1669
1670/******************************************************************************
1671 * GetLocaleInfoW (KERNEL32.@)
1672 *
1673 * See GetLocaleInfoA.
1674 */
1676{
1677 LANGID lang_id;
1678 HRSRC hrsrc;
1679 HGLOBAL hmem;
1680 INT ret;
1681 UINT lcflags;
1682 const WCHAR *p;
1683 unsigned int i;
1684
1685 if (len < 0 || (len && !buffer))
1686 {
1688 return 0;
1689 }
1692 {
1694 return 0;
1695 }
1696
1697 if (!len) buffer = NULL;
1698
1700
1702 lctype &= 0xffff;
1703
1704 TRACE( "(lcid=0x%x,lctype=0x%x,%p,%d)\n", lcid, lctype, buffer, len );
1705
1706 /* first check for overrides in the registry */
1707
1708 if (!(lcflags & LOCALE_NOUSEROVERRIDE) &&
1710 {
1712
1713 if (value)
1714 {
1715 if (lcflags & LOCALE_RETURN_NUMBER)
1716 {
1717 WCHAR tmp[16];
1718 ret = get_registry_locale_info( value, tmp, sizeof(tmp)/sizeof(WCHAR) );
1719 if (ret > 0)
1720 {
1721 WCHAR *end;
1723 if (*end) /* invalid number */
1724 {
1726 return 0;
1727 }
1728 ret = sizeof(UINT)/sizeof(WCHAR);
1729 if (!buffer) return ret;
1730 if (ret > len)
1731 {
1733 return 0;
1734 }
1735 memcpy( buffer, &number, sizeof(number) );
1736 }
1737 }
1739
1740 if (ret != -1) return ret;
1741 }
1742 }
1743
1744 /* now load it from kernel resources */
1745
1746 lang_id = LANGIDFROMLCID( lcid );
1747
1748 /* replace SUBLANG_NEUTRAL by SUBLANG_DEFAULT */
1749 if (SUBLANGID(lang_id) == SUBLANG_NEUTRAL) lang_id = get_default_sublang( lang_id );
1750
1752 ULongToPtr((lctype >> 4) + 1), lang_id )))
1753 {
1754 SetLastError( ERROR_INVALID_FLAGS ); /* no such lctype */
1755 return 0;
1756 }
1757 if (!(hmem = LoadResource( kernel32_handle, hrsrc )))
1758 return 0;
1759
1760 p = LockResource( hmem );
1761 for (i = 0; i < (lctype & 0x0f); i++) p += *p + 1;
1762
1763 if (lcflags & LOCALE_RETURN_NUMBER) ret = sizeof(UINT)/sizeof(WCHAR);
1764 else if (is_genitive_name_supported( lctype ) && *p)
1765 {
1766 /* genitive form's stored after a null separator from a nominative */
1767 for (i = 1; i <= *p; i++) if (!p[i]) break;
1768
1769 if (i <= *p && (lcflags & LOCALE_RETURN_GENITIVE_NAMES))
1770 {
1771 ret = *p - i + 1;
1772 p += i;
1773 }
1774 else ret = i;
1775 }
1776 else
1777 ret = (lctype == LOCALE_FONTSIGNATURE) ? *p : *p + 1;
1778
1779 if (!buffer) return ret;
1780
1781 if (ret > len)
1782 {
1784 return 0;
1785 }
1786
1787 if (lcflags & LOCALE_RETURN_NUMBER)
1788 {
1789 UINT number;
1790 WCHAR *end, *tmp = HeapAlloc( GetProcessHeap(), 0, (*p + 1) * sizeof(WCHAR) );
1791 if (!tmp) return 0;
1792 memcpy( tmp, p + 1, *p * sizeof(WCHAR) );
1793 tmp[*p] = 0;
1795 if (!*end)
1796 memcpy( buffer, &number, sizeof(number) );
1797 else /* invalid number */
1798 {
1800 ret = 0;
1801 }
1802 HeapFree( GetProcessHeap(), 0, tmp );
1803
1804 TRACE( "(lcid=0x%x,lctype=0x%x,%p,%d) returning number %d\n",
1805 lcid, lctype, buffer, len, number );
1806 }
1807 else
1808 {
1809 memcpy( buffer, p + 1, ret * sizeof(WCHAR) );
1810 if (lctype != LOCALE_FONTSIGNATURE) buffer[ret-1] = 0;
1811
1812 TRACE( "(lcid=0x%x,lctype=0x%x,%p,%d) returning %d %s\n",
1814 }
1815 return ret;
1816}
1817
1818#if (WINVER >= 0x0600)
1819#if 0 // See kernel32_vista
1820/******************************************************************************
1821 * GetLocaleInfoEx (KERNEL32.@)
1822 */
1824{
1826
1827 TRACE("%s, lcid=0x%x, 0x%x\n", debugstr_w(locale), lcid, info);
1828
1829 if (!lcid) return 0;
1830
1831 /* special handling for neutral locale names */
1832 if (locale && strlenW(locale) == 2)
1833 {
1834 switch (info)
1835 {
1836 case LOCALE_SNAME:
1837 if (len && len < 3)
1838 {
1840 return 0;
1841 }
1842 if (len) strcpyW(buffer, locale);
1843 return 3;
1844 case LOCALE_SPARENT:
1845 if (len) buffer[0] = 0;
1846 return 1;
1847 }
1848 }
1849
1850 return GetLocaleInfoW(lcid, info, buffer, len);
1851}
1852#endif
1853
1854#if 0 // See kernel32_vista
1855BOOL
1856WINAPI
1858 LPCWSTR lpLocaleName
1859)
1860{
1861 TRACE( "IsValidLocaleName not implemented (lpLocaleName=%s)\n", debugstr_w(lpLocaleName));
1862 return TRUE;
1863}
1864#endif
1865#endif
1866
1867/******************************************************************************
1868 * SetLocaleInfoA [KERNEL32.@]
1869 *
1870 * Set information about an aspect of a locale.
1871 *
1872 * PARAMS
1873 * lcid [I] LCID of the locale
1874 * lctype [I] LCTYPE_ flags from "winnls.h"
1875 * data [I] Information to set
1876 *
1877 * RETURNS
1878 * Success: TRUE. The information given will be returned by GetLocaleInfoA()
1879 * whenever it is called without LOCALE_NOUSEROVERRIDE.
1880 * Failure: FALSE. Use GetLastError() to determine the cause.
1881 *
1882 * NOTES
1883 * - Values are only be set for the current user locale; the system locale
1884 * settings cannot be changed.
1885 * - Any settings changed by this call are lost when the locale is changed by
1886 * the control panel (in Wine, this happens every time you change LANG).
1887 * - The native implementation of this function does not check that lcid matches
1888 * the current user locale, and simply sets the new values. Wine warns you in
1889 * this case, but behaves the same.
1890 */
1892{
1894 WCHAR *strW;
1895 DWORD len;
1896 BOOL ret;
1897
1899
1900 if (!data)
1901 {
1903 return FALSE;
1904 }
1905 len = MultiByteToWideChar( codepage, 0, data, -1, NULL, 0 );
1906 if (!(strW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
1907 {
1909 return FALSE;
1910 }
1913 HeapFree( GetProcessHeap(), 0, strW );
1914 return ret;
1915}
1916
1917
1918/******************************************************************************
1919 * SetLocaleInfoW (KERNEL32.@)
1920 *
1921 * See SetLocaleInfoA.
1922 */
1924{
1925 struct registry_value *value;
1926 static const WCHAR intlW[] = {'i','n','t','l',0 };
1929 HANDLE hkey;
1930
1931 lctype &= 0xffff;
1933
1934 if (!data || !value)
1935 {
1937 return FALSE;
1938 }
1939
1941 {
1943 return FALSE;
1944 }
1945
1946 TRACE("setting %x (%s) to %s\n", lctype, debugstr_w(value->name), debugstr_w(data) );
1947
1948 /* FIXME: should check that data to set is sane */
1949
1950 /* FIXME: profile functions should map to registry */
1951 WriteProfileStringW( intlW, value->name, data );
1952
1953 if (!(hkey = create_registry_key())) return FALSE;
1955 status = NtSetValueKey( hkey, &valueW, 0, REG_SZ, (PVOID)data, (strlenW(data)+1)*sizeof(WCHAR) );
1956
1958 HeapFree( GetProcessHeap(), 0, value->cached_value );
1959 value->cached_value = NULL;
1961
1963 {
1964 /* Set I-value from S value */
1965 WCHAR *lpD, *lpM, *lpY;
1966 WCHAR szBuff[2];
1967
1968 lpD = strrchrW(data, 'd');
1969 lpM = strrchrW(data, 'M');
1970 lpY = strrchrW(data, 'y');
1971
1972 if (lpD <= lpM)
1973 {
1974 szBuff[0] = '1'; /* D-M-Y */
1975 }
1976 else
1977 {
1978 if (lpY <= lpM)
1979 szBuff[0] = '2'; /* Y-M-D */
1980 else
1981 szBuff[0] = '0'; /* M-D-Y */
1982 }
1983
1984 szBuff[1] = '\0';
1985
1988 else
1990
1992
1993 WriteProfileStringW( intlW, value->name, szBuff );
1994
1996 status = NtSetValueKey( hkey, &valueW, 0, REG_SZ, szBuff, sizeof(szBuff) );
1997
1999 HeapFree( GetProcessHeap(), 0, value->cached_value );
2000 value->cached_value = NULL;
2002 }
2003
2004 NtClose( hkey );
2005
2007 return !status;
2008}
2009
2010
2011#ifndef __REACTOS__
2012/******************************************************************************
2013 * GetACP (KERNEL32.@)
2014 *
2015 * Get the current Ansi code page Id for the system.
2016 *
2017 * PARAMS
2018 * None.
2019 *
2020 * RETURNS
2021 * The current Ansi code page identifier for the system.
2022 */
2024{
2026 return ansi_cptable->info.codepage;
2027}
2028
2029
2030/******************************************************************************
2031 * SetCPGlobal (KERNEL32.@)
2032 *
2033 * Set the current Ansi code page Id for the system.
2034 *
2035 * PARAMS
2036 * acp [I] code page ID to be the new ACP.
2037 *
2038 * RETURNS
2039 * The previous ACP.
2040 */
2042{
2043 UINT ret = GetACP();
2044 const union cptable *new_cptable = wine_cp_get_table( acp );
2045
2046 if (new_cptable) ansi_cptable = new_cptable;
2047 return ret;
2048}
2049
2050
2051/***********************************************************************
2052 * GetOEMCP (KERNEL32.@)
2053 *
2054 * Get the current OEM code page Id for the system.
2055 *
2056 * PARAMS
2057 * None.
2058 *
2059 * RETURNS
2060 * The current OEM code page identifier for the system.
2061 */
2063{
2065 return oem_cptable->info.codepage;
2066}
2067
2068
2069/***********************************************************************
2070 * IsValidCodePage (KERNEL32.@)
2071 *
2072 * Determine if a given code page identifier is valid.
2073 *
2074 * PARAMS
2075 * codepage [I] Code page Id to verify.
2076 *
2077 * RETURNS
2078 * TRUE, If codepage is valid and available on the system,
2079 * FALSE otherwise.
2080 */
2082{
2083 switch(codepage) {
2084 case CP_UTF7:
2085 case CP_UTF8:
2086 return TRUE;
2087 default:
2088 return wine_cp_get_table( codepage ) != NULL;
2089 }
2090}
2091
2092
2093/***********************************************************************
2094 * IsDBCSLeadByteEx (KERNEL32.@)
2095 *
2096 * Determine if a character is a lead byte in a given code page.
2097 *
2098 * PARAMS
2099 * codepage [I] Code page for the test.
2100 * testchar [I] Character to test
2101 *
2102 * RETURNS
2103 * TRUE, if testchar is a lead byte in codepage,
2104 * FALSE otherwise.
2105 */
2107{
2108 const union cptable *table = get_codepage_table( codepage );
2109 return table && wine_is_dbcs_leadbyte( table, testchar );
2110}
2111
2112
2113/***********************************************************************
2114 * IsDBCSLeadByte (KERNEL32.@)
2115 * IsDBCSLeadByte (KERNEL.207)
2116 *
2117 * Determine if a character is a lead byte.
2118 *
2119 * PARAMS
2120 * testchar [I] Character to test
2121 *
2122 * RETURNS
2123 * TRUE, if testchar is a lead byte in the ANSI code page,
2124 * FALSE otherwise.
2125 */
2127{
2128 if (!ansi_cptable) return FALSE;
2129 return wine_is_dbcs_leadbyte( ansi_cptable, testchar );
2130}
2131
2132
2133/***********************************************************************
2134 * GetCPInfo (KERNEL32.@)
2135 *
2136 * Get information about a code page.
2137 *
2138 * PARAMS
2139 * codepage [I] Code page number
2140 * cpinfo [O] Destination for code page information
2141 *
2142 * RETURNS
2143 * Success: TRUE. cpinfo is updated with the information about codepage.
2144 * Failure: FALSE, if codepage is invalid or cpinfo is NULL.
2145 */
2147{
2148 const union cptable *table;
2149
2150 if (!cpinfo)
2151 {
2153 return FALSE;
2154 }
2155
2156 if (!(table = get_codepage_table( codepage )))
2157 {
2158 switch(codepage)
2159 {
2160 case CP_UTF7:
2161 case CP_UTF8:
2162 cpinfo->DefaultChar[0] = 0x3f;
2163 cpinfo->DefaultChar[1] = 0;
2164 cpinfo->LeadByte[0] = cpinfo->LeadByte[1] = 0;
2165 cpinfo->MaxCharSize = (codepage == CP_UTF7) ? 5 : 4;
2166 return TRUE;
2167 }
2168
2170 return FALSE;
2171 }
2172 if (table->info.def_char & 0xff00)
2173 {
2174 cpinfo->DefaultChar[0] = (table->info.def_char & 0xff00) >> 8;
2175 cpinfo->DefaultChar[1] = table->info.def_char & 0x00ff;
2176 }
2177 else
2178 {
2179 cpinfo->DefaultChar[0] = table->info.def_char & 0xff;
2180 cpinfo->DefaultChar[1] = 0;
2181 }
2182 if ((cpinfo->MaxCharSize = table->info.char_size) == 2)
2183 memcpy( cpinfo->LeadByte, table->dbcs.lead_bytes, sizeof(cpinfo->LeadByte) );
2184 else
2185 cpinfo->LeadByte[0] = cpinfo->LeadByte[1] = 0;
2186
2187 return TRUE;
2188}
2189
2190/***********************************************************************
2191 * GetCPInfoExA (KERNEL32.@)
2192 *
2193 * Get extended information about a code page.
2194 *
2195 * PARAMS
2196 * codepage [I] Code page number
2197 * dwFlags [I] Reserved, must to 0.
2198 * cpinfo [O] Destination for code page information
2199 *
2200 * RETURNS
2201 * Success: TRUE. cpinfo is updated with the information about codepage.
2202 * Failure: FALSE, if codepage is invalid or cpinfo is NULL.
2203 */
2205{
2206 CPINFOEXW cpinfoW;
2207
2208 if (!GetCPInfoExW( codepage, dwFlags, &cpinfoW ))
2209 return FALSE;
2210
2211 /* the layout is the same except for CodePageName */
2212 memcpy(cpinfo, &cpinfoW, sizeof(CPINFOEXA));
2213 WideCharToMultiByte(CP_ACP, 0, cpinfoW.CodePageName, -1, cpinfo->CodePageName, sizeof(cpinfo->CodePageName), NULL, NULL);
2214 return TRUE;
2215}
2216
2217/***********************************************************************
2218 * GetCPInfoExW (KERNEL32.@)
2219 *
2220 * Unicode version of GetCPInfoExA.
2221 */
2223{
2224 if (!GetCPInfo( codepage, (LPCPINFO)cpinfo ))
2225 return FALSE;
2226
2227 switch(codepage)
2228 {
2229 case CP_UTF7:
2230 {
2231 static const WCHAR utf7[] = {'U','n','i','c','o','d','e',' ','(','U','T','F','-','7',')',0};
2232
2233 cpinfo->CodePage = CP_UTF7;
2234 cpinfo->UnicodeDefaultChar = 0x3f;
2235 strcpyW(cpinfo->CodePageName, utf7);
2236 break;
2237 }
2238
2239 case CP_UTF8:
2240 {
2241 static const WCHAR utf8[] = {'U','n','i','c','o','d','e',' ','(','U','T','F','-','8',')',0};
2242
2243 cpinfo->CodePage = CP_UTF8;
2244 cpinfo->UnicodeDefaultChar = 0x3f;
2245 strcpyW(cpinfo->CodePageName, utf8);
2246 break;
2247 }
2248
2249 default:
2250 {
2251 const union cptable *table = get_codepage_table( codepage );
2252
2253 cpinfo->CodePage = table->info.codepage;
2254 cpinfo->UnicodeDefaultChar = table->info.def_unicode_char;
2255 MultiByteToWideChar( CP_ACP, 0, table->info.name, -1, cpinfo->CodePageName,
2256 sizeof(cpinfo->CodePageName)/sizeof(WCHAR));
2257 break;
2258 }
2259 }
2260 return TRUE;
2261}
2262
2263/***********************************************************************
2264 * EnumSystemCodePagesA (KERNEL32.@)
2265 *
2266 * Call a user defined function for every code page installed on the system.
2267 *
2268 * PARAMS
2269 * lpfnCodePageEnum [I] User CODEPAGE_ENUMPROC to call with each found code page
2270 * flags [I] Reserved, set to 0.
2271 *
2272 * RETURNS
2273 * TRUE, If all code pages have been enumerated, or
2274 * FALSE if lpfnCodePageEnum returned FALSE to stop the enumeration.
2275 */
2277{
2278 const union cptable *table;
2279 char buffer[10];
2280 int index = 0;
2281
2282 for (;;)
2283 {
2284 if (!(table = wine_cp_enum_table( index++ ))) break;
2285 sprintf( buffer, "%d", table->info.codepage );
2286 if (!lpfnCodePageEnum( buffer )) break;
2287 }
2288 return TRUE;
2289}
2290
2291
2292/***********************************************************************
2293 * EnumSystemCodePagesW (KERNEL32.@)
2294 *
2295 * See EnumSystemCodePagesA.
2296 */
2298{
2299 const union cptable *table;
2300 WCHAR buffer[10], *p;
2301 int page, index = 0;
2302
2303 for (;;)
2304 {
2305 if (!(table = wine_cp_enum_table( index++ ))) break;
2306 p = buffer + sizeof(buffer)/sizeof(WCHAR);
2307 *--p = 0;
2308 page = table->info.codepage;
2309 do
2310 {
2311 *--p = '0' + (page % 10);
2312 page /= 10;
2313 } while( page );
2314 if (!lpfnCodePageEnum( p )) break;
2315 }
2316 return TRUE;
2317}
2318
2319
2320/***********************************************************************
2321 * utf7_write_w
2322 *
2323 * Helper for utf7_mbstowcs
2324 *
2325 * RETURNS
2326 * TRUE on success, FALSE on error
2327 */
2328static inline BOOL utf7_write_w(WCHAR *dst, int dstlen, int *index, WCHAR character)
2329{
2330 if (dstlen > 0)
2331 {
2332 if (*index >= dstlen)
2333 return FALSE;
2334
2335 dst[*index] = character;
2336 }
2337
2338 (*index)++;
2339
2340 return TRUE;
2341}
2342
2343/***********************************************************************
2344 * utf7_mbstowcs
2345 *
2346 * UTF-7 to UTF-16 string conversion, helper for MultiByteToWideChar
2347 *
2348 * RETURNS
2349 * On success, the number of characters written
2350 * On dst buffer overflow, -1
2351 */
2352static int utf7_mbstowcs(const char *src, int srclen, WCHAR *dst, int dstlen)
2353{
2354 static const signed char base64_decoding_table[] =
2355 {
2356 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00-0x0F */
2357 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10-0x1F */
2358 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 0x20-0x2F */
2359 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 0x30-0x3F */
2360 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 0x40-0x4F */
2361 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 0x50-0x5F */
2362 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60-0x6F */
2363 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 /* 0x70-0x7F */
2364 };
2365
2366 const char *source_end = src + srclen;
2367 int dest_index = 0;
2368
2369 DWORD byte_pair = 0;
2370 short offset = 0;
2371
2372 while (src < source_end)
2373 {
2374 if (*src == '+')
2375 {
2376 src++;
2377 if (src >= source_end)
2378 break;
2379
2380 if (*src == '-')
2381 {
2382 /* just a plus sign escaped as +- */
2383 if (!utf7_write_w(dst, dstlen, &dest_index, '+'))
2384 return -1;
2385 src++;
2386 continue;
2387 }
2388
2389 do
2390 {
2391 signed char sextet = *src;
2392 if (sextet == '-')
2393 {
2394 /* skip over the dash and end base64 decoding
2395 * the current, unfinished byte pair is discarded */
2396 src++;
2397 offset = 0;
2398 break;
2399 }
2400 if (sextet < 0)
2401 {
2402 /* the next character of src is < 0 and therefore not part of a base64 sequence
2403 * the current, unfinished byte pair is NOT discarded in this case
2404 * this is probably a bug in Windows */
2405 break;
2406 }
2407
2408 sextet = base64_decoding_table[sextet];
2409 if (sextet == -1)
2410 {
2411 /* -1 means that the next character of src is not part of a base64 sequence
2412 * in other words, all sextets in this base64 sequence have been processed
2413 * the current, unfinished byte pair is discarded */
2414 offset = 0;
2415 break;
2416 }
2417
2418 byte_pair = (byte_pair << 6) | sextet;
2419 offset += 6;
2420
2421 if (offset >= 16)
2422 {
2423 /* this byte pair is done */
2424 if (!utf7_write_w(dst, dstlen, &dest_index, (byte_pair >> (offset - 16)) & 0xFFFF))
2425 return -1;
2426 offset -= 16;
2427 }
2428
2429 src++;
2430 }
2431 while (src < source_end);
2432 }
2433 else
2434 {
2435 /* we have to convert to unsigned char in case *src < 0 */
2436 if (!utf7_write_w(dst, dstlen, &dest_index, (unsigned char)*src))
2437 return -1;
2438 src++;
2439 }
2440 }
2441
2442 return dest_index;
2443}
2444
2445/***********************************************************************
2446 * MultiByteToWideChar (KERNEL32.@)
2447 *
2448 * Convert a multibyte character string into a Unicode string.
2449 *
2450 * PARAMS
2451 * page [I] Codepage character set to convert from
2452 * flags [I] Character mapping flags
2453 * src [I] Source string buffer
2454 * srclen [I] Length of src (in bytes), or -1 if src is NUL terminated
2455 * dst [O] Destination buffer
2456 * dstlen [I] Length of dst (in WCHARs), or 0 to compute the required length
2457 *
2458 * RETURNS
2459 * Success: If dstlen > 0, the number of characters written to dst.
2460 * If dstlen == 0, the number of characters needed to perform the
2461 * conversion. In both cases the count includes the terminating NUL.
2462 * Failure: 0. Use GetLastError() to determine the cause. Possible errors are
2463 * ERROR_INSUFFICIENT_BUFFER, if not enough space is available in dst
2464 * and dstlen != 0; ERROR_INVALID_PARAMETER, if an invalid parameter
2465 * is passed, and ERROR_NO_UNICODE_TRANSLATION if no translation is
2466 * possible for src.
2467 */
2469 LPWSTR dst, INT dstlen )
2470{
2471 const union cptable *table;
2472 int ret;
2473
2474 if (!src || !srclen || (!dst && dstlen) || dstlen < 0)
2475 {
2477 return 0;
2478 }
2479
2480 if (srclen < 0) srclen = strlen(src) + 1;
2481
2482 switch(page)
2483 {
2484 case CP_SYMBOL:
2485 if (flags)
2486 {
2488 return 0;
2489 }
2491 break;
2492 case CP_UTF7:
2493 if (flags)
2494 {
2496 return 0;
2497 }
2499 break;
2500 case CP_UNIXCP:
2501 if (unix_cptable)
2502 {
2504 break;
2505 }
2506#ifdef __APPLE__
2507 flags |= MB_COMPOSITE; /* work around broken Mac OS X filesystem that enforces decomposed Unicode */
2508#endif
2509 /* fall through */
2510 case CP_UTF8:
2511 if (flags & ~MB_FLAGSMASK)
2512 {
2514 return 0;
2515 }
2517 break;
2518 default:
2519 if (!(table = get_codepage_table( page )))
2520 {
2522 return 0;
2523 }
2524 if (flags & ~MB_FLAGSMASK)
2525 {
2527 return 0;
2528 }
2530 break;
2531 }
2532
2533 if (ret < 0)
2534 {
2535 switch(ret)
2536 {
2537 case -1: SetLastError( ERROR_INSUFFICIENT_BUFFER ); break;
2538 case -2: SetLastError( ERROR_NO_UNICODE_TRANSLATION ); break;
2539 }
2540 ret = 0;
2541 }
2542 TRACE("cp %d %s -> %s, ret = %d\n",
2544 return ret;
2545}
2546
2547
2548/***********************************************************************
2549 * utf7_can_directly_encode
2550 *
2551 * Helper for utf7_wcstombs
2552 */
2553static inline BOOL utf7_can_directly_encode(WCHAR codepoint)
2554{
2555 static const BOOL directly_encodable_table[] =
2556 {
2557 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, /* 0x00 - 0x0F */
2558 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1F */
2559 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* 0x20 - 0x2F */
2560 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x30 - 0x3F */
2561 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4F */
2562 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x50 - 0x5F */
2563 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6F */
2564 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* 0x70 - 0x7A */
2565 };
2566
2567 return codepoint <= 0x7A ? directly_encodable_table[codepoint] : FALSE;
2568}
2569
2570/***********************************************************************
2571 * utf7_write_c
2572 *
2573 * Helper for utf7_wcstombs
2574 *
2575 * RETURNS
2576 * TRUE on success, FALSE on error
2577 */
2578static inline BOOL utf7_write_c(char *dst, int dstlen, int *index, char character)
2579{
2580 if (dstlen > 0)
2581 {
2582 if (*index >= dstlen)
2583 return FALSE;
2584
2585 dst[*index] = character;
2586 }
2587
2588 (*index)++;
2589
2590 return TRUE;
2591}
2592
2593/***********************************************************************
2594 * utf7_wcstombs
2595 *
2596 * UTF-16 to UTF-7 string conversion, helper for WideCharToMultiByte
2597 *
2598 * RETURNS
2599 * On success, the number of characters written
2600 * On dst buffer overflow, -1
2601 */
2602static int utf7_wcstombs(const WCHAR *src, int srclen, char *dst, int dstlen)
2603{
2604 static const char base64_encoding_table[] =
2605 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2606
2607 const WCHAR *source_end = src + srclen;
2608 int dest_index = 0;
2609
2610 while (src < source_end)
2611 {
2612 if (*src == '+')
2613 {
2614 if (!utf7_write_c(dst, dstlen, &dest_index, '+'))
2615 return -1;
2616 if (!utf7_write_c(dst, dstlen, &dest_index, '-'))
2617 return -1;
2618 src++;
2619 }
2620 else if (utf7_can_directly_encode(*src))
2621 {
2622 if (!utf7_write_c(dst, dstlen, &dest_index, *src))
2623 return -1;
2624 src++;
2625 }
2626 else
2627 {
2628 unsigned int offset = 0;
2629 DWORD byte_pair = 0;
2630
2631 if (!utf7_write_c(dst, dstlen, &dest_index, '+'))
2632 return -1;
2633
2634 while (src < source_end && !utf7_can_directly_encode(*src))
2635 {
2636 byte_pair = (byte_pair << 16) | *src;
2637 offset += 16;
2638 while (offset >= 6)
2639 {
2640 if (!utf7_write_c(dst, dstlen, &dest_index, base64_encoding_table[(byte_pair >> (offset - 6)) & 0x3F]))
2641 return -1;
2642 offset -= 6;
2643 }
2644 src++;
2645 }
2646
2647 if (offset)
2648 {
2649 /* Windows won't create a padded base64 character if there's no room for the - sign
2650 * as well ; this is probably a bug in Windows */
2651 if (dstlen > 0 && dest_index + 1 >= dstlen)
2652 return -1;
2653
2654 byte_pair <<= (6 - offset);
2655 if (!utf7_write_c(dst, dstlen, &dest_index, base64_encoding_table[byte_pair & 0x3F]))
2656 return -1;
2657 }
2658
2659 /* Windows always explicitly terminates the base64 sequence
2660 even though RFC 2152 (page 3, rule 2) does not require this */
2661 if (!utf7_write_c(dst, dstlen, &dest_index, '-'))
2662 return -1;
2663 }
2664 }
2665
2666 return dest_index;
2667}
2668
2669/***********************************************************************
2670 * WideCharToMultiByte (KERNEL32.@)
2671 *
2672 * Convert a Unicode character string into a multibyte string.
2673 *
2674 * PARAMS
2675 * page [I] Code page character set to convert to
2676 * flags [I] Mapping Flags (MB_ constants from "winnls.h").
2677 * src [I] Source string buffer
2678 * srclen [I] Length of src (in WCHARs), or -1 if src is NUL terminated
2679 * dst [O] Destination buffer
2680 * dstlen [I] Length of dst (in bytes), or 0 to compute the required length
2681 * defchar [I] Default character to use for conversion if no exact
2682 * conversion can be made
2683 * used [O] Set if default character was used in the conversion
2684 *
2685 * RETURNS
2686 * Success: If dstlen > 0, the number of characters written to dst.
2687 * If dstlen == 0, number of characters needed to perform the
2688 * conversion. In both cases the count includes the terminating NUL.
2689 * Failure: 0. Use GetLastError() to determine the cause. Possible errors are
2690 * ERROR_INSUFFICIENT_BUFFER, if not enough space is available in dst
2691 * and dstlen != 0, and ERROR_INVALID_PARAMETER, if an invalid
2692 * parameter was given.
2693 */
2695 LPSTR dst, INT dstlen, LPCSTR defchar, BOOL *used )
2696{
2697 const union cptable *table;
2698 int ret, used_tmp;
2699
2700 if (!src || !srclen || (!dst && dstlen) || dstlen < 0)
2701 {
2703 return 0;
2704 }
2705
2706 if (srclen < 0) srclen = strlenW(src) + 1;
2707
2708 switch(page)
2709 {
2710 case CP_SYMBOL:
2711 /* when using CP_SYMBOL, ERROR_INVALID_FLAGS takes precedence */
2712 if (flags)
2713 {
2715 return 0;
2716 }
2717 if (defchar || used)
2718 {
2720 return 0;
2721 }
2723 break;
2724 case CP_UTF7:
2725 /* when using CP_UTF7, ERROR_INVALID_PARAMETER takes precedence */
2726 if (defchar || used)
2727 {
2729 return 0;
2730 }
2731 if (flags)
2732 {
2734 return 0;
2735 }
2737 break;
2738 case CP_UNIXCP:
2739 if (unix_cptable)
2740 {
2742 defchar, used ? &used_tmp : NULL );
2743 break;
2744 }
2745 /* fall through */
2746 case CP_UTF8:
2747 if (defchar || used)
2748 {
2750 return 0;
2751 }
2752 if (flags & ~WC_FLAGSMASK)
2753 {
2755 return 0;
2756 }
2758 break;
2759 default:
2760 if (!(table = get_codepage_table( page )))
2761 {
2763 return 0;
2764 }
2765 if (flags & ~WC_FLAGSMASK)
2766 {
2768 return 0;
2769 }
2771 defchar, used ? &used_tmp : NULL );
2772 if (used) *used = used_tmp;
2773 break;
2774 }
2775
2776 if (ret < 0)
2777 {
2778 switch(ret)
2779 {
2780 case -1: SetLastError( ERROR_INSUFFICIENT_BUFFER ); break;
2781 case -2: SetLastError( ERROR_NO_UNICODE_TRANSLATION ); break;
2782 }
2783 ret = 0;
2784 }
2785 TRACE("cp %d %s -> %s, ret = %d\n",
2787 return ret;
2788}
2789#endif // !__REACTOS__
2790
2791
2792/***********************************************************************
2793 * GetThreadLocale (KERNEL32.@)
2794 *
2795 * Get the current threads locale.
2796 *
2797 * PARAMS
2798 * None.
2799 *
2800 * RETURNS
2801 * The LCID currently associated with the calling thread.
2802 */
2804{
2805 LCID ret = NtCurrentTeb()->CurrentLocale;
2806 if (!ret) NtCurrentTeb()->CurrentLocale = ret = GetUserDefaultLCID();
2807 return ret;
2808}
2809
2810/**********************************************************************
2811 * SetThreadLocale (KERNEL32.@)
2812 *
2813 * Set the current threads locale.
2814 *
2815 * PARAMS
2816 * lcid [I] LCID of the locale to set
2817 *
2818 * RETURNS
2819 * Success: TRUE. The threads locale is set to lcid.
2820 * Failure: FALSE. Use GetLastError() to determine the cause.
2821 */
2823{
2824 TRACE("(0x%04X)\n", lcid);
2825
2827
2828 if (lcid != GetThreadLocale())
2829 {
2831 {
2833 return FALSE;
2834 }
2835
2836 NtCurrentTeb()->CurrentLocale = lcid;
2837 }
2838 return TRUE;
2839}
2840
2841#ifndef __REACTOS__
2842/**********************************************************************
2843 * SetThreadUILanguage (KERNEL32.@)
2844 *
2845 * Set the current threads UI language.
2846 *
2847 * PARAMS
2848 * langid [I] LANGID of the language to set, or 0 to use
2849 * the available language which is best supported
2850 * for console applications
2851 *
2852 * RETURNS
2853 * Success: The return value is the same as the input value.
2854 * Failure: The return value differs from the input value.
2855 * Use GetLastError() to determine the cause.
2856 */
2858{
2859 TRACE("(0x%04x) stub - returning success\n", langid);
2860 return langid;
2861}
2862#endif // !__REACTOS__
2863
2864/******************************************************************************
2865 * ConvertDefaultLocale (KERNEL32.@)
2866 *
2867 * Convert a default locale identifier into a real identifier.
2868 *
2869 * PARAMS
2870 * lcid [I] LCID identifier of the locale to convert
2871 *
2872 * RETURNS
2873 * lcid unchanged, if not a default locale or its sublanguage is
2874 * not SUBLANG_NEUTRAL.
2875 * GetSystemDefaultLCID(), if lcid == LOCALE_SYSTEM_DEFAULT.
2876 * GetUserDefaultLCID(), if lcid == LOCALE_USER_DEFAULT or LOCALE_NEUTRAL.
2877 * Otherwise, lcid with sublanguage changed to SUBLANG_DEFAULT.
2878 */
2880{
2881 LANGID langid;
2882
2883 switch (lcid)
2884 {
2885 case LOCALE_INVARIANT:
2886 /* keep as-is */
2887 break;
2890 break;
2892 case LOCALE_NEUTRAL:
2894 break;
2895 default:
2896 /* Replace SUBLANG_NEUTRAL with SUBLANG_DEFAULT */
2899 {
2902 }
2903 }
2904 return lcid;
2905}
2906
2907
2908/******************************************************************************
2909 * IsValidLocale (KERNEL32.@)
2910 *
2911 * Determine if a locale is valid.
2912 *
2913 * PARAMS
2914 * lcid [I] LCID of the locale to check
2915 * flags [I] LCID_SUPPORTED = Valid, LCID_INSTALLED = Valid and installed on the system
2916 *
2917 * RETURNS
2918 * TRUE, if lcid is valid,
2919 * FALSE, otherwise.
2920 *
2921 * NOTES
2922 * Wine does not currently make the distinction between supported and installed. All
2923 * languages supported are installed by default.
2924 */
2926{
2927 /* check if language is registered in the kernel32 resources */
2930}
2931
2932#ifndef __REACTOS__
2933/******************************************************************************
2934 * IsValidLocaleName (KERNEL32.@)
2935 */
2937{
2938 struct locale_name locale_name;
2939
2940 if (!locale)
2941 return FALSE;
2942
2943 /* string parsing */
2944 parse_locale_name( locale, &locale_name );
2945
2946 TRACE( "found lcid %x for %s, matches %d\n",
2948
2949 return locale_name.matches > 0;
2950}
2951#endif // !__REACTOS__
2952
2955{
2956 LOCALE_ENUMPROCA lpfnLocaleEnum = (LOCALE_ENUMPROCA)lParam;
2957 char buf[20];
2958
2959 sprintf(buf, "%08x", (UINT)LangID);
2960 return lpfnLocaleEnum( buf );
2961}
2962
2965{
2966 static const WCHAR formatW[] = {'%','0','8','x',0};
2967 LOCALE_ENUMPROCW lpfnLocaleEnum = (LOCALE_ENUMPROCW)lParam;
2968 WCHAR buf[20];
2969 sprintfW( buf, formatW, (UINT)LangID );
2970 return lpfnLocaleEnum( buf );
2971}
2972
2973/******************************************************************************
2974 * EnumSystemLocalesA (KERNEL32.@)
2975 *
2976 * Call a users function for each locale available on the system.
2977 *
2978 * PARAMS
2979 * lpfnLocaleEnum [I] Callback function to call for each locale
2980 * dwFlags [I] LOCALE_SUPPORTED=All supported, LOCALE_INSTALLED=Installed only
2981 *
2982 * RETURNS
2983 * Success: TRUE.
2984 * Failure: FALSE. Use GetLastError() to determine the cause.
2985 */
2987{
2988 TRACE("(%p,%08x)\n", lpfnLocaleEnum, dwFlags);
2991 (LONG_PTR)lpfnLocaleEnum);
2992 return TRUE;
2993}
2994
2995
2996/******************************************************************************
2997 * EnumSystemLocalesW (KERNEL32.@)
2998 *
2999 * See EnumSystemLocalesA.
3000 */
3002{
3003 TRACE("(%p,%08x)\n", lpfnLocaleEnum, dwFlags);
3006 (LONG_PTR)lpfnLocaleEnum);
3007 return TRUE;
3008}
3009
3010
3012{
3014 DWORD flags;
3015 LPARAM lparam;
3016};
3017
3018#if 0
3021{
3023 WCHAR buffer[256];
3024 DWORD neutral;
3025 unsigned int flags;
3026
3028 buffer, sizeof(buffer) / sizeof(WCHAR) );
3030 LOCALE_INEUTRAL | LOCALE_NOUSEROVERRIDE | LOCALE_RETURN_NUMBER,
3031 (LPWSTR)&neutral, sizeof(neutral) / sizeof(WCHAR) ))
3032 neutral = 0;
3035 if (data->flags && !(data->flags & flags)) return TRUE;
3036 return data->proc( buffer, flags, data->lparam );
3037}
3038
3039/******************************************************************************
3040 * EnumSystemLocalesEx (KERNEL32.@)
3041 */
3043{
3045
3046 if (reserved)
3047 {
3049 return FALSE;
3050 }
3051 data.proc = proc;
3052 data.flags = flags;
3053 data.lparam = lparam;
3057 return TRUE;
3058}
3059#endif
3060
3061/***********************************************************************
3062 * VerLanguageNameA (KERNEL32.@)
3063 *
3064 * Get the name of a language.
3065 *
3066 * PARAMS
3067 * wLang [I] LANGID of the language
3068 * szLang [O] Destination for the language name
3069 *
3070 * RETURNS
3071 * Success: The size of the language name. If szLang is non-NULL, it is filled
3072 * with the name.
3073 * Failure: 0. Use GetLastError() to determine the cause.
3074 *
3075 */
3077{
3078 return GetLocaleInfoA( MAKELCID(wLang, SORT_DEFAULT), LOCALE_SENGLANGUAGE, szLang, nSize );
3079}
3080
3081
3082/***********************************************************************
3083 * VerLanguageNameW (KERNEL32.@)
3084 *
3085 * See VerLanguageNameA.
3086 */
3088{
3089 return GetLocaleInfoW( MAKELCID(wLang, SORT_DEFAULT), LOCALE_SENGLANGUAGE, szLang, nSize );
3090}
3091
3092
3093/******************************************************************************
3094 * GetStringTypeW (KERNEL32.@)
3095 *
3096 * See GetStringTypeA.
3097 */
3099{
3100 static const unsigned char type2_map[16] =
3101 {
3102 C2_NOTAPPLICABLE, /* unassigned */
3103 C2_LEFTTORIGHT, /* L */
3104 C2_RIGHTTOLEFT, /* R */
3105 C2_EUROPENUMBER, /* EN */
3106 C2_EUROPESEPARATOR, /* ES */
3107 C2_EUROPETERMINATOR, /* ET */
3108 C2_ARABICNUMBER, /* AN */
3109 C2_COMMONSEPARATOR, /* CS */
3110 C2_BLOCKSEPARATOR, /* B */
3111 C2_SEGMENTSEPARATOR, /* S */
3112 C2_WHITESPACE, /* WS */
3113 C2_OTHERNEUTRAL, /* ON */
3114 C2_RIGHTTOLEFT, /* AL */
3115 C2_NOTAPPLICABLE, /* NSM */
3116 C2_NOTAPPLICABLE, /* BN */
3117 C2_OTHERNEUTRAL /* LRE, LRO, RLE, RLO, PDF */
3118 };
3119
3120 if (!src)
3121 {
3123 return FALSE;
3124 }
3125
3126 if (count == -1) count = strlenW(src) + 1;
3127 switch(type)
3128 {
3129 case CT_CTYPE1:
3130 while (count--) *chartype++ = get_char_typeW( *src++ ) & 0xfff;
3131 break;
3132 case CT_CTYPE2:
3133 while (count--) *chartype++ = type2_map[get_char_typeW( *src++ ) >> 12];
3134 break;
3135 case CT_CTYPE3:
3136 {
3137 WARN("CT_CTYPE3: semi-stub.\n");
3138 while (count--)
3139 {
3140 int c = *src;
3141 WORD type1, type3 = 0; /* C3_NOTAPPLICABLE */
3142
3143 type1 = get_char_typeW( *src++ ) & 0xfff;
3144 /* try to construct type3 from type1 */
3145 if(type1 & C1_SPACE) type3 |= C3_SYMBOL;
3146 if(type1 & C1_ALPHA) type3 |= C3_ALPHA;
3147 if ((c>=0x30A0)&&(c<=0x30FF)) type3 |= C3_KATAKANA;
3148 if ((c>=0x3040)&&(c<=0x309F)) type3 |= C3_HIRAGANA;
3149 if ((c>=0x4E00)&&(c<=0x9FAF)) type3 |= C3_IDEOGRAPH;
3150 if (c == 0x0640) type3 |= C3_KASHIDA;
3151 if ((c>=0x3000)&&(c<=0x303F)) type3 |= C3_SYMBOL;
3152
3153 if ((c>=0xD800)&&(c<=0xDBFF)) type3 |= C3_HIGHSURROGATE;
3154 if ((c>=0xDC00)&&(c<=0xDFFF)) type3 |= C3_LOWSURROGATE;
3155
3156 if ((c>=0xFF00)&&(c<=0xFF60)) type3 |= C3_FULLWIDTH;
3157 if ((c>=0xFF00)&&(c<=0xFF20)) type3 |= C3_SYMBOL;
3158 if ((c>=0xFF3B)&&(c<=0xFF40)) type3 |= C3_SYMBOL;
3159 if ((c>=0xFF5B)&&(c<=0xFF60)) type3 |= C3_SYMBOL;
3160 if ((c>=0xFF21)&&(c<=0xFF3A)) type3 |= C3_ALPHA;
3161 if ((c>=0xFF41)&&(c<=0xFF5A)) type3 |= C3_ALPHA;
3162 if ((c>=0xFFE0)&&(c<=0xFFE6)) type3 |= C3_FULLWIDTH;
3163 if ((c>=0xFFE0)&&(c<=0xFFE6)) type3 |= C3_SYMBOL;
3164
3165 if ((c>=0xFF61)&&(c<=0xFFDC)) type3 |= C3_HALFWIDTH;
3166 if ((c>=0xFF61)&&(c<=0xFF64)) type3 |= C3_SYMBOL;
3167 if ((c>=0xFF65)&&(c<=0xFF9F)) type3 |= C3_KATAKANA;
3168 if ((c>=0xFF65)&&(c<=0xFF9F)) type3 |= C3_ALPHA;
3169 if ((c>=0xFFE8)&&(c<=0xFFEE)) type3 |= C3_HALFWIDTH;
3170 if ((c>=0xFFE8)&&(c<=0xFFEE)) type3 |= C3_SYMBOL;
3171 *chartype++ = type3;
3172 }
3173 break;
3174 }
3175 default:
3177 return FALSE;
3178 }
3179 return TRUE;
3180}
3181
3182
3183/******************************************************************************
3184 * GetStringTypeExW (KERNEL32.@)
3185 *
3186 * See GetStringTypeExA.
3187 */
3189{
3190 /* locale is ignored for Unicode */
3191 return GetStringTypeW( type, src, count, chartype );
3192}
3193
3194
3195/******************************************************************************
3196 * GetStringTypeA (KERNEL32.@)
3197 *
3198 * Get characteristics of the characters making up a string.
3199 *
3200 * PARAMS
3201 * locale [I] Locale Id for the string
3202 * type [I] CT_CTYPE1 = classification, CT_CTYPE2 = directionality, CT_CTYPE3 = typographic info
3203 * src [I] String to analyse
3204 * count [I] Length of src in chars, or -1 if src is NUL terminated
3205 * chartype [O] Destination for the calculated characteristics
3206 *
3207 * RETURNS
3208 * Success: TRUE. chartype is filled with the requested characteristics of each char
3209 * in src.
3210 * Failure: FALSE. Use GetLastError() to determine the cause.
3211 */
3213{
3214 UINT cp;
3215 INT countW;
3216 LPWSTR srcW;
3217 BOOL ret = FALSE;
3218
3219 if(count == -1) count = strlen(src) + 1;
3220
3221 if (!(cp = get_lcid_codepage( locale )))
3222 {
3223 FIXME("For locale %04x using current ANSI code page\n", locale);
3224 cp = GetACP();
3225 }
3226
3227 countW = MultiByteToWideChar(cp, 0, src, count, NULL, 0);
3228 if((srcW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
3229 {
3230 MultiByteToWideChar(cp, 0, src, count, srcW, countW);
3231 /*
3232 * NOTE: the target buffer has 1 word for each CHARACTER in the source
3233 * string, with multibyte characters there maybe be more bytes in count
3234 * than character space in the buffer!
3235 */
3236 ret = GetStringTypeW(type, srcW, countW, chartype);
3237 HeapFree(GetProcessHeap(), 0, srcW);
3238 }
3239 return ret;
3240}
3241
3242/******************************************************************************
3243 * GetStringTypeExA (KERNEL32.@)
3244 *
3245 * Get characteristics of the characters making up a string.
3246 *
3247 * PARAMS
3248 * locale [I] Locale Id for the string
3249 * type [I] CT_CTYPE1 = classification, CT_CTYPE2 = directionality, CT_CTYPE3 = typographic info
3250 * src [I] String to analyse
3251 * count [I] Length of src in chars, or -1 if src is NUL terminated
3252 * chartype [O] Destination for the calculated characteristics
3253 *
3254 * RETURNS
3255 * Success: TRUE. chartype is filled with the requested characteristics of each char
3256 * in src.
3257 * Failure: FALSE. Use GetLastError() to determine the cause.
3258 */
3260{
3261 return GetStringTypeA(locale, type, src, count, chartype);
3262}
3263
3264#ifdef __REACTOS__
3265static inline void map_byterev(const WCHAR *src, int len, WCHAR *dst)
3266{
3267 while (len--)
3268 *dst++ = RtlUshortByteSwap(*src++);
3269}
3270
3271static int map_to_hiragana(const WCHAR *src, int srclen, WCHAR *dst, int dstlen)
3272{
3273 int pos;
3274 for (pos = 0; srclen; src++, srclen--, pos++)
3275 {
3276 /*
3277 * U+30A1 ... U+30F3: Katakana
3278 * U+30F4: Katakana Letter VU
3279 * U+30F5: Katakana Letter Small KA
3280 * U+30FD: Katakana Iteration Mark
3281 * U+30FE: Katakana Voiced Iteration Mark
3282 */
3283 WCHAR wch = *src;
3284 if ((0x30A1 <= wch && wch <= 0x30F3) ||
3285 wch == 0x30F4 || wch == 0x30F5 || wch == 0x30FD || wch == 0x30FE)
3286 {
3287 wch -= 0x60; /* Katakana to Hiragana */
3288 }
3289 if (pos < dstlen)
3290 dst[pos] = wch;
3291 }
3292 return pos;
3293}
3294
3295static int map_to_katakana(const WCHAR *src, int srclen, WCHAR *dst, int dstlen)
3296{
3297 int pos;
3298 for (pos = 0; srclen; src++, srclen--, pos++)
3299 {
3300 /*
3301 * U+3041 ... U+3093: Hiragana
3302 * U+3094: Hiragana Letter VU
3303 * U+3095: Hiragana Letter Small KA
3304 * U+309D: Hiragana Iteration Mark
3305 * U+309E: Hiragana Voiced Iteration Mark
3306 */
3307 WCHAR wch = *src;
3308 if ((0x3041 <= wch && wch <= 0x3093) ||
3309 wch == 3094 || wch == 0x3095 || wch == 0x309D || wch == 0x309E)
3310 {
3311 wch += 0x60; /* Hiragana to Katakana */
3312 }
3313 if (pos < dstlen)
3314 dst[pos] = wch;
3315 }
3316 return pos;
3317}
3318
3319/* The table that contains fullwidth characters and halfwidth characters */
3320typedef WCHAR FULL2HALF_ENTRY[3];
3321static const FULL2HALF_ENTRY full2half_table[] =
3322{
3323#define DEFINE_FULL2HALF(full, half1, half2) { full, half1, half2 },
3324#include "full2half.h"
3325#undef DEFINE_FULL2HALF
3326};
3327#define GET_FULL(table, index) ((table)[index][0])
3328#define GET_HALF1(table, index) ((table)[index][1])
3329#define GET_HALF2(table, index) ((table)[index][2])
3330
3331/* The table that contains dakuten entries */
3332typedef WCHAR DAKUTEN_ENTRY[3];
3333static const DAKUTEN_ENTRY dakuten_table[] =
3334{
3335#define DEFINE_DAKUTEN(voiced, single1, single2, half1, half2) { voiced, single1, single2 },
3336#include "dakuten.h"
3337#undef DEFINE_DAKUTEN
3338};
3339#define GET_VOICED(table, index) ((table)[index][0])
3340#define GET_SINGLE1(table, index) ((table)[index][1])
3341#define GET_SINGLE2(table, index) ((table)[index][2])
3342
3343static int map_to_halfwidth(DWORD flags, const WCHAR *src, int srclen, WCHAR *dst, int dstlen)
3344{
3345 int pos, i;
3346 const int count1 = (int)ARRAY_SIZE(full2half_table);
3347 const FULL2HALF_ENTRY *table1 = full2half_table;
3348
3349 for (pos = 0; srclen; src++, srclen--, pos++)
3350 {
3351 WCHAR ch = *src;
3352
3353 if (flags & LCMAP_KATAKANA)
3354 map_to_katakana(&ch, 1, &ch, 1);
3355 else if (flags & LCMAP_HIRAGANA)
3356 map_to_hiragana(&ch, 1, &ch, 1);
3357
3358 if (ch < 0x3000) /* Quick judgment */
3359 {
3360 if (pos < dstlen)
3361 dst[pos] = ch;
3362 continue;
3363 }
3364
3365 if (0xFF01 <= ch && ch <= 0xFF5E) /* U+FF01 ... U+FF5E */
3366 {
3367 if (pos < dstlen)
3368 dst[pos] = ch - 0xFEE0; /* Fullwidth ASCII to halfwidth ASCII */
3369 continue;
3370 }
3371
3372 /* Search in table1 (full/half) */
3373 for (i = count1 - 1; i >= 0; --i) /* In reverse order */
3374 {
3375 if (GET_FULL(table1, i) != ch)
3376 continue;
3377
3378 if (GET_HALF2(table1, i) == 0)
3379 {
3380 if (pos < dstlen)
3381 dst[pos] = GET_HALF1(table1, i);
3382 }
3383 else if (!dstlen)
3384 {
3385 pos++;
3386 }
3387 else if (pos + 1 < dstlen)
3388 {
3389 dst[pos++] = GET_HALF1(table1, i);
3390 dst[pos ] = GET_HALF2(table1, i);
3391 }
3392 else
3393 {
3394 dst[pos] = ch;
3395 }
3396 break;
3397 }
3398
3399 if (i >= 0)
3400 continue;
3401
3402 if (pos < dstlen)
3403 dst[pos] = ch;
3404 }
3405
3406 return pos;
3407}
3408
3409static int map_to_fullwidth(const WCHAR *src, int srclen, WCHAR *dst, int dstlen)
3410{
3411 int pos, i;
3412 const FULL2HALF_ENTRY *table1 = full2half_table;
3413 const DAKUTEN_ENTRY *table2 = dakuten_table;
3414 const int count1 = (int)ARRAY_SIZE(full2half_table);
3415 const int count2 = (int)ARRAY_SIZE(dakuten_table);
3416
3417 for (pos = 0; srclen; src++, srclen--, pos++)
3418 {
3419 WCHAR ch = *src;
3420
3421 if (ch == 0x20) /* U+0020: Space */
3422 {
3423 if (pos < dstlen)
3424 dst[pos] = 0x3000; /* U+3000: Ideographic Space */
3425 continue;
3426 }
3427
3428 if (0x21 <= ch && ch <= 0x7E) /* Mappable halfwidth ASCII */
3429 {
3430 if (pos < dstlen)
3431 dst[pos] = ch + 0xFEE0; /* U+FF01 ... U+FF5E */
3432 continue;
3433 }
3434
3435 if (ch < 0xFF00) /* Quick judgment */
3436 {
3437 if (pos < dstlen)
3438 dst[pos] = ch;
3439 continue;
3440 }
3441
3442 /* Search in table1 (full/half) */
3443 for (i = count1 - 1; i >= 0; --i) /* In reverse order */
3444 {
3445 if (GET_HALF1(table1, i) != ch)
3446 continue; /* Mismatched */
3447
3448 if (GET_HALF2(table1, i) == 0)
3449 {
3450 if (pos < dstlen)
3451 dst[pos] = GET_FULL(table1, i);
3452 break;
3453 }
3454
3455 if (srclen <= 1 || GET_HALF2(table1, i) != src[1])
3456 continue; /* Mismatched */
3457
3458 --srclen;
3459 ++src;
3460
3461 if (pos < dstlen)
3462 dst[pos] = GET_FULL(table1, i);
3463 break;
3464 }
3465
3466 if (i >= 0)
3467 continue;
3468
3469 /* Search in table2 (dakuten) */
3470 for (i = count2 - 1; i >= 0; --i) /* In reverse order */
3471 {
3472 if (GET_SINGLE1(table2, i) != ch)
3473 continue; /* Mismatched */
3474
3475 if (srclen <= 1 || GET_SINGLE2(table2, i) != src[1])
3476 continue; /* Mismatched */
3477
3478 --srclen;
3479 ++src;
3480
3481 if (pos < dstlen)
3482 dst[pos] = GET_VOICED(table2, i);
3483 break;
3484 }
3485
3486 if (i >= 0)
3487 continue;
3488
3489 if (pos < dstlen)
3490 dst[pos] = ch;
3491 }
3492
3493 return pos;
3494}
3495
3496static int map_to_lowercase(DWORD flags, const WCHAR *src, int srclen, WCHAR *dst, int dstlen)
3497{
3498 int pos;
3499 for (pos = 0; srclen; src++, srclen--)
3500 {
3501 WCHAR wch = *src;
3503 continue;
3504 if (pos < dstlen)
3505 dst[pos] = tolowerW(wch);
3506 pos++;
3507 }
3508 return pos;
3509}
3510
3511static int map_to_uppercase(DWORD flags, const WCHAR *src, int srclen, WCHAR *dst, int dstlen)
3512{
3513 int pos;
3514 for (pos = 0; srclen; src++, srclen--)
3515 {
3516 WCHAR wch = *src;
3518 continue;
3519 if (pos < dstlen)
3520 dst[pos] = toupperW(wch);
3521 pos++;
3522 }
3523 return pos;
3524}
3525
3526typedef struct tagWCHAR_PAIR
3527{
3528 WCHAR from, to;
3529} WCHAR_PAIR, *PWCHAR_PAIR;
3530
3531/* The table to convert Simplified Chinese to Traditional Chinese */
3532static const WCHAR_PAIR s_sim2tra[] =
3533{
3534#define DEFINE_SIM2TRA(from, to) { from, to },
3535#include "sim2tra.h"
3536#undef DEFINE_SIM2TRA
3537};
3538
3539/* The table to convert Traditional Chinese to Simplified Chinese */
3540static const WCHAR_PAIR s_tra2sim[] =
3541{
3542#define DEFINE_TRA2SIM(from, to) { from, to },
3543#include "tra2sim.h"
3544#undef DEFINE_TRA2SIM
3545};
3546
3547/* The comparison function to do bsearch */
3548static int compare_wchar_pair(const void *x, const void *y)
3549{
3550 const WCHAR_PAIR *a = x;
3551 const WCHAR_PAIR *b = y;
3552 if (a->from < b->from)
3553 return -1;
3554 if (a->from > b->from)
3555 return +1;
3556 return 0;
3557}
3558
3559static WCHAR find_wchar_pair(const WCHAR_PAIR *pairs, size_t count, WCHAR ch)
3560{
3561 PWCHAR_PAIR found = bsearch(&ch, pairs, count, sizeof(WCHAR_PAIR), compare_wchar_pair);
3562 if (found)
3563 return found->to;
3564 return ch;
3565}
3566
3567static int map_to_simplified_chinese(DWORD flags, const WCHAR *src, int srclen, WCHAR *dst, int dstlen)
3568{
3569 int pos;
3570 for (pos = 0; srclen; src++, srclen--)
3571 {
3572 WCHAR wch = *src;
3573 if (pos < dstlen)
3574 dst[pos] = find_wchar_pair(s_tra2sim, ARRAY_SIZE(s_tra2sim), wch);
3575 pos++;
3576 }
3577 return pos;
3578}
3579
3580static int map_to_traditional_chinese(DWORD flags, const WCHAR *src, int srclen, WCHAR *dst, int dstlen)
3581{
3582 int pos;
3583 for (pos = 0; srclen; src++, srclen--)
3584 {
3585 WCHAR wch = *src;
3586 if (pos < dstlen)
3587 dst[pos] = find_wchar_pair(s_sim2tra, ARRAY_SIZE(s_sim2tra), wch);
3588 pos++;
3589 }
3590 return pos;
3591}
3592
3593static int map_remove_ignored(DWORD flags, const WCHAR *src, int srclen, WCHAR *dst, int dstlen)
3594{
3595 int pos;
3596 WORD wC1, wC2, wC3;
3597 for (pos = 0; srclen; src++, srclen--)
3598 {
3599 WCHAR wch = *src;
3600 GetStringTypeW(CT_CTYPE1, &wch, 1, &wC1);
3601 GetStringTypeW(CT_CTYPE2, &wch, 1, &wC2);
3602 GetStringTypeW(CT_CTYPE3, &wch, 1, &wC3);
3604 {
3605 if ((wC1 & C1_PUNCT) || (wC3 & C3_SYMBOL))
3606 continue;
3607 }
3609 {
3610 if ((wC2 & C2_OTHERNEUTRAL) && (wC3 & (C3_NONSPACING | C3_DIACRITIC)))
3611 continue;
3612 }
3613 if (pos < dstlen)
3614 dst[pos] = wch;
3615 pos++;
3616 }
3617 return pos;
3618}
3619
3620static int lcmap_string(DWORD flags, const WCHAR *src, int srclen, WCHAR *dst, int dstlen)
3621{
3622 int ret = 0;
3623
3625 {
3627 return 0;
3628 }
3629
3631 {
3632 case LCMAP_HIRAGANA:
3633 ret = map_to_hiragana(src, srclen, dst, dstlen);
3634 break;
3635 case LCMAP_KATAKANA:
3636 ret = map_to_katakana(src, srclen, dst, dstlen);
3637 break;
3638 case LCMAP_HALFWIDTH:
3640 break;
3643 break;
3646 break;
3647 case LCMAP_FULLWIDTH:
3649 break;
3652 if (dstlen && ret)
3653 map_to_hiragana(dst, ret, dst, dstlen);
3654 break;
3657 if (dstlen && ret)
3658 map_to_katakana(dst, ret, dst, dstlen);
3659 break;
3661 ret = map_to_simplified_chinese(flags, src, srclen, dst, dstlen);
3662 break;
3664 ret = map_to_traditional_chinese(flags, src, srclen, dst, dstlen);
3665 break;
3667 case NORM_IGNORESYMBOLS:
3670 {
3672 return 0;
3673 }
3675 break;
3676 case 0:
3677 if (flags & LCMAP_LOWERCASE)
3678 {
3679 ret = map_to_lowercase(flags, src, srclen, dst, dstlen);
3680 flags &= ~LCMAP_LOWERCASE;
3681 break;
3682 }
3683 if (flags & LCMAP_UPPERCASE)
3684 {
3685 ret = map_to_uppercase(flags, src, srclen, dst, dstlen);
3686 flags &= ~LCMAP_UPPERCASE;
3687 break;
3688 }
3689 if (flags & LCMAP_BYTEREV)
3690 {
3691 if (dstlen == 0)
3692 {
3693 ret = srclen;
3694 break;
3695 }
3696 ret = min(srclen, dstlen);
3697 RtlCopyMemory(dst, src, ret * sizeof(WCHAR));
3698 break;
3699 }
3700 /* fall through */
3701 default:
3703 return 0;
3704 }
3705
3706 if (dstlen)
3707 {
3708 if (flags & LCMAP_LOWERCASE)
3709 map_to_lowercase(flags, dst, ret, dst, dstlen);
3710 if (flags & LCMAP_UPPERCASE)
3711 map_to_uppercase(flags, dst, ret, dst, dstlen);
3712 if (flags & LCMAP_BYTEREV)
3714
3715 if (dstlen < ret)
3716 {
3718 return 0;
3719 }
3720 }
3721
3722 return ret;
3723}
3724#endif // __REACTOS__
3725
3726/*************************************************************************
3727 * LCMapStringEx (KERNEL32.@)
3728 *
3729 * Map characters in a locale sensitive string.
3730 *
3731 * PARAMS
3732 * locale [I] Locale name for the conversion.
3733 * flags [I] Flags controlling the mapping (LCMAP_ constants from "winnls.h")
3734 * src [I] String to map
3735 * srclen [I] Length of src in chars, or -1 if src is NUL terminated
3736 * dst [O] Destination for mapped string
3737 * dstlen [I] Length of dst in characters
3738 * version [I] reserved, must be NULL
3739 * reserved [I] reserved, must be NULL
3740 * lparam [I] reserved, must be 0
3741 *
3742 * RETURNS
3743 * Success: The length of the mapped string in dst, including the NUL terminator.
3744 * Failure: 0. Use GetLastError() to determine the cause.
3745 */
3748{
3749 if (version) FIXME("unsupported version structure %p\n", version);
3750 if (reserved) FIXME("unsupported reserved pointer %p\n", reserved);
3751 if (handle)
3752 {
3753 static int once;
3754 if (!once++) FIXME("unsupported lparam %Ix\n", handle);
3755 }
3756
3757 if (!src || !srclen || dstlen < 0)
3758 {
3760 return 0;
3761 }
3762
3763 if (srclen < 0) srclen = lstrlenW(src) + 1;
3764
3765 TRACE( "(%s,0x%08lx,%s,%d,%p,%d)\n",
3767
3768 flags &= ~LOCALE_USE_CP_ACP;
3769
3770 if (src == dst && (flags & ~(LCMAP_LOWERCASE | LCMAP_UPPERCASE)))
3771 {
3773 return 0;
3774 }
3775
3776 if (!dstlen) dst = NULL;
3777
3778 if (flags & LCMAP_SORTKEY)
3779 {
3780 INT ret;
3781
3782 if (srclen < 0)
3783 srclen = strlenW(src);
3784
3785 ret = wine_get_sortkey(flags, src, srclen, (char *)dst, dstlen);
3786 if (ret == 0)
3788 else
3789 ret++;
3790 return ret;
3791 }
3792
3793 /* SORT_STRINGSORT must be used exclusively with LCMAP_SORTKEY */
3794 if (flags & SORT_STRINGSORT)
3795 {
3797 return 0;
3798 }
3799
3800 return lcmap_string(flags, src, srclen, dst, dstlen);
3801}
3802
3803/*************************************************************************
3804 * LCMapStringW (KERNEL32.@)
3805 *
3806 * See LCMapStringA.
3807 */
3810{
3811 TRACE("(0x%04x,0x%08x,%s,%d,%p,%d)\n",
3813
3814 return LCMapStringEx(NULL, flags, src, srclen, dst, dstlen, NULL, NULL, 0);
3815}
3816
3817/*************************************************************************
3818 * LCMapStringA (KERNEL32.@)
3819 *
3820 * Map characters in a locale sensitive string.
3821 *
3822 * PARAMS
3823 * lcid [I] LCID for the conversion.
3824 * flags [I] Flags controlling the mapping (LCMAP_ constants from "winnls.h").
3825 * src [I] String to map
3826 * srclen [I] Length of src in chars, or -1 if src is NUL terminated
3827 * dst [O] Destination for mapped string
3828 * dstlen [I] Length of dst in characters
3829 *
3830 * RETURNS
3831 * Success: The length of the mapped string in dst, including the NUL terminator.
3832 * Failure: 0. Use GetLastError() to determine the cause.
3833 */
3836{
3837 WCHAR *bufW = NtCurrentTeb()->StaticUnicodeBuffer;
3838 LPWSTR srcW, dstW;
3839 INT ret = 0, srclenW, dstlenW;
3840 UINT locale_cp = CP_ACP;
3841
3842 if (!src || !srclen || dstlen < 0)
3843 {
3845 return 0;
3846 }
3847
3848 if (!(flags & LOCALE_USE_CP_ACP)) locale_cp = get_lcid_codepage( lcid );
3849
3850 srclenW = MultiByteToWideChar(locale_cp, 0, src, srclen, bufW, 260);
3851 if (srclenW)
3852 srcW = bufW;
3853 else
3854 {
3855 srclenW = MultiByteToWideChar(locale_cp, 0, src, srclen, NULL, 0);
3856 srcW = HeapAlloc(GetProcessHeap(), 0, srclenW * sizeof(WCHAR));
3857 if (!srcW)
3858 {
3860 return 0;
3861 }
3862 MultiByteToWideChar(locale_cp, 0, src, srclen, srcW, srclenW);
3863 }
3864
3865 if (flags & LCMAP_SORTKEY)
3866 {
3867 if (src == dst)
3868 {
3870 goto map_string_exit;
3871 }
3872 ret = wine_get_sortkey(flags, srcW, srclenW, dst, dstlen);
3873 if (ret == 0)
3875 else
3876 ret++;
3877 goto map_string_exit;
3878 }
3879
3880 if (flags & SORT_STRINGSORT)
3881 {
3883 goto map_string_exit;
3884 }
3885
3886 dstlenW = LCMapStringEx(NULL, flags, srcW, srclenW, NULL, 0, NULL, NULL, 0);
3887 if (!dstlenW)
3888 goto map_string_exit;
3889
3890 dstW = HeapAlloc(GetProcessHeap(), 0, dstlenW * sizeof(WCHAR));
3891 if (!dstW)
3892 {
3894 goto map_string_exit;
3895 }
3896
3897 LCMapStringEx(NULL, flags, srcW, srclenW, dstW, dstlenW, NULL, NULL, 0);
3898 ret = WideCharToMultiByte(locale_cp, 0, dstW, dstlenW, dst, dstlen, NULL, NULL);
3899 HeapFree(GetProcessHeap(), 0, dstW);
3900
3901map_string_exit:
3902 if (srcW != bufW) HeapFree(GetProcessHeap(), 0, srcW);
3903 return ret;
3904}
3905
3906/*************************************************************************
3907 * FoldStringA (KERNEL32.@)
3908 *
3909 * Map characters in a string.
3910 *
3911 * PARAMS
3912 * dwFlags [I] Flags controlling chars to map (MAP_ constants from "winnls.h")
3913 * src [I] String to map
3914 * srclen [I] Length of src, or -1 if src is NUL terminated
3915 * dst [O] Destination for mapped string
3916 * dstlen [I] Length of dst, or 0 to find the required length for the mapped string
3917 *
3918 * RETURNS
3919 * Success: The length of the string written to dst, including the terminating NUL. If
3920 * dstlen is 0, the value returned is the same, but nothing is written to dst,
3921 * and dst may be NULL.
3922 * Failure: 0. Use GetLastError() to determine the cause.
3923 */
3926{
3927 INT ret = 0, srclenW = 0;
3928 WCHAR *srcW = NULL, *dstW = NULL;
3929
3930 if (!src || !srclen || dstlen < 0 || (dstlen && !dst) || src == dst)
3931 {
3933 return 0;
3934 }
3935
3937 src, srclen, NULL, 0);
3938 srcW = HeapAlloc(GetProcessHeap(), 0, srclenW * sizeof(WCHAR));
3939
3940 if (!srcW)
3941 {
3943 goto FoldStringA_exit;
3944 }
3945
3947 src, srclen, srcW, srclenW);
3948
3949 dwFlags = (dwFlags & ~MAP_PRECOMPOSED) | MAP_FOLDCZONE;
3950
3951 ret = FoldStringW(dwFlags, srcW, srclenW, NULL, 0);
3952 if (ret && dstlen)
3953 {
3954 dstW = HeapAlloc(GetProcessHeap(), 0, ret * sizeof(WCHAR));
3955
3956 if (!dstW)
3957 {
3959 goto FoldStringA_exit;
3960 }
3961
3962 ret = FoldStringW(dwFlags, srcW, srclenW, dstW, ret);
3963 if (!WideCharToMultiByte(CP_ACP, 0, dstW, ret, dst, dstlen, NULL, NULL))
3964 {
3965 ret = 0;
3967 }
3968 }
3969
3970 HeapFree(GetProcessHeap(), 0, dstW);
3971
3972FoldStringA_exit:
3973 HeapFree(GetProcessHeap(), 0, srcW);
3974 return ret;
3975}
3976
3977/*************************************************************************
3978 * FoldStringW (KERNEL32.@)
3979 *
3980 * See FoldStringA.
3981 */
3984{
3985 int ret;
3986
3987 switch (dwFlags & (MAP_COMPOSITE|MAP_PRECOMPOSED|MAP_EXPAND_LIGATURES))
3988 {
3989 case 0:
3990 if (dwFlags)
3991 break;
3992 /* Fall through for dwFlags == 0 */
3994 case MAP_PRECOMPOSED|MAP_EXPAND_LIGATURES:
3995 case MAP_COMPOSITE|MAP_EXPAND_LIGATURES:
3997 return 0;
3998 }
3999
4000 if (!src || !srclen || dstlen < 0 || (dstlen && !dst) || src == dst)
4001 {
4003 return 0;
4004 }
4005
4007 if (!ret)
4009 return ret;
4010}
4011
4012/******************************************************************************
4013 * CompareStringW (KERNEL32.@)
4014 *
4015 * See CompareStringA.
4016 */
4018 LPCWSTR str1, INT len1, LPCWSTR str2, INT len2)
4019{
4020 return CompareStringEx(NULL, flags, str1, len1, str2, len2, NULL, NULL, 0);
4021}
4022
4023/******************************************************************************
4024 * CompareStringEx (KERNEL32.@)
4025 */
4028{
4031 DWORD semistub_flags = NORM_LINGUISTIC_CASING|LINGUISTIC_IGNORECASE|0x10000000;
4032 /* 0x10000000 is related to diacritics in Arabic, Japanese, and Hebrew */
4033 INT ret;
4034 static int once;
4035
4036 if (version) FIXME("unexpected version parameter\n");
4037 if (reserved) FIXME("unexpected reserved value\n");
4038 if (lParam) FIXME("unexpected lParam\n");
4039
4040 if (!str1 || !str2)
4041 {
4043 return 0;
4044 }
4045
4046 if (flags & ~(supported_flags|semistub_flags))
4047 {
4049 return 0;
4050 }
4051
4052 if (flags & semistub_flags)
4053 {
4054 if (!once++)
4055 FIXME("semi-stub behavior for flag(s) 0x%x\n", flags & semistub_flags);
4056 }
4057
4058 if (len1 < 0) len1 = strlenW(str1);
4059 if (len2 < 0) len2 = strlenW(str2);
4060
4061 ret = wine_compare_string(flags, str1, len1, str2, len2);
4062
4063 if (ret) /* need to translate result */
4064 return (ret < 0) ? CSTR_LESS_THAN : CSTR_GREATER_THAN;
4065 return CSTR_EQUAL;
4066}
4067
4068/******************************************************************************
4069 * CompareStringA (KERNEL32.@)
4070 *
4071 * Compare two locale sensitive strings.
4072 *
4073 * PARAMS
4074 * lcid [I] LCID for the comparison
4075 * flags [I] Flags for the comparison (NORM_ constants from "winnls.h").
4076 * str1 [I] First string to compare
4077 * len1 [I] Length of str1, or -1 if str1 is NUL terminated
4078 * str2 [I] Second string to compare
4079 * len2 [I] Length of str2, or -1 if str2 is NUL terminated
4080 *
4081 * RETURNS
4082 * Success: CSTR_LESS_THAN, CSTR_EQUAL or CSTR_GREATER_THAN depending on whether
4083 * str1 is less than, equal to or greater than str2 respectively.
4084 * Failure: FALSE. Use GetLastError() to determine the cause.
4085 */
4087 LPCSTR str1, INT len1, LPCSTR str2, INT len2)
4088{
4089 WCHAR *buf1W = NtCurrentTeb()->StaticUnicodeBuffer;
4090 WCHAR *buf2W = buf1W + 130;
4091 LPWSTR str1W, str2W;
4092 INT len1W = 0, len2W = 0, ret;
4093 UINT locale_cp = CP_ACP;
4094
4095 if (!str1 || !str2)
4096 {
4098 return 0;
4099 }
4100 if (len1 < 0) len1 = strlen(str1);
4101 if (len2 < 0) len2 = strlen(str2);
4102
4103 if (!(flags & LOCALE_USE_CP_ACP)) locale_cp = get_lcid_codepage( lcid );
4104
4105 if (len1)
4106 {
4107 if (len1 <= 130) len1W = MultiByteToWideChar(locale_cp, 0, str1, len1, buf1W, 130);
4108 if (len1W)
4109 str1W = buf1W;
4110 else
4111 {
4112 len1W = MultiByteToWideChar(locale_cp, 0, str1, len1, NULL, 0);
4113 str1W = HeapAlloc(GetProcessHeap(), 0, len1W * sizeof(WCHAR));
4114 if (!str1W)
4115 {
4117 return 0;
4118 }
4119 MultiByteToWideChar(locale_cp, 0, str1, len1, str1W, len1W);
4120 }
4121 }
4122 else
4123 {
4124 len1W = 0;
4125 str1W = buf1W;
4126 }
4127
4128 if (len2)
4129 {
4130 if (len2 <= 130) len2W = MultiByteToWideChar(locale_cp, 0, str2, len2, buf2W, 130);
4131 if (len2W)
4132 str2W = buf2W;
4133 else
4134 {
4135 len2W = MultiByteToWideChar(locale_cp, 0, str2, len2, NULL, 0);
4136 str2W = HeapAlloc(GetProcessHeap(), 0, len2W * sizeof(WCHAR));
4137 if (!str2W)
4138 {
4139 if (str1W != buf1W) HeapFree(GetProcessHeap(), 0, str1W);
4141 return 0;
4142 }
4143 MultiByteToWideChar(locale_cp, 0, str2, len2, str2W, len2W);
4144 }
4145 }
4146 else
4147 {
4148 len2W = 0;
4149 str2W = buf2W;
4150 }
4151
4152 ret = CompareStringEx(NULL, flags, str1W, len1W, str2W, len2W, NULL, NULL, 0);
4153
4154 if (str1W != buf1W) HeapFree(GetProcessHeap(), 0, str1W);
4155 if (str2W != buf2W) HeapFree(GetProcessHeap(), 0, str2W);
4156 return ret;
4157}
4158
4159#if (WINVER >= 0x0600)
4160/******************************************************************************
4161 * CompareStringOrdinal (KERNEL32.@)
4162 */
4163INT WINAPI CompareStringOrdinal(const WCHAR *str1, INT len1, const WCHAR *str2, INT len2, BOOL ignore_case)
4164{
4165 int ret;
4166
4167 if (!str1 || !str2)
4168 {
4170 return 0;
4171 }
4172 if (len1 < 0) len1 = strlenW(str1);
4173 if (len2 < 0) len2 = strlenW(str2);
4174
4175 ret = RtlCompareUnicodeStrings( str1, len1, str2, len2, ignore_case );
4176 if (ret < 0) return CSTR_LESS_THAN;
4177 if (ret > 0) return CSTR_GREATER_THAN;
4178 return CSTR_EQUAL;
4179}
4180#endif // (WINVER >= 0x0600)
4181
4182#ifndef __REACTOS__
4183/*************************************************************************
4184 * lstrcmp (KERNEL32.@)
4185 * lstrcmpA (KERNEL32.@)
4186 *
4187 * Compare two strings using the current thread locale.
4188 *
4189 * PARAMS
4190 * str1 [I] First string to compare
4191 * str2 [I] Second string to compare
4192 *
4193 * RETURNS
4194 * Success: A number less than, equal to or greater than 0 depending on whether
4195 * str1 is less than, equal to or greater than str2 respectively.
4196 * Failure: FALSE. Use GetLastError() to determine the cause.
4197 */
4199{
4200 int ret;
4201
4202 if ((str1 == NULL) && (str2 == NULL)) return 0;
4203 if (str1 == NULL) return -1;
4204 if (str2 == NULL) return 1;
4205
4206 ret = CompareStringA(GetThreadLocale(), LOCALE_USE_CP_ACP, str1, -1, str2, -1);
4207 if (ret) ret -= 2;
4208
4209 return ret;
4210}
4211
4212/*************************************************************************
4213 * lstrcmpi (KERNEL32.@)
4214 * lstrcmpiA (KERNEL32.@)
4215 *
4216 * Compare two strings using the current thread locale, ignoring case.
4217 *
4218 * PARAMS
4219 * str1 [I] First string to compare
4220 * str2 [I] Second string to compare
4221 *
4222 * RETURNS
4223 * Success: A number less than, equal to or greater than 0 depending on whether
4224 * str2 is less than, equal to or greater than str1 respectively.
4225 * Failure: FALSE. Use GetLastError() to determine the cause.
4226 */
4228{
4229 int ret;
4230
4231 if ((str1 == NULL) && (str2 == NULL)) return 0;
4232 if (str1 == NULL) return -1;
4233 if (str2 == NULL) return 1;
4234
4236 if (ret) ret -= 2;
4237
4238 return ret;
4239}
4240
4241/*************************************************************************
4242 * lstrcmpW (KERNEL32.@)
4243 *
4244 * See lstrcmpA.
4245 */
4247{
4248 int ret;
4249
4250 if ((str1 == NULL) && (str2 == NULL)) return 0;
4251 if (str1 == NULL) return -1;
4252 if (str2 == NULL) return 1;
4253
4254 ret = CompareStringW(GetThreadLocale(), 0, str1, -1, str2, -1);
4255 if (ret) ret -= 2;
4256
4257 return ret;
4258}
4259
4260/*************************************************************************
4261 * lstrcmpiW (KERNEL32.@)
4262 *
4263 * See lstrcmpiA.
4264 */
4266{
4267 int ret;
4268
4269 if ((str1 == NULL) && (str2 == NULL)) return 0;
4270 if (str1 == NULL) return -1;
4271 if (str2 == NULL) return 1;
4272
4273 ret = CompareStringW(GetThreadLocale(), NORM_IGNORECASE, str1, -1, str2, -1);
4274 if (ret) ret -= 2;
4275
4276 return ret;
4277}
4278
4279/******************************************************************************
4280 * LOCALE_Init
4281 */
4282void LOCALE_Init(void)
4283{
4284 extern void CDECL __wine_init_codepages( const union cptable *ansi_cp, const union cptable *oem_cp,
4285 const union cptable *unix_cp );
4286
4287 UINT ansi_cp = 1252, oem_cp = 437, mac_cp = 10000, unix_cp;
4288
4289 setlocale( LC_ALL, "" );
4290
4291#ifdef __APPLE__
4292 /* MacOS doesn't set the locale environment variables so we have to do it ourselves */
4293 if (!has_env("LANG"))
4294 {
4295 const char* mac_locale = get_mac_locale();
4296
4297 setenv( "LANG", mac_locale, 1 );
4298 if (setlocale( LC_ALL, "" ))
4299 TRACE( "setting LANG to '%s'\n", mac_locale );
4300 else
4301 {
4302 /* no C library locale matching Mac locale; don't pass garbage to children */
4303 unsetenv("LANG");
4304 TRACE( "Mac locale %s is not supported by the C library\n", debugstr_a(mac_locale) );
4305 }
4306 }
4307#endif /* __APPLE__ */
4308
4311
4312#ifdef __APPLE__
4313 if (!unix_cp)
4314 unix_cp = CP_UTF8; /* default to utf-8 even if we don't get a valid locale */
4315#endif
4316
4320
4323 (LPWSTR)&mac_cp, sizeof(mac_cp)/sizeof(WCHAR) );
4325 (LPWSTR)&oem_cp, sizeof(oem_cp)/sizeof(WCHAR) );
4326 if (!unix_cp)
4328 (LPWSTR)&unix_cp, sizeof(unix_cp)/sizeof(WCHAR) );
4329
4330 if (!(ansi_cptable = wine_cp_get_table( ansi_cp )))
4332 if (!(oem_cptable = wine_cp_get_table( oem_cp )))
4334 if (!(mac_cptable = wine_cp_get_table( mac_cp )))
4335 mac_cptable = wine_cp_get_table( 10000 );
4336 if (unix_cp != CP_UTF8)
4337 {
4340 }
4341
4342 __wine_init_codepages( ansi_cptable, oem_cptable, unix_cptable );
4343
4344 TRACE( "ansi=%03d oem=%03d mac=%03d unix=%03d\n",
4345 ansi_cptable->info.codepage, oem_cptable->info.codepage,
4346 mac_cptable->info.codepage, unix_cp );
4347
4348 setlocale(LC_NUMERIC, "C"); /* FIXME: oleaut32 depends on this */
4349}
4350
4351#endif // !__REACTOS__
4352
4353#ifdef __REACTOS__
4354HANDLE NLS_RegOpenKey(HANDLE hRootKey, LPCWSTR szKeyName)
4355#else
4356static HANDLE NLS_RegOpenKey(HANDLE hRootKey, LPCWSTR szKeyName)
4357#endif
4358{
4359 UNICODE_STRING keyName;
4361 HANDLE hkey;
4362
4363 RtlInitUnicodeString( &keyName, szKeyName );
4364#ifdef __REACTOS__
4366#else
4367 InitializeObjectAttributes(&attr, &keyName, 0, hRootKey, NULL);
4368#endif
4369
4370 if (NtOpenKey( &hkey, KEY_READ, &attr ) != STATUS_SUCCESS)
4371 hkey = 0;
4372
4373 return hkey;
4374}
4375
4376#ifdef __REACTOS__
4378 LPWSTR szValueName, ULONG valueNameSize,
4379 LPWSTR szValueData, ULONG valueDataSize)
4380#else
4382 LPWSTR szValueName, ULONG valueNameSize,
4383 LPWSTR szValueData, ULONG valueDataSize)
4384#endif
4385{
4386 BYTE buffer[80];
4388 DWORD dwLen;
4389
4391 buffer, sizeof(buffer), &dwLen ) != STATUS_SUCCESS ||
4392 info->NameLength > valueNameSize ||
4393 info->DataLength > valueDataSize)
4394 {
4395 return FALSE;
4396 }
4397
4398 TRACE("info->Name %s info->DataLength %d\n", debugstr_w(info->Name), info->DataLength);
4399
4400 memcpy( szValueName, info->Name, info->NameLength);
4401 szValueName[info->NameLength / sizeof(WCHAR)] = '\0';
4402 memcpy( szValueData, buffer + info->DataOffset, info->DataLength );
4403 szValueData[info->DataLength / sizeof(WCHAR)] = '\0';
4404
4405 TRACE("returning %s %s\n", debugstr_w(szValueName), debugstr_w(szValueData));
4406 return TRUE;
4407}
4408
4409static BOOL NLS_RegGetDword(HANDLE hKey, LPCWSTR szValueName, DWORD *lpVal)
4410{
4411 BYTE buffer[128];
4413 DWORD dwSize = sizeof(buffer);
4414 UNICODE_STRING valueName;
4415
4416 RtlInitUnicodeString( &valueName, szValueName );
4417
4418 TRACE("%p, %s\n", hKey, debugstr_w(szValueName));
4421 info->DataLength == sizeof(DWORD))
4422 {
4423 memcpy(lpVal, info->Data, sizeof(DWORD));
4424 return TRUE;
4425 }
4426
4427 return FALSE;
4428}
4429
4431{
4432 LANGID langId;
4433 LPCWSTR szResourceName = MAKEINTRESOURCEW(((lgrpid + 0x2000) >> 4) + 1);
4434 HRSRC hResource;
4435 BOOL bRet = FALSE;
4436
4437 /* FIXME: Is it correct to use the system default langid? */
4438 langId = GetSystemDefaultLangID();
4439
4440 if (SUBLANGID(langId) == SUBLANG_NEUTRAL) langId = get_default_sublang( langId );
4441
4442 hResource = FindResourceExW( kernel32_handle, (LPWSTR)RT_STRING, szResourceName, langId );
4443
4444 if (hResource)
4445 {
4446 HGLOBAL hResDir = LoadResource( kernel32_handle, hResource );
4447
4448 if (hResDir)
4449 {
4450 ULONG iResourceIndex = lgrpid & 0xf;
4451 LPCWSTR lpResEntry = LockResource( hResDir );
4452 ULONG i;
4453
4454 for (i = 0; i < iResourceIndex; i++)
4455 lpResEntry += *lpResEntry + 1;
4456
4457 if (*lpResEntry < nameSize)
4458 {
4459 memcpy( szName, lpResEntry + 1, *lpResEntry * sizeof(WCHAR) );
4460 szName[*lpResEntry] = '\0';
4461 bRet = TRUE;
4462 }
4463
4464 }
4465 FreeResource( hResource );
4466 }
4467 return bRet;
4468}
4469
4470/* Callback function ptrs for EnumSystemLanguageGroupsA/W */
4471typedef struct
4472{
4478
4479/* Internal implementation of EnumSystemLanguageGroupsA/W */
4481{
4482 WCHAR szNumber[10], szValue[4];
4483 HANDLE hKey;
4484 BOOL bContinue = TRUE;
4485 ULONG ulIndex = 0;
4486
4487 if (!lpProcs)
4488 {
4490 return FALSE;
4491 }
4492
4493 switch (lpProcs->dwFlags)
4494 {
4495 case 0:
4496 /* Default to LGRPID_INSTALLED */
4497 lpProcs->dwFlags = LGRPID_INSTALLED;
4498 /* Fall through... */
4499 case LGRPID_INSTALLED:
4500 case LGRPID_SUPPORTED:
4501 break;
4502 default:
4504 return FALSE;
4505 }
4506
4508
4509 if (!hKey)
4510 FIXME("NLS registry key not found. Please apply the default registry file 'wine.inf'\n");
4511
4512 while (bContinue)
4513 {
4514 if (NLS_RegEnumValue( hKey, ulIndex, szNumber, sizeof(szNumber),
4515 szValue, sizeof(szValue) ))
4516 {
4517 BOOL bInstalled = szValue[0] == '1';
4518 LGRPID lgrpid = strtoulW( szNumber, NULL, 16 );
4519
4520 TRACE("grpid %s (%sinstalled)\n", debugstr_w(szNumber),
4521 bInstalled ? "" : "not ");
4522
4523 if (lpProcs->dwFlags == LGRPID_SUPPORTED || bInstalled)
4524 {
4525 WCHAR szGrpName[48];
4526
4527 if (!NLS_GetLanguageGroupName( lgrpid, szGrpName, sizeof(szGrpName) / sizeof(WCHAR) ))
4528 szGrpName[0] = '\0';
4529
4530 if (lpProcs->procW)
4531 bContinue = lpProcs->procW( lgrpid, szNumber, szGrpName, lpProcs->dwFlags,
4532 lpProcs->lParam );
4533 else
4534 {
4535 char szNumberA[sizeof(szNumber)/sizeof(WCHAR)];
4536 char szGrpNameA[48];
4537
4538 /* FIXME: MSDN doesn't say which code page the W->A translation uses,
4539 * or whether the language names are ever localised. Assume CP_ACP.
4540 */
4541
4542 WideCharToMultiByte(CP_ACP, 0, szNumber, -1, szNumberA, sizeof(szNumberA), 0, 0);
4543 WideCharToMultiByte(CP_ACP, 0, szGrpName, -1, szGrpNameA, sizeof(szGrpNameA), 0, 0);
4544
4545 bContinue = lpProcs->procA( lgrpid, szNumberA, szGrpNameA, lpProcs->dwFlags,
4546 lpProcs->lParam );
4547 }
4548 }
4549
4550 ulIndex++;
4551 }
4552 else
4553 bContinue = FALSE;
4554
4555 if (!bContinue)
4556 break;
4557 }
4558
4559 if (hKey)
4560 NtClose( hKey );
4561
4562 return TRUE;
4563}
4564
4565/******************************************************************************
4566 * EnumSystemLanguageGroupsA (KERNEL32.@)
4567 *
4568 * Call a users function for each language group available on the system.
4569 *
4570 * PARAMS
4571 * pLangGrpEnumProc [I] Callback function to call for each language group
4572 * dwFlags [I] LGRPID_SUPPORTED=All Supported, LGRPID_INSTALLED=Installed only
4573 * lParam [I] User parameter to pass to pLangGrpEnumProc
4574 *
4575 * RETURNS
4576 * Success: TRUE.
4577 * Failure: FALSE. Use GetLastError() to determine the cause.
4578 */
4581{
4583
4584 TRACE("(%p,0x%08X,0x%08lX)\n", pLangGrpEnumProc, dwFlags, lParam);
4585
4586 procs.procA = pLangGrpEnumProc;
4587 procs.procW = NULL;
4588 procs.dwFlags = dwFlags;
4589 procs.lParam = lParam;
4590
4591 return NLS_EnumSystemLanguageGroups( pLangGrpEnumProc ? &procs : NULL);
4592}
4593
4594/******************************************************************************
4595 * EnumSystemLanguageGroupsW (KERNEL32.@)
4596 *
4597 * See EnumSystemLanguageGroupsA.
4598 */
4601{
4603
4604 TRACE("(%p,0x%08X,0x%08lX)\n", pLangGrpEnumProc, dwFlags, lParam);
4605
4606 procs.procA = NULL;
4607 procs.procW = pLangGrpEnumProc;
4608 procs.dwFlags = dwFlags;
4609 procs.lParam = lParam;
4610
4611 return NLS_EnumSystemLanguageGroups( pLangGrpEnumProc ? &procs : NULL);
4612}
4613
4614/******************************************************************************
4615 * IsValidLanguageGroup (KERNEL32.@)
4616 *
4617 * Determine if a language group is supported and/or installed.
4618 *
4619 * PARAMS
4620 * lgrpid [I] Language Group Id (LGRPID_ values from "winnls.h")
4621 * dwFlags [I] LGRPID_SUPPORTED=Supported, LGRPID_INSTALLED=Installed
4622 *
4623 * RETURNS
4624 * TRUE, if lgrpid is supported and/or installed, according to dwFlags.
4625 * FALSE otherwise.
4626 */
4628{
4629 static const WCHAR szFormat[] = { '%','x','\0' };
4630 WCHAR szValueName[16], szValue[2];
4631 BOOL bSupported = FALSE, bInstalled = FALSE;
4632 HANDLE hKey;
4633
4634
4635 switch (dwFlags)
4636 {
4637 case LGRPID_INSTALLED:
4638 case LGRPID_SUPPORTED:
4639
4641
4642 sprintfW( szValueName, szFormat, lgrpid );
4643
4644 if (NLS_RegGetDword( hKey, szValueName, (LPDWORD)szValue ))
4645 {
4646 bSupported = TRUE;
4647
4648 if (szValue[0] == '1')
4649 bInstalled = TRUE;
4650 }
4651
4652 if (hKey)
4653 NtClose( hKey );
4654
4655 break;
4656 }
4657
4658 if ((dwFlags == LGRPID_SUPPORTED && bSupported) ||
4659 (dwFlags == LGRPID_INSTALLED && bInstalled))
4660 return TRUE;
4661
4662 return FALSE;
4663}
4664
4665/* Callback function ptrs for EnumLanguageGrouplocalesA/W */
4666typedef struct
4667{
4674
4675/* Internal implementation of EnumLanguageGrouplocalesA/W */
4677{
4678 static const WCHAR szAlternateSortsKeyName[] = {
4679 'A','l','t','e','r','n','a','t','e',' ','S','o','r','t','s','\0'
4680 };
4681 WCHAR szNumber[10], szValue[4];
4682 HANDLE hKey;
4683 BOOL bContinue = TRUE, bAlternate = FALSE;
4684 LGRPID lgrpid;
4685 ULONG ulIndex = 1; /* Ignore default entry of 1st key */
4686
4687 if (!lpProcs || !lpProcs->lgrpid || lpProcs->lgrpid > LGRPID_ARMENIAN)
4688 {
4690 return FALSE;
4691 }
4692
4693 if (lpProcs->dwFlags)
4694 {
4696 return FALSE;
4697 }
4698
4700
4701 if (!hKey)
4702 WARN("NLS registry key not found. Please apply the default registry file 'wine.inf'\n");
4703
4704 while (bContinue)
4705 {
4706 if (NLS_RegEnumValue( hKey, ulIndex, szNumber, sizeof(szNumber),
4707 szValue, sizeof(szValue) ))
4708 {
4709 lgrpid = strtoulW( szValue, NULL, 16 );
4710
4711 TRACE("lcid %s, grpid %d (%smatched)\n", debugstr_w(szNumber),
4712 lgrpid, lgrpid == lpProcs->lgrpid ? "" : "not ");
4713
4714 if (lgrpid == lpProcs->lgrpid)
4715 {
4716 LCID lcid;
4717
4718 lcid = strtoulW( szNumber, NULL, 16 );
4719
4720 /* FIXME: native returns extra text for a few (17/150) locales, e.g:
4721 * '00000437 ;Georgian'
4722 * At present we only pass the LCID string.
4723 */
4724
4725 if (lpProcs->procW)
4726 bContinue = lpProcs->procW( lgrpid, lcid, szNumber, lpProcs->lParam );
4727 else
4728 {
4729 char szNumberA[sizeof(szNumber)/sizeof(WCHAR)];
4730
4731 WideCharToMultiByte(CP_ACP, 0, szNumber, -1, szNumberA, sizeof(szNumberA), 0, 0);
4732
4733 bContinue = lpProcs->procA( lgrpid, lcid, szNumberA, lpProcs->lParam );
4734 }
4735 }
4736
4737 ulIndex++;
4738 }
4739 else
4740 {
4741 /* Finished enumerating this key */
4742 if (!bAlternate)
4743 {
4744 /* Enumerate alternate sorts also */
4745 hKey = NLS_RegOpenKey( hKey, szAlternateSortsKeyName );
4746 bAlternate = TRUE;
4747 ulIndex = 0;
4748 }
4749 else
4750 bContinue = FALSE; /* Finished both keys */
4751 }
4752
4753 if (!bContinue)
4754 break;
4755 }
4756
4757 if (hKey)
4758 NtClose( hKey );
4759
4760 return TRUE;
4761}
4762
4763/******************************************************************************
4764 * EnumLanguageGroupLocalesA (KERNEL32.@)
4765 *
4766 * Call a users function for every locale in a language group available on the system.
4767 *
4768 * PARAMS
4769 * pLangGrpLcEnumProc [I] Callback function to call for each locale
4770 * lgrpid [I] Language group (LGRPID_ values from "winnls.h")
4771 * dwFlags [I] Reserved, set to 0
4772 * lParam [I] User parameter to pass to pLangGrpLcEnumProc
4773 *
4774 * RETURNS
4775 * Success: TRUE.
4776 * Failure: FALSE. Use GetLastError() to determine the cause.
4777 */
4780{
4782
4783 TRACE("(%p,0x%08X,0x%08X,0x%08lX)\n", pLangGrpLcEnumProc, lgrpid, dwFlags, lParam);
4784
4785 callbacks.procA = pLangGrpLcEnumProc;
4786 callbacks.procW = NULL;
4787 callbacks.dwFlags = dwFlags;
4788 callbacks.lgrpid = lgrpid;
4789 callbacks.lParam = lParam;
4790
4791 return NLS_EnumLanguageGroupLocales( pLangGrpLcEnumProc ? &callbacks : NULL );
4792}
4793
4794/******************************************************************************
4795 * EnumLanguageGroupLocalesW (KERNEL32.@)
4796 *
4797 * See EnumLanguageGroupLocalesA.
4798 */
4801{
4803
4804 TRACE("(%p,0x%08X,0x%08X,0x%08lX)\n", pLangGrpLcEnumProc, lgrpid, dwFlags, lParam);
4805
4806 callbacks.procA = NULL;
4807 callbacks.procW = pLangGrpLcEnumProc;
4808 callbacks.dwFlags = dwFlags;
4809 callbacks.lgrpid = lgrpid;
4810 callbacks.lParam = lParam;
4811
4812 return NLS_EnumLanguageGroupLocales( pLangGrpLcEnumProc ? &callbacks : NULL );
4813}
4814
4815/******************************************************************************
4816 * InvalidateNLSCache (KERNEL32.@)
4817 *
4818 * Invalidate the cache of NLS values.
4819 *
4820 * PARAMS
4821 * None.
4822 *
4823 * RETURNS
4824 * Success: TRUE.
4825 * Failure: FALSE.
4826 */
4828{
4829#ifdef __REACTOS__
4831 return TRUE;
4832#else
4833 FIXME("() stub\n");
4834 return FALSE;
4835#endif
4836}
4837
4838/******************************************************************************
4839 * GetUserGeoID (KERNEL32.@)
4840 */
4842{
4844 static const WCHAR geoW[] = {'G','e','o',0};
4845 static const WCHAR nationW[] = {'N','a','t','i','o','n',0};
4846 WCHAR bufferW[40], *end;
4847 DWORD count;
4848 HANDLE hkey, hSubkey = 0;
4849 UNICODE_STRING keyW;
4851 RtlInitUnicodeString( &keyW, nationW );
4852 count = sizeof(bufferW);
4853
4854 if(!(hkey = create_registry_key())) return ret;
4855
4856 switch( GeoClass ){
4857 case GEOCLASS_NATION:
4858 if ((hSubkey = NLS_RegOpenKey(hkey, geoW)))
4859 {
4860 if((NtQueryValueKey(hSubkey, &keyW, KeyValuePartialInformation,
4861 bufferW, count, &count) == STATUS_SUCCESS ) && info->DataLength)
4862 ret = strtolW((LPCWSTR)info->Data, &end, 10);
4863 }
4864 break;
4865 case GEOCLASS_REGION:
4866 FIXME("GEOCLASS_REGION not handled yet\n");
4867 break;
4868 }
4869
4870 NtClose(hkey);
4871 if (hSubkey) NtClose(hSubkey);
4872 return ret;
4873}
4874
4875/******************************************************************************
4876 * SetUserGeoID (KERNEL32.@)
4877 */
4879{
4880 static const WCHAR geoW[] = {'G','e','o',0};
4881 static const WCHAR nationW[] = {'N','a','t','i','o','n',0};
4882 static const WCHAR formatW[] = {'%','i',0};
4883 UNICODE_STRING nameW,keyW;
4884 WCHAR bufferW[10];
4886 HANDLE hkey;
4887
4888 if(!(hkey = create_registry_key())) return FALSE;
4889
4890 attr.Length = sizeof(attr);
4891 attr.RootDirectory = hkey;
4892 attr.ObjectName = &nameW;
4893 attr.Attributes = 0;
4894 attr.SecurityDescriptor = NULL;
4895 attr.SecurityQualityOfService = NULL;
4896 RtlInitUnicodeString( &nameW, geoW );
4897 RtlInitUnicodeString( &keyW, nationW );
4898
4899 if (NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL ) != STATUS_SUCCESS)
4900
4901 {
4902 NtClose(attr.RootDirectory);
4903 return FALSE;
4904 }
4905
4906 sprintfW(bufferW, formatW, GeoID);
4907 NtSetValueKey(hkey, &keyW, 0, REG_SZ, bufferW, (strlenW(bufferW) + 1) * sizeof(WCHAR));
4908 NtClose(attr.RootDirectory);
4909 NtClose(hkey);
4910 return TRUE;
4911}
4912
4913typedef struct
4914{
4915 union
4916 {
4919 } u;
4923
4926{
4928 char buf[20];
4929
4930 sprintf(buf, "%08x", (UINT)LangID);
4931 return enum_uilang->u.procA( buf, enum_uilang->param );
4932}
4933
4936{
4937 static const WCHAR formatW[] = {'%','0','8','x',0};
4939 WCHAR buf[20];
4940
4941 sprintfW( buf, formatW, (UINT)LangID );
4942 return enum_uilang->u.procW( buf, enum_uilang->param );
4943}
4944
4945/******************************************************************************
4946 * EnumUILanguagesA (KERNEL32.@)
4947 */
4949{
4950 ENUM_UILANG_CALLBACK enum_uilang;
4951
4952 TRACE("%p, %x, %lx\n", pUILangEnumProc, dwFlags, lParam);
4953
4954 if(!pUILangEnumProc) {
4956 return FALSE;
4957 }
4958 if(dwFlags) {
4960 return FALSE;
4961 }
4962
4963 enum_uilang.u.procA = pUILangEnumProc;
4964 enum_uilang.flags = dwFlags;
4965 enum_uilang.param = lParam;
4966
4969 (LONG_PTR)&enum_uilang);
4970 return TRUE;
4971}
4972
4973/******************************************************************************
4974 * EnumUILanguagesW (KERNEL32.@)
4975 */
4977{
4978 ENUM_UILANG_CALLBACK enum_uilang;
4979
4980 TRACE("%p, %x, %lx\n", pUILangEnumProc, dwFlags, lParam);
4981
4982
4983 if(!pUILangEnumProc) {
4985 return FALSE;
4986 }
4987 if(dwFlags) {
4989 return FALSE;
4990 }
4991
4992 enum_uilang.u.procW = pUILangEnumProc;
4993 enum_uilang.flags = dwFlags;
4994 enum_uilang.param = lParam;
4995
4998 (LONG_PTR)&enum_uilang);
4999 return TRUE;
5000}
5001
5007
5015};
5016
5017static const struct geoinfo_t geoinfodata[] = {
5018 { 2, {'A','G',0}, {'A','T','G',0}, 10039880, 28 }, /* Antigua and Barbuda */
5019 { 3, {'A','F',0}, {'A','F','G',0}, 47614, 4 }, /* Afghanistan */
5020 { 4, {'D','Z',0}, {'D','Z','A',0}, 42487, 12 }, /* Algeria */
5021 { 5, {'A','Z',0}, {'A','Z','E',0}, 47611, 31 }, /* Azerbaijan */
5022 { 6, {'A','L',0}, {'A','L','B',0}, 47610, 8 }, /* Albania */
5023 { 7, {'A','M',0}, {'A','R','M',0}, 47611, 51 }, /* Armenia */
5024 { 8, {'A','D',0}, {'A','N','D',0}, 47610, 20 }, /* Andorra */
5025 { 9, {'A','O',0}, {'A','G','O',0}, 42484, 24 }, /* Angola */
5026 { 10, {'A','S',0}, {'A','S','M',0}, 26286, 16 }, /* American Samoa */
5027 { 11, {'A','R',0}, {'A','R','G',0}, 31396, 32 }, /* Argentina */
5028 { 12, {'A','U',0}, {'A','U','S',0}, 10210825, 36 }, /* Australia */
5029 { 14, {'A','T',0}, {'A','U','T',0}, 10210824, 40 }, /* Austria */
5030 { 17, {'B','H',0}, {'B','H','R',0}, 47611, 48 }, /* Bahrain */
5031 { 18, {'B','B',0}, {'B','R','B',0}, 10039880, 52 }, /* Barbados */
5032 { 19, {'B','W',0}, {'B','W','A',0}, 10039883, 72 }, /* Botswana */
5033 { 20, {'B','M',0}, {'B','M','U',0}, 23581, 60 }, /* Bermuda */
5034 { 21, {'B','E',0}, {'B','E','L',0}, 10210824, 56 }, /* Belgium */
5035 { 22, {'B','S',0}, {'B','H','S',0}, 10039880, 44 }, /* Bahamas, The */
5036 { 23, {'B','D',0}, {'B','G','D',0}, 47614, 50 }, /* Bangladesh */
5037 { 24, {'B','Z',0}, {'B','L','Z',0}, 27082, 84 }, /* Belize */
5038 { 25, {'B','A',0}, {'B','I','H',0}, 47610, 70 }, /* Bosnia and Herzegovina */
5039 { 26, {'B','O',0}, {'B','O','L',0}, 31396, 68 }, /* Bolivia */
5040 { 27, {'M','M',0}, {'M','M','R',0}, 47599, 104 }, /* Myanmar */
5041 { 28, {'B','J',0}, {'B','E','N',0}, 42483, 204 }, /* Benin */
5042 { 29, {'B','Y',0}, {'B','L','R',0}, 47609, 112 }, /* Belarus */
5043 { 30, {'S','B',0}, {'S','L','B',0}, 20900, 90 }, /* Solomon Islands */
5044 { 32, {'B','R',0}, {'B','R','A',0}, 31396, 76 }, /* Brazil */
5045 { 34, {'B','T',0}, {'B','T','N',0}, 47614, 64 }, /* Bhutan */
5046 { 35, {'B','G',0}, {'B','G','R',0}, 47609, 100 }, /* Bulgaria */
5047 { 37, {'B','N',0}, {'B','R','N',0}, 47599, 96 }, /* Brunei */
5048 { 38, {'B','I',0}, {'B','D','I',0}, 47603, 108 }, /* Burundi */
5049 { 39, {'C','A',0}, {'C','A','N',0}, 23581, 124 }, /* Canada */
5050 { 40, {'K','H',0}, {'K','H','M',0}, 47599, 116 }, /* Cambodia */
5051 { 41, {'T','D',0}, {'T','C','D',0}, 42484, 148 }, /* Chad */
5052 { 42, {'L','K',0}, {'L','K','A',0}, 47614, 144 }, /* Sri Lanka */
5053 { 43, {'C','G',0}, {'C','O','G',0}, 42484, 178 }, /* Congo */
5054 { 44, {'C','D',0}, {'C','O','D',0}, 42484, 180 }, /* Congo (DRC) */
5055 { 45, {'C','N',0}, {'C','H','N',0}, 47600, 156 }, /* China */
5056 { 46, {'C','L',0}, {'C','H','L',0}, 31396, 152 }, /* Chile */
5057 { 49, {'C','M',0}, {'C','M','R',0}, 42484, 120 }, /* Cameroon */
5058 { 50, {'K','M',0}, {'C','O','M',0}, 47603, 174 }, /* Comoros */
5059 { 51, {'C','O',0}, {'C','O','L',0}, 31396, 170 }, /* Colombia */
5060 { 54, {'C','R',0}, {'C','R','I',0}, 27082, 188 }, /* Costa Rica */
5061 { 55, {'C','F',0}, {'C','A','F',0}, 42484, 140 }, /* Central African Republic */
5062 { 56, {'C','U',0}, {'C','U','B',0}, 10039880, 192 }, /* Cuba */
5063 { 57, {'C','V',0}, {'C','P','V',0}, 42483, 132 }, /* Cape Verde */
5064 { 59, {'C','Y',0}, {'C','Y','P',0}, 47611, 196 }, /* Cyprus */
5065 { 61, {'D','K',0}, {'D','N','K',0}, 10039882, 208 }, /* Denmark */
5066 { 62, {'D','J',0}, {'D','J','I',0}, 47603, 262 }, /* Djibouti */
5067 { 63, {'D','M',0}, {'D','M','A',0}, 10039880, 212 }, /* Dominica */
5068 { 65, {'D','O',0}, {'D','O','M',0}, 10039880, 214 }, /* Dominican Republic */
5069 { 66, {'E','C',0}, {'E','C','U',0}, 31396, 218 }, /* Ecuador */
5070 { 67, {'E','G',0}, {'E','G','Y',0}, 42487, 818 }, /* Egypt */
5071 { 68, {'I','E',0}, {'I','R','L',0}, 10039882, 372 }, /* Ireland */
5072 { 69, {'G','Q',0}, {'G','N','Q',0}, 42484, 226 }, /* Equatorial Guinea */
5073 { 70, {'E','E',0}, {'E','S','T',0}, 10039882, 233 }, /* Estonia */
5074 { 71, {'E','R',0}, {'E','R','I',0}, 47603, 232 }, /* Eritrea */
5075 { 72, {'S','V',0}, {'S','L','V',0}, 27082, 222 }, /* El Salvador */
5076 { 73, {'E','T',0}, {'E','T','H',0}, 47603, 231 }, /* Ethiopia */
5077 { 75, {'C','Z',0}, {'C','Z','E',0}, 47609, 203 }, /* Czech Republic */
5078 { 77, {'F','I',0}, {'F','I','N',0}, 10039882, 246 }, /* Finland */
5079 { 78, {'F','J',0}, {'F','J','I',0}, 20900, 242 }, /* Fiji Islands */
5080 { 80, {'F','M',0}, {'F','S','M',0}, 21206, 583 }, /* Micronesia */
5081 { 81, {'F','O',0}, {'F','R','O',0}, 10039882, 234 }, /* Faroe Islands */
5082 { 84, {'F','R',0}, {'F','R','A',0}, 10210824, 250 }, /* France */
5083 { 86, {'G','M',0}, {'G','M','B',0}, 42483, 270 }, /* Gambia, The */
5084 { 87, {'G','A',0}, {'G','A','B',0}, 42484, 266 }, /* Gabon */
5085 { 88, {'G','E',0}, {'G','E','O',0}, 47611, 268 }, /* Georgia */
5086 { 89, {'G','H',0}, {'G','H','A',0}, 42483, 288 }, /* Ghana */
5087 { 90, {'G','I',0}, {'G','I','B',0}, 47610, 292 }, /* Gibraltar */
5088 { 91, {'G','D',0}, {'G','R','D',0}, 10039880, 308 }, /* Grenada */
5089 { 93, {'G','L',0}, {'G','R','L',0}, 23581, 304 }, /* Greenland */
5090 { 94, {'D','E',0}, {'D','E','U',0}, 10210824, 276 }, /* Germany */
5091 { 98, {'G','R',0}, {'G','R','C',0}, 47610, 300 }, /* Greece */
5092 { 99, {'G','T',0}, {'G','T','M',0}, 27082, 320 }, /* Guatemala */
5093 { 100, {'G','N',0}, {'G','I','N',0}, 42483, 324 }, /* Guinea */
5094 { 101, {'G','Y',0}, {'G','U','Y',0}, 31396, 328 }, /* Guyana */
5095 { 103, {'H','T',0}, {'H','T','I',0}, 10039880, 332 }, /* Haiti */
5096 { 104, {'H','K',0}, {'H','K','G',0}, 47600, 344 }, /* Hong Kong S.A.R. */
5097 { 106, {'H','N',0}, {'H','N','D',0}, 27082, 340 }, /* Honduras */
5098 { 108, {'H','R',0}, {'H','R','V',0}, 47610, 191 }, /* Croatia */
5099 { 109, {'H','U',0}, {'H','U','N',0}, 47609, 348 }, /* Hungary */
5100 { 110, {'I','S',0}, {'I','S','L',0}, 10039882, 352 }, /* Iceland */
5101 { 111, {'I','D',0}, {'I','D','N',0}, 47599, 360 }, /* Indonesia */
5102 { 113, {'I','N',0}, {'I','N','D',0}, 47614, 356 }, /* India */
5103 { 114, {'I','O',0}, {'I','O','T',0}, 39070, 86 }, /* British Indian Ocean Territory */
5104 { 116, {'I','R',0}, {'I','R','N',0}, 47614, 364 }, /* Iran */
5105 { 117, {'I','L',0}, {'I','S','R',0}, 47611, 376 }, /* Israel */
5106 { 118, {'I','T',0}, {'I','T','A',0}, 47610, 380 }, /* Italy */
5107 { 119, {'C','I',0}, {'C','I','V',0}, 42483, 384 }, /* Côte d'Ivoire */
5108 { 121, {'I','Q',0}, {'I','R','Q',0}, 47611, 368 }, /* Iraq */
5109 { 122, {'J','P',0}, {'J','P','N',0}, 47600, 392 }, /* Japan */
5110 { 124, {'J','M',0}, {'J','A','M',0}, 10039880, 388 }, /* Jamaica */
5111 { 125, {'S','J',0}, {'S','J','M',0}, 10039882, 744 }, /* Jan Mayen */
5112 { 126, {'J','O',0}, {'J','O','R',0}, 47611, 400 }, /* Jordan */
5113 { 127, {'X','X',0}, {'X','X',0}, 161832256 }, /* Johnston Atoll */
5114 { 129, {'K','E',0}, {'K','E','N',0}, 47603, 404 }, /* Kenya */
5115 { 130, {'K','G',0}, {'K','G','Z',0}, 47590, 417 }, /* Kyrgyzstan */
5116 { 131, {'K','P',0}, {'P','R','K',0}, 47600, 408 }, /* North Korea */
5117 { 133, {'K','I',0}, {'K','I','R',0}, 21206, 296 }, /* Kiribati */
5118 { 134, {'K','R',0}, {'K','O','R',0}, 47600, 410 }, /* Korea */
5119 { 136, {'K','W',0}, {'K','W','T',0}, 47611, 414 }, /* Kuwait */
5120 { 137, {'K','Z',0}, {'K','A','Z',0}, 47590, 398 }, /* Kazakhstan */
5121 { 138, {'L','A',0}, {'L','A','O',0}, 47599, 418 }, /* Laos */
5122 { 139, {'L','B',0}, {'L','B','N',0}, 47611, 422 }, /* Lebanon */
5123 { 140, {'L','V',0}, {'L','V','A',0}, 10039882, 428 }, /* Latvia */
5124 { 141, {'L','T',0}, {'L','T','U',0}, 10039882, 440 }, /* Lithuania */
5125 { 142, {'L','R',0}, {'L','B','R',0}, 42483, 430 }, /* Liberia */
5126 { 143, {'S','K',0}, {'S','V','K',0}, 47609, 703 }, /* Slovakia */
5127 { 145, {'L','I',0}, {'L','I','E',0}, 10210824, 438 }, /* Liechtenstein */
5128 { 146, {'L','S',0}, {'L','S','O',0}, 10039883, 426 }, /* Lesotho */
5129 { 147, {'L','U',0}, {'L','U','X',0}, 10210824, 442 }, /* Luxembourg */
5130 { 148, {'L','Y',0}, {'L','B','Y',0}, 42487, 434 }, /* Libya */
5131 { 149, {'M','G',0}, {'M','D','G',0}, 47603, 450 }, /* Madagascar */
5132 { 151, {'M','O',0}, {'M','A','C',0}, 47600, 446 }, /* Macao S.A.R. */
5133 { 152, {'M','D',0}, {'M','D','A',0}, 47609, 498 }, /* Moldova */
5134 { 154, {'M','N',0}, {'M','N','G',0}, 47600, 496 }, /* Mongolia */
5135 { 156, {'M','W',0}, {'M','W','I',0}, 47603, 454 }, /* Malawi */
5136 { 157, {'M','L',0}, {'M','L','I',0}, 42483, 466 }, /* Mali */
5137 { 158, {'M','C',0}, {'M','C','O',0}, 10210824, 492 }, /* Monaco */
5138 { 159, {'M','A',0}, {'M','A','R',0}, 42487, 504 }, /* Morocco */
5139 { 160, {'M','U',0}, {'M','U','S',0}, 47603, 480 }, /* Mauritius */
5140 { 162, {'M','R',0}, {'M','R','T',0}, 42483, 478 }, /* Mauritania */
5141 { 163, {'M','T',0}, {'M','L','T',0}, 47610, 470 }, /* Malta */
5142 { 164, {'O','M',0}, {'O','M','N',0}, 47611, 512 }, /* Oman */
5143 { 165, {'M','V',0}, {'M','D','V',0}, 47614, 462 }, /* Maldives */
5144 { 166, {'M','X',0}, {'M','E','X',0}, 27082, 484 }, /* Mexico */
5145 { 167, {'M','Y',0}, {'M','Y','S',0}, 47599, 458 }, /* Malaysia */
5146 { 168, {'M','Z',0}, {'M','O','Z',0}, 47603, 508 }, /* Mozambique */
5147 { 173, {'N','E',0}, {'N','E','R',0}, 42483, 562 }, /* Niger */
5148 { 174, {'V','U',0}, {'V','U','T',0}, 20900, 548 }, /* Vanuatu */
5149 { 175, {'N','G',0}, {'N','G','A',0}, 42483, 566 }, /* Nigeria */
5150 { 176, {'N','L',0}, {'N','L','D',0}, 10210824, 528 }, /* Netherlands */
5151 { 177, {'N','O',0}, {'N','O','R',0}, 10039882, 578 }, /* Norway */
5152 { 178, {'N','P',0}, {'N','P','L',0}, 47614, 524 }, /* Nepal */
5153 { 180, {'N','R',0}, {'N','R','U',0}, 21206, 520 }, /* Nauru */
5154 { 181, {'S','R',0}, {'S','U','R',0}, 31396, 740 }, /* Suriname */
5155 { 182, {'N','I',0}, {'N','I','C',0}, 27082, 558 }, /* Nicaragua */
5156 { 183, {'N','Z',0}, {'N','Z','L',0}, 10210825, 554 }, /* New Zealand */
5157 { 184, {'P','S',0}, {'P','S','E',0}, 47611, 275 }, /* Palestinian Authority */
5158 { 185, {'P','Y',0}, {'P','R','Y',0}, 31396, 600 }, /* Paraguay */
5159 { 187, {'P','E',0}, {'P','E','R',0}, 31396, 604 }, /* Peru */
5160 { 190, {'P','K',0}, {'P','A','K',0}, 47614, 586 }, /* Pakistan */
5161 { 191, {'P','L',0}, {'P','O','L',0}, 47609, 616 }, /* Poland */
5162 { 192, {'P','A',0}, {'P','A','N',0}, 27082, 591 }, /* Panama */
5163 { 193, {'P','T',0}, {'P','R','T',0}, 47610, 620 }, /* Portugal */
5164 { 194, {'P','G',0}, {'P','N','G',0}, 20900, 598 }, /* Papua New Guinea */
5165 { 195, {'P','W',0}, {'P','L','W',0}, 21206, 585 }, /* Palau */
5166 { 196, {'G','W',0}, {'G','N','B',0}, 42483, 624 }, /* Guinea-Bissau */
5167 { 197, {'Q','A',0}, {'Q','A','T',0}, 47611, 634 }, /* Qatar */
5168 { 198, {'R','E',0}, {'R','E','U',0}, 47603, 638 }, /* Reunion */
5169 { 199, {'M','H',0}, {'M','H','L',0}, 21206, 584 }, /* Marshall Islands */
5170 { 200, {'R','O',0}, {'R','O','U',0}, 47609, 642 }, /* Romania */
5171 { 201, {'P','H',0}, {'P','H','L',0}, 47599, 608 }, /* Philippines */
5172 { 202, {'P','R',0}, {'P','R','I',0}, 10039880, 630 }, /* Puerto Rico */
5173 { 203, {'R','U',0}, {'R','U','S',0}, 47609, 643 }, /* Russia */
5174 { 204, {'R','W',0}, {'R','W','A',0}, 47603, 646 }, /* Rwanda */
5175 { 205, {'S','A',0}, {'S','A','U',0}, 47611, 682 }, /* Saudi Arabia */
5176 { 206, {'P','M',0}, {'S','P','M',0}, 23581, 666 }, /* St. Pierre and Miquelon */
5177 { 207, {'K','N',0}, {'K','N','A',0}, 10039880, 659 }, /* St. Kitts and Nevis */
5178 { 208, {'S','C',0}, {'S','Y','C',0}, 47603, 690 }, /* Seychelles */
5179 { 209, {'Z','A',0}, {'Z','A','F',0}, 10039883, 710 }, /* South Africa */
5180 { 210, {'S','N',0}, {'S','E','N',0}, 42483, 686 }, /* Senegal */
5181 { 212, {'S','I',0}, {'S','V','N',0}, 47610, 705 }, /* Slovenia */
5182 { 213, {'S','L',0}, {'S','L','E',0}, 42483, 694 }, /* Sierra Leone */
5183 { 214, {'S','M',0}, {'S','M','R',0}, 47610, 674 }, /* San Marino */
5184 { 215, {'S','G',0}, {'S','G','P',0}, 47599, 702 }, /* Singapore */
5185 { 216, {'S','O',0}, {'S','O','M',0}, 47603, 706 }, /* Somalia */
5186 { 217, {'E','S',0}, {'E','S','P',0}, 47610, 724 }, /* Spain */
5187 { 218, {'L','C',0}, {'L','C','A',0}, 10039880, 662 }, /* St. Lucia */
5188 { 219, {'S','D',0}, {'S','D','N',0}, 42487, 736 }, /* Sudan */
5189 { 220, {'S','J',0}, {'S','J','M',0}, 10039882, 744 }, /* Svalbard */
5190 { 221, {'S','E',0}, {'S','W','E',0}, 10039882, 752 }, /* Sweden */
5191 { 222, {'S','Y',0}, {'S','Y','R',0}, 47611, 760 }, /* Syria */
5192 { 223, {'C','H',0}, {'C','H','E',0}, 10210824, 756 }, /* Switzerland */
5193 { 224, {'A','E',0}, {'A','R','E',0}, 47611, 784 }, /* United Arab Emirates */
5194 { 225, {'T','T',0}, {'T','T','O',0}, 10039880, 780 }, /* Trinidad and Tobago */
5195 { 227, {'T','H',0}, {'T','H','A',0}, 47599, 764 }, /* Thailand */
5196 { 228, {'T','J',0}, {'T','J','K',0}, 47590, 762 }, /* Tajikistan */
5197 { 231, {'T','O',0}, {'T','O','N',0}, 26286, 776 }, /* Tonga */
5198 { 232, {'T','G',0}, {'T','G','O',0}, 42483, 768 }, /* Togo */
5199 { 233, {'S','T',0}, {'S','T','P',0}, 42484, 678 }, /* São Tomé and Príncipe */
5200 { 234, {'T','N',0}, {'T','U','N',0}, 42487, 788 }, /* Tunisia */
5201 { 235, {'T','R',0}, {'T','U','R',0}, 47611, 792 }, /* Turkey */
5202 { 236, {'T','V',0}, {'T','U','V',0}, 26286, 798 }, /* Tuvalu */
5203 { 237, {'T','W',0}, {'T','W','N',0}, 47600, 158 }, /* Taiwan */
5204 { 238, {'T','M',0}, {'T','K','M',0}, 47590, 795 }, /* Turkmenistan */
5205 { 239, {'T','Z',0}, {'T','Z','A',0}, 47603, 834 }, /* Tanzania */
5206 { 240, {'U','G',0}, {'U','G','A',0}, 47603, 800 }, /* Uganda */
5207 { 241, {'U','A',0}, {'U','K','R',0}, 47609, 804 }, /* Ukraine */
5208 { 242, {'G','B',0}, {'G','B','R',0}, 10039882, 826 }, /* United Kingdom */
5209 { 244, {'U','S',0}, {'U','S','A',0}, 23581, 840 }, /* United States */
5210 { 245, {'B','F',0}, {'B','F','A',0}, 42483, 854 }, /* Burkina Faso */
5211 { 246, {'U','Y',0}, {'U','R','Y',0}, 31396, 858 }, /* Uruguay */
5212 { 247, {'U','Z',0}, {'U','Z','B',0}, 47590, 860 }, /* Uzbekistan */
5213 { 248, {'V','C',0}, {'V','C','T',0}, 10039880, 670 }, /* St. Vincent and the Grenadines */
5214 { 249, {'V','E',0}, {'V','E','N',0}, 31396, 862 }, /* Bolivarian Republic of Venezuela */
5215 { 251, {'V','N',0}, {'V','N','M',0}, 47599, 704 }, /* Vietnam */
5216 { 252, {'V','I',0}, {'V','I','R',0}, 10039880, 850 }, /* Virgin Islands */
5217 { 253, {'V','A',0}, {'V','A','T',0}, 47610, 336 }, /* Vatican City */
5218 { 254, {'N','A',0}, {'N','A','M',0}, 10039883, 516 }, /* Namibia */
5219 { 257, {'E','H',0}, {'E','S','H',0}, 42487, 732 }, /* Western Sahara (disputed) */
5220 { 258, {'X','X',0}, {'X','X',0}, 161832256 }, /* Wake Island */
5221 { 259, {'W','S',0}, {'W','S','M',0}, 26286, 882 }, /* Samoa */
5222 { 260, {'S','Z',0}, {'S','W','Z',0}, 10039883, 748 }, /* Swaziland */
5223 { 261, {'Y','E',0}, {'Y','E','M',0}, 47611, 887 }, /* Yemen */
5224 { 263, {'Z','M',0}, {'Z','M','B',0}, 47603, 894 }, /* Zambia */
5225 { 264, {'Z','W',0}, {'Z','W','E',0}, 47603, 716 }, /* Zimbabwe */
5226 { 269, {'C','S',0}, {'S','C','G',0}, 47610, 891 }, /* Serbia and Montenegro (Former) */
5227 { 270, {'M','E',0}, {'M','N','E',0}, 47610, 499 }, /* Montenegro */
5228 { 271, {'R','S',0}, {'S','R','B',0}, 47610, 688 }, /* Serbia */
5229 { 273, {'C','W',0}, {'C','U','W',0}, 10039880, 531 }, /* Curaçao */
5230 { 276, {'S','S',0}, {'S','S','D',0}, 42487, 728 }, /* South Sudan */
5231 { 300, {'A','I',0}, {'A','I','A',0}, 10039880, 660 }, /* Anguilla */
5232 { 301, {'A','Q',0}, {'A','T','A',0}, 39070, 10 }, /* Antarctica */
5233 { 302, {'A','W',0}, {'A','B','W',0}, 10039880, 533 }, /* Aruba */
5234 { 303, {'X','X',0}, {'X','X',0}, 39070 }, /* Ascension Island */
5235 { 304, {'X','X',0}, {'X','X',0}, 10210825 }, /* Ashmore and Cartier Islands */
5236 { 305, {'X','X',0}, {'X','X',0}, 161832256 }, /* Baker Island */
5237 { 306, {'B','V',0}, {'B','V','T',0}, 39070, 74 }, /* Bouvet Island */
5238 { 307, {'K','Y',0}, {'C','Y','M',0}, 10039880, 136 }, /* Cayman Islands */
5239 { 308, {'X','X',0}, {'X','X',0}, 10210824, 0, LOCATION_BOTH }, /* Channel Islands */
5240 { 309, {'C','X',0}, {'C','X','R',0}, 12, 162 }, /* Christmas Island */
5241 { 310, {'X','X',0}, {'X','X',0}, 27114 }, /* Clipperton Island */
5242 { 311, {'C','C',0}, {'C','C','K',0}, 10210825, 166 }, /* Cocos (Keeling) Islands */
5243 { 312, {'C','K',0}, {'C','O','K',0}, 26286, 184 }, /* Cook Islands */
5244 { 313, {'X','X',0}, {'X','X',0}, 10210825 }, /* Coral Sea Islands */
5245 { 314, {'X','X',0}, {'X','X',0}, 114 }, /* Diego Garcia */
5246 { 315, {'F','K',0}, {'F','L','K',0}, 31396, 238 }, /* Falkland Islands (Islas Malvinas) */
5247 { 317, {'G','F',0}, {'G','U','F',0}, 31396, 254 }, /* French Guiana */
5248 { 318, {'P','F',0}, {'P','Y','F',0}, 26286, 258 }, /* French Polynesia */
5249 { 319, {'T','F',0}, {'A','T','F',0}, 39070, 260 }, /* French Southern and Antarctic Lands */
5250 { 321, {'G','P',0}, {'G','L','P',0}, 10039880, 312 }, /* Guadeloupe */
5251 { 322, {'G','U',0}, {'G','U','M',0}, 21206, 316 }, /* Guam */
5252 { 323, {'X','X',0}, {'X','X',0}, 39070 }, /* Guantanamo Bay */
5253 { 324, {'G','G',0}, {'G','G','Y',0}, 308, 831 }, /* Guernsey */
5254 { 325, {'H','M',0}, {'H','M','D',0}, 39070, 334 }, /* Heard Island and McDonald Islands */
5255 { 326, {'X','X',0}, {'X','X',0}, 161832256 }, /* Howland Island */
5256 { 327, {'X','X',0}, {'X','X',0}, 161832256 }, /* Jarvis Island */
5257 { 328, {'J','E',0}, {'J','E','Y',0}, 308, 832 }, /* Jersey */
5258 { 329, {'X','X',0}, {'X','X',0}, 161832256 }, /* Kingman Reef */
5259 { 330, {'M','Q',0}, {'M','T','Q',0}, 10039880, 474 }, /* Martinique */
5260 { 331, {'Y','T',0}, {'M','Y','T',0}, 47603, 175 }, /* Mayotte */
5261 { 332, {'M','S',0}, {'M','S','R',0}, 10039880, 500 }, /* Montserrat */
5262 { 333, {'A','N',0}, {'A','N','T',0}, 10039880, 530, LOCATION_BOTH }, /* Netherlands Antilles (Former) */
5263 { 334, {'N','C',0}, {'N','C','L',0}, 20900, 540 }, /* New Caledonia */
5264 { 335, {'N','U',0}, {'N','I','U',0}, 26286, 570 }, /* Niue */
5265 { 336, {'N','F',0}, {'N','F','K',0}, 10210825, 574 }, /* Norfolk Island */
5266 { 337, {'M','P',0}, {'M','N','P',0}, 21206, 580 }, /* Northern Mariana Islands */
5267 { 338, {'X','X',0}, {'X','X',0}, 161832256 }, /* Palmyra Atoll */
5268 { 339, {'P','N',0}, {'P','C','N',0}, 26286, 612 }, /* Pitcairn Islands */
5269 { 340, {'X','X',0}, {'X','X',0}, 337 }, /* Rota Island */
5270 { 341, {'X','X',0}, {'X','X',0}, 337 }, /* Saipan */
5271 { 342, {'G','S',0}, {'S','G','S',0}, 39070, 239 }, /* South Georgia and the South Sandwich Islands */
5272 { 343, {'S','H',0}, {'S','H','N',0}, 42483, 654 }, /* St. Helena */
5273 { 346, {'X','X',0}, {'X','X',0}, 337 }, /* Tinian Island */
5274 { 347, {'T','K',0}, {'T','K','L',0}, 26286, 772 }, /* Tokelau */
5275 { 348, {'X','X',0}, {'X','X',0}, 39070 }, /* Tristan da Cunha */
5276 { 349, {'T','C',0}, {'T','C','A',0}, 10039880, 796 }, /* Turks and Caicos Islands */
5277 { 351, {'V','G',0}, {'V','G','B',0}, 10039880, 92 }, /* Virgin Islands, British */
5278 { 352, {'W','F',0}, {'W','L','F',0}, 26286, 876 }, /* Wallis and Futuna */
5279 { 742, {'X','X',0}, {'X','X',0}, 39070, 0, LOCATION_REGION }, /* Africa */
5280 { 2129, {'X','X',0}, {'X','X',0}, 39070, 0, LOCATION_REGION }, /* Asia */
5281 { 10541, {'X','X',0}, {'X','X',0}, 39070, 0, LOCATION_REGION }, /* Europe */
5282 { 15126, {'I','M',0}, {'I','M','N',0}, 10039882, 833 }, /* Man, Isle of */
5283 { 19618, {'M','K',0}, {'M','K','D',0}, 47610, 807 }, /* Macedonia, Former Yugoslav Republic of */
5284 { 20900, {'X','X',0}, {'X','X',0}, 27114, 0, LOCATION_REGION }, /* Melanesia */
5285 { 21206, {'X','X',0}, {'X','X',0}, 27114, 0, LOCATION_REGION }, /* Micronesia */
5286 { 21242, {'X','X',0}, {'X','X',0}, 161832256 }, /* Midway Islands */
5287 { 23581, {'X','X',0}, {'X','X',0}, 10026358, 0, LOCATION_REGION }, /* Northern America */
5288 { 26286, {'X','X',0}, {'X','X',0}, 27114, 0, LOCATION_REGION }, /* Polynesia */
5289 { 27082, {'X','X',0}, {'X','X',0}, 161832257, 0, LOCATION_REGION }, /* Central America */
5290 { 27114, {'X','X',0}, {'X','X',0}, 39070, 0, LOCATION_REGION }, /* Oceania */
5291 { 30967, {'S','X',0}, {'S','X','M',0}, 10039880, 534 }, /* Sint Maarten (Dutch part) */
5292 { 31396, {'X','X',0}, {'X','X',0}, 161832257, 0, LOCATION_REGION }, /* South America */
5293 { 31706, {'M','F',0}, {'M','A','F',0}, 10039880, 663 }, /* Saint Martin (French part) */
5294 { 39070, {'X','X',0}, {'X','X',0}, 39070, 0, LOCATION_REGION }, /* World */
5295 { 42483, {'X','X',0}, {'X','X',0}, 742, 0, LOCATION_REGION }, /* Western Africa */
5296 { 42484, {'X','X',0}, {'X','X',0}, 742, 0, LOCATION_REGION }, /* Middle Africa */
5297 { 42487, {'X','X',0}, {'X','X',0}, 742, 0, LOCATION_REGION }, /* Northern Africa */
5298 { 47590, {'X','X',0}, {'X','X',0}, 2129, 0, LOCATION_REGION }, /* Central Asia */
5299 { 47599, {'X','X',0}, {'X','X',0}, 2129, 0, LOCATION_REGION }, /* South-Eastern Asia */
5300 { 47600, {'X','X',0}, {'X','X',0}, 2129, 0, LOCATION_REGION }, /* Eastern Asia */
5301 { 47603, {'X','X',0}, {'X','X',0}, 742, 0, LOCATION_REGION }, /* Eastern Africa */
5302 { 47609, {'X','X',0}, {'X','X',0}, 10541, 0, LOCATION_REGION }, /* Eastern Europe */
5303 { 47610, {'X','X',0}, {'X','X',0}, 10541, 0, LOCATION_REGION }, /* Southern Europe */
5304 { 47611, {'X','X',0}, {'X','X',0}, 2129, 0, LOCATION_REGION }, /* Middle East */
5305 { 47614, {'X','X',0}, {'X','X',0}, 2129, 0, LOCATION_REGION }, /* Southern Asia */
5306 { 7299303, {'T','L',0}, {'T','L','S',0}, 47599, 626 }, /* Democratic Republic of Timor-Leste */
5307 { 10026358, {'X','X',0}, {'X','X',0}, 39070, 0, LOCATION_REGION }, /* Americas */
5308 { 10028789, {'A','X',0}, {'A','L','A',0}, 10039882, 248 }, /* Åland Islands */
5309 { 10039880, {'X','X',0}, {'X','X',0}, 161832257, 0, LOCATION_REGION }, /* Caribbean */
5310 { 10039882, {'X','X',0}, {'X','X',0}, 10541, 0, LOCATION_REGION }, /* Northern Europe */
5311 { 10039883, {'X','X',0}, {'X','X',0}, 742, 0, LOCATION_REGION }, /* Southern Africa */
5312 { 10210824, {'X','X',0}, {'X','X',0}, 10541, 0, LOCATION_REGION }, /* Western Europe */
5313 { 10210825, {'X','X',0}, {'X','X',0}, 27114, 0, LOCATION_REGION }, /* Australia and New Zealand */
5314 { 161832015, {'B','L',0}, {'B','L','M',0}, 10039880, 652 }, /* Saint Barthélemy */
5315 { 161832256, {'U','M',0}, {'U','M','I',0}, 27114, 581 }, /* U.S. Minor Outlying Islands */
5316 { 161832257, {'X','X',0}, {'X','X',0}, 10026358, 0, LOCATION_REGION }, /* Latin America and the Caribbean */
5317};
5318
5319#ifdef __REACTOS__
5320/* Callback function ptrs for EnumSystemCodePagesA/W */
5321typedef struct
5322{
5323 CODEPAGE_ENUMPROCA procA;
5324 CODEPAGE_ENUMPROCW procW;
5325 DWORD dwFlags;
5326} ENUMSYSTEMCODEPAGES_CALLBACKS;
5327
5328/* Internal implementation of EnumSystemCodePagesA/W */
5329static BOOL NLS_EnumSystemCodePages(ENUMSYSTEMCODEPAGES_CALLBACKS *lpProcs)
5330{
5331 WCHAR szNumber[5 + 1], szValue[MAX_PATH];
5332 HANDLE hKey;
5333 BOOL bContinue = TRUE;
5334 ULONG ulIndex = 0;
5335
5336 if (!lpProcs)
5337 {
5339 return FALSE;
5340 }
5341
5342 switch (lpProcs->dwFlags)
5343 {
5344 case CP_INSTALLED:
5345 case CP_SUPPORTED:
5346 break;
5347 default:
5349 return FALSE;
5350 }
5351
5352 hKey = NLS_RegOpenKey(0, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage");
5353 if (!hKey)
5354 {
5355 WARN("NLS_RegOpenKey() failed\n");
5356 return FALSE;
5357 }
5358
5359 while (bContinue)
5360 {
5361 if (NLS_RegEnumValue(hKey, ulIndex, szNumber, sizeof(szNumber),
5362 szValue, sizeof(szValue)))
5363 {
5364 if ((lpProcs->dwFlags == CP_SUPPORTED)||
5365 ((lpProcs->dwFlags == CP_INSTALLED)&&(wcslen(szValue) > 2)))
5366 {
5367 if (lpProcs->procW)
5368 {
5369 bContinue = lpProcs->procW(szNumber);
5370 }
5371 else
5372 {
5373 char szNumberA[sizeof(szNumber)/sizeof(WCHAR)];
5374
5375 WideCharToMultiByte(CP_ACP, 0, szNumber, -1, szNumberA, sizeof(szNumberA), 0, 0);
5376 bContinue = lpProcs->procA(szNumberA);
5377 }
5378 }
5379
5380 ulIndex++;
5381
5382 } else bContinue = FALSE;
5383
5384 if (!bContinue)
5385 break;
5386 }
5387
5388 if (hKey)
5389 NtClose(hKey);
5390
5391 return TRUE;
5392}
5393
5394/*
5395 * @implemented
5396 */
5397BOOL
5398WINAPI
5400 CODEPAGE_ENUMPROCW lpCodePageEnumProc,
5402 )
5403{
5404 ENUMSYSTEMCODEPAGES_CALLBACKS procs;
5405
5406 TRACE("(%p,0x%08X)\n", lpCodePageEnumProc, dwFlags);
5407
5408 procs.procA = NULL;
5409 procs.procW = lpCodePageEnumProc;
5410 procs.dwFlags = dwFlags;
5411
5412 return NLS_EnumSystemCodePages(lpCodePageEnumProc ? &procs : NULL);
5413}
5414
5415
5416/*
5417 * @implemented
5418 */
5419BOOL
5420WINAPI
5422 CODEPAGE_ENUMPROCA lpCodePageEnumProc,
5424 )
5425{
5426 ENUMSYSTEMCODEPAGES_CALLBACKS procs;
5427
5428 TRACE("(%p,0x%08X)\n", lpCodePageEnumProc, dwFlags);
5429
5430 procs.procA = lpCodePageEnumProc;
5431 procs.procW = NULL;
5432 procs.dwFlags = dwFlags;
5433
5434 return NLS_EnumSystemCodePages(lpCodePageEnumProc ? &procs : NULL);
5435}
5436
5437
5438static int
5439#ifdef __REACTOS__
5440NLS_GetGeoFriendlyName(GEOID Location, LPWSTR szFriendlyName, int cchData, LANGID lang)
5441#else
5442NLS_GetGeoFriendlyName(GEOID Location, LPWSTR szFriendlyName, int cchData)
5443#endif
5444{
5445 /* FIXME: move *.nls resources out of kernel32 into locale.nls */
5446 Location += NLSRC_OFFSET;
5447 Location &= 0xFFFF;
5448
5449 if (cchData == 0)
5450#ifdef __REACTOS__
5451 return GetLocalisedText(Location, NULL, 0, lang);
5452#else
5453 return GetLocalisedText(Location, NULL, 0);
5454#endif
5455
5456#ifdef __REACTOS__
5457 if (GetLocalisedText(Location, szFriendlyName, (UINT)cchData, lang))
5458#else
5459 if (GetLocalisedText(Location, szFriendlyName, (UINT)cchData))
5460#endif
5461 return strlenW(szFriendlyName) + 1;
5462
5463 return 0;
5464}
5465#endif // __REACTOS__
5466
5467static const struct geoinfo_t *get_geoinfo_dataptr(GEOID geoid)
5468{
5469 int min, max;
5470
5471 min = 0;
5472 max = sizeof(geoinfodata)/sizeof(struct geoinfo_t)-1;
5473
5474 while (min <= max) {
5475 const struct geoinfo_t *ptr;
5476 int n = (min+max)/2;
5477
5478 ptr = &geoinfodata[n];
5479 if (geoid == ptr->id)
5480 /* we don't need empty entries */
5481 return *ptr->iso2W ? ptr : NULL;
5482
5483 if (ptr->id > geoid)
5484 max = n-1;
5485 else
5486 min = n+1;
5487 }
5488
5489 return NULL;
5490}
5491
5492/******************************************************************************
5493 * GetGeoInfoW (KERNEL32.@)
5494 */
5495INT WINAPI GetGeoInfoW(GEOID geoid, GEOTYPE geotype, LPWSTR data, int data_len, LANGID lang)
5496{
5497 const struct geoinfo_t *ptr;
5498 const WCHAR *str = NULL;
5499 WCHAR buffW[12];
5500 LONG val = 0;
5501 INT len;
5502
5503 TRACE("%d %d %p %d %d\n", geoid, geotype, data, data_len, lang);
5504
5505 if (!(ptr = get_geoinfo_dataptr(geoid))) {
5507 return 0;
5508 }
5509
5510 switch (geotype) {
5511 case GEO_FRIENDLYNAME:
5512 {
5513#ifdef __REACTOS__
5514 return NLS_GetGeoFriendlyName(geoid, data, data_len, lang);
5515#else
5516 return NLS_GetGeoFriendlyName(geoid, data, data_len);
5517#endif
5518 }
5519 case GEO_NATION:
5520 val = geoid;
5521 break;
5522 case GEO_ISO_UN_NUMBER:
5523 val = ptr->uncode;
5524 break;
5525 case GEO_PARENT:
5526 val = ptr->parent;
5527 break;
5528 case GEO_ISO2:
5529 case GEO_ISO3:
5530 {
5531 str = geotype == GEO_ISO2 ? ptr->iso2W : ptr->iso3W;
5532 break;
5533 }
5534 case GEO_RFC1766:
5535 case GEO_LCID:
5536 case GEO_OFFICIALNAME:
5537 case GEO_TIMEZONES:
5539 case GEO_LATITUDE:
5540 case GEO_LONGITUDE:
5541 FIXME("type %d is not supported\n", geotype);
5543 return 0;
5544 default:
5545 WARN("unrecognized type %d\n", geotype);
5547 return 0;
5548 }
5549
5550 if (val) {
5551 static const WCHAR fmtW[] = {'%','d',0};
5552 sprintfW(buffW, fmtW, val);
5553 str = buffW;
5554 }
5555
5556 len = strlenW(str) + 1;
5557 if (!data || !data_len)
5558 return len;
5559
5560 memcpy(data, str, min(len, data_len)*sizeof(WCHAR));
5561 if (data_len < len)
5563 return data_len < len ? 0 : len;
5564}
5565
5566/******************************************************************************
5567 * GetGeoInfoA (KERNEL32.@)
5568 */
5569INT WINAPI GetGeoInfoA(GEOID geoid, GEOTYPE geotype, LPSTR data, int data_len, LANGID lang)
5570{
5571 WCHAR *buffW;
5572 INT len;
5573
5574 TRACE("%d %d %p %d %d\n", geoid, geotype, data, data_len, lang);
5575
5576 len = GetGeoInfoW(geoid, geotype, NULL, 0, lang);
5577 if (!len)
5578 return 0;
5579
5580 buffW = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
5581 if (!buffW)
5582 return 0;
5583
5584 GetGeoInfoW(geoid, geotype, buffW, len, lang);
5585 len = WideCharToMultiByte(CP_ACP, 0, buffW, -1, NULL, 0, NULL, NULL);
5586 if (!data || !data_len) {
5587 HeapFree(GetProcessHeap(), 0, buffW);
5588 return len;
5589 }
5590
5591 len = WideCharToMultiByte(CP_ACP, 0, buffW, -1, data, data_len, NULL, NULL);
5592 HeapFree(GetProcessHeap(), 0, buffW);
5593
5594 if (data_len < len)
5596 return data_len < len ? 0 : len;
5597}
5598
5599/******************************************************************************
5600 * EnumSystemGeoID (KERNEL32.@)
5601 *
5602 * Call a users function for every location available on the system.
5603 *
5604 * PARAMS
5605 * geoclass [I] Type of information desired (SYSGEOTYPE enum from "winnls.h")
5606 * parent [I] GEOID for the parent
5607 * enumproc [I] Callback function to call for each location
5608 *
5609 * RETURNS
5610 * Success: TRUE.
5611 * Failure: FALSE. Use GetLastError() to determine the cause.
5612 */
5614{
5615 INT i;
5616
5617 TRACE("(%d, %d, %p)\n", geoclass, parent, enumproc);
5618
5619 if (!enumproc) {
5621 return FALSE;
5622 }
5623
5624 if (geoclass != GEOCLASS_NATION && geoclass != GEOCLASS_REGION) {
5626 return FALSE;
5627 }
5628
5629 for (i = 0; i < sizeof(geoinfodata)/sizeof(struct geoinfo_t); i++) {
5630 const struct geoinfo_t *ptr = &geoinfodata[i];
5631
5632 if (geoclass == GEOCLASS_NATION && (ptr->kind == LOCATION_REGION))
5633 continue;
5634
5635 if (geoclass == GEOCLASS_REGION && (ptr->kind == LOCATION_NATION))
5636 continue;
5637
5638 if (parent && ptr->parent != parent)
5639 continue;
5640
5641 if (!enumproc(ptr->id))
5642 return TRUE;
5643 }
5644
5645 return TRUE;
5646}
5647
5648#ifndef __REACTOS__
5649INT WINAPI GetUserDefaultLocaleName(LPWSTR localename, int buffersize)
5650{
5651 LCID userlcid;
5652
5653 TRACE("%p, %d\n", localename, buffersize);
5654
5655 userlcid = GetUserDefaultLCID();
5656 return LCIDToLocaleName(userlcid, localename, buffersize, 0);
5657}
5658
5659/******************************************************************************
5660 * NormalizeString (KERNEL32.@)
5661 */
5662INT WINAPI NormalizeString(NORM_FORM NormForm, LPCWSTR lpSrcString, INT cwSrcLength,
5663 LPWSTR lpDstString, INT cwDstLength)
5664{
5665 FIXME("%x %p %d %p %d\n", NormForm, lpSrcString, cwSrcLength, lpDstString, cwDstLength);
5667 return 0;
5668}
5669
5670/******************************************************************************
5671 * IsNormalizedString (KERNEL32.@)
5672 */
5673BOOL WINAPI IsNormalizedString(NORM_FORM NormForm, LPCWSTR lpString, INT cwLength)
5674{
5675 FIXME("%x %p %d\n", NormForm, lpString, cwLength);
5677 return FALSE;
5678}
5679
5680enum {
5681 BASE = 36,
5682 TMIN = 1,
5683 TMAX = 26,
5684 SKEW = 38,
5685 DAMP = 700,
5687 INIT_N = 128
5689
5690static inline INT adapt(INT delta, INT numpoints, BOOL firsttime)
5691{
5692 INT k;
5693
5694 delta /= (firsttime ? DAMP : 2);
5695 delta += delta/numpoints;
5696
5697 for(k=0; delta>((BASE-TMIN)*TMAX)/2; k+=BASE)
5698 delta /= BASE-TMIN;
5699 return k+((BASE-TMIN+1)*delta)/(delta+SKEW);
5700}
5701
5702/******************************************************************************
5703 * IdnToAscii (KERNEL32.@)
5704 * Implementation of Punycode based on RFC 3492.
5705 */
5706INT WINAPI IdnToAscii(DWORD dwFlags, LPCWSTR lpUnicodeCharStr, INT cchUnicodeChar,
5707 LPWSTR lpASCIICharStr, INT cchASCIIChar)
5708{
5709 static const WCHAR prefixW[] = {'x','n','-','-'};
5710
5711 WCHAR *norm_str;
5712 INT i, label_start, label_end, norm_len, out_label, out = 0;
5713
5714 TRACE("%x %p %d %p %d\n", dwFlags, lpUnicodeCharStr, cchUnicodeChar,
5715 lpASCIICharStr, cchASCIIChar);
5716
5717 norm_len = IdnToNameprepUnicode(dwFlags, lpUnicodeCharStr, cchUnicodeChar, NULL, 0);
5718 if(!norm_len)
5719 return 0;
5720 norm_str = HeapAlloc(GetProcessHeap(), 0, norm_len*sizeof(WCHAR));
5721 if(!norm_str) {
5723 return 0;
5724 }
5725 norm_len = IdnToNameprepUnicode(dwFlags, lpUnicodeCharStr,
5726 cchUnicodeChar, norm_str, norm_len);
5727 if(!norm_len) {
5728 HeapFree(GetProcessHeap(), 0, norm_str);
5729 return 0;
5730 }
5731
5732 for(label_start=0; label_start<norm_len;) {
5733 INT n = INIT_N, bias = INIT_BIAS;
5734 INT delta = 0, b = 0, h;
5735
5736 out_label = out;
5737 for(i=label_start; i<norm_len && norm_str[i]!='.' &&
5738 norm_str[i]!=0x3002 && norm_str[i]!='\0'; i++)
5739 if(norm_str[i] < 0x80)
5740 b++;
5741 label_end = i;
5742
5743 if(b == label_end-label_start) {
5744 if(label_end < norm_len)
5745 b++;
5746 if(!lpASCIICharStr) {
5747 out += b;
5748 }else if(out+b <= cchASCIIChar) {
5749 memcpy(lpASCIICharStr+out, norm_str+label_start, b*sizeof(WCHAR));
5750 out += b;
5751 }else {
5752 HeapFree(GetProcessHeap(), 0, norm_str);
5754 return 0;
5755 }
5756 label_start = label_end+1;
5757 continue;
5758 }
5759
5760 if(!lpASCIICharStr) {
5761 out += 5+b; /* strlen(xn--...-) */
5762 }else if(out+5+b <= cchASCIIChar) {
5763 memcpy(lpASCIICharStr+out, prefixW, sizeof(prefixW));
5764 out += 4;
5765 for(i=label_start; i<label_end; i++)
5766 if(norm_str[i] < 0x80)
5767 lpASCIICharStr[out++] = norm_str[i];
5768 lpASCIICharStr[out++] = '-';
5769 }else {
5770 HeapFree(GetProcessHeap(), 0, norm_str);
5772 return 0;
5773 }
5774 if(!b)
5775 out--;
5776
5777 for(h=b; h<label_end-label_start;) {
5778 INT m = 0xffff, q, k;
5779
5780 for(i=label_start; i<label_end; i++) {
5781 if(norm_str[i]>=n && m>norm_str[i])
5782 m = norm_str[i];
5783 }
5784 delta += (m-n)*(h+1);
5785 n = m;
5786
5787 for(i=label_start; i<label_end; i++) {
5788 if(norm_str[i] < n) {
5789 delta++;
5790 }else if(norm_str[i] == n) {
5791 for(q=delta, k=BASE; ; k+=BASE) {
5792 INT t = k<=bias ? TMIN : k>=bias+TMAX ? TMAX : k-bias;
5793 INT disp = q<t ? q : t+(q-t)%(BASE-t);
5794 if(!lpASCIICharStr) {
5795 out++;
5796 }else if(out+1 <= cchASCIIChar) {
5797 lpASCIICharStr[out++] = disp<='z'-'a' ?
5798 'a'+disp : '0'+disp-'z'+'a'-1;
5799 }else {
5800 HeapFree(GetProcessHeap(), 0, norm_str);
5802 return 0;
5803 }
5804 if(q < t)
5805 break;
5806 q = (q-t)/(BASE-t);
5807 }
5808 bias = adapt(delta, h+1, h==b);
5809 delta = 0;
5810 h++;
5811 }
5812 }
5813 delta++;
5814 n++;
5815 }
5816
5817 if(out-out_label > 63) {
5818 HeapFree(GetProcessHeap(), 0, norm_str);
5820 return 0;
5821 }
5822
5823 if(label_end < norm_len) {
5824 if(!lpASCIICharStr) {
5825 out++;
5826 }else if(out+1 <= cchASCIIChar) {
5827 lpASCIICharStr[out++] = norm_str[label_end] ? '.' : 0;
5828 }else {
5829 HeapFree(GetProcessHeap(), 0, norm_str);
5831 return 0;
5832 }
5833 }
5834 label_start = label_end+1;
5835 }
5836
5837 HeapFree(GetProcessHeap(), 0, norm_str);
5838 return out;
5839}
5840
5841/******************************************************************************
5842 * IdnToNameprepUnicode (KERNEL32.@)
5843 */
5844INT WINAPI IdnToNameprepUnicode(DWORD dwFlags, LPCWSTR lpUnicodeCharStr, INT cchUnicodeChar,
5845 LPWSTR lpNameprepCharStr, INT cchNameprepChar)
5846{
5847 enum {
5848 UNASSIGNED = 0x1,
5849 PROHIBITED = 0x2,
5850 BIDI_RAL = 0x4,
5851 BIDI_L = 0x8
5852 };
5853
5854 extern const unsigned short nameprep_char_type[] DECLSPEC_HIDDEN;
5855 extern const WCHAR nameprep_mapping[] DECLSPEC_HIDDEN;
5856 const WCHAR *ptr;
5857 WORD flags;
5858 WCHAR buf[64], *map_str, norm_str[64], ch;
5859 DWORD i, map_len, norm_len, mask, label_start, label_end, out = 0;
5860 BOOL have_bidi_ral, prohibit_bidi_ral, ascii_only;
5861
5862 TRACE("%x %p %d %p %d\n", dwFlags, lpUnicodeCharStr, cchUnicodeChar,
5863 lpNameprepCharStr, cchNameprepChar);
5864
5865 if(dwFlags & ~(IDN_ALLOW_UNASSIGNED|IDN_USE_STD3_ASCII_RULES)) {
5867 return 0;
5868 }
5869
5870 if(!lpUnicodeCharStr || cchUnicodeChar<-1) {
5872 return 0;
5873 }
5874
5875 if(cchUnicodeChar == -1)
5876 cchUnicodeChar = strlenW(lpUnicodeCharStr)+1;
5877 if(!cchUnicodeChar || (cchUnicodeChar==1 && lpUnicodeCharStr[0]==0)) {
5879 return 0;
5880 }
5881
5882 for(label_start=0; label_start<cchUnicodeChar;) {
5883 ascii_only = TRUE;
5884 for(i=label_start; i<cchUnicodeChar; i++) {
5885 ch = lpUnicodeCharStr[i];
5886
5887 if(i!=cchUnicodeChar-1 && !ch) {
5889 return 0;
5890 }
5891 /* check if ch is one of label separators defined in RFC3490 */
5892 if(!ch || ch=='.' || ch==0x3002 || ch==0xff0e || ch==0xff61)
5893 break;
5894
5895 if(ch > 0x7f) {
5896 ascii_only = FALSE;
5897 continue;
5898 }
5899
5900 if((dwFlags&IDN_USE_STD3_ASCII_RULES) == 0)
5901 continue;
5902 if((ch>='a' && ch<='z') || (ch>='A' && ch<='Z')
5903 || (ch>='0' && ch<='9') || ch=='-')
5904 continue;
5905
5907 return 0;
5908 }
5909 label_end = i;
5910 /* last label may be empty */
5911 if(label_start==label_end && ch) {
5913 return 0;
5914 }
5915
5916 if((dwFlags&IDN_USE_STD3_ASCII_RULES) && (lpUnicodeCharStr[label_start]=='-' ||
5917 lpUnicodeCharStr[label_end-1]=='-')) {
5919 return 0;
5920 }
5921
5922 if(ascii_only) {
5923 /* maximal label length is 63 characters */
5924 if(label_end-label_start > 63) {
5926 return 0;
5927 }
5928 if(label_end < cchUnicodeChar)
5929 label_end++;
5930
5931 if(!lpNameprepCharStr) {
5932 out += label_end-label_start;
5933 }else if(out+label_end-label_start <= cchNameprepChar) {
5934 memcpy(lpNameprepCharStr+out, lpUnicodeCharStr+label_start,
5935 (label_end-label_start)*sizeof(WCHAR));
5936 if(lpUnicodeCharStr[label_end-1] > 0x7f)
5937 lpNameprepCharStr[out+label_end-label_start-1] = '.';
5938 out += label_end-label_start;
5939 }else {
5941 return 0;
5942 }
5943
5944 label_start = label_end;
5945 continue;
5946 }
5947
5948 map_len = 0;
5949 for(i=label_start; i<label_end; i++) {
5950 ch = lpUnicodeCharStr[i];
5952 ptr = nameprep_mapping + ptr[(ch>>4)&0x0f] + 3*(ch&0x0f);
5953
5954 if(!ptr[0]) map_len++;
5955 else if(!ptr[1]) map_len++;
5956 else if(!ptr[2]) map_len += 2;
5957 else if(ptr[0]!=0xffff || ptr[1]!=0xffff || ptr[2]!=0xffff) map_len += 3;
5958 }
5959 if(map_len*sizeof(WCHAR) > sizeof(buf)) {
5960 map_str = HeapAlloc(GetProcessHeap(), 0, map_len*sizeof(WCHAR));
5961 if(!map_str) {
5963 return 0;
5964 }
5965 }else {
5966 map_str = buf;
5967 }
5968 map_len = 0;
5969 for(i=label_start; i<label_end; i++) {
5970 ch = lpUnicodeCharStr[i];
5972 ptr = nameprep_mapping + ptr[(ch>>4)&0x0f] + 3*(ch&0x0f);
5973
5974 if(!ptr[0]) {
5975 map_str[map_len++] = ch;
5976 }else if(!ptr[1]) {
5977 map_str[map_len++] = ptr[0];
5978 }else if(!ptr[2]) {
5979 map_str[map_len++] = ptr[0];
5980 map_str[map_len++] = ptr[1];
5981 }else if(ptr[0]!=0xffff || ptr[1]!=0xffff || ptr[2]!=0xffff) {
5982 map_str[map_len++] = ptr[0];
5983 map_str[map_len++] = ptr[1];
5984 map_str[map_len++] = ptr[2];
5985 }
5986 }
5987
5988 norm_len = FoldStringW(MAP_FOLDCZONE, map_str, map_len,
5989 norm_str, sizeof(norm_str)/sizeof(WCHAR)-1);
5990 if(map_str != buf)
5991 HeapFree(GetProcessHeap(), 0, map_str);
5992 if(!norm_len) {
5995 return 0;
5996 }
5997
5998 if(label_end < cchUnicodeChar) {
5999 norm_str[norm_len++] = lpUnicodeCharStr[label_end] ? '.' : 0;
6000 label_end++;
6001 }
6002
6003 if(!lpNameprepCharStr) {
6004 out += norm_len;
6005 }else if(out+norm_len <= cchNameprepChar) {
6006 memcpy(lpNameprepCharStr+out, norm_str, norm_len*sizeof(WCHAR));
6007 out += norm_len;
6008 }else {
6010 return 0;
6011 }
6012
6013 have_bidi_ral = prohibit_bidi_ral = FALSE;
6014 mask = PROHIBITED;
6015 if((dwFlags&IDN_ALLOW_UNASSIGNED) == 0)
6016 mask |= UNASSIGNED;
6017 for(i=0; i<norm_len; i++) {
6018 ch = norm_str[i];
6020
6021 if(flags & mask) {
6022 SetLastError((flags & PROHIBITED) ? ERROR_INVALID_NAME
6024 return 0;
6025 }
6026
6027 if(flags & BIDI_RAL)
6028 have_bidi_ral = TRUE;
6029 if(flags & BIDI_L)
6030 prohibit_bidi_ral = TRUE;
6031 }
6032
6033 if(have_bidi_ral) {
6034 ch = norm_str[0];
6036 if((flags & BIDI_RAL) == 0)
6037 prohibit_bidi_ral = TRUE;
6038
6039 ch = norm_str[norm_len-1];
6041 if((flags & BIDI_RAL) == 0)
6042 prohibit_bidi_ral = TRUE;
6043 }
6044
6045 if(have_bidi_ral && prohibit_bidi_ral) {
6047 return 0;
6048 }
6049
6050 label_start = label_end;
6051 }
6052
6053 return out;
6054}
6055
6056/******************************************************************************
6057 * IdnToUnicode (KERNEL32.@)
6058 */
6059INT WINAPI IdnToUnicode(DWORD dwFlags, LPCWSTR lpASCIICharStr, INT cchASCIIChar,
6060 LPWSTR lpUnicodeCharStr, INT cchUnicodeChar)
6061{
6062 extern const unsigned short nameprep_char_type[];
6063
6064 INT i, label_start, label_end, out_label, out = 0;
6065 WCHAR ch;
6066
6067 TRACE("%x %p %d %p %d\n", dwFlags, lpASCIICharStr, cchASCIIChar,
6068 lpUnicodeCharStr, cchUnicodeChar);
6069
6070 for(label_start=0; label_start<cchASCIIChar;) {
6071 INT n = INIT_N, pos = 0, old_pos, w, k, bias = INIT_BIAS, delim=0, digit, t;
6072
6073 out_label = out;
6074 for(i=label_start; i<cchASCIIChar; i++) {
6075 ch = lpASCIICharStr[i];
6076
6077 if(ch>0x7f || (i!=cchASCIIChar-1 && !ch)) {
6079 return 0;
6080 }
6081
6082 if(!ch || ch=='.')
6083 break;
6084 if(ch == '-')
6085 delim = i;
6086
6087 if((dwFlags&IDN_USE_STD3_ASCII_RULES) == 0)
6088 continue;
6089 if((ch>='a' && ch<='z') || (ch>='A' && ch<='Z')
6090 || (ch>='0' && ch<='9') || ch=='-')
6091 continue;
6092
6094 return 0;
6095 }
6096 label_end = i;
6097 /* last label may be empty */
6098 if(label_start==label_end && ch) {
6100 return 0;
6101 }
6102
6103 if((dwFlags&IDN_USE_STD3_ASCII_RULES) && (lpASCIICharStr[label_start]=='-' ||
6104 lpASCIICharStr[label_end-1]=='-')) {
6106 return 0;
6107 }
6108 if(label_end-label_start > 63) {
6110 return 0;
6111 }
6112
6113 if(label_end-label_start<4 ||
6114 tolowerW(lpASCIICharStr[label_start])!='x' ||
6115 tolowerW(lpASCIICharStr[label_start+1])!='n' ||
6116 lpASCIICharStr[label_start+2]!='-' || lpASCIICharStr[label_start+3]!='-') {
6117 if(label_end < cchASCIIChar)
6118 label_end++;
6119
6120 if(!lpUnicodeCharStr) {
6121 out += label_end-label_start;
6122 }else if(out+label_end-label_start <= cchUnicodeChar) {
6123 memcpy(lpUnicodeCharStr+out, lpASCIICharStr+label_start,
6124 (label_end-label_start)*sizeof(WCHAR));
6125 out += label_end-label_start;
6126 }else {
6128 return 0;
6129 }
6130
6131 label_start = label_end;
6132 continue;
6133 }
6134
6135 if(delim == label_start+3)
6136 delim++;
6137 if(!lpUnicodeCharStr) {
6138 out += delim-label_start-4;
6139 }else if(out+delim-label_start-4 <= cchUnicodeChar) {
6140 memcpy(lpUnicodeCharStr+out, lpASCIICharStr+label_start+4,
6141 (delim-label_start-4)*sizeof(WCHAR));
6142 out += delim-label_start-4;
6143 }else {
6145 return 0;
6146 }
6147 if(out != out_label)
6148 delim++;
6149
6150 for(i=delim; i<label_end;) {
6151 old_pos = pos;
6152 w = 1;
6153 for(k=BASE; ; k+=BASE) {
6154 ch = i<label_end ? tolowerW(lpASCIICharStr[i++]) : 0;
6155 if((ch<'a' || ch>'z') && (ch<'0' || ch>'9')) {
6157 return 0;
6158 }
6159 digit = ch<='9' ? ch-'0'+'z'-'a'+1 : ch-'a';
6160 pos += digit*w;
6161 t = k<=bias ? TMIN : k>=bias+TMAX ? TMAX : k-bias;
6162 if(digit < t)
6163 break;
6164 w *= BASE-t;
6165 }
6166 bias = adapt(pos-old_pos, out-out_label+1, old_pos==0);
6167 n += pos/(out-out_label+1);
6168 pos %= out-out_label+1;
6169
6170 if((dwFlags&IDN_ALLOW_UNASSIGNED)==0 &&
6171 get_table_entry(nameprep_char_type, n)==1/*UNASSIGNED*/) {
6173 return 0;
6174 }
6175 if(!lpUnicodeCharStr) {
6176 out++;
6177 }else if(out+1 <= cchASCIIChar) {
6178 memmove(lpUnicodeCharStr+out_label+pos+1,
6179 lpUnicodeCharStr+out_label+pos,
6180 (out-out_label-pos)*sizeof(WCHAR));
6181 lpUnicodeCharStr[out_label+pos] = n;
6182 out++;
6183 }else {
6185 return 0;
6186 }
6187 pos++;
6188 }
6189
6190 if(out-out_label > 63) {
6192 return 0;
6193 }
6194
6195 if(label_end < cchASCIIChar) {
6196 if(!lpUnicodeCharStr) {
6197 out++;
6198 }else if(out+1 <= cchUnicodeChar) {
6199 lpUnicodeCharStr[out++] = lpASCIICharStr[label_end];
6200 }else {
6202 return 0;
6203 }
6204 }
6205 label_start = label_end+1;
6206 }
6207
6208 return out;
6209}
6210
6211
6212/******************************************************************************
6213 * GetFileMUIPath (KERNEL32.@)
6214 */
6215
6216BOOL WINAPI GetFileMUIPath(DWORD flags, PCWSTR filepath, PWSTR language, PULONG languagelen,
6217 PWSTR muipath, PULONG muipathlen, PULONGLONG enumerator)
6218{
6219 FIXME("stub: 0x%x, %s, %s, %p, %p, %p, %p\n", flags, debugstr_w(filepath),
6220 debugstr_w(language), languagelen, muipath, muipathlen, enumerator);
6221
6223
6224 return FALSE;
6225}
6226
6227/******************************************************************************
6228 * GetFileMUIInfo (KERNEL32.@)
6229 */
6230
6232{
6233 FIXME("stub: %u, %s, %p, %p\n", flags, debugstr_w(path), info, size);
6234
6236 return FALSE;
6237}
6238
6239/******************************************************************************
6240 * ResolveLocaleName (KERNEL32.@)
6241 */
6242
6244{
6245 FIXME("stub: %s, %p, %d\n", wine_dbgstr_w(name), localename, len);
6246
6248 return 0;
6249}
6250#endif // !__REACTOS__
static BOOL CALLBACK enum_locale_ex_proc(HMODULE module, LPCWSTR type, LPCWSTR name, WORD lang, LONG_PTR lparam)
BOOL WINAPI EnumSystemLocalesEx(LOCALE_ENUMPROCEX proc, DWORD flags, LPARAM lparam, LPVOID reserved)
INT WINAPI GetLocaleInfoEx(LPCWSTR locale, LCTYPE info, LPWSTR buffer, INT len)
int WINAPI LCIDToLocaleName(_In_ LCID Locale, _Out_writes_opt_(cchName) LPWSTR lpName, _In_ int cchName, _In_ DWORD dwFlags)
static BOOL CALLBACK find_locale_id_callback(_In_ HMODULE hModule, _In_ LPCWSTR type, _In_ LPCWSTR name, _In_ LANGID lang, _In_ LPARAM lParam)
WCHAR lpszDest[260]
@ lparam
Definition: SystemMenu.c:31
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
static int used
Definition: adh-main.c:39
LONG NTSTATUS
Definition: precomp.h:26
static const WCHAR nameW[]
Definition: main.c:49
#define DEBUG_CHANNEL(args)
Definition: rdesktop.h:159
#define index(s, c)
Definition: various.h:29
#define ARRAY_SIZE(A)
Definition: main.h:20
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ULongToPtr(ul)
Definition: basetsd.h:92
static WCHAR * get_locale(void)
Definition: builtin.c:3937
CFF_Charset charset
Definition: cffcmap.c:138
Definition: _locale.h:75
LPARAM lParam
Definition: combotst.c:139
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define DECLSPEC_HIDDEN
Definition: precomp.h:8
HMODULE hModule
Definition: animate.c:44
#define CDECL
Definition: compat.h:29
#define CP_UNIXCP
Definition: compat.h:79
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:55
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CALLBACK
Definition: compat.h:35
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define ERROR_INVALID_NAME
Definition: compat.h:103
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
static const WCHAR version[]
Definition: asmname.c:66
static const WCHAR valueW[]
Definition: object.c:48
LCID WINAPI LocaleNameToLCID(_In_ LPCWSTR lpName, _In_ DWORD dwFlags)
BOOL WINAPI WriteProfileStringW(LPCWSTR section, LPCWSTR entry, LPCWSTR string)
Definition: profile.c:1287
BOOL WINAPI FreeResource(HGLOBAL handle)
Definition: res.c:559
BOOL WINAPI EnumResourceLanguagesA(HMODULE hmod, LPCSTR type, LPCSTR name, ENUMRESLANGPROCA lpfun, LONG_PTR lparam)
Definition: res.c:428
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
HRSRC WINAPI FindResourceExW(HMODULE hModule, LPCWSTR type, LPCWSTR name, WORD lang)
Definition: res.c:164
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
BOOL WINAPI EnumResourceLanguagesW(HMODULE hmod, LPCWSTR type, LPCWSTR name, ENUMRESLANGPROCW lpfun, LONG_PTR lparam)
Definition: res.c:480
GEOID WINAPI GetUserGeoID(GEOCLASS GeoClass)
Definition: locale.c:4841
#define LOCALE_NAME_USER_DEFAULT
Definition: locale.c:43
LCID WINAPI GetThreadLocale(void)
Definition: locale.c:2803
BOOL WINAPI SetThreadLocale(LCID lcid)
Definition: locale.c:2822
static const WCHAR iLZeroW[]
Definition: locale.c:180
locationkind
Definition: locale.c:5002
@ LOCATION_REGION
Definition: locale.c:5004
@ LOCATION_BOTH
Definition: locale.c:5005
@ LOCATION_NATION
Definition: locale.c:5003
static const WCHAR sLanguageW[]
Definition: locale.c:195
static const WCHAR iDateW[]
Definition: locale.c:175
static LANGID get_default_sublang(LANGID lang)
Definition: locale.c:369
static const WCHAR iMeasureW[]
Definition: locale.c:181
static void strcpynAtoW(WCHAR *dst, const char *src, size_t n)
Definition: locale.c:267
static BOOL NLS_EnumSystemLanguageGroups(ENUMLANGUAGEGROUP_CALLBACKS *lpProcs)
Definition: locale.c:4480
static INT adapt(INT delta, INT numpoints, BOOL firsttime)
Definition: locale.c:5690
static const WCHAR sLongDateW[]
Definition: locale.c:197
BOOL WINAPI EnumSystemLocalesW(LOCALE_ENUMPROCW lpfnLocaleEnum, DWORD dwFlags)
Definition: locale.c:3001
static BOOL CALLBACK enum_lang_proc_w(HMODULE hModule, LPCWSTR type, LPCWSTR name, WORD LangID, LONG_PTR lParam)
Definition: locale.c:2963
static const struct geoinfo_t geoinfodata[]
Definition: locale.c:5017
LANGID WINAPI SetThreadUILanguage(LANGID langid)
Definition: locale.c:2857
#define WC_FLAGSMASK
Definition: locale.c:61
INT WINAPI LCMapStringA(LCID lcid, DWORD flags, LPCSTR src, INT srclen, LPSTR dst, INT dstlen)
Definition: locale.c:3834
static BOOL utf7_can_directly_encode(WCHAR codepoint)
Definition: locale.c:2553
BOOL WINAPI GetFileMUIInfo(DWORD flags, PCWSTR path, FILEMUIINFO *info, DWORD *size)
Definition: locale.c:6231
static struct registry_value * get_locale_registry_value(DWORD lctype)
Definition: locale.c:1461
static const union cptable * unix_cptable
Definition: locale.c:68
INT WINAPI ResolveLocaleName(LPCWSTR name, LPWSTR localename, INT len)
Definition: locale.c:6243
static const WCHAR iDigitsW[]
Definition: locale.c:176
#define NLSRC_OFFSET
Definition: locale.c:54
BOOL WINAPI IsDBCSLeadByte(BYTE testchar)
Definition: locale.c:2126
UINT WINAPI GetACP(void)
Definition: locale.c:2023
static const WCHAR iFirstDayOfWeekW[]
Definition: locale.c:177
static UINT get_lcid_codepage(LCID lcid)
Definition: locale.c:288
static const WCHAR sMonDecimalSepW[]
Definition: locale.c:198
static const WCHAR sNegativeSignW[]
Definition: locale.c:202
static LCID lcid_LC_MONETARY
Definition: locale.c:164
BOOL WINAPI GetStringTypeA(LCID locale, DWORD type, LPCSTR src, INT count, LPWORD chartype)
Definition: locale.c:3212
static BOOL CALLBACK enum_lang_proc_a(HMODULE hModule, LPCSTR type, LPCSTR name, WORD LangID, LONG_PTR lParam)
Definition: locale.c:2953
BOOL WINAPI EnumSystemLanguageGroupsW(LANGUAGEGROUP_ENUMPROCW pLangGrpEnumProc, DWORD dwFlags, LONG_PTR lParam)
Definition: locale.c:4599
static INT get_registry_locale_info(struct registry_value *registry_value, LPWSTR buffer, INT len)
Definition: locale.c:1477
static LCID convert_default_lcid(LCID lcid, LCTYPE lctype)
Definition: locale.c:592
static const WCHAR szLocaleKeyName[]
Definition: locale.c:70
static const WCHAR sThousandW[]
Definition: locale.c:205
BOOL WINAPI IsValidLanguageGroup(LGRPID lgrpid, DWORD dwFlags)
Definition: locale.c:4627
BOOL WINAPI EnumSystemCodePagesW(CODEPAGE_ENUMPROCW lpfnCodePageEnum, DWORD flags)
Definition: locale.c:2297
static const WCHAR iFirstWeekOfYearW[]
Definition: locale.c:178
BOOL WINAPI EnumSystemCodePagesA(CODEPAGE_ENUMPROCA lpfnCodePageEnum, DWORD flags)
Definition: locale.c:2276
static const WCHAR szLangGroupsKeyName[]
Definition: locale.c:76
static BOOL utf7_write_c(char *dst, int dstlen, int *index, char character)
Definition: locale.c:2578
static BOOL is_genitive_name_supported(LCTYPE lctype)
Definition: locale.c:743
UINT GetLocalisedText(IN UINT uID, IN LPWSTR lpszDest, IN UINT cchDest)
BOOL WINAPI GetFileMUIPath(DWORD flags, PCWSTR filepath, PWSTR language, PULONG languagelen, PWSTR muipath, PULONG muipathlen, PULONGLONG enumerator)
Definition: locale.c:6216
void LOCALE_InitRegistry(void)
Definition: locale.c:843
INT WINAPI FoldStringA(DWORD dwFlags, LPCSTR src, INT srclen, LPSTR dst, INT dstlen)
Definition: locale.c:3924
#define LOCALE_LOCALEINFOFLAGSMASK
Definition: locale.c:58
INT WINAPI NormalizeString(NORM_FORM NormForm, LPCWSTR lpSrcString, INT cwSrcLength, LPWSTR lpDstString, INT cwDstLength)
Definition: locale.c:5662
static LCID lcid_LC_TIME
Definition: locale.c:166
static const WCHAR sMonGroupingW[]
Definition: locale.c:199
static const WCHAR sTimeW[]
Definition: locale.c:207
static RTL_CRITICAL_SECTION cache_section
Definition: locale.c:263
LANGID WINAPI GetSystemDefaultLangID(void)
Definition: locale.c:1199
BOOL WINAPI IsValidCodePage(UINT codepage)
Definition: locale.c:2081
static BOOL get_dummy_preferred_ui_language(DWORD flags, ULONG *count, WCHAR *buffer, ULONG *size)
Definition: locale.c:1252
static BOOL NLS_EnumLanguageGroupLocales(ENUMLANGUAGEGROUPLOCALE_CALLBACKS *lpProcs)
Definition: locale.c:4676
INT WINAPI CompareStringA(LCID lcid, DWORD flags, LPCSTR str1, INT len1, LPCSTR str2, INT len2)
Definition: locale.c:4086
INT WINAPI IdnToUnicode(DWORD dwFlags, LPCWSTR lpASCIICharStr, INT cchASCIIChar, LPWSTR lpUnicodeCharStr, INT cchUnicodeChar)
Definition: locale.c:6059
int wine_get_sortkey(int flags, const WCHAR *src, int srclen, char *dst, int dstlen)
Definition: sortkey.c:33
static const WCHAR iPaperSizeW[]
Definition: locale.c:184
static const WCHAR iCurrencyW[]
Definition: locale.c:174
static const WCHAR iCountryW[]
Definition: locale.c:172
static LCID lcid_LC_NUMERIC
Definition: locale.c:165
static const struct geoinfo_t * get_geoinfo_dataptr(GEOID geoid)
Definition: locale.c:5467
static const WCHAR s2359W[]
Definition: locale.c:189
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4246
INT WINAPI CompareStringW(LCID lcid, DWORD flags, LPCWSTR str1, INT len1, LPCWSTR str2, INT len2)
Definition: locale.c:4017
int wine_fold_string(int flags, const WCHAR *src, int srclen, WCHAR *dst, int dstlen)
Definition: fold.c:118
void LOCALE_Init(void)
Definition: locale.c:4282
BOOL WINAPI SetUserGeoID(GEOID GeoID)
Definition: locale.c:4878
LANGID WINAPI GetUserDefaultUILanguage(void)
Definition: locale.c:1380
static const WCHAR s1159W[]
Definition: locale.c:188
BOOL WINAPI GetStringTypeExA(LCID locale, DWORD type, LPCSTR src, INT count, LPWORD chartype)
Definition: locale.c:3259
static const WCHAR NumShapeW[]
Definition: locale.c:209
static const WCHAR sCurrencyW[]
Definition: locale.c:191
DWORD WINAPI VerLanguageNameW(DWORD wLang, LPWSTR szLang, DWORD nSize)
Definition: locale.c:3087
static const WCHAR iNegNumberW[]
Definition: locale.c:183
static int utf7_wcstombs(const WCHAR *src, int srclen, char *dst, int dstlen)
Definition: locale.c:2602
static BOOL utf7_write_w(WCHAR *dst, int dstlen, int *index, WCHAR character)
Definition: locale.c:2328
static const WCHAR iCalendarTypeW[]
Definition: locale.c:171
BOOL WINAPI GetSystemPreferredUILanguages(DWORD flags, ULONG *count, WCHAR *buffer, ULONG *size)
Definition: locale.c:1301
static BOOL NLS_RegEnumValue(HANDLE hKey, UINT ulIndex, LPWSTR szValueName, ULONG valueNameSize, LPWSTR szValueData, ULONG valueDataSize)
Definition: locale.c:4381
static BOOL NLS_GetLanguageGroupName(LGRPID lgrpid, LPWSTR szName, ULONG nameSize)
Definition: locale.c:4430
static const WCHAR iTLZeroW[]
Definition: locale.c:185
static const WCHAR iLDateW[]
Definition: locale.c:179
BOOL WINAPI GetCPInfoExW(UINT codepage, DWORD dwFlags, LPCPINFOEXW cpinfo)
Definition: locale.c:2222
static LCID lcid_LC_COLLATE
Definition: locale.c:161
INT WINAPI GetLocaleInfoA(LCID lcid, LCTYPE lctype, LPSTR buffer, INT len)
Definition: locale.c:1609
BOOL WINAPI GetCPInfo(UINT codepage, LPCPINFO cpinfo)
Definition: locale.c:2146
static const union cptable * get_codepage_table(unsigned int codepage)
Definition: locale.c:302
#define MB_FLAGSMASK
Definition: locale.c:60
static int get_value_base_by_lctype(LCTYPE lctype)
Definition: locale.c:1665
static const WCHAR iCurrDigitsW[]
Definition: locale.c:173
static struct registry_value registry_values[]
static const WCHAR sCountryW[]
Definition: locale.c:190
static BOOL CALLBACK enum_uilang_proc_a(HMODULE hModule, LPCSTR type, LPCSTR name, WORD LangID, LONG_PTR lParam)
Definition: locale.c:4924
INT WINAPI GetGeoInfoW(GEOID geoid, GEOTYPE geotype, LPWSTR data, int data_len, LANGID lang)
Definition: locale.c:5495
BOOL WINAPI IsValidLocaleName(LPCWSTR locale)
Definition: locale.c:2936
INT WINAPI IdnToAscii(DWORD dwFlags, LPCWSTR lpUnicodeCharStr, INT cchUnicodeChar, LPWSTR lpASCIICharStr, INT cchASCIIChar)
Definition: locale.c:5706
BOOL WINAPI EnumUILanguagesW(UILANGUAGE_ENUMPROCW pUILangEnumProc, DWORD dwFlags, LONG_PTR lParam)
Definition: locale.c:4976
int WINAPI lstrcmpA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4198
static int utf7_mbstowcs(const char *src, int srclen, WCHAR *dst, int dstlen)
Definition: locale.c:2352
static const WCHAR sGroupingW[]
Definition: locale.c:194
BOOL WINAPI EnumSystemLocalesA(LOCALE_ENUMPROCA lpfnLocaleEnum, DWORD dwFlags)
Definition: locale.c:2986
@ INIT_N
Definition: locale.c:5687
@ DAMP
Definition: locale.c:5685
@ SKEW
Definition: locale.c:5684
@ BASE
Definition: locale.c:5681
@ TMIN
Definition: locale.c:5682
@ TMAX
Definition: locale.c:5683
@ INIT_BIAS
Definition: locale.c:5686
static const WCHAR sTimeFormatW[]
Definition: locale.c:206
static LCID lcid_LC_CTYPE
Definition: locale.c:162
static HANDLE create_registry_key(void)
Definition: locale.c:771
DWORD WINAPI VerLanguageNameA(DWORD wLang, LPSTR szLang, DWORD nSize)
Definition: locale.c:3076
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4265
INT WINAPI LCMapStringEx(LPCWSTR locale, DWORD flags, LPCWSTR src, INT srclen, LPWSTR dst, INT dstlen, LPNLSVERSIONINFO version, LPVOID reserved, LPARAM handle)
Definition: locale.c:3746
static BOOL NLS_RegGetDword(HANDLE hKey, LPCWSTR szValueName, DWORD *lpVal)
Definition: locale.c:4409
LANGID WINAPI GetSystemDefaultUILanguage(void)
Definition: locale.c:1400
int WINAPI lstrcmpiA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4227
static LCID lcid_LC_MEASUREMENT
Definition: locale.c:168
BOOL WINAPI GetStringTypeW(DWORD type, LPCWSTR src, INT count, LPWORD chartype)
Definition: locale.c:3098
UINT WINAPI SetCPGlobal(UINT acp)
Definition: locale.c:2041
static const WCHAR iTimePrefixW[]
Definition: locale.c:186
BOOL WINAPI IsValidLocale(LCID lcid, DWORD flags)
Definition: locale.c:2925
INT WINAPI GetSystemDefaultLocaleName(LPWSTR localename, INT len)
Definition: locale.c:1246
BOOL WINAPI IsDBCSLeadByteEx(UINT codepage, BYTE testchar)
Definition: locale.c:2106
INT WINAPI FoldStringW(DWORD dwFlags, LPCWSTR src, INT srclen, LPWSTR dst, INT dstlen)
Definition: locale.c:3982
BOOL WINAPI GetThreadPreferredUILanguages(DWORD flags, ULONG *count, WCHAR *buf, ULONG *size)
Definition: locale.c:1334
static HANDLE NLS_RegOpenKey(HANDLE hRootKey, LPCWSTR szKeyName)
Definition: locale.c:4356
static const WCHAR sShortDateW[]
Definition: locale.c:204
LCID WINAPI GetUserDefaultLCID(void)
Definition: locale.c:1216
static UINT setup_unix_locales(void)
Definition: locale.c:1116
INT WINAPI CompareStringEx(LPCWSTR locale, DWORD flags, LPCWSTR str1, INT len1, LPCWSTR str2, INT len2, LPNLSVERSIONINFO version, LPVOID reserved, LPARAM lParam)
Definition: locale.c:4026
int wine_compare_string(int flags, const WCHAR *str1, int len1, const WCHAR *str2, int len2)
Definition: sortkey.c:358
static const WCHAR sMonThousandSepW[]
Definition: locale.c:200
BOOL WINAPI EnumLanguageGroupLocalesW(LANGGROUPLOCALE_ENUMPROCW pLangGrpLcEnumProc, LGRPID lgrpid, DWORD dwFlags, LONG_PTR lParam)
Definition: locale.c:4799
static LCID lcid_LC_TELEPHONE
Definition: locale.c:169
static unsigned short get_table_entry(const unsigned short *table, WCHAR ch)
Definition: locale.c:277
LANGID WINAPI GetUserDefaultLangID(void)
Definition: locale.c:1182
LCID WINAPI GetSystemDefaultLCID(void)
Definition: locale.c:1235
static const WCHAR iNegCurrW[]
Definition: locale.c:182
static BOOL locale_update_registry(HKEY hkey, const WCHAR *name, LCID lcid, const LCTYPE *values, UINT nb_values)
Definition: locale.c:804
BOOL WINAPI EnumUILanguagesA(UILANGUAGE_ENUMPROCA pUILangEnumProc, DWORD dwFlags, LONG_PTR lParam)
Definition: locale.c:4948
BOOL WINAPI GetStringTypeExW(LCID locale, DWORD type, LPCWSTR src, INT count, LPWORD chartype)
Definition: locale.c:3188
BOOL WINAPI IsNormalizedString(NORM_FORM NormForm, LPCWSTR lpString, INT cwLength)
Definition: locale.c:5673
INT WINAPI LCMapStringW(LCID lcid, DWORD flags, LPCWSTR src, INT srclen, LPWSTR dst, INT dstlen)
Definition: locale.c:3808
BOOL WINAPI SetThreadPreferredUILanguages(DWORD flags, PCZZWSTR buffer, PULONG count)
Definition: locale.c:1325
BOOL WINAPI EnumSystemGeoID(GEOCLASS geoclass, GEOID parent, GEO_ENUMPROC enumproc)
Definition: locale.c:5613
BOOL WINAPI GetCPInfoExA(UINT codepage, DWORD dwFlags, LPCPINFOEXA cpinfo)
Definition: locale.c:2204
static const union cptable * oem_cptable
Definition: locale.c:66
BOOL WINAPI InvalidateNLSCache(void)
Definition: locale.c:4827
static BOOL CALLBACK enum_uilang_proc_w(HMODULE hModule, LPCWSTR type, LPCWSTR name, WORD LangID, LONG_PTR lParam)
Definition: locale.c:4934
static const WCHAR sDateW[]
Definition: locale.c:192
BOOL WINAPI EnumLanguageGroupLocalesA(LANGGROUPLOCALE_ENUMPROCA pLangGrpLcEnumProc, LGRPID lgrpid, DWORD dwFlags, LONG_PTR lParam)
Definition: locale.c:4778
static const WCHAR sPositiveSignW[]
Definition: locale.c:203
#define GET_UNIX_LOCALE(cat)
static const WCHAR sListW[]
Definition: locale.c:196
BOOL WINAPI EnumSystemLanguageGroupsA(LANGUAGEGROUP_ENUMPROCA pLangGrpEnumProc, DWORD dwFlags, LONG_PTR lParam)
Definition: locale.c:4579
UINT WINAPI GetOEMCP(void)
Definition: locale.c:2062
HMODULE kernel32_handle
Definition: dllmain.c:26
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: locale.c:1675
static const union cptable * ansi_cptable
Definition: locale.c:65
BOOL WINAPI SetLocaleInfoA(LCID lcid, LCTYPE lctype, LPCSTR data)
Definition: locale.c:1891
static const WCHAR sYearMonthW[]
Definition: locale.c:208
#define REG_SZ
Definition: locale.c:45
static const WCHAR sNativeDigitsW[]
Definition: locale.c:201
INT WINAPI GetGeoInfoA(GEOID geoid, GEOTYPE geotype, LPSTR data, int data_len, LANGID lang)
Definition: locale.c:5569
static const union cptable * mac_cptable
Definition: locale.c:67
static const WCHAR iTimeW[]
Definition: locale.c:187
static const WCHAR sDecimalW[]
Definition: locale.c:193
static LCID lcid_LC_PAPER
Definition: locale.c:167
LCID WINAPI ConvertDefaultLocale(LCID lcid)
Definition: locale.c:2879
BOOL WINAPI SetLocaleInfoW(LCID lcid, LCTYPE lctype, LPCWSTR data)
Definition: locale.c:1923
INT WINAPI IdnToNameprepUnicode(DWORD dwFlags, LPCWSTR lpUnicodeCharStr, INT cchUnicodeChar, LPWSTR lpNameprepCharStr, INT cchNameprepChar)
Definition: locale.c:5844
INT WINAPI GetUserDefaultLocaleName(LPWSTR localename, int buffersize)
Definition: locale.c:5649
static LCID lcid_LC_MESSAGES
Definition: locale.c:163
static int map_to_fullwidth(const USHORT *table, const WCHAR *src, int srclen, WCHAR *dst, int dstlen)
Definition: locale.c:3987
LCID lcid
Definition: locale.c:5656
static int map_remove_ignored(DWORD flags, const WCHAR *src, int srclen, WCHAR *dst, int dstlen)
Definition: locale.c:4052
static int map_to_halfwidth(const USHORT *table, const WCHAR *src, int srclen, WCHAR *dst, int dstlen)
Definition: locale.c:4091
static HKEY nls_key
Definition: locale.c:309
static void map_byterev(const WCHAR *src, int len, WCHAR *dst)
Definition: locale.c:2042
static UINT unix_cp
Definition: locale.c:305
static int lcmap_string(const struct sortguid *sortid, DWORD flags, const WCHAR *src, int srclen, WCHAR *dst, int dstlen)
Definition: locale.c:4134
INT WINAPI DECLSPEC_HOTPATCH CompareStringOrdinal(const WCHAR *str1, INT len1, const WCHAR *str2, INT len2, BOOL ignore_case)
Definition: locale.c:4886
const WCHAR * text
Definition: package.c:1794
unsigned char
Definition: typeof.h:29
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define assert(x)
Definition: debug.h:53
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
r parent
Definition: btrfs.c:3010
r reserved
Definition: btrfs.c:3006
#define strcasecmp
Definition: fake.h:9
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
FxAutoRegKey hKey
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble t
Definition: gl.h:2047
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLdouble n
Definition: glext.h:7729
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLenum GLenum GLuint components
Definition: glext.h:9620
GLfloat bias
Definition: glext.h:7909
GLintptr offset
Definition: glext.h:5920
const GLubyte * c
Definition: glext.h:8905
GLuint index
Definition: glext.h:6031
GLenum GLint GLuint mask
Definition: glext.h:6028
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLenum dst
Definition: glext.h:6340
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:5666
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLuint GLfloat * val
Definition: glext.h:7180
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
const GLfloat * m
Definition: glext.h:10848
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
int wine_cpsymbol_wcstombs(const WCHAR *src, int srclen, char *dst, int dstlen)
#define C1_PUNCT
Definition: unicode.h:35
#define C1_SPACE
Definition: unicode.h:34
#define C1_ALPHA
Definition: unicode.h:39
#define MB_COMPOSITE
Definition: unicode.h:40
const union cptable * wine_cp_enum_table(unsigned int index)
Definition: cptable.c:203
int wine_utf8_wcstombs(int flags, const WCHAR *src, int srclen, char *dst, int dstlen)
Definition: utf8.c:98
int wine_cp_wcstombs(const union cptable *table, int flags, const WCHAR *src, int srclen, char *dst, int dstlen, const char *defchar, int *used)
Definition: wctomb.c:411
const union cptable * wine_cp_get_table(unsigned int codepage)
Definition: cptable.c:192
WINE_UNICODE_INLINE int wine_is_dbcs_leadbyte(const union cptable *table, unsigned char ch)
Definition: unicode.h:130
int wine_cpsymbol_mbstowcs(const char *src, int srclen, WCHAR *dst, int dstlen)
int wine_cp_mbstowcs(const union cptable *table, int flags, const char *src, int srclen, WCHAR *dst, int dstlen)
Definition: mbtowc.c:265
int wine_utf8_mbstowcs(int flags, const char *src, int srclen, WCHAR *dst, int dstlen)
Definition: utf8.c:304
WINE_UNICODE_INLINE unsigned short get_char_typeW(WCHAR ch)
Definition: unicode.h:149
_Check_return_ _CRTIMP int __cdecl isalnum(_In_ int _C)
#define LC_CTYPE
Definition: locale.h:19
#define LC_NUMERIC
Definition: locale.h:21
#define LC_MONETARY
Definition: locale.h:20
#define LC_ALL
Definition: locale.h:17
#define LC_TIME
Definition: locale.h:22
#define LC_COLLATE
Definition: locale.h:18
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
#define NtCurrentTeb
uint32_t entry
Definition: isohybrid.c:63
void JapaneseEra_ClearCache(void)
Definition: japanese.c:38
#define b
Definition: ke_i.h:79
BOOL WINAPI GetUserPreferredUILanguages(DWORD dwFlags, PULONG pulNumLanguages, PZZWSTR pwszLanguagesBuffer, PULONG pcchLanguagesBuffer)
Definition: vista.c:698
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_wn
Definition: kernel32.h:33
#define debugstr_w
Definition: kernel32.h:32
#define wine_dbgstr_w
Definition: kernel32.h:34
#define nls
Definition: kernel32.h:13
USHORT LANGID
Definition: mui.h:9
ULONG GEOID
Definition: mui.h:28
if(dx< 0)
Definition: linetemp.h:194
POINT cp
Definition: magnifier.c:59
#define matches(FN)
Definition: match.h:70
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
static PVOID ptr
Definition: dispmode.c:27
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static unsigned int number
Definition: dsound.c:1479
static const WCHAR localeW[]
Definition: locale.c:43
static DWORD LPDWORD LPCSTR DWORD srclen
Definition: directory.c:52
static DWORD dstlen
Definition: directory.c:51
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
WCHAR strW[12]
Definition: clipboard.c:2029
#define min(a, b)
Definition: monoChain.cc:55
int k
Definition: mpi.c:3369
LANGID langid
Definition: msctf.idl:626
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
const unsigned short nameprep_char_type[4432]
Definition: nameprep.c:5
const unsigned short nameprep_mapping[5856]
Definition: nameprep.c:565
unsigned int UINT
Definition: ndis.h:50
NTSYSAPI NTSTATUS NTAPI RtlOpenCurrentUser(_In_ ACCESS_MASK DesiredAccess, _Out_ PHANDLE KeyHandle)
_Must_inspect_result_ NTSYSAPI LONG NTAPI RtlCompareUnicodeStrings(_In_reads_(String1Length) PCWCH String1, _In_ SIZE_T String1Length, _In_reads_(String2Length) PCWCH String2, _In_ SIZE_T String2Length, _In_ BOOLEAN CaseInSensitive)
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
NTSYSAPI NTSTATUS NTAPI NtSetValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN ULONG TitleIndex OPTIONAL, IN ULONG Type, IN PVOID Data, IN ULONG DataSize)
Definition: ntapi.c:859
@ KeyValuePartialInformation
Definition: nt_native.h:1182
@ KeyValueFullInformation
Definition: nt_native.h:1181
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI NTSTATUS NTAPI NtQueryValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, IN PULONG ResultLength)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSTATUS NTAPI NtCreateKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG TitleIndex, IN PUNICODE_STRING Class OPTIONAL, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL)
Definition: ntapi.c:240
NTSTATUS NTAPI NtEnumerateValueKey(IN HANDLE KeyHandle, IN ULONG Index, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, OUT PVOID KeyValueInformation, IN ULONG Length, OUT PULONG ResultLength)
Definition: ntapi.c:542
#define LOCALE_NEUTRAL
#define LOCALE_USER_DEFAULT
#define LOCALE_INVARIANT
#define SORTIDFROMLCID(lcid)
#define LOCALE_SYSTEM_DEFAULT
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:395
#define SORT_DEFAULT
#define MAKELCID(lgid, srtid)
_NullNull_terminated_ CONST WCHAR * PCZZWSTR
Definition: ntbasedef.h:433
NTSTATUS NTAPI NtQueryInstallUILanguage(OUT LANGID *LanguageId)
Definition: locale.c:611
NTSTATUS NTAPI NtQueryDefaultLocale(IN BOOLEAN UserProfile, OUT PLCID DefaultLocaleId)
Definition: locale.c:396
NTSTATUS NTAPI NtSetDefaultUILanguage(IN LANGID LanguageId)
Definition: locale.c:692
NTSTATUS NTAPI NtQueryDefaultUILanguage(OUT LANGID *LanguageId)
Definition: locale.c:645
NTSTATUS NTAPI NtSetDefaultLocale(IN BOOLEAN UserProfile, IN LCID DefaultLocaleId)
Definition: locale.c:437
#define MAKEINTRESOURCE(i)
Definition: ntverrsrc.c:25
static HANDLE proc()
Definition: pdb.c:34
#define RT_STRING
Definition: pedump.c:368
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
static const WCHAR szName[]
Definition: powrprof.c:45
#define strncmpiW(s1, s2, n)
Definition: unicode.h:46
#define toupperW(n)
Definition: unicode.h:51
#define strcmpW(s1, s2)
Definition: unicode.h:44
#define strchrW(s, c)
Definition: unicode.h:40
#define strcmpiW(s1, s2)
Definition: unicode.h:45
#define tolowerW(n)
Definition: unicode.h:50
#define strlenW(s)
Definition: unicode.h:34
#define strrchrW(s, c)
Definition: unicode.h:41
#define strcatW(d, s)
Definition: unicode.h:36
#define strtoulW(s1, s2, b)
Definition: unicode.h:47
#define sprintfW
Definition: unicode.h:64
#define strtolW(s, e, b)
Definition: unicode.h:39
#define strcpyW(d, s)
Definition: unicode.h:35
#define strpbrkW(str, accept)
Definition: unicode.h:49
const WCHAR * str
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
#define LANG_NEUTRAL
Definition: nls.h:22
#define MAKELANGID(p, s)
Definition: nls.h:15
#define SUBLANG_CHINESE_SINGAPORE
Definition: nls.h:211
#define SUBLANGID(l)
Definition: nls.h:17
#define LANG_SPANISH
Definition: nls.h:123
#define SUBLANG_CHINESE_MACAU
Definition: nls.h:212
#define LANG_ENGLISH
Definition: nls.h:52
#define LANGIDFROMLCID(l)
Definition: nls.h:18
#define SUBLANG_CHINESE_TRADITIONAL
Definition: nls.h:208
#define SUBLANG_NEUTRAL
Definition: nls.h:167
#define SUBLANG_CHINESE_SIMPLIFIED
Definition: nls.h:209
#define SUBLANG_DEFAULT
Definition: nls.h:168
#define SUBLANG_CHINESE_HONGKONG
Definition: nls.h:210
#define LANG_CHINESE
Definition: nls.h:42
DWORD LCID
Definition: nls.h:13
#define CP_UTF8
Definition: nls.h:20
#define PRIMARYLANGID(l)
Definition: nls.h:16
#define SUBLANG_SPANISH_MODERN
Definition: nls.h:338
strcat
Definition: string.h:92
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define TRACE(s)
Definition: solgame.cpp:4
CardRegion * from
Definition: spigame.cpp:19
LANGGROUPLOCALE_ENUMPROCW procW
Definition: locale.c:4669
LANGGROUPLOCALE_ENUMPROCA procA
Definition: locale.c:4668
LANGUAGEGROUP_ENUMPROCW procW
Definition: locale.c:4474
LANGUAGEGROUP_ENUMPROCA procA
Definition: locale.c:4473
union ENUM_UILANG_CALLBACK::@511 u
UILANGUAGE_ENUMPROCA procA
Definition: locale.c:4917
UILANGUAGE_ENUMPROCW procW
Definition: locale.c:4918
BYTE LeadByte[MAX_LEADBYTES]
Definition: winnls.h:603
BYTE DefaultChar[MAX_DEFAULTCHAR]
Definition: winnls.h:602
UINT MaxCharSize
Definition: winnls.h:601
CHAR CodePageName[MAX_PATH]
Definition: winnls.h:611
WCHAR UnicodeDefaultChar
Definition: winnls.h:617
WCHAR CodePageName[MAX_PATH]
Definition: winnls.h:619
UINT CodePage
Definition: winnls.h:618
Definition: cookie.c:202
Definition: mimeintl.c:44
LOCALE_ENUMPROCEX proc
INT uncode
Definition: locale.c:5013
enum locationkind kind
Definition: locale.c:5014
GEOID parent
Definition: locale.c:5012
GEOID id
Definition: locale.c:5009
WCHAR iso2W[3]
Definition: locale.c:5010
WCHAR iso3W[4]
Definition: locale.c:5011
WCHAR win_name[128]
Definition: locale.c:149
int matches
Definition: locale.c:156
UINT codepage
Definition: locale.c:157
LCID lcid
Definition: locale.c:155
WCHAR lang[128]
Definition: locale.c:150
WCHAR * country
Definition: locale.c:151
WCHAR * charset
Definition: locale.c:152
WCHAR * modifier
Definition: locale.c:154
WCHAR * script
Definition: locale.c:153
Definition: name.c:39
Definition: module.h:576
WCHAR * cached_value
Definition: locale.c:215
const WCHAR * name
Definition: locale.c:214
DWORD lctype
Definition: locale.c:213
Definition: ps.c:97
const WCHAR * name
#define max(a, b)
Definition: svc.c:63
#define bsearch
#define setlocale(n, s)
Definition: locale.h:46
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint16_t * LPWORD
Definition: typedefs.h:56
uint32_t * LPDWORD
Definition: typedefs.h:59
int32_t INT
Definition: typedefs.h:58
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
struct cp_info info
Definition: unicode.h:96
Definition: pdh_main.c:96
static const WCHAR lang[]
Definition: wbemdisp.c:287
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_writes_opt_ NumCharacters PUSHORT _Inout_ PUSHORT _In_ UCHAR _In_opt_ USHORT LangID
Definition: wdfusb.h:1083
int codepage
Definition: win_iconv.c:156
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:2125
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
LONG_PTR LPARAM
Definition: windef.h:208
#define WINAPI
Definition: msvc.h:6
#define ERROR_NO_UNICODE_TRANSLATION
Definition: winerror.h:649
#define ERROR_INVALID_FLAGS
Definition: winerror.h:583
#define LGRPID_INSTALLED
Definition: winnls.h:478
#define C2_ARABICNUMBER
Definition: winnls.h:273
#define LOCALE_USE_CP_ACP
Definition: winnls.h:20
#define LCMAP_LINGUISTIC_CASING
Definition: winnls.h:205
#define LOCALE_SABBREVMONTHNAME10
Definition: winnls.h:120
#define LOCALE_SMONTHNAME12
Definition: winnls.h:109
#define CP_THREAD_ACP
Definition: winnls.h:251
#define LOCALE_ICURRDIGITS
Definition: winnls.h:61
#define LOCALE_IDEFAULTCODEPAGE
Definition: winnls.h:44
#define NORM_IGNORECASE
Definition: winnls.h:187
#define LOCALE_SMONTHNAME5
Definition: winnls.h:102
#define C3_FULLWIDTH
Definition: winnls.h:287
#define CP_OEMCP
Definition: winnls.h:249
#define LOCALE_SCOUNTRY
Definition: winnls.h:37
#define LOCALE_SDATE
Definition: winnls.h:65
#define LOCALE_SDAYNAME5
Definition: winnls.h:88
#define C3_ALPHA
Definition: winnls.h:291
DWORD LGRPID
Definition: winnls.h:540
#define LOCALE_SABBREVMONTHNAME9
Definition: winnls.h:119
BOOL(CALLBACK * LOCALE_ENUMPROCEX)(LPWSTR, DWORD, LPARAM)
Definition: winnls.h:559
BOOL(CALLBACK * LANGGROUPLOCALE_ENUMPROCA)(LGRPID, LCID, LPSTR, LONG_PTR)
Definition: winnls.h:553
enum _NORM_FORM NORM_FORM
#define LOCALE_NEUTRALDATA
Definition: winnls.h:228
#define LOCALE_SABBREVMONTHNAME11
Definition: winnls.h:121
#define LOCALE_SABBREVDAYNAME5
Definition: winnls.h:95
#define LOCALE_SABBREVDAYNAME2
Definition: winnls.h:92
#define LOCALE_INEGSEPBYSPACE
Definition: winnls.h:131
#define LOCALE_SABBREVMONTHNAME2
Definition: winnls.h:112
#define LOCALE_INEGSIGNPOSN
Definition: winnls.h:127
#define LOCALE_IDEFAULTUNIXCODEPAGE
Definition: winnls.h:185
#define C2_OTHERNEUTRAL
Definition: winnls.h:278
#define LOCALE_SMONTHNAME13
Definition: winnls.h:110
#define LOCALE_SGROUPING
Definition: winnls.h:51
#define C2_LEFTTORIGHT
Definition: winnls.h:268
#define LOCALE_SMONTHNAME3
Definition: winnls.h:100
#define CT_CTYPE2
Definition: winnls.h:256
#define SORT_STRINGSORT
Definition: winnls.h:195
#define C3_DIACRITIC
Definition: winnls.h:281
#define C3_IDEOGRAPH
Definition: winnls.h:288
#define LOCALE_SSHORTTIME
Definition: winnls.h:170
#define LOCALE_ICOUNTRY
Definition: winnls.h:36
#define LINGUISTIC_IGNORECASE
Definition: winnls.h:192
#define LCMAP_SIMPLIFIED_CHINESE
Definition: winnls.h:206
#define CP_SYMBOL
Definition: winnls.h:252
#define LOCALE_SDECIMAL
Definition: winnls.h:49
#define LOCALE_SMONTHNAME11
Definition: winnls.h:108
#define LOCALE_SMONTHNAME8
Definition: winnls.h:105
@ GEO_ISO3
Definition: winnls.h:586
@ GEO_OFFICIALLANGUAGES
Definition: winnls.h:592
@ GEO_OFFICIALNAME
Definition: winnls.h:590
@ GEO_TIMEZONES
Definition: winnls.h:591
@ GEO_FRIENDLYNAME
Definition: winnls.h:589
@ GEO_LONGITUDE
Definition: winnls.h:584
@ GEO_ISO_UN_NUMBER
Definition: winnls.h:593
@ GEO_PARENT
Definition: winnls.h:594
@ GEO_ISO2
Definition: winnls.h:585
@ GEO_LATITUDE
Definition: winnls.h:583
@ GEO_NATION
Definition: winnls.h:582
@ GEO_LCID
Definition: winnls.h:588
@ GEO_RFC1766
Definition: winnls.h:587
#define LCMAP_TRADITIONAL_CHINESE
Definition: winnls.h:207
#define LGRPID_ARMENIAN
Definition: winnls.h:496
#define CT_CTYPE3
Definition: winnls.h:257
#define CT_CTYPE1
Definition: winnls.h:255
#define LOCALE_IDATE
Definition: winnls.h:70
#define LOCALE_SMONTHNAME4
Definition: winnls.h:101
#define LOCALE_FONTSIGNATURE
Definition: winnls.h:132
BOOL(CALLBACK * UILANGUAGE_ENUMPROCW)(LPWSTR, LONG_PTR)
Definition: winnls.h:555
#define LOCALE_SENGLANGUAGE
Definition: winnls.h:32
#define C3_HALFWIDTH
Definition: winnls.h:286
#define MAP_PRECOMPOSED
Definition: winnls.h:233
#define LOCALE_SABBREVMONTHNAME13
Definition: winnls.h:123
#define C2_EUROPENUMBER
Definition: winnls.h:270
#define LOCALE_IFIRSTWEEKOFYEAR
Definition: winnls.h:83
#define LCMAP_HALFWIDTH
Definition: winnls.h:203
#define LOCALE_SDAYNAME1
Definition: winnls.h:84
#define LOCALE_IMEASURE
Definition: winnls.h:48
#define C3_NONSPACING
Definition: winnls.h:280
#define LCMAP_HIRAGANA
Definition: winnls.h:201
#define LOCALE_ILANGUAGE
Definition: winnls.h:30
#define C3_SYMBOL
Definition: winnls.h:283
#define LOCALE_SNAME
Definition: winnls.h:137
#define LCMAP_UPPERCASE
Definition: winnls.h:198
#define LOCALE_SLONGDATE
Definition: winnls.h:68
#define LOCALE_SMONTHNAME7
Definition: winnls.h:104
#define C3_LOWSURROGATE
Definition: winnls.h:294
#define NORM_IGNOREKANATYPE
Definition: winnls.h:188
#define NORM_LINGUISTIC_CASING
Definition: winnls.h:194
#define LOCALE_IINTLCURRDIGITS
Definition: winnls.h:62
#define C2_COMMONSEPARATOR
Definition: winnls.h:274
#define LOCALE_S1159
Definition: winnls.h:78
#define LOCALE_SSHORTDATE
Definition: winnls.h:67
#define CSTR_EQUAL
Definition: winnls.h:476
#define GEOID_NOT_AVAILABLE
Definition: winnls.h:13
BOOL(CALLBACK * GEO_ENUMPROC)(GEOID)
Definition: winnls.h:568
BOOL(CALLBACK * LANGGROUPLOCALE_ENUMPROCW)(LGRPID, LCID, LPWSTR, LONG_PTR)
Definition: winnls.h:554
#define NORM_IGNORENONSPACE
Definition: winnls.h:189
BOOL(CALLBACK * CODEPAGE_ENUMPROCA)(LPSTR)
Definition: winnls.h:560
#define LOCALE_SPECIFICDATA
Definition: winnls.h:229
#define LOCALE_IPOSSYMPRECEDES
Definition: winnls.h:128
#define LOCALE_IDAYLZERO
Definition: winnls.h:76
#define C3_KATAKANA
Definition: winnls.h:284
#define C2_EUROPESEPARATOR
Definition: winnls.h:271
#define CP_UTF7
Definition: winnls.h:253
#define LOCALE_SABBREVMONTHNAME4
Definition: winnls.h:114
#define CP_MACCP
Definition: winnls.h:250
#define LOCALE_SPOSITIVESIGN
Definition: winnls.h:124
BOOL(CALLBACK * LANGUAGEGROUP_ENUMPROCW)(LGRPID, LPWSTR, LPWSTR, DWORD, LONG_PTR)
Definition: winnls.h:552
#define NORM_IGNORESYMBOLS
Definition: winnls.h:190
#define LOCALE_INEUTRAL
Definition: winnls.h:163
#define LOCALE_IDEFAULTLANGUAGE
Definition: winnls.h:42
_In_ DWORD _In_ int _In_ int cchDest
Definition: winnls.h:1197
#define C2_EUROPETERMINATOR
Definition: winnls.h:272
#define LOCALE_SABBREVDAYNAME4
Definition: winnls.h:94
#define LOCALE_SMONDECIMALSEP
Definition: winnls.h:58
#define CP_INSTALLED
Definition: winnls.h:212
#define LOCALE_SISO639LANGNAME
Definition: winnls.h:133
#define LCMAP_SORTKEY
Definition: winnls.h:199
#define MAP_COMPOSITE
Definition: winnls.h:234
#define LCMAP_LOWERCASE
Definition: winnls.h:197
#define LOCALE_ITIME
Definition: winnls.h:72
#define LOCALE_ICURRENCY
Definition: winnls.h:63
#define C2_SEGMENTSEPARATOR
Definition: winnls.h:276
#define C3_KASHIDA
Definition: winnls.h:289
#define LOCALE_SMONTHNAME1
Definition: winnls.h:98
#define LOCALE_SABBREVMONTHNAME3
Definition: winnls.h:113
#define LOCALE_ITLZERO
Definition: winnls.h:75
#define LOCALE_INEGSYMPRECEDES
Definition: winnls.h:130
BOOL(CALLBACK * LOCALE_ENUMPROCA)(LPSTR)
Definition: winnls.h:557
#define LOCALE_SMONTHOUSANDSEP
Definition: winnls.h:59
#define LOCALE_SDAYNAME7
Definition: winnls.h:90
#define LOCALE_IPOSSIGNPOSN
Definition: winnls.h:126
#define C2_RIGHTTOLEFT
Definition: winnls.h:269
#define LOCALE_SDAYNAME2
Definition: winnls.h:85
#define LOCALE_SABBREVMONTHNAME1
Definition: winnls.h:111
DWORD GEOCLASS
Definition: winnls.h:543
#define LOCALE_NOUSEROVERRIDE
Definition: winnls.h:19
#define LOCALE_IOPTIONALCALENDAR
Definition: winnls.h:81
#define LOCALE_IDIGITS
Definition: winnls.h:52
#define MAP_FOLDCZONE
Definition: winnls.h:231
DWORD GEOTYPE
Definition: winnls.h:542
#define LCID_SUPPORTED
Definition: winnls.h:215
#define LOCALE_STHOUSAND
Definition: winnls.h:50
#define LOCALE_IDEFAULTANSICODEPAGE
Definition: winnls.h:45
#define C3_HIRAGANA
Definition: winnls.h:285
#define LOCALE_SISO3166CTRYNAME
Definition: winnls.h:134
#define LOCALE_SABBREVDAYNAME6
Definition: winnls.h:96
#define LOCALE_SMONTHNAME2
Definition: winnls.h:99
#define LOCALE_STIMEFORMAT
Definition: winnls.h:69
BOOL(CALLBACK * LANGUAGEGROUP_ENUMPROCA)(LGRPID, LPSTR, LPSTR, DWORD, LONG_PTR)
Definition: winnls.h:551
#define LOCALE_SABBREVDAYNAME1
Definition: winnls.h:91
#define LOCALE_IFIRSTDAYOFWEEK
Definition: winnls.h:82
#define LOCALE_SABBREVMONTHNAME6
Definition: winnls.h:116
#define LOCALE_SMONTHNAME6
Definition: winnls.h:103
#define C2_WHITESPACE
Definition: winnls.h:277
#define LOCALE_STIME
Definition: winnls.h:66
#define NORM_IGNOREWIDTH
Definition: winnls.h:191
#define LOCALE_SABBREVLANGNAME
Definition: winnls.h:34
#define C3_HIGHSURROGATE
Definition: winnls.h:293
BOOL(CALLBACK * UILANGUAGE_ENUMPROCA)(LPSTR, LONG_PTR)
Definition: winnls.h:556
#define LOCALE_INEGNUMBER
Definition: winnls.h:54
#define LOCALE_SNEGATIVESIGN
Definition: winnls.h:125
#define LOCALE_WINDOWS
Definition: winnls.h:224
DWORD LCTYPE
Definition: winnls.h:537
#define LOCALE_SDAYNAME3
Definition: winnls.h:86
#define CSTR_LESS_THAN
Definition: winnls.h:475
#define LOCALE_S2359
Definition: winnls.h:79
#define LOCALE_SNATIVEDIGITS
Definition: winnls.h:55
#define LOCALE_SLIST
Definition: winnls.h:47
#define LOCALE_SABBREVDAYNAME3
Definition: winnls.h:93
#define CP_SUPPORTED
Definition: winnls.h:213
#define C2_NOTAPPLICABLE
Definition: winnls.h:279
#define LOCALE_ILZERO
Definition: winnls.h:53
#define LOCALE_SABBREVMONTHNAME5
Definition: winnls.h:115
#define LOCALE_SABBREVMONTHNAME7
Definition: winnls.h:117
#define LOCALE_ICALENDARTYPE
Definition: winnls.h:80
#define LOCALE_SINTLSYMBOL
Definition: winnls.h:57
BOOL(CALLBACK * LOCALE_ENUMPROCW)(LPWSTR)
Definition: winnls.h:558
#define LOCALE_SABBREVMONTHNAME8
Definition: winnls.h:118
#define LCMAP_KATAKANA
Definition: winnls.h:202
#define CSTR_GREATER_THAN
Definition: winnls.h:477
#define LOCALE_SMONGROUPING
Definition: winnls.h:60
#define LOCALE_SDAYNAME4
Definition: winnls.h:87
#define LOCALE_SCURRENCY
Definition: winnls.h:56
#define LOCALE_SMONTHNAME10
Definition: winnls.h:107
#define LOCALE_INEGCURR
Definition: winnls.h:64
#define LOCALE_ILDATE
Definition: winnls.h:71
#define LCMAP_FULLWIDTH
Definition: winnls.h:204
#define LCMAP_BYTEREV
Definition: winnls.h:200
#define LOCALE_SMONTHNAME9
Definition: winnls.h:106
BOOL(CALLBACK * CODEPAGE_ENUMPROCW)(LPWSTR)
Definition: winnls.h:561
#define LOCALE_IPOSSEPBYSPACE
Definition: winnls.h:129
#define LOCALE_ICENTURY
Definition: winnls.h:74
#define C2_BLOCKSEPARATOR
Definition: winnls.h:275
#define LOCALE_IMONLZERO
Definition: winnls.h:77
@ GEOCLASS_REGION
Definition: winnls.h:576
@ GEOCLASS_NATION
Definition: winnls.h:575
#define LOCALE_SABBREVMONTHNAME12
Definition: winnls.h:122
#define LOCALE_IDEFAULTMACCODEPAGE
Definition: winnls.h:46
#define LGRPID_SUPPORTED
Definition: winnls.h:479
#define LOCALE_SDAYNAME6
Definition: winnls.h:89
#define LOCALE_ITIMEMARKPOSN
Definition: winnls.h:73
#define LOCALE_RETURN_GENITIVE_NAMES
Definition: winnls.h:24
#define LOCALE_SABBREVDAYNAME7
Definition: winnls.h:97
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
#define RtlUshortByteSwap(_x)
Definition: rtlfuncs.h:3214
static int callbacks
Definition: xmllint.c:838
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193