diff --git a/reactos/dll/win32/kernel32/file/volume.c b/reactos/dll/win32/kernel32/file/volume.c index 28b9f0e69ba..fa8f311ac6c 100644 --- a/reactos/dll/win32/kernel32/file/volume.c +++ b/reactos/dll/win32/kernel32/file/volume.c @@ -1083,7 +1083,7 @@ GetVolumeNameForVolumeMountPointA( if ((ret = GetVolumeNameForVolumeMountPointW( pathW, volumeW, len ))) FilenameW2A_N( lpszVolumeName, len, volumeW, -1 ); - HeapFree( GetProcessHeap(), 0, pathW ); + RtlFreeHeap( GetProcessHeap(), 0, pathW ); return ret; } @@ -1107,7 +1107,7 @@ FindFirstVolumeW( MOUNTMGR_MOUNT_POINT input; MOUNTMGR_MOUNT_POINTS *output; - if (!(output = HeapAlloc( GetProcessHeap(), 0, size ))) + if (!(output = RtlAllocateHeap( GetProcessHeap(), 0, size ))) { SetLastError( ERROR_NOT_ENOUGH_MEMORY ); break; @@ -1119,7 +1119,7 @@ FindFirstVolumeW( { if (GetLastError() != ERROR_MORE_DATA) break; size = output->Size; - HeapFree( GetProcessHeap(), 0, output ); + RtlFreeHeap( GetProcessHeap(), 0, output ); continue; } CloseHandle( mgr ); @@ -1127,7 +1127,7 @@ FindFirstVolumeW( output->Size = 0; if (!FindNextVolumeW( output, volume, len )) { - HeapFree( GetProcessHeap(), 0, output ); + RtlFreeHeap( GetProcessHeap(), 0, output ); return INVALID_HANDLE_VALUE; } return (HANDLE)output; @@ -1146,7 +1146,7 @@ FindFirstVolumeA( DWORD len ) { - WCHAR *buffer = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); + WCHAR *buffer = RtlAllocateHeap( GetProcessHeap(), 0, len * sizeof(WCHAR) ); HANDLE handle = FindFirstVolumeW( buffer, len ); if (handle != INVALID_HANDLE_VALUE) @@ -1157,7 +1157,7 @@ FindFirstVolumeA( handle = INVALID_HANDLE_VALUE; } } - HeapFree( GetProcessHeap(), 0, buffer ); + RtlFreeHeap( GetProcessHeap(), 0, buffer ); return handle; } @@ -1170,7 +1170,7 @@ FindVolumeClose( HANDLE hFindVolume ) { - return HeapFree(GetProcessHeap(), 0, hFindVolume); + return RtlFreeHeap(GetProcessHeap(), 0, hFindVolume); } /* EOF */ diff --git a/reactos/dll/win32/kernel32/misc/stubs.c b/reactos/dll/win32/kernel32/misc/stubs.c index 3dac9665c58..6b85d312b37 100644 --- a/reactos/dll/win32/kernel32/misc/stubs.c +++ b/reactos/dll/win32/kernel32/misc/stubs.c @@ -728,21 +728,6 @@ SetThreadExecutionState( return old; } -/* - * @unimplemented - */ -BOOL -STDCALL -TzSpecificLocalTimeToSystemTime( - CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation, - CONST SYSTEMTIME *lpLocalTime, - LPSYSTEMTIME lpUniversalTime - ) -{ - STUB; - return 0; -} - /* * @unimplemented */ diff --git a/reactos/dll/win32/kernel32/misc/time.c b/reactos/dll/win32/kernel32/misc/time.c index 8cbbb95b1af..391fbe0235a 100644 --- a/reactos/dll/win32/kernel32/misc/time.c +++ b/reactos/dll/win32/kernel32/misc/time.c @@ -35,6 +35,204 @@ typedef struct __DOSDATE #define TICKSPERMIN 600000000 +#define LL2FILETIME( ll, pft )\ + (pft)->dwLowDateTime = (UINT)(ll); \ + (pft)->dwHighDateTime = (UINT)((ll) >> 32); +#define FILETIME2LL( pft, ll) \ + ll = (((LONGLONG)((pft)->dwHighDateTime))<<32) + (pft)-> dwLowDateTime ; + +static const int MonthLengths[2][12] = +{ + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +}; + +/* STATIC FUNTIONS **********************************************************/ + +static inline int IsLeapYear(int Year) +{ + return Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) ? 1 : 0; +} + +/*********************************************************************** + * TIME_DayLightCompareDate + * + * Compares two dates without looking at the year. + * + * PARAMS + * date [in] The local time to compare. + * compareDate [in] The daylight savings begin or end date. + * + * RETURNS + * + * -1 if date < compareDate + * 0 if date == compareDate + * 1 if date > compareDate + * -2 if an error occurs + */ +static int TIME_DayLightCompareDate( const SYSTEMTIME *date, + const SYSTEMTIME *compareDate ) +{ + int limit_day, dayinsecs; + + if (date->wMonth < compareDate->wMonth) + return -1; /* We are in a month before the date limit. */ + + if (date->wMonth > compareDate->wMonth) + return 1; /* We are in a month after the date limit. */ + + /* if year is 0 then date is in day-of-week format, otherwise + * it's absolute date. + */ + if (compareDate->wYear == 0) + { + WORD First; + /* compareDate->wDay is interpreted as number of the week in the month + * 5 means: the last week in the month */ + int weekofmonth = compareDate->wDay; + /* calculate the day of the first DayOfWeek in the month */ + First = ( 6 + compareDate->wDayOfWeek - date->wDayOfWeek + date->wDay + ) % 7 + 1; + limit_day = First + 7 * (weekofmonth - 1); + /* check needed for the 5th weekday of the month */ + if(limit_day > MonthLengths[date->wMonth==2 && IsLeapYear(date->wYear)] + [date->wMonth - 1]) + limit_day -= 7; + } + else + { + limit_day = compareDate->wDay; + } + + /* convert to seconds */ + limit_day = ((limit_day * 24 + compareDate->wHour) * 60 + + compareDate->wMinute ) * 60; + dayinsecs = ((date->wDay * 24 + date->wHour) * 60 + + date->wMinute ) * 60 + date->wSecond; + /* and compare */ + return dayinsecs < limit_day ? -1 : + dayinsecs > limit_day ? 1 : + 0; /* date is equal to the date limit. */ +} + +/*********************************************************************** + * TIME_CompTimeZoneID + * + * Computes the local time bias for a given time and time zone. + * + * PARAMS + * pTZinfo [in] The time zone data. + * lpFileTime [in] The system or local time. + * islocal [in] it is local time. + * + * 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 daylight savings time + */ +static DWORD TIME_CompTimeZoneID ( const TIME_ZONE_INFORMATION *pTZinfo, + FILETIME *lpFileTime, BOOL islocal ) +{ + int ret; + BOOL beforeStandardDate, afterDaylightDate; + DWORD retval = TIME_ZONE_ID_INVALID; + LONGLONG llTime = 0; /* initialized to prevent gcc complaining */ + SYSTEMTIME SysTime; + FILETIME ftTemp; + + if (pTZinfo->DaylightDate.wMonth != 0) + { + /* if year is 0 then date is in day-of-week format, otherwise + * it's absolute date. + */ + if (pTZinfo->StandardDate.wMonth == 0 || + (pTZinfo->StandardDate.wYear == 0 && + (pTZinfo->StandardDate.wDay<1 || + pTZinfo->StandardDate.wDay>5 || + pTZinfo->DaylightDate.wDay<1 || + pTZinfo->DaylightDate.wDay>5))) + { + SetLastError(ERROR_INVALID_PARAMETER); + return TIME_ZONE_ID_INVALID; + } + + if (!islocal) { + FILETIME2LL( lpFileTime, llTime ); + llTime -= ( pTZinfo->Bias + pTZinfo->DaylightBias ) + * (LONGLONG) TICKSPERMIN; + LL2FILETIME( llTime, &ftTemp) + lpFileTime = &ftTemp; + } + + FileTimeToSystemTime(lpFileTime, &SysTime); + + /* check for daylight savings */ + ret = TIME_DayLightCompareDate( &SysTime, &pTZinfo->StandardDate); + if (ret == -2) + return TIME_ZONE_ID_INVALID; + + beforeStandardDate = ret < 0; + + if (!islocal) { + llTime -= ( pTZinfo->StandardBias - pTZinfo->DaylightBias ) + * (LONGLONG) TICKSPERMIN; + LL2FILETIME( llTime, &ftTemp) + FileTimeToSystemTime(lpFileTime, &SysTime); + } + + ret = TIME_DayLightCompareDate( &SysTime, &pTZinfo->DaylightDate); + if (ret == -2) + return TIME_ZONE_ID_INVALID; + + afterDaylightDate = ret >= 0; + + retval = TIME_ZONE_ID_STANDARD; + if( pTZinfo->DaylightDate.wMonth < pTZinfo->StandardDate.wMonth ) { + /* Northern hemisphere */ + if( beforeStandardDate && afterDaylightDate ) + retval = TIME_ZONE_ID_DAYLIGHT; + } else /* Down south */ + if( beforeStandardDate || afterDaylightDate ) + retval = TIME_ZONE_ID_DAYLIGHT; + } else + /* No transition date */ + retval = TIME_ZONE_ID_UNKNOWN; + + return retval; +} + +/*********************************************************************** + * TIME_GetTimezoneBias + * + * Calculates the local time bias for a given time zone. + * + * PARAMS + * pTZinfo [in] The time zone data. + * lpFileTime [in] The system or local time. + * islocal [in] It is local time. + * pBias [out] The calculated bias in minutes. + * + * RETURNS + * TRUE when the time zone bias was calculated. + */ +static BOOL TIME_GetTimezoneBias( const TIME_ZONE_INFORMATION *pTZinfo, + FILETIME *lpFileTime, BOOL islocal, LONG *pBias ) +{ + 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; +} + + /* FUNCTIONS ****************************************************************/ /* @@ -444,6 +642,44 @@ SystemTimeToTzSpecificLocalTime( } +/* + * @implemented (Wine 13 sep 2008) + */ +BOOL +STDCALL +TzSpecificLocalTimeToSystemTime( + CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation, + CONST SYSTEMTIME *lpLocalTime, + LPSYSTEMTIME lpUniversalTime + ) +{ + FILETIME ft; + LONG lBias; + LONGLONG t; + TIME_ZONE_INFORMATION tzinfo; + + if (lpTimeZoneInformation != NULL) + { + tzinfo = *lpTimeZoneInformation; + } + else + { + if (GetTimeZoneInformation(&tzinfo) == TIME_ZONE_ID_INVALID) + return FALSE; + } + + if (!SystemTimeToFileTime(lpLocalTime, &ft)) + return FALSE; + FILETIME2LL( &ft, t) + if (!TIME_GetTimezoneBias(&tzinfo, &ft, TRUE, &lBias)) + return FALSE; + /* convert minutes to 100-nanoseconds-ticks */ + t += (LONGLONG)lBias * TICKSPERMIN; + LL2FILETIME( t, &ft) + return FileTimeToSystemTime(&ft, lpUniversalTime); +} + + /* * @implemented */