misc.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 558 行
C
558 行
/*++
Copyright (c) 1999 - 2003 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
misc.c
Abstract:
Miscellaneous functions
Revision History
--*/
#include "fat.h"
EFI_STATUS
FatSetVolumeDirty (
IN FAT_VOLUME *Vol,
IN BOOLEAN Dirty
)
/*++
Routine Description:
Set the volume as dirty or not
Arguments:
Returns:
--*/
{
EFI_STATUS Status;
Status = EFI_SUCCESS;
if (Vol->FatType == FAT12) {
//
// Do nothing
//
;
} else if (Vol->FatType == FAT16) {
if (Dirty) {
Status = FatDiskIo (Vol, WRITE_DISK, Vol->FatPos + 2,
2, &Vol->DirtyValue);
} else {
Status = FatDiskIo (Vol, WRITE_DISK, Vol->FatPos + 2,
2, &Vol->NotDirtyValue);
}
} else if (Vol->FatType == FAT32) {
if (Dirty) {
Status = FatDiskIo (Vol, WRITE_DISK, Vol->FatPos + 4,
4, &Vol->DirtyValue);
} else {
Status = FatDiskIo (Vol, WRITE_DISK, Vol->FatPos + 4,
4, &Vol->NotDirtyValue);
}
}
//
// Flush all dirty cache entries to disk
//
if (Vol->Valid) {
Status = FatVolumeFlushCache (Vol);
if (EFI_ERROR(Status)) {
return Status;
}
}
return Status;
}
EFI_STATUS
FatDiskIo (
IN FAT_VOLUME *Vol,
IN DISK_IO_MODE IoMode,
IN UINT64 Offset,
IN UINTN BufferSize,
IN OUT VOID *Buffer
)
/*++
Routine Description:
General disk access function
Arguments:
Returns:
--*/
{
EFI_STATUS Status;
if (Vol->Valid == FALSE) {
return EFI_MEDIA_CHANGED;
}
//
// Verify the IO is in devices range
//
Status = EFI_VOLUME_CORRUPTED;
if (Offset + BufferSize <= Vol->VolSize) {
switch (IoMode) {
case READ_DISK:
Status = FatDiskIoReadVolume (Vol, Offset, BufferSize, Buffer);
break;
case WRITE_DISK:
Status = FatDiskIoWriteVolume (Vol, Offset, BufferSize, Buffer);
break;
default:
Status = EFI_UNSUPPORTED;
break;
}
}
if (EFI_ERROR(Status)) {
DEBUG ((EFI_D_INFO, "FatDiskIo: error %r\n", Status));
}
return Status;
}
VOID
FatAcquireLock ()
/*++
Routine Description:
Lock the volume.
Arguments:
Null.
Returns:
VOID.
--*/
{
EfiAcquireLock (&FatFsLock);
}
BOOLEAN
FatIsLocked ()
/*++
Routine Description:
Get the locking status of the volume.
Arguments:
Null.
Returns:
TRUE - the volume is locked
FALSE - the volume is not locked
--*/
{
return (BOOLEAN)(FatFsLock.Lock);
}
VOID
FatReleaseLock ()
/*++
Routine Description:
Unlock the volume.
Arguments:
Null.
Returns:
VOID.
--*/
{
EfiReleaseLock (&FatFsLock);
}
UINTN
FatSizeToClusters (
IN UINT64 Size,
IN UINTN ClusterSize
)
/*++
Routine Description:
Count the number of clusters given a size
Arguments:
Returns:
--*/
{
UINTN Rem;
UINTN Clusters;
Clusters = (UINTN) DriverLibDivU64x32(Size, (UINT32) ClusterSize, &Rem);
if (Rem) {
Clusters += 1;
}
return Clusters;
}
FAT_OFILE *
FatAllocateOFile (
IN FAT_VOLUME *Vol
)
/*++
Routine Description:
Allocate OFile structure
Arguments:
Returns:
--*/
{
FAT_OFILE *OFile;
OFile = EfiLibAllocateZeroPool(sizeof(FAT_OFILE));
if (OFile) {
OFile->Signature = FAT_OFILE_SIGNATURE;
OFile->Vol = Vol;
InitializeListHead (&OFile->Opens);
InitializeListHead (&OFile->ChildHead);
}
return OFile;
}
VOID
FatFreeOFile (
IN FAT_OFILE *OFile
)
/*++
Routine Description:
Free OFile structure
Arguments:
Returns:
--*/
{
UINTN Index;
if (OFile->NameNotFound) {
gBS->FreePool (OFile->NameNotFound);
}
if (OFile->FileString) {
gBS->FreePool (OFile->FileString);
}
if (OFile->ChildHashTable) {
for (Index = 0; Index < HASH_WORD_MASK + 1; Index ++) {
if (OFile->ChildHashTable[Index].HashNode) {
gBS->FreePool (OFile->ChildHashTable[Index].HashNode);
}
}
gBS->FreePool (OFile->ChildHashTable);
}
gBS->FreePool (OFile);
}
VOID
FatEfiTimeToFatTime (
IN EFI_TIME *ETime,
OUT FAT_DATE_TIME *FTime
)
/*++
Routine Description:
Translate EFI time to FAT time
Arguments:
Returns:
--*/
{
//ignores timezone info in source ETime
if (ETime->Year > 1980) {
FTime->Date.Year = (UINT16)(ETime->Year - 1980);
}
if (ETime->Year >= 1980 + 128) {
FTime->Date.Year = (UINT16)-1;
}
FTime->Date.Month = ETime->Month;
FTime->Date.Day = ETime->Day;
FTime->Time.Hour = ETime->Hour;
FTime->Time.Minute = ETime->Minute;
FTime->Time.DoubleSecond = (UINT16)(ETime->Second / 2);
}
VOID
FatFatTimeToEfiTime (
IN FAT_DATE_TIME *FTime,
OUT EFI_TIME *ETime
)
/*++
Routine Description:
Translate Fat time to EFI time
Arguments:
Returns:
--*/
{
ETime->Year = (UINT16) (FTime->Date.Year + 1980);
ETime->Month = (UINT8) FTime->Date.Month;
ETime->Day = (UINT8) FTime->Date.Day;
ETime->Hour = (UINT8) FTime->Time.Hour;
ETime->Minute = (UINT8) FTime->Time.Minute;
ETime->Second = (UINT8) (FTime->Time.DoubleSecond * 2);
ETime->Nanosecond = 0;
ETime->TimeZone = EFI_UNSPECIFIED_TIMEZONE;
ETime->Daylight = 0;
}
BOOLEAN
FatIsValidTime (
IN EFI_TIME *Time
)
/*++
Routine Description:
Check whether a time is valid
Arguments:
Returns:
--*/
{
static UINT8 MonthDays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
UINTN Day;
BOOLEAN Status;
Status = TRUE;
//
// Check the fields for range problems
//
if (Time->Year < 1980 || // Fat can only support from 1980
Time->Month < 1 ||
Time->Month > 12 || // Month is 1-12
Time->Day < 1 ||
Time->Day > 31 ||
Time->Hour > 23 ||
Time->Minute > 59 ||
Time->Second > 59 ||
Time->Nanosecond > 999999999) {
Status = FALSE;
} else {
//
// Perform a more specific check of the day of the month
//
Day = MonthDays[Time->Month - 1];
if (Time->Month == 2 && // Is it February & a leap year?
Time->Year % 4 == 0 && // leap is every 4 years,
(Time->Year % 100 != 0 || // but not on century year
Time->Year % 400 == 0) // unless it's every 4th century
) {
Day += 1; // 1 extra day this month
}
if (Time->Day > Day) {
Status = FALSE;
}
}
return Status;
}
UINTN
FatStrToFatLen (
IN CHAR16 *String
)
/*++
Routine Description:
Convert CHAR16 string to FAT string
Arguments:
Returns:
--*/
// N.B. only works on lengths up to 20 chars (but that enough
// for all 8.3 style calculations
{
CHAR8 Buffer[20];
EfiSetMem (Buffer, sizeof(Buffer), 0);
FatStrToFat (String, sizeof(Buffer)-1, Buffer);
return EfiAsciiStrLen (Buffer);
}
VOID
FatStrUpr (
IN CHAR16 *Str
)
/*++
Routine Description:
Uppercase a string
Arguments:
Returns:
--*/
{
if (gUnicodeCollationInterface) {
gUnicodeCollationInterface->StrUpr (gUnicodeCollationInterface, Str);
}
}
VOID
FatStrLwr (
IN CHAR16 *Str
)
/*++
Routine Description:
Lowercase a string
Arguments:
Returns:
--*/
{
if (gUnicodeCollationInterface) {
gUnicodeCollationInterface->StrLwr (gUnicodeCollationInterface, Str);
}
}
INTN
FatStriCmp (
IN CHAR16 *s1,
IN CHAR16 *s2
)
/*++
Routine Description:
Case insensitive string compare
Arguments:
Returns:
--*/
{
if (gUnicodeCollationInterface) {
return gUnicodeCollationInterface->StriColl (gUnicodeCollationInterface,
s1,
s2);
} else {
return 1;
}
}
VOID
FatFatToStr (
IN UINTN FatSize,
IN CHAR8 *Fat,
OUT CHAR16 *String
)
/*++
Routine Description:
Convert FAT string to unicode string
Arguments:
Returns:
--*/
{
if (gUnicodeCollationInterface) {
gUnicodeCollationInterface->FatToStr(gUnicodeCollationInterface,
FatSize,
Fat,
String);
}
}
BOOLEAN
FatStrToFat (
IN CHAR16 *String,
IN UINTN FatSize,
OUT CHAR8 *Fat
)
/*++
Routine Description:
Convert unicode string to Fat string
Arguments:
Returns:
--*/
{
if (gUnicodeCollationInterface) {
return gUnicodeCollationInterface->StrToFat(gUnicodeCollationInterface,
String,
FatSize,
Fat);
} else {
return FALSE;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?