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 READ_DISK
= 0, // raw disk read
148 WRITE_DISK
= 1, // raw disk write
149 READ_FAT
= 2, // read fat cache
150 WRITE_FAT
= 3, // write fat cache
151 READ_DATA
= 6, // read data cache
152 WRITE_DATA
= 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
187 typedef struct _FAT_DIRENT
{
189 UINT16 EntryPos
; // The position of this directory entry in the parent directory file
190 UINT8 EntryCount
; // The count of the directory entry in the parent directory file
191 BOOLEAN Invalid
; // Indicate whether this directory entry is valid
192 CHAR16
*FileString
; // The unicode long file name for this directory entry
193 struct _FAT_OFILE
*OFile
; // The OFile of the corresponding directory entry
194 struct _FAT_DIRENT
*ShortNameForwardLink
; // Hash successor link for short filename
195 struct _FAT_DIRENT
*LongNameForwardLink
; // Hash successor link for long filename
196 LIST_ENTRY Link
; // Connection of every directory entry
197 FAT_DIRECTORY_ENTRY Entry
; // The physical directory entry stored in disk
200 typedef struct _FAT_ODIR
{
202 UINT32 CurrentEndPos
; // Current end position of the directory
203 UINT32 CurrentPos
; // Current position of the directory
204 LIST_ENTRY
*CurrentCursor
; // Current directory entry pointer
205 LIST_ENTRY ChildList
; // List of all directory entries
206 BOOLEAN EndOfDir
; // Indicate whether we have reached the end of the directory
207 LIST_ENTRY DirCacheLink
; // Linked in Volume->DirCacheList when discarded
208 UINTN DirCacheTag
; // The identification of the directory when in directory cache
209 FAT_DIRENT
*LongNameHashTable
[HASH_TABLE_SIZE
];
210 FAT_DIRENT
*ShortNameHashTable
[HASH_TABLE_SIZE
];
215 EFI_FILE_PROTOCOL Handle
;
218 struct _FAT_OFILE
*OFile
;
219 LIST_ENTRY Tasks
; // List of all FAT_TASKs
220 LIST_ENTRY Link
; // Link to other IFiles
225 EFI_FILE_IO_TOKEN
*FileIoToken
;
227 LIST_ENTRY Subtasks
; // List of all FAT_SUBTASKs
228 LIST_ENTRY Link
; // Link to other FAT_TASKs
233 EFI_DISK_IO2_TOKEN DiskIo2Token
;
243 // FAT_OFILE - Each opened file
245 typedef struct _FAT_OFILE
{
247 struct _FAT_VOLUME
*Volume
;
249 // A permanant error code to return to all accesses to
254 // A list of the IFILE instances for this OFile
259 // The dynamic infomation
263 UINTN FileCurrentCluster
;
264 UINTN FileLastCluster
;
267 // Dirty is set if there have been any updates to the
269 // Archive is set if the archive attribute in the file's
270 // directory entry needs to be set when performing flush
271 // PreserveLastMod is set if the last modification of the
272 // file is specified by SetInfo API
275 BOOLEAN IsFixedRootDir
;
276 BOOLEAN PreserveLastModification
;
279 // Set by an OFile SetPosition
281 UINTN Position
; // within file
282 UINT64 PosDisk
; // on the disk
283 UINTN PosRem
; // remaining in this disk run
285 // The opened parent, full path length and currently opened child files
287 struct _FAT_OFILE
*Parent
;
289 LIST_ENTRY ChildHead
;
290 LIST_ENTRY ChildLink
;
293 // The opened directory structure for a directory; if this
294 // OFile represents a file, then ODir = NULL
298 // The directory entry for the Ofile
303 // Link in Volume's reference list
305 LIST_ENTRY CheckLink
;
308 typedef struct _FAT_VOLUME
{
315 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL VolumeInterface
;
318 // If opened, the parent handle and BlockIo interface
320 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
321 EFI_DISK_IO_PROTOCOL
*DiskIo
;
322 EFI_DISK_IO2_PROTOCOL
*DiskIo2
;
327 // Computed values from fat bpb info
330 UINT64 FatPos
; // Disk pos of fat tables
331 UINT64 RootPos
; // Disk pos of root directory
332 UINT64 FirstClusterPos
; // Disk pos of first cluster
333 UINTN FatSize
; // Number of bytes in each fat
334 UINTN MaxCluster
; // Max cluster number
335 UINTN ClusterSize
; // Cluster size of fat partition
336 UINT8 ClusterAlignment
; // Equal to log_2 (clustersize);
337 FAT_VOLUME_TYPE FatType
;
340 // Current part of fat table that's present
342 UINT64 FatEntryPos
; // Location of buffer
343 UINTN FatEntrySize
; // Size of buffer
344 UINT32 FatEntryBuffer
; // The buffer
345 FAT_INFO_SECTOR FatInfoSector
; // Free cluster info
346 UINTN FreeInfoPos
; // Pos with the free cluster info
347 BOOLEAN FreeInfoValid
; // If free cluster info is valid
349 // Unpacked Fat BPB info
352 UINTN RootEntries
; // < FAT32, root dir is fixed size
353 UINTN RootCluster
; // >= FAT32, root cluster chain head
355 // info for marking the volume dirty or not
357 BOOLEAN FatDirty
; // If fat-entries have been updated
359 UINT32 NotDirtyValue
;
362 // The root directory entry and opened root file
364 FAT_DIRENT RootDirEnt
;
366 // File Name of root OFile, it is empty string
368 CHAR16 RootFileString
[1];
369 struct _FAT_OFILE
*Root
;
372 // New OFiles are added to this list so they
373 // can be cleaned up if they aren't referenced.
378 // Directory cache List
380 LIST_ENTRY DirCacheList
;
384 // Disk Cache for this volume
387 DISK_CACHE DiskCache
[CACHE_MAX_TYPE
];
391 // Function Prototypes
396 IN EFI_FILE_PROTOCOL
*FHand
,
397 OUT EFI_FILE_PROTOCOL
**NewHandle
,
405 Implements Open() of Simple File System Protocol.
409 FHand - File handle of the file serves as a starting reference point.
410 NewHandle - Handle of the file that is newly opened.
411 FileName - File name relative to FHand.
412 OpenMode - Open mode.
413 Attributes - Attributes to set if the file is created.
417 EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty.
418 The OpenMode is not supported.
419 The Attributes is not the valid attributes.
420 EFI_OUT_OF_RESOURCES - Can not allocate the memory for file string.
421 EFI_SUCCESS - Open the file successfully.
422 Others - The status of open file.
430 IN EFI_FILE_PROTOCOL
*FHand
,
431 OUT EFI_FILE_PROTOCOL
**NewHandle
,
434 IN UINT64 Attributes
,
435 IN OUT EFI_FILE_IO_TOKEN
*Token
440 Implements OpenEx() of Simple File System Protocol.
444 FHand - File handle of the file serves as a starting reference point.
445 NewHandle - Handle of the file that is newly opened.
446 FileName - File name relative to FHand.
447 OpenMode - Open mode.
448 Attributes - Attributes to set if the file is created.
449 Token - A pointer to the token associated with the transaction.
453 EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty.
454 The OpenMode is not supported.
455 The Attributes is not the valid attributes.
456 EFI_OUT_OF_RESOURCES - Can not allocate the memory for file string.
457 EFI_SUCCESS - Open the file successfully.
458 Others - The status of open file.
466 IN EFI_FILE_PROTOCOL
*FHand
,
473 Get the file's position of the file
477 FHand - The handle of file.
478 Position - The file's position of the file.
482 EFI_SUCCESS - Get the info successfully.
483 EFI_DEVICE_ERROR - Can not find the OFile for the file.
484 EFI_UNSUPPORTED - The open file is not a file.
492 IN EFI_FILE_PROTOCOL
*FHand
,
494 IN OUT UINTN
*BufferSize
,
501 Get the some types info of the file into Buffer
505 FHand - The handle of file.
506 Type - The type of the info.
507 BufferSize - Size of Buffer.
508 Buffer - Buffer containing volume info.
512 EFI_SUCCESS - Get the info successfully.
513 EFI_DEVICE_ERROR - Can not find the OFile for the file.
521 IN EFI_FILE_PROTOCOL
*FHand
,
530 Set the some types info of the file into Buffer
534 FHand - The handle of file.
535 Type - The type of the info.
536 BufferSize - Size of Buffer.
537 Buffer - Buffer containing volume info.
541 EFI_SUCCESS - Set the info successfully.
542 EFI_DEVICE_ERROR - Can not find the OFile for the file.
550 IN EFI_FILE_PROTOCOL
*FHand
556 Flushes all data associated with the file handle
560 FHand - Handle to file to flush
564 EFI_SUCCESS - Flushed the file successfully
565 EFI_WRITE_PROTECTED - The volume is read only
566 EFI_ACCESS_DENIED - The volume is not read only
567 but the file is read only
568 Others - Flushing of the file is failed
576 IN EFI_FILE_PROTOCOL
*FHand
,
577 IN EFI_FILE_IO_TOKEN
*Token
583 Flushes all data associated with the file handle.
587 FHand - Handle to file to flush.
588 Token - A pointer to the token associated with the transaction.
592 EFI_SUCCESS - Flushed the file successfully.
593 EFI_WRITE_PROTECTED - The volume is read only.
594 EFI_ACCESS_DENIED - The file is read only.
595 Others - Flushing of the file failed.
603 IN EFI_FILE_PROTOCOL
*FHand
609 Flushes & Closes the file handle.
613 FHand - Handle to the file to delete.
617 EFI_SUCCESS - Closed the file successfully.
625 IN EFI_FILE_PROTOCOL
*FHand
631 Deletes the file & Closes the file handle.
635 FHand - Handle to the file to delete.
639 EFI_SUCCESS - Delete the file successfully.
640 EFI_WARN_DELETE_FAILURE - Fail to delete the file.
648 IN EFI_FILE_PROTOCOL
*FHand
,
655 Set the file's position of the file
659 FHand - The handle of file
660 Position - The file's position of the file
664 EFI_SUCCESS - Set the info successfully
665 EFI_DEVICE_ERROR - Can not find the OFile for the file
666 EFI_UNSUPPORTED - Set a directory with a not-zero position
674 IN EFI_FILE_PROTOCOL
*FHand
,
675 IN OUT UINTN
*BufferSize
,
686 FHand - The handle of the file.
687 BufferSize - Size of Buffer.
688 Buffer - Buffer containing read data.
692 EFI_SUCCESS - Get the file info successfully.
693 EFI_DEVICE_ERROR - Can not find the OFile for the file.
694 EFI_VOLUME_CORRUPTED - The file type of open file is error.
695 other - An error occurred when operation the disk.
703 IN EFI_FILE_PROTOCOL
*FHand
,
704 IN OUT EFI_FILE_IO_TOKEN
*Token
714 FHand - The handle of the file.
715 Token - A pointer to the token associated with the transaction.
719 EFI_SUCCESS - Get the file info successfully.
720 EFI_DEVICE_ERROR - Can not find the OFile for the file.
721 EFI_VOLUME_CORRUPTED - The file type of open file is error.
722 other - An error occurred when operation the disk.
730 IN EFI_FILE_PROTOCOL
*FHand
,
731 IN OUT UINTN
*BufferSize
,
742 FHand - The handle of the file.
743 BufferSize - Size of Buffer.
744 Buffer - Buffer containing write data.
748 EFI_SUCCESS - Set the file info successfully.
749 EFI_WRITE_PROTECTED - The disk is write protected.
750 EFI_ACCESS_DENIED - The file is read-only.
751 EFI_DEVICE_ERROR - The OFile is not valid.
752 EFI_UNSUPPORTED - The open file is not a file.
753 - The writing file size is larger than 4GB.
754 other - An error occurred when operation the disk.
762 IN EFI_FILE_PROTOCOL
*FHand
,
763 IN OUT EFI_FILE_IO_TOKEN
*Token
773 FHand - The handle of the file.
774 Token - A pointer to the token associated with the transaction.
778 EFI_SUCCESS - Get the file info successfully.
779 EFI_DEVICE_ERROR - Can not find the OFile for the file.
780 EFI_VOLUME_CORRUPTED - The file type of open file is error.
781 other - An error occurred when operation the disk.
790 FatInitializeDiskCache (
791 IN FAT_VOLUME
*Volume
796 IN FAT_VOLUME
*Volume
,
797 IN CACHE_DATA_TYPE CacheDataType
,
801 IN OUT UINT8
*Buffer
,
806 FatVolumeFlushCache (
807 IN FAT_VOLUME
*Volume
,
837 IN FAT_VOLUME
*Volume
,
839 IN EFI_STATUS EfiStatus
,
854 IN UINT64 NewSizeInBytes
859 IN FAT_VOLUME
*Volume
,
864 FatPhysicalFileSize (
865 IN FAT_VOLUME
*Volume
,
878 IN FAT_VOLUME
*Volume
886 IN EFI_HANDLE Handle
,
887 IN EFI_DISK_IO_PROTOCOL
*DiskIo
,
888 IN EFI_DISK_IO2_PROTOCOL
*DiskIo2
,
889 IN EFI_BLOCK_IO_PROTOCOL
*BlockIo
894 IN OUT FAT_VOLUME
*Volume
899 IN FAT_VOLUME
*Volume
908 EFI_FILE_IO_TOKEN
*Token
917 FatWaitNonblockingTask (
933 FatAccessVolumeDirty (
934 IN FAT_VOLUME
*Volume
,
941 IN FAT_VOLUME
*Volume
,
960 FatAcquireLockOrFail (
966 IN FAT_DIRENT
*DirEnt
971 IN FAT_VOLUME
*Volume
975 FatEfiTimeToFatTime (
977 OUT FAT_DATE_TIME
*FTime
981 FatFatTimeToEfiTime (
982 IN FAT_DATE_TIME
*FTime
,
987 FatGetCurrentFatTime (
988 OUT FAT_DATE_TIME
*FatTime
997 // UnicodeCollation.c
1000 InitializeUnicodeCollationSupport (
1001 IN EFI_HANDLE AgentHandle
1039 IN FAT_OFILE
*OFile
,
1040 OUT FAT_IFILE
**NewIFile
,
1041 IN CHAR16
*FileName
,
1048 IN FAT_OFILE
*OFile
,
1049 OUT FAT_IFILE
**PtrIFile
1058 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*This
,
1059 OUT EFI_FILE_PROTOCOL
**File
1067 IN FAT_OFILE
*OFile
,
1070 IN UINTN
*DataBufferSize
,
1071 IN UINT8
*UserBuffer
,
1077 IN FAT_OFILE
*OFile
,
1078 IN UINT64 ExpandedSize
1083 IN FAT_OFILE
*OFile
,
1089 IN FAT_OFILE
*OFile
,
1090 IN UINTN TruncatedSize
1094 // DirectoryManage.c
1097 FatResetODirCursor (
1103 IN FAT_OFILE
*OFILE
,
1104 OUT FAT_DIRENT
**PtrDirEnt
1109 IN FAT_OFILE
*OFile
,
1110 IN FAT_DIRENT
*DirEnt
1115 IN FAT_OFILE
*OFile
,
1116 IN FAT_DIRENT
*DirEnt
1121 IN FAT_OFILE
*OFile
,
1122 IN CHAR16
*FileName
,
1123 IN UINT8 Attributes
,
1124 OUT FAT_DIRENT
**PtrDirEnt
1129 IN FAT_DIRENT
*DirEnt
1133 FatUpdateDirEntClusterSizeInfo (
1139 IN FAT_DIRENT
*DirEnt1
,
1140 IN FAT_DIRENT
*DirEnt2
1145 IN FAT_VOLUME
*Volume
,
1146 IN FAT_DIRENT
*DirEnt
,
1147 IN OUT UINTN
*BufferSize
,
1153 IN FAT_OFILE
*OFile
,
1154 IN FAT_DIRENT
*DirEnt
1158 FatCreateDotDirEnts (
1164 IN FAT_DIRENT
*DirEnt
1169 IN OUT FAT_OFILE
**PtrOFile
,
1170 IN CHAR16
*FileName
,
1171 IN UINT8 Attributes
,
1172 OUT CHAR16
*NewFileName
1177 IN FAT_VOLUME
*Volume
,
1183 IN FAT_VOLUME
*Volume
,
1191 FatLongNameHashSearch (
1193 IN CHAR16
*LongNameString
1197 FatShortNameHashSearch (
1199 IN CHAR8
*ShortNameString
1203 FatInsertToHashTable (
1205 IN FAT_DIRENT
*DirEnt
1209 FatDeleteFromHashTable (
1211 IN FAT_DIRENT
*DirEnt
1218 FatCheckIs8Dot3Name (
1219 IN CHAR16
*FileName
,
1220 OUT CHAR8
*File8Dot3Name
1224 FatCreate8Dot3Name (
1225 IN FAT_OFILE
*Parent
,
1226 IN FAT_DIRENT
*DirEnt
1239 IN FAT_DIRENT
*DirEnt
1243 FatGetFileNameViaCaseFlag (
1244 IN FAT_DIRENT
*DirEnt
,
1245 IN OUT CHAR16
*FileString
,
1246 IN UINTN FileStringMax
1251 IN CHAR8
*ShortNameString
1255 FatGetNextNameComponent (
1261 FatFileNameIsValid (
1262 IN CHAR16
*InputFileName
,
1263 OUT CHAR16
*OutputFileName
1280 FatCleanupODirCache (
1281 IN FAT_VOLUME
*Volume
1287 extern EFI_DRIVER_BINDING_PROTOCOL gFatDriverBinding
;
1288 extern EFI_COMPONENT_NAME_PROTOCOL gFatComponentName
;
1289 extern EFI_COMPONENT_NAME2_PROTOCOL gFatComponentName2
;
1290 extern EFI_LOCK FatFsLock
;
1291 extern EFI_LOCK FatTaskLock
;
1292 extern EFI_FILE_PROTOCOL FatFileInterface
;