OSDN Git Service

Big-endian machines support.
[android-x86/external-exfat.git] / libexfat / exfatfs.h
1 /*
2  *  exfatfs.h
3  *  Definitions of structures and constants used in exFAT file system.
4  *
5  *  Created by Andrew Nayenko on 29.08.09.
6  *  This software is distributed under the GNU General Public License 
7  *  version 3 or any later.
8  */
9
10 #ifndef EXFATFS_H_INCLUDED
11 #define EXFATFS_H_INCLUDED
12
13 #include <stdint.h>
14 #include <endian.h>
15 #include <byteswap.h>
16
17 typedef uint32_t cluster_t;             /* cluster number */
18
19 typedef struct { uint16_t __u16; } le16_t;
20 typedef struct { uint32_t __u32; } le32_t;
21 typedef struct { uint64_t __u64; } le64_t;
22
23 #if __BYTE_ORDER == __LITTLE_ENDIAN
24 static inline uint16_t le16_to_cpu(le16_t v) { return v.__u16; }
25 static inline uint32_t le32_to_cpu(le32_t v) { return v.__u32; }
26 static inline uint64_t le64_to_cpu(le64_t v) { return v.__u64; }
27
28 static inline le16_t cpu_to_le16(uint16_t v) { le16_t t = {v}; return t; }
29 static inline le32_t cpu_to_le32(uint32_t v) { le32_t t = {v}; return t; }
30 static inline le64_t cpu_to_le64(uint64_t v) { le64_t t = {v}; return t; }
31 #elif __BYTE_ORDER == __BIG_ENDIAN
32 static inline uint16_t le16_to_cpu(le16_t v) { return bswap_16(v.__u16); }
33 static inline uint32_t le32_to_cpu(le32_t v) { return bswap_32(v.__u32); }
34 static inline uint64_t le64_to_cpu(le64_t v) { return bswap_64(v.__u64); }
35
36 static inline le16_t cpu_to_le16(uint16_t v)
37         { le16_t t = {bswap_16(v)}; return t; }
38 static inline le32_t cpu_to_le32(uint32_t v)
39         { le32_t t = {bswap_32(v)}; return t; }
40 static inline le64_t cpu_to_le64(uint64_t v)
41         { le64_t t = {bswap_64(v)}; return t; }
42 #else
43 #error Wow! You have a PDP machine?!
44 #endif
45
46 #define EXFAT_FIRST_DATA_CLUSTER 2
47
48 #define EXFAT_CLUSTER_FREE         0 /* free cluster */
49 #define EXFAT_CLUSTER_BAD 0xfffffff7 /* cluster contains bad block */
50 #define EXFAT_CLUSTER_END 0xffffffff /* final cluster of file or directory */
51
52 struct exfat_super_block
53 {
54         uint8_t jump[3];                                /* 0x00 jmp and nop instructions */
55         uint8_t oem_name[8];                    /* 0x03 "EXFAT   " */
56         uint8_t __unknown1[53];                 /* 0x0B ? always 0 */
57         le64_t block_start;                             /* 0x40 partition first block */
58         le64_t block_count;                             /* 0x48 partition blocks count */
59         le32_t fat_block_start;                 /* 0x50 FAT first block */
60         le32_t fat_block_count;                 /* 0x54 FAT blocks count */
61         le32_t cluster_block_start;             /* 0x58 first cluster block */
62         le32_t cluster_count;                   /* 0x5C total clusters count */
63         le32_t rootdir_cluster;                 /* 0x60 first cluster of the root dir */
64         le32_t volume_serial;                   /* 0x64 */
65         le16_t __unknown2;                              /* 0x68 version? always 0x00 0x01 */
66         le16_t volume_state;                    /* 0x6A */
67         uint8_t block_bits;                             /* 0x6C block size as (1 << n) */
68         uint8_t bpc_bits;                               /* 0x6D blocks per cluster as (1 << n) */
69         uint8_t __unknown3;                             /* 0x6E ? always 1 */
70         uint8_t __unknown4;                             /* 0x6F drive number? always 0x80 */
71         uint8_t allocated_percent;              /* 0x70 percentage of allocated space */
72         uint8_t __unknown5[397];                /* 0x71 padding? all zero */
73         le16_t boot_signature;                  /* the value of 0xAA55 */
74 };
75
76 #define EXFAT_ENTRY_VALID     0x80
77 #define EXFAT_ENTRY_CONTINUED 0x40
78
79 #define EXFAT_ENTRY_EOD       (0x00)
80 #define EXFAT_ENTRY_BITMAP    (0x01 | EXFAT_ENTRY_VALID)
81 #define EXFAT_ENTRY_UPCASE    (0x02 | EXFAT_ENTRY_VALID)
82 #define EXFAT_ENTRY_LABEL     (0x03 | EXFAT_ENTRY_VALID)
83 #define EXFAT_ENTRY_FILE      (0x05 | EXFAT_ENTRY_VALID)
84 #define EXFAT_ENTRY_FILE_INFO (0x00 | EXFAT_ENTRY_VALID | EXFAT_ENTRY_CONTINUED)
85 #define EXFAT_ENTRY_FILE_NAME (0x01 | EXFAT_ENTRY_VALID | EXFAT_ENTRY_CONTINUED)
86
87 struct exfat_entry                                      /* common container for all entries */
88 {
89         uint8_t type;                                   /* any of EXFAT_ENTRY_xxx */
90         uint8_t data[31];
91 };
92
93 #define EXFAT_ENAME_MAX 15
94
95 struct exfat_bitmap                                     /* allocated clusters bitmap */
96 {
97         uint8_t type;                                   /* EXFAT_ENTRY_BITMAP */
98         uint8_t __unknown1[19];
99         le32_t start_cluster;
100         le64_t size;                                    /* in bytes */
101 };
102
103 struct exfat_upcase                                     /* upper case translation table */
104 {
105         uint8_t type;                                   /* EXFAT_ENTRY_UPCASE */
106         uint8_t __unknown1[3];
107         le32_t checksum;
108         uint8_t __unknown2[12];
109         le32_t start_cluster;
110         le64_t size;                                    /* in bytes */
111 };
112
113 struct exfat_label                                      /* volume label */
114 {
115         uint8_t type;                                   /* EXFAT_ENTRY_LABEL */
116         uint8_t length;                                 /* number of characters */
117         le16_t name[EXFAT_ENAME_MAX];   /* in UTF-16LE */
118 };
119
120 #define EXFAT_ATTRIB_RO     0x01
121 #define EXFAT_ATTRIB_HIDDEN 0x02
122 #define EXFAT_ATTRIB_SYSTEM 0x04
123 #define EXFAT_ATTRIB_VOLUME 0x08
124 #define EXFAT_ATTRIB_DIR    0x10
125 #define EXFAT_ATTRIB_ARCH   0x20
126
127 struct exfat_file                                       /* file or directory */
128 {
129         uint8_t type;                                   /* EXFAT_ENTRY_FILE */
130         uint8_t continuations;
131         le16_t checksum;
132         le16_t attrib;                                  /* combination of EXFAT_ATTRIB_xxx */
133         le16_t __unknown1;
134         le16_t crtime, crdate;                  /* creation date and time */
135         le16_t mtime, mdate;                    /* latest modification date and time */
136         le16_t atime, adate;                    /* latest access date and time */
137         uint8_t crtime_cs;                              /* creation time in cs (centiseconds) */
138         uint8_t mtime_cs;                               /* latest modification time in cs */
139         uint8_t __unknown2[10];
140 };
141
142 #define EXFAT_FLAG_FRAGMENTED 1
143 #define EXFAT_FLAG_CONTIGUOUS 3
144
145 struct exfat_file_info                          /* file or directory info */
146 {
147         uint8_t type;                                   /* EXFAT_ENTRY_FILE_INFO */
148         uint8_t flag;                                   /* fragmented or contiguous */
149         uint8_t __unknown1;
150         uint8_t name_length;
151         le16_t name_hash;
152         le16_t __unknown2;
153         le64_t real_size;                               /* in bytes, equals to size */
154         uint8_t __unknown3[4];
155         le32_t start_cluster;
156         le64_t size;                                    /* in bytes, equals to real_size */
157 };
158
159 struct exfat_file_name                          /* file or directory name */
160 {
161         uint8_t type;                                   /* EXFAT_ENTRY_FILE_NAME */
162         uint8_t __unknown;
163         le16_t name[EXFAT_ENAME_MAX];   /* in UTF-16LE */
164 };
165
166 #endif /* ifndef EXFATFS_H_INCLUDED */