Further changes to fix issue 574\685.

There appear to be some additional problems with the impact of daylight
savings time kicking in. Calculations of BIAS, Standard BIAS &
Daylight BIAS are wrong.
This is showing up with Outlook 2010 meeting appointments, for example
select America\Vancouver, appointments, once accepted get assigned an hour
early.
I have also applied a fix to correctly send the Timezone information
currently commented out of code referencing this issue number in
libfreerdp_locale/timezone.c function freerdp_time_zone_detect()
This commit is contained in:
Nigel Reeves 2013-04-08 14:42:49 +01:00
parent c48a7bc5f1
commit 777dff2d0b
3 changed files with 23 additions and 67 deletions

View File

@ -117,9 +117,6 @@ BOOL rdp_read_client_time_zone(wStream* s, rdpSettings* settings)
void rdp_write_client_time_zone(wStream* s, rdpSettings* settings)
{
UINT32 bias;
INT32 sbias;
UINT32 bias2c;
WCHAR* standardName = NULL;
WCHAR* daylightName = NULL;
int standardNameLength;
@ -138,57 +135,34 @@ void rdp_write_client_time_zone(wStream* s, rdpSettings* settings)
if (daylightNameLength > 62)
daylightNameLength = 62;
/* UTC = LocalTime + Bias <-> Bias = UTC - LocalTime */
/* Translate from biases used throughout libfreerdp-locale/timezone.c
* to what RDP expects, which is minutes *west* of UTC.
* Though MS-RDPBCGR specifies bias as unsigned, two's complement
* (a negative integer) works fine for zones east of UTC.
*/
if (clientTimeZone->bias <= 720)
bias = -1 * clientTimeZone->bias;
else
bias = 1440 - clientTimeZone->bias;
stream_write_UINT32(s, bias); /* Bias */
/* Bias */
stream_write_UINT32(s, clientTimeZone->bias);
/* standardName (64 bytes) */
stream_write(s, standardName, standardNameLength);
stream_write_zero(s, 64 - standardNameLength);
rdp_write_system_time(s, &clientTimeZone->standardDate); /* StandardDate */
/* StandardDate */
rdp_write_system_time(s, &clientTimeZone->standardDate);
DEBUG_TIMEZONE("bias=%d stdName='%s' dlName='%s'",
bias, clientTimeZone->standardName, clientTimeZone->daylightName);
sbias = clientTimeZone->standardBias - clientTimeZone->bias;
if (sbias < 0)
bias2c = (UINT32) sbias;
else
bias2c = ~((UINT32) sbias) + 1;
DEBUG_TIMEZONE("bias=%d stdName='%s' dlName='%s'", clientTimeZone->bias, clientTimeZone->standardName, clientTimeZone->daylightName);
/* Note that StandardBias is ignored if no valid standardDate is provided. */
stream_write_UINT32(s, bias2c); /* StandardBias */
DEBUG_TIMEZONE("StandardBias=%d", bias2c);
/* StandardBias */
stream_write_UINT32(s, clientTimeZone->standardBias);
DEBUG_TIMEZONE("StandardBias=%d", clientTimeZone->standardBias);
/* daylightName (64 bytes) */
stream_write(s, daylightName, daylightNameLength);
stream_write_zero(s, 64 - daylightNameLength);
stream_write(s, daylightName, daylightNameLength);
stream_write_zero(s, 64 - daylightNameLength);
rdp_write_system_time(s, &clientTimeZone->daylightDate); /* DaylightDate */
sbias = clientTimeZone->daylightBias - clientTimeZone->bias;
if (sbias < 0)
bias2c = (UINT32) sbias;
else
bias2c = ~((UINT32) sbias) + 1;
/* DaylightDate */
rdp_write_system_time(s, &clientTimeZone->daylightDate);
/* Note that DaylightBias is ignored if no valid daylightDate is provided. */
stream_write_UINT32(s, bias2c); /* DaylightBias */
DEBUG_TIMEZONE("DaylightBias=%d", bias2c);
/* DaylightBias */
stream_write_UINT32(s, clientTimeZone->daylightBias);
DEBUG_TIMEZONE("DaylightBias=%d", clientTimeZone->daylightBias);
free(standardName);
free(daylightName);

View File

@ -1640,7 +1640,7 @@ TIME_ZONE_RULE_ENTRY* freerdp_get_current_time_zone_rule(TIME_ZONE_RULE_ENTRY* r
for (i = 0; i < (int) count; i++)
{
if ((rules[i].TicksStart <= windows_time) && (windows_time >= rules[i].TicksEnd))
if ((rules[i].TicksStart >= windows_time) && (windows_time >= rules[i].TicksEnd))
{
/*fprintf(stderr, "Got rule %d from table at %p with count %u\n", i, rules, count);*/
return &rules[i];
@ -1657,14 +1657,14 @@ void freerdp_time_zone_detect(TIME_ZONE_INFO* clientTimeZone)
TIME_ZONE_ENTRY* tz;
struct tm* local_time;
clientTimeZone->standardBias = 0;
time(&t);
local_time = localtime(&t);
#ifdef HAVE_TM_GMTOFF
if (local_time->tm_gmtoff >= 0)
clientTimeZone->bias = (UINT32) (local_time->tm_gmtoff / 60);
else
clientTimeZone->bias = (UINT32) (1440 + (INT32) (local_time->tm_gmtoff / 60));
clientTimeZone->bias = timezone / 60;
DEBUG_TIMEZONE("tzname[std]: %s, tzname[dst]: %s, timezone: %ld, Daylight: %d", tzname[0], tzname[1], timezone, daylight);
#elif defined(sun)
if (local_time->tm_isdst > 0)
clientTimeZone->bias = (UINT32) (altzone / 3600);
@ -1673,19 +1673,6 @@ void freerdp_time_zone_detect(TIME_ZONE_INFO* clientTimeZone)
#else
clientTimeZone->bias = 0;
#endif
if (local_time->tm_isdst > 0)
{
clientTimeZone->standardBias = clientTimeZone->bias - 60;
clientTimeZone->daylightBias = clientTimeZone->bias;
}
else
{
clientTimeZone->standardBias = clientTimeZone->bias;
clientTimeZone->daylightBias = clientTimeZone->bias + 60;
}
DEBUG_TIMEZONE("Bias: %d, StandardBias: %d, DaylightBias: %d",
clientTimeZone->bias, clientTimeZone->standardBias,
clientTimeZone->daylightBias);
tz = freerdp_detect_windows_time_zone(clientTimeZone->bias);
@ -1694,8 +1681,7 @@ void freerdp_time_zone_detect(TIME_ZONE_INFO* clientTimeZone)
DEBUG_TIMEZONE("tz: Id='%s' Bias=%d DST=%d dn='%s' sn='%s' dln='%s'",
tz->Id, tz->Bias, tz->SupportsDST, tz->DisplayName,
tz->StandardName, tz->DaylightName);
/* Not printed: RuleTable, RuleTableCount */
clientTimeZone->bias = tz->Bias;
sprintf(clientTimeZone->standardName, "%s", tz->StandardName);
sprintf(clientTimeZone->daylightName, "%s", tz->DaylightName);
@ -1704,11 +1690,9 @@ void freerdp_time_zone_detect(TIME_ZONE_INFO* clientTimeZone)
TIME_ZONE_RULE_ENTRY* rule;
rule = freerdp_get_current_time_zone_rule(tz->RuleTable, tz->RuleTableCount);
/* issue #574 -- temporarily disabled this block as it seems to be setting the wrong time
if (rule != NULL)
{
clientTimeZone->standardBias = 0;
clientTimeZone->daylightBias = rule->DaylightDelta;
clientTimeZone->daylightBias = -rule->DaylightDelta;
clientTimeZone->standardDate.wYear = rule->StandardDate.wYear;
clientTimeZone->standardDate.wMonth = rule->StandardDate.wMonth;
@ -1728,9 +1712,7 @@ void freerdp_time_zone_detect(TIME_ZONE_INFO* clientTimeZone)
clientTimeZone->daylightDate.wSecond = rule->DaylightDate.wSecond;
clientTimeZone->daylightDate.wMilliseconds = rule->DaylightDate.wMilliseconds;
}
*/
}
free(tz);
}
else

View File

@ -43,7 +43,7 @@ UINT64 freerdp_windows_gmtime()
UINT64 freerdp_get_windows_time_from_unix_time(time_t unix_time)
{
UINT64 windows_time;
windows_time = (unix_time * 10000000) + 621355968000000000ULL;
windows_time = ((UINT64)unix_time * 10000000) + 621355968000000000ULL;
return windows_time;
}