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
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.
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.
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
33 #define WIN32_NO_STATUS
40 #include "kernel_private.h"
41 #include "wine/heap.h"
42 #include "wine/debug.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(nls
);
46 extern BOOL WINAPI
Internal_EnumCalendarInfo( CALINFO_ENUMPROCW proc
, LCID lcid
, CALID id
,
47 CALTYPE type
, BOOL unicode
, BOOL ex
,
48 BOOL exex
, LPARAM lparam
);
49 extern BOOL WINAPI
Internal_EnumDateFormats( DATEFMT_ENUMPROCW proc
, LCID lcid
, DWORD flags
, BOOL unicode
,
50 BOOL ex
, BOOL exex
, LPARAM lparam
);
51 extern BOOL WINAPI
Internal_EnumLanguageGroupLocales( LANGGROUPLOCALE_ENUMPROCW proc
, LGRPID id
,
52 DWORD flags
, LONG_PTR param
, BOOL unicode
);
53 extern BOOL WINAPI
Internal_EnumSystemCodePages( CODEPAGE_ENUMPROCW proc
, DWORD flags
, BOOL unicode
);
54 extern BOOL WINAPI
Internal_EnumSystemLanguageGroups( LANGUAGEGROUP_ENUMPROCW proc
, DWORD flags
,
55 LONG_PTR param
, BOOL unicode
);
56 extern BOOL WINAPI
Internal_EnumTimeFormats( TIMEFMT_ENUMPROCW proc
, LCID lcid
, DWORD flags
,
57 BOOL unicode
, BOOL ex
, LPARAM lparam
);
58 extern BOOL WINAPI
Internal_EnumUILanguages( UILANGUAGE_ENUMPROCW proc
, DWORD flags
,
59 LONG_PTR param
, BOOL unicode
);
61 /***********************************************************************
64 * Retrieve the ANSI codepage for a given locale.
66 static inline UINT
get_lcid_codepage( LCID lcid
)
69 if (!GetLocaleInfoW( lcid
, LOCALE_IDEFAULTANSICODEPAGE
|LOCALE_RETURN_NUMBER
, (WCHAR
*)&ret
,
70 sizeof(ret
)/sizeof(WCHAR
) )) ret
= 0;
75 /******************************************************************************
76 * SetLocaleInfoA [KERNEL32.@]
78 * Set information about an aspect of a locale.
81 * lcid [I] LCID of the locale
82 * lctype [I] LCTYPE_ flags from "winnls.h"
83 * data [I] Information to set
86 * Success: TRUE. The information given will be returned by GetLocaleInfoA()
87 * whenever it is called without LOCALE_NOUSEROVERRIDE.
88 * Failure: FALSE. Use GetLastError() to determine the cause.
91 * - Values are only be set for the current user locale; the system locale
92 * settings cannot be changed.
93 * - Any settings changed by this call are lost when the locale is changed by
94 * the control panel (in Wine, this happens every time you change LANG).
95 * - The native implementation of this function does not check that lcid matches
96 * the current user locale, and simply sets the new values. Wine warns you in
97 * this case, but behaves the same.
99 BOOL WINAPI
SetLocaleInfoA(LCID lcid
, LCTYPE lctype
, LPCSTR data
)
101 UINT codepage
= CP_ACP
;
106 if (!(lctype
& LOCALE_USE_CP_ACP
)) codepage
= get_lcid_codepage( lcid
);
110 SetLastError( ERROR_INVALID_PARAMETER
);
113 len
= MultiByteToWideChar( codepage
, 0, data
, -1, NULL
, 0 );
114 if (!(strW
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) )))
116 SetLastError( ERROR_NOT_ENOUGH_MEMORY
);
119 MultiByteToWideChar( codepage
, 0, data
, -1, strW
, len
);
120 ret
= SetLocaleInfoW( lcid
, lctype
, strW
);
121 HeapFree( GetProcessHeap(), 0, strW
);
126 /******************************************************************************
127 * SetCPGlobal (KERNEL32.@)
129 * Set the current Ansi code page Id for the system.
132 * acp [I] code page ID to be the new ACP.
137 UINT WINAPI
SetCPGlobal( UINT acp
)
139 FIXME( "not supported\n" );
144 /***********************************************************************
145 * GetCPInfoExA (KERNEL32.@)
147 * Get extended information about a code page.
150 * codepage [I] Code page number
151 * dwFlags [I] Reserved, must to 0.
152 * cpinfo [O] Destination for code page information
155 * Success: TRUE. cpinfo is updated with the information about codepage.
156 * Failure: FALSE, if codepage is invalid or cpinfo is NULL.
158 BOOL WINAPI
GetCPInfoExA( UINT codepage
, DWORD dwFlags
, LPCPINFOEXA cpinfo
)
162 if (!GetCPInfoExW( codepage
, dwFlags
, &cpinfoW
))
165 /* the layout is the same except for CodePageName */
166 memcpy(cpinfo
, &cpinfoW
, sizeof(CPINFOEXA
));
167 WideCharToMultiByte(CP_ACP
, 0, cpinfoW
.CodePageName
, -1, cpinfo
->CodePageName
, sizeof(cpinfo
->CodePageName
), NULL
, NULL
);
172 /*********************************************************************
173 * GetDaylightFlag (KERNEL32.@)
175 BOOL WINAPI
GetDaylightFlag(void)
177 TIME_ZONE_INFORMATION tzinfo
;
178 return GetTimeZoneInformation( &tzinfo
) == TIME_ZONE_ID_DAYLIGHT
;
182 /***********************************************************************
183 * EnumSystemCodePagesA (KERNEL32.@)
185 BOOL WINAPI
EnumSystemCodePagesA( CODEPAGE_ENUMPROCA proc
, DWORD flags
)
187 return Internal_EnumSystemCodePages( (CODEPAGE_ENUMPROCW
)proc
, flags
, FALSE
);
191 /******************************************************************************
192 * GetStringTypeExA (KERNEL32.@)
194 * Get characteristics of the characters making up a string.
197 * locale [I] Locale Id for the string
198 * type [I] CT_CTYPE1 = classification, CT_CTYPE2 = directionality, CT_CTYPE3 = typographic info
199 * src [I] String to analyse
200 * count [I] Length of src in chars, or -1 if src is NUL terminated
201 * chartype [O] Destination for the calculated characteristics
204 * Success: TRUE. chartype is filled with the requested characteristics of each char
206 * Failure: FALSE. Use GetLastError() to determine the cause.
208 BOOL WINAPI
GetStringTypeExA( LCID locale
, DWORD type
, LPCSTR src
, INT count
, LPWORD chartype
)
210 return GetStringTypeA(locale
, type
, src
, count
, chartype
);
213 /*************************************************************************
214 * FoldStringA (KERNEL32.@)
216 * Map characters in a string.
219 * dwFlags [I] Flags controlling chars to map (MAP_ constants from "winnls.h")
220 * src [I] String to map
221 * srclen [I] Length of src, or -1 if src is NUL terminated
222 * dst [O] Destination for mapped string
223 * dstlen [I] Length of dst, or 0 to find the required length for the mapped string
226 * Success: The length of the string written to dst, including the terminating NUL. If
227 * dstlen is 0, the value returned is the same, but nothing is written to dst,
228 * and dst may be NULL.
229 * Failure: 0. Use GetLastError() to determine the cause.
231 INT WINAPI
FoldStringA(DWORD dwFlags
, LPCSTR src
, INT srclen
,
232 LPSTR dst
, INT dstlen
)
234 INT ret
= 0, srclenW
= 0;
235 WCHAR
*srcW
= NULL
, *dstW
= NULL
;
237 if (!src
|| !srclen
|| dstlen
< 0 || (dstlen
&& !dst
) || src
== dst
)
239 SetLastError(ERROR_INVALID_PARAMETER
);
243 srclenW
= MultiByteToWideChar(CP_ACP
, 0, src
, srclen
, NULL
, 0);
244 srcW
= HeapAlloc(GetProcessHeap(), 0, srclenW
* sizeof(WCHAR
));
248 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
249 goto FoldStringA_exit
;
252 MultiByteToWideChar(CP_ACP
, 0, src
, srclen
, srcW
, srclenW
);
254 ret
= FoldStringW(dwFlags
, srcW
, srclenW
, NULL
, 0);
257 dstW
= HeapAlloc(GetProcessHeap(), 0, ret
* sizeof(WCHAR
));
261 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
262 goto FoldStringA_exit
;
265 ret
= FoldStringW(dwFlags
, srcW
, srclenW
, dstW
, ret
);
266 if (!WideCharToMultiByte(CP_ACP
, 0, dstW
, ret
, dst
, dstlen
, NULL
, NULL
))
269 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
273 HeapFree(GetProcessHeap(), 0, dstW
);
276 HeapFree(GetProcessHeap(), 0, srcW
);
280 /******************************************************************************
281 * EnumSystemLanguageGroupsA (KERNEL32.@)
283 BOOL WINAPI
EnumSystemLanguageGroupsA( LANGUAGEGROUP_ENUMPROCA proc
, DWORD flags
, LONG_PTR param
)
285 return Internal_EnumSystemLanguageGroups( (LANGUAGEGROUP_ENUMPROCW
)proc
, flags
, param
, FALSE
);
288 /******************************************************************************
289 * EnumLanguageGroupLocalesA (KERNEL32.@)
291 BOOL WINAPI
EnumLanguageGroupLocalesA( LANGGROUPLOCALE_ENUMPROCA proc
, LGRPID id
,
292 DWORD flags
, LONG_PTR param
)
294 return Internal_EnumLanguageGroupLocales( (LANGGROUPLOCALE_ENUMPROCW
)proc
, id
, flags
, param
, FALSE
);
297 /******************************************************************************
298 * EnumCalendarInfoA [KERNEL32.@]
300 BOOL WINAPI
EnumCalendarInfoA( CALINFO_ENUMPROCA proc
, LCID lcid
, CALID id
, CALTYPE type
)
302 return Internal_EnumCalendarInfo( (CALINFO_ENUMPROCW
)proc
, lcid
, id
, type
, FALSE
, FALSE
, FALSE
, 0 );
305 /******************************************************************************
306 * EnumCalendarInfoExA [KERNEL32.@]
308 BOOL WINAPI
EnumCalendarInfoExA( CALINFO_ENUMPROCEXA proc
, LCID lcid
, CALID id
, CALTYPE type
)
310 return Internal_EnumCalendarInfo( (CALINFO_ENUMPROCW
)proc
, lcid
, id
, type
, FALSE
, TRUE
, FALSE
, 0 );
313 /**************************************************************************
314 * EnumDateFormatsExA (KERNEL32.@)
316 * FIXME: MSDN mentions only LOCALE_USE_CP_ACP, should we handle
317 * LOCALE_NOUSEROVERRIDE here as well?
319 BOOL WINAPI
EnumDateFormatsExA(DATEFMT_ENUMPROCEXA proc
, LCID lcid
, DWORD flags
)
321 return Internal_EnumDateFormats( (DATEFMT_ENUMPROCW
)proc
, lcid
, flags
, FALSE
, TRUE
, FALSE
, 0 );
324 /**************************************************************************
325 * EnumDateFormatsA (KERNEL32.@)
327 * FIXME: MSDN mentions only LOCALE_USE_CP_ACP, should we handle
328 * LOCALE_NOUSEROVERRIDE here as well?
330 BOOL WINAPI
EnumDateFormatsA(DATEFMT_ENUMPROCA proc
, LCID lcid
, DWORD flags
)
332 return Internal_EnumDateFormats( (DATEFMT_ENUMPROCW
)proc
, lcid
, flags
, FALSE
, FALSE
, FALSE
, 0 );
335 /**************************************************************************
336 * EnumTimeFormatsA (KERNEL32.@)
338 * FIXME: MSDN mentions only LOCALE_USE_CP_ACP, should we handle
339 * LOCALE_NOUSEROVERRIDE here as well?
341 BOOL WINAPI
EnumTimeFormatsA( TIMEFMT_ENUMPROCA proc
, LCID lcid
, DWORD flags
)
343 /* EnumTimeFormatsA doesn't support flags, EnumTimeFormatsW does. */
344 if (flags
& ~LOCALE_USE_CP_ACP
)
346 SetLastError(ERROR_INVALID_FLAGS
);
349 return Internal_EnumTimeFormats( (TIMEFMT_ENUMPROCW
)proc
, lcid
, flags
, FALSE
, FALSE
, 0 );
352 /******************************************************************************
353 * InvalidateNLSCache (KERNEL32.@)
355 * Invalidate the cache of NLS values.
364 BOOL WINAPI
InvalidateNLSCache(void)
370 /******************************************************************************
371 * EnumUILanguagesA (KERNEL32.@)
373 BOOL WINAPI
EnumUILanguagesA( UILANGUAGE_ENUMPROCA proc
, DWORD flags
, LONG_PTR param
)
375 return Internal_EnumUILanguages( (UILANGUAGE_ENUMPROCW
)proc
, flags
, param
, FALSE
);
379 /******************************************************************************
380 * GetGeoInfoA (KERNEL32.@)
382 INT WINAPI
GetGeoInfoA(GEOID geoid
, GEOTYPE geotype
, LPSTR data
, int data_len
, LANGID lang
)
387 TRACE("%d %d %p %d %d\n", geoid
, geotype
, data
, data_len
, lang
);
389 len
= GetGeoInfoW(geoid
, geotype
, NULL
, 0, lang
);
393 buffW
= HeapAlloc(GetProcessHeap(), 0, len
*sizeof(WCHAR
));
397 GetGeoInfoW(geoid
, geotype
, buffW
, len
, lang
);
398 len
= WideCharToMultiByte(CP_ACP
, 0, buffW
, -1, NULL
, 0, NULL
, NULL
);
399 if (!data
|| !data_len
) {
400 HeapFree(GetProcessHeap(), 0, buffW
);
404 len
= WideCharToMultiByte(CP_ACP
, 0, buffW
, -1, data
, data_len
, NULL
, NULL
);
405 HeapFree(GetProcessHeap(), 0, buffW
);
408 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
409 return data_len
< len
? 0 : len
;