Home | History | Annotate | Download | only in EnhancedFatDxe
      1 /** @file
      2   Main header file for EFI FAT file system driver.
      3 
      4 Copyright (c) 2005 - 2013, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials are licensed and made available
      6 under the terms and conditions of the BSD License which accompanies this
      7 distribution. The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #ifndef _FAT_H_
     16 #define _FAT_H_
     17 
     18 #include <Uefi.h>
     19 
     20 #include <Guid/FileInfo.h>
     21 #include <Guid/FileSystemInfo.h>
     22 #include <Guid/FileSystemVolumeLabelInfo.h>
     23 #include <Protocol/BlockIo.h>
     24 #include <Protocol/DiskIo.h>
     25 #include <Protocol/DiskIo2.h>
     26 #include <Protocol/SimpleFileSystem.h>
     27 #include <Protocol/UnicodeCollation.h>
     28 
     29 #include <Library/PcdLib.h>
     30 #include <Library/DebugLib.h>
     31 #include <Library/UefiLib.h>
     32 #include <Library/BaseLib.h>
     33 #include <Library/BaseMemoryLib.h>
     34 #include <Library/MemoryAllocationLib.h>
     35 #include <Library/UefiDriverEntryPoint.h>
     36 #include <Library/UefiBootServicesTableLib.h>
     37 #include <Library/UefiRuntimeServicesTableLib.h>
     38 
     39 #include "FatFileSystem.h"
     40 
     41 //
     42 // The FAT signature
     43 //
     44 #define FAT_VOLUME_SIGNATURE         SIGNATURE_32 ('f', 'a', 't', 'v')
     45 #define FAT_IFILE_SIGNATURE          SIGNATURE_32 ('f', 'a', 't', 'i')
     46 #define FAT_ODIR_SIGNATURE           SIGNATURE_32 ('f', 'a', 't', 'd')
     47 #define FAT_DIRENT_SIGNATURE         SIGNATURE_32 ('f', 'a', 't', 'e')
     48 #define FAT_OFILE_SIGNATURE          SIGNATURE_32 ('f', 'a', 't', 'o')
     49 #define FAT_TASK_SIGNATURE           SIGNATURE_32 ('f', 'a', 't', 'T')
     50 #define FAT_SUBTASK_SIGNATURE        SIGNATURE_32 ('f', 'a', 't', 'S')
     51 
     52 #define ASSERT_VOLUME_LOCKED(a)      ASSERT_LOCKED (&FatFsLock)
     53 
     54 #define IFILE_FROM_FHAND(a)          CR (a, FAT_IFILE, Handle, FAT_IFILE_SIGNATURE)
     55 
     56 #define DIRENT_FROM_LINK(a)          CR (a, FAT_DIRENT, Link, FAT_DIRENT_SIGNATURE)
     57 
     58 #define VOLUME_FROM_ROOT_DIRENT(a)   CR (a, FAT_VOLUME, RootDirEnt, FAT_VOLUME_SIGNATURE)
     59 
     60 #define VOLUME_FROM_VOL_INTERFACE(a) CR (a, FAT_VOLUME, VolumeInterface, FAT_VOLUME_SIGNATURE);
     61 
     62 #define ODIR_FROM_DIRCACHELINK(a)    CR (a, FAT_ODIR, DirCacheLink, FAT_ODIR_SIGNATURE)
     63 
     64 #define OFILE_FROM_CHECKLINK(a)      CR (a, FAT_OFILE, CheckLink, FAT_OFILE_SIGNATURE)
     65 
     66 #define OFILE_FROM_CHILDLINK(a)      CR (a, FAT_OFILE, ChildLink, FAT_OFILE_SIGNATURE)
     67 
     68 //
     69 // Minimum sector size is 512B, Maximum sector size is 4096B
     70 // Max sectors per cluster is 128
     71 //
     72 #define MAX_BLOCK_ALIGNMENT               12
     73 #define MIN_BLOCK_ALIGNMENT               9
     74 #define MAX_SECTORS_PER_CLUSTER_ALIGNMENT 7
     75 
     76 //
     77 // Efi Time Definition
     78 //
     79 #define IS_LEAP_YEAR(a)                   (((a) % 4 == 0) && (((a) % 100 != 0) || ((a) % 400 == 0)))
     80 
     81 //
     82 // Minimum fat page size is 8K, maximum fat page alignment is 32K
     83 // Minimum data page size is 8K, maximum fat page alignment is 64K
     84 //
     85 #define FAT_FATCACHE_PAGE_MIN_ALIGNMENT   13
     86 #define FAT_FATCACHE_PAGE_MAX_ALIGNMENT   15
     87 #define FAT_DATACACHE_PAGE_MIN_ALIGNMENT  13
     88 #define FAT_DATACACHE_PAGE_MAX_ALIGNMENT  16
     89 #define FAT_DATACACHE_GROUP_COUNT         64
     90 #define FAT_FATCACHE_GROUP_MIN_COUNT      1
     91 #define FAT_FATCACHE_GROUP_MAX_COUNT      16
     92 
     93 //
     94 // Used in 8.3 generation algorithm
     95 //
     96 #define MAX_SPEC_RETRY          4
     97 #define SPEC_BASE_TAG_LEN       6
     98 #define HASH_BASE_TAG_LEN       2
     99 #define HASH_VALUE_TAG_LEN      (SPEC_BASE_TAG_LEN - HASH_BASE_TAG_LEN)
    100 
    101 //
    102 // Path name separator is back slash
    103 //
    104 #define PATH_NAME_SEPARATOR     L'\\'
    105 
    106 
    107 #define EFI_PATH_STRING_LENGTH  260
    108 #define EFI_FILE_STRING_LENGTH  255
    109 #define FAT_MAX_ALLOCATE_SIZE   0xA00000
    110 #define LC_ISO_639_2_ENTRY_SIZE 3
    111 #define MAX_LANG_CODE_SIZE      100
    112 
    113 #define FAT_MAX_DIR_CACHE_COUNT 8
    114 #define FAT_MAX_DIRENTRY_COUNT  0xFFFF
    115 typedef CHAR8                   LC_ISO_639_2;
    116 
    117 //
    118 // The fat types we support
    119 //
    120 typedef enum {
    121   Fat12,
    122   Fat16,
    123   Fat32,
    124   FatUndefined
    125 } FAT_VOLUME_TYPE;
    126 
    127 typedef enum {
    128   CacheFat,
    129   CacheData,
    130   CacheMaxType
    131 } CACHE_DATA_TYPE;
    132 
    133 //
    134 // Used in FatDiskIo
    135 //
    136 typedef enum {
    137   ReadDisk     = 0,  // raw disk read
    138   WriteDisk    = 1,  // raw disk write
    139   ReadFat      = 2,  // read fat cache
    140   WriteFat     = 3,  // write fat cache
    141   ReadData     = 6,  // read data cache
    142   WriteData    = 7   // write data cache
    143 } IO_MODE;
    144 
    145 #define CACHE_ENABLED(a)  ((a) >= 2)
    146 #define RAW_ACCESS(a)     ((IO_MODE)((a) & 0x1))
    147 #define CACHE_TYPE(a)     ((CACHE_DATA_TYPE)((a) >> 2))
    148 
    149 //
    150 // Disk cache tag
    151 //
    152 typedef struct {
    153   UINTN   PageNo;
    154   UINTN   RealSize;
    155   BOOLEAN Dirty;
    156 } CACHE_TAG;
    157 
    158 typedef struct {
    159   UINT64    BaseAddress;
    160   UINT64    LimitAddress;
    161   UINT8     *CacheBase;
    162   BOOLEAN   Dirty;
    163   UINT8     PageAlignment;
    164   UINTN     GroupMask;
    165   CACHE_TAG CacheTag[FAT_DATACACHE_GROUP_COUNT];
    166 } DISK_CACHE;
    167 
    168 //
    169 // Hash table size
    170 //
    171 #define HASH_TABLE_SIZE  0x400
    172 #define HASH_TABLE_MASK  (HASH_TABLE_SIZE - 1)
    173 
    174 //
    175 // The directory entry for opened directory
    176 //
    177 
    178 typedef struct _FAT_DIRENT FAT_DIRENT;
    179 typedef struct _FAT_ODIR FAT_ODIR;
    180 typedef struct _FAT_OFILE FAT_OFILE;
    181 typedef struct _FAT_VOLUME FAT_VOLUME;
    182 
    183 struct _FAT_DIRENT {
    184   UINTN               Signature;
    185   UINT16              EntryPos;               // The position of this directory entry in the parent directory file
    186   UINT8               EntryCount;             // The count of the directory entry in the parent directory file
    187   BOOLEAN             Invalid;                // Indicate whether this directory entry is valid
    188   CHAR16              *FileString;            // The unicode long file name for this directory entry
    189   FAT_OFILE           *OFile;                 // The OFile of the corresponding directory entry
    190   FAT_DIRENT          *ShortNameForwardLink;  // Hash successor link for short filename
    191   FAT_DIRENT          *LongNameForwardLink;   // Hash successor link for long filename
    192   LIST_ENTRY          Link;                   // Connection of every directory entry
    193   FAT_DIRECTORY_ENTRY Entry;                  // The physical directory entry stored in disk
    194 };
    195 
    196 struct _FAT_ODIR {
    197   UINTN               Signature;
    198   UINT32              CurrentEndPos;          // Current end position of the directory
    199   UINT32              CurrentPos;             // Current position of the directory
    200   LIST_ENTRY          *CurrentCursor;         // Current directory entry pointer
    201   LIST_ENTRY          ChildList;              // List of all directory entries
    202   BOOLEAN             EndOfDir;               // Indicate whether we have reached the end of the directory
    203   LIST_ENTRY          DirCacheLink;           // Linked in Volume->DirCacheList when discarded
    204   UINTN               DirCacheTag;            // The identification of the directory when in directory cache
    205   FAT_DIRENT          *LongNameHashTable[HASH_TABLE_SIZE];
    206   FAT_DIRENT          *ShortNameHashTable[HASH_TABLE_SIZE];
    207 };
    208 
    209 typedef struct {
    210   UINTN               Signature;
    211   EFI_FILE_PROTOCOL   Handle;
    212   UINT64              Position;
    213   BOOLEAN             ReadOnly;
    214   FAT_OFILE          *OFile;
    215   LIST_ENTRY          Tasks;                  // List of all FAT_TASKs
    216   LIST_ENTRY          Link;                   // Link to other IFiles
    217 } FAT_IFILE;
    218 
    219 typedef struct {
    220   UINTN               Signature;
    221   EFI_FILE_IO_TOKEN   *FileIoToken;
    222   FAT_IFILE           *IFile;
    223   LIST_ENTRY          Subtasks;               // List of all FAT_SUBTASKs
    224   LIST_ENTRY          Link;                   // Link to other FAT_TASKs
    225 } FAT_TASK;
    226 
    227 typedef struct {
    228   UINTN               Signature;
    229   EFI_DISK_IO2_TOKEN  DiskIo2Token;
    230   FAT_TASK            *Task;
    231   BOOLEAN             Write;
    232   UINT64              Offset;
    233   VOID                *Buffer;
    234   UINTN               BufferSize;
    235   LIST_ENTRY          Link;
    236 } FAT_SUBTASK;
    237 
    238 //
    239 // FAT_OFILE - Each opened file
    240 //
    241 struct _FAT_OFILE {
    242   UINTN               Signature;
    243   FAT_VOLUME          *Volume;
    244   //
    245   // A permanant error code to return to all accesses to
    246   // this opened file
    247   //
    248   EFI_STATUS          Error;
    249   //
    250   // A list of the IFILE instances for this OFile
    251   //
    252   LIST_ENTRY          Opens;
    253 
    254   //
    255   // The dynamic infomation
    256   //
    257   UINTN               FileSize;
    258   UINTN               FileCluster;
    259   UINTN               FileCurrentCluster;
    260   UINTN               FileLastCluster;
    261 
    262   //
    263   // Dirty is set if there have been any updates to the
    264   // file
    265   // Archive is set if the archive attribute in the file's
    266   // directory entry needs to be set when performing flush
    267   // PreserveLastMod is set if the last modification of the
    268   // file is specified by SetInfo API
    269   //
    270   BOOLEAN             Dirty;
    271   BOOLEAN             IsFixedRootDir;
    272   BOOLEAN             PreserveLastModification;
    273   BOOLEAN             Archive;
    274   //
    275   // Set by an OFile SetPosition
    276   //
    277   UINTN               Position; // within file
    278   UINT64              PosDisk;  // on the disk
    279   UINTN               PosRem;   // remaining in this disk run
    280   //
    281   // The opened parent, full path length and currently opened child files
    282   //
    283   FAT_OFILE           *Parent;
    284   UINTN               FullPathLen;
    285   LIST_ENTRY          ChildHead;
    286   LIST_ENTRY          ChildLink;
    287 
    288   //
    289   // The opened directory structure for a directory; if this
    290   // OFile represents a file, then ODir = NULL
    291   //
    292   FAT_ODIR            *ODir;
    293   //
    294   // The directory entry for the Ofile
    295   //
    296   FAT_DIRENT          *DirEnt;
    297 
    298   //
    299   // Link in Volume's reference list
    300   //
    301   LIST_ENTRY          CheckLink;
    302 };
    303 
    304 struct _FAT_VOLUME {
    305   UINTN                           Signature;
    306 
    307   EFI_HANDLE                      Handle;
    308   BOOLEAN                         Valid;
    309   BOOLEAN                         DiskError;
    310 
    311   EFI_SIMPLE_FILE_SYSTEM_PROTOCOL VolumeInterface;
    312 
    313   //
    314   // If opened, the parent handle and BlockIo interface
    315   //
    316   EFI_BLOCK_IO_PROTOCOL           *BlockIo;
    317   EFI_DISK_IO_PROTOCOL            *DiskIo;
    318   EFI_DISK_IO2_PROTOCOL           *DiskIo2;
    319   UINT32                          MediaId;
    320   BOOLEAN                         ReadOnly;
    321 
    322   //
    323   // Computed values from fat bpb info
    324   //
    325   UINT64                          VolumeSize;
    326   UINT64                          FatPos;           // Disk pos of fat tables
    327   UINT64                          RootPos;          // Disk pos of root directory
    328   UINT64                          FirstClusterPos;  // Disk pos of first cluster
    329   UINTN                           FatSize;          // Number of bytes in each fat
    330   UINTN                           MaxCluster;       // Max cluster number
    331   UINTN                           ClusterSize;      // Cluster size of fat partition
    332   UINT8                           ClusterAlignment; // Equal to log_2 (clustersize);
    333   FAT_VOLUME_TYPE                 FatType;
    334 
    335   //
    336   // Current part of fat table that's present
    337   //
    338   UINT64                          FatEntryPos;    // Location of buffer
    339   UINTN                           FatEntrySize;   // Size of buffer
    340   UINT32                          FatEntryBuffer; // The buffer
    341   FAT_INFO_SECTOR                 FatInfoSector;  // Free cluster info
    342   UINTN                           FreeInfoPos;    // Pos with the free cluster info
    343   BOOLEAN                         FreeInfoValid;  // If free cluster info is valid
    344   //
    345   // Unpacked Fat BPB info
    346   //
    347   UINTN                           NumFats;
    348   UINTN                           RootEntries;    // < FAT32, root dir is fixed size
    349   UINTN                           RootCluster;    // >= FAT32, root cluster chain head
    350   //
    351   // info for marking the volume dirty or not
    352   //
    353   BOOLEAN                         FatDirty;       // If fat-entries have been updated
    354   UINT32                          DirtyValue;
    355   UINT32                          NotDirtyValue;
    356 
    357   //
    358   // The root directory entry and opened root file
    359   //
    360   FAT_DIRENT                      RootDirEnt;
    361   //
    362   // File Name of root OFile, it is empty string
    363   //
    364   CHAR16                          RootFileString[1];
    365   FAT_OFILE                       *Root;
    366 
    367   //
    368   // New OFiles are added to this list so they
    369   // can be cleaned up if they aren't referenced.
    370   //
    371   LIST_ENTRY                      CheckRef;
    372 
    373   //
    374   // Directory cache List
    375   //
    376   LIST_ENTRY                      DirCacheList;
    377   UINTN                           DirCacheCount;
    378 
    379   //
    380   // Disk Cache for this volume
    381   //
    382   VOID                            *CacheBuffer;
    383   DISK_CACHE                      DiskCache[CacheMaxType];
    384 };
    385 
    386 //
    387 // Function Prototypes
    388 //
    389 
    390 /**
    391 
    392   Implements Open() of Simple File System Protocol.
    393 
    394   @param  FHand                 - File handle of the file serves as a starting reference point.
    395   @param  NewHandle             - Handle of the file that is newly opened.
    396   @param  FileName              - File name relative to FHand.
    397   @param  OpenMode              - Open mode.
    398   @param  Attributes            - Attributes to set if the file is created.
    399 
    400 
    401   @retval EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty.
    402                           The OpenMode is not supported.
    403                           The Attributes is not the valid attributes.
    404   @retval EFI_OUT_OF_RESOURCES  - Can not allocate the memory for file string.
    405   @retval EFI_SUCCESS           - Open the file successfully.
    406   @return Others                - The status of open file.
    407 
    408 **/
    409 EFI_STATUS
    410 EFIAPI
    411 FatOpen (
    412   IN  EFI_FILE_PROTOCOL *FHand,
    413   OUT EFI_FILE_PROTOCOL **NewHandle,
    414   IN  CHAR16            *FileName,
    415   IN  UINT64            OpenMode,
    416   IN  UINT64            Attributes
    417   )
    418 ;
    419 
    420 /**
    421 
    422   Implements OpenEx() of Simple File System Protocol.
    423 
    424   @param  FHand                 - File handle of the file serves as a starting reference point.
    425   @param  NewHandle             - Handle of the file that is newly opened.
    426   @param  FileName              - File name relative to FHand.
    427   @param  OpenMode              - Open mode.
    428   @param  Attributes            - Attributes to set if the file is created.
    429   @param  Token                 - A pointer to the token associated with the transaction.
    430 
    431   @retval EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty.
    432                           The OpenMode is not supported.
    433                           The Attributes is not the valid attributes.
    434   @retval EFI_OUT_OF_RESOURCES  - Can not allocate the memory for file string.
    435   @retval EFI_SUCCESS           - Open the file successfully.
    436   @return Others                - The status of open file.
    437 
    438 **/
    439 EFI_STATUS
    440 EFIAPI
    441 FatOpenEx (
    442   IN  EFI_FILE_PROTOCOL       *FHand,
    443   OUT EFI_FILE_PROTOCOL       **NewHandle,
    444   IN  CHAR16                  *FileName,
    445   IN  UINT64                  OpenMode,
    446   IN  UINT64                  Attributes,
    447   IN OUT EFI_FILE_IO_TOKEN    *Token
    448   )
    449 ;
    450 
    451 /**
    452 
    453   Get the file's position of the file
    454 
    455   @param  FHand                 - The handle of file.
    456   @param  Position              - The file's position of the file.
    457 
    458   @retval EFI_SUCCESS           - Get the info successfully.
    459   @retval EFI_DEVICE_ERROR      - Can not find the OFile for the file.
    460   @retval EFI_UNSUPPORTED       - The open file is not a file.
    461 
    462 **/
    463 EFI_STATUS
    464 EFIAPI
    465 FatGetPosition (
    466   IN  EFI_FILE_PROTOCOL *FHand,
    467   OUT UINT64            *Position
    468   )
    469 ;
    470 
    471 /**
    472 
    473   Get the some types info of the file into Buffer
    474 
    475   @param  FHand                 - The handle of file.
    476   @param  Type                  - The type of the info.
    477   @param  BufferSize            - Size of Buffer.
    478   @param  Buffer                - Buffer containing volume info.
    479 
    480   @retval EFI_SUCCESS           - Get the info successfully.
    481   @retval EFI_DEVICE_ERROR      - Can not find the OFile for the file.
    482 
    483 **/
    484 EFI_STATUS
    485 EFIAPI
    486 FatGetInfo (
    487   IN     EFI_FILE_PROTOCOL      *FHand,
    488   IN     EFI_GUID               *Type,
    489   IN OUT UINTN                  *BufferSize,
    490      OUT VOID                   *Buffer
    491   )
    492 ;
    493 
    494 /**
    495 
    496   Set the some types info of the file into Buffer.
    497 
    498   @param  FHand                 - The handle of file.
    499   @param  Type                  - The type of the info.
    500   @param  BufferSize            - Size of Buffer.
    501   @param  Buffer                - Buffer containing volume info.
    502 
    503   @retval EFI_SUCCESS           - Set the info successfully.
    504   @retval EFI_DEVICE_ERROR      - Can not find the OFile for the file.
    505 
    506 **/
    507 EFI_STATUS
    508 EFIAPI
    509 FatSetInfo (
    510   IN EFI_FILE_PROTOCOL  *FHand,
    511   IN EFI_GUID           *Type,
    512   IN UINTN              BufferSize,
    513   IN VOID               *Buffer
    514   )
    515 ;
    516 
    517 /**
    518 
    519   Flushes all data associated with the file handle.
    520 
    521   @param  FHand                 - Handle to file to flush
    522 
    523   @retval EFI_SUCCESS           - Flushed the file successfully
    524   @retval EFI_WRITE_PROTECTED   - The volume is read only
    525   @retval EFI_ACCESS_DENIED     - The volume is not read only
    526                           but the file is read only
    527   @return Others                - Flushing of the file is failed
    528 
    529 **/
    530 EFI_STATUS
    531 EFIAPI
    532 FatFlush (
    533   IN EFI_FILE_PROTOCOL  *FHand
    534   )
    535 ;
    536 
    537 /**
    538 
    539   Flushes all data associated with the file handle.
    540 
    541   @param  FHand                 - Handle to file to flush.
    542   @param  Token                 - A pointer to the token associated with the transaction.
    543 
    544   @retval EFI_SUCCESS           - Flushed the file successfully.
    545   @retval EFI_WRITE_PROTECTED   - The volume is read only.
    546   @retval EFI_ACCESS_DENIED     - The file is read only.
    547   @return Others                - Flushing of the file failed.
    548 
    549 **/
    550 EFI_STATUS
    551 EFIAPI
    552 FatFlushEx (
    553   IN EFI_FILE_PROTOCOL  *FHand,
    554   IN EFI_FILE_IO_TOKEN  *Token
    555   )
    556 ;
    557 
    558 /**
    559 
    560   Flushes & Closes the file handle.
    561 
    562   @param  FHand                 - Handle to the file to delete.
    563 
    564   @retval EFI_SUCCESS           - Closed the file successfully.
    565 
    566 **/
    567 EFI_STATUS
    568 EFIAPI
    569 FatClose (
    570   IN EFI_FILE_PROTOCOL  *FHand
    571   )
    572 ;
    573 
    574 /**
    575 
    576   Deletes the file & Closes the file handle.
    577 
    578   @param  FHand                    - Handle to the file to delete.
    579 
    580   @retval EFI_SUCCESS              - Delete the file successfully.
    581   @retval EFI_WARN_DELETE_FAILURE  - Fail to delete the file.
    582 
    583 **/
    584 EFI_STATUS
    585 EFIAPI
    586 FatDelete (
    587   IN EFI_FILE_PROTOCOL  *FHand
    588   )
    589 ;
    590 
    591 /**
    592 
    593   Set the file's position of the file.
    594 
    595   @param  FHand                 - The handle of file
    596   @param  Position              - The file's position of the file
    597 
    598   @retval EFI_SUCCESS           - Set the info successfully
    599   @retval EFI_DEVICE_ERROR      - Can not find the OFile for the file
    600   @retval EFI_UNSUPPORTED       - Set a directory with a not-zero position
    601 
    602 **/
    603 EFI_STATUS
    604 EFIAPI
    605 FatSetPosition (
    606   IN EFI_FILE_PROTOCOL  *FHand,
    607   IN UINT64             Position
    608   )
    609 ;
    610 
    611 /**
    612 
    613   Get the file info.
    614 
    615   @param FHand                 - The handle of the file.
    616   @param BufferSize            - Size of Buffer.
    617   @param Buffer                - Buffer containing read data.
    618 
    619   @retval EFI_SUCCESS           - Get the file info successfully.
    620   @retval EFI_DEVICE_ERROR      - Can not find the OFile for the file.
    621   @retval EFI_VOLUME_CORRUPTED  - The file type of open file is error.
    622   @return other                 - An error occurred when operation the disk.
    623 
    624 **/
    625 EFI_STATUS
    626 EFIAPI
    627 FatRead (
    628   IN     EFI_FILE_PROTOCOL    *FHand,
    629   IN OUT UINTN                *BufferSize,
    630      OUT VOID                 *Buffer
    631   )
    632 ;
    633 
    634 /**
    635 
    636   Get the file info.
    637 
    638   @param FHand                 - The handle of the file.
    639   @param Token                 - A pointer to the token associated with the transaction.
    640 
    641   @retval EFI_SUCCESS           - Get the file info successfully.
    642   @retval EFI_DEVICE_ERROR      - Can not find the OFile for the file.
    643   @retval EFI_VOLUME_CORRUPTED  - The file type of open file is error.
    644   @return other                 - An error occurred when operation the disk.
    645 
    646 **/
    647 EFI_STATUS
    648 EFIAPI
    649 FatReadEx (
    650   IN     EFI_FILE_PROTOCOL  *FHand,
    651   IN OUT EFI_FILE_IO_TOKEN  *Token
    652   )
    653 ;
    654 
    655 /**
    656 
    657   Set the file info.
    658 
    659   @param  FHand                 - The handle of the file.
    660   @param  BufferSize            - Size of Buffer.
    661   @param Buffer                - Buffer containing write data.
    662 
    663   @retval EFI_SUCCESS           - Set the file info successfully.
    664   @retval EFI_WRITE_PROTECTED   - The disk is write protected.
    665   @retval EFI_ACCESS_DENIED     - The file is read-only.
    666   @retval EFI_DEVICE_ERROR      - The OFile is not valid.
    667   @retval EFI_UNSUPPORTED       - The open file is not a file.
    668                         - The writing file size is larger than 4GB.
    669   @return other                 - An error occurred when operation the disk.
    670 
    671 **/
    672 EFI_STATUS
    673 EFIAPI
    674 FatWrite (
    675   IN     EFI_FILE_PROTOCOL      *FHand,
    676   IN OUT UINTN                  *BufferSize,
    677   IN     VOID                   *Buffer
    678   )
    679 ;
    680 
    681 /**
    682 
    683   Get the file info.
    684 
    685   @param  FHand                 - The handle of the file.
    686   @param  Token                 - A pointer to the token associated with the transaction.
    687 
    688   @retval EFI_SUCCESS           - Get the file info successfully.
    689   @retval EFI_DEVICE_ERROR      - Can not find the OFile for the file.
    690   @retval EFI_VOLUME_CORRUPTED  - The file type of open file is error.
    691   @return other                 - An error occurred when operation the disk.
    692 
    693 **/
    694 EFI_STATUS
    695 EFIAPI
    696 FatWriteEx (
    697   IN     EFI_FILE_PROTOCOL  *FHand,
    698   IN OUT EFI_FILE_IO_TOKEN  *Token
    699   )
    700 ;
    701 
    702 //
    703 // DiskCache.c
    704 //
    705 /**
    706 
    707   Initialize the disk cache according to Volume's FatType.
    708 
    709   @param  Volume                - FAT file system volume.
    710 
    711   @retval EFI_SUCCESS           - The disk cache is successfully initialized.
    712   @retval EFI_OUT_OF_RESOURCES  - Not enough memory to allocate disk cache.
    713 
    714 **/
    715 EFI_STATUS
    716 FatInitializeDiskCache (
    717   IN FAT_VOLUME              *Volume
    718   );
    719 
    720 /**
    721 
    722   Read BufferSize bytes from the position of Offset into Buffer,
    723   or write BufferSize bytes from Buffer into the position of Offset.
    724 
    725   Base on the parameter of CACHE_DATA_TYPE, the data access will be divided into
    726   the access of FAT cache (CACHE_FAT) and the access of Data cache (CACHE_DATA):
    727 
    728   1. Access of FAT cache (CACHE_FAT): Access the data in the FAT cache, if there is cache
    729      page hit, just return the cache page; else update the related cache page and return
    730      the right cache page.
    731   2. Access of Data cache (CACHE_DATA):
    732      The access data will be divided into UnderRun data, Aligned data and OverRun data;
    733      The UnderRun data and OverRun data will be accessed by the Data cache,
    734      but the Aligned data will be accessed with disk directly.
    735 
    736   @param  Volume                - FAT file system volume.
    737   @param  CacheDataType         - The type of cache: CACHE_DATA or CACHE_FAT.
    738   @param  IoMode                - Indicate the type of disk access.
    739   @param  Offset                - The starting byte offset to read from.
    740   @param  BufferSize            - Size of Buffer.
    741   @param  Buffer                - Buffer containing cache data.
    742   @param  Task                    point to task instance.
    743 
    744   @retval EFI_SUCCESS           - The data was accessed correctly.
    745   @retval EFI_MEDIA_CHANGED     - The MediaId does not match the current device.
    746   @return Others                - An error occurred when accessing cache.
    747 
    748 **/
    749 EFI_STATUS
    750 FatAccessCache (
    751   IN     FAT_VOLUME          *Volume,
    752   IN     CACHE_DATA_TYPE     CacheDataType,
    753   IN     IO_MODE             IoMode,
    754   IN     UINT64              Offset,
    755   IN     UINTN               BufferSize,
    756   IN OUT UINT8               *Buffer,
    757   IN     FAT_TASK            *Task
    758   );
    759 
    760 /**
    761 
    762   Flush all the dirty cache back, include the FAT cache and the Data cache.
    763 
    764   @param  Volume                - FAT file system volume.
    765   @param  Task                    point to task instance.
    766 
    767   @retval EFI_SUCCESS           - Flush all the dirty cache back successfully
    768   @return other                 - An error occurred when writing the data into the disk
    769 
    770 **/
    771 EFI_STATUS
    772 FatVolumeFlushCache (
    773   IN FAT_VOLUME              *Volume,
    774   IN FAT_TASK                *Task
    775   );
    776 
    777 //
    778 // Flush.c
    779 //
    780 /**
    781 
    782   Flush the data associated with an open file.
    783   In this implementation, only last Mod/Access time is updated.
    784 
    785   @param  OFile                 - The open file.
    786 
    787   @retval EFI_SUCCESS           - The OFile is flushed successfully.
    788   @return Others                - An error occurred when flushing this OFile.
    789 
    790 **/
    791 EFI_STATUS
    792 FatOFileFlush (
    793   IN FAT_OFILE          *OFile
    794   );
    795 
    796 /**
    797 
    798   Check the references of the OFile.
    799   If the OFile (that is checked) is no longer
    800   referenced, then it is freed.
    801 
    802   @param  OFile                 - The OFile to be checked.
    803 
    804   @retval TRUE                  - The OFile is not referenced and freed.
    805   @retval FALSE                 - The OFile is kept.
    806 
    807 **/
    808 BOOLEAN
    809 FatCheckOFileRef (
    810   IN FAT_OFILE          *OFile
    811   );
    812 
    813 /**
    814 
    815   Set the OFile and its child OFile with the error Status
    816 
    817   @param  OFile                 - The OFile whose permanent error code is to be set.
    818   @param  Status                - Error code to be set.
    819 
    820 **/
    821 VOID
    822 FatSetVolumeError (
    823   IN FAT_OFILE          *OFile,
    824   IN EFI_STATUS         Status
    825   );
    826 
    827 /**
    828 
    829   Close the open file instance.
    830 
    831   @param  IFile                 - Open file instance.
    832 
    833   @retval EFI_SUCCESS           - Closed the file successfully.
    834 
    835 **/
    836 EFI_STATUS
    837 FatIFileClose (
    838   FAT_IFILE             *IFile
    839   );
    840 
    841 /**
    842 
    843   Set error status for a specific OFile, reference checking the volume.
    844   If volume is already marked as invalid, and all resources are freed
    845   after reference checking, the file system protocol is uninstalled and
    846   the volume structure is freed.
    847 
    848   @param  Volume                - the Volume that is to be reference checked and unlocked.
    849   @param  OFile                 - the OFile whose permanent error code is to be set.
    850   @param  EfiStatus             - error code to be set.
    851   @param  Task                    point to task instance.
    852 
    853   @retval EFI_SUCCESS           - Clean up the volume successfully.
    854   @return Others                - Cleaning up of the volume is failed.
    855 
    856 **/
    857 EFI_STATUS
    858 FatCleanupVolume (
    859   IN FAT_VOLUME         *Volume,
    860   IN FAT_OFILE          *OFile,
    861   IN EFI_STATUS         EfiStatus,
    862   IN FAT_TASK           *Task
    863   );
    864 
    865 //
    866 // FileSpace.c
    867 //
    868 /**
    869 
    870   Shrink the end of the open file base on the file size.
    871 
    872   @param  OFile                 - The open file.
    873 
    874   @retval EFI_SUCCESS           - Shrinked sucessfully.
    875   @retval EFI_VOLUME_CORRUPTED  - There are errors in the file's clusters.
    876 
    877 **/
    878 EFI_STATUS
    879 FatShrinkEof (
    880   IN FAT_OFILE          *OFile
    881   );
    882 
    883 /**
    884 
    885   Grow the end of the open file base on the NewSizeInBytes.
    886 
    887   @param  OFile                 - The open file.
    888   @param  NewSizeInBytes        - The new size in bytes of the open file.
    889 
    890   @retval EFI_SUCCESS           - The file is grown sucessfully.
    891   @retval EFI_UNSUPPORTED       - The file size is larger than 4GB.
    892   @retval EFI_VOLUME_CORRUPTED  - There are errors in the files' clusters.
    893   @retval EFI_VOLUME_FULL       - The volume is full and can not grow the file.
    894 
    895 **/
    896 EFI_STATUS
    897 FatGrowEof (
    898   IN FAT_OFILE          *OFile,
    899   IN UINT64             NewSizeInBytes
    900   );
    901 
    902 /**
    903 
    904   Get the size of directory of the open file.
    905 
    906   @param  Volume                - The File System Volume.
    907   @param  Cluster               - The Starting cluster.
    908 
    909   @return The physical size of the file starting at the input cluster, if there is error in the
    910   cluster chain, the return value is 0.
    911 
    912 **/
    913 UINTN
    914 FatPhysicalDirSize (
    915   IN FAT_VOLUME         *Volume,
    916   IN UINTN              Cluster
    917   );
    918 
    919 /**
    920 
    921   Get the physical size of a file on the disk.
    922 
    923   @param  Volume                - The file system volume.
    924   @param  RealSize              - The real size of a file.
    925 
    926   @return The physical size of a file on the disk.
    927 
    928 **/
    929 UINT64
    930 FatPhysicalFileSize (
    931   IN FAT_VOLUME         *Volume,
    932   IN UINTN              RealSize
    933   );
    934 
    935 /**
    936 
    937   Seek OFile to requested position, and calculate the number of
    938   consecutive clusters from the position in the file
    939 
    940   @param  OFile                 - The open file.
    941   @param  Position              - The file's position which will be accessed.
    942   @param  PosLimit              - The maximum length current reading/writing may access
    943 
    944   @retval EFI_SUCCESS           - Set the info successfully.
    945   @retval EFI_VOLUME_CORRUPTED  - Cluster chain corrupt.
    946 
    947 **/
    948 EFI_STATUS
    949 FatOFilePosition (
    950   IN FAT_OFILE            *OFile,
    951   IN UINTN                Position,
    952   IN UINTN                PosLimit
    953   );
    954 
    955 /**
    956 
    957   Update the free cluster info of FatInfoSector of the volume.
    958 
    959   @param  Volume                - FAT file system volume.
    960 
    961 **/
    962 VOID
    963 FatComputeFreeInfo (
    964   IN FAT_VOLUME         *Volume
    965   );
    966 
    967 //
    968 // Init.c
    969 //
    970 /**
    971 
    972   Allocates volume structure, detects FAT file system, installs protocol,
    973   and initialize cache.
    974 
    975   @param  Handle                - The handle of parent device.
    976   @param  DiskIo                - The DiskIo of parent device.
    977   @param  DiskIo2               - The DiskIo2 of parent device.
    978   @param  BlockIo               - The BlockIo of parent devicel
    979 
    980   @retval EFI_SUCCESS           - Allocate a new volume successfully.
    981   @retval EFI_OUT_OF_RESOURCES  - Can not allocate the memory.
    982   @return Others                - Allocating a new volume failed.
    983 
    984 **/
    985 EFI_STATUS
    986 FatAllocateVolume (
    987   IN  EFI_HANDLE                     Handle,
    988   IN  EFI_DISK_IO_PROTOCOL           *DiskIo,
    989   IN  EFI_DISK_IO2_PROTOCOL          *DiskIo2,
    990   IN  EFI_BLOCK_IO_PROTOCOL          *BlockIo
    991   );
    992 
    993 /**
    994 
    995   Detects FAT file system on Disk and set relevant fields of Volume.
    996 
    997   @param Volume                - The volume structure.
    998 
    999   @retval EFI_SUCCESS           - The Fat File System is detected successfully
   1000   @retval EFI_UNSUPPORTED       - The volume is not FAT file system.
   1001   @retval EFI_VOLUME_CORRUPTED  - The volume is corrupted.
   1002 
   1003 **/
   1004 EFI_STATUS
   1005 FatOpenDevice (
   1006   IN OUT FAT_VOLUME     *Volume
   1007   );
   1008 
   1009 /**
   1010 
   1011   Called by FatDriverBindingStop(), Abandon the volume.
   1012 
   1013   @param  Volume                - The volume to be abandoned.
   1014 
   1015   @retval EFI_SUCCESS           - Abandoned the volume successfully.
   1016   @return Others                - Can not uninstall the protocol interfaces.
   1017 
   1018 **/
   1019 EFI_STATUS
   1020 FatAbandonVolume (
   1021   IN FAT_VOLUME         *Volume
   1022   );
   1023 
   1024 //
   1025 // Misc.c
   1026 //
   1027 /**
   1028 
   1029   Create the task
   1030 
   1031   @param  IFile                 - The instance of the open file.
   1032   @param  Token                 - A pointer to the token associated with the transaction.
   1033 
   1034   @return FAT_TASK *            - Return the task instance.
   1035 
   1036 **/
   1037 FAT_TASK *
   1038 FatCreateTask (
   1039   FAT_IFILE           *IFile,
   1040   EFI_FILE_IO_TOKEN   *Token
   1041   );
   1042 
   1043 /**
   1044 
   1045   Destroy the task.
   1046 
   1047   @param  Task                  - The task to be destroyed.
   1048 
   1049 **/
   1050 VOID
   1051 FatDestroyTask (
   1052   FAT_TASK            *Task
   1053   );
   1054 
   1055 /**
   1056 
   1057   Wait all non-blocking requests complete.
   1058 
   1059   @param  IFile                 - The instance of the open file.
   1060 
   1061 **/
   1062 VOID
   1063 FatWaitNonblockingTask (
   1064   FAT_IFILE           *IFile
   1065   );
   1066 
   1067 /**
   1068 
   1069   Remove the subtask from subtask list.
   1070 
   1071   @param  Subtask               - The subtask to be removed.
   1072 
   1073   @return LIST_ENTRY *          - The next node in the list.
   1074 
   1075 **/
   1076 LIST_ENTRY *
   1077 FatDestroySubtask (
   1078   FAT_SUBTASK         *Subtask
   1079   );
   1080 
   1081 /**
   1082 
   1083   Execute the task.
   1084 
   1085   @param  IFile                 - The instance of the open file.
   1086   @param  Task                  - The task to be executed.
   1087 
   1088   @retval EFI_SUCCESS           - The task was executed sucessfully.
   1089   @return other                 - An error occurred when executing the task.
   1090 
   1091 **/
   1092 EFI_STATUS
   1093 FatQueueTask (
   1094   IN FAT_IFILE        *IFile,
   1095   IN FAT_TASK         *Task
   1096   );
   1097 
   1098 /**
   1099 
   1100   Set the volume as dirty or not.
   1101 
   1102   @param  Volume                - FAT file system volume.
   1103   @param  IoMode                - The access mode.
   1104   @param  DirtyValue            - Set the volume as dirty or not.
   1105 
   1106   @retval EFI_SUCCESS           - Set the new FAT entry value sucessfully.
   1107   @return other                 - An error occurred when operation the FAT entries.
   1108 
   1109 **/
   1110 EFI_STATUS
   1111 FatAccessVolumeDirty (
   1112   IN FAT_VOLUME         *Volume,
   1113   IN IO_MODE            IoMode,
   1114   IN VOID               *DirtyValue
   1115   );
   1116 
   1117 /**
   1118 
   1119   General disk access function.
   1120 
   1121   @param  Volume                - FAT file system volume.
   1122   @param  IoMode                - The access mode (disk read/write or cache access).
   1123   @param  Offset                - The starting byte offset to read from.
   1124   @param  BufferSize            - Size of Buffer.
   1125   @param  Buffer                - Buffer containing read data.
   1126   @param  Task                    point to task instance.
   1127 
   1128   @retval EFI_SUCCESS           - The operation is performed successfully.
   1129   @retval EFI_VOLUME_CORRUPTED  - The accesss is
   1130   @return Others                - The status of read/write the disk
   1131 
   1132 **/
   1133 EFI_STATUS
   1134 FatDiskIo (
   1135   IN FAT_VOLUME         *Volume,
   1136   IN IO_MODE            IoMode,
   1137   IN UINT64             Offset,
   1138   IN UINTN              BufferSize,
   1139   IN OUT VOID           *Buffer,
   1140   IN FAT_TASK           *Task
   1141   );
   1142 
   1143 /**
   1144 
   1145   Lock the volume.
   1146 
   1147 **/
   1148 VOID
   1149 FatAcquireLock (
   1150   VOID
   1151   );
   1152 
   1153 /**
   1154 
   1155   Unlock the volume.
   1156 
   1157 **/
   1158 VOID
   1159 FatReleaseLock (
   1160   VOID
   1161   );
   1162 
   1163 /**
   1164 
   1165   Lock the volume.
   1166   If the lock is already in the acquired state, then EFI_ACCESS_DENIED is returned.
   1167   Otherwise, EFI_SUCCESS is returned.
   1168 
   1169   @retval EFI_SUCCESS           - The volume is locked.
   1170   @retval EFI_ACCESS_DENIED     - The volume could not be locked because it is already locked.
   1171 
   1172 **/
   1173 EFI_STATUS
   1174 FatAcquireLockOrFail (
   1175   VOID
   1176   );
   1177 
   1178 /**
   1179 
   1180   Free directory entry.
   1181 
   1182   @param  DirEnt                - The directory entry to be freed.
   1183 
   1184 **/
   1185 VOID
   1186 FatFreeDirEnt (
   1187   IN FAT_DIRENT         *DirEnt
   1188   );
   1189 
   1190 /**
   1191 
   1192   Free volume structure (including the contents of directory cache and disk cache).
   1193 
   1194   @param  Volume                - The volume structure to be freed.
   1195 
   1196 **/
   1197 VOID
   1198 FatFreeVolume (
   1199   IN FAT_VOLUME         *Volume
   1200   );
   1201 
   1202 /**
   1203 
   1204   Translate EFI time to FAT time.
   1205 
   1206   @param  ETime                 - The time of EFI_TIME.
   1207   @param  FTime                 - The time of FAT_DATE_TIME.
   1208 
   1209 **/
   1210 VOID
   1211 FatEfiTimeToFatTime (
   1212   IN EFI_TIME           *ETime,
   1213   OUT FAT_DATE_TIME     *FTime
   1214   );
   1215 
   1216 /**
   1217 
   1218   Translate Fat time to EFI time.
   1219 
   1220   @param  FTime                 - The time of FAT_DATE_TIME.
   1221   @param  ETime                 - The time of EFI_TIME..
   1222 
   1223 **/
   1224 VOID
   1225 FatFatTimeToEfiTime (
   1226   IN FAT_DATE_TIME      *FTime,
   1227   OUT EFI_TIME          *ETime
   1228   );
   1229 
   1230 /**
   1231 
   1232   Get Current FAT time.
   1233 
   1234   @param  FatTime               - Current FAT time.
   1235 
   1236 **/
   1237 VOID
   1238 FatGetCurrentFatTime (
   1239   OUT FAT_DATE_TIME     *FatTime
   1240   );
   1241 
   1242 /**
   1243 
   1244   Check whether a time is valid.
   1245 
   1246   @param  Time                  - The time of EFI_TIME.
   1247 
   1248   @retval TRUE                  - The time is valid.
   1249   @retval FALSE                 - The time is not valid.
   1250 
   1251 **/
   1252 BOOLEAN
   1253 FatIsValidTime (
   1254   IN EFI_TIME           *Time
   1255   );
   1256 
   1257 //
   1258 // UnicodeCollation.c
   1259 //
   1260 /**
   1261   Initialize Unicode Collation support.
   1262 
   1263   It tries to locate Unicode Collation 2 protocol and matches it with current
   1264   platform language code. If for any reason the first attempt fails, it then tries to
   1265   use Unicode Collation Protocol.
   1266 
   1267   @param  AgentHandle          The handle used to open Unicode Collation (2) protocol.
   1268 
   1269   @retval EFI_SUCCESS          The Unicode Collation (2) protocol has been successfully located.
   1270   @retval Others               The Unicode Collation (2) protocol has not been located.
   1271 
   1272 **/
   1273 EFI_STATUS
   1274 InitializeUnicodeCollationSupport (
   1275   IN EFI_HANDLE    AgentHandle
   1276   );
   1277 
   1278 /**
   1279   Convert FAT string to unicode string.
   1280 
   1281   @param  FatSize               The size of FAT string.
   1282   @param  Fat                   The FAT string.
   1283   @param  String                The unicode string.
   1284 
   1285   @return None.
   1286 
   1287 **/
   1288 VOID
   1289 FatFatToStr (
   1290   IN UINTN              FatSize,
   1291   IN CHAR8              *Fat,
   1292   OUT CHAR16            *String
   1293   );
   1294 
   1295 /**
   1296   Convert unicode string to Fat string.
   1297 
   1298   @param  String                The unicode string.
   1299   @param  FatSize               The size of the FAT string.
   1300   @param  Fat                   The FAT string.
   1301 
   1302   @retval TRUE                  Convert successfully.
   1303   @retval FALSE                 Convert error.
   1304 
   1305 **/
   1306 BOOLEAN
   1307 FatStrToFat (
   1308   IN  CHAR16            *String,
   1309   IN  UINTN             FatSize,
   1310   OUT CHAR8             *Fat
   1311   );
   1312 
   1313 /**
   1314   Lowercase a string
   1315 
   1316   @param  Str                   The string which will be lower-cased.
   1317 
   1318 **/
   1319 VOID
   1320 FatStrLwr (
   1321   IN CHAR16             *Str
   1322   );
   1323 
   1324 /**
   1325   Uppercase a string.
   1326 
   1327   @param  Str                   The string which will be upper-cased.
   1328 
   1329 **/
   1330 VOID
   1331 FatStrUpr (
   1332   IN CHAR16             *Str
   1333   );
   1334 
   1335 /**
   1336   Performs a case-insensitive comparison of two Null-terminated Unicode strings.
   1337 
   1338   @param  Str1                   A pointer to a Null-terminated Unicode string.
   1339   @param  Str2                   A pointer to a Null-terminated Unicode string.
   1340 
   1341   @retval 0                    S1 is equivalent to S2.
   1342   @retval >0                   S1 is lexically greater than S2.
   1343   @retval <0                   S1 is lexically less than S2.
   1344 **/
   1345 INTN
   1346 FatStriCmp (
   1347   IN CHAR16             *Str1,
   1348   IN CHAR16             *Str2
   1349   );
   1350 
   1351 //
   1352 // Open.c
   1353 //
   1354 
   1355 /**
   1356 
   1357   Open a file for a file name relative to an existing OFile.
   1358   The IFile of the newly opened file is passed out.
   1359 
   1360   @param  OFile                 - The file that serves as a starting reference point.
   1361   @param  NewIFile              - The newly generated IFile instance.
   1362   @param  FileName              - The file name relative to the OFile.
   1363   @param  OpenMode              - Open mode.
   1364   @param  Attributes            - Attributes to set if the file is created.
   1365 
   1366 
   1367   @retval EFI_SUCCESS           - Open the file successfully.
   1368   @retval EFI_INVALID_PARAMETER - The open mode is conflict with the attributes
   1369                           or the file name is not valid.
   1370   @retval EFI_NOT_FOUND         - Conficts between dir intention and attribute.
   1371   @retval EFI_WRITE_PROTECTED   - Can't open for write if the volume is read only.
   1372   @retval EFI_ACCESS_DENIED     - If the file's attribute is read only, and the
   1373                           open is for read-write fail it.
   1374   @retval EFI_OUT_OF_RESOURCES  - Can not allocate the memory.
   1375 
   1376 **/
   1377 EFI_STATUS
   1378 FatOFileOpen (
   1379   IN FAT_OFILE          *OFile,
   1380   OUT FAT_IFILE         **NewIFile,
   1381   IN CHAR16             *FileName,
   1382   IN UINT64             OpenMode,
   1383   IN UINT8              Attributes
   1384   );
   1385 
   1386 /**
   1387 
   1388   Create an Open instance for the existing OFile.
   1389   The IFile of the newly opened file is passed out.
   1390 
   1391   @param  OFile                 - The file that serves as a starting reference point.
   1392   @param  PtrIFile              - The newly generated IFile instance.
   1393 
   1394   @retval EFI_OUT_OF_RESOURCES  - Can not allocate the memory for the IFile
   1395   @retval EFI_SUCCESS           - Create the new IFile for the OFile successfully
   1396 
   1397 **/
   1398 EFI_STATUS
   1399 FatAllocateIFile (
   1400   IN FAT_OFILE          *OFile,
   1401   OUT FAT_IFILE         **PtrIFile
   1402   );
   1403 
   1404 //
   1405 // OpenVolume.c
   1406 //
   1407 /**
   1408 
   1409   Implements Simple File System Protocol interface function OpenVolume().
   1410 
   1411   @param  This                  - Calling context.
   1412   @param  File                  - the Root Directory of the volume.
   1413 
   1414   @retval EFI_OUT_OF_RESOURCES  - Can not allocate the memory.
   1415   @retval EFI_VOLUME_CORRUPTED  - The FAT type is error.
   1416   @retval EFI_SUCCESS           - Open the volume successfully.
   1417 
   1418 **/
   1419 EFI_STATUS
   1420 EFIAPI
   1421 FatOpenVolume (
   1422   IN  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
   1423   OUT EFI_FILE_PROTOCOL               **File
   1424   );
   1425 
   1426 //
   1427 // ReadWrite.c
   1428 //
   1429 /**
   1430 
   1431   This function reads data from a file or writes data to a file.
   1432   It uses OFile->PosRem to determine how much data can be accessed in one time.
   1433 
   1434   @param  OFile                 - The open file.
   1435   @param  IoMode                - Indicate whether the access mode is reading or writing.
   1436   @param  Position              - The position where data will be accessed.
   1437   @param  DataBufferSize        - Size of Buffer.
   1438   @param  UserBuffer            - Buffer containing data.
   1439   @param  Task                    point to task instance.
   1440 
   1441   @retval EFI_SUCCESS           - Access the data successfully.
   1442   @return other                 - An error occurred when operating on the disk.
   1443 
   1444 **/
   1445 EFI_STATUS
   1446 FatAccessOFile (
   1447   IN FAT_OFILE          *OFile,
   1448   IN IO_MODE            IoMode,
   1449   IN UINTN              Position,
   1450   IN UINTN              *DataBufferSize,
   1451   IN UINT8              *UserBuffer,
   1452   IN FAT_TASK           *Task
   1453   );
   1454 
   1455 /**
   1456 
   1457   Expand OFile by appending zero bytes at the end of OFile.
   1458 
   1459   @param  OFile                 - The open file.
   1460   @param  ExpandedSize          - The number of zero bytes appended at the end of the file.
   1461 
   1462   @retval EFI_SUCCESS           - The file is expanded successfully.
   1463   @return other                 - An error occurred when expanding file.
   1464 
   1465 **/
   1466 EFI_STATUS
   1467 FatExpandOFile (
   1468   IN FAT_OFILE          *OFile,
   1469   IN UINT64             ExpandedSize
   1470   );
   1471 
   1472 /**
   1473 
   1474   Write zero pool from the WritePos to the end of OFile.
   1475 
   1476   @param  OFile                 - The open file to write zero pool.
   1477   @param  WritePos              - The number of zero bytes written.
   1478 
   1479   @retval EFI_SUCCESS           - Write the zero pool successfully.
   1480   @retval EFI_OUT_OF_RESOURCES  - Not enough memory to perform the operation.
   1481   @return other                 - An error occurred when writing disk.
   1482 
   1483 **/
   1484 EFI_STATUS
   1485 FatWriteZeroPool (
   1486   IN FAT_OFILE          *OFile,
   1487   IN UINTN              WritePos
   1488   );
   1489 
   1490 /**
   1491 
   1492   Truncate the OFile to smaller file size.
   1493 
   1494   @param  OFile                 - The open file.
   1495   @param  TruncatedSize         - The new file size.
   1496 
   1497   @retval EFI_SUCCESS           - The file is truncated successfully.
   1498   @return other                 - An error occurred when truncating file.
   1499 
   1500 **/
   1501 EFI_STATUS
   1502 FatTruncateOFile (
   1503   IN FAT_OFILE          *OFile,
   1504   IN UINTN              TruncatedSize
   1505   );
   1506 
   1507 //
   1508 // DirectoryManage.c
   1509 //
   1510 /**
   1511 
   1512   Set the OFile's current directory cursor to the list head.
   1513 
   1514   @param OFile                 - The directory OFile whose directory cursor is reset.
   1515 
   1516 **/
   1517 VOID
   1518 FatResetODirCursor (
   1519   IN FAT_OFILE          *OFile
   1520   );
   1521 
   1522 /**
   1523 
   1524   Set the directory's cursor to the next and get the next directory entry.
   1525 
   1526   @param  OFile                 - The parent OFile.
   1527   @param PtrDirEnt             - The next directory entry.
   1528 
   1529   @retval EFI_SUCCESS           - We get the next directory entry successfully.
   1530   @return other                 - An error occurred when get next directory entry.
   1531 
   1532 **/
   1533 EFI_STATUS
   1534 FatGetNextDirEnt (
   1535   IN  FAT_OFILE         *OFile,
   1536   OUT FAT_DIRENT        **PtrDirEnt
   1537   );
   1538 
   1539 /**
   1540 
   1541   Remove this directory entry node from the list of directory entries and hash table.
   1542 
   1543   @param  OFile                - The parent OFile.
   1544   @param  DirEnt               - The directory entry to be removed.
   1545 
   1546   @retval EFI_SUCCESS          - The directory entry is successfully removed.
   1547   @return other                - An error occurred when removing the directory entry.
   1548 
   1549 **/
   1550 EFI_STATUS
   1551 FatRemoveDirEnt (
   1552   IN FAT_OFILE          *OFile,
   1553   IN FAT_DIRENT         *DirEnt
   1554   );
   1555 
   1556 /**
   1557 
   1558   Save the directory entry to disk.
   1559 
   1560   @param  OFile                 - The parent OFile which needs to update.
   1561   @param  DirEnt                - The directory entry to be saved.
   1562 
   1563   @retval EFI_SUCCESS           - Store the directory entry successfully.
   1564   @return other                 - An error occurred when writing the directory entry.
   1565 
   1566 **/
   1567 EFI_STATUS
   1568 FatStoreDirEnt (
   1569   IN FAT_OFILE          *OFile,
   1570   IN FAT_DIRENT         *DirEnt
   1571   );
   1572 
   1573 /**
   1574 
   1575   Create a directory entry in the parent OFile.
   1576 
   1577   @param  OFile                 - The parent OFile.
   1578   @param  FileName              - The filename of the newly-created directory entry.
   1579   @param  Attributes            - The attribute of the newly-created directory entry.
   1580   @param  PtrDirEnt             - The pointer to the newly-created directory entry.
   1581 
   1582   @retval EFI_SUCCESS           - The directory entry is successfully created.
   1583   @retval EFI_OUT_OF_RESOURCES  - Not enough memory to create the directory entry.
   1584   @return other                 - An error occurred when creating the directory entry.
   1585 
   1586 **/
   1587 EFI_STATUS
   1588 FatCreateDirEnt (
   1589   IN  FAT_OFILE         *OFile,
   1590   IN  CHAR16            *FileName,
   1591   IN  UINT8             Attributes,
   1592   OUT FAT_DIRENT        **PtrDirEnt
   1593   );
   1594 
   1595 /**
   1596 
   1597   Determine whether the directory entry is "." or ".." entry.
   1598 
   1599   @param  DirEnt               - The corresponding directory entry.
   1600 
   1601   @retval TRUE                 - The directory entry is "." or ".." directory entry
   1602   @retval FALSE                - The directory entry is not "." or ".." directory entry
   1603 
   1604 **/
   1605 BOOLEAN
   1606 FatIsDotDirEnt (
   1607   IN FAT_DIRENT         *DirEnt
   1608   );
   1609 
   1610 /**
   1611 
   1612   Set the OFile's cluster and size info in its directory entry.
   1613 
   1614   @param  OFile                 - The corresponding OFile.
   1615 
   1616 **/
   1617 VOID
   1618 FatUpdateDirEntClusterSizeInfo (
   1619   IN FAT_OFILE          *OFile
   1620   );
   1621 
   1622 /**
   1623 
   1624   Copy all the information of DirEnt2 to DirEnt1 except for 8.3 name.
   1625 
   1626   @param  DirEnt1               - The destination directory entry.
   1627   @param  DirEnt2               - The source directory entry.
   1628 
   1629 **/
   1630 VOID
   1631 FatCloneDirEnt (
   1632   IN  FAT_DIRENT        *DirEnt1,
   1633   IN  FAT_DIRENT        *DirEnt2
   1634   );
   1635 
   1636 /**
   1637 
   1638   Get the directory entry's info into Buffer.
   1639 
   1640   @param  Volume                - FAT file system volume.
   1641   @param  DirEnt                - The corresponding directory entry.
   1642   @param  BufferSize            - Size of Buffer.
   1643   @param  Buffer                - Buffer containing file info.
   1644 
   1645   @retval EFI_SUCCESS           - Get the file info successfully.
   1646   @retval EFI_BUFFER_TOO_SMALL  - The buffer is too small.
   1647 
   1648 **/
   1649 EFI_STATUS
   1650 FatGetDirEntInfo (
   1651   IN FAT_VOLUME         *Volume,
   1652   IN FAT_DIRENT         *DirEnt,
   1653   IN OUT UINTN          *BufferSize,
   1654   OUT VOID              *Buffer
   1655   );
   1656 
   1657 /**
   1658 
   1659   Open the directory entry to get the OFile.
   1660 
   1661   @param  Parent                - The parent OFile.
   1662   @param  DirEnt                - The directory entry to be opened.
   1663 
   1664   @retval EFI_SUCCESS           - The directory entry is successfully opened.
   1665   @retval EFI_OUT_OF_RESOURCES  - not enough memory to allocate a new OFile.
   1666   @return other                 - An error occurred when opening the directory entry.
   1667 
   1668 **/
   1669 EFI_STATUS
   1670 FatOpenDirEnt (
   1671   IN FAT_OFILE          *OFile,
   1672   IN FAT_DIRENT         *DirEnt
   1673   );
   1674 
   1675 /**
   1676 
   1677   Create "." and ".." directory entries in the newly-created parent OFile.
   1678 
   1679   @param  OFile                 - The parent OFile.
   1680 
   1681   @retval EFI_SUCCESS           - The dot directory entries are successfully created.
   1682   @return other                 - An error occurred when creating the directory entry.
   1683 
   1684 **/
   1685 EFI_STATUS
   1686 FatCreateDotDirEnts (
   1687   IN FAT_OFILE          *OFile
   1688   );
   1689 
   1690 /**
   1691 
   1692   Close the directory entry and free the OFile.
   1693 
   1694   @param  DirEnt               - The directory entry to be closed.
   1695 
   1696 **/
   1697 VOID
   1698 FatCloseDirEnt (
   1699   IN FAT_DIRENT         *DirEnt
   1700   );
   1701 
   1702 /**
   1703 
   1704   Traverse filename and open all OFiles that can be opened.
   1705   Update filename pointer to the component that can't be opened.
   1706   If more than one name component remains, returns an error;
   1707   otherwise, return the remaining name component so that the caller might choose to create it.
   1708 
   1709   @param  PtrOFile              - As input, the reference OFile; as output, the located OFile.
   1710   @param  FileName              - The file name relevant to the OFile.
   1711   @param  Attributes            - The attribute of the destination OFile.
   1712   @param  NewFileName           - The remaining file name.
   1713 
   1714   @retval EFI_NOT_FOUND         - The file name can't be opened and there is more than one
   1715                           components within the name left (this means the name can
   1716                           not be created either).
   1717   @retval EFI_INVALID_PARAMETER - The parameter is not valid.
   1718   @retval EFI_SUCCESS           - Open the file successfully.
   1719   @return other                 - An error occured when locating the OFile.
   1720 
   1721 **/
   1722 EFI_STATUS
   1723 FatLocateOFile (
   1724   IN OUT FAT_OFILE      **PtrOFile,
   1725   IN     CHAR16         *FileName,
   1726   IN     UINT8          Attributes,
   1727      OUT CHAR16         *NewFileName
   1728   );
   1729 
   1730 /**
   1731 
   1732   Get the directory entry for the volume.
   1733 
   1734   @param  Volume                - FAT file system volume.
   1735   @param  Name                  - The file name of the volume.
   1736 
   1737   @retval EFI_SUCCESS           - Update the volume with the directory entry sucessfully.
   1738   @return others                - An error occurred when getting volume label.
   1739 
   1740 **/
   1741 EFI_STATUS
   1742 FatGetVolumeEntry (
   1743   IN FAT_VOLUME         *Volume,
   1744   IN CHAR16             *Name
   1745   );
   1746 
   1747 /**
   1748 
   1749   Set the relevant directory entry into disk for the volume.
   1750 
   1751   @param  Volume              - FAT file system volume.
   1752   @param  Name                - The new file name of the volume.
   1753 
   1754   @retval EFI_SUCCESS         - Update the Volume sucessfully.
   1755   @retval EFI_UNSUPPORTED     - The input label is not a valid volume label.
   1756   @return other               - An error occurred when setting volume label.
   1757 
   1758 **/
   1759 EFI_STATUS
   1760 FatSetVolumeEntry (
   1761   IN FAT_VOLUME         *Volume,
   1762   IN CHAR16             *Name
   1763   );
   1764 
   1765 //
   1766 // Hash.c
   1767 //
   1768 /**
   1769 
   1770   Search the long name hash table for the directory entry.
   1771 
   1772   @param  ODir                  - The directory to be searched.
   1773   @param  LongNameString        - The long name string to search.
   1774 
   1775   @return The previous long name hash node of the directory entry.
   1776 
   1777 **/
   1778 FAT_DIRENT **
   1779 FatLongNameHashSearch (
   1780   IN FAT_ODIR           *ODir,
   1781   IN CHAR16             *LongNameString
   1782   );
   1783 
   1784 /**
   1785 
   1786   Search the short name hash table for the directory entry.
   1787 
   1788   @param  ODir                  - The directory to be searched.
   1789   @param  ShortNameString       - The short name string to search.
   1790 
   1791   @return The previous short name hash node of the directory entry.
   1792 
   1793 **/
   1794 FAT_DIRENT **
   1795 FatShortNameHashSearch (
   1796   IN FAT_ODIR           *ODir,
   1797   IN CHAR8              *ShortNameString
   1798   );
   1799 
   1800 /**
   1801 
   1802   Insert directory entry to hash table.
   1803 
   1804   @param  ODir                  - The parent directory.
   1805   @param  DirEnt                - The directory entry node.
   1806 
   1807 **/
   1808 VOID
   1809 FatInsertToHashTable (
   1810   IN FAT_ODIR           *ODir,
   1811   IN FAT_DIRENT         *DirEnt
   1812   );
   1813 
   1814 /**
   1815 
   1816   Delete directory entry from hash table.
   1817 
   1818   @param  ODir                  - The parent directory.
   1819   @param  DirEnt                - The directory entry node.
   1820 
   1821 **/
   1822 VOID
   1823 FatDeleteFromHashTable (
   1824   IN FAT_ODIR           *ODir,
   1825   IN FAT_DIRENT         *DirEnt
   1826   );
   1827 
   1828 //
   1829 // FileName.c
   1830 //
   1831 /**
   1832 
   1833   This function checks whether the input FileName is a valid 8.3 short name.
   1834   If the input FileName is a valid 8.3, the output is the 8.3 short name;
   1835   otherwise, the output is the base tag of 8.3 short name.
   1836 
   1837   @param  FileName              - The input unicode filename.
   1838   @param  File8Dot3Name         - The output ascii 8.3 short name or base tag of 8.3 short name.
   1839 
   1840   @retval TRUE                  - The input unicode filename is a valid 8.3 short name.
   1841   @retval FALSE                 - The input unicode filename is not a valid 8.3 short name.
   1842 
   1843 **/
   1844 BOOLEAN
   1845 FatCheckIs8Dot3Name (
   1846   IN CHAR16             *FileName,
   1847   OUT CHAR8             *File8Dot3Name
   1848   );
   1849 
   1850 /**
   1851 
   1852   This function generates 8Dot3 name from user specified name for a newly created file.
   1853 
   1854   @param  Parent                - The parent directory.
   1855   @param  DirEnt                - The directory entry whose 8Dot3Name needs to be generated.
   1856 
   1857 **/
   1858 VOID
   1859 FatCreate8Dot3Name (
   1860   IN FAT_OFILE          *Parent,
   1861   IN FAT_DIRENT         *DirEnt
   1862   );
   1863 
   1864 /**
   1865 
   1866   Convert the ascii fat name to the unicode string and strip trailing spaces,
   1867   and if necessary, convert the unicode string to lower case.
   1868 
   1869   @param  FatName               - The Char8 string needs to be converted.
   1870   @param  Len                   - The length of the fat name.
   1871   @param  LowerCase             - Indicate whether to convert the string to lower case.
   1872   @param  Str                   - The result of the convertion.
   1873 
   1874 **/
   1875 VOID
   1876 FatNameToStr (
   1877   IN CHAR8              *FatName,
   1878   IN UINTN              Len,
   1879   IN UINTN              LowerCase,
   1880   IN CHAR16             *Str
   1881   );
   1882 
   1883 /**
   1884 
   1885   Set the caseflag value for the directory entry.
   1886 
   1887   @param DirEnt                - The logical directory entry whose caseflag value is to be set.
   1888 
   1889 **/
   1890 VOID
   1891 FatSetCaseFlag (
   1892   IN FAT_DIRENT         *DirEnt
   1893   );
   1894 
   1895 /**
   1896 
   1897   Convert the 8.3 ASCII fat name to cased Unicode string according to case flag.
   1898 
   1899   @param  DirEnt                - The corresponding directory entry.
   1900   @param  FileString            - The output Unicode file name.
   1901   @param  FileStringMax           The max length of FileString.
   1902 
   1903 **/
   1904 VOID
   1905 FatGetFileNameViaCaseFlag (
   1906   IN     FAT_DIRENT     *DirEnt,
   1907   IN OUT CHAR16         *FileString,
   1908   IN     UINTN          FileStringMax
   1909   );
   1910 
   1911 /**
   1912 
   1913   Get the Check sum for a short name.
   1914 
   1915   @param  ShortNameString       - The short name for a file.
   1916 
   1917   @retval Sum                   - UINT8 checksum.
   1918 
   1919 **/
   1920 UINT8
   1921 FatCheckSum (
   1922   IN CHAR8              *ShortNameString
   1923   );
   1924 
   1925 /**
   1926 
   1927   Takes Path as input, returns the next name component
   1928   in Name, and returns the position after Name (e.g., the
   1929   start of the next name component)
   1930 
   1931   @param  Path                  - The path of one file.
   1932   @param  Name                  - The next name component in Path.
   1933 
   1934   The position after Name in the Path
   1935 
   1936 **/
   1937 CHAR16*
   1938 FatGetNextNameComponent (
   1939   IN  CHAR16            *Path,
   1940   OUT CHAR16            *Name
   1941   );
   1942 
   1943 /**
   1944 
   1945   Check whether the IFileName is valid long file name. If the IFileName is a valid
   1946   long file name, then we trim the possible leading blanks and leading/trailing dots.
   1947   the trimmed filename is stored in OutputFileName
   1948 
   1949   @param  InputFileName         - The input file name.
   1950   @param  OutputFileName        - The output file name.
   1951 
   1952   @retval TRUE                  - The InputFileName is a valid long file name.
   1953   @retval FALSE                 - The InputFileName is not a valid long file name.
   1954 
   1955 **/
   1956 BOOLEAN
   1957 FatFileNameIsValid (
   1958   IN  CHAR16  *InputFileName,
   1959   OUT CHAR16  *OutputFileName
   1960   );
   1961 
   1962 //
   1963 // DirectoryCache.c
   1964 //
   1965 /**
   1966 
   1967   Discard the directory structure when an OFile will be freed.
   1968   Volume will cache this directory if the OFile does not represent a deleted file.
   1969 
   1970   @param  OFile                 - The OFile whose directory structure is to be discarded.
   1971 
   1972 **/
   1973 VOID
   1974 FatDiscardODir (
   1975   IN FAT_OFILE    *OFile
   1976   );
   1977 
   1978 /**
   1979 
   1980   Request the directory structure when an OFile is newly generated.
   1981   If the directory structure is cached by volume, then just return this directory;
   1982   Otherwise, allocate a new one for OFile.
   1983 
   1984   @param  OFile                 - The OFile which requests directory structure.
   1985 
   1986 **/
   1987 VOID
   1988 FatRequestODir (
   1989   IN FAT_OFILE    *OFile
   1990   );
   1991 
   1992 /**
   1993 
   1994   Clean up all the cached directory structures when the volume is going to be abandoned.
   1995 
   1996   @param  Volume                - FAT file system volume.
   1997 
   1998 **/
   1999 VOID
   2000 FatCleanupODirCache (
   2001   IN FAT_VOLUME   *Volume
   2002   );
   2003 
   2004 //
   2005 // Global Variables
   2006 //
   2007 extern EFI_DRIVER_BINDING_PROTOCOL     gFatDriverBinding;
   2008 extern EFI_COMPONENT_NAME_PROTOCOL     gFatComponentName;
   2009 extern EFI_COMPONENT_NAME2_PROTOCOL    gFatComponentName2;
   2010 extern EFI_LOCK                        FatFsLock;
   2011 extern EFI_LOCK                        FatTaskLock;
   2012 extern EFI_FILE_PROTOCOL               FatFileInterface;
   2013 
   2014 #endif
   2015