Zune 30Gb Bug Sourcecode
As you may have heard, all 30Gb Zune’s refused to work on December 31st 2008 due to a bug in the internal clock driver related to the way the device handles a leap year.
Somehow, the sourcecode to the RTC clock driver code has appeared on the internet. The code itself was written by Freescale Semiconductor though, not Microsoft.
The problematic code seems to start on line 249:
//------------------------------------------------------------------------------
//
// Function: ConvertDays
//
// Local helper function that split total days since Jan 1, ORIGINYEAR into
// year, month and day
//
// Parameters:
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//------------------------------------------------------------------------------
BOOL ConvertDays(UINT32 days, SYSTEMTIME* lpTime)
{
int dayofweek, month, year;
UINT8 *month_tab;
//Calculate current day of the week
dayofweek = GetDayOfWeek(days);
year = ORIGINYEAR;
while (days > 365)
{
if (IsLeapYear(year))
{
if (days > 366)
{
days -= 366;
year += 1;
}
}
else
{
days -= 365;
year += 1;
}
}
// Determine whether it is a leap year
month_tab = (UINT8 *)((IsLeapYear(year))? monthtable_leap : monthtable);
for (month=0; month<12; month++)
{
if (days <= month_tab[month])
break;
days -= month_tab[month];
}
month += 1;
lpTime->wDay = days;
lpTime->wDayOfWeek = dayofweek;
lpTime->wMonth = month;
lpTime->wYear = year;
return TRUE;
}
Basically, December 31st was being qualified as a day > 365 (Which is correct, it was day 366 as 2008 was a leap year). The bug is that the code only checks for days > 366, not = 366. The poor Zune’s were getting stuck in the while loop until January 1st when they could finally break out.