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