• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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