3 Copyright (c) 2005 - 2007, Intel Corporation
4 All rights reserved. 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/SimpleFileSystem.h>
36 #include <Protocol/UnicodeCollation.h>
38 #include <Library/PcdLib.h>
39 #include <Library/DebugLib.h>
40 #include <Library/UefiLib.h>
41 #include <Library/BaseLib.h>
42 #include <Library/BaseMemoryLib.h>
43 #include <Library/MemoryAllocationLib.h>
44 #include <Library/UefiDriverEntryPoint.h>
45 #include <Library/UefiBootServicesTableLib.h>
46 #include <Library/UefiRuntimeServicesTableLib.h>
48 #include "FatFileSystem.h"
53 #define FAT_VOLUME_SIGNATURE SIGNATURE_32 ('f', 'a', 't', 'v')
54 #define FAT_IFILE_SIGNATURE SIGNATURE_32 ('f', 'a', 't', 'i')
55 #define FAT_ODIR_SIGNATURE SIGNATURE_32 ('f', 'a', 't', 'd')
56 #define FAT_DIRENT_SIGNATURE SIGNATURE_32 ('f', 'a', 't', 'e')
57 #define FAT_OFILE_SIGNATURE SIGNATURE_32 ('f', 'a', 't', 'o')
59 #define ASSERT_VOLUME_LOCKED(a) ASSERT_LOCKED (&FatFsLock)
61 #define IFILE_FROM_FHAND(a) CR (a, FAT_IFILE, Handle, FAT_IFILE_SIGNATURE)
63 #define DIRENT_FROM_LINK(a) CR (a, FAT_DIRENT, Link, FAT_DIRENT_SIGNATURE)
65 #define VOLUME_FROM_ROOT_DIRENT(a) CR (a, FAT_VOLUME, RootDirEnt, FAT_VOLUME_SIGNATURE)
67 #define VOLUME_FROM_VOL_INTERFACE(a) CR (a, FAT_VOLUME, VolumeInterface, FAT_VOLUME_SIGNATURE);
69 #define ODIR_FROM_DIRCACHELINK(a) CR (a, FAT_ODIR, DirCacheLink, FAT_ODIR_SIGNATURE)
71 #define OFILE_FROM_CHECKLINK(a) CR (a, FAT_OFILE, CheckLink, FAT_OFILE_SIGNATURE)
73 #define OFILE_FROM_CHILDLINK(a) CR (a, FAT_OFILE, ChildLink, FAT_OFILE_SIGNATURE)
76 // Minimum sector size is 512B, Maximum sector size is 4096B
77 // Max sectors per cluster is 128
79 #define MAX_BLOCK_ALIGNMENT 12
80 #define MIN_BLOCK_ALIGNMENT 9
81 #define MAX_SECTORS_PER_CLUSTER_ALIGNMENT 7
84 // Efi Time Definition
86 #define IS_LEAP_YEAR(a) (((a) % 4 == 0) && (((a) % 100 != 0) || ((a) % 400 == 0)))
89 // Minimum fat page size is 8K, maximum fat page alignment is 32K
90 // Minimum data page size is 8K, maximum fat page alignment is 64K
92 #define FAT_FATCACHE_PAGE_MIN_ALIGNMENT 13
93 #define FAT_FATCACHE_PAGE_MAX_ALIGNMENT 15
94 #define FAT_DATACACHE_PAGE_MIN_ALIGNMENT 13
95 #define FAT_DATACACHE_PAGE_MAX_ALIGNMENT 16
96 #define FAT_DATACACHE_GROUP_COUNT 64
97 #define FAT_FATCACHE_GROUP_MIN_COUNT 1
98 #define FAT_FATCACHE_GROUP_MAX_COUNT 16
101 // Used in 8.3 generation algorithm
103 #define MAX_SPEC_RETRY 4
104 #define SPEC_BASE_TAG_LEN 6
105 #define HASH_BASE_TAG_LEN 2
106 #define HASH_VALUE_TAG_LEN (SPEC_BASE_TAG_LEN - HASH_BASE_TAG_LEN)
109 // Path name separator is back slash
111 #define PATH_NAME_SEPARATOR L'\\'
114 #define EFI_PATH_STRING_LENGTH 260
115 #define EFI_FILE_STRING_LENGTH 255
116 #define FAT_MAX_ALLOCATE_SIZE 0xA00000
117 #define LC_ISO_639_2_ENTRY_SIZE 3
118 #define MAX_LANG_CODE_SIZE 100
120 #define FAT_MAX_DIR_CACHE_COUNT 8
121 #define FAT_MAX_DIRENTRY_COUNT 0xFFFF
122 typedef CHAR8 LC_ISO_639_2
;
125 // The fat types we support
144 READ_DISK
= 0, // raw disk read
145 WRITE_DISK
= 1, // raw disk write
146 READ_FAT
= 2, // read fat cache
147 WRITE_FAT
= 3, // write fat cache
148 READ_DATA
= 6, // read data cache
149 WRITE_DATA
= 7 // write data cache
152 #define CACHE_ENABLED(a) ((a) >= 2)
153 #define RAW_ACCESS(a) ((IO_MODE)((a) & 0x1))
154 #define CACHE_TYPE(a) ((CACHE_DATA_TYPE)((a) >> 2))
172 CACHE_TAG CacheTag
[FAT_DATACACHE_GROUP_COUNT
];
178 #define HASH_TABLE_SIZE 0x400
179 #define HASH_TABLE_MASK (HASH_TABLE_SIZE - 1)
182 // The directory entry for opened directory
184 typedef struct _FAT_DIRENT
{
186 UINT16 EntryPos
; // The position of this directory entry in the parent directory file
187 UINT8 EntryCount
; // The count of the directory entry in the parent directory file
188 BOOLEAN Invalid
; // Indicate whether this directory entry is valid
189 CHAR16
*FileString
; // The unicode long file name for this directory entry
190 struct _FAT_OFILE
*OFile
; // The OFile of the corresponding directory entry
191 struct _FAT_DIRENT
*ShortNameForwardLink
; // Hash successor link for short filename
192 struct _FAT_DIRENT
*LongNameForwardLink
; // Hash successor link for long filename
193 LIST_ENTRY Link
; // Connection of every directory entry
194 FAT_DIRECTORY_ENTRY Entry
; // The physical directory entry stored in disk
197 typedef struct _FAT_ODIR
{
199 UINT32 CurrentEndPos
; // Current end position of the directory
200 UINT32 CurrentPos
; // Current position of the directory
201 LIST_ENTRY
*CurrentCursor
; // Current directory entry pointer
202 LIST_ENTRY ChildList
; // List of all directory entries
203 BOOLEAN EndOfDir
; // Indicate whether we have reached the end of the directory
204 LIST_ENTRY DirCacheLink
; // Linked in Volume->DirCacheList when discarded
205 UINTN DirCacheTag
; // The identification of the directory when in directory cache
206 FAT_DIRENT
*LongNameHashTable
[HASH_TABLE_SIZE
];
207 FAT_DIRENT
*ShortNameHashTable
[HASH_TABLE_SIZE
];
215 struct _FAT_OFILE
*OFile
;
220 // FAT_OFILE - Each opened file
222 typedef struct _FAT_OFILE
{
224 struct _FAT_VOLUME
*Volume
;
226 // A permanant error code to return to all accesses to
231 // A list of the IFILE instances for this OFile
236 // The dynamic infomation
240 UINTN FileCurrentCluster
;
241 UINTN FileLastCluster
;
244 // Dirty is set if there have been any updates to the
246 // Archive is set if the archive attribute in the file's
247 // directory entry needs to be set when performing flush
248 // PreserveLastMod is set if the last modification of the
249 // file is specified by SetInfo API
252 BOOLEAN IsFixedRootDir
;
253 BOOLEAN PreserveLastModification
;
256 // Set by an OFile SetPosition
258 UINTN Position
; // within file
259 UINT64 PosDisk
; // on the disk
260 UINTN PosRem
; // remaining in this disk run
262 // The opened parent, full path length and currently opened child files
264 struct _FAT_OFILE
*Parent
;
266 LIST_ENTRY ChildHead
;
267 LIST_ENTRY ChildLink
;
270 // The opened directory structure for a directory; if this
271 // OFile represents a file, then ODir = NULL
275 // The directory entry for the Ofile
280 // Link in Volume's reference list
282 LIST_ENTRY CheckLink
;
285 typedef struct _FAT_VOLUME
{
292 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL VolumeInterface
;
295 // If opened, the parent handle and BlockIo interface
297 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
298 EFI_DISK_IO_PROTOCOL
*DiskIo
;
303 // Computed values from fat bpb info
306 UINT64 FatPos
; // Disk pos of fat tables
307 UINT64 RootPos
; // Disk pos of root directory
308 UINT64 FirstClusterPos
; // Disk pos of first cluster
309 UINTN FatSize
; // Number of bytes in each fat
310 UINTN MaxCluster
; // Max cluster number
311 UINTN ClusterSize
; // Cluster size of fat partition
312 UINT8 ClusterAlignment
; // Equal to log_2 (clustersize);
313 FAT_VOLUME_TYPE FatType
;
316 // Current part of fat table that's present
318 UINT64 FatEntryPos
; // Location of buffer
319 UINTN FatEntrySize
; // Size of buffer
320 UINT32 FatEntryBuffer
; // The buffer
321 FAT_INFO_SECTOR FatInfoSector
; // Free cluster info
322 UINTN FreeInfoPos
; // Pos with the free cluster info
323 BOOLEAN FreeInfoValid
; // If free cluster info is valid
325 // Unpacked Fat BPB info
328 UINTN RootEntries
; // < FAT32, root dir is fixed size
329 UINTN RootCluster
; // >= FAT32, root cluster chain head
331 // info for marking the volume dirty or not
333 BOOLEAN FatDirty
; // If fat-entries have been updated
335 UINT32 NotDirtyValue
;
338 // The root directory entry and opened root file
340 FAT_DIRENT RootDirEnt
;
342 // File Name of root OFile, it is empty string
344 CHAR16 RootFileString
[1];
345 struct _FAT_OFILE
*Root
;
348 // New OFiles are added to this list so they
349 // can be cleaned up if they aren't referenced.
354 // Directory cache List
356 LIST_ENTRY DirCacheList
;
360 // Disk Cache for this volume
363 DISK_CACHE DiskCache
[CACHE_MAX_TYPE
];
367 // Function Prototypes
373 OUT EFI_FILE
**NewHandle
,
381 Implements Open() of Simple File System Protocol.
385 FHand - File handle of the file serves as a starting reference point.
386 NewHandle - Handle of the file that is newly opened.
387 FileName - File name relative to FHand.
388 OpenMode - Open mode.
389 Attributes - Attributes to set if the file is created.
393 EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty.
394 The OpenMode is not supported.
395 The Attributes is not the valid attributes.
396 EFI_OUT_OF_RESOURCES - Can not allocate the memory for file string.
397 EFI_SUCCESS - Open the file successfully.
398 Others - The status of open file.
413 Get the file's position of the file
417 FHand - The handle of file.
418 Position - The file's position of the file.
422 EFI_SUCCESS - Get the info successfully.
423 EFI_DEVICE_ERROR - Can not find the OFile for the file.
424 EFI_UNSUPPORTED - The open file is not a file.
434 IN OUT UINTN
*BufferSize
,
441 Get the some types info of the file into Buffer
445 FHand - The handle of file.
446 Type - The type of the info.
447 BufferSize - Size of Buffer.
448 Buffer - Buffer containing volume info.
452 EFI_SUCCESS - Get the info successfully.
453 EFI_DEVICE_ERROR - Can not find the OFile for the file.
470 Set the some types info of the file into Buffer
474 FHand - The handle of file.
475 Type - The type of the info.
476 BufferSize - Size of Buffer.
477 Buffer - Buffer containing volume info.
481 EFI_SUCCESS - Set the info successfully.
482 EFI_DEVICE_ERROR - Can not find the OFile for the file.
496 Flushes all data associated with the file handle
500 FHand - Handle to file to flush
504 EFI_SUCCESS - Flushed the file successfully
505 EFI_WRITE_PROTECTED - The volume is read only
506 EFI_ACCESS_DENIED - The volume is not read only
507 but the file is read only
508 Others - Flushing of the file is failed
522 Flushes & Closes the file handle.
526 FHand - Handle to the file to delete.
530 EFI_SUCCESS - Closed the file successfully.
544 Deletes the file & Closes the file handle.
548 FHand - Handle to the file to delete.
552 EFI_SUCCESS - Delete the file successfully.
553 EFI_WARN_DELETE_FAILURE - Fail to delete the file.
568 Set the file's position of the file
572 FHand - The handle of file
573 Position - The file's position of the file
577 EFI_SUCCESS - Set the info successfully
578 EFI_DEVICE_ERROR - Can not find the OFile for the file
579 EFI_UNSUPPORTED - Set a directory with a not-zero position
588 IN OUT UINTN
*BufferSize
,
599 FHand - The handle of the file.
600 BufferSize - Size of Buffer.
601 Buffer - Buffer containing read data.
605 EFI_SUCCESS - Get the file info successfully.
606 EFI_DEVICE_ERROR - Can not find the OFile for the file.
607 EFI_VOLUME_CORRUPTED - The file type of open file is error.
608 other - An error occurred when operation the disk.
617 IN OUT UINTN
*BufferSize
,
628 FHand - The handle of the file.
629 BufferSize - Size of Buffer.
630 Buffer - Buffer containing write data.
634 EFI_SUCCESS - Set the file info successfully.
635 EFI_WRITE_PROTECTED - The disk is write protected.
636 EFI_ACCESS_DENIED - The file is read-only.
637 EFI_DEVICE_ERROR - The OFile is not valid.
638 EFI_UNSUPPORTED - The open file is not a file.
639 - The writing file size is larger than 4GB.
640 other - An error occurred when operation the disk.
649 FatInitializeDiskCache (
650 IN FAT_VOLUME
*Volume
655 IN FAT_VOLUME
*Volume
,
656 IN CACHE_DATA_TYPE CacheDataType
,
664 FatVolumeFlushCache (
665 IN FAT_VOLUME
*Volume
694 IN FAT_VOLUME
*Volume
,
696 IN EFI_STATUS EfiStatus
710 IN UINT64 NewSizeInBytes
715 IN FAT_VOLUME
*Volume
,
720 FatPhysicalFileSize (
721 IN FAT_VOLUME
*Volume
,
734 IN FAT_VOLUME
*Volume
742 IN EFI_HANDLE Handle
,
743 IN EFI_DISK_IO_PROTOCOL
*DiskIo
,
744 IN EFI_BLOCK_IO_PROTOCOL
*BlockIo
749 IN OUT FAT_VOLUME
*Volume
754 IN FAT_VOLUME
*Volume
761 FatAccessVolumeDirty (
762 IN FAT_VOLUME
*Volume
,
769 IN FAT_VOLUME
*Volume
,
793 IN FAT_DIRENT
*DirEnt
798 IN FAT_VOLUME
*Volume
802 FatEfiTimeToFatTime (
804 OUT FAT_DATE_TIME
*FTime
808 FatFatTimeToEfiTime (
809 IN FAT_DATE_TIME
*FTime
,
814 FatGetCurrentFatTime (
815 OUT FAT_DATE_TIME
*FatTime
824 // UnicodeCollation.c
827 InitializeUnicodeCollationSupport (
828 IN EFI_HANDLE AgentHandle
867 OUT FAT_IFILE
**NewIFile
,
876 OUT FAT_IFILE
**PtrIFile
885 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*This
,
897 IN UINTN
*DataBufferSize
,
904 IN UINT64 ExpandedSize
916 IN UINTN TruncatedSize
930 OUT FAT_DIRENT
**PtrDirEnt
936 IN FAT_DIRENT
*DirEnt
942 IN FAT_DIRENT
*DirEnt
950 OUT FAT_DIRENT
**PtrDirEnt
955 IN FAT_DIRENT
*DirEnt
959 FatUpdateDirEntClusterSizeInfo (
965 IN FAT_DIRENT
*DirEnt1
,
966 IN FAT_DIRENT
*DirEnt2
971 IN FAT_VOLUME
*Volume
,
972 IN FAT_DIRENT
*DirEnt
,
973 IN OUT UINTN
*BufferSize
,
980 IN FAT_DIRENT
*DirEnt
984 FatCreateDotDirEnts (
990 IN FAT_DIRENT
*DirEnt
995 IN OUT FAT_OFILE
**PtrOFile
,
998 OUT CHAR16
*NewFileName
1003 IN FAT_VOLUME
*Volume
,
1009 IN FAT_VOLUME
*Volume
,
1017 FatLongNameHashSearch (
1019 IN CHAR16
*LongNameString
1023 FatShortNameHashSearch (
1025 IN CHAR8
*ShortNameString
1029 FatInsertToHashTable (
1031 IN FAT_DIRENT
*DirEnt
1035 FatDeleteFromHashTable (
1037 IN FAT_DIRENT
*DirEnt
1044 FatCheckIs8Dot3Name (
1045 IN CHAR16
*FileName
,
1046 OUT CHAR8
*File8Dot3Name
1050 FatCreate8Dot3Name (
1051 IN FAT_OFILE
*Parent
,
1052 IN FAT_DIRENT
*DirEnt
1065 IN FAT_DIRENT
*DirEnt
1069 FatGetFileNameViaCaseFlag (
1070 IN FAT_DIRENT
*DirEnt
,
1071 OUT CHAR16
*FileString
1076 IN CHAR8
*ShortNameString
1080 FatGetNextNameComponent (
1086 FatFileNameIsValid (
1087 IN CHAR16
*InputFileName
,
1088 OUT CHAR16
*OutputFileName
1105 FatCleanupODirCache (
1106 IN FAT_VOLUME
*Volume
1112 extern EFI_DRIVER_BINDING_PROTOCOL gFatDriverBinding
;
1113 extern EFI_COMPONENT_NAME_PROTOCOL gFatComponentName
;
1114 extern EFI_COMPONENT_NAME2_PROTOCOL gFatComponentName2
;
1115 extern EFI_LOCK FatFsLock
;
1116 extern EFI_FILE FatFileInterface
;