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 <Guid/GlobalVariable.h>
34 #include <Protocol/BlockIo.h>
35 #include <Protocol/DiskIo.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 EFI_SIGNATURE_32 ('f', 'a', 't', 'v')
55 #define FAT_IFILE_SIGNATURE EFI_SIGNATURE_32 ('f', 'a', 't', 'i')
56 #define FAT_ODIR_SIGNATURE EFI_SIGNATURE_32 ('f', 'a', 't', 'd')
57 #define FAT_DIRENT_SIGNATURE EFI_SIGNATURE_32 ('f', 'a', 't', 'e')
58 #define FAT_OFILE_SIGNATURE EFI_SIGNATURE_32 ('f', 'a', 't', 'o')
60 #define ASSERT_VOLUME_LOCKED(a) ASSERT_LOCKED (&FatFsLock)
62 #define IFILE_FROM_FHAND(a) CR (a, FAT_IFILE, Handle, FAT_IFILE_SIGNATURE)
64 #define DIRENT_FROM_LINK(a) CR (a, FAT_DIRENT, Link, FAT_DIRENT_SIGNATURE)
66 #define VOLUME_FROM_ROOT_DIRENT(a) CR (a, FAT_VOLUME, RootDirEnt, FAT_VOLUME_SIGNATURE)
68 #define VOLUME_FROM_VOL_INTERFACE(a) CR (a, FAT_VOLUME, VolumeInterface, FAT_VOLUME_SIGNATURE);
70 #define ODIR_FROM_DIRCACHELINK(a) CR (a, FAT_ODIR, DirCacheLink, FAT_ODIR_SIGNATURE)
72 #define OFILE_FROM_CHECKLINK(a) CR (a, FAT_OFILE, CheckLink, FAT_OFILE_SIGNATURE)
74 #define OFILE_FROM_CHILDLINK(a) CR (a, FAT_OFILE, ChildLink, FAT_OFILE_SIGNATURE)
77 // Minimum sector size is 512B, Maximum sector size is 4096B
78 // Max sectors per cluster is 128
80 #define MAX_BLOCK_ALIGNMENT 12
81 #define MIN_BLOCK_ALIGNMENT 9
82 #define MAX_SECTORS_PER_CLUSTER_ALIGNMENT 7
85 // Efi Time Definition
87 #define IS_LEAP_YEAR(a) (((a) % 4 == 0) && (((a) % 100 != 0) || ((a) % 400 == 0)))
90 // Minimum fat page size is 8K, maximum fat page alignment is 32K
91 // Minimum data page size is 8K, maximum fat page alignment is 64K
93 #define FAT_FATCACHE_PAGE_MIN_ALIGNMENT 13
94 #define FAT_FATCACHE_PAGE_MAX_ALIGNMENT 15
95 #define FAT_DATACACHE_PAGE_MIN_ALIGNMENT 13
96 #define FAT_DATACACHE_PAGE_MAX_ALIGNMENT 16
97 #define FAT_DATACACHE_GROUP_COUNT 64
98 #define FAT_FATCACHE_GROUP_MIN_COUNT 1
99 #define FAT_FATCACHE_GROUP_MAX_COUNT 16
102 // Used in 8.3 generation algorithm
104 #define MAX_SPEC_RETRY 4
105 #define SPEC_BASE_TAG_LEN 6
106 #define HASH_BASE_TAG_LEN 2
107 #define HASH_VALUE_TAG_LEN (SPEC_BASE_TAG_LEN - HASH_BASE_TAG_LEN)
110 // Path name separator is back slash
112 #define PATH_NAME_SEPARATOR L'\\'
115 #define EFI_PATH_STRING_LENGTH 260
116 #define EFI_FILE_STRING_LENGTH 255
117 #define FAT_MAX_ALLOCATE_SIZE 0xA00000
118 #define LC_ISO_639_2_ENTRY_SIZE 3
119 #define MAX_LANG_CODE_SIZE 100
121 #define FAT_MAX_DIR_CACHE_COUNT 8
122 #define FAT_MAX_DIRENTRY_COUNT 0xFFFF
123 typedef CHAR8 LC_ISO_639_2
;
126 // The fat types we support
145 READ_DISK
= 0, // raw disk read
146 WRITE_DISK
= 1, // raw disk write
147 READ_FAT
= 2, // read fat cache
148 WRITE_FAT
= 3, // write fat cache
149 READ_DATA
= 6, // read data cache
150 WRITE_DATA
= 7 // write data cache
153 #define CACHE_ENABLED(a) ((a) >= 2)
154 #define RAW_ACCESS(a) ((IO_MODE)((a) & 0x1))
155 #define CACHE_TYPE(a) ((CACHE_DATA_TYPE)((a) >> 2))
173 CACHE_TAG CacheTag
[FAT_DATACACHE_GROUP_COUNT
];
179 #define HASH_TABLE_SIZE 0x400
180 #define HASH_TABLE_MASK (HASH_TABLE_SIZE - 1)
183 // The directory entry for opened directory
185 typedef struct _FAT_DIRENT
{
187 UINT16 EntryPos
; // The position of this directory entry in the parent directory file
188 UINT8 EntryCount
; // The count of the directory entry in the parent directory file
189 BOOLEAN Invalid
; // Indicate whether this directory entry is valid
190 CHAR16
*FileString
; // The unicode long file name for this directory entry
191 struct _FAT_OFILE
*OFile
; // The OFile of the corresponding directory entry
192 struct _FAT_DIRENT
*ShortNameForwardLink
; // Hash successor link for short filename
193 struct _FAT_DIRENT
*LongNameForwardLink
; // Hash successor link for long filename
194 LIST_ENTRY Link
; // Connection of every directory entry
195 FAT_DIRECTORY_ENTRY Entry
; // The physical directory entry stored in disk
198 typedef struct _FAT_ODIR
{
200 UINT32 CurrentEndPos
; // Current end position of the directory
201 UINT32 CurrentPos
; // Current position of the directory
202 LIST_ENTRY
*CurrentCursor
; // Current directory entry pointer
203 LIST_ENTRY ChildList
; // List of all directory entries
204 BOOLEAN EndOfDir
; // Indicate whether we have reached the end of the directory
205 LIST_ENTRY DirCacheLink
; // Linked in Volume->DirCacheList when discarded
206 UINTN DirCacheTag
; // The identification of the directory when in directory cache
207 FAT_DIRENT
*LongNameHashTable
[HASH_TABLE_SIZE
];
208 FAT_DIRENT
*ShortNameHashTable
[HASH_TABLE_SIZE
];
216 struct _FAT_OFILE
*OFile
;
221 // FAT_OFILE - Each opened file
223 typedef struct _FAT_OFILE
{
225 struct _FAT_VOLUME
*Volume
;
227 // A permanant error code to return to all accesses to
232 // A list of the IFILE instances for this OFile
237 // The dynamic infomation
241 UINTN FileCurrentCluster
;
242 UINTN FileLastCluster
;
245 // Dirty is set if there have been any updates to the
247 // Archive is set if the archive attribute in the file's
248 // directory entry needs to be set when performing flush
249 // PreserveLastMod is set if the last modification of the
250 // file is specified by SetInfo API
253 BOOLEAN IsFixedRootDir
;
254 BOOLEAN PreserveLastModification
;
257 // Set by an OFile SetPosition
259 UINTN Position
; // within file
260 UINT64 PosDisk
; // on the disk
261 UINTN PosRem
; // remaining in this disk run
263 // The opened parent, full path length and currently opened child files
265 struct _FAT_OFILE
*Parent
;
267 LIST_ENTRY ChildHead
;
268 LIST_ENTRY ChildLink
;
271 // The opened directory structure for a directory; if this
272 // OFile represents a file, then ODir = NULL
276 // The directory entry for the Ofile
281 // Link in Volume's reference list
283 LIST_ENTRY CheckLink
;
286 typedef struct _FAT_VOLUME
{
293 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL VolumeInterface
;
296 // If opened, the parent handle and BlockIo interface
298 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
299 EFI_DISK_IO_PROTOCOL
*DiskIo
;
304 // Computed values from fat bpb info
307 UINT64 FatPos
; // Disk pos of fat tables
308 UINT64 RootPos
; // Disk pos of root directory
309 UINT64 FirstClusterPos
; // Disk pos of first cluster
310 UINTN FatSize
; // Number of bytes in each fat
311 UINTN MaxCluster
; // Max cluster number
312 UINTN ClusterSize
; // Cluster size of fat partition
313 UINT8 ClusterAlignment
; // Equal to log_2 (clustersize);
314 FAT_VOLUME_TYPE FatType
;
317 // Current part of fat table that's present
319 UINT64 FatEntryPos
; // Location of buffer
320 UINTN FatEntrySize
; // Size of buffer
321 UINT32 FatEntryBuffer
; // The buffer
322 FAT_INFO_SECTOR FatInfoSector
; // Free cluster info
323 UINTN FreeInfoPos
; // Pos with the free cluster info
324 BOOLEAN FreeInfoValid
; // If free cluster info is valid
326 // Unpacked Fat BPB info
329 UINTN RootEntries
; // < FAT32, root dir is fixed size
330 UINTN RootCluster
; // >= FAT32, root cluster chain head
332 // info for marking the volume dirty or not
334 BOOLEAN FatDirty
; // If fat-entries have been updated
336 UINT32 NotDirtyValue
;
339 // The root directory entry and opened root file
341 FAT_DIRENT RootDirEnt
;
343 // File Name of root OFile, it is empty string
345 CHAR16 RootFileString
[1];
346 struct _FAT_OFILE
*Root
;
349 // New OFiles are added to this list so they
350 // can be cleaned up if they aren't referenced.
355 // Directory cache List
357 LIST_ENTRY DirCacheList
;
361 // Disk Cache for this volume
364 DISK_CACHE DiskCache
[CACHE_MAX_TYPE
];
368 // Function Prototypes
374 OUT EFI_FILE
**NewHandle
,
382 Implements Open() of Simple File System Protocol.
386 FHand - File handle of the file serves as a starting reference point.
387 NewHandle - Handle of the file that is newly opened.
388 FileName - File name relative to FHand.
389 OpenMode - Open mode.
390 Attributes - Attributes to set if the file is created.
394 EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty.
395 The OpenMode is not supported.
396 The Attributes is not the valid attributes.
397 EFI_OUT_OF_RESOURCES - Can not allocate the memory for file string.
398 EFI_SUCCESS - Open the file successfully.
399 Others - The status of open file.
414 Get the file's position of the file
418 FHand - The handle of file.
419 Position - The file's position of the file.
423 EFI_SUCCESS - Get the info successfully.
424 EFI_DEVICE_ERROR - Can not find the OFile for the file.
425 EFI_UNSUPPORTED - The open file is not a file.
435 IN OUT UINTN
*BufferSize
,
442 Get the some types info of the file into Buffer
446 FHand - The handle of file.
447 Type - The type of the info.
448 BufferSize - Size of Buffer.
449 Buffer - Buffer containing volume info.
453 EFI_SUCCESS - Get the info successfully.
454 EFI_DEVICE_ERROR - Can not find the OFile for the file.
471 Set the some types info of the file into Buffer
475 FHand - The handle of file.
476 Type - The type of the info.
477 BufferSize - Size of Buffer.
478 Buffer - Buffer containing volume info.
482 EFI_SUCCESS - Set the info successfully.
483 EFI_DEVICE_ERROR - Can not find the OFile for the file.
497 Flushes all data associated with the file handle
501 FHand - Handle to file to flush
505 EFI_SUCCESS - Flushed the file successfully
506 EFI_WRITE_PROTECTED - The volume is read only
507 EFI_ACCESS_DENIED - The volume is not read only
508 but the file is read only
509 Others - Flushing of the file is failed
523 Flushes & Closes the file handle.
527 FHand - Handle to the file to delete.
531 EFI_SUCCESS - Closed the file successfully.
545 Deletes the file & Closes the file handle.
549 FHand - Handle to the file to delete.
553 EFI_SUCCESS - Delete the file successfully.
554 EFI_WARN_DELETE_FAILURE - Fail to delete the file.
569 Set the file's position of the file
573 FHand - The handle of file
574 Position - The file's position of the file
578 EFI_SUCCESS - Set the info successfully
579 EFI_DEVICE_ERROR - Can not find the OFile for the file
580 EFI_UNSUPPORTED - Set a directory with a not-zero position
589 IN OUT UINTN
*BufferSize
,
600 FHand - The handle of the file.
601 BufferSize - Size of Buffer.
602 Buffer - Buffer containing read data.
606 EFI_SUCCESS - Get the file info successfully.
607 EFI_DEVICE_ERROR - Can not find the OFile for the file.
608 EFI_VOLUME_CORRUPTED - The file type of open file is error.
609 other - An error occurred when operation the disk.
618 IN OUT UINTN
*BufferSize
,
629 FHand - The handle of the file.
630 BufferSize - Size of Buffer.
631 Buffer - Buffer containing write data.
635 EFI_SUCCESS - Set the file info successfully.
636 EFI_WRITE_PROTECTED - The disk is write protected.
637 EFI_ACCESS_DENIED - The file is read-only.
638 EFI_DEVICE_ERROR - The OFile is not valid.
639 EFI_UNSUPPORTED - The open file is not a file.
640 - The writing file size is larger than 4GB.
641 other - An error occurred when operation the disk.
650 FatInitializeDiskCache (
651 IN FAT_VOLUME
*Volume
656 IN FAT_VOLUME
*Volume
,
657 IN CACHE_DATA_TYPE CacheDataType
,
665 FatVolumeFlushCache (
666 IN FAT_VOLUME
*Volume
695 IN FAT_VOLUME
*Volume
,
697 IN EFI_STATUS EfiStatus
711 IN UINT64 NewSizeInBytes
716 IN FAT_VOLUME
*Volume
,
721 FatPhysicalFileSize (
722 IN FAT_VOLUME
*Volume
,
735 IN FAT_VOLUME
*Volume
743 IN EFI_HANDLE Handle
,
744 IN EFI_DISK_IO_PROTOCOL
*DiskIo
,
745 IN EFI_BLOCK_IO_PROTOCOL
*BlockIo
750 IN OUT FAT_VOLUME
*Volume
755 IN FAT_VOLUME
*Volume
762 FatAccessVolumeDirty (
763 IN FAT_VOLUME
*Volume
,
770 IN FAT_VOLUME
*Volume
,
794 IN FAT_DIRENT
*DirEnt
799 IN FAT_VOLUME
*Volume
803 FatEfiTimeToFatTime (
805 OUT FAT_DATE_TIME
*FTime
809 FatFatTimeToEfiTime (
810 IN FAT_DATE_TIME
*FTime
,
815 FatGetCurrentFatTime (
816 OUT FAT_DATE_TIME
*FatTime
825 // UnicodeCollation.c
828 InitializeUnicodeCollationSupport (
829 IN EFI_HANDLE AgentHandle
868 OUT FAT_IFILE
**NewIFile
,
877 OUT FAT_IFILE
**PtrIFile
886 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*This
,
898 IN UINTN
*DataBufferSize
,
905 IN UINT64 ExpandedSize
917 IN UINTN TruncatedSize
931 OUT FAT_DIRENT
**PtrDirEnt
937 IN FAT_DIRENT
*DirEnt
943 IN FAT_DIRENT
*DirEnt
951 OUT FAT_DIRENT
**PtrDirEnt
956 IN FAT_DIRENT
*DirEnt
960 FatUpdateDirEntClusterSizeInfo (
966 IN FAT_DIRENT
*DirEnt1
,
967 IN FAT_DIRENT
*DirEnt2
972 IN FAT_VOLUME
*Volume
,
973 IN FAT_DIRENT
*DirEnt
,
974 IN OUT UINTN
*BufferSize
,
981 IN FAT_DIRENT
*DirEnt
985 FatCreateDotDirEnts (
991 IN FAT_DIRENT
*DirEnt
996 IN OUT FAT_OFILE
**PtrOFile
,
999 OUT CHAR16
*NewFileName
1004 IN FAT_VOLUME
*Volume
,
1010 IN FAT_VOLUME
*Volume
,
1018 FatLongNameHashSearch (
1020 IN CHAR16
*LongNameString
1024 FatShortNameHashSearch (
1026 IN CHAR8
*ShortNameString
1030 FatInsertToHashTable (
1032 IN FAT_DIRENT
*DirEnt
1036 FatDeleteFromHashTable (
1038 IN FAT_DIRENT
*DirEnt
1045 FatCheckIs8Dot3Name (
1046 IN CHAR16
*FileName
,
1047 OUT CHAR8
*File8Dot3Name
1051 FatCreate8Dot3Name (
1052 IN FAT_OFILE
*Parent
,
1053 IN FAT_DIRENT
*DirEnt
1066 IN FAT_DIRENT
*DirEnt
1070 FatGetFileNameViaCaseFlag (
1071 IN FAT_DIRENT
*DirEnt
,
1072 OUT CHAR16
*FileString
1077 IN CHAR8
*ShortNameString
1081 FatGetNextNameComponent (
1087 FatFileNameIsValid (
1088 IN CHAR16
*InputFileName
,
1089 OUT CHAR16
*OutputFileName
1106 FatCleanupODirCache (
1107 IN FAT_VOLUME
*Volume
1113 extern EFI_DRIVER_BINDING_PROTOCOL gFatDriverBinding
;
1114 extern EFI_COMPONENT_NAME_PROTOCOL gFatComponentName
;
1115 extern EFI_COMPONENT_NAME2_PROTOCOL gFatComponentName2
;
1116 extern EFI_LOCK FatFsLock
;
1117 extern EFI_FILE FatFileInterface
;