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 * Copyright 2003 Jon Griffiths
9 * Copyright 2005 Dmitry Timoshkov
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
30 #define WIN32_NO_STATUS
37 #include "kernelbase.h"
38 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(nls
);
43 static const WCHAR codepages_key
[] =
44 { 'S','y','s','t','e','m','\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t',
45 '\\','C','o','n','t','r','o','l','\\','N','l','s','\\','C','o','d','e','P','a','g','e',0};
46 static const WCHAR language_groups_key
[] =
47 { 'S','y','s','t','e','m','\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t',
48 '\\','C','o','n','t','r','o','l','\\','N','l','s',
49 '\\','L','a','n','g','u','a','g','e',' ','G','r','o','u','p','s',0 };
50 static const WCHAR locales_key
[] =
51 { 'S','y','s','t','e','m','\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t',
52 '\\','C','o','n','t','r','o','l','\\','N','l','s','\\','L','o','c','a','l','e',0};
53 static const WCHAR altsort_key
[] = {'A','l','t','e','r','n','a','t','e',' ','S','o','r','t','s',0};
56 /* Note: the Internal_ functions are not documented. The number of parameters
57 * should be correct, but their exact meaning may not.
60 /******************************************************************************
61 * Internal_EnumCalendarInfo (kernelbase.@)
63 BOOL WINAPI DECLSPEC_HOTPATCH
Internal_EnumCalendarInfo( CALINFO_ENUMPROCW proc
, LCID lcid
, CALID id
,
64 CALTYPE type
, BOOL unicode
, BOOL ex
,
65 BOOL exex
, LPARAM lparam
)
73 SetLastError( ERROR_INVALID_PARAMETER
);
77 if (id
== ENUM_ALL_CALENDARS
)
79 if (!GetLocaleInfoW( lcid
, LOCALE_ICALENDARTYPE
| LOCALE_RETURN_NUMBER
,
80 (WCHAR
*)&id
, sizeof(id
) / sizeof(WCHAR
) )) return FALSE
;
81 if (!GetLocaleInfoW( lcid
, LOCALE_IOPTIONALCALENDAR
| LOCALE_RETURN_NUMBER
,
82 (WCHAR
*)&optional
, sizeof(optional
) / sizeof(WCHAR
) )) optional
= 0;
87 if (type
& CAL_RETURN_NUMBER
)
88 ret
= GetCalendarInfoW( lcid
, id
, type
, NULL
, 0, (LPDWORD
)buffer
);
90 ret
= GetCalendarInfoW( lcid
, id
, type
, buffer
, ARRAY_SIZE(buffer
), NULL
);
94 ret
= GetCalendarInfoW( lcid
, id
, type
, bufW
, ARRAY_SIZE(bufW
), NULL
);
95 if (ret
) WideCharToMultiByte( CP_ACP
, 0, bufW
, -1, (char *)buffer
, sizeof(buffer
), NULL
, NULL
);
100 if (exex
) ret
= ((CALINFO_ENUMPROCEXEX
)proc
)( buffer
, id
, NULL
, lparam
);
101 else if (ex
) ret
= ((CALINFO_ENUMPROCEXW
)proc
)( buffer
, id
);
102 else ret
= proc( buffer
);
105 if (!optional
) break;
112 /**************************************************************************
113 * Internal_EnumDateFormats (kernelbase.@)
115 BOOL WINAPI DECLSPEC_HOTPATCH
Internal_EnumDateFormats( DATEFMT_ENUMPROCW proc
, LCID lcid
, DWORD flags
,
116 BOOL unicode
, BOOL ex
, BOOL exex
, LPARAM lparam
)
125 SetLastError( ERROR_INVALID_PARAMETER
);
128 if (!GetLocaleInfoW( lcid
, LOCALE_ICALENDARTYPE
|LOCALE_RETURN_NUMBER
,
129 (LPWSTR
)&cal_id
, sizeof(cal_id
)/sizeof(WCHAR
) ))
132 switch (flags
& ~LOCALE_USE_CP_ACP
)
136 lctype
= LOCALE_SSHORTDATE
;
139 lctype
= LOCALE_SLONGDATE
;
142 lctype
= LOCALE_SYEARMONTH
;
145 FIXME( "unknown date format 0x%08x\n", flags
);
146 SetLastError( ERROR_INVALID_PARAMETER
);
150 lctype
|= flags
& LOCALE_USE_CP_ACP
;
152 ret
= GetLocaleInfoW( lcid
, lctype
, buffer
, ARRAY_SIZE(buffer
) );
154 ret
= GetLocaleInfoA( lcid
, lctype
, (char *)buffer
, sizeof(buffer
) );
158 if (exex
) ((DATEFMT_ENUMPROCEXEX
)proc
)( buffer
, cal_id
, lparam
);
159 else if (ex
) ((DATEFMT_ENUMPROCEXW
)proc
)( buffer
, cal_id
);
166 /******************************************************************************
167 * Internal_EnumLanguageGroupLocales (kernelbase.@)
169 BOOL WINAPI DECLSPEC_HOTPATCH
Internal_EnumLanguageGroupLocales( LANGGROUPLOCALE_ENUMPROCW proc
, LGRPID id
,
170 DWORD flags
, LONG_PTR param
, BOOL unicode
)
172 WCHAR name
[10], value
[10];
173 DWORD name_len
, value_len
, type
, index
= 0, alt
= 0;
177 if (!proc
|| id
< LGRPID_WESTERN_EUROPE
|| id
> LGRPID_ARMENIAN
)
179 SetLastError( ERROR_INVALID_PARAMETER
);
183 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
, locales_key
, 0, KEY_READ
, &key
)) return FALSE
;
184 if (RegOpenKeyExW( key
, altsort_key
, 0, KEY_READ
, &altkey
)) altkey
= 0;
188 name_len
= ARRAY_SIZE(name
);
189 value_len
= sizeof(value
);
190 if (RegEnumValueW( alt
? altkey
: key
, index
++, name
, &name_len
, NULL
,
191 &type
, (BYTE
*)value
, &value_len
))
197 if (type
!= REG_SZ
) continue;
198 if (id
!= wcstoul( value
, NULL
, 16 )) continue;
199 lcid
= wcstoul( name
, NULL
, 16 );
203 WideCharToMultiByte( CP_ACP
, 0, name
, -1, nameA
, sizeof(nameA
), NULL
, NULL
);
204 if (!((LANGGROUPLOCALE_ENUMPROCA
)proc
)( id
, lcid
, nameA
, param
)) break;
206 else if (!proc( id
, lcid
, name
, param
)) break;
208 RegCloseKey( altkey
);
214 /***********************************************************************
215 * Internal_EnumSystemCodePages (kernelbase.@)
217 BOOL WINAPI DECLSPEC_HOTPATCH
Internal_EnumSystemCodePages( CODEPAGE_ENUMPROCW proc
, DWORD flags
,
221 DWORD name_len
, type
, index
= 0;
224 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
, codepages_key
, 0, KEY_READ
, &key
)) return FALSE
;
228 name_len
= ARRAY_SIZE(name
);
229 if (RegEnumValueW( key
, index
++, name
, &name_len
, NULL
, &type
, NULL
, NULL
)) break;
230 if (type
!= REG_SZ
) continue;
231 if (!wcstoul( name
, NULL
, 10 )) continue;
235 WideCharToMultiByte( CP_ACP
, 0, name
, -1, nameA
, sizeof(nameA
), NULL
, NULL
);
236 if (!((CODEPAGE_ENUMPROCA
)proc
)( nameA
)) break;
238 else if (!proc( name
)) break;
245 /******************************************************************************
246 * Internal_EnumSystemLanguageGroups (kernelbase.@)
248 BOOL WINAPI DECLSPEC_HOTPATCH
Internal_EnumSystemLanguageGroups( LANGUAGEGROUP_ENUMPROCW proc
,
249 DWORD flags
, LONG_PTR param
, BOOL unicode
)
251 WCHAR name
[10], value
[10], descr
[80];
252 DWORD name_len
, value_len
, type
, index
= 0;
258 SetLastError( ERROR_INVALID_PARAMETER
);
265 flags
= LGRPID_INSTALLED
;
267 case LGRPID_INSTALLED
:
268 case LGRPID_SUPPORTED
:
271 SetLastError( ERROR_INVALID_FLAGS
);
275 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
, language_groups_key
, 0, KEY_READ
, &key
)) return FALSE
;
279 name_len
= ARRAY_SIZE(name
);
280 value_len
= sizeof(value
);
281 if (RegEnumValueW( key
, index
++, name
, &name_len
, NULL
, &type
, (BYTE
*)value
, &value_len
)) break;
282 if (type
!= REG_SZ
) continue;
284 id
= wcstoul( name
, NULL
, 16 );
286 if (!(flags
& LGRPID_SUPPORTED
) && !wcstoul( value
, NULL
, 10 )) continue;
287 if (!LoadStringW( kernel32_handle
, 0x2000 + id
, descr
, ARRAY_SIZE(descr
) )) descr
[0] = 0;
288 TRACE( "%p: %u %s %s %x %lx\n", proc
, id
, debugstr_w(name
), debugstr_w(descr
), flags
, param
);
291 char nameA
[10], descrA
[80];
292 WideCharToMultiByte( CP_ACP
, 0, name
, -1, nameA
, sizeof(nameA
), NULL
, NULL
);
293 WideCharToMultiByte( CP_ACP
, 0, descr
, -1, descrA
, sizeof(descrA
), NULL
, NULL
);
294 if (!((LANGUAGEGROUP_ENUMPROCA
)proc
)( id
, nameA
, descrA
, flags
, param
)) break;
296 else if (!proc( id
, name
, descr
, flags
, param
)) break;
303 /**************************************************************************
304 * Internal_EnumTimeFormats (kernelbase.@)
306 BOOL WINAPI DECLSPEC_HOTPATCH
Internal_EnumTimeFormats( TIMEFMT_ENUMPROCW proc
, LCID lcid
, DWORD flags
,
307 BOOL unicode
, BOOL ex
, LPARAM lparam
)
315 SetLastError( ERROR_INVALID_PARAMETER
);
318 switch (flags
& ~LOCALE_USE_CP_ACP
)
321 lctype
= LOCALE_STIMEFORMAT
;
324 lctype
= LOCALE_SSHORTTIME
;
327 FIXME( "Unknown time format %x\n", flags
);
328 SetLastError( ERROR_INVALID_PARAMETER
);
332 lctype
|= flags
& LOCALE_USE_CP_ACP
;
334 ret
= GetLocaleInfoW( lcid
, lctype
, buffer
, ARRAY_SIZE(buffer
) );
336 ret
= GetLocaleInfoA( lcid
, lctype
, (char *)buffer
, sizeof(buffer
) );
340 if (ex
) ((TIMEFMT_ENUMPROCEX
)proc
)( buffer
, lparam
);
347 /******************************************************************************
348 * Internal_EnumUILanguages (kernelbase.@)
350 BOOL WINAPI DECLSPEC_HOTPATCH
Internal_EnumUILanguages( UILANGUAGE_ENUMPROCW proc
, DWORD flags
,
351 LONG_PTR param
, BOOL unicode
)
354 DWORD name_len
, type
, index
= 0;
359 SetLastError( ERROR_INVALID_PARAMETER
);
362 if (flags
& ~MUI_LANGUAGE_ID
)
364 SetLastError( ERROR_INVALID_FLAGS
);
368 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
, locales_key
, 0, KEY_READ
, &key
)) return FALSE
;
372 name_len
= ARRAY_SIZE(name
);
373 if (RegEnumValueW( key
, index
++, name
, &name_len
, NULL
, &type
, NULL
, NULL
)) break;
374 if (type
!= REG_SZ
) continue;
375 if (!wcstoul( name
, NULL
, 16 )) continue;
379 WideCharToMultiByte( CP_ACP
, 0, name
, -1, nameA
, sizeof(nameA
), NULL
, NULL
);
380 if (!((UILANGUAGE_ENUMPROCA
)proc
)( nameA
, param
)) break;
382 else if (!proc( name
, param
)) break;
389 /******************************************************************************
390 * CompareStringOrdinal (kernelbase.@)
392 INT WINAPI DECLSPEC_HOTPATCH
CompareStringOrdinal( const WCHAR
*str1
, INT len1
,
393 const WCHAR
*str2
, INT len2
, BOOL ignore_case
)
399 SetLastError( ERROR_INVALID_PARAMETER
);
402 if (len1
< 0) len1
= lstrlenW( str1
);
403 if (len2
< 0) len2
= lstrlenW( str2
);
405 ret
= RtlCompareUnicodeStrings( str1
, len1
, str2
, len2
, ignore_case
);
406 if (ret
< 0) return CSTR_LESS_THAN
;
407 if (ret
> 0) return CSTR_GREATER_THAN
;
412 /******************************************************************************
413 * EnumCalendarInfoW (kernelbase.@)
415 BOOL WINAPI DECLSPEC_HOTPATCH
EnumCalendarInfoW( CALINFO_ENUMPROCW proc
, LCID lcid
,
416 CALID id
, CALTYPE type
)
418 return Internal_EnumCalendarInfo( proc
, lcid
, id
, type
, TRUE
, FALSE
, FALSE
, 0 );
422 /******************************************************************************
423 * EnumCalendarInfoExW (kernelbase.@)
425 BOOL WINAPI DECLSPEC_HOTPATCH
EnumCalendarInfoExW( CALINFO_ENUMPROCEXW proc
, LCID lcid
,
426 CALID id
, CALTYPE type
)
428 return Internal_EnumCalendarInfo( (CALINFO_ENUMPROCW
)proc
, lcid
, id
, type
, TRUE
, TRUE
, FALSE
, 0 );
431 /******************************************************************************
432 * EnumCalendarInfoExEx (kernelbase.@)
434 BOOL WINAPI DECLSPEC_HOTPATCH
EnumCalendarInfoExEx( CALINFO_ENUMPROCEXEX proc
, LPCWSTR locale
, CALID id
,
435 LPCWSTR reserved
, CALTYPE type
, LPARAM lparam
)
437 LCID lcid
= LocaleNameToLCID( locale
, 0 );
438 return Internal_EnumCalendarInfo( (CALINFO_ENUMPROCW
)proc
, lcid
, id
, type
, TRUE
, TRUE
, TRUE
, lparam
);
442 /**************************************************************************
443 * EnumDateFormatsW (kernelbase.@)
445 BOOL WINAPI DECLSPEC_HOTPATCH
EnumDateFormatsW( DATEFMT_ENUMPROCW proc
, LCID lcid
, DWORD flags
)
447 return Internal_EnumDateFormats( proc
, lcid
, flags
, TRUE
, FALSE
, FALSE
, 0 );
451 /**************************************************************************
452 * EnumDateFormatsExW (kernelbase.@)
454 BOOL WINAPI DECLSPEC_HOTPATCH
EnumDateFormatsExW( DATEFMT_ENUMPROCEXW proc
, LCID lcid
, DWORD flags
)
456 return Internal_EnumDateFormats( (DATEFMT_ENUMPROCW
)proc
, lcid
, flags
, TRUE
, TRUE
, FALSE
, 0 );
460 /**************************************************************************
461 * EnumDateFormatsExEx (kernelbase.@)
463 BOOL WINAPI DECLSPEC_HOTPATCH
EnumDateFormatsExEx( DATEFMT_ENUMPROCEXEX proc
, const WCHAR
*locale
,
464 DWORD flags
, LPARAM lparam
)
466 LCID lcid
= LocaleNameToLCID( locale
, 0 );
467 return Internal_EnumDateFormats( (DATEFMT_ENUMPROCW
)proc
, lcid
, flags
, TRUE
, TRUE
, TRUE
, lparam
);
471 /******************************************************************************
472 * EnumLanguageGroupLocalesW (kernelbase.@)
474 BOOL WINAPI DECLSPEC_HOTPATCH
EnumLanguageGroupLocalesW( LANGGROUPLOCALE_ENUMPROCW proc
, LGRPID id
,
475 DWORD flags
, LONG_PTR param
)
477 return Internal_EnumLanguageGroupLocales( proc
, id
, flags
, param
, TRUE
);
481 /******************************************************************************
482 * EnumUILanguagesW (kernelbase.@)
484 BOOL WINAPI DECLSPEC_HOTPATCH
EnumUILanguagesW( UILANGUAGE_ENUMPROCW proc
, DWORD flags
, LONG_PTR param
)
486 return Internal_EnumUILanguages( proc
, flags
, param
, TRUE
);
490 /***********************************************************************
491 * EnumSystemCodePagesW (kernelbase.@)
493 BOOL WINAPI DECLSPEC_HOTPATCH
EnumSystemCodePagesW( CODEPAGE_ENUMPROCW proc
, DWORD flags
)
495 return Internal_EnumSystemCodePages( proc
, flags
, TRUE
);
499 /******************************************************************************
500 * EnumSystemLanguageGroupsW (kernelbase.@)
502 BOOL WINAPI DECLSPEC_HOTPATCH
EnumSystemLanguageGroupsW( LANGUAGEGROUP_ENUMPROCW proc
,
503 DWORD flags
, LONG_PTR param
)
505 return Internal_EnumSystemLanguageGroups( proc
, flags
, param
, TRUE
);
509 /******************************************************************************
510 * EnumSystemLocalesA (kernelbase.@)
512 BOOL WINAPI DECLSPEC_HOTPATCH
EnumSystemLocalesA( LOCALE_ENUMPROCA proc
, DWORD flags
)
515 DWORD name_len
, type
, index
= 0;
518 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
, locales_key
, 0, KEY_READ
, &key
)) return FALSE
;
522 name_len
= ARRAY_SIZE(name
);
523 if (RegEnumValueA( key
, index
++, name
, &name_len
, NULL
, &type
, NULL
, NULL
)) break;
524 if (type
!= REG_SZ
) continue;
525 if (!strtoul( name
, NULL
, 16 )) continue;
526 if (!proc( name
)) break;
533 /******************************************************************************
534 * EnumSystemLocalesW (kernelbase.@)
536 BOOL WINAPI DECLSPEC_HOTPATCH
EnumSystemLocalesW( LOCALE_ENUMPROCW proc
, DWORD flags
)
539 DWORD name_len
, type
, index
= 0;
542 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
, locales_key
, 0, KEY_READ
, &key
)) return FALSE
;
546 name_len
= ARRAY_SIZE(name
);
547 if (RegEnumValueW( key
, index
++, name
, &name_len
, NULL
, &type
, NULL
, NULL
)) break;
548 if (type
!= REG_SZ
) continue;
549 if (!wcstoul( name
, NULL
, 16 )) continue;
550 if (!proc( name
)) break;
557 /******************************************************************************
558 * EnumSystemLocalesEx (kernelbase.@)
560 BOOL WINAPI DECLSPEC_HOTPATCH
EnumSystemLocalesEx( LOCALE_ENUMPROCEX proc
, DWORD wanted_flags
,
561 LPARAM param
, void *reserved
)
563 WCHAR buffer
[256], name
[10];
564 DWORD name_len
, type
, neutral
, flags
, index
= 0, alt
= 0;
570 SetLastError( ERROR_INVALID_PARAMETER
);
574 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
, locales_key
, 0, KEY_READ
, &key
)) return FALSE
;
575 if (RegOpenKeyExW( key
, altsort_key
, 0, KEY_READ
, &altkey
)) altkey
= 0;
579 name_len
= ARRAY_SIZE(name
);
580 if (RegEnumValueW( alt
? altkey
: key
, index
++, name
, &name_len
, NULL
, &type
, NULL
, NULL
))
586 if (type
!= REG_SZ
) continue;
587 if (!(lcid
= wcstoul( name
, NULL
, 16 ))) continue;
589 GetLocaleInfoW( lcid
, LOCALE_SNAME
| LOCALE_NOUSEROVERRIDE
, buffer
, ARRAY_SIZE( buffer
));
590 if (!GetLocaleInfoW( lcid
, LOCALE_INEUTRAL
| LOCALE_NOUSEROVERRIDE
| LOCALE_RETURN_NUMBER
,
591 (LPWSTR
)&neutral
, sizeof(neutral
) / sizeof(WCHAR
) ))
595 flags
= LOCALE_ALTERNATE_SORTS
;
597 flags
= LOCALE_WINDOWS
| (neutral
? LOCALE_NEUTRALDATA
: LOCALE_SPECIFICDATA
);
599 if (wanted_flags
&& !(flags
& wanted_flags
)) continue;
600 if (!proc( buffer
, flags
, param
)) break;
602 RegCloseKey( altkey
);
608 /**************************************************************************
609 * EnumTimeFormatsW (kernelbase.@)
611 BOOL WINAPI DECLSPEC_HOTPATCH
EnumTimeFormatsW( TIMEFMT_ENUMPROCW proc
, LCID lcid
, DWORD flags
)
613 return Internal_EnumTimeFormats( proc
, lcid
, flags
, TRUE
, FALSE
, 0 );
617 /**************************************************************************
618 * EnumTimeFormatsEx (kernelbase.@)
620 BOOL WINAPI DECLSPEC_HOTPATCH
EnumTimeFormatsEx( TIMEFMT_ENUMPROCEX proc
, const WCHAR
*locale
,
621 DWORD flags
, LPARAM lparam
)
623 LCID lcid
= LocaleNameToLCID( locale
, 0 );
624 return Internal_EnumTimeFormats( (TIMEFMT_ENUMPROCW
)proc
, lcid
, flags
, TRUE
, TRUE
, lparam
);
628 /******************************************************************************
629 * FindStringOrdinal (kernelbase.@)
631 INT WINAPI DECLSPEC_HOTPATCH
FindStringOrdinal( DWORD flag
, const WCHAR
*src
, INT src_size
,
632 const WCHAR
*val
, INT val_size
, BOOL ignore_case
)
634 INT offset
, inc
, count
;
636 TRACE( "%#x %s %d %s %d %d\n", flag
, wine_dbgstr_w(src
), src_size
,
637 wine_dbgstr_w(val
), val_size
, ignore_case
);
641 SetLastError( ERROR_INVALID_PARAMETER
);
645 if (flag
!= FIND_FROMSTART
&& flag
!= FIND_FROMEND
&& flag
!= FIND_STARTSWITH
&& flag
!= FIND_ENDSWITH
)
647 SetLastError( ERROR_INVALID_FLAGS
);
651 if (src_size
== -1) src_size
= lstrlenW( src
);
652 if (val_size
== -1) val_size
= lstrlenW( val
);
654 SetLastError( ERROR_SUCCESS
);
655 src_size
-= val_size
;
656 if (src_size
< 0) return -1;
658 count
= flag
& (FIND_FROMSTART
| FIND_FROMEND
) ? src_size
+ 1 : 1;
659 offset
= flag
& (FIND_FROMSTART
| FIND_STARTSWITH
) ? 0 : src_size
;
660 inc
= flag
& (FIND_FROMSTART
| FIND_STARTSWITH
) ? 1 : -1;
663 if (CompareStringOrdinal( src
+ offset
, val_size
, val
, val_size
, ignore_case
) == CSTR_EQUAL
)
671 /******************************************************************************
672 * IsValidLanguageGroup (kernelbase.@)
674 BOOL WINAPI DECLSPEC_HOTPATCH
IsValidLanguageGroup( LGRPID id
, DWORD flags
)
676 static const WCHAR format
[] = { '%','x',0 };
677 WCHAR name
[10], value
[10];
678 DWORD type
, value_len
= sizeof(value
);
682 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
, language_groups_key
, 0, KEY_READ
, &key
)) return FALSE
;
684 swprintf( name
, ARRAY_SIZE(name
), format
, id
);
685 if (!RegQueryValueExW( key
, name
, NULL
, &type
, (BYTE
*)value
, &value_len
) && type
== REG_SZ
)
686 ret
= (flags
& LGRPID_SUPPORTED
) || wcstoul( value
, NULL
, 10 );
693 /***********************************************************************
694 * LCIDToLocaleName (kernelbase.@)
696 INT WINAPI DECLSPEC_HOTPATCH
LCIDToLocaleName( LCID lcid
, LPWSTR name
, INT count
, DWORD flags
)
699 if (flags
&& !once
++) FIXME( "unsupported flags %x\n", flags
);
701 return GetLocaleInfoW( lcid
, LOCALE_SNAME
| LOCALE_NOUSEROVERRIDE
, name
, count
);
705 /***********************************************************************
706 * GetSystemDefaultLCID (kernelbase.@)
708 LCID WINAPI DECLSPEC_HOTPATCH
GetSystemDefaultLCID(void)
711 NtQueryDefaultLocale( FALSE
, &lcid
);
716 /***********************************************************************
717 * GetSystemDefaultLangID (kernelbase.@)
719 LANGID WINAPI DECLSPEC_HOTPATCH
GetSystemDefaultLangID(void)
721 return LANGIDFROMLCID( GetSystemDefaultLCID() );
725 /***********************************************************************
726 * GetSystemDefaultLocaleName (kernelbase.@)
728 INT WINAPI DECLSPEC_HOTPATCH
GetSystemDefaultLocaleName( LPWSTR name
, INT len
)
730 return LCIDToLocaleName( GetSystemDefaultLCID(), name
, len
, 0 );
734 /***********************************************************************
735 * GetSystemDefaultUILanguage (kernelbase.@)
737 LANGID WINAPI DECLSPEC_HOTPATCH
GetSystemDefaultUILanguage(void)
740 NtQueryInstallUILanguage( &lang
);
745 /***********************************************************************
746 * GetUserDefaultLCID (kernelbase.@)
748 LCID WINAPI DECLSPEC_HOTPATCH
GetUserDefaultLCID(void)
751 NtQueryDefaultLocale( TRUE
, &lcid
);
756 /***********************************************************************
757 * GetUserDefaultLangID (kernelbase.@)
759 LANGID WINAPI DECLSPEC_HOTPATCH
GetUserDefaultLangID(void)
761 return LANGIDFROMLCID( GetUserDefaultLCID() );
765 /***********************************************************************
766 * GetUserDefaultLocaleName (kernelbase.@)
768 INT WINAPI DECLSPEC_HOTPATCH
GetUserDefaultLocaleName( LPWSTR name
, INT len
)
770 return LCIDToLocaleName( GetUserDefaultLCID(), name
, len
, 0 );
774 /***********************************************************************
775 * GetUserDefaultUILanguage (kernelbase.@)
777 LANGID WINAPI DECLSPEC_HOTPATCH
GetUserDefaultUILanguage(void)
780 NtQueryDefaultUILanguage( &lang
);
785 /******************************************************************************
786 * ResolveLocaleName (kernelbase.@)
788 INT WINAPI DECLSPEC_HOTPATCH
ResolveLocaleName( LPCWSTR name
, LPWSTR buffer
, INT len
)
790 FIXME( "stub: %s, %p, %d\n", wine_dbgstr_w(name
), buffer
, len
);
792 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
797 /***********************************************************************
798 * VerLanguageNameA (kernelbase.@)
800 DWORD WINAPI DECLSPEC_HOTPATCH
VerLanguageNameA( DWORD lang
, LPSTR buffer
, DWORD size
)
802 return GetLocaleInfoA( MAKELCID( lang
, SORT_DEFAULT
), LOCALE_SENGLANGUAGE
, buffer
, size
);
806 /***********************************************************************
807 * VerLanguageNameW (kernelbase.@)
809 DWORD WINAPI DECLSPEC_HOTPATCH
VerLanguageNameW( DWORD lang
, LPWSTR buffer
, DWORD size
)
811 return GetLocaleInfoW( MAKELCID( lang
, SORT_DEFAULT
), LOCALE_SENGLANGUAGE
, buffer
, size
);