2 Handle operations in files and directories from UDF/ECMA-167 file systems.
4 Copyright (C) 2014-2017 Paulo Alcantara <pcacjr@zytor.com>
6 This program and the accompanying materials are licensed and made available
7 under the terms and conditions of the BSD License which accompanies this
8 distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
12 WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 EFI_FILE_PROTOCOL gUdfFileIoOps
= {
18 EFI_FILE_PROTOCOL_REVISION
,
35 #define _ROOT_FILE(_PrivData) (_PrivData)->Root
36 #define _PARENT_FILE(_PrivData) \
37 ((_PrivData)->IsRootDirectory ? (_PrivData)->Root : &(_PrivData)->File)
38 #define _FILE(_PrivData) _PARENT_FILE(_PrivData)
41 Open the root directory on a volume.
43 @param This Protocol instance pointer.
44 @param Root Returns an Open file handle for the root directory
46 @retval EFI_SUCCESS The device was opened.
47 @retval EFI_UNSUPPORTED This volume does not support the file system.
48 @retval EFI_NO_MEDIA The device has no media.
49 @retval EFI_DEVICE_ERROR The device reported an error.
50 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
51 @retval EFI_ACCESS_DENIED The service denied access to the file.
52 @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of
59 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*This
,
60 OUT EFI_FILE_PROTOCOL
**Root
65 PRIVATE_UDF_SIMPLE_FS_DATA
*PrivFsData
;
66 PRIVATE_UDF_FILE_DATA
*PrivFileData
;
68 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
70 if (This
== NULL
|| Root
== NULL
) {
71 Status
= EFI_INVALID_PARAMETER
;
72 goto Error_Invalid_Params
;
75 PrivFsData
= PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (This
);
77 if (PrivFsData
->OpenFiles
== 0) {
79 // There is no more open files. Read volume information again since it was
80 // cleaned up on the last UdfClose() call.
82 Status
= ReadUdfVolumeInformation (
87 if (EFI_ERROR (Status
)) {
88 goto Error_Read_Udf_Volume
;
92 CleanupFileInformation (&PrivFsData
->Root
);
95 // Find root directory file.
97 Status
= FindRootDirectory (
103 if (EFI_ERROR (Status
)) {
104 goto Error_Find_Root_Dir
;
108 (PRIVATE_UDF_FILE_DATA
*) AllocateZeroPool (sizeof (PRIVATE_UDF_FILE_DATA
));
109 if (PrivFileData
== NULL
) {
110 Status
= EFI_OUT_OF_RESOURCES
;
111 goto Error_Alloc_Priv_File_Data
;
114 PrivFileData
->Signature
= PRIVATE_UDF_FILE_DATA_SIGNATURE
;
115 PrivFileData
->SimpleFs
= This
;
116 PrivFileData
->Root
= &PrivFsData
->Root
;
117 PrivFileData
->IsRootDirectory
= TRUE
;
119 CopyMem ((VOID
*)&PrivFileData
->FileIo
, (VOID
*)&gUdfFileIoOps
,
120 sizeof (EFI_FILE_PROTOCOL
));
122 *Root
= &PrivFileData
->FileIo
;
124 PrivFsData
->OpenFiles
++;
126 gBS
->RestoreTPL (OldTpl
);
130 Error_Alloc_Priv_File_Data
:
131 CleanupFileInformation (&PrivFsData
->Root
);
135 Error_Read_Udf_Volume
:
136 Error_Invalid_Params
:
137 gBS
->RestoreTPL (OldTpl
);
143 Opens a new file relative to the source file's location.
145 @param This The protocol instance pointer.
146 @param NewHandle Returns File Handle for FileName.
147 @param FileName Null terminated string. "\", ".", and ".." are supported.
148 @param OpenMode Open mode for file.
149 @param Attributes Only used for EFI_FILE_MODE_CREATE.
151 @retval EFI_SUCCESS The device was opened.
152 @retval EFI_NOT_FOUND The specified file could not be found on the
154 @retval EFI_NO_MEDIA The device has no media.
155 @retval EFI_MEDIA_CHANGED The media has changed.
156 @retval EFI_DEVICE_ERROR The device reported an error.
157 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
158 @retval EFI_ACCESS_DENIED The service denied access to the file.
159 @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of
161 @retval EFI_VOLUME_FULL The volume is full.
167 IN EFI_FILE_PROTOCOL
*This
,
168 OUT EFI_FILE_PROTOCOL
**NewHandle
,
176 PRIVATE_UDF_FILE_DATA
*PrivFileData
;
177 PRIVATE_UDF_SIMPLE_FS_DATA
*PrivFsData
;
178 CHAR16 FilePath
[UDF_PATH_LENGTH
];
180 PRIVATE_UDF_FILE_DATA
*NewPrivFileData
;
181 CHAR16
*TempFileName
;
183 ZeroMem (FilePath
, sizeof FilePath
);
184 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
186 if (This
== NULL
|| NewHandle
== NULL
|| FileName
== NULL
) {
187 Status
= EFI_INVALID_PARAMETER
;
188 goto Error_Invalid_Params
;
191 if (OpenMode
!= EFI_FILE_MODE_READ
) {
192 Status
= EFI_WRITE_PROTECTED
;
193 goto Error_Invalid_Params
;
196 PrivFileData
= PRIVATE_UDF_FILE_DATA_FROM_THIS (This
);
198 PrivFsData
= PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData
->SimpleFs
);
203 if (*FileName
== L
'\\') {
204 StrCpyS (FilePath
, UDF_PATH_LENGTH
, FileName
);
206 StrCpyS (FilePath
, UDF_PATH_LENGTH
, PrivFileData
->AbsoluteFileName
);
207 StrCatS (FilePath
, UDF_PATH_LENGTH
, L
"\\");
208 StrCatS (FilePath
, UDF_PATH_LENGTH
, FileName
);
211 MangleFileName (FilePath
);
212 if (FilePath
[0] == L
'\0') {
213 Status
= EFI_NOT_FOUND
;
214 goto Error_Bad_FileName
;
222 _ROOT_FILE (PrivFileData
),
223 _PARENT_FILE (PrivFileData
),
224 &_PARENT_FILE(PrivFileData
)->FileIdentifierDesc
->Icb
,
227 if (EFI_ERROR (Status
)) {
228 goto Error_Find_File
;
232 (PRIVATE_UDF_FILE_DATA
*)AllocateZeroPool (sizeof (PRIVATE_UDF_FILE_DATA
));
233 if (NewPrivFileData
== NULL
) {
234 Status
= EFI_OUT_OF_RESOURCES
;
235 goto Error_Alloc_New_Priv_File_Data
;
238 CopyMem ((VOID
*)NewPrivFileData
, (VOID
*)PrivFileData
,
239 sizeof (PRIVATE_UDF_FILE_DATA
));
240 CopyMem ((VOID
*)&NewPrivFileData
->File
, &File
, sizeof (UDF_FILE_INFO
));
242 NewPrivFileData
->IsRootDirectory
= FALSE
;
244 StrCpyS (NewPrivFileData
->AbsoluteFileName
, UDF_PATH_LENGTH
, FilePath
);
245 FileName
= NewPrivFileData
->AbsoluteFileName
;
247 while ((TempFileName
= StrStr (FileName
, L
"\\")) != NULL
) {
248 FileName
= TempFileName
+ 1;
251 StrCpyS (NewPrivFileData
->FileName
, UDF_PATH_LENGTH
, FileName
);
253 Status
= GetFileSize (
257 &NewPrivFileData
->File
,
258 &NewPrivFileData
->FileSize
260 if (EFI_ERROR (Status
)) {
263 "%a: GetFileSize() fails with status - %r.\n",
266 goto Error_Get_File_Size
;
269 NewPrivFileData
->FilePosition
= 0;
270 ZeroMem ((VOID
*)&NewPrivFileData
->ReadDirInfo
,
271 sizeof (UDF_READ_DIRECTORY_INFO
));
273 *NewHandle
= &NewPrivFileData
->FileIo
;
275 PrivFsData
->OpenFiles
++;
277 gBS
->RestoreTPL (OldTpl
);
282 FreePool ((VOID
*)NewPrivFileData
);
284 Error_Alloc_New_Priv_File_Data
:
285 CleanupFileInformation (&File
);
289 Error_Invalid_Params
:
290 gBS
->RestoreTPL (OldTpl
);
296 Read data from the file.
298 @param This Protocol instance pointer.
299 @param BufferSize On input size of buffer, on output amount of data in
301 @param Buffer The buffer in which data is read.
303 @retval EFI_SUCCESS Data was read.
304 @retval EFI_NO_MEDIA The device has no media.
305 @retval EFI_DEVICE_ERROR The device reported an error.
306 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
307 @retval EFI_BUFFER_TO_SMALL BufferSize is too small. BufferSize contains
314 IN EFI_FILE_PROTOCOL
*This
,
315 IN OUT UINTN
*BufferSize
,
321 PRIVATE_UDF_FILE_DATA
*PrivFileData
;
322 PRIVATE_UDF_SIMPLE_FS_DATA
*PrivFsData
;
323 UDF_VOLUME_INFO
*Volume
;
324 UDF_FILE_INFO
*Parent
;
325 UDF_READ_DIRECTORY_INFO
*ReadDirInfo
;
326 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
327 EFI_DISK_IO_PROTOCOL
*DiskIo
;
328 UDF_FILE_INFO FoundFile
;
329 UDF_FILE_IDENTIFIER_DESCRIPTOR
*NewFileIdentifierDesc
;
330 VOID
*NewFileEntryData
;
331 CHAR16 FileName
[UDF_FILENAME_LENGTH
];
333 UINT64 BufferSizeUint64
;
335 ZeroMem (FileName
, sizeof FileName
);
336 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
338 if (This
== NULL
|| BufferSize
== NULL
|| (*BufferSize
!= 0 &&
340 Status
= EFI_INVALID_PARAMETER
;
341 goto Error_Invalid_Params
;
344 PrivFileData
= PRIVATE_UDF_FILE_DATA_FROM_THIS (This
);
345 PrivFsData
= PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData
->SimpleFs
);
347 BlockIo
= PrivFsData
->BlockIo
;
348 DiskIo
= PrivFsData
->DiskIo
;
349 Volume
= &PrivFsData
->Volume
;
350 ReadDirInfo
= &PrivFileData
->ReadDirInfo
;
351 NewFileIdentifierDesc
= NULL
;
352 NewFileEntryData
= NULL
;
354 Parent
= _PARENT_FILE (PrivFileData
);
356 Status
= EFI_VOLUME_CORRUPTED
;
358 if (IS_FID_NORMAL_FILE (Parent
->FileIdentifierDesc
)) {
359 if (PrivFileData
->FilePosition
> PrivFileData
->FileSize
) {
361 // File's position is beyond the EOF
363 Status
= EFI_DEVICE_ERROR
;
364 goto Error_File_Beyond_The_Eof
;
367 if (PrivFileData
->FilePosition
== PrivFileData
->FileSize
) {
369 Status
= EFI_SUCCESS
;
373 BufferSizeUint64
= *BufferSize
;
375 Status
= ReadFileData (
380 PrivFileData
->FileSize
,
381 &PrivFileData
->FilePosition
,
385 ASSERT (BufferSizeUint64
<= MAX_UINTN
);
386 *BufferSize
= (UINTN
)BufferSizeUint64
;
387 } else if (IS_FID_DIRECTORY_FILE (Parent
->FileIdentifierDesc
)) {
388 if (ReadDirInfo
->FidOffset
== 0 && PrivFileData
->FilePosition
> 0) {
389 Status
= EFI_DEVICE_ERROR
;
395 Status
= ReadDirectoryEntry (
399 &Parent
->FileIdentifierDesc
->Icb
,
402 &NewFileIdentifierDesc
404 if (EFI_ERROR (Status
)) {
405 if (Status
== EFI_DEVICE_ERROR
) {
406 FreePool (ReadDirInfo
->DirectoryData
);
407 ZeroMem ((VOID
*)ReadDirInfo
, sizeof (UDF_READ_DIRECTORY_INFO
));
410 Status
= EFI_SUCCESS
;
416 // After calling function ReadDirectoryEntry(), if 'NewFileIdentifierDesc'
417 // is NULL, then the 'Status' must be EFI_OUT_OF_RESOURCES. Hence, if the
418 // code reaches here, 'NewFileIdentifierDesc' must be not NULL.
420 // The ASSERT here is for addressing a false positive NULL pointer
421 // dereference issue raised from static analysis.
423 ASSERT (NewFileIdentifierDesc
!= NULL
);
425 if (!IS_FID_PARENT_FILE (NewFileIdentifierDesc
)) {
429 FreePool ((VOID
*)NewFileIdentifierDesc
);
432 Status
= FindFileEntry (
436 &NewFileIdentifierDesc
->Icb
,
439 if (EFI_ERROR (Status
)) {
442 ASSERT (NewFileEntryData
!= NULL
);
444 if (FE_ICB_FILE_TYPE (NewFileEntryData
) == UdfFileEntrySymlink
) {
445 Status
= ResolveSymlink (
453 if (EFI_ERROR (Status
)) {
454 goto Error_Resolve_Symlink
;
457 FreePool ((VOID
*)NewFileEntryData
);
458 NewFileEntryData
= FoundFile
.FileEntry
;
460 Status
= GetFileNameFromFid (NewFileIdentifierDesc
, FileName
);
461 if (EFI_ERROR (Status
)) {
462 FreePool ((VOID
*)FoundFile
.FileIdentifierDesc
);
463 goto Error_Get_FileName
;
466 FreePool ((VOID
*)NewFileIdentifierDesc
);
467 NewFileIdentifierDesc
= FoundFile
.FileIdentifierDesc
;
469 FoundFile
.FileIdentifierDesc
= NewFileIdentifierDesc
;
470 FoundFile
.FileEntry
= NewFileEntryData
;
472 Status
= GetFileNameFromFid (FoundFile
.FileIdentifierDesc
, FileName
);
473 if (EFI_ERROR (Status
)) {
474 goto Error_Get_FileName
;
478 Status
= GetFileSize (
485 if (EFI_ERROR (Status
)) {
486 goto Error_Get_File_Size
;
489 Status
= SetFileInfo (
496 if (EFI_ERROR (Status
)) {
497 goto Error_Set_File_Info
;
500 PrivFileData
->FilePosition
++;
501 Status
= EFI_SUCCESS
;
502 } else if (IS_FID_DELETED_FILE (Parent
->FileIdentifierDesc
)) {
504 // Code should never reach here.
507 Status
= EFI_DEVICE_ERROR
;
513 Error_Resolve_Symlink
:
514 if (NewFileEntryData
!= NULL
) {
515 FreePool (NewFileEntryData
);
519 if (NewFileIdentifierDesc
!= NULL
) {
520 FreePool ((VOID
*)NewFileIdentifierDesc
);
524 Error_File_Beyond_The_Eof
:
525 Error_Invalid_Params
:
526 gBS
->RestoreTPL (OldTpl
);
532 Close the file handle.
534 @param This Protocol instance pointer.
536 @retval EFI_SUCCESS The file was closed.
542 IN EFI_FILE_PROTOCOL
*This
547 PRIVATE_UDF_FILE_DATA
*PrivFileData
;
549 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
551 Status
= EFI_SUCCESS
;
554 Status
= EFI_INVALID_PARAMETER
;
558 PrivFileData
= PRIVATE_UDF_FILE_DATA_FROM_THIS (This
);
560 if (!PrivFileData
->IsRootDirectory
) {
561 CleanupFileInformation (&PrivFileData
->File
);
563 if (PrivFileData
->ReadDirInfo
.DirectoryData
!= NULL
) {
564 FreePool (PrivFileData
->ReadDirInfo
.DirectoryData
);
568 FreePool ((VOID
*)PrivFileData
);
571 gBS
->RestoreTPL (OldTpl
);
577 Close and delete the file handle.
579 @param This Protocol instance pointer.
581 @retval EFI_SUCCESS The file was closed and deleted.
582 @retval EFI_WARN_DELETE_FAILURE The handle was closed but the file was not
589 IN EFI_FILE_PROTOCOL
*This
592 PRIVATE_UDF_FILE_DATA
*PrivFileData
;
595 return EFI_INVALID_PARAMETER
;
598 PrivFileData
= PRIVATE_UDF_FILE_DATA_FROM_THIS (This
);
600 (VOID
)PrivFileData
->FileIo
.Close(This
);
602 return EFI_WARN_DELETE_FAILURE
;
606 Write data to a file.
608 @param This Protocol instance pointer.
609 @param BufferSize On input size of buffer, on output amount of data in
611 @param Buffer The buffer in which data to write.
613 @retval EFI_SUCCESS Data was written.
614 @retval EFI_UNSUPPORTED Writes to Open directory are not supported.
615 @retval EFI_NO_MEDIA The device has no media.
616 @retval EFI_DEVICE_ERROR The device reported an error.
617 @retval EFI_DEVICE_ERROR An attempt was made to write to a deleted file.
618 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
619 @retval EFI_WRITE_PROTECTED The device is write protected.
620 @retval EFI_ACCESS_DENIED The file was open for read only.
621 @retval EFI_VOLUME_FULL The volume is full.
627 IN EFI_FILE_PROTOCOL
*This
,
628 IN OUT UINTN
*BufferSize
,
632 return EFI_UNSUPPORTED
;
636 Get file's current position.
638 @param This Protocol instance pointer.
639 @param Position Byte position from the start of the file.
641 @retval EFI_SUCCESS Position was updated.
642 @retval EFI_UNSUPPORTED Seek request for directories is not valid.
648 IN EFI_FILE_PROTOCOL
*This
,
652 PRIVATE_UDF_FILE_DATA
*PrivFileData
;
654 if (This
== NULL
|| Position
== NULL
) {
655 return EFI_INVALID_PARAMETER
;
658 PrivFileData
= PRIVATE_UDF_FILE_DATA_FROM_THIS (This
);
661 // As per UEFI spec, if the file handle is a directory, then the current file
662 // position has no meaning and the operation is not supported.
664 if (IS_FID_DIRECTORY_FILE (PrivFileData
->File
.FileIdentifierDesc
)) {
665 return EFI_UNSUPPORTED
;
669 // The file is not a directory. So, return its position.
671 *Position
= PrivFileData
->FilePosition
;
677 Set file's current position.
679 @param This Protocol instance pointer.
680 @param Position Byte position from the start of the file.
682 @retval EFI_SUCCESS Position was updated.
683 @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open.
689 IN EFI_FILE_PROTOCOL
*This
,
694 PRIVATE_UDF_FILE_DATA
*PrivFileData
;
695 UDF_FILE_IDENTIFIER_DESCRIPTOR
*FileIdentifierDesc
;
698 return EFI_INVALID_PARAMETER
;
701 Status
= EFI_UNSUPPORTED
;
703 PrivFileData
= PRIVATE_UDF_FILE_DATA_FROM_THIS (This
);
705 FileIdentifierDesc
= _FILE (PrivFileData
)->FileIdentifierDesc
;
706 ASSERT (FileIdentifierDesc
!= NULL
);
707 if (IS_FID_DIRECTORY_FILE (FileIdentifierDesc
)) {
709 // If the file handle is a directory, the _only_ position that may be set is
710 // zero. This has no effect of starting the read proccess of the directory
714 PrivFileData
->FilePosition
= Position
;
715 PrivFileData
->ReadDirInfo
.FidOffset
= 0;
716 Status
= EFI_SUCCESS
;
718 } else if (IS_FID_NORMAL_FILE (FileIdentifierDesc
)) {
720 // Seeking to position 0xFFFFFFFFFFFFFFFF causes the current position to be
723 if (Position
== 0xFFFFFFFFFFFFFFFF) {
724 PrivFileData
->FilePosition
= PrivFileData
->FileSize
- 1;
726 PrivFileData
->FilePosition
= Position
;
729 Status
= EFI_SUCCESS
;
736 Get information about a file.
738 @param This Protocol instance pointer.
739 @param InformationType Type of information to return in Buffer.
740 @param BufferSize On input size of buffer, on output amount of data in
742 @param Buffer The buffer to return data.
744 @retval EFI_SUCCESS Data was returned.
745 @retval EFI_UNSUPPORTED InformationType is not supported.
746 @retval EFI_NO_MEDIA The device has no media.
747 @retval EFI_DEVICE_ERROR The device reported an error.
748 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
749 @retval EFI_WRITE_PROTECTED The device is write protected.
750 @retval EFI_ACCESS_DENIED The file was open for read only.
751 @retval EFI_BUFFER_TOO_SMALL Buffer was too small; required size returned in
758 IN EFI_FILE_PROTOCOL
*This
,
759 IN EFI_GUID
*InformationType
,
760 IN OUT UINTN
*BufferSize
,
765 PRIVATE_UDF_FILE_DATA
*PrivFileData
;
766 PRIVATE_UDF_SIMPLE_FS_DATA
*PrivFsData
;
767 EFI_FILE_SYSTEM_INFO
*FileSystemInfo
;
768 UINTN FileSystemInfoLength
;
770 UDF_FILE_SET_DESCRIPTOR
*FileSetDesc
;
772 UINT8
*OstaCompressed
;
775 UINT64 FreeSpaceSize
;
776 CHAR16 VolumeLabel
[64];
778 if (This
== NULL
|| InformationType
== NULL
|| BufferSize
== NULL
||
779 (*BufferSize
!= 0 && Buffer
== NULL
)) {
780 return EFI_INVALID_PARAMETER
;
783 PrivFileData
= PRIVATE_UDF_FILE_DATA_FROM_THIS (This
);
785 PrivFsData
= PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData
->SimpleFs
);
787 Status
= EFI_UNSUPPORTED
;
789 if (CompareGuid (InformationType
, &gEfiFileInfoGuid
)) {
790 Status
= SetFileInfo (
791 _FILE (PrivFileData
),
792 PrivFileData
->FileSize
,
793 PrivFileData
->FileName
,
797 } else if (CompareGuid (InformationType
, &gEfiFileSystemInfoGuid
)) {
798 String
= VolumeLabel
;
800 FileSetDesc
= &PrivFsData
->Volume
.FileSetDesc
;
802 OstaCompressed
= &FileSetDesc
->LogicalVolumeIdentifier
[0];
804 CompressionId
= OstaCompressed
[0];
805 if (!IS_VALID_COMPRESSION_ID (CompressionId
)) {
806 return EFI_VOLUME_CORRUPTED
;
809 for (Index
= 1; Index
< 128; Index
++) {
810 if (CompressionId
== 16) {
811 *String
= *(UINT8
*)(OstaCompressed
+ Index
) << 8;
818 *String
|= (CHAR16
)(*(UINT8
*)(OstaCompressed
+ Index
));
822 // Unlike FID Identifiers, Logical Volume Identifier is stored in a
823 // NULL-terminated OSTA compressed format, so we must check for the NULL
826 if (*String
== L
'\0') {
835 FileSystemInfoLength
= StrSize (VolumeLabel
) +
836 sizeof (EFI_FILE_SYSTEM_INFO
);
837 if (*BufferSize
< FileSystemInfoLength
) {
838 *BufferSize
= FileSystemInfoLength
;
839 return EFI_BUFFER_TOO_SMALL
;
842 FileSystemInfo
= (EFI_FILE_SYSTEM_INFO
*)Buffer
;
843 StrCpyS (FileSystemInfo
->VolumeLabel
, ARRAY_SIZE (VolumeLabel
),
845 Status
= GetVolumeSize (
852 if (EFI_ERROR (Status
)) {
856 FileSystemInfo
->Size
= FileSystemInfoLength
;
857 FileSystemInfo
->ReadOnly
= TRUE
;
858 FileSystemInfo
->BlockSize
=
859 PrivFsData
->Volume
.LogicalVolDesc
.LogicalBlockSize
;
860 FileSystemInfo
->VolumeSize
= VolumeSize
;
861 FileSystemInfo
->FreeSpace
= FreeSpaceSize
;
863 *BufferSize
= FileSystemInfoLength
;
864 Status
= EFI_SUCCESS
;
871 Set information about a file.
873 @param This Protocol instance pointer.
874 @param InformationType Type of information in Buffer.
875 @param BufferSize Size of buffer.
876 @param Buffer The data to write.
878 @retval EFI_SUCCESS Data was set.
879 @retval EFI_UNSUPPORTED InformationType is not supported.
880 @retval EFI_NO_MEDIA The device has no media.
881 @retval EFI_DEVICE_ERROR The device reported an error.
882 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
883 @retval EFI_WRITE_PROTECTED The device is write protected.
884 @retval EFI_ACCESS_DENIED The file was open for read only.
890 IN EFI_FILE_PROTOCOL
*This
,
891 IN EFI_GUID
*InformationType
,
896 return EFI_WRITE_PROTECTED
;
900 Flush data back for the file handle.
902 @param This Protocol instance pointer.
904 @retval EFI_SUCCESS Data was flushed.
905 @retval EFI_UNSUPPORTED Writes to Open directory are not supported.
906 @retval EFI_NO_MEDIA The device has no media.
907 @retval EFI_DEVICE_ERROR The device reported an error.
908 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
909 @retval EFI_WRITE_PROTECTED The device is write protected.
910 @retval EFI_ACCESS_DENIED The file was open for read only.
911 @retval EFI_VOLUME_FULL The volume is full.
917 IN EFI_FILE_PROTOCOL
*This
920 return EFI_WRITE_PROTECTED
;