info.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 693 行 · 第 1/2 页
C
693 行
//
// File was not found. We do not allow rename of the current directory if
// there are open files below the current directory
//
Renamed = TRUE;
if (!IsListEmpty(&OFile->ChildHead)) {
Status = EFI_ACCESS_DENIED;
goto Done;
}
if (OFile->Attributes & EFI_FILE_READ_ONLY) {
Status = EFI_WRITE_PROTECTED;
goto Done;
}
//
// See if we can create the new filename
// N.B. If this is a rename of a directory, we first create the
// name as a file as to not allocate any space for it.
//
Status = FatOFileOpen(
OFile->Parent,
&NewIFile,
NewInfo->FileName,
EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE,
OFile->Attributes & ~EFI_FILE_DIRECTORY
);
if (EFI_ERROR(Status)) {
goto Done;
}
//
// File was created.
// Move the data stream to the new file. Update the attributes
// to capture the directory attribute bit.
//
NewOFile = NewIFile->OFile;
if (NewOFile->FileCluster != FAT_CLUSTER_FREE) {
Status = EFI_VOLUME_CORRUPTED;
goto Done;
}
NewOFile->FileSize = OFile->FileSize;
NewOFile->FileCluster = OFile->FileCluster;
NewOFile->FileCurrentCluster = OFile->FileCluster;
NewOFile->FileLastCluster = OFile->FileLastCluster;
NewOFile->DirType = OFile->DirType;
NewOFile->Attributes = OFile->Attributes;
NewOFile->ChildHashTable = OFile->ChildHashTable;
NewOFile->HashTopPosition = OFile->HashTopPosition;
NewOFile->HashEntry1 = OFile->HashEntry1;
NewOFile->HashEntry2 = OFile->HashEntry2;
NewOFile->CurrentEntryPos = OFile->CurrentEntryPos;
NewOFile->FreeEntryPos = OFile->FreeEntryPos;
NewOFile->NameNotFound = OFile->NameNotFound;
OFile->FileSize = 0;
OFile->FileCluster = FAT_CLUSTER_FREE;
OFile->FileCurrentCluster = FAT_CLUSTER_FREE;
OFile->FileLastCluster = 0;
OFile->Dirty = TRUE;
OFile->DirType = IsEmpty;
OFile->ChildHashTable = NULL;
OFile->NameNotFound = NULL;
//
// Move all the open handles to the new entry
// This version could pass /O1 and /Ow optimization switch
//
List = OFile->Opens.ForwardLink;
while (List != &OFile->Opens) {
Open = CR(List, FAT_IFILE, Link, FAT_IFILE_SIGNATURE);
List = List->ForwardLink;
RemoveEntryList (&Open->Link);
Open->OFile = NewOFile;
InsertTailList (&NewOFile->Opens, &Open->Link);
}
//
// Add the OFile to the check reference list
//
if (!OFile->CheckLink.ForwardLink) {
InsertHeadList (&Vol->CheckRef, &OFile->CheckLink);
}
//
// Apply the remaining SetInfo updates to the new ofile
//
OFile = NewOFile;
}
//
// Set file info is dirty
//
OFile->Dirty = TRUE;
//
// If the file size has changed, apply it
//
if (NewInfo->FileSize < OFile->FileSize) {
OFile->FileSize = NewInfo->FileSize;
Status = FatShrinkEof (OFile);
if (EFI_ERROR(Status)) {
goto Done;
}
}
if (NewInfo->FileSize > OFile->FileSize) {
Status = FatGrowEof (OFile, NewInfo->FileSize);
if (EFI_ERROR(Status)) {
FatShrinkEof (OFile);
goto Done;
}
*ZeroBufferSize = (UINTN)(NewInfo->FileSize - OFile->FileSize);
ZeroBuffer = EfiLibAllocateZeroPool (*ZeroBufferSize);
if (!ZeroBuffer) {
gBS->FreePool (ZeroBuffer);
return EFI_OUT_OF_RESOURCES;
}
FatOFileWrite (OFile, OFile->FileSize, ZeroBufferSize, ZeroBuffer);
if (ZeroBuffer) {
gBS->FreePool (ZeroBuffer);
}
OFile->FileSize = NewInfo->FileSize;
}
//
// Set the time info
//
EfiCopyMem (&OFile->CreateTime, &NewInfo->CreateTime, sizeof(EFI_TIME));
if (EfiCompareMem (&OFile->LastModification,
&NewInfo->ModificationTime,
sizeof(EFI_TIME))) {
//
// User wants to specify a modification time, don't update it when flush
//
OFile->PreserveLastMod = TRUE;
EfiCopyMem (&OFile->LastModification,
&NewInfo->ModificationTime,
sizeof(EFI_TIME)
);
}
EfiCopyMem (&OFile->LastAccess, &NewInfo->LastAccessTime, sizeof(EFI_TIME));
//
// If this is a directory, synchronize it's contained dot file's
// date and time field
// Be noted that now Sync failure is simply ignored
//
if (OFile->DirType == IsDir &&(!FatIsDotEntry(OFile))) {
Position = 0;
for (; ;) {
SyncStatus = FatGetDirOFile (OFile, &Position, &Entry);
//if some msg need to info user, we can use Sync_Status
if (EFI_ERROR(SyncStatus)) {
break;
}
if (Entry->DirType != IsEmpty && FatIsDotEntry(Entry)) {
Entry->PreserveLastMod = TRUE;
Entry->Dirty = TRUE;
EfiCopyMem (&Entry->CreateTime,
&NewInfo->CreateTime,
sizeof(EFI_TIME));
EfiCopyMem (&Entry->LastAccess,
&NewInfo->LastAccessTime,
sizeof(EFI_TIME));
EfiCopyMem (&Entry->LastModification,
&NewInfo->ModificationTime,
sizeof(EFI_TIME));
break;
}
}
}
//
// Set the current attributes
//
OFile->Attributes = (UINT8)((OFile->Attributes & ~EFI_FILE_VALID_ATTR) |
(UINT8) NewInfo->Attribute);
//
// If the file is renamed, we should append the ARCHIVE attribute
//
if (Renamed) {
OFile->Attributes = (UINT8)(OFile->Attributes | FAT_ATTRIBUTE_ARCHIVE);
}
//
// Done
//
Done:
//
// If we opened a handle, close it
//
if (NewIFile) {
FatIFileClose (NewIFile);
}
//
// Write the dirent changes for the new file
//
if (NewOFile) {
FatOFileFlush(NewOFile);
}
return Status;
}
EFI_STATUS
EFIAPI
FatGetInfo (
IN EFI_FILE *FHand,
IN EFI_GUID *Type,
IN OUT UINTN *BufferSize,
OUT VOID *Buffer
)
{
FAT_IFILE *IFile;
FAT_OFILE *OFile;
FAT_VOLUME *Vol;
EFI_STATUS Status;
IFile = IFILE_FROM_FHAND(FHand);
OFile = IFile->OFile;
Vol = OFile->Vol;
Status = OFile->Error;
if (Status == EFI_NOT_FOUND) {
return EFI_DEVICE_ERROR;
}
FatAcquireLock ();
//
// Verify the file handle isn't in an error state
//
if (!Status) {
//
// Get the proper information based on the request
//
Status = EFI_UNSUPPORTED;
if (EfiCompareGuid (Type, &gEfiFileInfoGuid)) {
Status = FatGetFileInfo (Vol, OFile, BufferSize, Buffer);
}
if (EfiCompareGuid (Type, &gEfiFileInfoIdGuid)) {
Status = FatGetVolumeInfo (Vol, BufferSize, Buffer);
}
if (EfiCompareGuid (Type, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
Status = FatGetVolumeLabelInfo (Vol, BufferSize, Buffer);
}
}
Status = FatCleanupVolume (OFile->Vol, NULL, Status);
FatReleaseLock();
return Status;
}
EFI_STATUS
EFIAPI
FatSetInfo (
IN EFI_FILE *FHand,
IN EFI_GUID *Type,
IN UINTN BufferSize,
IN VOID *Buffer
)
{
FAT_IFILE *IFile;
FAT_OFILE *OFile;
FAT_VOLUME *Vol;
EFI_STATUS Status;
IFile = IFILE_FROM_FHAND(FHand);
OFile = IFile->OFile;
Vol = OFile->Vol;
Status = OFile->Error;
if (Status == EFI_NOT_FOUND) {
return EFI_DEVICE_ERROR;
}
FatAcquireLock ();
//
// Verify the file handle isn't in an error state
//
if (!Status) {
//
// Get the proper information based on the request
//
Status = EFI_UNSUPPORTED;
if (EfiCompareGuid (Type, &gEfiFileInfoGuid)) {
Status = FatSetFileInfo (Vol, IFile, OFile, BufferSize, Buffer);
}
if (EfiCompareGuid (Type, &gEfiFileInfoIdGuid)) {
Status = FatSetVolumeInfo (Vol, BufferSize, Buffer);
}
if (EfiCompareGuid (Type, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
Status = FatSetVolumeLabelInfo (Vol, BufferSize, Buffer);
}
}
Status = FatCleanupVolume (OFile->Vol, NULL, Status);
FatReleaseLock();
return Status;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?