Module: wine Branch: master Commit: 81183c1e207e81b09bc93ace389e8bb7c369ca79 URL: http://source.winehq.org/git/wine.git/?a=commit;h=81183c1e207e81b09bc93ace38...
Author: Alexandre Julliard julliard@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);