info.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 693 行 · 第 1/2 页
C
693 行
/*++
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:
info.c
Abstract:
Routines dealing with setting/getting file/volume info
Revision History
--*/
#include "fat.h"
EFI_STATUS
FatGetVolumeInfo (
IN FAT_VOLUME *Vol,
IN OUT UINTN *BufferSize,
OUT VOID *Buffer
);
EFI_STATUS
FatSetVolumeInfo (
IN FAT_VOLUME *Vol,
IN OUT UINTN BufferSize,
OUT VOID *Buffer
);
EFI_STATUS
FatGetFileInfo (
IN FAT_VOLUME *Vol,
IN FAT_OFILE *OFile,
IN OUT UINTN *BufferSize,
OUT VOID *Buffer
)
{
UINTN Size, NameSize, ResultSize, Rem;
EFI_STATUS Status;
EFI_FILE_INFO *Info;
ASSERT_VOLUME_LOCKED (Vol);
Size = SIZE_OF_EFI_FILE_INFO;
NameSize = EfiStrSize (OFile->FileString);
ResultSize = Size + NameSize;
Status = EFI_BUFFER_TOO_SMALL;
if (*BufferSize >= ResultSize) {
EfiZeroMem (Buffer, ResultSize);
Status = EFI_SUCCESS;
Info = Buffer;
Info->Size = ResultSize;
Info->FileSize = OFile->FileSize;
Info->PhysicalSize = DriverLibDivU64x32(OFile->FileSize, Vol->ClusterSize, &Rem);
Info->PhysicalSize = DriverLibMultU64x32(
Info->PhysicalSize,
Vol->ClusterSize) + (Rem ? Vol->ClusterSize : 0
);
EfiCopyMem (&Info->CreateTime, &OFile->CreateTime, sizeof(EFI_TIME));
EfiCopyMem (&Info->ModificationTime,
&OFile->LastModification,
sizeof(EFI_TIME)
);
EfiCopyMem (&Info->LastAccessTime, &OFile->LastAccess, sizeof(EFI_TIME));
Info->Attribute = OFile->Attributes & EFI_FILE_VALID_ATTR;
EfiCopyMem ((CHAR8 *) Buffer + Size, OFile->FileString, NameSize);
}
*BufferSize = ResultSize;
return Status;
}
EFI_STATUS
FatGetVolumeInfo (
IN FAT_VOLUME *Vol,
IN OUT UINTN *BufferSize,
OUT VOID *Buffer
)
{
UINTN Size, NameSize, ResultSize;
CHAR16 Name[12];
EFI_STATUS Status;
EFI_FILE_SYSTEM_INFO *Info;
UINTN ClusterSize;
Size = SIZE_OF_EFI_FILE_SYSTEM_INFO;
Status = FatGetVolumeEntry (Vol,Name);
NameSize = EfiStrSize (Name);
ResultSize = Size + NameSize;
ClusterSize = Vol->ClusterSize;
//
// If we don't have valid info, compute it now
//
FatComputeFreeInfo (Vol);
Status = EFI_BUFFER_TOO_SMALL;
if (*BufferSize >= ResultSize) {
Status = EFI_SUCCESS;
Info = Buffer;
EfiZeroMem (Info, SIZE_OF_EFI_FILE_SYSTEM_INFO);
Info->Size = ResultSize;
Info->ReadOnly = Vol->BlkIo->Media->ReadOnly;
Info->BlockSize = (UINT32) ClusterSize;
Info->VolumeSize = DriverLibMultU64x32 (Vol->MaxCluster, ClusterSize);
Info->FreeSpace = DriverLibMultU64x32 (Vol->FatInfoSector.FreeInfo.ClusterCount,
ClusterSize
);
EfiCopyMem ((CHAR8 *) Buffer + Size, Name, NameSize);
}
*BufferSize = ResultSize;
return Status;
}
EFI_STATUS
FatGetVolumeLabelInfo (
IN FAT_VOLUME *Vol,
IN OUT UINTN *BufferSize,
OUT VOID *Buffer
)
{
UINTN Size, NameSize, ResultSize;
CHAR16 Name[12];
EFI_STATUS Status;
EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *Info;
Size = SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL_INFO;
Status = FatGetVolumeEntry (Vol,Name);
NameSize = EfiStrSize (Name);
ResultSize = Size + NameSize;
Status = EFI_BUFFER_TOO_SMALL;
if (*BufferSize >= ResultSize) {
Status = EFI_SUCCESS;
Info = Buffer;
EfiZeroMem (Info, SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL_INFO);
EfiCopyMem ((CHAR8 *) Buffer + Size, Name, NameSize);
}
*BufferSize = ResultSize;
return Status;
}
EFI_STATUS
FatSetVolumeInfo (
IN FAT_VOLUME *Vol,
IN UINTN BufferSize,
IN VOID *Buffer
)
{
EFI_STATUS Status;
EFI_FILE_SYSTEM_INFO *Info;
if (Vol->ReadOnly) {
return EFI_WRITE_PROTECTED;
}
Info = (EFI_FILE_SYSTEM_INFO *)Buffer;
if (BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + 2 || Info->Size > BufferSize){
return EFI_BAD_BUFFER_SIZE;
}
Status = FatSetVolumeEntry(Vol,Info->VolumeLabel);
return Status;
}
EFI_STATUS
FatSetVolumeLabelInfo (
IN FAT_VOLUME *Vol,
IN UINTN BufferSize,
IN VOID *Buffer
)
{
EFI_STATUS Status;
EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *Info;
if (Vol->ReadOnly) {
return EFI_WRITE_PROTECTED;
}
Info = (EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *)Buffer;
if (BufferSize < SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL_INFO + 2) {
return EFI_BAD_BUFFER_SIZE;
}
Status = FatSetVolumeEntry(Vol,Info->VolumeLabel);
return Status;
}
EFI_STATUS
FatSetFileInfo (
IN FAT_VOLUME *Vol,
IN FAT_IFILE *IFile,
IN FAT_OFILE *OFile,
IN UINTN BufferSize,
IN VOID *Buffer
)
{
EFI_FILE_INFO *NewInfo;
FAT_IFILE *NewIFile, *Open;
FAT_OFILE *NewOFile;
EFI_STATUS Status;
BOOLEAN Renamed;
EFI_TIME ZeroTime;
EFI_LIST_ENTRY *List;
FAT_OFILE *Entry;
EFI_STATUS SyncStatus;
UINT64 Position;
UINTN *ZeroBufferSize;
void *ZeroBuffer;
EfiZeroMem(&ZeroTime, sizeof(EFI_TIME));
Renamed = FALSE;
NewIFile = NULL;
NewOFile = NULL;
Entry = NULL;
ZeroBuffer = NULL;
ZeroBufferSize = NULL;
//
// Make sure there's a valid input buffer
//
NewInfo = Buffer;
if (BufferSize < SIZE_OF_EFI_FILE_INFO + 2 || NewInfo->Size > BufferSize) {
return EFI_BAD_BUFFER_SIZE;
}
//
// if a zero time is specified, then the original time is preserved
//
if (!EfiCompareMem (&ZeroTime, &NewInfo->CreateTime, sizeof(EFI_TIME))) {
EfiCopyMem (&NewInfo->CreateTime, &OFile->CreateTime, sizeof(EFI_TIME));
}
if (!EfiCompareMem (&ZeroTime, &NewInfo->ModificationTime, sizeof(EFI_TIME))){
EfiCopyMem (&NewInfo->ModificationTime,
&OFile->LastModification,
sizeof(EFI_TIME)
);
}
if (!EfiCompareMem (&ZeroTime, &NewInfo->LastAccessTime, sizeof (EFI_TIME))) {
EfiCopyMem (&NewInfo->LastAccessTime, &OFile->LastAccess, sizeof(EFI_TIME));
}
if ((NewInfo->Attribute & ~EFI_FILE_VALID_ATTR) ||
!FatIsValidTime(&NewInfo->CreateTime) ||
!FatIsValidTime(&NewInfo->ModificationTime)) {
return EFI_INVALID_PARAMETER;
}
// Can not change the directory attribute bit
if ((NewInfo->Attribute ^ OFile->Attributes) & EFI_FILE_DIRECTORY) {
return EFI_ACCESS_DENIED;
}
// If this is a directory, can't change the file size
if ((OFile->Attributes & EFI_FILE_DIRECTORY) &&
NewInfo->FileSize != OFile->FileSize) {
return EFI_ACCESS_DENIED;
}
//
// If this is the root directory, we can't make any updates
//
if (!OFile->Parent) {
return EFI_ACCESS_DENIED;
}
//
// If the IFile is read-only, the only change allowed is to
// update the attributes.
//
if (IFile->ReadOnly || (OFile->Attributes & EFI_FILE_READ_ONLY)) {
//
// If the volume is read-only, then it doesn't matter we can't update it
//
if (Vol->ReadOnly) {
return EFI_WRITE_PROTECTED;
}
//
// See if the caller is trying to change anything else
//
if (NewInfo->FileSize != OFile->FileSize ||
EfiCompareMem(&OFile->CreateTime, &NewInfo->CreateTime, sizeof(EFI_TIME)) ||
EfiCompareMem (&OFile->LastModification, &NewInfo->ModificationTime, sizeof(EFI_TIME)) ||
EfiCompareMem (&OFile->LastAccess, &NewInfo->LastAccessTime, sizeof(EFI_TIME))) {
return EFI_ACCESS_DENIED;
}
}
//
// Just in case, flush the current file info
//
Status = FatOFileFlush (OFile);
if (EFI_ERROR(Status)) {
goto Done;
}
//
// Open the filename and see if it refers to an existing file
//
Status = FatOFileOpen (OFile->Parent,
&NewIFile,
NewInfo->FileName,
EFI_FILE_MODE_READ,
0
);
if (!EFI_ERROR(Status)) {
if (NewIFile->OFile != OFile) {
// filename is to a different filename that already exists
Status = EFI_ACCESS_DENIED;
goto Done;
}
} else {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?