Home | History | Annotate | Download | only in EfiFileLib

Lines Matching defs:File

1 /** @file

2 File IO routines inspired by Streams with an EFI flavor
31 fs3: - EFI Simple File System device 3
33 10.0.1.102: - TFTP service IP followed by the file name
71 EFI_OPEN_FILE File;
93 Internal worker function to validate a File handle.
95 @param File Open File Handle
97 @return TRUE File is valid
98 @return FALSE File is not valid
104 IN EFI_OPEN_FILE *File
109 // Look right before and after file structure for the correct signatures
110 GuardFile = BASE_CR (File, EFI_OPEN_FILE_GUARD, File);
186 // If we can't do this then we can't support file system entries
189 // Loop through all the file system structures and cache the file system info data
213 Return TRUE if the <devce name> prefix of PathName matches a file system
364 @param File Open file handle
365 @param FileName Name of file after device stripped off
371 IN OUT EFI_OPEN_FILE *File,
403 if (File->EfiHandle != NULL) {
404 File->DevicePath = DevicePathFromHandle (File->EfiHandle);
407 File->DevicePath = AppendDevicePath (File->DevicePath, FileDevicePath);
411 Status = gBS->HandleProtocol (File->EfiHandle, &gEfiBlockIoProtocolGuid, (VOID **)&BlkIo);
413 File->FsBlockIoMedia = BlkIo->Media;
414 File->FsBlockIo = BlkIo;
416 // If we are not opening the device this will get over written with file info
417 File->MaxPosition = MultU64x32 (BlkIo->Media->LastBlock + 1, BlkIo->Media->BlockSize);
420 if (File->Type == EfiOpenFileSystem) {
421 Status = gBS->HandleProtocol (File->EfiHandle, &gEfiSimpleFileSystemProtocolGuid, (VOID **)&Fs);
427 Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, File->FsInfo);
429 File->FsInfo = AllocatePool (Size);
430 Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, File->FsInfo);
433 // Get information about the file
434 Status = Root->Open (Root, &File->FsFileHandle, UnicodeFileName, OpenMode, 0);
437 Status = File->FsFileHandle->GetInfo (File->FsFileHandle, &gEfiFileInfoGuid, &Size, NULL);
439 File->FsFileInfo = AllocatePool (Size);
440 Status = File->FsFileHandle->GetInfo (File->FsFileHandle, &gEfiFileInfoGuid, &Size, File->FsFileInfo);
442 File->Size = (UINTN)File->FsFileInfo->FileSize;
443 File->MaxPosition = (UINT64)File->Size;
451 } else if (File->Type == EfiOpenBlockIo) {
452 File->Size = (UINTN)File->MaxPosition;
502 @param File Open file handle
503 @param FileName Name of file after device stripped off
509 IN OUT EFI_OPEN_FILE *File,
531 Status = gBS->HandleProtocol (File->EfiHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&File->Fv);
537 Status = gBS->HandleProtocol (File->EfiHandle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&Fvb);
539 Status = Fvb->GetPhysicalAddress (Fvb, &File->FvStart);
541 FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)File->FvStart;
542 File->FvHeaderSize = sizeof (EFI_FIRMWARE_VOLUME_HEADER);
544 File->FvHeaderSize += sizeof (EFI_FV_BLOCK_MAP_ENTRY);
547 for (Lba = 0, File->FvSize = 0, NumberOfBlocks = 0; ; File->FvSize += (BlockSize * NumberOfBlocks), Lba += NumberOfBlocks) {
557 DevicePath = DevicePathFromHandle (File->EfiHandle);
560 File->DevicePath = DuplicateDevicePath (DevicePath);
561 File->Size = File->FvSize;
562 File->MaxPosition = File->Size;
566 File->FvType = EFI_FV_FILETYPE_ALL;
567 GetNextFileStatus = File->Fv->GetNextFile (
568 File->Fv,
570 &File->FvType,
571 &File->FvNameGuid,
572 &File->FvAttributes,
573 &File->Size
577 Status = CompareGuidToString (&File->FvNameGuid, FileName);
583 Status = File->Fv->ReadSection (
584 File->Fv,
585 &File->FvNameGuid,
610 File->Size = 0;
611 Status = File->Fv->ReadSection (
612 File->Fv,
613 &File->FvNameGuid,
617 &File->Size,
625 File->MaxPosition = File->Size;
626 EfiInitializeFwVolDevicepathNode (&DevicePathNode, &File->FvNameGuid);
627 File->DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&DevicePathNode);
640 path separated by a :. See file header for more details on the PathName
641 syntax. There is no checking to prevent a file from being opened more than
644 SectionType is only used to open an FV. Each file in an FV contains multiple
647 For any file that is opened with EfiOpen() must be closed with EfiClose().
665 EFI_OPEN_FILE *File;
682 File = &FileData;
683 ZeroMem (File, sizeof (EFI_OPEN_FILE));
742 File = EfiOpen (CwdPlusPathName, OpenMode, SectionType);
744 return File;
750 File->DeviceName = AllocatePool (StrLen);
751 AsciiStrCpyS (File->DeviceName, StrLen, PathName);
752 File->DeviceName[FileStart - 1] = '\0';
753 File->FileName = &File->DeviceName[FileStart];
754 if (File->FileName[0] == '\0') {
755 // if it is just a file name use / as root
756 File->FileName = "\\";
770 File->Type = EfiOpenFileSystem;
771 File->EfiHandle = mFs[DevNumber];
772 Status = EblFileDevicePath (File, &PathName[FileStart], OpenMode);
778 File->Type = EfiOpenFirmwareVolume;
779 File->EfiHandle = mFv[DevNumber];
791 // This means open the PE32 Section of the file
796 File->FvSectionType = ModifiedSectionType;
797 Status = EblFvFileDevicePath (File, &PathName[FileStart], ModifiedSectionType);
801 File->Type = EfiOpenMemoryBuffer;
803 File->Buffer = (VOID *)AsciiStrHexToUintn (&PathName[FileStart]);
812 File->Size = 0;
814 File->Size = AsciiStrHexToUintn (&PathName[FileStart + 1]);
819 if (File->Size == 0) {
820 File->Size = (UINTN)(0 - (UINTN)File->Buffer);
823 File->MaxPosition = File->Size;
824 File->BaseOffset = (UINTN)File->Buffer;
830 File->Type = EfiOpenLoadFile;
831 File->EfiHandle = mLoadFile[DevNumber];
833 Status = gBS->HandleProtocol (File->EfiHandle, &gEfiLoadFileProtocolGuid, (VOID **)&File->LoadFile);
838 Status = gBS->HandleProtocol (File->EfiHandle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath);
842 File->DevicePath = DuplicateDevicePath (DevicePath);
849 File->Type = EfiOpenBlockIo;
850 File->EfiHandle = mBlkIo[DevNumber];
851 EblFileDevicePath (File, "", OpenMode);
854 File->DiskOffset = AsciiStrHexToUintn (&PathName[FileStart]);
871 File->Size = File->Size - File->DiskOffset;
873 File->Size = Size;
876 File->MaxPosition = File->Size;
877 File->BaseOffset = File->DiskOffset;
889 File->Type = EfiOpenTftp;
890 File->IsDirty = FALSE;
891 File->IsBufferValid = FALSE;
893 Status = ConvertIpStringToEfiIp (PathName, &File->ServerIp);
906 CopyMem (&(GuardFile->File), &FileData, sizeof (EFI_OPEN_FILE));
909 return &(GuardFile->File);
912 FreePool (File->DeviceName);
934 AsciiPrint("Source file open error.\n");
941 AsciiPrint("Destination file open error.\n");
959 AsciiPrint("Read file error %r\n", Status);
965 AsciiPrint("Write file error %r\n", Status);
976 AsciiPrint("Read file error\n");
982 AsciiPrint("Write file error\n");
1055 Close a file handle opened by EfiOpen() and free all resources allocated by
1058 @param Stream Open File Handle
1060 @return EFI_INVALID_PARAMETER Stream is not an Open File
1066 IN EFI_OPEN_FILE *File
1072 if (!FileHandleValid (File)) {
1076 //Write the buffer contents to TFTP file.
1077 if ((File->Type == EfiOpenTftp) && (File->IsDirty)) {
1079 TftpBufferSize = File->Size;
1082 File->Buffer,
1086 &File->ServerIp,
1087 (UINT8 *)File->FileName,
1097 if ((File->Type == EfiOpenLoadFile) ||
1098 ((File->Type == EfiOpenTftp) && (File->IsBufferValid == TRUE)) ||
1099 ((File->Type == EfiOpenFirmwareVolume) && (File->IsBufferValid == TRUE))) {
1100 EblFreePool(File->Buffer);
1103 EblFreePool (File->DevicePath);
1104 EblFreePool (File->DeviceName);
1105 EblFreePool (File->FsFileInfo);
1106 EblFreePool (File->FsInfo);
1108 if (File->FsFileHandle != NULL) {
1109 File->FsFileHandle->Close (File->FsFileHandle);
1112 // Need to free File and it's Guard structures
1113 EblFreePool (BASE_CR (File, EFI_OPEN_FILE_GUARD, File));
1119 Return the size of the file represented by Stream. Also return the current
1120 Seek position. Opening a file will enable a valid file size to be returned.
1121 LoadFile is an exception as a load file size is set to zero.
1123 @param Stream Open File Handle
1125 @return 0 Stream is not an Open File or a valid LoadFile handle
1130 IN EFI_OPEN_FILE *File,
1137 if (!FileHandleValid (File)) {
1142 *CurrentPosition = File->CurrentPosition;
1145 if (File->Type == EfiOpenLoadFile) {
1146 // Figure out the File->Size
1147 File->Buffer = NULL;
1148 File->Size = 0;
1149 Status = File->LoadFile->LoadFile (File->LoadFile, File->DevicePath, FALSE, &File->Size, File->Buffer);
1154 File->MaxPosition = (UINT64)File->Size;
1155 } else if (File->Type == EfiOpenTftp) {
1163 &File->ServerIp,
1164 (UINT8 *)File->FileName,
1173 File->Size = (UINTN)BufferSize;
1174 File->MaxPosition = File->Size;
1177 return File->Size;
1182 Seek to the Offset location in the file. LoadFile and FV device types do
1183 not support EfiSeek(). It is not possible to grow the file size using
1186 SeekType defines how use Offset to calculate the new file position:
1189 EfiSeekEnd : Only supported if Offset is zero to seek to end of file.
1191 @param Stream Open File Handle
1196 @return EFI_INVALID_PARAMETER Stream is not an Open File
1198 @return EFI_NOT_FOUND Seek past the end of the file.
1204 IN EFI_OPEN_FILE *File,
1212 if (!FileHandleValid (File)) {
1216 if (File->Type == EfiOpenLoadFile) {
1221 CurrentPosition = File->CurrentPosition;
1224 if (Offset > File->MaxPosition) {
1231 if ((File->CurrentPosition + Offset) > File->MaxPosition) {
1239 // We don't support growing file size via seeking past end of file
1242 CurrentPosition = File->MaxPosition;
1250 if (File->FsFileHandle != NULL) {
1251 Status = File->FsFileHandle->SetPosition (File->FsFileHandle, CurrentPosition);
1255 File->CurrentPosition = CurrentPosition;
1263 IN OUT EFI_OPEN_FILE *File
1269 if (File->IsBufferValid) {
1273 // Make sure the file size is set.
1274 EfiTell (File, NULL);
1276 //Allocate a buffer to hold the whole file.
1277 File->Buffer = AllocatePool(File->Size);
1278 if (File->Buffer == NULL) {
1282 TftpBufferSize = File->Size;
1286 File->Buffer,
1290 &File->ServerIp,
1291 (UINT8 *)File->FileName,
1296 FreePool(File->Buffer);
1301 File->IsBufferValid = TRUE;
1307 Read BufferSize bytes from the current location in the file. For load file,
1308 FV, and TFTP case you must read the entire file.
1310 @param Stream Open File Handle
1315 @return EFI_SUCCESS Stream is not an Open File
1316 @return EFI_END_OF_FILE Tried to read past the end of the file
1317 @return EFI_INVALID_PARAMETER Stream is not an open file handle
1324 IN EFI_OPEN_FILE *File,
1333 if (!FileHandleValid (File)) {
1337 // Don't read past the end of the file.
1338 if ((File->CurrentPosition + *BufferSize) > File->MaxPosition) {
1342 switch (File->Type) {
1344 // Figure out the File->Size
1345 EfiTell (File, NULL);
1347 Status = File->LoadFile->LoadFile (File->LoadFile, File->DevicePath, FALSE, BufferSize, Buffer);
1351 if (CompareGuid (&File->FvNameGuid, &gZeroGuid)) {
1353 CopyMem (Buffer, (VOID *)(UINTN)(File->FvStart + File->CurrentPosition), *BufferSize);
1354 File->CurrentPosition += *BufferSize;
1357 if (File->Buffer == NULL) {
1358 if (File->FvSectionType == EFI_SECTION_ALL) {
1359 Status = File->Fv->ReadFile (
1360 File->Fv,
1361 &File->FvNameGuid,
1362 (VOID **)&File->Buffer,
1363 &File->Size,
1364 &File->FvType,
1365 &File->FvAttributes,
1369 Status = File->Fv->ReadSection (
1370 File->Fv,
1371 &File->FvNameGuid,
1372 File->FvSectionType,
1374 (VOID **)&File->Buffer,
1375 &File->Size,
1382 File->IsBufferValid = TRUE;
1385 CopyMem (Buffer, File->Buffer + File->CurrentPosition, *BufferSize);
1386 File->CurrentPosition += *BufferSize;
1392 CopyMem (Buffer, File->Buffer + File->CurrentPosition, *BufferSize);
1393 File->CurrentPosition += *BufferSize;
1398 Status = File->FsFileHandle->Read (File->FsFileHandle, BufferSize, Buffer);
1399 File->CurrentPosition += *BufferSize;
1403 Status = gBS->HandleProtocol(File->EfiHandle, &gEfiDiskIoProtocolGuid, (VOID **)&DiskIo);
1405 Status = DiskIo->ReadDisk(DiskIo, File->FsBlockIoMedia->MediaId, File->DiskOffset + File->CurrentPosition, *BufferSize, Buffer);
1407 File->CurrentPosition += *BufferSize;
1411 // Cache the file if it hasn't been cached yet.
1412 if (File->IsBufferValid == FALSE) {
1413 Status = CacheTftpFile (File);
1420 CopyMem (Buffer, File->Buffer + File->CurrentPosition, *BufferSize);
1421 File->CurrentPosition += *BufferSize;
1435 Read the entire file into a buffer. This routine allocates the buffer and
1438 This is very useful for load file where it's hard to know how big the buffer
1441 @param Stream Open File Handle
1446 @return EFI_SUCCESS Stream is not an Open File
1447 @return EFI_END_OF_FILE Tried to read past the end of the file
1448 @return EFI_INVALID_PARAMETER Stream is not an open file handle
1455 IN EFI_OPEN_FILE *File,
1460 if (!FileHandleValid (File)) {
1464 // Loadfile defers file size determination on Open so use tell to find it
1465 EfiTell (File, NULL);
1467 *BufferSize = File->Size;
1473 return EfiRead (File, *Buffer, BufferSize);
1478 Write data back to the file. For TFTP case you must write the entire file.
1480 @param Stream Open File Handle
1485 @return EFI_SUCCESS Stream is not an Open File
1486 @return EFI_END_OF_FILE Tried to read past the end of the file
1487 @return EFI_INVALID_PARAMETER Stream is not an open file handle
1494 IN EFI_OPEN_FILE *File,
1503 if (!FileHandleValid (File)) {
1507 switch (File->Type) {
1509 if ((File->CurrentPosition + *BufferSize) > File->MaxPosition) {
1513 CopyMem (File->Buffer + File->CurrentPosition, Buffer, *BufferSize);
1514 File->CurrentPosition += *BufferSize;
1522 if (File->FvSectionType != EFI_SECTION_ALL) {
1523 // Writes not support to a specific section. You have to update entire file
1527 FileData.NameGuid = &(File->FvNameGuid);
1528 FileData.Type = File->FvType;
1529 FileData.FileAttributes = File->FvAttributes;
1532 Status = File->Fv->WriteFile (File->Fv, 1, EFI_FV_UNRELIABLE_WRITE, &FileData);
1536 Status = File->FsFileHandle->Write (File->FsFileHandle, BufferSize, Buffer);
1537 File->CurrentPosition += *BufferSize;
1541 if ((File->CurrentPosition + *BufferSize) > File->MaxPosition) {
1545 Status = gBS->HandleProtocol (File->EfiHandle, &gEfiDiskIoProtocolGuid, (VOID **)&DiskIo);
1547 Status = DiskIo->WriteDisk (DiskIo, File->FsBlockIoMedia->MediaId, File->DiskOffset + File->CurrentPosition, *BufferSize, Buffer);
1549 File->CurrentPosition += *BufferSize;
1553 // Cache the file if it hasn't been cached yet.
1554 if (File->IsBufferValid == FALSE) {
1555 Status = CacheTftpFile(File);
1562 if ((File->CurrentPosition + *BufferSize) > File->MaxPosition) {
1565 TempBuffer = File->Buffer;
1567 File->Buffer = AllocatePool ((UINTN)(File->CurrentPosition + *BufferSize));
1568 if (File->Buffer == NULL) {
1572 CopyMem (File->Buffer, TempBuffer, File->Size);
1576 File->Size = (UINTN)(File->CurrentPosition + *BufferSize);
1577 File->MaxPosition = (UINT64)File->Size;
1581 CopyMem (File->Buffer + File->CurrentPosition, Buffer, *BufferSize);
1582 File->CurrentPosition += *BufferSize;
1584 // Mark the file dirty
1585 File->IsDirty = TRUE;
1659 // replace / will Null to remove trailing file/dir reference
1692 EFI_OPEN_FILE *File;
1725 File = EfiOpen (Path, EFI_FILE_MODE_READ, 0);
1726 if (File == NULL) {
1736 AllocLen = AsciiStrSize (File->DeviceName) + AsciiStrSize (File->FileName) + 10;
1742 AsciiStrCpyS (gCwd, AllocLen, File->DeviceName);
1743 if (File->FileName == NULL) {
1747 AsciiStrCatS (gCwd, AllocLen, File->FileName);
1751 EfiClose (File);