GetTimeZoneInformation return value fix

Rein Klazes rklazes at xs4all.nl
Sun Oct 24 10:28:07 CDT 2004


Hi,

Changelog:
	dlls/kernel	: time.c
	include		: winbase.h

	- reordered some code from the existing helper _GetTimeZoneBias
	to make it more general useful (and changed the helper names to 
	TIME_xyz).
	- Make GetTimeZoneInformation return the correct zone id
	constants.
	- changed some "const LPX_Y_Z" declarations to "const X_Y_Z *"

Rein.
-- 
Rein Klazes
rklazes at xs4all.nl
-------------- next part --------------
--- wine/dlls/kernel/time.c	2004-09-11 08:26:58.000000000 +0200
+++ mywine/dlls/kernel/time.c	2004-10-24 14:40:48.000000000 +0200
@@ -60,143 +60,7 @@
     ll = (((LONGLONG)((pft)->dwHighDateTime))<<32) + (pft)-> dwLowDateTime ;
 
 /***********************************************************************
- *              SetLocalTime            (KERNEL32.@)
- *
- *  Set the local time using current time zone and daylight
- *  savings settings.
- *
- * RETURNS
- *  Success: TRUE. The time was set
- *  Failure: FALSE, if the time was invalid or caller does not have
- *           permission to change the time.
- */
-BOOL WINAPI SetLocalTime(
-    const SYSTEMTIME *systime) /* [in] The desired local time. */
-{
-    FILETIME ft;
-    LARGE_INTEGER st, st2;
-    NTSTATUS status;
-
-    SystemTimeToFileTime( systime, &ft );
-    st.u.LowPart = ft.dwLowDateTime;
-    st.u.HighPart = ft.dwHighDateTime;
-    RtlLocalTimeToSystemTime( &st, &st2 );
-
-    if ((status = NtSetSystemTime(&st2, NULL)))
-        SetLastError( RtlNtStatusToDosError(status) );
-    return !status;
-}
-
-
-/***********************************************************************
- *           GetSystemTimeAdjustment     (KERNEL32.@)
- *
- *  Get the period between clock interrupts and the amount the clock
- *  is adjusted each interrupt so as to keep it in sync with an external source.
- *
- * RETURNS
- *  TRUE.
- *
- * BUGS
- *  Only the special case of disabled time adjustments is supported.
- */
-BOOL WINAPI GetSystemTimeAdjustment(
-    PDWORD lpTimeAdjustment,         /* [out] The clock adjustment per interupt in 100's of nanoseconds. */
-    PDWORD lpTimeIncrement,          /* [out] The time between clock interupts in 100's of nanoseconds. */
-    PBOOL  lpTimeAdjustmentDisabled) /* [out] The clock synchonisation has been disabled. */
-{
-    *lpTimeAdjustment = 0;
-    *lpTimeIncrement = 0;
-    *lpTimeAdjustmentDisabled = TRUE;
-    return TRUE;
-}
-
-
-/***********************************************************************
- *              SetSystemTime            (KERNEL32.@)
- *
- *  Set the system time in utc.
- *
- * RETURNS
- *  Success: TRUE. The time was set
- *  Failure: FALSE, if the time was invalid or caller does not have
- *           permission to change the time.
- */
-BOOL WINAPI SetSystemTime(
-    const SYSTEMTIME *systime) /* [in] The desired system time. */
-{
-    FILETIME ft;
-    LARGE_INTEGER t;
-    NTSTATUS status;
-
-    SystemTimeToFileTime( systime, &ft );
-    t.u.LowPart = ft.dwLowDateTime;
-    t.u.HighPart = ft.dwHighDateTime;
-    if ((status = NtSetSystemTime(&t, NULL)))
-        SetLastError( RtlNtStatusToDosError(status) );
-    return !status;
-}
-
-/***********************************************************************
- *              SetSystemTimeAdjustment  (KERNEL32.@)
- *
- *  Enables or disables the timing adjustments to the system's clock.
- *
- * RETURNS
- *  Success: TRUE.
- *  Failure: FALSE.
- */
-BOOL WINAPI SetSystemTimeAdjustment(
-    DWORD dwTimeAdjustment,
-    BOOL bTimeAdjustmentDisabled)
-{
-    /* Fake function for now... */
-    FIXME("(%08lx,%d): stub !\n", dwTimeAdjustment, bTimeAdjustmentDisabled);
-    return TRUE;
-}
-
-
-/***********************************************************************
- *              GetTimeZoneInformation  (KERNEL32.@)
- *
- *  Get information about the current local time zone.
- *
- * RETURNS
- *  Success: TIME_ZONE_ID_STANDARD. tzinfo contains the time zone info.
- *  Failure: TIME_ZONE_ID_INVALID.
- *  FIXME: return TIME_ZONE_ID_DAYLIGHT when daylight saving is on.
- */
-DWORD WINAPI GetTimeZoneInformation(
-    LPTIME_ZONE_INFORMATION tzinfo) /* [out] Destination for time zone information */
-{
-    NTSTATUS status;
-    if ((status = RtlQueryTimeZoneInformation(tzinfo)))
-        SetLastError( RtlNtStatusToDosError(status) );
-    return TIME_ZONE_ID_STANDARD;
-}
-
-
-/***********************************************************************
- *              SetTimeZoneInformation  (KERNEL32.@)
- *
- *  Change the settings of the current local time zone.
- *
- * RETURNS
- *  Success: TRUE. The time zone was updated with the settings from tzinfo
- *  Failure: FALSE.
- */
-BOOL WINAPI SetTimeZoneInformation(
-    const LPTIME_ZONE_INFORMATION tzinfo) /* [in] The new time zone. */
-{
-    NTSTATUS status;
-    if ((status = RtlSetTimeZoneInformation(tzinfo)))
-        SetLastError( RtlNtStatusToDosError(status) );
-    return !status;
-}
-
-
-/***********************************************************************
- *  _DayLightCompareDate
+ *  TIME_DayLightCompareDate
  *
  *  Compares two dates without looking at the year
  *
@@ -207,10 +71,9 @@
  *   1 if date > compareDate
  *  -2 if an error occures
  */
-
-static int _DayLightCompareDate(
-    const LPSYSTEMTIME date,        /* [in] The local time to compare. */
-    const LPSYSTEMTIME compareDate) /* [in] The daylight saving begin
+static int TIME_DayLightCompareDate(
+    const SYSTEMTIME *date,        /* [in] The local time to compare. */
+    const SYSTEMTIME *compareDate) /* [in] The daylight saving begin
                                        or end date */
 {
     int limit_day, dayinsecs;
@@ -295,96 +158,273 @@
            0;   /* date is equal to the date limit. */
 }
 
-
 /***********************************************************************
- *  _GetTimezoneBias
- *
- *  Calculates the local time bias for a given time zone
+ *  TIME_CompTimeZoneID
  *
- * RETURNS
+ *  Computes the local time bias for a given time and time zone
  *
- *  Returns TRUE when the time zone bias was calculated.
+ *  Returns:
+ *      TIME_ZONE_ID_INVALID    An error occurred
+ *      TIME_ZONE_ID_UNKNOWN    There are no transition time known
+ *      TIME_ZONE_ID_STANDARD   Current time is standard time
+ *      TIME_ZONE_ID_DAYLIGHT   Current time is dayligh saving time
  */
-
-static BOOL _GetTimezoneBias(
-    const LPTIME_ZONE_INFORMATION
-                   lpTimeZoneInformation, /* [in] The time zone data. */
-    LPSYSTEMTIME   lpSysOrLocalTime,   /* [in] The system or local time. */
-    BOOL           islocal,            /* [in] it is local time */       
-    LONG*          pBias               /* [out] The calulated bias in minutes */
+static BOOL TIME_CompTimeZoneID (
+    const TIME_ZONE_INFORMATION *pTZinfo, /* [in] The time zone data. */
+    FILETIME      *lpFileTime,            /* [in] The system or local time. */
+    BOOL           islocal                /* [in] it is local time */       
     )
 {
     int ret;
     BOOL beforeStandardDate, afterDaylightDate;
-    BOOL daylightsaving = FALSE;
-    LONG bias = lpTimeZoneInformation->Bias;
-    FILETIME ft;
+    DWORD retval = TIME_ZONE_ID_INVALID;
     LONGLONG llTime = 0; /* initialized to prevent gcc complaining */
-    SYSTEMTIME stTemp;
-    LPSYSTEMTIME lpTime = lpSysOrLocalTime;
+    SYSTEMTIME SysTime;
+    FILETIME ftTemp;
 
-    if (lpTimeZoneInformation->DaylightDate.wMonth != 0)
+    if (pTZinfo->DaylightDate.wMonth != 0)
     {
-        if (lpTimeZoneInformation->StandardDate.wMonth == 0 ||
-            lpTimeZoneInformation->StandardDate.wDay<1 ||
-            lpTimeZoneInformation->StandardDate.wDay>5 ||
-            lpTimeZoneInformation->DaylightDate.wDay<1 ||
-            lpTimeZoneInformation->DaylightDate.wDay>5)
+        if (pTZinfo->StandardDate.wMonth == 0 ||
+            pTZinfo->StandardDate.wDay<1 ||
+            pTZinfo->StandardDate.wDay>5 ||
+            pTZinfo->DaylightDate.wDay<1 ||
+            pTZinfo->DaylightDate.wDay>5)
         {
             SetLastError(ERROR_INVALID_PARAMETER);
-            return FALSE;
+            return TIME_ZONE_ID_INVALID;
         }
 
         if (!islocal) {
-            if (!SystemTimeToFileTime(lpSysOrLocalTime, &ft)) return -2;
-            FILETIME2LL( &ft, llTime );
-            llTime -= ( lpTimeZoneInformation->Bias +
-                    lpTimeZoneInformation->DaylightBias ) * (LONGLONG)600000000;
-            LL2FILETIME( llTime, &ft)
-            FileTimeToSystemTime(&ft, &stTemp);
-            lpTime =  &stTemp;
+            FILETIME2LL( lpFileTime, llTime );
+            llTime -= ( pTZinfo->Bias + pTZinfo->DaylightBias )
+                * (LONGLONG)600000000;
+            LL2FILETIME( llTime, &ftTemp)
+            lpFileTime = &ftTemp;
         }
+
+        FileTimeToSystemTime(lpFileTime, &SysTime);
         
          /* check for daylight saving */
-        ret = _DayLightCompareDate(lpTime, &lpTimeZoneInformation->StandardDate);
+        ret = TIME_DayLightCompareDate( &SysTime, &pTZinfo->StandardDate);
         if (ret == -2)
-          return FALSE;
+          return TIME_ZONE_ID_INVALID;
 
         beforeStandardDate = ret < 0;
 
         if (!islocal) {
-            llTime -= ( lpTimeZoneInformation->StandardBias -
-                    lpTimeZoneInformation->DaylightBias ) * (LONGLONG)600000000;
-            LL2FILETIME( llTime, &ft)
-            FileTimeToSystemTime(&ft, &stTemp);
-            lpTime =  &stTemp;
+            llTime -= ( pTZinfo->StandardBias - pTZinfo->DaylightBias )
+                * (LONGLONG)600000000;
+            LL2FILETIME( llTime, &ftTemp)
+            FileTimeToSystemTime(lpFileTime, &SysTime);
         }
 
-        ret = _DayLightCompareDate(lpTime, &lpTimeZoneInformation->DaylightDate);
+        ret = TIME_DayLightCompareDate( &SysTime, &pTZinfo->DaylightDate);
         if (ret == -2)
-          return FALSE;
+          return TIME_ZONE_ID_INVALID;
 
         afterDaylightDate = ret >= 0;
 
-        if( lpTimeZoneInformation->DaylightDate.wMonth <       /* Northern */
-                lpTimeZoneInformation->StandardDate.wMonth ) { /* hemisphere */
+        retval = TIME_ZONE_ID_STANDARD;
+        if( pTZinfo->DaylightDate.wMonth <  pTZinfo->StandardDate.wMonth ) {
+            /* Northern hemisphere */
             if( beforeStandardDate && afterDaylightDate )
-                daylightsaving = TRUE;
+                retval = TIME_ZONE_ID_DAYLIGHT;
         } else    /* Down south */
             if( beforeStandardDate || afterDaylightDate )
-            daylightsaving = TRUE;
-    }
+            retval = TIME_ZONE_ID_DAYLIGHT;
+    } else 
+        /* No transition date */
+        retval = TIME_ZONE_ID_UNKNOWN;
+        
+    return retval;
+}
 
-    if (daylightsaving)
-        bias += lpTimeZoneInformation->DaylightBias;
-    else if (lpTimeZoneInformation->StandardDate.wMonth != 0)
-        bias += lpTimeZoneInformation->StandardBias;
+/***********************************************************************
+ *  TIME_TimeZoneID
+ *
+ *  Calculates whether daylight saving is on now.
+ *
+ *  Returns:
+ *      TIME_ZONE_ID_INVALID    An error occurred
+ *      TIME_ZONE_ID_UNKNOWN    There are no transition time known
+ *      TIME_ZONE_ID_STANDARD   Current time is standard time
+ *      TIME_ZONE_ID_DAYLIGHT   Current time is dayligh saving time
+ */
+static DWORD TIME_ZoneID(
+        const TIME_ZONE_INFORMATION  *pTzi   /* Timezone info */
+        )
+{
+    FILETIME ftTime;
+    GetSystemTimeAsFileTime( &ftTime);
+    return TIME_CompTimeZoneID( pTzi, &ftTime, FALSE);
+}
+
+/***********************************************************************
+ *  TIME_GetTimezoneBias
+ *
+ *  Calculates the local time bias for a given time zone
+ *
+ * RETURNS
+ *
+ *  Returns TRUE when the time zone bias was calculated.
+ */
+static BOOL TIME_GetTimezoneBias(
+    const TIME_ZONE_INFORMATION
+                  *pTZinfo, /* [in] The time zone data. */
+    FILETIME      *lpFileTime,         /* [in] The system or local time. */
+    BOOL           islocal,            /* [in] it is local time */       
+    LONG          *pBias               /* [out] The calulated bias in minutes */
+    )
+{
+    LONG bias = pTZinfo->Bias;
+    DWORD tzid = TIME_CompTimeZoneID( pTZinfo, lpFileTime, islocal);
 
+    if( tzid == TIME_ZONE_ID_INVALID)
+        return FALSE;
+    if (tzid == TIME_ZONE_ID_DAYLIGHT)
+        bias += pTZinfo->DaylightBias;
+    else if (tzid == TIME_ZONE_ID_STANDARD)
+        bias += pTZinfo->StandardBias;
     *pBias = bias;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *              SetLocalTime            (KERNEL32.@)
+ *
+ *  Set the local time using current time zone and daylight
+ *  savings settings.
+ *
+ * RETURNS
+ *  Success: TRUE. The time was set
+ *  Failure: FALSE, if the time was invalid or caller does not have
+ *           permission to change the time.
+ */
+BOOL WINAPI SetLocalTime(
+    const SYSTEMTIME *systime) /* [in] The desired local time. */
+{
+    FILETIME ft;
+    LARGE_INTEGER st, st2;
+    NTSTATUS status;
+
+    SystemTimeToFileTime( systime, &ft );
+    st.u.LowPart = ft.dwLowDateTime;
+    st.u.HighPart = ft.dwHighDateTime;
+    RtlLocalTimeToSystemTime( &st, &st2 );
+
+    if ((status = NtSetSystemTime(&st2, NULL)))
+        SetLastError( RtlNtStatusToDosError(status) );
+    return !status;
+}
+
+
+/***********************************************************************
+ *           GetSystemTimeAdjustment     (KERNEL32.@)
+ *
+ *  Get the period between clock interrupts and the amount the clock
+ *  is adjusted each interrupt so as to keep it in sync with an external source.
+ *
+ * RETURNS
+ *  TRUE.
+ *
+ * BUGS
+ *  Only the special case of disabled time adjustments is supported.
+ */
+BOOL WINAPI GetSystemTimeAdjustment(
+    PDWORD lpTimeAdjustment,         /* [out] The clock adjustment per interupt in 100's of nanoseconds. */
+    PDWORD lpTimeIncrement,          /* [out] The time between clock interupts in 100's of nanoseconds. */
+    PBOOL  lpTimeAdjustmentDisabled) /* [out] The clock synchonisation has been disabled. */
+{
+    *lpTimeAdjustment = 0;
+    *lpTimeIncrement = 0;
+    *lpTimeAdjustmentDisabled = TRUE;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *              SetSystemTime            (KERNEL32.@)
+ *
+ *  Set the system time in utc.
+ *
+ * RETURNS
+ *  Success: TRUE. The time was set
+ *  Failure: FALSE, if the time was invalid or caller does not have
+ *           permission to change the time.
+ */
+BOOL WINAPI SetSystemTime(
+    const SYSTEMTIME *systime) /* [in] The desired system time. */
+{
+    FILETIME ft;
+    LARGE_INTEGER t;
+    NTSTATUS status;
 
+    SystemTimeToFileTime( systime, &ft );
+    t.u.LowPart = ft.dwLowDateTime;
+    t.u.HighPart = ft.dwHighDateTime;
+    if ((status = NtSetSystemTime(&t, NULL)))
+        SetLastError( RtlNtStatusToDosError(status) );
+    return !status;
+}
+
+/***********************************************************************
+ *              SetSystemTimeAdjustment  (KERNEL32.@)
+ *
+ *  Enables or disables the timing adjustments to the system's clock.
+ *
+ * RETURNS
+ *  Success: TRUE.
+ *  Failure: FALSE.
+ */
+BOOL WINAPI SetSystemTimeAdjustment(
+    DWORD dwTimeAdjustment,
+    BOOL bTimeAdjustmentDisabled)
+{
+    /* Fake function for now... */
+    FIXME("(%08lx,%d): stub !\n", dwTimeAdjustment, bTimeAdjustmentDisabled);
     return TRUE;
 }
 
+/***********************************************************************
+ *              GetTimeZoneInformation  (KERNEL32.@)
+ *
+ *  Get information about the current local time zone.
+ *
+ * RETURNS
+ *      TIME_ZONE_ID_INVALID    An error occurred
+ *      TIME_ZONE_ID_UNKNOWN    There are no transition time known
+ *      TIME_ZONE_ID_STANDARD   Current time is standard time
+ *      TIME_ZONE_ID_DAYLIGHT   Current time is dayligh saving time
+ */
+DWORD WINAPI GetTimeZoneInformation(
+    LPTIME_ZONE_INFORMATION tzinfo) /* [out] Destination for time zone information */
+{
+    NTSTATUS status;
+    if ((status = RtlQueryTimeZoneInformation(tzinfo))) {
+        SetLastError( RtlNtStatusToDosError(status) );
+        return TIME_ZONE_ID_INVALID;
+    }
+    return TIME_ZoneID( tzinfo );
+}
+
+/***********************************************************************
+ *              SetTimeZoneInformation  (KERNEL32.@)
+ *
+ *  Change the settings of the current local time zone.
+ *
+ * RETURNS
+ *  Success: TRUE. The time zone was updated with the settings from tzinfo
+ *  Failure: FALSE.
+ */
+BOOL WINAPI SetTimeZoneInformation(
+    const TIME_ZONE_INFORMATION *tzinfo) /* [in] The new time zone. */
+{
+    NTSTATUS status;
+    if ((status = RtlSetTimeZoneInformation(tzinfo)))
+        SetLastError( RtlNtStatusToDosError(status) );
+    return !status;
+}
 
 /***********************************************************************
  *              SystemTimeToTzSpecificLocalTime  (KERNEL32.@)
@@ -420,7 +460,7 @@
     if (!SystemTimeToFileTime(lpUniversalTime, &ft))
         return FALSE;
     FILETIME2LL( &ft, llTime)
-    if (!_GetTimezoneBias(&tzinfo, lpUniversalTime, FALSE, &lBias))
+    if (!TIME_GetTimezoneBias(&tzinfo, &ft, FALSE, &lBias))
         return FALSE;
     /* convert minutes to 100-nanoseconds-ticks */
     llTime -= (LONGLONG)lBias * 600000000;
@@ -462,7 +502,7 @@
     if (!SystemTimeToFileTime(lpLocalTime, &ft))
         return FALSE;
     FILETIME2LL( &ft, t)
-    if (!_GetTimezoneBias(&tzinfo, lpLocalTime, TRUE, &lBias))
+    if (!TIME_GetTimezoneBias(&tzinfo, &ft, TRUE, &lBias))
         return FALSE;
     /* convert minutes to 100-nanoseconds-ticks */
     t += (LONGLONG)lBias * 600000000;
@@ -894,12 +934,10 @@
  */
 BOOL WINAPI GetDaylightFlag(void)
 {
-    time_t t = time(NULL);
-    struct tm *ptm = localtime( &t);
-    return ptm->tm_isdst > 0;
+    TIME_ZONE_INFORMATION tzinfo;
+    return GetTimeZoneInformation( &tzinfo) == TIME_ZONE_ID_DAYLIGHT;
 }
 
-
 /***********************************************************************
  *           DosDateTimeToFileTime   (KERNEL32.@)
  */
--- wine/include/winbase.h	2004-09-21 10:54:25.000000000 +0200
+++ mywine/include/winbase.h	2004-10-23 17:33:02.000000000 +0200
@@ -1638,7 +1638,7 @@
 BOOL        WINAPI SetThreadPriority(HANDLE,INT);
 BOOL        WINAPI SetThreadPriorityBoost(HANDLE,BOOL);
 BOOL        WINAPI SetThreadToken(PHANDLE,HANDLE);
-BOOL        WINAPI SetTimeZoneInformation(const LPTIME_ZONE_INFORMATION);
+BOOL        WINAPI SetTimeZoneInformation(const TIME_ZONE_INFORMATION *);
 BOOL        WINAPI SetVolumeMountPointA(LPCSTR,LPCSTR);
 BOOL        WINAPI SetVolumeMountPointW(LPCSTR,LPCSTR);
 #define     SetVolumeMountPoint WINELIB_NAME_AW(SetVolumeMountPoint)


More information about the wine-patches mailing list