3 Copyright (c) 2005 - 2013, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials are licensed and made available
5 under the terms and conditions of the BSD License which accompanies this
6 distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 Routines dealing with setting/getting file/volume info
29 IN FAT_VOLUME
*Volume
,
30 IN OUT UINTN
*BufferSize
,
36 IN FAT_VOLUME
*Volume
,
37 IN OUT UINTN BufferSize
,
44 IN EFI_FILE_PROTOCOL
*FHand
,
46 IN OUT UINTN
*BufferSize
,
53 IN OUT UINTN
*BufferSize
,
60 Get the open file's info into Buffer.
64 OFile - The open file.
65 BufferSize - Size of Buffer.
66 Buffer - Buffer containing file info.
70 EFI_SUCCESS - Get the file info successfully.
71 EFI_BUFFER_TOO_SMALL - The buffer is too small.
75 return FatGetDirEntInfo (OFile
->Volume
, OFile
->DirEnt
, BufferSize
, Buffer
);
80 IN FAT_VOLUME
*Volume
,
81 IN OUT UINTN
*BufferSize
,
88 Get the volume's info into Buffer.
92 Volume - FAT file system volume.
93 BufferSize - Size of Buffer.
94 Buffer - Buffer containing volume info.
98 EFI_SUCCESS - Get the volume info successfully.
99 EFI_BUFFER_TOO_SMALL - The buffer is too small.
106 CHAR16 Name
[FAT_NAME_LEN
+ 1];
108 EFI_FILE_SYSTEM_INFO
*Info
;
109 UINT8 ClusterAlignment
;
111 Size
= SIZE_OF_EFI_FILE_SYSTEM_INFO
;
112 Status
= FatGetVolumeEntry (Volume
, Name
);
113 NameSize
= StrSize (Name
);
114 ResultSize
= Size
+ NameSize
;
115 ClusterAlignment
= Volume
->ClusterAlignment
;
118 // If we don't have valid info, compute it now
120 FatComputeFreeInfo (Volume
);
122 Status
= EFI_BUFFER_TOO_SMALL
;
123 if (*BufferSize
>= ResultSize
) {
124 Status
= EFI_SUCCESS
;
127 ZeroMem (Info
, SIZE_OF_EFI_FILE_SYSTEM_INFO
);
129 Info
->Size
= ResultSize
;
130 Info
->ReadOnly
= Volume
->ReadOnly
;
131 Info
->BlockSize
= (UINT32
) Volume
->ClusterSize
;
132 Info
->VolumeSize
= LShiftU64 (Volume
->MaxCluster
, ClusterAlignment
);
133 Info
->FreeSpace
= LShiftU64 (
134 Volume
->FatInfoSector
.FreeInfo
.ClusterCount
,
137 CopyMem ((CHAR8
*) Buffer
+ Size
, Name
, NameSize
);
140 *BufferSize
= ResultSize
;
145 FatGetVolumeLabelInfo (
146 IN FAT_VOLUME
*Volume
,
147 IN OUT UINTN
*BufferSize
,
154 Get the volume's label info into Buffer.
158 Volume - FAT file system volume.
159 BufferSize - Size of Buffer.
160 Buffer - Buffer containing volume's label info.
164 EFI_SUCCESS - Get the volume's label info successfully.
165 EFI_BUFFER_TOO_SMALL - The buffer is too small.
172 CHAR16 Name
[FAT_NAME_LEN
+ 1];
175 Size
= SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL
;
176 Status
= FatGetVolumeEntry (Volume
, Name
);
177 NameSize
= StrSize (Name
);
178 ResultSize
= Size
+ NameSize
;
180 Status
= EFI_BUFFER_TOO_SMALL
;
181 if (*BufferSize
>= ResultSize
) {
182 Status
= EFI_SUCCESS
;
183 CopyMem ((CHAR8
*) Buffer
+ Size
, Name
, NameSize
);
186 *BufferSize
= ResultSize
;
192 IN FAT_VOLUME
*Volume
,
200 Set the volume's info.
204 Volume - FAT file system volume.
205 BufferSize - Size of Buffer.
206 Buffer - Buffer containing the new volume info.
210 EFI_SUCCESS - Set the volume info successfully.
211 EFI_BAD_BUFFER_SIZE - The buffer size is error.
212 EFI_WRITE_PROTECTED - The volume is read only.
213 other - An error occurred when operation the disk.
217 EFI_FILE_SYSTEM_INFO
*Info
;
219 Info
= (EFI_FILE_SYSTEM_INFO
*) Buffer
;
221 if (BufferSize
< SIZE_OF_EFI_FILE_SYSTEM_INFO
+ 2 || Info
->Size
> BufferSize
) {
222 return EFI_BAD_BUFFER_SIZE
;
225 return FatSetVolumeEntry (Volume
, Info
->VolumeLabel
);
229 FatSetVolumeLabelInfo (
230 IN FAT_VOLUME
*Volume
,
238 Set the volume's label info
242 Volume - FAT file system volume.
243 BufferSize - Size of Buffer.
244 Buffer - Buffer containing the new volume label info.
248 EFI_SUCCESS - Set the volume label info successfully.
249 EFI_WRITE_PROTECTED - The disk is write protected.
250 EFI_BAD_BUFFER_SIZE - The buffer size is error.
251 other - An error occurred when operation the disk.
255 EFI_FILE_SYSTEM_VOLUME_LABEL
*Info
;
257 Info
= (EFI_FILE_SYSTEM_VOLUME_LABEL
*) Buffer
;
259 if (BufferSize
< SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL
+ 2) {
260 return EFI_BAD_BUFFER_SIZE
;
263 return FatSetVolumeEntry (Volume
, Info
->VolumeLabel
);
268 IN FAT_VOLUME
*Volume
,
282 Volume - FAT file system volume.
283 IFile - The instance of the open file.
284 OFile - The open file.
285 BufferSize - Size of Buffer.
286 Buffer - Buffer containing the new file info.
290 EFI_SUCCESS - Set the file info successfully.
291 EFI_ACCESS_DENIED - It is the root directory
292 or the directory attribute bit can not change
293 or try to change a directory size
295 EFI_UNSUPPORTED - The new file size is larger than 4GB.
296 EFI_WRITE_PROTECTED - The disk is write protected.
297 EFI_BAD_BUFFER_SIZE - The buffer size is error.
298 EFI_INVALID_PARAMETER - The time info or attributes info is error.
299 EFI_OUT_OF_RESOURCES - Can not allocate new memory.
300 EFI_VOLUME_CORRUPTED - The volume is corrupted.
301 other - An error occurred when operation the disk.
306 EFI_FILE_INFO
*NewInfo
;
309 CHAR16 NewFileName
[EFI_PATH_STRING_LENGTH
];
312 FAT_DIRENT
*TempDirEnt
;
316 ZeroMem (&ZeroTime
, sizeof (EFI_TIME
));
317 Parent
= OFile
->Parent
;
318 DirEnt
= OFile
->DirEnt
;
320 // If this is the root directory, we can't make any updates
322 if (Parent
== NULL
) {
323 return EFI_ACCESS_DENIED
;
326 // Make sure there's a valid input buffer
329 if (BufferSize
< SIZE_OF_EFI_FILE_INFO
+ 2 || NewInfo
->Size
> BufferSize
) {
330 return EFI_BAD_BUFFER_SIZE
;
333 ReadOnly
= (BOOLEAN
)(IFile
->ReadOnly
|| (DirEnt
->Entry
.Attributes
& EFI_FILE_READ_ONLY
));
335 // if a zero time is specified, then the original time is preserved
337 if (CompareMem (&ZeroTime
, &NewInfo
->CreateTime
, sizeof (EFI_TIME
)) != 0) {
338 if (!FatIsValidTime (&NewInfo
->CreateTime
)) {
339 return EFI_INVALID_PARAMETER
;
343 FatEfiTimeToFatTime (&NewInfo
->CreateTime
, &DirEnt
->Entry
.FileCreateTime
);
347 if (CompareMem (&ZeroTime
, &NewInfo
->ModificationTime
, sizeof (EFI_TIME
)) != 0) {
348 if (!FatIsValidTime (&NewInfo
->ModificationTime
)) {
349 return EFI_INVALID_PARAMETER
;
353 FatEfiTimeToFatTime (&NewInfo
->ModificationTime
, &DirEnt
->Entry
.FileModificationTime
);
356 OFile
->PreserveLastModification
= TRUE
;
359 if (NewInfo
->Attribute
& (~EFI_FILE_VALID_ATTR
)) {
360 return EFI_INVALID_PARAMETER
;
363 NewAttribute
= (UINT8
) NewInfo
->Attribute
;
365 // Can not change the directory attribute bit
367 if ((NewAttribute
^ DirEnt
->Entry
.Attributes
) & EFI_FILE_DIRECTORY
) {
368 return EFI_ACCESS_DENIED
;
371 // Set the current attributes even if the IFile->ReadOnly is TRUE
373 DirEnt
->Entry
.Attributes
= (UINT8
) ((DirEnt
->Entry
.Attributes
&~EFI_FILE_VALID_ATTR
) | NewAttribute
);
375 // Open the filename and see if it refers to an existing file
377 Status
= FatLocateOFile (&Parent
, NewInfo
->FileName
, DirEnt
->Entry
.Attributes
, NewFileName
);
378 if (EFI_ERROR (Status
)) {
382 if (*NewFileName
!= 0) {
384 // File was not found. We do not allow rename of the current directory if
385 // there are open files below the current directory
387 if (!IsListEmpty (&OFile
->ChildHead
) || Parent
== OFile
) {
388 return EFI_ACCESS_DENIED
;
392 return EFI_ACCESS_DENIED
;
395 Status
= FatRemoveDirEnt (OFile
->Parent
, DirEnt
);
396 if (EFI_ERROR (Status
)) {
402 Status
= FatCreateDirEnt (Parent
, NewFileName
, DirEnt
->Entry
.Attributes
, &TempDirEnt
);
403 if (EFI_ERROR (Status
)) {
407 FatCloneDirEnt (TempDirEnt
, DirEnt
);
408 FatFreeDirEnt (DirEnt
);
410 DirEnt
->OFile
= OFile
;
411 OFile
->DirEnt
= DirEnt
;
412 OFile
->Parent
= Parent
;
413 RemoveEntryList (&OFile
->ChildLink
);
414 InsertHeadList (&Parent
->ChildHead
, &OFile
->ChildLink
);
416 // If this is a directory, synchronize its dot directory entry
418 if (OFile
->ODir
!= NULL
) {
420 // Syncronize its dot entry
422 FatResetODirCursor (OFile
);
423 ASSERT (OFile
->Parent
!= NULL
);
424 for (DotOFile
= OFile
; DotOFile
!= OFile
->Parent
->Parent
; DotOFile
= DotOFile
->Parent
) {
425 Status
= FatGetNextDirEnt (OFile
, &DirEnt
);
426 if (EFI_ERROR (Status
) || DirEnt
== NULL
|| !FatIsDotDirEnt (DirEnt
)) {
427 return EFI_VOLUME_CORRUPTED
;
430 FatCloneDirEnt (DirEnt
, DotOFile
->DirEnt
);
431 Status
= FatStoreDirEnt (OFile
, DirEnt
);
432 if (EFI_ERROR (Status
)) {
438 // If the file is renamed, we should append the ARCHIVE attribute
440 OFile
->Archive
= TRUE
;
441 } else if (Parent
!= OFile
) {
443 // filename is to a different filename that already exists
445 return EFI_ACCESS_DENIED
;
448 // If the file size has changed, apply it
450 if (NewInfo
->FileSize
!= OFile
->FileSize
) {
451 if (OFile
->ODir
!= NULL
|| ReadOnly
) {
453 // If this is a directory or the file is read only, we can't change the file size
455 return EFI_ACCESS_DENIED
;
458 if (NewInfo
->FileSize
> OFile
->FileSize
) {
459 Status
= FatExpandOFile (OFile
, NewInfo
->FileSize
);
461 Status
= FatTruncateOFile (OFile
, (UINTN
) NewInfo
->FileSize
);
464 if (EFI_ERROR (Status
)) {
468 FatUpdateDirEntClusterSizeInfo (OFile
);
472 return FatOFileFlush (OFile
);
478 IN EFI_FILE_PROTOCOL
*FHand
,
480 IN OUT UINTN
*BufferSize
,
487 Set or Get the some types info of the file into Buffer
491 IsSet - TRUE:The access is set, else is get
492 FHand - The handle of file
493 Type - The type of the info
494 BufferSize - Size of Buffer
495 Buffer - Buffer containing volume info
499 EFI_SUCCESS - Get the info successfully
500 EFI_DEVICE_ERROR - Can not find the OFile for the file
509 IFile
= IFILE_FROM_FHAND (FHand
);
510 OFile
= IFile
->OFile
;
511 Volume
= OFile
->Volume
;
513 Status
= OFile
->Error
;
514 if (Status
== EFI_NOT_FOUND
) {
515 return EFI_DEVICE_ERROR
;
518 FatWaitNonblockingTask (IFile
);
523 // Verify the file handle isn't in an error state
525 if (!EFI_ERROR (Status
)) {
527 // Get the proper information based on the request
529 Status
= EFI_UNSUPPORTED
;
531 if (Volume
->ReadOnly
) {
532 Status
= EFI_WRITE_PROTECTED
;
534 if (CompareGuid (Type
, &gEfiFileInfoGuid
)) {
535 Status
= FatSetFileInfo (Volume
, IFile
, OFile
, *BufferSize
, Buffer
);
538 if (CompareGuid (Type
, &gEfiFileSystemInfoGuid
)) {
539 Status
= FatSetVolumeInfo (Volume
, *BufferSize
, Buffer
);
542 if (CompareGuid (Type
, &gEfiFileSystemVolumeLabelInfoIdGuid
)) {
543 Status
= FatSetVolumeLabelInfo (Volume
, *BufferSize
, Buffer
);
547 if (CompareGuid (Type
, &gEfiFileInfoGuid
)) {
548 Status
= FatGetFileInfo (OFile
, BufferSize
, Buffer
);
551 if (CompareGuid (Type
, &gEfiFileSystemInfoGuid
)) {
552 Status
= FatGetVolumeInfo (Volume
, BufferSize
, Buffer
);
555 if (CompareGuid (Type
, &gEfiFileSystemVolumeLabelInfoIdGuid
)) {
556 Status
= FatGetVolumeLabelInfo (Volume
, BufferSize
, Buffer
);
561 Status
= FatCleanupVolume (Volume
, NULL
, Status
, NULL
);
570 IN EFI_FILE_PROTOCOL
*FHand
,
572 IN OUT UINTN
*BufferSize
,
579 Get the some types info of the file into Buffer.
583 FHand - The handle of file.
584 Type - The type of the info.
585 BufferSize - Size of Buffer.
586 Buffer - Buffer containing volume info.
590 EFI_SUCCESS - Get the info successfully.
591 EFI_DEVICE_ERROR - Can not find the OFile for the file.
595 return FatSetOrGetInfo (FALSE
, FHand
, Type
, BufferSize
, Buffer
);
601 IN EFI_FILE_PROTOCOL
*FHand
,
610 Set the some types info of the file into Buffer.
614 FHand - The handle of file.
615 Type - The type of the info.
616 BufferSize - Size of Buffer
617 Buffer - Buffer containing volume info.
621 EFI_SUCCESS - Set the info successfully.
622 EFI_DEVICE_ERROR - Can not find the OFile for the file.
626 return FatSetOrGetInfo (TRUE
, FHand
, Type
, &BufferSize
, Buffer
);