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
;
114 CopyMem ((VOID
*)&PrivFileData
->FileIo
, (VOID
*)&gUdfFileIoOps
,
115 sizeof (EFI_FILE_PROTOCOL
));
117 *Root
= &PrivFileData
->FileIo
;
119 PrivFsData
->OpenFiles
++;
121 gBS
->RestoreTPL (OldTpl
);
125 Error_Alloc_Priv_File_Data
:
126 CleanupFileInformation (&PrivFsData
->Root
);
130 Error_Read_Udf_Volume
:
131 Error_Invalid_Params
:
132 gBS
->RestoreTPL (OldTpl
);
138 Opens a new file relative to the source file's location.
140 @param This The protocol instance pointer.
141 @param NewHandle Returns File Handle for FileName.
142 @param FileName Null terminated string. "\", ".", and ".." are supported.
143 @param OpenMode Open mode for file.
144 @param Attributes Only used for EFI_FILE_MODE_CREATE.
146 @retval EFI_SUCCESS The device was opened.
147 @retval EFI_NOT_FOUND The specified file could not be found on the
149 @retval EFI_NO_MEDIA The device has no media.
150 @retval EFI_MEDIA_CHANGED The media has changed.
151 @retval EFI_DEVICE_ERROR The device reported an error.
152 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
153 @retval EFI_ACCESS_DENIED The service denied access to the file.
154 @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of
156 @retval EFI_VOLUME_FULL The volume is full.
162 IN EFI_FILE_PROTOCOL
*This
,
163 OUT EFI_FILE_PROTOCOL
**NewHandle
,
171 PRIVATE_UDF_FILE_DATA
*PrivFileData
;
172 PRIVATE_UDF_SIMPLE_FS_DATA
*PrivFsData
;
173 CHAR16 FilePath
[UDF_PATH_LENGTH
];
175 PRIVATE_UDF_FILE_DATA
*NewPrivFileData
;
176 CHAR16
*TempFileName
;
178 ZeroMem (FilePath
, sizeof FilePath
);
179 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
181 if (This
== NULL
|| NewHandle
== NULL
|| FileName
== NULL
) {
182 Status
= EFI_INVALID_PARAMETER
;
183 goto Error_Invalid_Params
;
186 if (OpenMode
!= EFI_FILE_MODE_READ
) {
187 Status
= EFI_WRITE_PROTECTED
;
188 goto Error_Invalid_Params
;
191 PrivFileData
= PRIVATE_UDF_FILE_DATA_FROM_THIS (This
);
193 PrivFsData
= PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData
->SimpleFs
);
198 if (*FileName
== L
'\\') {
199 StrCpyS (FilePath
, UDF_PATH_LENGTH
, FileName
);
201 StrCpyS (FilePath
, UDF_PATH_LENGTH
, PrivFileData
->AbsoluteFileName
);
202 StrCatS (FilePath
, UDF_PATH_LENGTH
, L
"\\");
203 StrCatS (FilePath
, UDF_PATH_LENGTH
, FileName
);
206 MangleFileName (FilePath
);
207 if (FilePath
[0] == L
'\0') {
208 Status
= EFI_NOT_FOUND
;
209 goto Error_Bad_FileName
;
217 _ROOT_FILE (PrivFileData
),
218 _PARENT_FILE (PrivFileData
),
219 &_PARENT_FILE(PrivFileData
)->FileIdentifierDesc
->Icb
,
222 if (EFI_ERROR (Status
)) {
223 goto Error_Find_File
;
227 (PRIVATE_UDF_FILE_DATA
*)AllocateZeroPool (sizeof (PRIVATE_UDF_FILE_DATA
));
228 if (NewPrivFileData
== NULL
) {
229 Status
= EFI_OUT_OF_RESOURCES
;
230 goto Error_Alloc_New_Priv_File_Data
;
233 CopyMem ((VOID
*)NewPrivFileData
, (VOID
*)PrivFileData
,
234 sizeof (PRIVATE_UDF_FILE_DATA
));
235 CopyMem ((VOID
*)&NewPrivFileData
->File
, &File
, sizeof (UDF_FILE_INFO
));
237 NewPrivFileData
->IsRootDirectory
= FALSE
;
239 StrCpyS (NewPrivFileData
->AbsoluteFileName
, UDF_PATH_LENGTH
, FilePath
);
240 FileName
= NewPrivFileData
->AbsoluteFileName
;
242 while ((TempFileName
= StrStr (FileName
, L
"\\")) != NULL
) {
243 FileName
= TempFileName
+ 1;
246 StrCpyS (NewPrivFileData
->FileName
, UDF_FILENAME_LENGTH
, FileName
);
248 Status
= GetFileSize (
252 &NewPrivFileData
->File
,
253 &NewPrivFileData
->FileSize
255 if (EFI_ERROR (Status
)) {
258 "%a: GetFileSize() fails with status - %r.\n",
261 goto Error_Get_File_Size
;
264 NewPrivFileData
->FilePosition
= 0;
265 ZeroMem ((VOID
*)&NewPrivFileData
->ReadDirInfo
,
266 sizeof (UDF_READ_DIRECTORY_INFO
));
268 *NewHandle
= &NewPrivFileData
->FileIo
;
270 PrivFsData
->OpenFiles
++;
272 gBS
->RestoreTPL (OldTpl
);
277 FreePool ((VOID
*)NewPrivFileData
);
279 Error_Alloc_New_Priv_File_Data
:
280 CleanupFileInformation (&File
);
284 Error_Invalid_Params
:
285 gBS
->RestoreTPL (OldTpl
);
291 Read data from the file.
293 @param This Protocol instance pointer.
294 @param BufferSize On input size of buffer, on output amount of data in
296 @param Buffer The buffer in which data is read.
298 @retval EFI_SUCCESS Data was read.
299 @retval EFI_NO_MEDIA The device has no media.
300 @retval EFI_DEVICE_ERROR The device reported an error.
301 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
302 @retval EFI_BUFFER_TO_SMALL BufferSize is too small. BufferSize contains
309 IN EFI_FILE_PROTOCOL
*This
,
310 IN OUT UINTN
*BufferSize
,
316 PRIVATE_UDF_FILE_DATA
*PrivFileData
;
317 PRIVATE_UDF_SIMPLE_FS_DATA
*PrivFsData
;
318 UDF_VOLUME_INFO
*Volume
;
319 UDF_FILE_INFO
*Parent
;
320 UDF_READ_DIRECTORY_INFO
*ReadDirInfo
;
321 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
322 EFI_DISK_IO_PROTOCOL
*DiskIo
;
323 UDF_FILE_INFO FoundFile
;
324 UDF_FILE_IDENTIFIER_DESCRIPTOR
*NewFileIdentifierDesc
;
325 VOID
*NewFileEntryData
;
326 CHAR16 FileName
[UDF_FILENAME_LENGTH
];
328 UINT64 BufferSizeUint64
;
330 ZeroMem (FileName
, sizeof FileName
);
331 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
333 if (This
== NULL
|| BufferSize
== NULL
|| (*BufferSize
!= 0 &&
335 Status
= EFI_INVALID_PARAMETER
;
336 goto Error_Invalid_Params
;
339 PrivFileData
= PRIVATE_UDF_FILE_DATA_FROM_THIS (This
);
340 PrivFsData
= PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData
->SimpleFs
);
342 BlockIo
= PrivFsData
->BlockIo
;
343 DiskIo
= PrivFsData
->DiskIo
;
344 Volume
= &PrivFsData
->Volume
;
345 ReadDirInfo
= &PrivFileData
->ReadDirInfo
;
346 NewFileIdentifierDesc
= NULL
;
347 NewFileEntryData
= NULL
;
349 Parent
= _PARENT_FILE (PrivFileData
);
351 Status
= EFI_VOLUME_CORRUPTED
;
353 if (IS_FID_NORMAL_FILE (Parent
->FileIdentifierDesc
)) {
354 if (PrivFileData
->FilePosition
> PrivFileData
->FileSize
) {
356 // File's position is beyond the EOF
358 Status
= EFI_DEVICE_ERROR
;
359 goto Error_File_Beyond_The_Eof
;
362 if (PrivFileData
->FilePosition
== PrivFileData
->FileSize
) {
364 Status
= EFI_SUCCESS
;
368 BufferSizeUint64
= *BufferSize
;
370 Status
= ReadFileData (
375 PrivFileData
->FileSize
,
376 &PrivFileData
->FilePosition
,
380 ASSERT (BufferSizeUint64
<= MAX_UINTN
);
381 *BufferSize
= (UINTN
)BufferSizeUint64
;
382 } else if (IS_FID_DIRECTORY_FILE (Parent
->FileIdentifierDesc
)) {
383 if (ReadDirInfo
->FidOffset
== 0 && PrivFileData
->FilePosition
> 0) {
384 Status
= EFI_DEVICE_ERROR
;
390 Status
= ReadDirectoryEntry (
394 &Parent
->FileIdentifierDesc
->Icb
,
397 &NewFileIdentifierDesc
399 if (EFI_ERROR (Status
)) {
400 if (Status
== EFI_DEVICE_ERROR
) {
401 FreePool (ReadDirInfo
->DirectoryData
);
402 ZeroMem ((VOID
*)ReadDirInfo
, sizeof (UDF_READ_DIRECTORY_INFO
));
405 Status
= EFI_SUCCESS
;
411 // After calling function ReadDirectoryEntry(), if 'NewFileIdentifierDesc'
412 // is NULL, then the 'Status' must be EFI_OUT_OF_RESOURCES. Hence, if the
413 // code reaches here, 'NewFileIdentifierDesc' must be not NULL.
415 // The ASSERT here is for addressing a false positive NULL pointer
416 // dereference issue raised from static analysis.
418 ASSERT (NewFileIdentifierDesc
!= NULL
);
420 if (!IS_FID_PARENT_FILE (NewFileIdentifierDesc
)) {
424 FreePool ((VOID
*)NewFileIdentifierDesc
);
427 Status
= FindFileEntry (
431 &NewFileIdentifierDesc
->Icb
,
434 if (EFI_ERROR (Status
)) {
437 ASSERT (NewFileEntryData
!= NULL
);
439 if (FE_ICB_FILE_TYPE (NewFileEntryData
) == UdfFileEntrySymlink
) {
440 Status
= ResolveSymlink (
448 if (EFI_ERROR (Status
)) {
449 goto Error_Resolve_Symlink
;
452 FreePool ((VOID
*)NewFileEntryData
);
453 NewFileEntryData
= FoundFile
.FileEntry
;
455 Status
= GetFileNameFromFid (NewFileIdentifierDesc
, ARRAY_SIZE (FileName
), FileName
);
456 if (EFI_ERROR (Status
)) {
457 FreePool ((VOID
*)FoundFile
.FileIdentifierDesc
);
458 goto Error_Get_FileName
;
461 FreePool ((VOID
*)NewFileIdentifierDesc
);
462 NewFileIdentifierDesc
= FoundFile
.FileIdentifierDesc
;
464 FoundFile
.FileIdentifierDesc
= NewFileIdentifierDesc
;
465 FoundFile
.FileEntry
= NewFileEntryData
;
467 Status
= GetFileNameFromFid (FoundFile
.FileIdentifierDesc
, ARRAY_SIZE (FileName
), FileName
);
468 if (EFI_ERROR (Status
)) {
469 goto Error_Get_FileName
;
473 Status
= GetFileSize (
480 if (EFI_ERROR (Status
)) {
481 goto Error_Get_File_Size
;
484 Status
= SetFileInfo (
491 if (EFI_ERROR (Status
)) {
492 goto Error_Set_File_Info
;
495 PrivFileData
->FilePosition
++;
496 Status
= EFI_SUCCESS
;
497 } else if (IS_FID_DELETED_FILE (Parent
->FileIdentifierDesc
)) {
499 // Code should never reach here.
502 Status
= EFI_DEVICE_ERROR
;
508 Error_Resolve_Symlink
:
509 if (NewFileEntryData
!= NULL
) {
510 FreePool (NewFileEntryData
);
514 if (NewFileIdentifierDesc
!= NULL
) {
515 FreePool ((VOID
*)NewFileIdentifierDesc
);
519 Error_File_Beyond_The_Eof
:
520 Error_Invalid_Params
:
521 gBS
->RestoreTPL (OldTpl
);
527 Close the file handle.
529 @param This Protocol instance pointer.
531 @retval EFI_SUCCESS The file was closed.
537 IN EFI_FILE_PROTOCOL
*This
542 PRIVATE_UDF_FILE_DATA
*PrivFileData
;
544 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
546 Status
= EFI_SUCCESS
;
549 Status
= EFI_INVALID_PARAMETER
;
553 PrivFileData
= PRIVATE_UDF_FILE_DATA_FROM_THIS (This
);
555 if (!PrivFileData
->IsRootDirectory
) {
556 CleanupFileInformation (&PrivFileData
->File
);
558 if (PrivFileData
->ReadDirInfo
.DirectoryData
!= NULL
) {
559 FreePool (PrivFileData
->ReadDirInfo
.DirectoryData
);
563 FreePool ((VOID
*)PrivFileData
);
566 gBS
->RestoreTPL (OldTpl
);
572 Close and delete the file handle.
574 @param This Protocol instance pointer.
576 @retval EFI_SUCCESS The file was closed and deleted.
577 @retval EFI_WARN_DELETE_FAILURE The handle was closed but the file was not
584 IN EFI_FILE_PROTOCOL
*This
587 PRIVATE_UDF_FILE_DATA
*PrivFileData
;
590 return EFI_INVALID_PARAMETER
;
593 PrivFileData
= PRIVATE_UDF_FILE_DATA_FROM_THIS (This
);
595 (VOID
)PrivFileData
->FileIo
.Close(This
);
597 return EFI_WARN_DELETE_FAILURE
;
601 Write data to a file.
603 @param This Protocol instance pointer.
604 @param BufferSize On input size of buffer, on output amount of data in
606 @param Buffer The buffer in which data to write.
608 @retval EFI_SUCCESS Data was written.
609 @retval EFI_UNSUPPORTED Writes to Open directory are not supported.
610 @retval EFI_NO_MEDIA The device has no media.
611 @retval EFI_DEVICE_ERROR The device reported an error.
612 @retval EFI_DEVICE_ERROR An attempt was made to write to a deleted file.
613 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
614 @retval EFI_WRITE_PROTECTED The device is write protected.
615 @retval EFI_ACCESS_DENIED The file was open for read only.
616 @retval EFI_VOLUME_FULL The volume is full.
622 IN EFI_FILE_PROTOCOL
*This
,
623 IN OUT UINTN
*BufferSize
,
627 return EFI_UNSUPPORTED
;
631 Get file's current position.
633 @param This Protocol instance pointer.
634 @param Position Byte position from the start of the file.
636 @retval EFI_SUCCESS Position was updated.
637 @retval EFI_UNSUPPORTED Seek request for directories is not valid.
643 IN EFI_FILE_PROTOCOL
*This
,
647 PRIVATE_UDF_FILE_DATA
*PrivFileData
;
649 if (This
== NULL
|| Position
== NULL
) {
650 return EFI_INVALID_PARAMETER
;
653 PrivFileData
= PRIVATE_UDF_FILE_DATA_FROM_THIS (This
);
656 // As per UEFI spec, if the file handle is a directory, then the current file
657 // position has no meaning and the operation is not supported.
659 if (IS_FID_DIRECTORY_FILE (PrivFileData
->File
.FileIdentifierDesc
)) {
660 return EFI_UNSUPPORTED
;
664 // The file is not a directory. So, return its position.
666 *Position
= PrivFileData
->FilePosition
;
672 Set file's current position.
674 @param This Protocol instance pointer.
675 @param Position Byte position from the start of the file.
677 @retval EFI_SUCCESS Position was updated.
678 @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open.
684 IN EFI_FILE_PROTOCOL
*This
,
689 PRIVATE_UDF_FILE_DATA
*PrivFileData
;
690 UDF_FILE_IDENTIFIER_DESCRIPTOR
*FileIdentifierDesc
;
693 return EFI_INVALID_PARAMETER
;
696 Status
= EFI_UNSUPPORTED
;
698 PrivFileData
= PRIVATE_UDF_FILE_DATA_FROM_THIS (This
);
700 FileIdentifierDesc
= _FILE (PrivFileData
)->FileIdentifierDesc
;
701 ASSERT (FileIdentifierDesc
!= NULL
);
702 if (IS_FID_DIRECTORY_FILE (FileIdentifierDesc
)) {
704 // If the file handle is a directory, the _only_ position that may be set is
705 // zero. This has no effect of starting the read proccess of the directory
709 PrivFileData
->FilePosition
= Position
;
710 PrivFileData
->ReadDirInfo
.FidOffset
= 0;
711 Status
= EFI_SUCCESS
;
713 } else if (IS_FID_NORMAL_FILE (FileIdentifierDesc
)) {
715 // Seeking to position 0xFFFFFFFFFFFFFFFF causes the current position to be
718 if (Position
== 0xFFFFFFFFFFFFFFFF) {
719 PrivFileData
->FilePosition
= PrivFileData
->FileSize
;
721 PrivFileData
->FilePosition
= Position
;
724 Status
= EFI_SUCCESS
;
731 Get information about a file.
733 @param This Protocol instance pointer.
734 @param InformationType Type of information to return in Buffer.
735 @param BufferSize On input size of buffer, on output amount of data in
737 @param Buffer The buffer to return data.
739 @retval EFI_SUCCESS Data was returned.
740 @retval EFI_UNSUPPORTED InformationType is not supported.
741 @retval EFI_NO_MEDIA The device has no media.
742 @retval EFI_DEVICE_ERROR The device reported an error.
743 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
744 @retval EFI_WRITE_PROTECTED The device is write protected.
745 @retval EFI_ACCESS_DENIED The file was open for read only.
746 @retval EFI_BUFFER_TOO_SMALL Buffer was too small; required size returned in
753 IN EFI_FILE_PROTOCOL
*This
,
754 IN EFI_GUID
*InformationType
,
755 IN OUT UINTN
*BufferSize
,
760 PRIVATE_UDF_FILE_DATA
*PrivFileData
;
761 PRIVATE_UDF_SIMPLE_FS_DATA
*PrivFsData
;
762 EFI_FILE_SYSTEM_INFO
*FileSystemInfo
;
763 UINTN FileSystemInfoLength
;
765 UINT64 FreeSpaceSize
;
766 EFI_FILE_SYSTEM_VOLUME_LABEL
*FileSystemVolumeLabel
;
767 UINTN FileSystemVolumeLabelLength
;
768 CHAR16 VolumeLabel
[64];
770 if (This
== NULL
|| InformationType
== NULL
|| BufferSize
== NULL
||
771 (*BufferSize
!= 0 && Buffer
== NULL
)) {
772 return EFI_INVALID_PARAMETER
;
775 PrivFileData
= PRIVATE_UDF_FILE_DATA_FROM_THIS (This
);
777 PrivFsData
= PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData
->SimpleFs
);
779 Status
= EFI_UNSUPPORTED
;
781 if (CompareGuid (InformationType
, &gEfiFileInfoGuid
)) {
782 Status
= SetFileInfo (
783 _FILE (PrivFileData
),
784 PrivFileData
->FileSize
,
785 PrivFileData
->FileName
,
789 } else if (CompareGuid (InformationType
, &gEfiFileSystemInfoGuid
)) {
790 Status
= GetVolumeLabel (&PrivFsData
->Volume
, ARRAY_SIZE (VolumeLabel
), VolumeLabel
);
791 if (EFI_ERROR (Status
)) {
795 FileSystemInfoLength
= StrSize (VolumeLabel
) +
796 sizeof (EFI_FILE_SYSTEM_INFO
);
797 if (*BufferSize
< FileSystemInfoLength
) {
798 *BufferSize
= FileSystemInfoLength
;
799 return EFI_BUFFER_TOO_SMALL
;
802 FileSystemInfo
= (EFI_FILE_SYSTEM_INFO
*)Buffer
;
804 FileSystemInfo
->VolumeLabel
,
805 (*BufferSize
- SIZE_OF_EFI_FILE_SYSTEM_INFO
) / sizeof (CHAR16
),
808 Status
= GetVolumeSize (
815 if (EFI_ERROR (Status
)) {
819 FileSystemInfo
->Size
= FileSystemInfoLength
;
820 FileSystemInfo
->ReadOnly
= TRUE
;
821 FileSystemInfo
->BlockSize
=
822 PrivFsData
->Volume
.LogicalVolDesc
.LogicalBlockSize
;
823 FileSystemInfo
->VolumeSize
= VolumeSize
;
824 FileSystemInfo
->FreeSpace
= FreeSpaceSize
;
826 *BufferSize
= FileSystemInfoLength
;
827 Status
= EFI_SUCCESS
;
828 } else if (CompareGuid (InformationType
, &gEfiFileSystemVolumeLabelInfoIdGuid
)) {
829 Status
= GetVolumeLabel (&PrivFsData
->Volume
, ARRAY_SIZE (VolumeLabel
), VolumeLabel
);
830 if (EFI_ERROR (Status
)) {
834 FileSystemVolumeLabelLength
= StrSize (VolumeLabel
) +
835 sizeof (EFI_FILE_SYSTEM_VOLUME_LABEL
);
836 if (*BufferSize
< FileSystemVolumeLabelLength
) {
837 *BufferSize
= FileSystemVolumeLabelLength
;
838 return EFI_BUFFER_TOO_SMALL
;
841 FileSystemVolumeLabel
= (EFI_FILE_SYSTEM_VOLUME_LABEL
*)Buffer
;
843 FileSystemVolumeLabel
->VolumeLabel
,
844 (*BufferSize
- SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL
) / sizeof (CHAR16
),
847 Status
= EFI_SUCCESS
;
854 Set information about a file.
856 @param This Protocol instance pointer.
857 @param InformationType Type of information in Buffer.
858 @param BufferSize Size of buffer.
859 @param Buffer The data to write.
861 @retval EFI_SUCCESS Data was set.
862 @retval EFI_UNSUPPORTED InformationType is not supported.
863 @retval EFI_NO_MEDIA The device has no media.
864 @retval EFI_DEVICE_ERROR The device reported an error.
865 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
866 @retval EFI_WRITE_PROTECTED The device is write protected.
867 @retval EFI_ACCESS_DENIED The file was open for read only.
873 IN EFI_FILE_PROTOCOL
*This
,
874 IN EFI_GUID
*InformationType
,
879 return EFI_WRITE_PROTECTED
;
883 Flush data back for the file handle.
885 @param This Protocol instance pointer.
887 @retval EFI_SUCCESS Data was flushed.
888 @retval EFI_UNSUPPORTED Writes to Open directory are not supported.
889 @retval EFI_NO_MEDIA The device has no media.
890 @retval EFI_DEVICE_ERROR The device reported an error.
891 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
892 @retval EFI_WRITE_PROTECTED The device is write protected.
893 @retval EFI_ACCESS_DENIED The file was open for read only.
894 @retval EFI_VOLUME_FULL The volume is full.
900 IN EFI_FILE_PROTOCOL
*This
903 return EFI_WRITE_PROTECTED
;