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