nckernel  0.1
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
fat0.h
Go to the documentation of this file.
1 
12 struct bpb {
13  unsigned char jmp[2];
14  unsigned char nop;
15  unsigned char oem[8];
16  unsigned short sector_size;
17  unsigned char sector_per_cluster;
18  unsigned short reserved_sector;
19  unsigned char nr_fat;
20  unsigned short nr_root_entry;
21  unsigned short total_sector16;
22  unsigned char media_type;
23  unsigned short size_of_fat16;
24  unsigned short sector_per_track;
25  unsigned short nr_head;
26  unsigned int hidden_sector;
27  unsigned int total_sector32;
28 
29  /* FAT12/16 */
30  union {
31  struct {
32  unsigned char boot_drive;
33  unsigned char reserved;
34  unsigned char boot_signature;
35  unsigned int volume_id;
36  unsigned char volume_label[11];
37  unsigned char fs_type[8];
38  } __PACKED fat16;
39 
40  struct {
41  unsigned int size_of_fat32;
42  unsigned short ext_flags;
43  unsigned short version;
44  unsigned int root_cluster;
45  unsigned short info;
46  unsigned short backup_boot_sec;
47  unsigned char reserved1[12];
48 
49  unsigned char boot_drive;
50  unsigned char reserved;
51  unsigned char boot_signature;
52  unsigned int volume_id;
53  unsigned char volume_label[11];
54  unsigned char fs_type[8];
55  } __PACKED fat32;
56  } type;
57 } __PACKED;
58 
60  unsigned int DiskSize;
61  unsigned char SecPerClusVal;
62 };
63 
64 struct fat32_fsinfo {
65  unsigned int lead_sig;
66  unsigned char reserved1[480];
67  unsigned int struct_sig;
68  unsigned int free_count;
69  unsigned int next_free;
70  unsigned char reserved2[12];
71  unsigned int trail_sig;
72 } __PACKED;
73 
74 #define SIZEOF_DENTRY 32
75 
77 #define ROOT_DIR_SECTORS(b) \
78  ((((b)->nr_root_entry * SIZEOF_DENTRY) + ((b)->sector_size - 1)) \
79  / (b)->sector_size)
80 
81 #define FAT_SIZE(b) \
82  ((b)->size_of_fat16 ? \
83  (b)->size_of_fat16 : \
84  (b)->type.fat32.size_of_fat32)
85 
86 #define FIRST_DATA_SECTOR(b) \
87  ((b)->reserved_sector + ((b)->nr_fat * FAT_SIZE(b)) \
88  + ROOT_DIR_SECTORS(b))
89 
90 #define FIRST_SECTOR_OF_CLUSTER(b, N) \
91  (((N) - 2) * ((b)->sector_per_cluster) + FIRST_DATA_SECTOR(b))
92 
93 #define TOTAL_SECTOR(b) \
94  ((b)->total_sector16 ? \
95  (b)->total_sector16 : \
96  (b)->total_sector32)
97 
98 #define NR_DATA_SECTOR(b) \
99  (TOTAL_SECTOR(b) - \
100  ((b)->reserved_sector + (b)->nr_fat * FAT_SIZE(b)) + \
101  ROOT_DIR_SECTORS(b))
102 
103 #define COUNT_OF_CLUSTER(b) \
104  (NR_DATA_SECTOR(b) / (b)->sector_per_cluster)
105 
106 #define IS_FAT12(b) \
107  (COUNT_OF_CLUSTER(b) < 4085)
108 
109 #define IS_FAT16(b) \
110  (!IS_FAT12(b) && (COUNT_OF_CLUSTER(b) < 65525))
111 
112 #define IS_FAT32(b) \
113  (COUNT_OF_CLUSTER(b) >= 65525)
114 
119 #define COUNT_OF_VALID_MAX_CLUSTER(b) \
120  (COUNT_OF_CLUSTER(b) + 1)
121 
122 #define FAT_OFFSET(b, N) \
123  (IS_FAT16(b) ? (N) << 1 \
124  : (IS_FAT32(b) ? (N) << 2 \
125  : (IS_FAT12(b) ? (N) + ((N)>>1) \
126  : -1)))
127 
128 #define FAT_SECTOR_NUMBER(b, N) \
129  (FAT_OFFSET((b), (N)) / (b)->sector_size)
130 
131 #define FAT_SECTORS(b, N) \
132  ((b)->reserved_sector + (N) * FAT_SIZE(b))
133 
134 #define THIS_FAT_OFFSET(b, N) \
135  (FAT_SECTORS((b), (N)) * (b)->sector_size)
136 
137 #define FAT_ENTRY_OFFSET(b, N) \
138  (FAT_OFFSET(b, (N)) % (b)->sector_size)
139 
140 #define WORD(buf) ((unsigned short*)(buf))
141 #define DWORD(buf) ((unsigned int*)(buf))
142 
143 #define FAT_EOF(bpb) (IS_FAT12(bpb) ? 0x0FF8 : \
144  IS_FAT16(bpb) ? 0xFFF8 : \
145  IS_FAT32(bpb) ? 0x0FFFFFF8 : 0)
146 
147 static inline int get_cluster_entry_value(struct bpb *bpb, char *table, int cluster)
148 {
149  char *tmp;
150  tmp = table + FAT_ENTRY_OFFSET(bpb, cluster);
151  if (IS_FAT16(bpb)) {
152  return *WORD(tmp);
153  }
154 
155  if (IS_FAT32(bpb)) {
156  return *DWORD(tmp) & 0x0FFFFFFF;
157  }
158 
159  if (IS_FAT12(bpb)) {
160  tmp = table;
161  tmp += FAT_SECTOR_NUMBER(bpb, cluster) * bpb->sector_size;
162  tmp += FAT_ENTRY_OFFSET(bpb, cluster);
163 
164  if (cluster & 0x0001) {
165  return *WORD(tmp) >> 4;
166  } else {
167  return *WORD(tmp) & 0x0FFF;
168  }
169  }
170 
171  return FAT_EOF(bpb);
172 }
173 
174 #define SET_CLUSTER_ENTRY_VALUE(b, B, N, val) \
175  do { \
176  if (IS_FAT16(b)) { \
177  *DWORD((B) + FAT_ENTRY_OFFSET(b, N)) = (val); \
178  } else if (IS_FAT32(b)) { \
179  (val) = (val) & 0x0FFFFFFF; \
180  *DWORD((B) + FAT_ENTRY_OFFSET(b, N)) &= 0xF0000000;\
181  *DWORD((B) + FAT_ENTRY_OFFSET(b, N)) |= (val); \
182  } else { \
183  if ((N) & 0x0001) { \
184  (val) = (val) << 4; \
185  *WORD((B) + FAT_ENTRY_OFFSET(b, N)) &= 0x000F;\
186  } else { \
187  (val) = (val) & 0x0FFF; \
188  *WORD((B) + FAT_ENTRY_OFFSET(b, N)) &= 0xF000;\
189  } \
190  *WORD((B) + FAT_ENTRY_OFFSET(b, N)) |= (val); \
191  } \
192  } while (0)
193 
194 #define IS_EOF(b, v) \
195  (IS_FAT12(b) ? (v) >= 0x0FF8 \
196  : IS_FAT16(b) ? (v) >= 0xFFF8 \
197  : IS_FAT32(b) ? (v) >= 0x0FFFFFF8 \
198  : 0)
199 
200 #define BAD_CLUSTER12 0x0FF7
201 #define BAD_CLUSTER16 0xFFF7
202 #define BAD_CLUSTER32 0x0FFFFFF7
203 
204 #define UPDATE_FAT_SIZE(b, dsksz) do { \
205  unsigned int tmp[2]; \
206  unsigned int fatsz; \
207  tmp[0] = (dsksz) - ((b)->reserved_sector + ROOT_DIR_SECTORS(b)); \
208  tmp[1] = (256 * (b)->sector_per_cluster) + (b)->nr_fat; \
209  if (IS_FAT32(b)) { \
210  tmp[1] >>= 1; \
211  } \
212  fatsz = (tmp[0] + (tmp[1] - 1)) / tmp[1]; \
213  if (IS_FAT32(b)) { \
214  (b)->size_of_fat16 = 0; \
215  (b)->type.fat32.size_of_fat32 = fatsz; \
216  } else { \
217  (b)->size_of_fat16 = fatsz & 0x0000FFFF; \
218  } \
219 } while (0)
220 
221 #define FIRST_ROOTDIR_SECTOR(b) \
222  ((b)->reserved_sector + (b)->nr_fat * FAT_SIZE(b))
223 
224 #define GET_FIRST_BLOCK(d) \
225  ((d)->first_cluster_hi << 16 | (d)->first_cluster_lo)
226 
227 struct fat_dentry {
228  unsigned char name[11];
229  unsigned char attr;
230  unsigned char reserved;
231  unsigned char create_time_tenth;
232  unsigned short create_time;
233  unsigned short create_date;
234  unsigned short last_access_date;
235  unsigned short first_cluster_hi;
236  unsigned short write_time;
237  unsigned short write_date;
238  unsigned short first_cluster_lo;
239  unsigned int file_size;
240 } __PACKED;
241 
242 #define IS_FREE_DENTRY(d) \
243  ((unsigned char)((d)->name[0] == (unsigned char)DELETED_FLAG) \
244  || ((d)->name[0] == 0x00))
245 
246 #define IS_KANJI_NAME(d) ((d)->name[0] == 0x05)
247 #define IS_VALID_CHAR_FOR_NAME(ch) (!(((ch) != 0x05 && (ch) < 0x20) && (ch) != 0x22 && ((ch) >= 0x2A && (ch) <= 0x2F) && ((ch) >= 0x3A && (ch) <= 0x3F) && (ch) != 0x5B && (ch) != 0x5C && (ch) != 0x5D && (ch) != 0x7C))
248 
250  ATTR_NONE = 0x00,
251  ATTR_RDONLY = 0x01,
252  ATTR_HIDDEN = 0x02,
253  ATTR_SYS = 0x04,
254  ATTR_VOLID = 0x08,
255  ATTR_DIR = 0x10,
256  ATTR_ARCH = 0x20,
261  ACTIVE_FLAG = 0x80,
263  DELETED_FLAG = 0xE5,
264 };
265 
267 #define DAY_OF_MONTH(e) ((e)->write_date & 0x000Fu)
268 #define MONTH_OF_YEAR(e) (((e)->write_date >> 4) & 0x000Fu)
269 #define COUNT_OF_YEAR(e) (1980 + (((e)->write_date >> 8) & 0x00FFu))
270 
272 #define SECOND_COUNT(e) ((e)->write_time & 0x000Fu)
273 #define MINUTES(e) (((e)->write_time >> 4) & 0x003F)
274 #define HOURS(e) (((e)->write_time >> 10) & 0x001F)
275 
278  char ord;
279  unsigned char name1[10];
280  char attr;
281  char type;
282  unsigned char checksum;
283  unsigned char name2[12];
284  unsigned short first_cluster_lo;
285  unsigned char name3[4];
286 } __PACKED;
287 
288 #define LAST_LONG_ENTRY 0x40
289 #define PATH_MAX 256
290 #define IS_LAST_SLOT(e) (((e)->ord & LAST_LONG_ENTRY) == 0)
291