Alexandre Julliard : kernel32: Fix the handling of CAL_ITWODIGITYEARMAX in GetCalendarInfo.
Alexandre Julliard
julliard at winehq.org
Wed Jun 8 11:27:01 CDT 2011
Module: wine
Branch: master
Commit: 81183c1e207e81b09bc93ace389e8bb7c369ca79
URL: http://source.winehq.org/git/wine.git/?a=commit;h=81183c1e207e81b09bc93ace389e8bb7c369ca79
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Jun 8 16:18:26 2011 +0200
kernel32: Fix the handling of CAL_ITWODIGITYEARMAX in GetCalendarInfo.
---
dlls/kernel32/tests/time.c | 61 ++++++++++++++++++++++++++++++++++++++++++++
dlls/kernel32/time.c | 27 ++++++++++++++++++-
2 files changed, 87 insertions(+), 1 deletions(-)
diff --git a/dlls/kernel32/tests/time.c b/dlls/kernel32/tests/time.c
index b0d8a46..e8df15b 100644
--- a/dlls/kernel32/tests/time.c
+++ b/dlls/kernel32/tests/time.c
@@ -25,6 +25,8 @@
static BOOL (WINAPI *pTzSpecificLocalTimeToSystemTime)(LPTIME_ZONE_INFORMATION, LPSYSTEMTIME, LPSYSTEMTIME);
static BOOL (WINAPI *pSystemTimeToTzSpecificLocalTime)(LPTIME_ZONE_INFORMATION, LPSYSTEMTIME, LPSYSTEMTIME);
+static int (WINAPI *pGetCalendarInfoA)(LCID,CALID,CALTYPE,LPSTR,int,LPDWORD);
+static int (WINAPI *pGetCalendarInfoW)(LCID,CALID,CALTYPE,LPWSTR,int,LPDWORD);
#define SECSPERMIN 60
#define SECSPERDAY 86400
@@ -637,11 +639,69 @@ static void test_FileTimeToDosDateTime(void)
"expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
}
+static void test_GetCalendarInfo(void)
+{
+ char bufferA[20];
+ WCHAR bufferW[20];
+ DWORD val1, val2;
+ int ret;
+
+ if (!pGetCalendarInfoA || !pGetCalendarInfoW)
+ {
+ trace( "GetCalendarInfo missing\n" );
+ return;
+ }
+
+ ret = pGetCalendarInfoA( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX | CAL_RETURN_NUMBER,
+ NULL, 0, &val1 );
+ ok( ret, "GetCalendarInfoA failed err %u\n", GetLastError() );
+ ok( ret == sizeof(val1), "wrong size %u\n", ret );
+ ok( val1 >= 2000 && val1 < 2100, "wrong value %u\n", val1 );
+
+ ret = pGetCalendarInfoW( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX | CAL_RETURN_NUMBER,
+ NULL, 0, &val2 );
+ ok( ret, "GetCalendarInfoW failed err %u\n", GetLastError() );
+ ok( ret == sizeof(val2)/sizeof(WCHAR), "wrong size %u\n", ret );
+ ok( val1 == val2, "A/W mismatch %u/%u\n", val1, val2 );
+
+ ret = pGetCalendarInfoA( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX, bufferA, sizeof(bufferA), NULL );
+ ok( ret, "GetCalendarInfoA failed err %u\n", GetLastError() );
+ ok( ret == 5, "wrong size %u\n", ret );
+ ok( atoi( bufferA ) == val1, "wrong value %s/%u\n", bufferA, val1 );
+
+ ret = pGetCalendarInfoW( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX, bufferW, sizeof(bufferW), NULL );
+ ok( ret, "GetCalendarInfoW failed err %u\n", GetLastError() );
+ ok( ret == 5, "wrong size %u\n", ret );
+ memset( bufferA, 0x55, sizeof(bufferA) );
+ WideCharToMultiByte( CP_ACP, 0, bufferW, -1, bufferA, sizeof(bufferA), NULL, NULL );
+ ok( atoi( bufferA ) == val1, "wrong value %s/%u\n", bufferA, val1 );
+
+ ret = pGetCalendarInfoA( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX | CAL_RETURN_NUMBER,
+ NULL, 0, NULL );
+ ok( !ret, "GetCalendarInfoA succeeded\n" );
+ ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
+
+ ret = pGetCalendarInfoA( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX, NULL, 0, NULL );
+ ok( ret, "GetCalendarInfoA failed err %u\n", GetLastError() );
+ ok( ret == 5, "wrong size %u\n", ret );
+
+ ret = pGetCalendarInfoW( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX | CAL_RETURN_NUMBER,
+ NULL, 0, NULL );
+ ok( !ret, "GetCalendarInfoW succeeded\n" );
+ ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
+
+ ret = pGetCalendarInfoW( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX, NULL, 0, NULL );
+ ok( ret, "GetCalendarInfoW failed err %u\n", GetLastError() );
+ ok( ret == 5, "wrong size %u\n", ret );
+}
+
START_TEST(time)
{
HMODULE hKernel = GetModuleHandle("kernel32");
pTzSpecificLocalTimeToSystemTime = (void *)GetProcAddress(hKernel, "TzSpecificLocalTimeToSystemTime");
pSystemTimeToTzSpecificLocalTime = (void *)GetProcAddress( hKernel, "SystemTimeToTzSpecificLocalTime");
+ pGetCalendarInfoA = (void *)GetProcAddress(hKernel, "GetCalendarInfoA");
+ pGetCalendarInfoW = (void *)GetProcAddress(hKernel, "GetCalendarInfoW");
test_conversions();
test_invalid_arg();
@@ -650,4 +710,5 @@ START_TEST(time)
test_FileTimeToLocalFileTime();
test_TzSpecificLocalTimeToSystemTime();
test_FileTimeToDosDateTime();
+ test_GetCalendarInfo();
}
diff --git a/dlls/kernel32/time.c b/dlls/kernel32/time.c
index 5dff796..deb0c33 100644
--- a/dlls/kernel32/time.c
+++ b/dlls/kernel32/time.c
@@ -618,6 +618,8 @@ int WINAPI GetCalendarInfoA(LCID lcid, CALID Calendar, CALTYPE CalType,
ret = GetCalendarInfoW(lcid, Calendar, CalType, lpCalDataW, cchData, lpValue);
if(ret && lpCalDataW && lpCalData)
WideCharToMultiByte(CP_ACP, 0, lpCalDataW, cchData, lpCalData, cchData, NULL, NULL);
+ else if (CalType & CAL_RETURN_NUMBER)
+ ret *= sizeof(WCHAR);
HeapFree(GetProcessHeap(), 0, lpCalDataW);
return ret;
@@ -636,6 +638,11 @@ int WINAPI GetCalendarInfoW(LCID Locale, CALID Calendar, CALTYPE CalType,
FIXME("flag CAL_USE_CP_ACP used, not fully implemented\n");
if (CalType & CAL_RETURN_NUMBER) {
+ if (!lpValue)
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return 0;
+ }
if (lpCalData != NULL)
WARN("lpCalData not NULL (%p) when it should!\n", lpCalData);
if (cchData != 0)
@@ -747,7 +754,25 @@ int WINAPI GetCalendarInfoW(LCID Locale, CALID Calendar, CALTYPE CalType,
case CAL_SYEARMONTH:
return GetLocaleInfoW(Locale, LOCALE_SYEARMONTH, lpCalData, cchData);
case CAL_ITWODIGITYEARMAX:
- if (lpValue) *lpValue = CALINFO_MAX_YEAR;
+ if (CalType & CAL_RETURN_NUMBER)
+ {
+ *lpValue = CALINFO_MAX_YEAR;
+ return sizeof(DWORD) / sizeof(WCHAR);
+ }
+ else
+ {
+ static const WCHAR fmtW[] = {'%','u',0};
+ WCHAR buffer[10];
+ int ret = snprintfW( buffer, 10, fmtW, CALINFO_MAX_YEAR ) + 1;
+ if (!lpCalData) return ret;
+ if (ret <= cchData)
+ {
+ strcpyW( lpCalData, buffer );
+ return ret;
+ }
+ SetLastError( ERROR_INSUFFICIENT_BUFFER );
+ return 0;
+ }
break;
default:
FIXME("Unknown caltype %d\n",CalType & 0xffff);
More information about the wine-cvs
mailing list