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.
429 IN EFI_FILE_PROTOCOL
*FHand
,
430 OUT EFI_FILE_PROTOCOL
**NewHandle
,
433 IN UINT64 Attributes
,
434 IN OUT EFI_FILE_IO_TOKEN
*Token
439 Implements OpenEx() of Simple File System Protocol.
443 FHand - File handle of the file serves as a starting reference point.
444 NewHandle - Handle of the file that is newly opened.
445 FileName - File name relative to FHand.
446 OpenMode - Open mode.
447 Attributes - Attributes to set if the file is created.
448 Token - A pointer to the token associated with the transaction.
452 EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty.
453 The OpenMode is not supported.
454 The Attributes is not the valid attributes.
455 EFI_OUT_OF_RESOURCES - Can not allocate the memory for file string.
456 EFI_SUCCESS - Open the file successfully.
457 Others - The status of open file.
465 IN EFI_FILE_PROTOCOL
*FHand
,
472 Get the file's position of the file
476 FHand - The handle of file.
477 Position - The file's position of the file.
481 EFI_SUCCESS - Get the info successfully.
482 EFI_DEVICE_ERROR - Can not find the OFile for the file.
483 EFI_UNSUPPORTED - The open file is not a file.
491 IN EFI_FILE_PROTOCOL
*FHand
,
493 IN OUT UINTN
*BufferSize
,
500 Get the some types info of the file into Buffer
504 FHand - The handle of file.
505 Type - The type of the info.
506 BufferSize - Size of Buffer.
507 Buffer - Buffer containing volume info.
511 EFI_SUCCESS - Get the info successfully.
512 EFI_DEVICE_ERROR - Can not find the OFile for the file.
520 IN EFI_FILE_PROTOCOL
*FHand
,
529 Set the some types info of the file into Buffer
533 FHand - The handle of file.
534 Type - The type of the info.
535 BufferSize - Size of Buffer.
536 Buffer - Buffer containing volume info.
540 EFI_SUCCESS - Set the info successfully.
541 EFI_DEVICE_ERROR - Can not find the OFile for the file.
549 IN EFI_FILE_PROTOCOL
*FHand
555 Flushes all data associated with the file handle
559 FHand - Handle to file to flush
563 EFI_SUCCESS - Flushed the file successfully
564 EFI_WRITE_PROTECTED - The volume is read only
565 EFI_ACCESS_DENIED - The volume is not read only
566 but the file is read only
567 Others - Flushing of the file is failed
575 IN EFI_FILE_PROTOCOL
*FHand
,
576 IN EFI_FILE_IO_TOKEN
*Token
582 Flushes all data associated with the file handle.
586 FHand - Handle to file to flush.
587 Token - A pointer to the token associated with the transaction.
591 EFI_SUCCESS - Flushed the file successfully.
592 EFI_WRITE_PROTECTED - The volume is read only.
593 EFI_ACCESS_DENIED - The file is read only.
594 Others - Flushing of the file failed.
602 IN EFI_FILE_PROTOCOL
*FHand
608 Flushes & Closes the file handle.
612 FHand - Handle to the file to delete.
616 EFI_SUCCESS - Closed the file successfully.
624 IN EFI_FILE_PROTOCOL
*FHand
630 Deletes the file & Closes the file handle.
634 FHand - Handle to the file to delete.
638 EFI_SUCCESS - Delete the file successfully.
639 EFI_WARN_DELETE_FAILURE - Fail to delete the file.
647 IN EFI_FILE_PROTOCOL
*FHand
,
654 Set the file's position of the file
658 FHand - The handle of file
659 Position - The file's position of the file
663 EFI_SUCCESS - Set the info successfully
664 EFI_DEVICE_ERROR - Can not find the OFile for the file
665 EFI_UNSUPPORTED - Set a directory with a not-zero position
673 IN EFI_FILE_PROTOCOL
*FHand
,
674 IN OUT UINTN
*BufferSize
,
685 FHand - The handle of the file.
686 BufferSize - Size of Buffer.
687 Buffer - Buffer containing read data.
691 EFI_SUCCESS - Get the file info successfully.
692 EFI_DEVICE_ERROR - Can not find the OFile for the file.
693 EFI_VOLUME_CORRUPTED - The file type of open file is error.
694 other - An error occurred when operation the disk.
702 IN EFI_FILE_PROTOCOL
*FHand
,
703 IN OUT EFI_FILE_IO_TOKEN
*Token
713 FHand - The handle of the file.
714 Token - A pointer to the token associated with the transaction.
718 EFI_SUCCESS - Get the file info successfully.
719 EFI_DEVICE_ERROR - Can not find the OFile for the file.
720 EFI_VOLUME_CORRUPTED - The file type of open file is error.
721 other - An error occurred when operation the disk.
729 IN EFI_FILE_PROTOCOL
*FHand
,
730 IN OUT UINTN
*BufferSize
,
741 FHand - The handle of the file.
742 BufferSize - Size of Buffer.
743 Buffer - Buffer containing write data.
747 EFI_SUCCESS - Set the file info successfully.
748 EFI_WRITE_PROTECTED - The disk is write protected.
749 EFI_ACCESS_DENIED - The file is read-only.
750 EFI_DEVICE_ERROR - The OFile is not valid.
751 EFI_UNSUPPORTED - The open file is not a file.
752 - The writing file size is larger than 4GB.
753 other - An error occurred when operation the disk.
761 IN EFI_FILE_PROTOCOL
*FHand
,
762 IN OUT EFI_FILE_IO_TOKEN
*Token
772 FHand - The handle of the file.
773 Token - A pointer to the token associated with the transaction.
777 EFI_SUCCESS - Get the file info successfully.
778 EFI_DEVICE_ERROR - Can not find the OFile for the file.
779 EFI_VOLUME_CORRUPTED - The file type of open file is error.
780 other - An error occurred when operation the disk.
789 FatInitializeDiskCache (
790 IN FAT_VOLUME
*Volume
795 IN FAT_VOLUME
*Volume
,
796 IN CACHE_DATA_TYPE CacheDataType
,
800 IN OUT UINT8
*Buffer
,
805 FatVolumeFlushCache (
806 IN FAT_VOLUME
*Volume
,
836 IN FAT_VOLUME
*Volume
,
838 IN EFI_STATUS EfiStatus
,
853 IN UINT64 NewSizeInBytes
858 IN FAT_VOLUME
*Volume
,
863 FatPhysicalFileSize (
864 IN FAT_VOLUME
*Volume
,
877 IN FAT_VOLUME
*Volume
885 IN EFI_HANDLE Handle
,
886 IN EFI_DISK_IO_PROTOCOL
*DiskIo
,
887 IN EFI_DISK_IO2_PROTOCOL
*DiskIo2
,
888 IN EFI_BLOCK_IO_PROTOCOL
*BlockIo
893 IN OUT FAT_VOLUME
*Volume
898 IN FAT_VOLUME
*Volume
907 EFI_FILE_IO_TOKEN
*Token
916 FatWaitNonblockingTask (
932 FatAccessVolumeDirty (
933 IN FAT_VOLUME
*Volume
,
940 IN FAT_VOLUME
*Volume
,
959 FatAcquireLockOrFail (
965 IN FAT_DIRENT
*DirEnt
970 IN FAT_VOLUME
*Volume
974 FatEfiTimeToFatTime (
976 OUT FAT_DATE_TIME
*FTime
980 FatFatTimeToEfiTime (
981 IN FAT_DATE_TIME
*FTime
,
986 FatGetCurrentFatTime (
987 OUT FAT_DATE_TIME
*FatTime
996 // UnicodeCollation.c
999 InitializeUnicodeCollationSupport (
1000 IN EFI_HANDLE AgentHandle
1038 IN FAT_OFILE
*OFile
,
1039 OUT FAT_IFILE
**NewIFile
,
1040 IN CHAR16
*FileName
,
1047 IN FAT_OFILE
*OFile
,
1048 OUT FAT_IFILE
**PtrIFile
1057 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*This
,
1058 OUT EFI_FILE_PROTOCOL
**File
1066 IN FAT_OFILE
*OFile
,
1069 IN UINTN
*DataBufferSize
,
1070 IN UINT8
*UserBuffer
,
1076 IN FAT_OFILE
*OFile
,
1077 IN UINT64 ExpandedSize
1082 IN FAT_OFILE
*OFile
,
1088 IN FAT_OFILE
*OFile
,
1089 IN UINTN TruncatedSize
1093 // DirectoryManage.c
1096 FatResetODirCursor (
1102 IN FAT_OFILE
*OFILE
,
1103 OUT FAT_DIRENT
**PtrDirEnt
1108 IN FAT_OFILE
*OFile
,
1109 IN FAT_DIRENT
*DirEnt
1114 IN FAT_OFILE
*OFile
,
1115 IN FAT_DIRENT
*DirEnt
1120 IN FAT_OFILE
*OFile
,
1121 IN CHAR16
*FileName
,
1122 IN UINT8 Attributes
,
1123 OUT FAT_DIRENT
**PtrDirEnt
1128 IN FAT_DIRENT
*DirEnt
1132 FatUpdateDirEntClusterSizeInfo (
1138 IN FAT_DIRENT
*DirEnt1
,
1139 IN FAT_DIRENT
*DirEnt2
1144 IN FAT_VOLUME
*Volume
,
1145 IN FAT_DIRENT
*DirEnt
,
1146 IN OUT UINTN
*BufferSize
,
1152 IN FAT_OFILE
*OFile
,
1153 IN FAT_DIRENT
*DirEnt
1157 FatCreateDotDirEnts (
1163 IN FAT_DIRENT
*DirEnt
1168 IN OUT FAT_OFILE
**PtrOFile
,
1169 IN CHAR16
*FileName
,
1170 IN UINT8 Attributes
,
1171 OUT CHAR16
*NewFileName
1176 IN FAT_VOLUME
*Volume
,
1182 IN FAT_VOLUME
*Volume
,
1190 FatLongNameHashSearch (
1192 IN CHAR16
*LongNameString
1196 FatShortNameHashSearch (
1198 IN CHAR8
*ShortNameString
1202 FatInsertToHashTable (
1204 IN FAT_DIRENT
*DirEnt
1208 FatDeleteFromHashTable (
1210 IN FAT_DIRENT
*DirEnt
1217 FatCheckIs8Dot3Name (
1218 IN CHAR16
*FileName
,
1219 OUT CHAR8
*File8Dot3Name
1223 FatCreate8Dot3Name (
1224 IN FAT_OFILE
*Parent
,
1225 IN FAT_DIRENT
*DirEnt
1238 IN FAT_DIRENT
*DirEnt
1242 FatGetFileNameViaCaseFlag (
1243 IN FAT_DIRENT
*DirEnt
,
1244 OUT CHAR16
*FileString
1249 IN CHAR8
*ShortNameString
1253 FatGetNextNameComponent (
1259 FatFileNameIsValid (
1260 IN CHAR16
*InputFileName
,
1261 OUT CHAR16
*OutputFileName
1278 FatCleanupODirCache (
1279 IN FAT_VOLUME
*Volume
1285 extern EFI_DRIVER_BINDING_PROTOCOL gFatDriverBinding
;
1286 extern EFI_COMPONENT_NAME_PROTOCOL gFatComponentName
;
1287 extern EFI_COMPONENT_NAME2_PROTOCOL gFatComponentName2
;
1288 extern EFI_LOCK FatFsLock
;
1289 extern EFI_LOCK FatTaskLock
;
1290 extern EFI_FILE_PROTOCOL FatFileInterface
;