1 /* 2 * Copyright 2011, Jérôme Duval, korli@users.berlios.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef EXFAT_H 6 #define EXFAT_H 7 8 9 #include <sys/stat.h> 10 11 #include <ByteOrder.h> 12 #include <fs_interface.h> 13 #include <KernelExport.h> 14 15 16 typedef uint64 fileblock_t; // file block number 17 typedef uint64 fsblock_t; // filesystem block number 18 19 typedef uint32 cluster_t; 20 21 #define EXFAT_SUPER_BLOCK_OFFSET 0x0 22 23 24 struct exfat_super_block { 25 uint8 jump_boot[3]; 26 char filesystem[8]; 27 uint8 reserved[53]; 28 uint64 first_block; 29 uint64 num_blocks; 30 uint32 first_fat_block; 31 uint32 fat_length; 32 uint32 first_data_block; 33 uint32 cluster_count; 34 uint32 root_dir_cluster; 35 uint32 serial_number; 36 uint8 version_minor; 37 uint8 version_major; 38 uint16 flags; 39 uint8 block_shift; 40 uint8 blocks_per_cluster_shift; 41 uint8 fat_count; 42 uint8 drive_select; 43 uint8 used_percent; 44 uint8 reserved2[7]; 45 uint8 boot_code[390]; 46 uint16 signature; 47 48 bool IsValid(); 49 // implemented in Volume.cpp 50 uint64 FirstBlock() const { return B_LENDIAN_TO_HOST_INT64(first_block); } 51 uint64 NumBlocks() const { return B_LENDIAN_TO_HOST_INT32(num_blocks); } 52 uint32 FirstFatBlock() const 53 { return B_LENDIAN_TO_HOST_INT32(first_fat_block); } 54 uint32 FatLength() const 55 { return B_LENDIAN_TO_HOST_INT32(fat_length); } 56 uint32 FirstDataBlock() const 57 { return B_LENDIAN_TO_HOST_INT32(first_data_block); } 58 uint32 ClusterCount() const 59 { return B_LENDIAN_TO_HOST_INT32(cluster_count); } 60 uint32 RootDirCluster() const 61 { return B_LENDIAN_TO_HOST_INT32(root_dir_cluster); } 62 uint32 SerialNumber() const 63 { return B_LENDIAN_TO_HOST_INT32(serial_number); } 64 uint8 VersionMinor() const { return version_minor; } 65 uint8 VersionMajor() const { return version_major; } 66 uint16 Flags() const { return B_LENDIAN_TO_HOST_INT16(flags); } 67 uint8 BlockShift() const { return block_shift; } 68 uint8 BlocksPerClusterShift() const { return blocks_per_cluster_shift; } 69 uint8 FatCount() const { return fat_count; } 70 uint8 DriveSelect() const { return drive_select; } 71 uint8 UsedPercent() const { return used_percent; } 72 } _PACKED; 73 74 75 #define EXFAT_SUPER_BLOCK_MAGIC "EXFAT " 76 77 #define EXFAT_ENTRY_TYPE_BITMAP 0x81 78 #define EXFAT_ENTRY_TYPE_UPPERCASE 0x82 79 #define EXFAT_ENTRY_TYPE_LABEL 0x83 80 #define EXFAT_ENTRY_TYPE_FILE 0x85 81 #define EXFAT_ENTRY_TYPE_FILEINFO 0xc0 82 #define EXFAT_ENTRY_TYPE_FILENAME 0xc1 83 #define EXFAT_CLUSTER_END 0xffffffff 84 #define EXFAT_ENTRY_ATTRIB_SUBDIR 0x10 85 86 #define EXFAT_ENTRY_FLAG_CONTIGUOUS 0x3 87 88 #define EXFAT_FILENAME_MAX_LENGTH 512 89 90 struct exfat_entry { 91 uint8 type; 92 union { 93 struct { 94 uint8 length; 95 char name[30]; 96 } _PACKED name_label; 97 struct { 98 uint8 reserved[3]; 99 uint32 checksum; 100 uint8 reserved2[12]; 101 uint32 start_cluster; 102 uint64 size; 103 } _PACKED bitmap_uppercase; 104 struct { 105 uint8 chunkCount; 106 uint16 checksum; 107 uint16 attribs; 108 uint16 reserved; 109 uint16 creation_time; 110 uint16 creation_date; 111 uint16 modification_time; 112 uint16 modification_date; 113 uint16 access_time; 114 uint16 access_date; 115 uint8 creation_time_low; 116 uint8 modification_time_low; 117 uint8 reserved2[10]; 118 uint16 ModificationTime() const 119 { return B_LENDIAN_TO_HOST_INT16(modification_time); } 120 uint16 ModificationDate() const 121 { return B_LENDIAN_TO_HOST_INT16(modification_date); } 122 uint16 AccessTime() const 123 { return B_LENDIAN_TO_HOST_INT16(access_time); } 124 uint16 AccessDate() const 125 { return B_LENDIAN_TO_HOST_INT16(access_date); } 126 uint16 CreationTime() const 127 { return B_LENDIAN_TO_HOST_INT16(creation_time); } 128 uint16 CreationDate() const 129 { return B_LENDIAN_TO_HOST_INT16(creation_date); } 130 uint16 Attribs() const 131 { return B_LENDIAN_TO_HOST_INT16(attribs); } 132 void SetAttribs(uint16 newAttribs) 133 { attribs = B_HOST_TO_LENDIAN_INT16(newAttribs); } 134 } _PACKED file; 135 struct { 136 uint8 flag; 137 uint8 reserved; 138 uint8 name_length; 139 uint16 name_hash; 140 uint8 reserved2[2]; 141 uint64 size1; 142 uint8 reserved3[4]; 143 uint32 start_cluster; 144 uint64 size2; 145 uint32 StartCluster() const 146 { return B_LENDIAN_TO_HOST_INT32(start_cluster); } 147 void SetStartCluster(uint32 startCluster) 148 { start_cluster = B_HOST_TO_LENDIAN_INT32(startCluster); } 149 bool IsContiguous() const 150 { return (flag & EXFAT_ENTRY_FLAG_CONTIGUOUS) != 0; } 151 void SetFlag(uint8 newFlag) 152 { flag = newFlag; } 153 uint64 Size() const 154 { return B_LENDIAN_TO_HOST_INT64(size1); } 155 } _PACKED file_info; 156 }; 157 } _PACKED; 158 159 160 struct file_cookie { 161 bigtime_t last_notification; 162 off_t last_size; 163 int open_mode; 164 }; 165 166 #define EXFAT_OPEN_MODE_USER_MASK 0x7fffffff 167 168 extern fs_volume_ops gExfatVolumeOps; 169 extern fs_vnode_ops gExfatVnodeOps; 170 171 #endif // EXFAT_H 172