-/*++\r
+/** @file\r
+ Routines dealing with disk spaces and FAT table entries.\r
\r
-Copyright (c) 2005, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials are licensed and made available\r
-under the terms and conditions of the BSD License which accompanies this\r
-distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
+Copyright (c) 2005 - 2013, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
\r
\r
-Module Name:\r
+**/\r
\r
- FileSpace.c\r
+#include "Fat.h"\r
\r
-Abstract:\r
\r
- Routines dealing with disk spaces and FAT table entries\r
+/**\r
\r
-Revision History\r
+ Get the FAT entry of the volume, which is identified with the Index.\r
\r
---*/\r
-\r
-#include "Fat.h"\r
+ @param Volume - FAT file system volume.\r
+ @param Index - The index of the FAT entry of the volume.\r
\r
+ @return The buffer of the FAT entry\r
\r
+**/\r
STATIC\r
VOID *\r
FatLoadFatEntry (\r
IN FAT_VOLUME *Volume,\r
IN UINTN Index\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Get the FAT entry of the volume, which is identified with the Index.\r
-\r
-Arguments:\r
-\r
- Volume - FAT file system volume.\r
- Index - The index of the FAT entry of the volume.\r
-\r
-Returns:\r
-\r
- The buffer of the FAT entry\r
-\r
---*/\r
{\r
UINTN Pos;\r
EFI_STATUS Status;\r
// Compute buffer position needed\r
//\r
switch (Volume->FatType) {\r
- case FAT12:\r
+ case Fat12:\r
Pos = FAT_POS_FAT12 (Index);\r
break;\r
\r
- case FAT16:\r
+ case Fat16:\r
Pos = FAT_POS_FAT16 (Index);\r
break;\r
\r
Volume->FatEntryPos = Volume->FatPos + Pos;\r
Status = FatDiskIo (\r
Volume,\r
- READ_FAT,\r
+ ReadFat,\r
Volume->FatEntryPos,\r
Volume->FatEntrySize,\r
- &Volume->FatEntryBuffer\r
+ &Volume->FatEntryBuffer,\r
+ NULL\r
);\r
if (EFI_ERROR (Status)) {\r
Volume->FatEntryBuffer = (UINT32) -1;\r
return &Volume->FatEntryBuffer;\r
}\r
\r
+/**\r
+\r
+ Get the FAT entry value of the volume, which is identified with the Index.\r
+\r
+ @param Volume - FAT file system volume.\r
+ @param Index - The index of the FAT entry of the volume.\r
+\r
+ @return The value of the FAT entry.\r
+\r
+**/\r
STATIC\r
UINTN\r
FatGetFatEntry (\r
IN FAT_VOLUME *Volume,\r
IN UINTN Index\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Get the FAT entry value of the volume, which is identified with the Index.\r
-\r
-Arguments:\r
-\r
- Volume - FAT file system volume.\r
- Index - The index of the FAT entry of the volume.\r
-\r
-Returns:\r
-\r
- The value of the FAT entry.\r
-\r
---*/\r
{\r
VOID *Pos;\r
- UINT8 *E12;\r
- UINT16 *E16;\r
- UINT32 *E32;\r
+ UINT8 *En12;\r
+ UINT16 *En16;\r
+ UINT32 *En32;\r
UINTN Accum;\r
\r
Pos = FatLoadFatEntry (Volume, Index);\r
}\r
\r
switch (Volume->FatType) {\r
- case FAT12:\r
- E12 = Pos;\r
- Accum = E12[0] | (E12[1] << 8);\r
+ case Fat12:\r
+ En12 = Pos;\r
+ Accum = En12[0] | (En12[1] << 8);\r
Accum = FAT_ODD_CLUSTER_FAT12 (Index) ? (Accum >> 4) : (Accum & FAT_CLUSTER_MASK_FAT12);\r
Accum = Accum | ((Accum >= FAT_CLUSTER_SPECIAL_FAT12) ? FAT_CLUSTER_SPECIAL_EXT : 0);\r
break;\r
\r
- case FAT16:\r
- E16 = Pos;\r
- Accum = *E16;\r
+ case Fat16:\r
+ En16 = Pos;\r
+ Accum = *En16;\r
Accum = Accum | ((Accum >= FAT_CLUSTER_SPECIAL_FAT16) ? FAT_CLUSTER_SPECIAL_EXT : 0);\r
break;\r
\r
default:\r
- E32 = Pos;\r
- Accum = *E32 & FAT_CLUSTER_MASK_FAT32;\r
+ En32 = Pos;\r
+ Accum = *En32 & FAT_CLUSTER_MASK_FAT32;\r
Accum = Accum | ((Accum >= FAT_CLUSTER_SPECIAL_FAT32) ? FAT_CLUSTER_SPECIAL_EXT : 0);\r
}\r
\r
return Accum;\r
}\r
\r
+/**\r
+\r
+ Set the FAT entry value of the volume, which is identified with the Index.\r
+\r
+ @param Volume - FAT file system volume.\r
+ @param Index - The index of the FAT entry of the volume.\r
+ @param Value - The new value of the FAT entry.\r
+\r
+ @retval EFI_SUCCESS - Set the new FAT entry value sucessfully.\r
+ @retval EFI_VOLUME_CORRUPTED - The FAT type of the volume is error.\r
+ @return other - An error occurred when operation the FAT entries.\r
+\r
+**/\r
STATIC\r
EFI_STATUS\r
FatSetFatEntry (\r
IN UINTN Index,\r
IN UINTN Value\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Set the FAT entry value of the volume, which is identified with the Index.\r
-\r
-Arguments:\r
-\r
- Volume - FAT file system volume.\r
- Index - The index of the FAT entry of the volume.\r
- Value - The new value of the FAT entry.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - Set the new FAT entry value sucessfully.\r
- EFI_VOLUME_CORRUPTED - The FAT type of the volume is error.\r
- other - An error occurred when operation the FAT entries.\r
-\r
---*/\r
{\r
VOID *Pos;\r
- UINT8 *E12;\r
- UINT16 *E16;\r
- UINT32 *E32;\r
+ UINT8 *En12;\r
+ UINT16 *En16;\r
+ UINT32 *En32;\r
UINTN Accum;\r
EFI_STATUS Status;\r
UINTN OriginalVal;\r
// Update the value\r
//\r
switch (Volume->FatType) {\r
- case FAT12:\r
- E12 = Pos;\r
- Accum = E12[0] | (E12[1] << 8);\r
+ case Fat12:\r
+ En12 = Pos;\r
+ Accum = En12[0] | (En12[1] << 8);\r
Value = Value & FAT_CLUSTER_MASK_FAT12;\r
\r
if (FAT_ODD_CLUSTER_FAT12 (Index)) {\r
Accum = Value | (Accum & FAT_CLUSTER_UNMASK_FAT12);\r
}\r
\r
- E12[0] = (UINT8) (Accum & 0xFF);\r
- E12[1] = (UINT8) (Accum >> 8);\r
+ En12[0] = (UINT8) (Accum & 0xFF);\r
+ En12[1] = (UINT8) (Accum >> 8);\r
break;\r
\r
- case FAT16:\r
- E16 = Pos;\r
- *E16 = (UINT16) Value;\r
+ case Fat16:\r
+ En16 = Pos;\r
+ *En16 = (UINT16) Value;\r
break;\r
\r
default:\r
- E32 = Pos;\r
- *E32 = (*E32 & FAT_CLUSTER_UNMASK_FAT32) | (UINT32) (Value & FAT_CLUSTER_MASK_FAT32);\r
+ En32 = Pos;\r
+ *En32 = (*En32 & FAT_CLUSTER_UNMASK_FAT32) | (UINT32) (Value & FAT_CLUSTER_MASK_FAT32);\r
}\r
//\r
// If the volume's dirty bit is not set, set it now\r
//\r
- if (!Volume->FatDirty && Volume->FatType != FAT12) {\r
+ if (!Volume->FatDirty && Volume->FatType != Fat12) {\r
Volume->FatDirty = TRUE;\r
- FatAccessVolumeDirty (Volume, WRITE_FAT, &Volume->DirtyValue);\r
+ FatAccessVolumeDirty (Volume, WriteFat, &Volume->DirtyValue);\r
}\r
//\r
// Write the updated fat entry value to the volume\r
//\r
Status = FatDiskIo (\r
Volume,\r
- WRITE_FAT,\r
+ WriteFat,\r
Volume->FatEntryPos,\r
Volume->FatEntrySize,\r
- &Volume->FatEntryBuffer\r
+ &Volume->FatEntryBuffer,\r
+ NULL\r
);\r
return Status;\r
}\r
\r
+/**\r
+\r
+ Free the cluster clain.\r
+\r
+ @param Volume - FAT file system volume.\r
+ @param Cluster - The first cluster of cluster chain.\r
+\r
+ @retval EFI_SUCCESS - The cluster chain is freed successfully.\r
+ @retval EFI_VOLUME_CORRUPTED - There are errors in the file's clusters.\r
+\r
+**/\r
STATIC\r
EFI_STATUS\r
FatFreeClusters (\r
IN FAT_VOLUME *Volume,\r
IN UINTN Cluster\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Free the cluster clain.\r
-\r
-Arguments:\r
-\r
- Volume - FAT file system volume.\r
- Cluster - The first cluster of cluster chain.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - The cluster chain is freed successfully.\r
- EFI_VOLUME_CORRUPTED - There are errors in the file's clusters.\r
-\r
---*/\r
{\r
UINTN LastCluster;\r
\r
return EFI_SUCCESS;\r
}\r
\r
-STATIC\r
-UINTN\r
-FatAllocateCluster (\r
- IN FAT_VOLUME *Volume\r
- )\r
-/*++\r
-\r
-Routine Description:\r
+/**\r
\r
Allocate a free cluster and return the cluster index.\r
\r
-Arguments:\r
-\r
- Volume - FAT file system volume.\r
+ @param Volume - FAT file system volume.\r
\r
-Returns:\r
+ @return The index of the free cluster\r
\r
- The index of the free cluster\r
-\r
---*/\r
+**/\r
+STATIC\r
+UINTN\r
+FatAllocateCluster (\r
+ IN FAT_VOLUME *Volume\r
+ )\r
{\r
UINTN Cluster;\r
\r
return Cluster;\r
}\r
\r
+/**\r
+\r
+ Count the number of clusters given a size.\r
+\r
+ @param Volume - The file system volume.\r
+ @param Size - The size in bytes.\r
+\r
+ @return The number of the clusters.\r
+\r
+**/\r
STATIC\r
UINTN\r
FatSizeToClusters (\r
IN FAT_VOLUME *Volume,\r
IN UINTN Size\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Count the number of clusters given a size\r
-\r
-Arguments:\r
-\r
- Volume - The file system volume.\r
- Size - The size in bytes.\r
-\r
-Returns:\r
-\r
- The number of the clusters.\r
-\r
---*/\r
{\r
UINTN Clusters;\r
\r
return Clusters;\r
}\r
\r
-EFI_STATUS\r
-FatShrinkEof (\r
- IN FAT_OFILE *OFile\r
- )\r
-/*++\r
-\r
-Routine Description:\r
+/**\r
\r
Shrink the end of the open file base on the file size.\r
\r
-Arguments:\r
-\r
- OFile - The open file.\r
-\r
-Returns:\r
+ @param OFile - The open file.\r
\r
- EFI_SUCCESS - Shrinked sucessfully.\r
- EFI_VOLUME_CORRUPTED - There are errors in the file's clusters.\r
+ @retval EFI_SUCCESS - Shrinked sucessfully.\r
+ @retval EFI_VOLUME_CORRUPTED - There are errors in the file's clusters.\r
\r
---*/\r
+**/\r
+EFI_STATUS\r
+FatShrinkEof (\r
+ IN FAT_OFILE *OFile\r
+ )\r
{\r
FAT_VOLUME *Volume;\r
UINTN NewSize;\r
return FatFreeClusters (Volume, Cluster);\r
}\r
\r
-EFI_STATUS\r
-FatGrowEof (\r
- IN FAT_OFILE *OFile,\r
- IN UINT64 NewSizeInBytes\r
- )\r
-/*++\r
-\r
-Routine Description:\r
+/**\r
\r
Grow the end of the open file base on the NewSizeInBytes.\r
\r
-Arguments:\r
-\r
- OFile - The open file.\r
- NewSizeInBytes - The new size in bytes of the open file.\r
-\r
-Returns:\r
+ @param OFile - The open file.\r
+ @param NewSizeInBytes - The new size in bytes of the open file.\r
\r
- EFI_SUCCESS - The file is grown sucessfully.\r
- EFI_UNSUPPORTED - The file size is larger than 4GB.\r
- EFI_VOLUME_CORRUPTED - There are errors in the files' clusters.\r
- EFI_VOLUME_FULL - The volume is full and can not grow the file.\r
+ @retval EFI_SUCCESS - The file is grown sucessfully.\r
+ @retval EFI_UNSUPPORTED - The file size is larger than 4GB.\r
+ @retval EFI_VOLUME_CORRUPTED - There are errors in the files' clusters.\r
+ @retval EFI_VOLUME_FULL - The volume is full and can not grow the file.\r
\r
---*/\r
+**/\r
+EFI_STATUS\r
+FatGrowEof (\r
+ IN FAT_OFILE *OFile,\r
+ IN UINT64 NewSizeInBytes\r
+ )\r
{\r
FAT_VOLUME *Volume;\r
EFI_STATUS Status;\r
ClusterCount = 0;\r
\r
while (!FAT_END_OF_FAT_CHAIN (Cluster)) {\r
- if (Cluster == FAT_CLUSTER_FREE || Cluster >= FAT_CLUSTER_SPECIAL) {\r
+ if (Cluster < FAT_MIN_CLUSTER || Cluster > Volume->MaxCluster + 1) {\r
\r
DEBUG (\r
(EFI_D_INIT | EFI_D_ERROR,\r
goto Done;\r
}\r
\r
+ if (NewCluster < FAT_MIN_CLUSTER || NewCluster > Volume->MaxCluster + 1) {\r
+ Status = EFI_VOLUME_CORRUPTED;\r
+ goto Done;\r
+ }\r
+\r
if (LastCluster != 0) {\r
FatSetFatEntry (Volume, LastCluster, NewCluster);\r
} else {\r
\r
LastCluster = NewCluster;\r
CurSize += 1;\r
+\r
+ //\r
+ // Terminate the cluster list\r
+ //\r
+ // Note that we must do this EVERY time we allocate a cluster, because\r
+ // FatAllocateCluster scans the FAT looking for a free cluster and\r
+ // "LastCluster" is no longer free! Usually, FatAllocateCluster will\r
+ // start looking with the cluster after "LastCluster"; however, when\r
+ // there is only one free cluster left, it will find "LastCluster"\r
+ // a second time. There are other, less predictable scenarios\r
+ // where this could happen, as well.\r
+ //\r
+ FatSetFatEntry (Volume, LastCluster, (UINTN) FAT_CLUSTER_LAST);\r
+ OFile->FileLastCluster = LastCluster;\r
}\r
- //\r
- // Terminate the cluster list\r
- //\r
- FatSetFatEntry (Volume, LastCluster, (UINTN) FAT_CLUSTER_LAST);\r
- OFile->FileLastCluster = LastCluster;\r
}\r
\r
OFile->FileSize = (UINTN) NewSizeInBytes;\r
return Status;\r
}\r
\r
-EFI_STATUS\r
-FatOFilePosition (\r
- IN FAT_OFILE *OFile,\r
- IN UINTN Position,\r
- IN UINTN PosLimit\r
- )\r
-/*++\r
-\r
-Routine Description:\r
+/**\r
\r
Seek OFile to requested position, and calculate the number of\r
consecutive clusters from the position in the file\r
\r
-Arguments:\r
+ @param OFile - The open file.\r
+ @param Position - The file's position which will be accessed.\r
+ @param PosLimit - The maximum length current reading/writing may access\r
\r
- OFile - The open file.\r
- Position - The file's position which will be accessed.\r
- PosLimit - The maximum length current reading/writing may access\r
+ @retval EFI_SUCCESS - Set the info successfully.\r
+ @retval EFI_VOLUME_CORRUPTED - Cluster chain corrupt.\r
\r
-Returns:\r
-\r
- EFI_SUCCESS - Set the info successfully.\r
- EFI_VOLUME_CORRUPTED - Cluster chain corrupt.\r
-\r
---*/\r
+**/\r
+EFI_STATUS\r
+FatOFilePosition (\r
+ IN FAT_OFILE *OFile,\r
+ IN UINTN Position,\r
+ IN UINTN PosLimit\r
+ )\r
{\r
FAT_VOLUME *Volume;\r
UINTN ClusterSize;\r
Cluster = FatGetFatEntry (Volume, Cluster);\r
}\r
\r
- if (Cluster < FAT_MIN_CLUSTER) {\r
+ if (Cluster < FAT_MIN_CLUSTER || Cluster > Volume->MaxCluster + 1) {\r
return EFI_VOLUME_CORRUPTED;\r
}\r
\r
return EFI_SUCCESS;\r
}\r
\r
-UINTN\r
-FatPhysicalDirSize (\r
- IN FAT_VOLUME *Volume,\r
- IN UINTN Cluster\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Get the size of directory of the open file\r
+/**\r
\r
-Arguments:\r
+ Get the size of directory of the open file.\r
\r
- Volume - The File System Volume.\r
- Cluster - The Starting cluster.\r
+ @param Volume - The File System Volume.\r
+ @param Cluster - The Starting cluster.\r
\r
-Returns:\r
-\r
- The physical size of the file starting at the input cluster, if there is error in the\r
+ @return The physical size of the file starting at the input cluster, if there is error in the\r
cluster chain, the return value is 0.\r
\r
---*/\r
+**/\r
+UINTN\r
+FatPhysicalDirSize (\r
+ IN FAT_VOLUME *Volume,\r
+ IN UINTN Cluster\r
+ )\r
{\r
UINTN Size;\r
ASSERT_VOLUME_LOCKED (Volume);\r
return Size;\r
}\r
\r
+/**\r
+\r
+ Get the physical size of a file on the disk.\r
+\r
+ @param Volume - The file system volume.\r
+ @param RealSize - The real size of a file.\r
+\r
+ @return The physical size of a file on the disk.\r
+\r
+**/\r
UINT64\r
FatPhysicalFileSize (\r
IN FAT_VOLUME *Volume,\r
IN UINTN RealSize\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Get the physical size of a file on the disk.\r
-\r
-Arguments:\r
-\r
- Volume - The file system volume.\r
- RealSize - The real size of a file.\r
-\r
-Returns:\r
-\r
- The physical size of a file on the disk.\r
-\r
---*/\r
{\r
UINTN ClusterSizeMask;\r
UINT64 PhysicalSize;\r
return PhysicalSize;\r
}\r
\r
-VOID\r
-FatComputeFreeInfo (\r
- IN FAT_VOLUME *Volume\r
- )\r
-/*++\r
-\r
-Routine Description:\r
+/**\r
\r
Update the free cluster info of FatInfoSector of the volume.\r
\r
-Arguments:\r
-\r
- Volume - FAT file system volume.\r
-\r
-Returns:\r
-\r
- None.\r
+ @param Volume - FAT file system volume.\r
\r
---*/\r
+**/\r
+VOID\r
+FatComputeFreeInfo (\r
+ IN FAT_VOLUME *Volume\r
+ )\r
{\r
UINTN Index;\r
\r