ntdll: Reimplement TIME_GetBias using new time zone code.
This commit is contained in:
parent
db552fbf4b
commit
d2d5bbe5d0
|
@ -51,6 +51,8 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
|
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
|
||||||
|
|
||||||
|
static int init_tz_info(RTL_TIME_ZONE_INFORMATION *tzi);
|
||||||
|
|
||||||
static RTL_CRITICAL_SECTION TIME_tz_section;
|
static RTL_CRITICAL_SECTION TIME_tz_section;
|
||||||
static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
|
static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
|
||||||
{
|
{
|
||||||
|
@ -239,26 +241,27 @@ BOOLEAN WINAPI RtlTimeFieldsToTime(
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* The bias for the current timezone.
|
* The bias for the current timezone.
|
||||||
*/
|
*/
|
||||||
static int TIME_GetBias(time_t utc, int *pdaylight)
|
static LONG TIME_GetBias(void)
|
||||||
{
|
{
|
||||||
struct tm *ptm;
|
|
||||||
static time_t last_utc;
|
static time_t last_utc;
|
||||||
static int last_bias;
|
static LONG last_bias;
|
||||||
static int last_daylight;
|
LONG ret;
|
||||||
int ret;
|
time_t utc;
|
||||||
|
|
||||||
|
utc = time( NULL );
|
||||||
|
|
||||||
RtlEnterCriticalSection( &TIME_tz_section );
|
RtlEnterCriticalSection( &TIME_tz_section );
|
||||||
if (utc != last_utc)
|
if (utc != last_utc)
|
||||||
{
|
{
|
||||||
ptm = localtime(&utc);
|
RTL_TIME_ZONE_INFORMATION tzi;
|
||||||
last_daylight = ptm->tm_isdst; /* daylight for local timezone */
|
int is_dst = init_tz_info( &tzi );
|
||||||
ptm = gmtime(&utc);
|
|
||||||
ptm->tm_isdst = last_daylight; /* use local daylight, not that of Greenwich */
|
|
||||||
last_utc = utc;
|
last_utc = utc;
|
||||||
last_bias = (int)(utc - mktime(ptm));
|
last_bias = tzi.Bias;
|
||||||
|
last_bias += is_dst ? tzi.DaylightBias : tzi.StandardBias;
|
||||||
|
last_bias *= SECSPERMIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
*pdaylight = last_daylight;
|
|
||||||
ret = last_bias;
|
ret = last_bias;
|
||||||
|
|
||||||
RtlLeaveCriticalSection( &TIME_tz_section );
|
RtlLeaveCriticalSection( &TIME_tz_section );
|
||||||
|
@ -281,15 +284,12 @@ static int TIME_GetBias(time_t utc, int *pdaylight)
|
||||||
NTSTATUS WINAPI RtlLocalTimeToSystemTime( const LARGE_INTEGER *LocalTime,
|
NTSTATUS WINAPI RtlLocalTimeToSystemTime( const LARGE_INTEGER *LocalTime,
|
||||||
PLARGE_INTEGER SystemTime)
|
PLARGE_INTEGER SystemTime)
|
||||||
{
|
{
|
||||||
time_t gmt;
|
LONG bias;
|
||||||
int bias, daylight;
|
|
||||||
|
|
||||||
TRACE("(%p, %p)\n", LocalTime, SystemTime);
|
TRACE("(%p, %p)\n", LocalTime, SystemTime);
|
||||||
|
|
||||||
gmt = time(NULL);
|
bias = TIME_GetBias();
|
||||||
bias = TIME_GetBias(gmt, &daylight);
|
SystemTime->QuadPart = LocalTime->QuadPart + bias * (LONGLONG)TICKSPERSEC;
|
||||||
|
|
||||||
SystemTime->QuadPart = LocalTime->QuadPart - bias * (LONGLONG)TICKSPERSEC;
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,15 +309,12 @@ NTSTATUS WINAPI RtlLocalTimeToSystemTime( const LARGE_INTEGER *LocalTime,
|
||||||
NTSTATUS WINAPI RtlSystemTimeToLocalTime( const LARGE_INTEGER *SystemTime,
|
NTSTATUS WINAPI RtlSystemTimeToLocalTime( const LARGE_INTEGER *SystemTime,
|
||||||
PLARGE_INTEGER LocalTime )
|
PLARGE_INTEGER LocalTime )
|
||||||
{
|
{
|
||||||
time_t gmt;
|
LONG bias;
|
||||||
int bias, daylight;
|
|
||||||
|
|
||||||
TRACE("(%p, %p)\n", SystemTime, LocalTime);
|
TRACE("(%p, %p)\n", SystemTime, LocalTime);
|
||||||
|
|
||||||
gmt = time(NULL);
|
bias = TIME_GetBias();
|
||||||
bias = TIME_GetBias(gmt, &daylight);
|
LocalTime->QuadPart = SystemTime->QuadPart - bias * (LONGLONG)TICKSPERSEC;
|
||||||
|
|
||||||
LocalTime->QuadPart = SystemTime->QuadPart + bias * (LONGLONG)TICKSPERSEC;
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -731,21 +728,31 @@ static time_t find_dst_change(unsigned long min, unsigned long max, int *is_dst)
|
||||||
return min;
|
return min;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_tz_info(RTL_TIME_ZONE_INFORMATION *tzi, int *valid_year)
|
static int init_tz_info(RTL_TIME_ZONE_INFORMATION *tzi)
|
||||||
{
|
{
|
||||||
|
static RTL_TIME_ZONE_INFORMATION cached_tzi;
|
||||||
|
static int current_year = -1;
|
||||||
struct tm *tm;
|
struct tm *tm;
|
||||||
time_t year_start, year_end, tmp, dlt = 0, std = 0;
|
time_t year_start, year_end, tmp, dlt = 0, std = 0;
|
||||||
int is_dst;
|
int is_dst, current_is_dst;
|
||||||
|
|
||||||
|
RtlEnterCriticalSection( &TIME_tz_section );
|
||||||
|
|
||||||
year_start = time(NULL);
|
year_start = time(NULL);
|
||||||
tm = localtime(&year_start);
|
tm = localtime(&year_start);
|
||||||
|
|
||||||
if (*valid_year == tm->tm_year) return;
|
current_is_dst = tm->tm_isdst;
|
||||||
|
if (current_year == tm->tm_year)
|
||||||
|
{
|
||||||
|
*tzi = cached_tzi;
|
||||||
|
RtlLeaveCriticalSection( &TIME_tz_section );
|
||||||
|
return current_is_dst;
|
||||||
|
}
|
||||||
|
|
||||||
memset(tzi, 0, sizeof(*tzi));
|
memset(tzi, 0, sizeof(*tzi));
|
||||||
|
|
||||||
TRACE("tz data will be valid through year %d\n", tm->tm_year + 1900);
|
TRACE("tz data will be valid through year %d\n", tm->tm_year + 1900);
|
||||||
*valid_year = tm->tm_year;
|
current_year = tm->tm_year;
|
||||||
|
|
||||||
tm->tm_isdst = 0;
|
tm->tm_isdst = 0;
|
||||||
tm->tm_mday = 1;
|
tm->tm_mday = 1;
|
||||||
|
@ -781,8 +788,9 @@ static void init_tz_info(RTL_TIME_ZONE_INFORMATION *tzi, int *valid_year)
|
||||||
|
|
||||||
if (dlt == std || !dlt || !std)
|
if (dlt == std || !dlt || !std)
|
||||||
{
|
{
|
||||||
|
RtlLeaveCriticalSection( &TIME_tz_section );
|
||||||
TRACE("there is no daylight saving rules in this time zone\n");
|
TRACE("there is no daylight saving rules in this time zone\n");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = dlt - tzi->Bias * 60;
|
tmp = dlt - tzi->Bias * 60;
|
||||||
|
@ -828,6 +836,11 @@ static void init_tz_info(RTL_TIME_ZONE_INFORMATION *tzi, int *valid_year)
|
||||||
tzi->StandardBias);
|
tzi->StandardBias);
|
||||||
|
|
||||||
find_reg_tz_info(tzi);
|
find_reg_tz_info(tzi);
|
||||||
|
cached_tzi = *tzi;
|
||||||
|
|
||||||
|
RtlLeaveCriticalSection( &TIME_tz_section );
|
||||||
|
|
||||||
|
return current_is_dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -844,18 +857,7 @@ static void init_tz_info(RTL_TIME_ZONE_INFORMATION *tzi, int *valid_year)
|
||||||
*/
|
*/
|
||||||
NTSTATUS WINAPI RtlQueryTimeZoneInformation(RTL_TIME_ZONE_INFORMATION *tzinfo)
|
NTSTATUS WINAPI RtlQueryTimeZoneInformation(RTL_TIME_ZONE_INFORMATION *tzinfo)
|
||||||
{
|
{
|
||||||
static RTL_TIME_ZONE_INFORMATION *cached_tzi;
|
init_tz_info( tzinfo );
|
||||||
static int current_year = -1;
|
|
||||||
|
|
||||||
RtlEnterCriticalSection(&TIME_tz_section);
|
|
||||||
|
|
||||||
if (!cached_tzi)
|
|
||||||
cached_tzi = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(*cached_tzi));
|
|
||||||
|
|
||||||
init_tz_info(cached_tzi, ¤t_year);
|
|
||||||
*tzinfo = *cached_tzi;
|
|
||||||
|
|
||||||
RtlLeaveCriticalSection(&TIME_tz_section);
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -894,41 +896,23 @@ NTSTATUS WINAPI RtlSetTimeZoneInformation( const RTL_TIME_ZONE_INFORMATION *tzin
|
||||||
*/
|
*/
|
||||||
NTSTATUS WINAPI NtSetSystemTime(const LARGE_INTEGER *NewTime, LARGE_INTEGER *OldTime)
|
NTSTATUS WINAPI NtSetSystemTime(const LARGE_INTEGER *NewTime, LARGE_INTEGER *OldTime)
|
||||||
{
|
{
|
||||||
TIME_FIELDS tf;
|
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
struct timezone tz;
|
time_t tm_t;
|
||||||
struct tm t;
|
DWORD sec, oldsec;
|
||||||
time_t sec, oldsec;
|
LARGE_INTEGER tm;
|
||||||
int dst, bias;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* Return the old time if necessary */
|
/* Return the old time if necessary */
|
||||||
if(OldTime)
|
if (!OldTime) OldTime = &tm;
|
||||||
NtQuerySystemTime(OldTime);
|
|
||||||
|
|
||||||
RtlTimeToTimeFields(NewTime, &tf);
|
NtQuerySystemTime( OldTime );
|
||||||
|
RtlTimeToSecondsSince1970( OldTime, &oldsec );
|
||||||
|
|
||||||
/* call gettimeofday to get the current timezone */
|
RtlTimeToSecondsSince1970( NewTime, &sec );
|
||||||
gettimeofday(&tv, &tz);
|
|
||||||
oldsec = tv.tv_sec;
|
|
||||||
/* get delta local time from utc */
|
|
||||||
bias = TIME_GetBias(oldsec, &dst);
|
|
||||||
|
|
||||||
/* get the number of seconds */
|
|
||||||
t.tm_sec = tf.Second;
|
|
||||||
t.tm_min = tf.Minute;
|
|
||||||
t.tm_hour = tf.Hour;
|
|
||||||
t.tm_mday = tf.Day;
|
|
||||||
t.tm_mon = tf.Month - 1;
|
|
||||||
t.tm_year = tf.Year - 1900;
|
|
||||||
t.tm_isdst = dst;
|
|
||||||
sec = mktime (&t);
|
|
||||||
/* correct for timezone and daylight */
|
|
||||||
sec += bias;
|
|
||||||
|
|
||||||
/* set the new time */
|
/* set the new time */
|
||||||
tv.tv_sec = sec;
|
tv.tv_sec = sec;
|
||||||
tv.tv_usec = tf.Milliseconds * 1000;
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
/* error and sanity check*/
|
/* error and sanity check*/
|
||||||
if(sec == (time_t)-1 || abs((int)(sec-oldsec)) > SETTIME_MAX_ADJUST) {
|
if(sec == (time_t)-1 || abs((int)(sec-oldsec)) > SETTIME_MAX_ADJUST) {
|
||||||
|
@ -943,8 +927,9 @@ NTSTATUS WINAPI NtSetSystemTime(const LARGE_INTEGER *NewTime, LARGE_INTEGER *Old
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ERR("Cannot set time to %d/%d/%d %d:%d:%d Time adjustment %ld %s\n",
|
tm_t = sec;
|
||||||
tf.Year, tf.Month, tf.Day, tf.Hour, tf.Minute, tf.Second,
|
ERR("Cannot set time to %s Time adjustment %ld %s\n",
|
||||||
|
ctime( &tm_t ),
|
||||||
(long)(sec-oldsec),
|
(long)(sec-oldsec),
|
||||||
err == -1 ? "No Permission"
|
err == -1 ? "No Permission"
|
||||||
: sec == (time_t)-1 ? "" : "is too large." );
|
: sec == (time_t)-1 ? "" : "is too large." );
|
||||||
|
|
Loading…
Reference in New Issue