2 Main header file for EFI FAT file system driver.
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
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.
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>
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>
39 #include "FatFileSystem.h"
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')
52 #define ASSERT_VOLUME_LOCKED(a) ASSERT_LOCKED (&FatFsLock)
54 #define IFILE_FROM_FHAND(a) CR (a, FAT_IFILE, Handle, FAT_IFILE_SIGNATURE)
56 #define DIRENT_FROM_LINK(a) CR (a, FAT_DIRENT, Link, FAT_DIRENT_SIGNATURE)
58 #define VOLUME_FROM_ROOT_DIRENT(a) CR (a, FAT_VOLUME, RootDirEnt, FAT_VOLUME_SIGNATURE)
60 #define VOLUME_FROM_VOL_INTERFACE(a) CR (a, FAT_VOLUME, VolumeInterface, FAT_VOLUME_SIGNATURE);
62 #define ODIR_FROM_DIRCACHELINK(a) CR (a, FAT_ODIR, DirCacheLink, FAT_ODIR_SIGNATURE)
64 #define OFILE_FROM_CHECKLINK(a) CR (a, FAT_OFILE, CheckLink, FAT_OFILE_SIGNATURE)
66 #define OFILE_FROM_CHILDLINK(a) CR (a, FAT_OFILE, ChildLink, FAT_OFILE_SIGNATURE)
69 // Minimum sector size is 512B, Maximum sector size is 4096B
70 // Max sectors per cluster is 128
72 #define MAX_BLOCK_ALIGNMENT 12
73 #define MIN_BLOCK_ALIGNMENT 9
74 #define MAX_SECTORS_PER_CLUSTER_ALIGNMENT 7
77 // Efi Time Definition
79 #define IS_LEAP_YEAR(a) (((a) % 4 == 0) && (((a) % 100 != 0) || ((a) % 400 == 0)))
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
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
94 // Used in 8.3 generation algorithm
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)
102 // Path name separator is back slash
104 #define PATH_NAME_SEPARATOR L'\\'
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
113 #define FAT_MAX_DIR_CACHE_COUNT 8
114 #define FAT_MAX_DIRENTRY_COUNT 0xFFFF
115 typedef CHAR8 LC_ISO_639_2
;
118 // The fat types we support
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
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))
165 CACHE_TAG CacheTag
[FAT_DATACACHE_GROUP_COUNT
];
171 #define HASH_TABLE_SIZE 0x400
172 #define HASH_TABLE_MASK (HASH_TABLE_SIZE - 1)
175 // The directory entry for opened directory
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
;
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
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
];
211 EFI_FILE_PROTOCOL Handle
;
215 LIST_ENTRY Tasks
; // List of all FAT_TASKs
216 LIST_ENTRY Link
; // Link to other IFiles
221 EFI_FILE_IO_TOKEN
*FileIoToken
;
223 LIST_ENTRY Subtasks
; // List of all FAT_SUBTASKs
224 LIST_ENTRY Link
; // Link to other FAT_TASKs
229 EFI_DISK_IO2_TOKEN DiskIo2Token
;
239 // FAT_OFILE - Each opened file
245 // A permanant error code to return to all accesses to
250 // A list of the IFILE instances for this OFile
255 // The dynamic infomation
259 UINTN FileCurrentCluster
;
260 UINTN FileLastCluster
;
263 // Dirty is set if there have been any updates to the
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
271 BOOLEAN IsFixedRootDir
;
272 BOOLEAN PreserveLastModification
;
275 // Set by an OFile SetPosition
277 UINTN Position
; // within file
278 UINT64 PosDisk
; // on the disk
279 UINTN PosRem
; // remaining in this disk run
281 // The opened parent, full path length and currently opened child files
285 LIST_ENTRY ChildHead
;
286 LIST_ENTRY ChildLink
;
289 // The opened directory structure for a directory; if this
290 // OFile represents a file, then ODir = NULL
294 // The directory entry for the Ofile
299 // Link in Volume's reference list
301 LIST_ENTRY CheckLink
;
311 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL VolumeInterface
;
314 // If opened, the parent handle and BlockIo interface
316 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
317 EFI_DISK_IO_PROTOCOL
*DiskIo
;
318 EFI_DISK_IO2_PROTOCOL
*DiskIo2
;
323 // Computed values from fat bpb info
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
;
336 // Current part of fat table that's present
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
345 // Unpacked Fat BPB info
348 UINTN RootEntries
; // < FAT32, root dir is fixed size
349 UINTN RootCluster
; // >= FAT32, root cluster chain head
351 // info for marking the volume dirty or not
353 BOOLEAN FatDirty
; // If fat-entries have been updated
355 UINT32 NotDirtyValue
;
358 // The root directory entry and opened root file
360 FAT_DIRENT RootDirEnt
;
362 // File Name of root OFile, it is empty string
364 CHAR16 RootFileString
[1];
368 // New OFiles are added to this list so they
369 // can be cleaned up if they aren't referenced.
374 // Directory cache List
376 LIST_ENTRY DirCacheList
;
380 // Disk Cache for this volume
383 DISK_CACHE DiskCache
[CacheMaxType
];
387 // Function Prototypes
392 Implements Open() of Simple File System Protocol.
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.
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.
412 IN EFI_FILE_PROTOCOL
*FHand
,
413 OUT EFI_FILE_PROTOCOL
**NewHandle
,
422 Implements OpenEx() of Simple File System Protocol.
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.
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.
442 IN EFI_FILE_PROTOCOL
*FHand
,
443 OUT EFI_FILE_PROTOCOL
**NewHandle
,
446 IN UINT64 Attributes
,
447 IN OUT EFI_FILE_IO_TOKEN
*Token
453 Get the file's position of the file
455 @param FHand - The handle of file.
456 @param Position - The file's position of the file.
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.
466 IN EFI_FILE_PROTOCOL
*FHand
,
473 Get the some types info of the file into Buffer
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.
480 @retval EFI_SUCCESS - Get the info successfully.
481 @retval EFI_DEVICE_ERROR - Can not find the OFile for the file.
487 IN EFI_FILE_PROTOCOL
*FHand
,
489 IN OUT UINTN
*BufferSize
,
496 Set the some types info of the file into Buffer.
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.
503 @retval EFI_SUCCESS - Set the info successfully.
504 @retval EFI_DEVICE_ERROR - Can not find the OFile for the file.
510 IN EFI_FILE_PROTOCOL
*FHand
,
519 Flushes all data associated with the file handle.
521 @param FHand - Handle to file to flush
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
533 IN EFI_FILE_PROTOCOL
*FHand
539 Flushes all data associated with the file handle.
541 @param FHand - Handle to file to flush.
542 @param Token - A pointer to the token associated with the transaction.
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.
553 IN EFI_FILE_PROTOCOL
*FHand
,
554 IN EFI_FILE_IO_TOKEN
*Token
560 Flushes & Closes the file handle.
562 @param FHand - Handle to the file to delete.
564 @retval EFI_SUCCESS - Closed the file successfully.
570 IN EFI_FILE_PROTOCOL
*FHand
576 Deletes the file & Closes the file handle.
578 @param FHand - Handle to the file to delete.
580 @retval EFI_SUCCESS - Delete the file successfully.
581 @retval EFI_WARN_DELETE_FAILURE - Fail to delete the file.
587 IN EFI_FILE_PROTOCOL
*FHand
593 Set the file's position of the file.
595 @param FHand - The handle of file
596 @param Position - The file's position of the file
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
606 IN EFI_FILE_PROTOCOL
*FHand
,
615 @param FHand - The handle of the file.
616 @param BufferSize - Size of Buffer.
617 @param Buffer - Buffer containing read data.
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.
628 IN EFI_FILE_PROTOCOL
*FHand
,
629 IN OUT UINTN
*BufferSize
,
638 @param FHand - The handle of the file.
639 @param Token - A pointer to the token associated with the transaction.
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.
650 IN EFI_FILE_PROTOCOL
*FHand
,
651 IN OUT EFI_FILE_IO_TOKEN
*Token
659 @param FHand - The handle of the file.
660 @param BufferSize - Size of Buffer.
661 @param Buffer - Buffer containing write data.
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.
675 IN EFI_FILE_PROTOCOL
*FHand
,
676 IN OUT UINTN
*BufferSize
,
685 @param FHand - The handle of the file.
686 @param Token - A pointer to the token associated with the transaction.
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.
697 IN EFI_FILE_PROTOCOL
*FHand
,
698 IN OUT EFI_FILE_IO_TOKEN
*Token
706 FatInitializeDiskCache (
707 IN FAT_VOLUME
*Volume
712 IN FAT_VOLUME
*Volume
,
713 IN CACHE_DATA_TYPE CacheDataType
,
717 IN OUT UINT8
*Buffer
,
722 FatVolumeFlushCache (
723 IN FAT_VOLUME
*Volume
,
753 IN FAT_VOLUME
*Volume
,
755 IN EFI_STATUS EfiStatus
,
770 IN UINT64 NewSizeInBytes
775 IN FAT_VOLUME
*Volume
,
780 FatPhysicalFileSize (
781 IN FAT_VOLUME
*Volume
,
794 IN FAT_VOLUME
*Volume
802 IN EFI_HANDLE Handle
,
803 IN EFI_DISK_IO_PROTOCOL
*DiskIo
,
804 IN EFI_DISK_IO2_PROTOCOL
*DiskIo2
,
805 IN EFI_BLOCK_IO_PROTOCOL
*BlockIo
810 IN OUT FAT_VOLUME
*Volume
815 IN FAT_VOLUME
*Volume
824 EFI_FILE_IO_TOKEN
*Token
833 FatWaitNonblockingTask (
849 FatAccessVolumeDirty (
850 IN FAT_VOLUME
*Volume
,
857 IN FAT_VOLUME
*Volume
,
876 FatAcquireLockOrFail (
882 IN FAT_DIRENT
*DirEnt
887 IN FAT_VOLUME
*Volume
891 FatEfiTimeToFatTime (
893 OUT FAT_DATE_TIME
*FTime
897 FatFatTimeToEfiTime (
898 IN FAT_DATE_TIME
*FTime
,
903 FatGetCurrentFatTime (
904 OUT FAT_DATE_TIME
*FatTime
913 // UnicodeCollation.c
916 InitializeUnicodeCollationSupport (
917 IN EFI_HANDLE AgentHandle
956 OUT FAT_IFILE
**NewIFile
,
965 OUT FAT_IFILE
**PtrIFile
974 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*This
,
975 OUT EFI_FILE_PROTOCOL
**File
986 IN UINTN
*DataBufferSize
,
987 IN UINT8
*UserBuffer
,
994 IN UINT64 ExpandedSize
1005 IN FAT_OFILE
*OFile
,
1006 IN UINTN TruncatedSize
1010 // DirectoryManage.c
1013 FatResetODirCursor (
1019 IN FAT_OFILE
*OFile
,
1020 OUT FAT_DIRENT
**PtrDirEnt
1025 IN FAT_OFILE
*OFile
,
1026 IN FAT_DIRENT
*DirEnt
1031 IN FAT_OFILE
*OFile
,
1032 IN FAT_DIRENT
*DirEnt
1037 IN FAT_OFILE
*OFile
,
1038 IN CHAR16
*FileName
,
1039 IN UINT8 Attributes
,
1040 OUT FAT_DIRENT
**PtrDirEnt
1045 IN FAT_DIRENT
*DirEnt
1049 FatUpdateDirEntClusterSizeInfo (
1055 IN FAT_DIRENT
*DirEnt1
,
1056 IN FAT_DIRENT
*DirEnt2
1061 IN FAT_VOLUME
*Volume
,
1062 IN FAT_DIRENT
*DirEnt
,
1063 IN OUT UINTN
*BufferSize
,
1069 IN FAT_OFILE
*OFile
,
1070 IN FAT_DIRENT
*DirEnt
1074 FatCreateDotDirEnts (
1080 IN FAT_DIRENT
*DirEnt
1085 IN OUT FAT_OFILE
**PtrOFile
,
1086 IN CHAR16
*FileName
,
1087 IN UINT8 Attributes
,
1088 OUT CHAR16
*NewFileName
1093 IN FAT_VOLUME
*Volume
,
1099 IN FAT_VOLUME
*Volume
,
1107 FatLongNameHashSearch (
1109 IN CHAR16
*LongNameString
1113 FatShortNameHashSearch (
1115 IN CHAR8
*ShortNameString
1119 FatInsertToHashTable (
1121 IN FAT_DIRENT
*DirEnt
1125 FatDeleteFromHashTable (
1127 IN FAT_DIRENT
*DirEnt
1134 FatCheckIs8Dot3Name (
1135 IN CHAR16
*FileName
,
1136 OUT CHAR8
*File8Dot3Name
1140 FatCreate8Dot3Name (
1141 IN FAT_OFILE
*Parent
,
1142 IN FAT_DIRENT
*DirEnt
1155 IN FAT_DIRENT
*DirEnt
1159 FatGetFileNameViaCaseFlag (
1160 IN FAT_DIRENT
*DirEnt
,
1161 IN OUT CHAR16
*FileString
,
1162 IN UINTN FileStringMax
1167 IN CHAR8
*ShortNameString
1171 FatGetNextNameComponent (
1177 FatFileNameIsValid (
1178 IN CHAR16
*InputFileName
,
1179 OUT CHAR16
*OutputFileName
1196 FatCleanupODirCache (
1197 IN FAT_VOLUME
*Volume
1203 extern EFI_DRIVER_BINDING_PROTOCOL gFatDriverBinding
;
1204 extern EFI_COMPONENT_NAME_PROTOCOL gFatComponentName
;
1205 extern EFI_COMPONENT_NAME2_PROTOCOL gFatComponentName2
;
1206 extern EFI_LOCK FatFsLock
;
1207 extern EFI_LOCK FatTaskLock
;
1208 extern EFI_FILE_PROTOCOL FatFileInterface
;