reactos/drivers/filesystems/fastfat_new/timesup.c
Pierre Schweitzer aeadcaf515
[FASTFAT] Import the MS FastFAT sample from WXP.
Modified it so that it builds in trunk (with GCC, though).
Not to be switched for now, as it doesn't work in ReactOS (yet?).
2017-11-23 12:35:51 +01:00

365 lines
7.9 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1989-2000 Microsoft Corporation
Module Name:
TimeSup.c
Abstract:
This module implements the Fat Time conversion support routines
--*/
#include "fatprocs.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FatNtTimeToFatTime)
#pragma alloc_text(PAGE, FatFatDateToNtTime)
#pragma alloc_text(PAGE, FatFatTimeToNtTime)
#pragma alloc_text(PAGE, FatGetCurrentFatTime)
#endif
BOOLEAN
FatNtTimeToFatTime (
IN PIRP_CONTEXT IrpContext,
IN PLARGE_INTEGER NtTime,
IN BOOLEAN Rounding,
OUT PFAT_TIME_STAMP FatTime,
#ifndef __REACTOS__
OUT OPTIONAL PCHAR TenMsecs
#else
OUT OPTIONAL PUCHAR TenMsecs
#endif
)
/*++
Routine Description:
This routine converts an NtTime value to its corresponding Fat time value.
Arguments:
NtTime - Supplies the Nt GMT Time value to convert from
Rounding - Indicates whether the NT time should be rounded up to a FAT boundary.
This should only be done *once* in the lifetime of a timestamp (important
for tunneling, which will cause a timestamp to pass through at least twice).
If true, rounded up. If false, rounded down to 10ms boundary. This obeys
the rules for non-creation time and creation times (respectively).
FatTime - Receives the equivalent Fat time value
TenMsecs - Optionally receive the number of tens of milliseconds the NtTime, after
any rounding, is greater than the FatTime
Return Value:
BOOLEAN - TRUE if the Nt time value is within the range of Fat's
time range, and FALSE otherwise
--*/
{
TIME_FIELDS TimeFields;
//
// Convert the input to the a time field record.
//
if (Rounding) {
//
// Add almost two seconds to round up to the nearest double second.
//
NtTime->QuadPart = NtTime->QuadPart + AlmostTwoSeconds;
}
ExSystemTimeToLocalTime( NtTime, NtTime );
RtlTimeToTimeFields( NtTime, &TimeFields );
//
// Check the range of the date found in the time field record
//
if ((TimeFields.Year < 1980) || (TimeFields.Year > (1980 + 127))) {
ExLocalTimeToSystemTime( NtTime, NtTime );
return FALSE;
}
//
// The year will fit in Fat so simply copy over the information
//
FatTime->Time.DoubleSeconds = (USHORT)(TimeFields.Second / 2);
FatTime->Time.Minute = (USHORT)(TimeFields.Minute);
FatTime->Time.Hour = (USHORT)(TimeFields.Hour);
FatTime->Date.Year = (USHORT)(TimeFields.Year - 1980);
FatTime->Date.Month = (USHORT)(TimeFields.Month);
FatTime->Date.Day = (USHORT)(TimeFields.Day);
if (TenMsecs) {
if (!Rounding) {
//
// If the number of seconds was not divisible by two, then there
// is another second of time (1 sec, 3 sec, etc.) Note we round down
// the number of milleconds onto tens of milleseconds boundaries.
//
*TenMsecs = (TimeFields.Milliseconds / 10) +
((TimeFields.Second % 2) * 100);
} else {
//
// If we rounded up, we have in effect changed the NT time. Therefore,
// it does not differ from the FAT time.
//
*TenMsecs = 0;
}
}
if (Rounding) {
//
// Slice off non-FAT boundary time and convert back to 64bit form
//
TimeFields.Milliseconds = 0;
TimeFields.Second -= TimeFields.Second % 2;
} else {
//
// Round down to 10ms boundary
//
TimeFields.Milliseconds -= TimeFields.Milliseconds % 10;
}
//
// Convert back to NT time
//
(VOID) RtlTimeFieldsToTime(&TimeFields, NtTime);
ExLocalTimeToSystemTime( NtTime, NtTime );
UNREFERENCED_PARAMETER( IrpContext );
return TRUE;
}
LARGE_INTEGER
FatFatDateToNtTime (
IN PIRP_CONTEXT IrpContext,
IN FAT_DATE FatDate
)
/*++
Routine Description:
This routine converts a Fat datev value to its corresponding Nt GMT
Time value.
Arguments:
FatDate - Supplies the Fat Date to convert from
Return Value:
LARGE_INTEGER - Receives the corresponding Nt Time value
--*/
{
TIME_FIELDS TimeFields;
LARGE_INTEGER Time;
//
// Pack the input time/date into a time field record
//
TimeFields.Year = (USHORT)(FatDate.Year + 1980);
TimeFields.Month = (USHORT)(FatDate.Month);
TimeFields.Day = (USHORT)(FatDate.Day);
TimeFields.Hour = (USHORT)0;
TimeFields.Minute = (USHORT)0;
TimeFields.Second = (USHORT)0;
TimeFields.Milliseconds = (USHORT)0;
//
// Convert the time field record to Nt LARGE_INTEGER, and set it to zero
// if we were given a bogus time.
//
if (!RtlTimeFieldsToTime( &TimeFields, &Time )) {
Time.LowPart = 0;
Time.HighPart = 0;
} else {
ExLocalTimeToSystemTime( &Time, &Time );
}
return Time;
UNREFERENCED_PARAMETER( IrpContext );
}
LARGE_INTEGER
FatFatTimeToNtTime (
IN PIRP_CONTEXT IrpContext,
IN FAT_TIME_STAMP FatTime,
IN UCHAR TenMilliSeconds
)
/*++
Routine Description:
This routine converts a Fat time value pair to its corresponding Nt GMT
Time value.
Arguments:
FatTime - Supplies the Fat Time to convert from
TenMilliSeconds - A 10 Milisecond resolution
Return Value:
LARGE_INTEGER - Receives the corresponding Nt GMT Time value
--*/
{
TIME_FIELDS TimeFields;
LARGE_INTEGER Time;
//
// Pack the input time/date into a time field record
//
TimeFields.Year = (USHORT)(FatTime.Date.Year + 1980);
TimeFields.Month = (USHORT)(FatTime.Date.Month);
TimeFields.Day = (USHORT)(FatTime.Date.Day);
TimeFields.Hour = (USHORT)(FatTime.Time.Hour);
TimeFields.Minute = (USHORT)(FatTime.Time.Minute);
TimeFields.Second = (USHORT)(FatTime.Time.DoubleSeconds * 2);
if (TenMilliSeconds != 0) {
TimeFields.Second += (USHORT)(TenMilliSeconds / 100);
TimeFields.Milliseconds = (USHORT)((TenMilliSeconds % 100) * 10);
} else {
TimeFields.Milliseconds = (USHORT)0;
}
//
// If the second value is greater than 59 then we truncate it to 0.
// Note that this can't happen with a proper FAT timestamp.
//
if (TimeFields.Second > 59) {
TimeFields.Second = 0;
}
//
// Convert the time field record to Nt LARGE_INTEGER, and set it to zero
// if we were given a bogus time.
//
if (!RtlTimeFieldsToTime( &TimeFields, &Time )) {
Time.LowPart = 0;
Time.HighPart = 0;
} else {
ExLocalTimeToSystemTime( &Time, &Time );
}
return Time;
UNREFERENCED_PARAMETER( IrpContext );
}
FAT_TIME_STAMP
FatGetCurrentFatTime (
IN PIRP_CONTEXT IrpContext
)
/*++
Routine Description:
This routine returns the current system time in Fat time
Arguments:
Return Value:
FAT_TIME_STAMP - Receives the current system time
--*/
{
LARGE_INTEGER Time;
TIME_FIELDS TimeFields;
FAT_TIME_STAMP FatTime;
//
// Get the current system time, and map it into a time field record.
//
KeQuerySystemTime( &Time );
ExSystemTimeToLocalTime( &Time, &Time );
//
// Always add almost two seconds to round up to the nearest double second.
//
Time.QuadPart = Time.QuadPart + AlmostTwoSeconds;
(VOID)RtlTimeToTimeFields( &Time, &TimeFields );
//
// Now simply copy over the information
//
FatTime.Time.DoubleSeconds = (USHORT)(TimeFields.Second / 2);
FatTime.Time.Minute = (USHORT)(TimeFields.Minute);
FatTime.Time.Hour = (USHORT)(TimeFields.Hour);
FatTime.Date.Year = (USHORT)(TimeFields.Year - 1980);
FatTime.Date.Month = (USHORT)(TimeFields.Month);
FatTime.Date.Day = (USHORT)(TimeFields.Day);
UNREFERENCED_PARAMETER( IrpContext );
return FatTime;
}