1*508ec739SDaniel Rosenberg /* SPDX-License-Identifier: GPL-2.0-or-later */ 2*508ec739SDaniel Rosenberg /* 3*508ec739SDaniel Rosenberg * Copyright (C) 2019 Namjae Jeon <[email protected]> 4*508ec739SDaniel Rosenberg */ 5*508ec739SDaniel Rosenberg 6*508ec739SDaniel Rosenberg #ifndef _EXFAT_H 7*508ec739SDaniel Rosenberg #define _EXFAT_H 8*508ec739SDaniel Rosenberg 9*508ec739SDaniel Rosenberg #include <stdint.h> 10*508ec739SDaniel Rosenberg #include <linux/fs.h> 11*508ec739SDaniel Rosenberg 12*508ec739SDaniel Rosenberg #ifdef HAVE_CONFIG_H 13*508ec739SDaniel Rosenberg #include <config.h> 14*508ec739SDaniel Rosenberg #endif 15*508ec739SDaniel Rosenberg 16*508ec739SDaniel Rosenberg #ifdef WORDS_BIGENDIAN 17*508ec739SDaniel Rosenberg #define cpu_to_le16(x) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8)) 18*508ec739SDaniel Rosenberg #define cpu_to_le32(x) \ 19*508ec739SDaniel Rosenberg ((((x) & 0xff000000u) >> 24) | (((x) & 0x00ff0000u) >> 8) | \ 20*508ec739SDaniel Rosenberg (((x) & 0x0000ff00u) << 8) | (((x) & 0x000000ffu) << 24)) 21*508ec739SDaniel Rosenberg #define cpu_to_le64(x) (cpu_to_le32((uint64_t)(x)) << 32 | \ 22*508ec739SDaniel Rosenberg cpu_to_le32((uint64_t)(x) >> 32)) 23*508ec739SDaniel Rosenberg #else 24*508ec739SDaniel Rosenberg #define cpu_to_le16(x) (x) 25*508ec739SDaniel Rosenberg #define cpu_to_le32(x) (x) 26*508ec739SDaniel Rosenberg #define cpu_to_le64(x) (x) 27*508ec739SDaniel Rosenberg #endif 28*508ec739SDaniel Rosenberg 29*508ec739SDaniel Rosenberg #define le64_to_cpu(x) ((uint64_t)cpu_to_le64(x)) 30*508ec739SDaniel Rosenberg #define le32_to_cpu(x) ((uint32_t)cpu_to_le32(x)) 31*508ec739SDaniel Rosenberg #define le16_to_cpu(x) ((uint16_t)cpu_to_le16(x)) 32*508ec739SDaniel Rosenberg 33*508ec739SDaniel Rosenberg #define PBR_SIGNATURE 0xAA55 34*508ec739SDaniel Rosenberg 35*508ec739SDaniel Rosenberg #define VOL_CLEAN 0x0000 36*508ec739SDaniel Rosenberg #define VOL_DIRTY 0x0002 37*508ec739SDaniel Rosenberg 38*508ec739SDaniel Rosenberg #define DENTRY_SIZE 32 /* directory entry size */ 39*508ec739SDaniel Rosenberg #define DENTRY_SIZE_BITS 5 40*508ec739SDaniel Rosenberg /* exFAT allows 8388608(256MB) directory entries */ 41*508ec739SDaniel Rosenberg #define MAX_EXFAT_DENTRIES 8388608 42*508ec739SDaniel Rosenberg #define MIN_FILE_DENTRIES 3 43*508ec739SDaniel Rosenberg 44*508ec739SDaniel Rosenberg /* dentry types */ 45*508ec739SDaniel Rosenberg #define MSDOS_DELETED 0xE5 /* deleted mark */ 46*508ec739SDaniel Rosenberg #define MSDOS_UNUSED 0x00 /* end of directory */ 47*508ec739SDaniel Rosenberg 48*508ec739SDaniel Rosenberg #define EXFAT_LAST 0x00 /* end of directory */ 49*508ec739SDaniel Rosenberg #define EXFAT_DELETE ~(0x80) 50*508ec739SDaniel Rosenberg #define IS_EXFAT_DELETED(x) ((x) < 0x80) /* deleted file (0x01~0x7F) */ 51*508ec739SDaniel Rosenberg #define EXFAT_INVAL 0x80 /* invalid value */ 52*508ec739SDaniel Rosenberg #define EXFAT_BITMAP 0x81 /* allocation bitmap */ 53*508ec739SDaniel Rosenberg #define EXFAT_UPCASE 0x82 /* upcase table */ 54*508ec739SDaniel Rosenberg #define EXFAT_VOLUME 0x83 /* volume label */ 55*508ec739SDaniel Rosenberg #define EXFAT_FILE 0x85 /* file or dir */ 56*508ec739SDaniel Rosenberg #define EXFAT_GUID 0xA0 57*508ec739SDaniel Rosenberg #define EXFAT_PADDING 0xA1 58*508ec739SDaniel Rosenberg #define EXFAT_ACLTAB 0xA2 59*508ec739SDaniel Rosenberg #define EXFAT_STREAM 0xC0 /* stream entry */ 60*508ec739SDaniel Rosenberg #define EXFAT_NAME 0xC1 /* file name entry */ 61*508ec739SDaniel Rosenberg #define EXFAT_ACL 0xC2 /* stream entry */ 62*508ec739SDaniel Rosenberg 63*508ec739SDaniel Rosenberg /* checksum types */ 64*508ec739SDaniel Rosenberg #define CS_DIR_ENTRY 0 65*508ec739SDaniel Rosenberg #define CS_PBR_SECTOR 1 66*508ec739SDaniel Rosenberg #define CS_DEFAULT 2 67*508ec739SDaniel Rosenberg 68*508ec739SDaniel Rosenberg /* file attributes */ 69*508ec739SDaniel Rosenberg #define ATTR_READONLY 0x0001 70*508ec739SDaniel Rosenberg #define ATTR_HIDDEN 0x0002 71*508ec739SDaniel Rosenberg #define ATTR_SYSTEM 0x0004 72*508ec739SDaniel Rosenberg #define ATTR_VOLUME 0x0008 73*508ec739SDaniel Rosenberg #define ATTR_SUBDIR 0x0010 74*508ec739SDaniel Rosenberg #define ATTR_ARCHIVE 0x0020 75*508ec739SDaniel Rosenberg #define ATTR_EXTEND (ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | \ 76*508ec739SDaniel Rosenberg ATTR_VOLUME) /* 0x000F */ 77*508ec739SDaniel Rosenberg 78*508ec739SDaniel Rosenberg #define ATTR_EXTEND_MASK (ATTR_EXTEND | ATTR_SUBDIR | ATTR_ARCHIVE) 79*508ec739SDaniel Rosenberg #define ATTR_RWMASK (ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME | \ 80*508ec739SDaniel Rosenberg ATTR_SUBDIR | ATTR_ARCHIVE) 81*508ec739SDaniel Rosenberg 82*508ec739SDaniel Rosenberg #define ATTR_READONLY_LE cpu_to_le16(0x0001) 83*508ec739SDaniel Rosenberg #define ATTR_HIDDEN_LE cpu_to_le16(0x0002) 84*508ec739SDaniel Rosenberg #define ATTR_SYSTEM_LE cpu_to_le16(0x0004) 85*508ec739SDaniel Rosenberg #define ATTR_VOLUME_LE cpu_to_le16(0x0008) 86*508ec739SDaniel Rosenberg #define ATTR_SUBDIR_LE cpu_to_le16(0x0010) 87*508ec739SDaniel Rosenberg #define ATTR_ARCHIVE_LE cpu_to_le16(0x0020) 88*508ec739SDaniel Rosenberg 89*508ec739SDaniel Rosenberg /* stream flags */ 90*508ec739SDaniel Rosenberg #define EXFAT_SF_CONTIGUOUS 0x02 91*508ec739SDaniel Rosenberg 92*508ec739SDaniel Rosenberg #define CLUSTER_32(x) ((unsigned int)((x) & 0xFFFFFFFFU)) 93*508ec739SDaniel Rosenberg #define EXFAT_EOF_CLUSTER CLUSTER_32(~0) 94*508ec739SDaniel Rosenberg #define EXFAT_BAD_CLUSTER (0xFFFFFFF7U) 95*508ec739SDaniel Rosenberg #define EXFAT_FREE_CLUSTER (0) 96*508ec739SDaniel Rosenberg #define EXFAT_FIRST_CLUSTER (2) 97*508ec739SDaniel Rosenberg #define EXFAT_RESERVED_CLUSTERS (2) 98*508ec739SDaniel Rosenberg 99*508ec739SDaniel Rosenberg 100*508ec739SDaniel Rosenberg /* EXFAT BIOS parameter block (64 bytes) */ 101*508ec739SDaniel Rosenberg struct bpb64 { 102*508ec739SDaniel Rosenberg __u8 jmp_boot[3]; 103*508ec739SDaniel Rosenberg __u8 oem_name[8]; 104*508ec739SDaniel Rosenberg __u8 res_zero[53]; 105*508ec739SDaniel Rosenberg }; 106*508ec739SDaniel Rosenberg 107*508ec739SDaniel Rosenberg /* EXFAT EXTEND BIOS parameter block (56 bytes) */ 108*508ec739SDaniel Rosenberg struct bsx64 { 109*508ec739SDaniel Rosenberg __le64 vol_offset; 110*508ec739SDaniel Rosenberg __le64 vol_length; 111*508ec739SDaniel Rosenberg __le32 fat_offset; 112*508ec739SDaniel Rosenberg __le32 fat_length; 113*508ec739SDaniel Rosenberg __le32 clu_offset; 114*508ec739SDaniel Rosenberg __le32 clu_count; 115*508ec739SDaniel Rosenberg __le32 root_cluster; 116*508ec739SDaniel Rosenberg __le32 vol_serial; 117*508ec739SDaniel Rosenberg __u8 fs_version[2]; 118*508ec739SDaniel Rosenberg __le16 vol_flags; 119*508ec739SDaniel Rosenberg __u8 sect_size_bits; 120*508ec739SDaniel Rosenberg __u8 sect_per_clus_bits; 121*508ec739SDaniel Rosenberg __u8 num_fats; 122*508ec739SDaniel Rosenberg __u8 phy_drv_no; 123*508ec739SDaniel Rosenberg __u8 perc_in_use; 124*508ec739SDaniel Rosenberg __u8 reserved2[7]; 125*508ec739SDaniel Rosenberg }; 126*508ec739SDaniel Rosenberg 127*508ec739SDaniel Rosenberg /* Common PBR[Partition Boot Record] (512 bytes) */ 128*508ec739SDaniel Rosenberg struct pbr { 129*508ec739SDaniel Rosenberg struct bpb64 bpb; 130*508ec739SDaniel Rosenberg struct bsx64 bsx; 131*508ec739SDaniel Rosenberg __u8 boot_code[390]; 132*508ec739SDaniel Rosenberg __le16 signature; 133*508ec739SDaniel Rosenberg }; 134*508ec739SDaniel Rosenberg 135*508ec739SDaniel Rosenberg #define VOLUME_LABEL_MAX_LEN 11 136*508ec739SDaniel Rosenberg #define ENTRY_NAME_MAX 15 137*508ec739SDaniel Rosenberg 138*508ec739SDaniel Rosenberg struct exfat_dentry { 139*508ec739SDaniel Rosenberg __u8 type; 140*508ec739SDaniel Rosenberg union { 141*508ec739SDaniel Rosenberg struct { 142*508ec739SDaniel Rosenberg __u8 character_count; 143*508ec739SDaniel Rosenberg __le16 volume_label[VOLUME_LABEL_MAX_LEN]; 144*508ec739SDaniel Rosenberg __u8 reserved[8]; 145*508ec739SDaniel Rosenberg } __attribute__((packed)) vol; /* file directory entry */ 146*508ec739SDaniel Rosenberg 147*508ec739SDaniel Rosenberg struct { 148*508ec739SDaniel Rosenberg __u8 num_ext; 149*508ec739SDaniel Rosenberg __le16 checksum; 150*508ec739SDaniel Rosenberg __le16 attr; 151*508ec739SDaniel Rosenberg __le16 reserved1; 152*508ec739SDaniel Rosenberg __le16 create_time; 153*508ec739SDaniel Rosenberg __le16 create_date; 154*508ec739SDaniel Rosenberg __le16 modify_time; 155*508ec739SDaniel Rosenberg __le16 modify_date; 156*508ec739SDaniel Rosenberg __le16 access_time; 157*508ec739SDaniel Rosenberg __le16 access_date; 158*508ec739SDaniel Rosenberg __u8 create_time_ms; 159*508ec739SDaniel Rosenberg __u8 modify_time_ms; 160*508ec739SDaniel Rosenberg __u8 create_tz; 161*508ec739SDaniel Rosenberg __u8 modify_tz; 162*508ec739SDaniel Rosenberg __u8 access_tz; 163*508ec739SDaniel Rosenberg __u8 reserved2[7]; 164*508ec739SDaniel Rosenberg } __attribute__((packed)) file; /* file directory entry */ 165*508ec739SDaniel Rosenberg struct { 166*508ec739SDaniel Rosenberg __u8 flags; 167*508ec739SDaniel Rosenberg __u8 reserved1; 168*508ec739SDaniel Rosenberg __u8 name_len; 169*508ec739SDaniel Rosenberg __le16 name_hash; 170*508ec739SDaniel Rosenberg __le16 reserved2; 171*508ec739SDaniel Rosenberg __le64 valid_size; 172*508ec739SDaniel Rosenberg __le32 reserved3; 173*508ec739SDaniel Rosenberg __le32 start_clu; 174*508ec739SDaniel Rosenberg __le64 size; 175*508ec739SDaniel Rosenberg } __attribute__((packed)) stream; /* stream extension directory entry */ 176*508ec739SDaniel Rosenberg struct { 177*508ec739SDaniel Rosenberg __u8 flags; 178*508ec739SDaniel Rosenberg __le16 unicode_0_14[15]; 179*508ec739SDaniel Rosenberg } __attribute__((packed)) name; /* file name directory entry */ 180*508ec739SDaniel Rosenberg struct { 181*508ec739SDaniel Rosenberg __u8 flags; 182*508ec739SDaniel Rosenberg __u8 reserved[18]; 183*508ec739SDaniel Rosenberg __le32 start_clu; 184*508ec739SDaniel Rosenberg __le64 size; 185*508ec739SDaniel Rosenberg } __attribute__((packed)) bitmap; /* allocation bitmap directory entry */ 186*508ec739SDaniel Rosenberg struct { 187*508ec739SDaniel Rosenberg __u8 reserved1[3]; 188*508ec739SDaniel Rosenberg __le32 checksum; 189*508ec739SDaniel Rosenberg __u8 reserved2[12]; 190*508ec739SDaniel Rosenberg __le32 start_clu; 191*508ec739SDaniel Rosenberg __le64 size; 192*508ec739SDaniel Rosenberg } __attribute__((packed)) upcase; /* up-case table directory entry */ 193*508ec739SDaniel Rosenberg } __attribute__((packed)) dentry; 194*508ec739SDaniel Rosenberg } __attribute__((packed)); 195*508ec739SDaniel Rosenberg 196*508ec739SDaniel Rosenberg #define vol_char_cnt dentry.vol.character_count 197*508ec739SDaniel Rosenberg #define vol_label dentry.vol.volume_label 198*508ec739SDaniel Rosenberg #define file_num_ext dentry.file.num_ext 199*508ec739SDaniel Rosenberg #define file_checksum dentry.file.checksum 200*508ec739SDaniel Rosenberg #define file_attr dentry.file.attr 201*508ec739SDaniel Rosenberg #define file_create_time dentry.file.create_time 202*508ec739SDaniel Rosenberg #define file_create_date dentry.file.create_date 203*508ec739SDaniel Rosenberg #define file_modify_time dentry.file.modify_time 204*508ec739SDaniel Rosenberg #define file_modify_date dentry.file.modify_date 205*508ec739SDaniel Rosenberg #define file_access_time dentry.file.access_time 206*508ec739SDaniel Rosenberg #define file_access_date dentry.file.access_date 207*508ec739SDaniel Rosenberg #define file_create_time_ms dentry.file.create_time_ms 208*508ec739SDaniel Rosenberg #define file_modify_time_ms dentry.file.modify_time_ms 209*508ec739SDaniel Rosenberg #define file_access_time_ms dentry.file.access_time_ms 210*508ec739SDaniel Rosenberg #define stream_flags dentry.stream.flags 211*508ec739SDaniel Rosenberg #define stream_name_len dentry.stream.name_len 212*508ec739SDaniel Rosenberg #define stream_name_hash dentry.stream.name_hash 213*508ec739SDaniel Rosenberg #define stream_start_clu dentry.stream.start_clu 214*508ec739SDaniel Rosenberg #define stream_valid_size dentry.stream.valid_size 215*508ec739SDaniel Rosenberg #define stream_size dentry.stream.size 216*508ec739SDaniel Rosenberg #define name_flags dentry.name.flags 217*508ec739SDaniel Rosenberg #define name_unicode dentry.name.unicode_0_14 218*508ec739SDaniel Rosenberg #define bitmap_flags dentry.bitmap.flags 219*508ec739SDaniel Rosenberg #define bitmap_start_clu dentry.bitmap.start_clu 220*508ec739SDaniel Rosenberg #define bitmap_size dentry.bitmap.size 221*508ec739SDaniel Rosenberg #define upcase_start_clu dentry.upcase.start_clu 222*508ec739SDaniel Rosenberg #define upcase_size dentry.upcase.size 223*508ec739SDaniel Rosenberg #define upcase_checksum dentry.upcase.checksum 224*508ec739SDaniel Rosenberg 225*508ec739SDaniel Rosenberg #endif /* !_EXFAT_H */ 226