2 Routines dealing with setting/getting file/volume info
4 Copyright (c) 2005 - 2015, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
15 Get the volume's info into Buffer.
17 @param Volume - FAT file system volume.
18 @param BufferSize - Size of Buffer.
19 @param Buffer - Buffer containing volume info.
21 @retval EFI_SUCCESS - Get the volume info successfully.
22 @retval EFI_BUFFER_TOO_SMALL - The buffer is too small.
27 IN FAT_VOLUME
*Volume
,
28 IN OUT UINTN
*BufferSize
,
34 Set the volume's info.
36 @param Volume - FAT file system volume.
37 @param BufferSize - Size of Buffer.
38 @param Buffer - Buffer containing the new volume info.
40 @retval EFI_SUCCESS - Set the volume info successfully.
41 @retval EFI_BAD_BUFFER_SIZE - The buffer size is error.
42 @retval EFI_WRITE_PROTECTED - The volume is read only.
43 @return other - An error occurred when operation the disk.
48 IN FAT_VOLUME
*Volume
,
55 Set or Get the some types info of the file into Buffer.
57 @param IsSet - TRUE:The access is set, else is get
58 @param FHand - The handle of file
59 @param Type - The type of the info
60 @param BufferSize - Size of Buffer
61 @param Buffer - Buffer containing volume info
63 @retval EFI_SUCCESS - Get the info successfully
64 @retval EFI_DEVICE_ERROR - Can not find the OFile for the file
70 IN EFI_FILE_PROTOCOL
*FHand
,
72 IN OUT UINTN
*BufferSize
,
78 Get the open file's info into Buffer.
80 @param OFile - The open file.
81 @param BufferSize - Size of Buffer.
82 @param Buffer - Buffer containing file info.
84 @retval EFI_SUCCESS - Get the file info successfully.
85 @retval EFI_BUFFER_TOO_SMALL - The buffer is too small.
91 IN OUT UINTN
*BufferSize
,
95 return FatGetDirEntInfo (OFile
->Volume
, OFile
->DirEnt
, BufferSize
, Buffer
);
100 Get the volume's info into Buffer.
102 @param Volume - FAT file system volume.
103 @param BufferSize - Size of Buffer.
104 @param Buffer - Buffer containing volume info.
106 @retval EFI_SUCCESS - Get the volume info successfully.
107 @retval EFI_BUFFER_TOO_SMALL - The buffer is too small.
112 IN FAT_VOLUME
*Volume
,
113 IN OUT UINTN
*BufferSize
,
120 CHAR16 Name
[FAT_NAME_LEN
+ 1];
122 EFI_FILE_SYSTEM_INFO
*Info
;
123 UINT8 ClusterAlignment
;
125 Size
= SIZE_OF_EFI_FILE_SYSTEM_INFO
;
126 Status
= FatGetVolumeEntry (Volume
, Name
);
127 NameSize
= StrSize (Name
);
128 ResultSize
= Size
+ NameSize
;
129 ClusterAlignment
= Volume
->ClusterAlignment
;
132 // If we don't have valid info, compute it now
134 FatComputeFreeInfo (Volume
);
136 Status
= EFI_BUFFER_TOO_SMALL
;
137 if (*BufferSize
>= ResultSize
) {
138 Status
= EFI_SUCCESS
;
141 ZeroMem (Info
, SIZE_OF_EFI_FILE_SYSTEM_INFO
);
143 Info
->Size
= ResultSize
;
144 Info
->ReadOnly
= Volume
->ReadOnly
;
145 Info
->BlockSize
= (UINT32
) Volume
->ClusterSize
;
146 Info
->VolumeSize
= LShiftU64 (Volume
->MaxCluster
, ClusterAlignment
);
147 Info
->FreeSpace
= LShiftU64 (
148 Volume
->FatInfoSector
.FreeInfo
.ClusterCount
,
151 CopyMem ((CHAR8
*) Buffer
+ Size
, Name
, NameSize
);
154 *BufferSize
= ResultSize
;
160 Get the volume's label info into Buffer.
162 @param Volume - FAT file system volume.
163 @param BufferSize - Size of Buffer.
164 @param Buffer - Buffer containing volume's label info.
166 @retval EFI_SUCCESS - Get the volume's label info successfully.
167 @retval EFI_BUFFER_TOO_SMALL - The buffer is too small.
171 FatGetVolumeLabelInfo (
172 IN FAT_VOLUME
*Volume
,
173 IN OUT UINTN
*BufferSize
,
180 CHAR16 Name
[FAT_NAME_LEN
+ 1];
183 Size
= SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL
;
184 Status
= FatGetVolumeEntry (Volume
, Name
);
185 NameSize
= StrSize (Name
);
186 ResultSize
= Size
+ NameSize
;
188 Status
= EFI_BUFFER_TOO_SMALL
;
189 if (*BufferSize
>= ResultSize
) {
190 Status
= EFI_SUCCESS
;
191 CopyMem ((CHAR8
*) Buffer
+ Size
, Name
, NameSize
);
194 *BufferSize
= ResultSize
;
200 Set the volume's info.
202 @param Volume - FAT file system volume.
203 @param BufferSize - Size of Buffer.
204 @param Buffer - Buffer containing the new volume info.
206 @retval EFI_SUCCESS - Set the volume info successfully.
207 @retval EFI_BAD_BUFFER_SIZE - The buffer size is error.
208 @retval EFI_WRITE_PROTECTED - The volume is read only.
209 @return other - An error occurred when operation the disk.
214 IN FAT_VOLUME
*Volume
,
219 EFI_FILE_SYSTEM_INFO
*Info
;
221 Info
= (EFI_FILE_SYSTEM_INFO
*) Buffer
;
223 if (BufferSize
< SIZE_OF_EFI_FILE_SYSTEM_INFO
+ 2 || Info
->Size
> BufferSize
) {
224 return EFI_BAD_BUFFER_SIZE
;
227 return FatSetVolumeEntry (Volume
, Info
->VolumeLabel
);
232 Set the volume's label info.
234 @param Volume - FAT file system volume.
235 @param BufferSize - Size of Buffer.
236 @param Buffer - Buffer containing the new volume label info.
238 @retval EFI_SUCCESS - Set the volume label info successfully.
239 @retval EFI_WRITE_PROTECTED - The disk is write protected.
240 @retval EFI_BAD_BUFFER_SIZE - The buffer size is error.
241 @return other - An error occurred when operation the disk.
245 FatSetVolumeLabelInfo (
246 IN FAT_VOLUME
*Volume
,
251 EFI_FILE_SYSTEM_VOLUME_LABEL
*Info
;
253 Info
= (EFI_FILE_SYSTEM_VOLUME_LABEL
*) Buffer
;
255 if (BufferSize
< SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL
+ 2) {
256 return EFI_BAD_BUFFER_SIZE
;
259 return FatSetVolumeEntry (Volume
, Info
->VolumeLabel
);
266 @param Volume - FAT file system volume.
267 @param IFile - The instance of the open file.
268 @param OFile - The open file.
269 @param BufferSize - Size of Buffer.
270 @param Buffer - Buffer containing the new file info.
272 @retval EFI_SUCCESS - Set the file info successfully.
273 @retval EFI_ACCESS_DENIED - It is the root directory
274 or the directory attribute bit can not change
275 or try to change a directory size
277 @retval EFI_UNSUPPORTED - The new file size is larger than 4GB.
278 @retval EFI_WRITE_PROTECTED - The disk is write protected.
279 @retval EFI_BAD_BUFFER_SIZE - The buffer size is error.
280 @retval EFI_INVALID_PARAMETER - The time info or attributes info is error.
281 @retval EFI_OUT_OF_RESOURCES - Can not allocate new memory.
282 @retval EFI_VOLUME_CORRUPTED - The volume is corrupted.
283 @return other - An error occurred when operation the disk.
288 IN FAT_VOLUME
*Volume
,
296 EFI_FILE_INFO
*NewInfo
;
299 CHAR16 NewFileName
[EFI_PATH_STRING_LENGTH
];
302 FAT_DIRENT
*TempDirEnt
;
306 ZeroMem (&ZeroTime
, sizeof (EFI_TIME
));
307 Parent
= OFile
->Parent
;
308 DirEnt
= OFile
->DirEnt
;
310 // If this is the root directory, we can't make any updates
312 if (Parent
== NULL
) {
313 return EFI_ACCESS_DENIED
;
316 // Make sure there's a valid input buffer
319 if (BufferSize
< SIZE_OF_EFI_FILE_INFO
+ 2 || NewInfo
->Size
> BufferSize
) {
320 return EFI_BAD_BUFFER_SIZE
;
323 ReadOnly
= (BOOLEAN
)(IFile
->ReadOnly
|| (DirEnt
->Entry
.Attributes
& EFI_FILE_READ_ONLY
));
325 // if a zero time is specified, then the original time is preserved
327 if (CompareMem (&ZeroTime
, &NewInfo
->CreateTime
, sizeof (EFI_TIME
)) != 0) {
328 if (!FatIsValidTime (&NewInfo
->CreateTime
)) {
329 return EFI_INVALID_PARAMETER
;
333 FatEfiTimeToFatTime (&NewInfo
->CreateTime
, &DirEnt
->Entry
.FileCreateTime
);
337 if (CompareMem (&ZeroTime
, &NewInfo
->ModificationTime
, sizeof (EFI_TIME
)) != 0) {
338 if (!FatIsValidTime (&NewInfo
->ModificationTime
)) {
339 return EFI_INVALID_PARAMETER
;
343 FatEfiTimeToFatTime (&NewInfo
->ModificationTime
, &DirEnt
->Entry
.FileModificationTime
);
346 OFile
->PreserveLastModification
= TRUE
;
349 if (NewInfo
->Attribute
& (~EFI_FILE_VALID_ATTR
)) {
350 return EFI_INVALID_PARAMETER
;
353 NewAttribute
= (UINT8
) NewInfo
->Attribute
;
355 // Can not change the directory attribute bit
357 if ((NewAttribute
^ DirEnt
->Entry
.Attributes
) & EFI_FILE_DIRECTORY
) {
358 return EFI_ACCESS_DENIED
;
361 // Set the current attributes even if the IFile->ReadOnly is TRUE
363 DirEnt
->Entry
.Attributes
= (UINT8
) ((DirEnt
->Entry
.Attributes
&~EFI_FILE_VALID_ATTR
) | NewAttribute
);
365 // Open the filename and see if it refers to an existing file
367 Status
= FatLocateOFile (&Parent
, NewInfo
->FileName
, DirEnt
->Entry
.Attributes
, NewFileName
);
368 if (EFI_ERROR (Status
)) {
372 if (*NewFileName
!= 0) {
374 // File was not found. We do not allow rename of the current directory if
375 // there are open files below the current directory
377 if (!IsListEmpty (&OFile
->ChildHead
) || Parent
== OFile
) {
378 return EFI_ACCESS_DENIED
;
382 return EFI_ACCESS_DENIED
;
385 Status
= FatRemoveDirEnt (OFile
->Parent
, DirEnt
);
386 if (EFI_ERROR (Status
)) {
392 Status
= FatCreateDirEnt (Parent
, NewFileName
, DirEnt
->Entry
.Attributes
, &TempDirEnt
);
393 if (EFI_ERROR (Status
)) {
397 FatCloneDirEnt (TempDirEnt
, DirEnt
);
398 FatFreeDirEnt (DirEnt
);
400 DirEnt
->OFile
= OFile
;
401 OFile
->DirEnt
= DirEnt
;
402 OFile
->Parent
= Parent
;
403 RemoveEntryList (&OFile
->ChildLink
);
404 InsertHeadList (&Parent
->ChildHead
, &OFile
->ChildLink
);
406 // If this is a directory, synchronize its dot directory entry
408 if (OFile
->ODir
!= NULL
) {
410 // Synchronize its dot entry
412 FatResetODirCursor (OFile
);
413 ASSERT (OFile
->Parent
!= NULL
);
414 for (DotOFile
= OFile
; DotOFile
!= OFile
->Parent
->Parent
; DotOFile
= DotOFile
->Parent
) {
415 Status
= FatGetNextDirEnt (OFile
, &DirEnt
);
416 if (EFI_ERROR (Status
) || DirEnt
== NULL
|| !FatIsDotDirEnt (DirEnt
)) {
417 return EFI_VOLUME_CORRUPTED
;
420 FatCloneDirEnt (DirEnt
, DotOFile
->DirEnt
);
421 Status
= FatStoreDirEnt (OFile
, DirEnt
);
422 if (EFI_ERROR (Status
)) {
428 // If the file is renamed, we should append the ARCHIVE attribute
430 OFile
->Archive
= TRUE
;
431 } else if (Parent
!= OFile
) {
433 // filename is to a different filename that already exists
435 return EFI_ACCESS_DENIED
;
438 // If the file size has changed, apply it
440 if (NewInfo
->FileSize
!= OFile
->FileSize
) {
441 if (OFile
->ODir
!= NULL
|| ReadOnly
) {
443 // If this is a directory or the file is read only, we can't change the file size
445 return EFI_ACCESS_DENIED
;
448 if (NewInfo
->FileSize
> OFile
->FileSize
) {
449 Status
= FatExpandOFile (OFile
, NewInfo
->FileSize
);
451 Status
= FatTruncateOFile (OFile
, (UINTN
) NewInfo
->FileSize
);
454 if (EFI_ERROR (Status
)) {
458 FatUpdateDirEntClusterSizeInfo (OFile
);
462 return FatOFileFlush (OFile
);
467 Set or Get the some types info of the file into Buffer.
469 @param IsSet - TRUE:The access is set, else is get
470 @param FHand - The handle of file
471 @param Type - The type of the info
472 @param BufferSize - Size of Buffer
473 @param Buffer - Buffer containing volume info
475 @retval EFI_SUCCESS - Get the info successfully
476 @retval EFI_DEVICE_ERROR - Can not find the OFile for the file
482 IN EFI_FILE_PROTOCOL
*FHand
,
484 IN OUT UINTN
*BufferSize
,
493 IFile
= IFILE_FROM_FHAND (FHand
);
494 OFile
= IFile
->OFile
;
495 Volume
= OFile
->Volume
;
497 Status
= OFile
->Error
;
498 if (Status
== EFI_NOT_FOUND
) {
499 return EFI_DEVICE_ERROR
;
502 FatWaitNonblockingTask (IFile
);
507 // Verify the file handle isn't in an error state
509 if (!EFI_ERROR (Status
)) {
511 // Get the proper information based on the request
513 Status
= EFI_UNSUPPORTED
;
515 if (CompareGuid (Type
, &gEfiFileInfoGuid
)) {
516 Status
= Volume
->ReadOnly
? EFI_WRITE_PROTECTED
: FatSetFileInfo (Volume
, IFile
, OFile
, *BufferSize
, Buffer
);
519 if (CompareGuid (Type
, &gEfiFileSystemInfoGuid
)) {
520 Status
= Volume
->ReadOnly
? EFI_WRITE_PROTECTED
: FatSetVolumeInfo (Volume
, *BufferSize
, Buffer
);
523 if (CompareGuid (Type
, &gEfiFileSystemVolumeLabelInfoIdGuid
)) {
524 Status
= Volume
->ReadOnly
? EFI_WRITE_PROTECTED
: FatSetVolumeLabelInfo (Volume
, *BufferSize
, Buffer
);
527 if (CompareGuid (Type
, &gEfiFileInfoGuid
)) {
528 Status
= FatGetFileInfo (OFile
, BufferSize
, Buffer
);
531 if (CompareGuid (Type
, &gEfiFileSystemInfoGuid
)) {
532 Status
= FatGetVolumeInfo (Volume
, BufferSize
, Buffer
);
535 if (CompareGuid (Type
, &gEfiFileSystemVolumeLabelInfoIdGuid
)) {
536 Status
= FatGetVolumeLabelInfo (Volume
, BufferSize
, Buffer
);
541 Status
= FatCleanupVolume (Volume
, NULL
, Status
, NULL
);
549 Get the some types info of the file into Buffer.
551 @param FHand - The handle of file.
552 @param Type - The type of the info.
553 @param BufferSize - Size of Buffer.
554 @param Buffer - Buffer containing volume info.
556 @retval EFI_SUCCESS - Get the info successfully.
557 @retval EFI_DEVICE_ERROR - Can not find the OFile for the file.
563 IN EFI_FILE_PROTOCOL
*FHand
,
565 IN OUT UINTN
*BufferSize
,
569 return FatSetOrGetInfo (FALSE
, FHand
, Type
, BufferSize
, Buffer
);
574 Set the some types info of the file into Buffer.
576 @param FHand - The handle of file.
577 @param Type - The type of the info.
578 @param BufferSize - Size of Buffer
579 @param Buffer - Buffer containing volume info.
581 @retval EFI_SUCCESS - Set the info successfully.
582 @retval EFI_DEVICE_ERROR - Can not find the OFile for the file.
588 IN EFI_FILE_PROTOCOL
*FHand
,
594 return FatSetOrGetInfo (TRUE
, FHand
, Type
, &BufferSize
, Buffer
);