Cheers,
Jon
License: X11
ChangeLog:
Jon Griffiths <jon_p_griffiths@xxxxxxxxx>
+dlls/kernel/locale.c
Allow user overridden locale data to be retrieved as numbers
+dlls/kernel/time.c
Fail GetCalendarInfoA for Unicode-only locales
__________________________________
Do you Yahoo!?
Free Pop-Up Blocker - Get it now
http://companion.yahoo.com/
diff -u --minimal wine/dlls/kernel/locale.c wine-develop/dlls/kernel/locale.c
--- wine/dlls/kernel/locale.c 2003-11-24 14:10:14.000000000 +0000
+++ wine-develop/dlls/kernel/locale.c 2003-12-01 23:57:41.000000000 +0000
@@ -739,7 +739,7 @@
* Retrieve user-modified locale info from the registry.
* Return length, 0 on error, -1 if not found.
*/
-static INT get_registry_locale_info( LPCWSTR value, LPWSTR buffer, INT len )
+static INT get_registry_locale_info( UINT flags, LPCWSTR value, LPWSTR buffer, INT len )
{
DWORD size;
INT ret;
@@ -752,9 +752,9 @@
if (!(hkey = create_registry_key())) return -1;
RtlInitUnicodeString( &nameW, value );
- size = info_size + len * sizeof(WCHAR);
+ size = info_size + (flags & LOCALE_RETURN_NUMBER ? 16 : len) * sizeof(WCHAR);
- if (!(info = HeapAlloc( GetProcessHeap(), 0, size )))
+ if (!(info = HeapAlloc( GetProcessHeap(), 0, size + sizeof(WCHAR))))
{
NtClose( hkey );
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
@@ -767,20 +767,42 @@
if (!status)
{
ret = (size - info_size) / sizeof(WCHAR);
- /* append terminating null if needed */
+ /* append terminating nul if needed */
if (!ret || ((WCHAR *)info->Data)[ret-1])
{
- if (ret < len || !buffer) ret++;
+ if (ret < len || !buffer)
+ {
+ ((WCHAR *)info->Data)[ret] = '\0';
+ ret++;
+ }
else
{
SetLastError( ERROR_INSUFFICIENT_BUFFER );
ret = 0;
}
}
- if (ret && buffer)
+
+ if (ret)
{
- memcpy( buffer, info->Data, (ret-1) * sizeof(WCHAR) );
- buffer[ret-1] = 0;
+ if (flags & LOCALE_RETURN_NUMBER)
+ {
+ UINT number;
+ WCHAR *end;
+ number = strtolW( (WCHAR *)info->Data, &end, 10 );
+ if (*end)
+ {
+ SetLastError( ERROR_INVALID_FLAGS );
+ ret = 0;
+ }
+ else
+ {
+ if (buffer)
+ memcpy( buffer, &number, sizeof(number) );
+ ret = sizeof(UINT)/sizeof(WCHAR);
+ }
+ }
+ else if (buffer)
+ memcpy( buffer, info->Data, (ret) * sizeof(WCHAR) );
}
}
else
@@ -883,6 +905,8 @@
const WCHAR *p;
unsigned int i;
+ TRACE("(0x%08lx,0x%08lx,%p,%d)\n", lcid, lctype, buffer, len);
+
if (len < 0 || (len && !buffer))
{
SetLastError( ERROR_INVALID_PARAMETER );
@@ -901,7 +925,12 @@
{
const WCHAR *value = get_locale_value_name(lctype);
- if (value && ((ret = get_registry_locale_info( value, buffer, len )) != -1)) return ret;
+ if (value)
+ {
+ ret = get_registry_locale_info( lcflags & LOCALE_RETURN_NUMBER, value, buffer, len );
+ if (ret != -1)
+ return ret;
+ }
}
/* now load it from kernel resources */
diff -u --minimal wine/dlls/kernel/time.c wine-develop/dlls/kernel/time.c
--- wine/dlls/kernel/time.c 2003-09-11 16:11:01.000000000 +0000
+++ wine-develop/dlls/kernel/time.c 2003-11-11 16:30:42.000000000 +0000
@@ -48,6 +48,7 @@
#define SETTIME_MAX_ADJUST 120
#define CALINFO_MAX_YEAR 2029
+extern BOOL WINAPI NLS_IsUnicodeOnlyLcid(LCID); /* in lcformat.c */
/***********************************************************************
* SetLocalTime (KERNEL32.@)
@@ -530,20 +531,28 @@
* GetCalendarInfoA (KERNEL32.@)
*
*/
-int WINAPI GetCalendarInfoA(LCID Locale, CALID Calendar, CALTYPE CalType,
+int WINAPI GetCalendarInfoA(LCID lcid, CALID Calendar, CALTYPE CalType,
LPSTR lpCalData, int cchData, LPDWORD lpValue)
{
int ret;
LPWSTR lpCalDataW = NULL;
FIXME("(%08lx,%08lx,%08lx,%p,%d,%p): quarter-stub\n",
- Locale, Calendar, CalType, lpCalData, cchData, lpValue);
- /* FIXME: Should verify if Locale is allowable in ANSI, as per MSDN */
+ lcid, Calendar, CalType, lpCalData, cchData, lpValue);
- if(cchData)
- if(!(lpCalDataW = HeapAlloc(GetProcessHeap(), 0, cchData*sizeof(WCHAR)))) return 0;
+ lcid = ConvertDefaultLocale(lcid);
- ret = GetCalendarInfoW(Locale, Calendar, CalType, lpCalDataW, cchData, lpValue);
+ if (NLS_IsUnicodeOnlyLcid(lcid))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+
+ if (cchData &&
+ !(lpCalDataW = HeapAlloc(GetProcessHeap(), 0, cchData*sizeof(WCHAR))))
+ return 0;
+
+ ret = GetCalendarInfoW(lcid, Calendar, CalType, lpCalDataW, cchData, lpValue);
if(ret && lpCalDataW && lpCalData)
WideCharToMultiByte(CP_ACP, 0, lpCalDataW, cchData, lpCalData, cchData, NULL, NULL);
if(lpCalDataW)