fatdent.cxx
来自「EFI(Extensible Firmware Interface)是下一代BI」· CXX 代码 · 共 1,176 行 · 第 1/2 页
CXX
1,176 行
Arguments:
None.
Return Value:
FALSE - Failure.
TRUE - Success.
--*/
{
TIME_FIELDS TimeFields;
USHORT t;
USHORT d;
USHORT msec;
USHORT year, month, day, hour, minute, second;
DebugAssert( _dirent );
DebugPtrAssert( TimeStamp );
memcpy(&t, &_dirent[14], sizeof(USHORT)); // time field
memcpy(&d, &_dirent[16], sizeof(USHORT)); // date field
msec = _dirent[13] * 10; // msec field
second = (t&0x001F)*2; // seconds
minute = (t&0x07E0)>>5; // Minutes
hour = t>>11; // Hours
day = d&0x001F; // Day of month 1-31
month = (d&0x01E0)>>5; // Month
year = (d>>9) + 1980; // Year
if (msec >= 1000) {
second += 1;
msec -= 1000;
}
TimeFields.Year = year;
TimeFields.Month = month;
TimeFields.Day = day;
TimeFields.Hour = hour;
TimeFields.Minute = minute;
TimeFields.Second = second;
TimeFields.Milliseconds = msec;
return RtlTimeFieldsToTime( &TimeFields, (PTIME)TimeStamp );
}
BOOLEAN
FAT_DIRENT::SetCreationTime(
)
/*++
Routine Description:
This routine sets the creation time to the current date and time.
Arguments:
None.
Return Value:
FALSE - Time stamp was not set successfully.
TRUE - Time stamp was set successfully.
--*/
{
USHORT fat_time;
USHORT fat_date;
DebugAssert(_dirent);
LARGE_INTEGER SystemTime, LocalTime;
TIME_FIELDS Time;
#if !defined( _SETUP_LOADER_ )
IFS_SYSTEM::QueryNtfsTime( &SystemTime );
RtlSystemTimeToLocalTime( &SystemTime, &LocalTime );
#else
IFS_SYSTEM::QueryNtfsTime( &LocalTime );
#endif
RtlTimeToTimeFields(&LocalTime, &Time);
fat_time = Time.Second/2;
fat_time |= Time.Minute<<5;
fat_time |= Time.Hour<<11;
fat_date = Time.Day;
fat_date |= Time.Month<<5;
fat_date |= (Time.Year - 1980)<<9;
memcpy(&_dirent[14], &fat_time, sizeof(USHORT));
memcpy(&_dirent[16], &fat_date, sizeof(USHORT));
return TRUE;
}
UFAT_EXPORT
BOOLEAN
FAT_DIRENT::IsValidLastAccessTime(
) CONST
/*++
Routine Description:
This routine verifies the validity of the last access time.
Arguments:
None.
Return Value:
FALSE - Invalid time stamp.
TRUE - Valid time stamp.
--*/
{
USHORT t = 0;
USHORT d;
DebugAssert(_dirent);
memcpy(&d, &_dirent[18], sizeof(USHORT)); // date field
return TimeStampsAreValid(t, d);
}
UFAT_EXPORT
BOOLEAN
FAT_DIRENT::QueryLastAccessTime(
OUT LARGE_INTEGER *TimeStamp
) CONST
/*++
Routine Description:
This routine returns the last access time in the form of a time fields
structure.
Arguments:
None.
Return Value:
FALSE - Failure.
TRUE - Success.
--*/
{
TIME_FIELDS TimeFields;
USHORT t;
USHORT d;
USHORT year, month, day, hour, minute, second;
DebugAssert( _dirent );
DebugPtrAssert( TimeStamp );
t = 0; // no time for last access; just date
memcpy(&d, &_dirent[18], sizeof(USHORT)); // date field
second = (t&0x001F)*2; // seconds
minute = (t&0x07E0)>>5; // Minutes
hour = t>>11; // Hours
day = d&0x001F; // Day of month 1-31
month = (d&0x01E0)>>5; // Month
year = (d>>9) + 1980; // Year
TimeFields.Year = year;
TimeFields.Month = month;
TimeFields.Day = day;
TimeFields.Hour = hour;
TimeFields.Minute = minute;
TimeFields.Second = second;
TimeFields.Milliseconds = 0;
return RtlTimeFieldsToTime( &TimeFields, (PTIME)TimeStamp );
}
BOOLEAN
FAT_DIRENT::SetLastAccessTime(
)
/*++
Routine Description:
This routine sets the last access time to the current date and time.
Arguments:
None.
Return Value:
FALSE - Time stamp was not set successfully.
TRUE - Time stamp was set successfully.
--*/
{
USHORT fat_date;
DebugAssert(_dirent);
LARGE_INTEGER SystemTime, LocalTime;
TIME_FIELDS Time;
#if !defined( _SETUP_LOADER_ )
IFS_SYSTEM::QueryNtfsTime( &SystemTime );
RtlSystemTimeToLocalTime( &SystemTime, &LocalTime );
#else
IFS_SYSTEM::QueryNtfsTime( &LocalTime );
#endif
RtlTimeToTimeFields(&LocalTime, &Time);
fat_date = Time.Day;
fat_date |= Time.Month<<5;
fat_date |= (Time.Year - 1980)<<9;
memcpy(&_dirent[18], &fat_date, sizeof(USHORT));
return TRUE;
}
VOID
FAT_DIRENT::Destroy(
)
/*++
Routine Description:
This routine returns the object to its initial state.
Arguments:
None.
Return Value:
None.
--*/
{
_dirent = NULL;
}
UCHAR
RotateCharRight(
IN UCHAR Char,
IN INT Shift
)
/*++
Routine Description:
This function rotates an eight-bit character right by the
specified number of bits.
Arguments:
Char -- Supplies the character to rotate
Shift -- Supplies the number of bits to shift
Return Value:
The rotated character.
--*/
{
UCHAR low_bit;
Shift %= 8;
while( Shift-- ) {
low_bit = Char & 1;
Char >>= 1;
if( low_bit ) {
Char |= 0x80;
}
}
return (UCHAR)Char;
}
UCHAR
FAT_DIRENT::QueryChecksum(
) CONST
/*++
Routine Description:
This method gets the checksum from the directory entry. If
the entry is a short entry, the checksum is computed; if the
entry is long, the checksum field is returned.
Arguments:
None.
Return Value:
The directory entry's checksum.
--*/
{
int name_length;
UCHAR sum;
PUCHAR name;
if( IsLongEntry() ) {
return( _dirent[13] );
} else {
sum = 0;
name = _dirent;
for( name_length = 11; name_length != 0; name_length-- ) {
sum = RotateCharRight(sum, 1) + *name++;
}
return( sum );
}
}
BOOLEAN
FAT_DIRENT::IsWellTerminatedLongNameEntry(
) CONST
/*++
Routine Description:
This method determines whether the entry is a well-terminated
long-name entry. A long-name entry is well terminated if:
--*/
{
ULONG i;
WCHAR Name[13];
if( IsErased() || !IsLongNameEntry() ) {
return FALSE;
}
// Assemble the bits and pieces of the name:
//
memcpy( &Name[0], &_dirent[1], 10 );
memcpy( &Name[5], &_dirent[14], 12 );
memcpy( &Name[11], &_dirent[28], 4 );
if( IsLastLongEntry() ) {
//
// Valid syntax for the last name entry is:
//
// N* {0 0xFFFF*}
//
// where N is the set of non-null characters.
//
for( i = 0; i < 13; i++ ) {
if( Name[i] == 0 ) {
break;
}
}
if( i < 13 ) {
//
// We hit a null character--step over it.
//
i++;
}
//
// The rest of the name-component must be 0xFFFF.
//
for( ; i < 13; i++ ) {
if( Name[i] != 0xFFFF ) {
return FALSE;
}
}
// This name-component was accepted.
//
return TRUE;
} else {
#if 0
// This is an additional consistency check that
// could be performed; however, now (as of 3/28/94)
// the file-system doesn't care, so neither do we.
// This is not the last component of the name, so
// it can't have any NULL's in it.
//
for( i = 0; i < 13; i++ ) {
if( Name[i] == 0 ) {
return FALSE;
}
}
#endif
return TRUE;
}
}
BOOLEAN
FAT_DIRENT::QueryLongNameComponent(
OUT PWSTRING NameComponent
) CONST
/*++
Routine Description:
This method extracts the long-name component from a Long Name
Directory Entry.
Arguments:
NameComponent -- Receives the long-name component
Return Value:
TRUE upon successful completion.
--*/
{
ULONG i;
WCHAR Name[13];
if( IsErased() || !IsLongNameEntry() ) {
return FALSE;
}
// Assemble the bits and pieces of the name:
//
memcpy( &Name[0], &_dirent[1], 10 );
memcpy( &Name[5], &_dirent[14], 12 );
memcpy( &Name[11], &_dirent[28], 4 );
// Long names may be zero terminated; however, if the
// name fits exactly into n long entries will not be
// zero terminated.
//
for( i = 0; i < 13 && Name[i]; i++ );
return( NameComponent->Initialize( Name, i ) );
}
BOOLEAN
FAT_DIRENT::NameHasTilde(
) CONST
/*++
Routine Description:
This routine checks a short name entry to see if it contains a tilde.
Arguments:
None.
Return Value:
TRUE - Tilde.
FALSE - No tilde.
--*/
{
USHORT i;
if (IsErased() || IsLongNameEntry()) {
return FALSE;
}
for (i = 0; i < 11; ++i) {
if ('~' == _dirent[i]) {
return TRUE;
}
}
return FALSE;
}
BOOLEAN
FAT_DIRENT::NameHasExtendedChars(
) CONST
/*++
Routine Description:
This routine determines whether there are any extended chars
(those with value >= 0x80) in the short file name.
Arguments:
None.
Return Value:
TRUE - There are one or more extended chars.
FALSE - There are no extended chars.
--*/
{
USHORT i;
if (IsErased() || IsLongNameEntry()) {
return FALSE;
}
for (i = 0; i < 11; ++i) {
if (_dirent[i] >= 0x80) {
return TRUE;
}
}
return FALSE;
}
BOOLEAN
FAT_DIRENT::TimeStampsAreValid(
USHORT t,
USHORT d
) CONST
/*++
Routine Description:
This routine examines the given time and date fields and
determines whether they represent valid dates.
Arguments:
None.
Return Value:
TRUE - The time and date are valid.
FALSE - One or both are invalid.
--*/
{
USHORT tmp;
tmp = t&0x001F; // 2-second increments
if (tmp > 29) {
return FALSE;
}
tmp = (t&0x07E0)>>5; // Minutes
if (tmp > 59) {
return FALSE;
}
tmp = (t&0xF800)>>11; // Hours
if (tmp > 23) {
return FALSE;
}
tmp = d&0x001F; // Day of month
if (tmp < 1 || tmp > 31) {
return FALSE;
}
tmp = (d&0x01E0)>>5; // Month
if (tmp < 1 || tmp > 12) {
return FALSE;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?