2 Handle operations in files and directories from UDF/ECMA-167 file systems.
4 Copyright (C) 2014-2017 Paulo Alcantara <pcacjr@zytor.com>
5 Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
12 EFI_FILE_PROTOCOL gUdfFileIoOps
= {
13 EFI_FILE_PROTOCOL_REVISION
,
30 #define _ROOT_FILE(_PrivData) (_PrivData)->Root
31 #define _PARENT_FILE(_PrivData) \
32 ((_PrivData)->IsRootDirectory ? (_PrivData)->Root : &(_PrivData)->File)
33 #define _FILE(_PrivData) _PARENT_FILE(_PrivData)
36 Open the root directory on a volume.
38 @param This Protocol instance pointer.
39 @param Root Returns an Open file handle for the root directory
41 @retval EFI_SUCCESS The device was opened.
42 @retval EFI_UNSUPPORTED This volume does not support the file system.
43 @retval EFI_NO_MEDIA The device has no media.
44 @retval EFI_DEVICE_ERROR The device reported an error.
45 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
46 @retval EFI_ACCESS_DENIED The service denied access to the file.
47 @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of
54 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*This
,
55 OUT EFI_FILE_PROTOCOL
**Root
60 PRIVATE_UDF_SIMPLE_FS_DATA
*PrivFsData
;
61 PRIVATE_UDF_FILE_DATA
*PrivFileData
;
63 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
65 if ((This
== NULL
) || (Root
== NULL
)) {
66 Status
= EFI_INVALID_PARAMETER
;
67 goto Error_Invalid_Params
;
70 PrivFsData
= PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (This
);
72 if (PrivFsData
->OpenFiles
== 0) {
74 // There is no more open files. Read volume information again since it was
75 // cleaned up on the last UdfClose() call.
77 Status
= ReadUdfVolumeInformation (
82 if (EFI_ERROR (Status
)) {
83 goto Error_Read_Udf_Volume
;
87 CleanupFileInformation (&PrivFsData
->Root
);
90 // Find root directory file.
92 Status
= FindRootDirectory (
98 if (EFI_ERROR (Status
)) {
99 goto Error_Find_Root_Dir
;
103 (PRIVATE_UDF_FILE_DATA
*)AllocateZeroPool (sizeof (PRIVATE_UDF_FILE_DATA
));
104 if (PrivFileData
== NULL
) {
105 Status
= EFI_OUT_OF_RESOURCES
;
106 goto Error_Alloc_Priv_File_Data
;
109 PrivFileData
->Signature
= PRIVATE_UDF_FILE_DATA_SIGNATURE
;
110 PrivFileData
->SimpleFs
= This
;
111 PrivFileData
->Root
= &PrivFsData
->Root
;
112 PrivFileData
->IsRootDirectory
= TRUE
;
115 (VOID
*)&PrivFileData
->FileIo
,
116 (VOID
*)&gUdfFileIoOps
,
117 sizeof (EFI_FILE_PROTOCOL
)
120 *Root
= &PrivFileData
->FileIo
;
122 PrivFsData
->OpenFiles
++;
124 gBS
->RestoreTPL (OldTpl
);
128 Error_Alloc_Priv_File_Data
:
129 CleanupFileInformation (&PrivFsData
->Root
);
133 Error_Read_Udf_Volume
:
134 Error_Invalid_Params
:
135 gBS
->RestoreTPL (OldTpl
);
141 Opens a new file relative to the source file's location.
143 @param This The protocol instance pointer.
144 @param NewHandle Returns File Handle for FileName.
145 @param FileName Null terminated string. "\", ".", and ".." are supported.
146 @param OpenMode Open mode for file.
147 @param Attributes Only used for EFI_FILE_MODE_CREATE.
149 @retval EFI_SUCCESS The device was opened.
150 @retval EFI_NOT_FOUND The specified file could not be found on the
152 @retval EFI_NO_MEDIA The device has no media.
153 @retval EFI_MEDIA_CHANGED The media has changed.
154 @retval EFI_DEVICE_ERROR The device reported an error.
155 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
156 @retval EFI_ACCESS_DENIED The service denied access to the file.
157 @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of
159 @retval EFI_VOLUME_FULL The volume is full.
165 IN EFI_FILE_PROTOCOL
*This
,
166 OUT EFI_FILE_PROTOCOL
**NewHandle
,
174 PRIVATE_UDF_FILE_DATA
*PrivFileData
;
175 PRIVATE_UDF_SIMPLE_FS_DATA
*PrivFsData
;
176 CHAR16 FilePath
[UDF_PATH_LENGTH
];
178 PRIVATE_UDF_FILE_DATA
*NewPrivFileData
;
179 CHAR16
*TempFileName
;
181 ZeroMem (FilePath
, sizeof FilePath
);
182 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
184 if ((This
== NULL
) || (NewHandle
== NULL
) || (FileName
== NULL
)) {
185 Status
= EFI_INVALID_PARAMETER
;
186 goto Error_Invalid_Params
;
189 if (OpenMode
!= EFI_FILE_MODE_READ
) {
190 Status
= EFI_WRITE_PROTECTED
;
191 goto Error_Invalid_Params
;
194 PrivFileData
= PRIVATE_UDF_FILE_DATA_FROM_THIS (This
);
196 PrivFsData
= PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData
->SimpleFs
);
201 if (*FileName
== L
'\\') {
202 StrCpyS (FilePath
, UDF_PATH_LENGTH
, FileName
);
204 StrCpyS (FilePath
, UDF_PATH_LENGTH
, PrivFileData
->AbsoluteFileName
);
205 StrCatS (FilePath
, UDF_PATH_LENGTH
, L
"\\");
206 StrCatS (FilePath
, UDF_PATH_LENGTH
, FileName
);
209 MangleFileName (FilePath
);
210 if (FilePath
[0] == L
'\0') {
211 Status
= EFI_NOT_FOUND
;
212 goto Error_Bad_FileName
;
220 _ROOT_FILE (PrivFileData
),
221 _PARENT_FILE (PrivFileData
),
222 &_PARENT_FILE (PrivFileData
)->FileIdentifierDesc
->Icb
,
225 if (EFI_ERROR (Status
)) {
226 goto Error_Find_File
;
230 (PRIVATE_UDF_FILE_DATA
*)AllocateZeroPool (sizeof (PRIVATE_UDF_FILE_DATA
));
231 if (NewPrivFileData
== NULL
) {
232 Status
= EFI_OUT_OF_RESOURCES
;
233 goto Error_Alloc_New_Priv_File_Data
;
237 (VOID
*)NewPrivFileData
,
238 (VOID
*)PrivFileData
,
239 sizeof (PRIVATE_UDF_FILE_DATA
)
241 CopyMem ((VOID
*)&NewPrivFileData
->File
, &File
, sizeof (UDF_FILE_INFO
));
243 NewPrivFileData
->IsRootDirectory
= FALSE
;
245 StrCpyS (NewPrivFileData
->AbsoluteFileName
, UDF_PATH_LENGTH
, FilePath
);
246 FileName
= NewPrivFileData
->AbsoluteFileName
;
248 while ((TempFileName
= StrStr (FileName
, L
"\\")) != NULL
) {
249 FileName
= TempFileName
+ 1;
252 StrCpyS (NewPrivFileData
->FileName
, UDF_FILENAME_LENGTH
, FileName
);
254 Status
= GetFileSize (
258 &NewPrivFileData
->File
,
259 &NewPrivFileData
->FileSize
261 if (EFI_ERROR (Status
)) {
264 "%a: GetFileSize() fails with status - %r.\n",
268 goto Error_Get_File_Size
;
271 NewPrivFileData
->FilePosition
= 0;
273 (VOID
*)&NewPrivFileData
->ReadDirInfo
,
274 sizeof (UDF_READ_DIRECTORY_INFO
)
277 *NewHandle
= &NewPrivFileData
->FileIo
;
279 PrivFsData
->OpenFiles
++;
281 gBS
->RestoreTPL (OldTpl
);
286 FreePool ((VOID
*)NewPrivFileData
);
288 Error_Alloc_New_Priv_File_Data
:
289 CleanupFileInformation (&File
);
293 Error_Invalid_Params
:
294 gBS
->RestoreTPL (OldTpl
);
300 Read data from the file.
302 @param This Protocol instance pointer.
303 @param BufferSize On input size of buffer, on output amount of data in
305 @param Buffer The buffer in which data is read.
307 @retval EFI_SUCCESS Data was read.
308 @retval EFI_NO_MEDIA The device has no media.
309 @retval EFI_DEVICE_ERROR The device reported an error.
310 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
311 @retval EFI_BUFFER_TO_SMALL BufferSize is too small. BufferSize contains
318 IN EFI_FILE_PROTOCOL
*This
,
319 IN OUT UINTN
*BufferSize
,
325 PRIVATE_UDF_FILE_DATA
*PrivFileData
;
326 PRIVATE_UDF_SIMPLE_FS_DATA
*PrivFsData
;
327 UDF_VOLUME_INFO
*Volume
;
328 UDF_FILE_INFO
*Parent
;
329 UDF_READ_DIRECTORY_INFO
*ReadDirInfo
;
330 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
331 EFI_DISK_IO_PROTOCOL
*DiskIo
;
332 UDF_FILE_INFO FoundFile
;
333 UDF_FILE_IDENTIFIER_DESCRIPTOR
*NewFileIdentifierDesc
;
334 VOID
*NewFileEntryData
;
335 CHAR16 FileName
[UDF_FILENAME_LENGTH
];
337 UINT64 BufferSizeUint64
;
339 ZeroMem (FileName
, sizeof FileName
);
340 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
342 if ((This
== NULL
) || (BufferSize
== NULL
) || ((*BufferSize
!= 0) &&
345 Status
= EFI_INVALID_PARAMETER
;
346 goto Error_Invalid_Params
;
349 PrivFileData
= PRIVATE_UDF_FILE_DATA_FROM_THIS (This
);
350 PrivFsData
= PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData
->SimpleFs
);
352 BlockIo
= PrivFsData
->BlockIo
;
353 DiskIo
= PrivFsData
->DiskIo
;
354 Volume
= &PrivFsData
->Volume
;
355 ReadDirInfo
= &PrivFileData
->ReadDirInfo
;
356 NewFileIdentifierDesc
= NULL
;
357 NewFileEntryData
= NULL
;
359 Parent
= _PARENT_FILE (PrivFileData
);
361 Status
= EFI_VOLUME_CORRUPTED
;
363 if (IS_FID_NORMAL_FILE (Parent
->FileIdentifierDesc
)) {
364 if (PrivFileData
->FilePosition
> PrivFileData
->FileSize
) {
366 // File's position is beyond the EOF
368 Status
= EFI_DEVICE_ERROR
;
369 goto Error_File_Beyond_The_Eof
;
372 if (PrivFileData
->FilePosition
== PrivFileData
->FileSize
) {
374 Status
= EFI_SUCCESS
;
378 BufferSizeUint64
= *BufferSize
;
380 Status
= ReadFileData (
385 PrivFileData
->FileSize
,
386 &PrivFileData
->FilePosition
,
390 ASSERT (BufferSizeUint64
<= MAX_UINTN
);
391 *BufferSize
= (UINTN
)BufferSizeUint64
;
392 } else if (IS_FID_DIRECTORY_FILE (Parent
->FileIdentifierDesc
)) {
393 if ((ReadDirInfo
->FidOffset
== 0) && (PrivFileData
->FilePosition
> 0)) {
394 Status
= EFI_DEVICE_ERROR
;
400 Status
= ReadDirectoryEntry (
404 &Parent
->FileIdentifierDesc
->Icb
,
407 &NewFileIdentifierDesc
409 if (EFI_ERROR (Status
)) {
410 if (Status
== EFI_DEVICE_ERROR
) {
411 FreePool (ReadDirInfo
->DirectoryData
);
412 ZeroMem ((VOID
*)ReadDirInfo
, sizeof (UDF_READ_DIRECTORY_INFO
));
415 Status
= EFI_SUCCESS
;
422 // After calling function ReadDirectoryEntry(), if 'NewFileIdentifierDesc'
423 // is NULL, then the 'Status' must be EFI_OUT_OF_RESOURCES. Hence, if the
424 // code reaches here, 'NewFileIdentifierDesc' must be not NULL.
426 // The ASSERT here is for addressing a false positive NULL pointer
427 // dereference issue raised from static analysis.
429 ASSERT (NewFileIdentifierDesc
!= NULL
);
431 if (!IS_FID_PARENT_FILE (NewFileIdentifierDesc
)) {
435 FreePool ((VOID
*)NewFileIdentifierDesc
);
438 Status
= FindFileEntry (
442 &NewFileIdentifierDesc
->Icb
,
445 if (EFI_ERROR (Status
)) {
449 ASSERT (NewFileEntryData
!= NULL
);
451 if (FE_ICB_FILE_TYPE (NewFileEntryData
) == UdfFileEntrySymlink
) {
452 Status
= ResolveSymlink (
460 if (EFI_ERROR (Status
)) {
461 goto Error_Resolve_Symlink
;
464 FreePool ((VOID
*)NewFileEntryData
);
465 NewFileEntryData
= FoundFile
.FileEntry
;
467 Status
= GetFileNameFromFid (NewFileIdentifierDesc
, ARRAY_SIZE (FileName
), FileName
);
468 if (EFI_ERROR (Status
)) {
469 FreePool ((VOID
*)FoundFile
.FileIdentifierDesc
);
470 goto Error_Get_FileName
;
473 FreePool ((VOID
*)NewFileIdentifierDesc
);
474 NewFileIdentifierDesc
= FoundFile
.FileIdentifierDesc
;
476 FoundFile
.FileIdentifierDesc
= NewFileIdentifierDesc
;
477 FoundFile
.FileEntry
= NewFileEntryData
;
479 Status
= GetFileNameFromFid (FoundFile
.FileIdentifierDesc
, ARRAY_SIZE (FileName
), FileName
);
480 if (EFI_ERROR (Status
)) {
481 goto Error_Get_FileName
;
485 Status
= GetFileSize (
492 if (EFI_ERROR (Status
)) {
493 goto Error_Get_File_Size
;
496 Status
= SetFileInfo (
503 if (EFI_ERROR (Status
)) {
504 goto Error_Set_File_Info
;
507 PrivFileData
->FilePosition
++;
508 Status
= EFI_SUCCESS
;
509 } else if (IS_FID_DELETED_FILE (Parent
->FileIdentifierDesc
)) {
511 // Code should never reach here.
514 Status
= EFI_DEVICE_ERROR
;
520 Error_Resolve_Symlink
:
521 if (NewFileEntryData
!= NULL
) {
522 FreePool (NewFileEntryData
);
526 if (NewFileIdentifierDesc
!= NULL
) {
527 FreePool ((VOID
*)NewFileIdentifierDesc
);
531 Error_File_Beyond_The_Eof
:
532 Error_Invalid_Params
:
533 gBS
->RestoreTPL (OldTpl
);
539 Close the file handle.
541 @param This Protocol instance pointer.
543 @retval EFI_SUCCESS The file was closed.
549 IN EFI_FILE_PROTOCOL
*This
554 PRIVATE_UDF_FILE_DATA
*PrivFileData
;
556 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
558 Status
= EFI_SUCCESS
;
561 Status
= EFI_INVALID_PARAMETER
;
565 PrivFileData
= PRIVATE_UDF_FILE_DATA_FROM_THIS (This
);
567 if (!PrivFileData
->IsRootDirectory
) {
568 CleanupFileInformation (&PrivFileData
->File
);
570 if (PrivFileData
->ReadDirInfo
.DirectoryData
!= NULL
) {
571 FreePool (PrivFileData
->ReadDirInfo
.DirectoryData
);
575 FreePool ((VOID
*)PrivFileData
);
578 gBS
->RestoreTPL (OldTpl
);
584 Close and delete the file handle.
586 @param This Protocol instance pointer.
588 @retval EFI_SUCCESS The file was closed and deleted.
589 @retval EFI_WARN_DELETE_FAILURE The handle was closed but the file was not
596 IN EFI_FILE_PROTOCOL
*This
599 PRIVATE_UDF_FILE_DATA
*PrivFileData
;
602 return EFI_INVALID_PARAMETER
;
605 PrivFileData
= PRIVATE_UDF_FILE_DATA_FROM_THIS (This
);
607 (VOID
)PrivFileData
->FileIo
.Close (This
);
609 return EFI_WARN_DELETE_FAILURE
;
613 Write data to a file.
615 @param This Protocol instance pointer.
616 @param BufferSize On input size of buffer, on output amount of data in
618 @param Buffer The buffer in which data to write.
620 @retval EFI_SUCCESS Data was written.
621 @retval EFI_UNSUPPORTED Writes to Open directory are not supported.
622 @retval EFI_NO_MEDIA The device has no media.
623 @retval EFI_DEVICE_ERROR The device reported an error.
624 @retval EFI_DEVICE_ERROR An attempt was made to write to a deleted file.
625 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
626 @retval EFI_WRITE_PROTECTED The device is write protected.
627 @retval EFI_ACCESS_DENIED The file was open for read only.
628 @retval EFI_VOLUME_FULL The volume is full.
634 IN EFI_FILE_PROTOCOL
*This
,
635 IN OUT UINTN
*BufferSize
,
639 return EFI_UNSUPPORTED
;
643 Get file's current position.
645 @param This Protocol instance pointer.
646 @param Position Byte position from the start of the file.
648 @retval EFI_SUCCESS Position was updated.
649 @retval EFI_UNSUPPORTED Seek request for directories is not valid.
655 IN EFI_FILE_PROTOCOL
*This
,
659 PRIVATE_UDF_FILE_DATA
*PrivFileData
;
661 if ((This
== NULL
) || (Position
== NULL
)) {
662 return EFI_INVALID_PARAMETER
;
665 PrivFileData
= PRIVATE_UDF_FILE_DATA_FROM_THIS (This
);
668 // As per UEFI spec, if the file handle is a directory, then the current file
669 // position has no meaning and the operation is not supported.
671 if (IS_FID_DIRECTORY_FILE (PrivFileData
->File
.FileIdentifierDesc
)) {
672 return EFI_UNSUPPORTED
;
676 // The file is not a directory. So, return its position.
678 *Position
= PrivFileData
->FilePosition
;
684 Set file's current position.
686 @param This Protocol instance pointer.
687 @param Position Byte position from the start of the file.
689 @retval EFI_SUCCESS Position was updated.
690 @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open.
696 IN EFI_FILE_PROTOCOL
*This
,
701 PRIVATE_UDF_FILE_DATA
*PrivFileData
;
702 UDF_FILE_IDENTIFIER_DESCRIPTOR
*FileIdentifierDesc
;
705 return EFI_INVALID_PARAMETER
;
708 Status
= EFI_UNSUPPORTED
;
710 PrivFileData
= PRIVATE_UDF_FILE_DATA_FROM_THIS (This
);
712 FileIdentifierDesc
= _FILE (PrivFileData
)->FileIdentifierDesc
;
713 ASSERT (FileIdentifierDesc
!= NULL
);
714 if (IS_FID_DIRECTORY_FILE (FileIdentifierDesc
)) {
716 // If the file handle is a directory, the _only_ position that may be set is
717 // zero. This has no effect of starting the read proccess of the directory
721 PrivFileData
->FilePosition
= Position
;
722 PrivFileData
->ReadDirInfo
.FidOffset
= 0;
723 Status
= EFI_SUCCESS
;
725 } else if (IS_FID_NORMAL_FILE (FileIdentifierDesc
)) {
727 // Seeking to position 0xFFFFFFFFFFFFFFFF causes the current position to be
730 if (Position
== 0xFFFFFFFFFFFFFFFF) {
731 PrivFileData
->FilePosition
= PrivFileData
->FileSize
;
733 PrivFileData
->FilePosition
= Position
;
736 Status
= EFI_SUCCESS
;
743 Get information about a file.
745 @param This Protocol instance pointer.
746 @param InformationType Type of information to return in Buffer.
747 @param BufferSize On input size of buffer, on output amount of data in
749 @param Buffer The buffer to return data.
751 @retval EFI_SUCCESS Data was returned.
752 @retval EFI_UNSUPPORTED InformationType is not supported.
753 @retval EFI_NO_MEDIA The device has no media.
754 @retval EFI_DEVICE_ERROR The device reported an error.
755 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
756 @retval EFI_WRITE_PROTECTED The device is write protected.
757 @retval EFI_ACCESS_DENIED The file was open for read only.
758 @retval EFI_BUFFER_TOO_SMALL Buffer was too small; required size returned in
765 IN EFI_FILE_PROTOCOL
*This
,
766 IN EFI_GUID
*InformationType
,
767 IN OUT UINTN
*BufferSize
,
772 PRIVATE_UDF_FILE_DATA
*PrivFileData
;
773 PRIVATE_UDF_SIMPLE_FS_DATA
*PrivFsData
;
774 EFI_FILE_SYSTEM_INFO
*FileSystemInfo
;
775 UINTN FileSystemInfoLength
;
777 UINT64 FreeSpaceSize
;
778 EFI_FILE_SYSTEM_VOLUME_LABEL
*FileSystemVolumeLabel
;
779 UINTN FileSystemVolumeLabelLength
;
780 CHAR16 VolumeLabel
[64];
782 if ((This
== NULL
) || (InformationType
== NULL
) || (BufferSize
== NULL
) ||
783 ((*BufferSize
!= 0) && (Buffer
== NULL
)))
785 return EFI_INVALID_PARAMETER
;
788 PrivFileData
= PRIVATE_UDF_FILE_DATA_FROM_THIS (This
);
790 PrivFsData
= PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData
->SimpleFs
);
792 Status
= EFI_UNSUPPORTED
;
794 if (CompareGuid (InformationType
, &gEfiFileInfoGuid
)) {
795 Status
= SetFileInfo (
796 _FILE (PrivFileData
),
797 PrivFileData
->FileSize
,
798 PrivFileData
->FileName
,
802 } else if (CompareGuid (InformationType
, &gEfiFileSystemInfoGuid
)) {
803 Status
= GetVolumeLabel (&PrivFsData
->Volume
, ARRAY_SIZE (VolumeLabel
), VolumeLabel
);
804 if (EFI_ERROR (Status
)) {
808 FileSystemInfoLength
= StrSize (VolumeLabel
) +
809 sizeof (EFI_FILE_SYSTEM_INFO
);
810 if (*BufferSize
< FileSystemInfoLength
) {
811 *BufferSize
= FileSystemInfoLength
;
812 return EFI_BUFFER_TOO_SMALL
;
815 FileSystemInfo
= (EFI_FILE_SYSTEM_INFO
*)Buffer
;
817 FileSystemInfo
->VolumeLabel
,
818 (*BufferSize
- SIZE_OF_EFI_FILE_SYSTEM_INFO
) / sizeof (CHAR16
),
821 Status
= GetVolumeSize (
828 if (EFI_ERROR (Status
)) {
832 FileSystemInfo
->Size
= FileSystemInfoLength
;
833 FileSystemInfo
->ReadOnly
= TRUE
;
834 FileSystemInfo
->BlockSize
=
835 PrivFsData
->Volume
.LogicalVolDesc
.LogicalBlockSize
;
836 FileSystemInfo
->VolumeSize
= VolumeSize
;
837 FileSystemInfo
->FreeSpace
= FreeSpaceSize
;
839 *BufferSize
= FileSystemInfoLength
;
840 Status
= EFI_SUCCESS
;
841 } else if (CompareGuid (InformationType
, &gEfiFileSystemVolumeLabelInfoIdGuid
)) {
842 Status
= GetVolumeLabel (&PrivFsData
->Volume
, ARRAY_SIZE (VolumeLabel
), VolumeLabel
);
843 if (EFI_ERROR (Status
)) {
847 FileSystemVolumeLabelLength
= StrSize (VolumeLabel
) +
848 sizeof (EFI_FILE_SYSTEM_VOLUME_LABEL
);
849 if (*BufferSize
< FileSystemVolumeLabelLength
) {
850 *BufferSize
= FileSystemVolumeLabelLength
;
851 return EFI_BUFFER_TOO_SMALL
;
854 FileSystemVolumeLabel
= (EFI_FILE_SYSTEM_VOLUME_LABEL
*)Buffer
;
856 FileSystemVolumeLabel
->VolumeLabel
,
857 (*BufferSize
- SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL
) / sizeof (CHAR16
),
860 Status
= EFI_SUCCESS
;
867 Set information about a file.
869 @param This Protocol instance pointer.
870 @param InformationType Type of information in Buffer.
871 @param BufferSize Size of buffer.
872 @param Buffer The data to write.
874 @retval EFI_SUCCESS Data was set.
875 @retval EFI_UNSUPPORTED InformationType is not supported.
876 @retval EFI_NO_MEDIA The device has no media.
877 @retval EFI_DEVICE_ERROR The device reported an error.
878 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
879 @retval EFI_WRITE_PROTECTED The device is write protected.
880 @retval EFI_ACCESS_DENIED The file was open for read only.
886 IN EFI_FILE_PROTOCOL
*This
,
887 IN EFI_GUID
*InformationType
,
892 return EFI_WRITE_PROTECTED
;
896 Flush data back for the file handle.
898 @param This Protocol instance pointer.
900 @retval EFI_SUCCESS Data was flushed.
901 @retval EFI_UNSUPPORTED Writes to Open directory are not supported.
902 @retval EFI_NO_MEDIA The device has no media.
903 @retval EFI_DEVICE_ERROR The device reported an error.
904 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
905 @retval EFI_WRITE_PROTECTED The device is write protected.
906 @retval EFI_ACCESS_DENIED The file was open for read only.
907 @retval EFI_VOLUME_FULL The volume is full.
913 IN EFI_FILE_PROTOCOL
*This
916 return EFI_WRITE_PROTECTED
;