3 Copyright (c) 2005 - 2013, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials are licensed and made available
5 under the terms and conditions of the BSD License which accompanies this
6 distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 Main header file for EFI FAT file system driver
30 #include <Guid/FileInfo.h>
31 #include <Guid/FileSystemInfo.h>
32 #include <Guid/FileSystemVolumeLabelInfo.h>
33 #include <Protocol/BlockIo.h>
34 #include <Protocol/DiskIo.h>
35 #include <Protocol/DiskIo2.h>
36 #include <Protocol/SimpleFileSystem.h>
37 #include <Protocol/UnicodeCollation.h>
39 #include <Library/PcdLib.h>
40 #include <Library/DebugLib.h>
41 #include <Library/UefiLib.h>
42 #include <Library/BaseLib.h>
43 #include <Library/BaseMemoryLib.h>
44 #include <Library/MemoryAllocationLib.h>
45 #include <Library/UefiDriverEntryPoint.h>
46 #include <Library/UefiBootServicesTableLib.h>
47 #include <Library/UefiRuntimeServicesTableLib.h>
49 #include "FatFileSystem.h"
54 #define FAT_VOLUME_SIGNATURE SIGNATURE_32 ('f', 'a', 't', 'v')
55 #define FAT_IFILE_SIGNATURE SIGNATURE_32 ('f', 'a', 't', 'i')
56 #define FAT_ODIR_SIGNATURE SIGNATURE_32 ('f', 'a', 't', 'd')
57 #define FAT_DIRENT_SIGNATURE SIGNATURE_32 ('f', 'a', 't', 'e')
58 #define FAT_OFILE_SIGNATURE SIGNATURE_32 ('f', 'a', 't', 'o')
59 #define FAT_TASK_SIGNATURE SIGNATURE_32 ('f', 'a', 't', 'T')
60 #define FAT_SUBTASK_SIGNATURE SIGNATURE_32 ('f', 'a', 't', 'S')
62 #define ASSERT_VOLUME_LOCKED(a) ASSERT_LOCKED (&FatFsLock)
64 #define IFILE_FROM_FHAND(a) CR (a, FAT_IFILE, Handle, FAT_IFILE_SIGNATURE)
66 #define DIRENT_FROM_LINK(a) CR (a, FAT_DIRENT, Link, FAT_DIRENT_SIGNATURE)
68 #define VOLUME_FROM_ROOT_DIRENT(a) CR (a, FAT_VOLUME, RootDirEnt, FAT_VOLUME_SIGNATURE)
70 #define VOLUME_FROM_VOL_INTERFACE(a) CR (a, FAT_VOLUME, VolumeInterface, FAT_VOLUME_SIGNATURE);
72 #define ODIR_FROM_DIRCACHELINK(a) CR (a, FAT_ODIR, DirCacheLink, FAT_ODIR_SIGNATURE)
74 #define OFILE_FROM_CHECKLINK(a) CR (a, FAT_OFILE, CheckLink, FAT_OFILE_SIGNATURE)
76 #define OFILE_FROM_CHILDLINK(a) CR (a, FAT_OFILE, ChildLink, FAT_OFILE_SIGNATURE)
79 // Minimum sector size is 512B, Maximum sector size is 4096B
80 // Max sectors per cluster is 128
82 #define MAX_BLOCK_ALIGNMENT 12
83 #define MIN_BLOCK_ALIGNMENT 9
84 #define MAX_SECTORS_PER_CLUSTER_ALIGNMENT 7
87 // Efi Time Definition
89 #define IS_LEAP_YEAR(a) (((a) % 4 == 0) && (((a) % 100 != 0) || ((a) % 400 == 0)))
92 // Minimum fat page size is 8K, maximum fat page alignment is 32K
93 // Minimum data page size is 8K, maximum fat page alignment is 64K
95 #define FAT_FATCACHE_PAGE_MIN_ALIGNMENT 13
96 #define FAT_FATCACHE_PAGE_MAX_ALIGNMENT 15
97 #define FAT_DATACACHE_PAGE_MIN_ALIGNMENT 13
98 #define FAT_DATACACHE_PAGE_MAX_ALIGNMENT 16
99 #define FAT_DATACACHE_GROUP_COUNT 64
100 #define FAT_FATCACHE_GROUP_MIN_COUNT 1
101 #define FAT_FATCACHE_GROUP_MAX_COUNT 16
104 // Used in 8.3 generation algorithm
106 #define MAX_SPEC_RETRY 4
107 #define SPEC_BASE_TAG_LEN 6
108 #define HASH_BASE_TAG_LEN 2
109 #define HASH_VALUE_TAG_LEN (SPEC_BASE_TAG_LEN - HASH_BASE_TAG_LEN)
112 // Path name separator is back slash
114 #define PATH_NAME_SEPARATOR L'\\'
117 #define EFI_PATH_STRING_LENGTH 260
118 #define EFI_FILE_STRING_LENGTH 255
119 #define FAT_MAX_ALLOCATE_SIZE 0xA00000
120 #define LC_ISO_639_2_ENTRY_SIZE 3
121 #define MAX_LANG_CODE_SIZE 100
123 #define FAT_MAX_DIR_CACHE_COUNT 8
124 #define FAT_MAX_DIRENTRY_COUNT 0xFFFF
125 typedef CHAR8 LC_ISO_639_2
;
128 // The fat types we support
147 ReadDisk
= 0, // raw disk read
148 WriteDisk
= 1, // raw disk write
149 ReadFat
= 2, // read fat cache
150 WriteFat
= 3, // write fat cache
151 ReadData
= 6, // read data cache
152 WriteData
= 7 // write data cache
155 #define CACHE_ENABLED(a) ((a) >= 2)
156 #define RAW_ACCESS(a) ((IO_MODE)((a) & 0x1))
157 #define CACHE_TYPE(a) ((CACHE_DATA_TYPE)((a) >> 2))
175 CACHE_TAG CacheTag
[FAT_DATACACHE_GROUP_COUNT
];
181 #define HASH_TABLE_SIZE 0x400
182 #define HASH_TABLE_MASK (HASH_TABLE_SIZE - 1)
185 // The directory entry for opened directory
188 typedef struct _FAT_DIRENT FAT_DIRENT
;
189 typedef struct _FAT_ODIR FAT_ODIR
;
190 typedef struct _FAT_OFILE FAT_OFILE
;
191 typedef struct _FAT_VOLUME FAT_VOLUME
;
195 UINT16 EntryPos
; // The position of this directory entry in the parent directory file
196 UINT8 EntryCount
; // The count of the directory entry in the parent directory file
197 BOOLEAN Invalid
; // Indicate whether this directory entry is valid
198 CHAR16
*FileString
; // The unicode long file name for this directory entry
199 FAT_OFILE
*OFile
; // The OFile of the corresponding directory entry
200 FAT_DIRENT
*ShortNameForwardLink
; // Hash successor link for short filename
201 FAT_DIRENT
*LongNameForwardLink
; // Hash successor link for long filename
202 LIST_ENTRY Link
; // Connection of every directory entry
203 FAT_DIRECTORY_ENTRY Entry
; // The physical directory entry stored in disk
208 UINT32 CurrentEndPos
; // Current end position of the directory
209 UINT32 CurrentPos
; // Current position of the directory
210 LIST_ENTRY
*CurrentCursor
; // Current directory entry pointer
211 LIST_ENTRY ChildList
; // List of all directory entries
212 BOOLEAN EndOfDir
; // Indicate whether we have reached the end of the directory
213 LIST_ENTRY DirCacheLink
; // Linked in Volume->DirCacheList when discarded
214 UINTN DirCacheTag
; // The identification of the directory when in directory cache
215 FAT_DIRENT
*LongNameHashTable
[HASH_TABLE_SIZE
];
216 FAT_DIRENT
*ShortNameHashTable
[HASH_TABLE_SIZE
];
221 EFI_FILE_PROTOCOL Handle
;
225 LIST_ENTRY Tasks
; // List of all FAT_TASKs
226 LIST_ENTRY Link
; // Link to other IFiles
231 EFI_FILE_IO_TOKEN
*FileIoToken
;
233 LIST_ENTRY Subtasks
; // List of all FAT_SUBTASKs
234 LIST_ENTRY Link
; // Link to other FAT_TASKs
239 EFI_DISK_IO2_TOKEN DiskIo2Token
;
249 // FAT_OFILE - Each opened file
255 // A permanant error code to return to all accesses to
260 // A list of the IFILE instances for this OFile
265 // The dynamic infomation
269 UINTN FileCurrentCluster
;
270 UINTN FileLastCluster
;
273 // Dirty is set if there have been any updates to the
275 // Archive is set if the archive attribute in the file's
276 // directory entry needs to be set when performing flush
277 // PreserveLastMod is set if the last modification of the
278 // file is specified by SetInfo API
281 BOOLEAN IsFixedRootDir
;
282 BOOLEAN PreserveLastModification
;
285 // Set by an OFile SetPosition
287 UINTN Position
; // within file
288 UINT64 PosDisk
; // on the disk
289 UINTN PosRem
; // remaining in this disk run
291 // The opened parent, full path length and currently opened child files
295 LIST_ENTRY ChildHead
;
296 LIST_ENTRY ChildLink
;
299 // The opened directory structure for a directory; if this
300 // OFile represents a file, then ODir = NULL
304 // The directory entry for the Ofile
309 // Link in Volume's reference list
311 LIST_ENTRY CheckLink
;
321 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL VolumeInterface
;
324 // If opened, the parent handle and BlockIo interface
326 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
327 EFI_DISK_IO_PROTOCOL
*DiskIo
;
328 EFI_DISK_IO2_PROTOCOL
*DiskIo2
;
333 // Computed values from fat bpb info
336 UINT64 FatPos
; // Disk pos of fat tables
337 UINT64 RootPos
; // Disk pos of root directory
338 UINT64 FirstClusterPos
; // Disk pos of first cluster
339 UINTN FatSize
; // Number of bytes in each fat
340 UINTN MaxCluster
; // Max cluster number
341 UINTN ClusterSize
; // Cluster size of fat partition
342 UINT8 ClusterAlignment
; // Equal to log_2 (clustersize);
343 FAT_VOLUME_TYPE FatType
;
346 // Current part of fat table that's present
348 UINT64 FatEntryPos
; // Location of buffer
349 UINTN FatEntrySize
; // Size of buffer
350 UINT32 FatEntryBuffer
; // The buffer
351 FAT_INFO_SECTOR FatInfoSector
; // Free cluster info
352 UINTN FreeInfoPos
; // Pos with the free cluster info
353 BOOLEAN FreeInfoValid
; // If free cluster info is valid
355 // Unpacked Fat BPB info
358 UINTN RootEntries
; // < FAT32, root dir is fixed size
359 UINTN RootCluster
; // >= FAT32, root cluster chain head
361 // info for marking the volume dirty or not
363 BOOLEAN FatDirty
; // If fat-entries have been updated
365 UINT32 NotDirtyValue
;
368 // The root directory entry and opened root file
370 FAT_DIRENT RootDirEnt
;
372 // File Name of root OFile, it is empty string
374 CHAR16 RootFileString
[1];
378 // New OFiles are added to this list so they
379 // can be cleaned up if they aren't referenced.
384 // Directory cache List
386 LIST_ENTRY DirCacheList
;
390 // Disk Cache for this volume
393 DISK_CACHE DiskCache
[CacheMaxType
];
397 // Function Prototypes
402 IN EFI_FILE_PROTOCOL
*FHand
,
403 OUT EFI_FILE_PROTOCOL
**NewHandle
,
411 Implements Open() of Simple File System Protocol.
415 FHand - File handle of the file serves as a starting reference point.
416 NewHandle - Handle of the file that is newly opened.
417 FileName - File name relative to FHand.
418 OpenMode - Open mode.
419 Attributes - Attributes to set if the file is created.
423 EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty.
424 The OpenMode is not supported.
425 The Attributes is not the valid attributes.
426 EFI_OUT_OF_RESOURCES - Can not allocate the memory for file string.
427 EFI_SUCCESS - Open the file successfully.
428 Others - The status of open file.
436 IN EFI_FILE_PROTOCOL
*FHand
,
437 OUT EFI_FILE_PROTOCOL
**NewHandle
,
440 IN UINT64 Attributes
,
441 IN OUT EFI_FILE_IO_TOKEN
*Token
446 Implements OpenEx() of Simple File System Protocol.
450 FHand - File handle of the file serves as a starting reference point.
451 NewHandle - Handle of the file that is newly opened.
452 FileName - File name relative to FHand.
453 OpenMode - Open mode.
454 Attributes - Attributes to set if the file is created.
455 Token - A pointer to the token associated with the transaction.
459 EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty.
460 The OpenMode is not supported.
461 The Attributes is not the valid attributes.
462 EFI_OUT_OF_RESOURCES - Can not allocate the memory for file string.
463 EFI_SUCCESS - Open the file successfully.
464 Others - The status of open file.
472 IN EFI_FILE_PROTOCOL
*FHand
,
479 Get the file's position of the file
483 FHand - The handle of file.
484 Position - The file's position of the file.
488 EFI_SUCCESS - Get the info successfully.
489 EFI_DEVICE_ERROR - Can not find the OFile for the file.
490 EFI_UNSUPPORTED - The open file is not a file.
498 IN EFI_FILE_PROTOCOL
*FHand
,
500 IN OUT UINTN
*BufferSize
,
507 Get the some types info of the file into Buffer
511 FHand - The handle of file.
512 Type - The type of the info.
513 BufferSize - Size of Buffer.
514 Buffer - Buffer containing volume info.
518 EFI_SUCCESS - Get the info successfully.
519 EFI_DEVICE_ERROR - Can not find the OFile for the file.
527 IN EFI_FILE_PROTOCOL
*FHand
,
536 Set the some types info of the file into Buffer
540 FHand - The handle of file.
541 Type - The type of the info.
542 BufferSize - Size of Buffer.
543 Buffer - Buffer containing volume info.
547 EFI_SUCCESS - Set the info successfully.
548 EFI_DEVICE_ERROR - Can not find the OFile for the file.
556 IN EFI_FILE_PROTOCOL
*FHand
562 Flushes all data associated with the file handle
566 FHand - Handle to file to flush
570 EFI_SUCCESS - Flushed the file successfully
571 EFI_WRITE_PROTECTED - The volume is read only
572 EFI_ACCESS_DENIED - The volume is not read only
573 but the file is read only
574 Others - Flushing of the file is failed
582 IN EFI_FILE_PROTOCOL
*FHand
,
583 IN EFI_FILE_IO_TOKEN
*Token
589 Flushes all data associated with the file handle.
593 FHand - Handle to file to flush.
594 Token - A pointer to the token associated with the transaction.
598 EFI_SUCCESS - Flushed the file successfully.
599 EFI_WRITE_PROTECTED - The volume is read only.
600 EFI_ACCESS_DENIED - The file is read only.
601 Others - Flushing of the file failed.
609 IN EFI_FILE_PROTOCOL
*FHand
615 Flushes & Closes the file handle.
619 FHand - Handle to the file to delete.
623 EFI_SUCCESS - Closed the file successfully.
631 IN EFI_FILE_PROTOCOL
*FHand
637 Deletes the file & Closes the file handle.
641 FHand - Handle to the file to delete.
645 EFI_SUCCESS - Delete the file successfully.
646 EFI_WARN_DELETE_FAILURE - Fail to delete the file.
654 IN EFI_FILE_PROTOCOL
*FHand
,
661 Set the file's position of the file
665 FHand - The handle of file
666 Position - The file's position of the file
670 EFI_SUCCESS - Set the info successfully
671 EFI_DEVICE_ERROR - Can not find the OFile for the file
672 EFI_UNSUPPORTED - Set a directory with a not-zero position
680 IN EFI_FILE_PROTOCOL
*FHand
,
681 IN OUT UINTN
*BufferSize
,
692 FHand - The handle of the file.
693 BufferSize - Size of Buffer.
694 Buffer - Buffer containing read data.
698 EFI_SUCCESS - Get the file info successfully.
699 EFI_DEVICE_ERROR - Can not find the OFile for the file.
700 EFI_VOLUME_CORRUPTED - The file type of open file is error.
701 other - An error occurred when operation the disk.
709 IN EFI_FILE_PROTOCOL
*FHand
,
710 IN OUT EFI_FILE_IO_TOKEN
*Token
720 FHand - The handle of the file.
721 Token - A pointer to the token associated with the transaction.
725 EFI_SUCCESS - Get the file info successfully.
726 EFI_DEVICE_ERROR - Can not find the OFile for the file.
727 EFI_VOLUME_CORRUPTED - The file type of open file is error.
728 other - An error occurred when operation the disk.
736 IN EFI_FILE_PROTOCOL
*FHand
,
737 IN OUT UINTN
*BufferSize
,
748 FHand - The handle of the file.
749 BufferSize - Size of Buffer.
750 Buffer - Buffer containing write data.
754 EFI_SUCCESS - Set the file info successfully.
755 EFI_WRITE_PROTECTED - The disk is write protected.
756 EFI_ACCESS_DENIED - The file is read-only.
757 EFI_DEVICE_ERROR - The OFile is not valid.
758 EFI_UNSUPPORTED - The open file is not a file.
759 - The writing file size is larger than 4GB.
760 other - An error occurred when operation the disk.
768 IN EFI_FILE_PROTOCOL
*FHand
,
769 IN OUT EFI_FILE_IO_TOKEN
*Token
779 FHand - The handle of the file.
780 Token - A pointer to the token associated with the transaction.
784 EFI_SUCCESS - Get the file info successfully.
785 EFI_DEVICE_ERROR - Can not find the OFile for the file.
786 EFI_VOLUME_CORRUPTED - The file type of open file is error.
787 other - An error occurred when operation the disk.
796 FatInitializeDiskCache (
797 IN FAT_VOLUME
*Volume
802 IN FAT_VOLUME
*Volume
,
803 IN CACHE_DATA_TYPE CacheDataType
,
807 IN OUT UINT8
*Buffer
,
812 FatVolumeFlushCache (
813 IN FAT_VOLUME
*Volume
,
843 IN FAT_VOLUME
*Volume
,
845 IN EFI_STATUS EfiStatus
,
860 IN UINT64 NewSizeInBytes
865 IN FAT_VOLUME
*Volume
,
870 FatPhysicalFileSize (
871 IN FAT_VOLUME
*Volume
,
884 IN FAT_VOLUME
*Volume
892 IN EFI_HANDLE Handle
,
893 IN EFI_DISK_IO_PROTOCOL
*DiskIo
,
894 IN EFI_DISK_IO2_PROTOCOL
*DiskIo2
,
895 IN EFI_BLOCK_IO_PROTOCOL
*BlockIo
900 IN OUT FAT_VOLUME
*Volume
905 IN FAT_VOLUME
*Volume
914 EFI_FILE_IO_TOKEN
*Token
923 FatWaitNonblockingTask (
939 FatAccessVolumeDirty (
940 IN FAT_VOLUME
*Volume
,
947 IN FAT_VOLUME
*Volume
,
966 FatAcquireLockOrFail (
972 IN FAT_DIRENT
*DirEnt
977 IN FAT_VOLUME
*Volume
981 FatEfiTimeToFatTime (
983 OUT FAT_DATE_TIME
*FTime
987 FatFatTimeToEfiTime (
988 IN FAT_DATE_TIME
*FTime
,
993 FatGetCurrentFatTime (
994 OUT FAT_DATE_TIME
*FatTime
1003 // UnicodeCollation.c
1006 InitializeUnicodeCollationSupport (
1007 IN EFI_HANDLE AgentHandle
1045 IN FAT_OFILE
*OFile
,
1046 OUT FAT_IFILE
**NewIFile
,
1047 IN CHAR16
*FileName
,
1054 IN FAT_OFILE
*OFile
,
1055 OUT FAT_IFILE
**PtrIFile
1064 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*This
,
1065 OUT EFI_FILE_PROTOCOL
**File
1073 IN FAT_OFILE
*OFile
,
1076 IN UINTN
*DataBufferSize
,
1077 IN UINT8
*UserBuffer
,
1083 IN FAT_OFILE
*OFile
,
1084 IN UINT64 ExpandedSize
1089 IN FAT_OFILE
*OFile
,
1095 IN FAT_OFILE
*OFile
,
1096 IN UINTN TruncatedSize
1100 // DirectoryManage.c
1103 FatResetODirCursor (
1109 IN FAT_OFILE
*OFile
,
1110 OUT FAT_DIRENT
**PtrDirEnt
1115 IN FAT_OFILE
*OFile
,
1116 IN FAT_DIRENT
*DirEnt
1121 IN FAT_OFILE
*OFile
,
1122 IN FAT_DIRENT
*DirEnt
1127 IN FAT_OFILE
*OFile
,
1128 IN CHAR16
*FileName
,
1129 IN UINT8 Attributes
,
1130 OUT FAT_DIRENT
**PtrDirEnt
1135 IN FAT_DIRENT
*DirEnt
1139 FatUpdateDirEntClusterSizeInfo (
1145 IN FAT_DIRENT
*DirEnt1
,
1146 IN FAT_DIRENT
*DirEnt2
1151 IN FAT_VOLUME
*Volume
,
1152 IN FAT_DIRENT
*DirEnt
,
1153 IN OUT UINTN
*BufferSize
,
1159 IN FAT_OFILE
*OFile
,
1160 IN FAT_DIRENT
*DirEnt
1164 FatCreateDotDirEnts (
1170 IN FAT_DIRENT
*DirEnt
1175 IN OUT FAT_OFILE
**PtrOFile
,
1176 IN CHAR16
*FileName
,
1177 IN UINT8 Attributes
,
1178 OUT CHAR16
*NewFileName
1183 IN FAT_VOLUME
*Volume
,
1189 IN FAT_VOLUME
*Volume
,
1197 FatLongNameHashSearch (
1199 IN CHAR16
*LongNameString
1203 FatShortNameHashSearch (
1205 IN CHAR8
*ShortNameString
1209 FatInsertToHashTable (
1211 IN FAT_DIRENT
*DirEnt
1215 FatDeleteFromHashTable (
1217 IN FAT_DIRENT
*DirEnt
1224 FatCheckIs8Dot3Name (
1225 IN CHAR16
*FileName
,
1226 OUT CHAR8
*File8Dot3Name
1230 FatCreate8Dot3Name (
1231 IN FAT_OFILE
*Parent
,
1232 IN FAT_DIRENT
*DirEnt
1245 IN FAT_DIRENT
*DirEnt
1249 FatGetFileNameViaCaseFlag (
1250 IN FAT_DIRENT
*DirEnt
,
1251 IN OUT CHAR16
*FileString
,
1252 IN UINTN FileStringMax
1257 IN CHAR8
*ShortNameString
1261 FatGetNextNameComponent (
1267 FatFileNameIsValid (
1268 IN CHAR16
*InputFileName
,
1269 OUT CHAR16
*OutputFileName
1286 FatCleanupODirCache (
1287 IN FAT_VOLUME
*Volume
1293 extern EFI_DRIVER_BINDING_PROTOCOL gFatDriverBinding
;
1294 extern EFI_COMPONENT_NAME_PROTOCOL gFatComponentName
;
1295 extern EFI_COMPONENT_NAME2_PROTOCOL gFatComponentName2
;
1296 extern EFI_LOCK FatFsLock
;
1297 extern EFI_LOCK FatTaskLock
;
1298 extern EFI_FILE_PROTOCOL FatFileInterface
;