- volume.c: replace HeapAlloc to RtlAllocateHeap, HeapFree to RtlFreeHeap

- move TzSpecificLocalTimeToSystemTime to time.c
- implement TzSpecificLocalTimeToSystemTime based on wine. It corrects 378 wine tests.

svn path=/trunk/; revision=36183
This commit is contained in:
Dmitry Chapyshev 2008-09-13 10:22:28 +00:00
parent 6df53c008e
commit 517a8ef2b2
3 changed files with 243 additions and 22 deletions

View file

@ -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 */

View file

@ -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
*/

View file

@ -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
*/