54 |
uint8_t magic[8]; |
uint8_t magic[8]; |
55 |
uint8_t dummy2[192]; |
uint8_t dummy2[192]; |
56 |
uint8_t pmagic[2]; |
uint8_t pmagic[2]; |
57 |
} __attribute__((__packed__)) fat; |
} PACKED fat; |
58 |
struct fat32_super_block { |
struct fat32_super_block { |
59 |
uint32_t fat32_length; |
uint32_t fat32_length; |
60 |
uint16_t flags; |
uint16_t flags; |
69 |
uint8_t magic[8]; |
uint8_t magic[8]; |
70 |
uint8_t dummy2[164]; |
uint8_t dummy2[164]; |
71 |
uint8_t pmagic[2]; |
uint8_t pmagic[2]; |
72 |
} __attribute__((__packed__)) fat32; |
} PACKED fat32; |
73 |
} __attribute__((__packed__)) type; |
} PACKED type; |
74 |
} __attribute__((__packed__)); |
} PACKED; |
75 |
|
|
76 |
struct vfat_dir_entry { |
struct vfat_dir_entry { |
77 |
uint8_t name[11]; |
uint8_t name[11]; |
85 |
uint16_t date_write; |
uint16_t date_write; |
86 |
uint16_t cluster_low; |
uint16_t cluster_low; |
87 |
uint32_t size; |
uint32_t size; |
88 |
} __attribute__((__packed__)); |
} PACKED; |
89 |
|
|
90 |
static uint8_t *get_attr_volume_id(struct vfat_dir_entry *dir, int count) |
static uint8_t *get_attr_volume_id(struct vfat_dir_entry *dir, int count) |
91 |
{ |
{ |
119 |
return NULL; |
return NULL; |
120 |
} |
} |
121 |
|
|
122 |
int volume_id_probe_vfat(struct volume_id *id, uint64_t fat_partition_off) |
int FAST_FUNC volume_id_probe_vfat(struct volume_id *id /*,uint64_t fat_partition_off*/) |
123 |
{ |
{ |
124 |
|
#define fat_partition_off ((uint64_t)0) |
125 |
struct vfat_super_block *vs; |
struct vfat_super_block *vs; |
126 |
struct vfat_dir_entry *dir; |
struct vfat_dir_entry *dir; |
127 |
uint16_t sector_size_bytes; |
uint16_t sector_size_bytes; |
246 |
buf_size = dir_entries * sizeof(struct vfat_dir_entry); |
buf_size = dir_entries * sizeof(struct vfat_dir_entry); |
247 |
buf = volume_id_get_buffer(id, fat_partition_off + root_start_off, buf_size); |
buf = volume_id_get_buffer(id, fat_partition_off + root_start_off, buf_size); |
248 |
if (buf == NULL) |
if (buf == NULL) |
249 |
goto found; |
goto ret; |
250 |
|
|
251 |
label = get_attr_volume_id((struct vfat_dir_entry*) buf, dir_entries); |
label = get_attr_volume_id((struct vfat_dir_entry*) buf, dir_entries); |
252 |
|
|
262 |
volume_id_set_label_string(id, vs->type.fat.label, 11); |
volume_id_set_label_string(id, vs->type.fat.label, 11); |
263 |
} |
} |
264 |
volume_id_set_uuid(id, vs->type.fat.serno, UUID_DOS); |
volume_id_set_uuid(id, vs->type.fat.serno, UUID_DOS); |
265 |
goto found; |
goto ret; |
266 |
|
|
267 |
fat32: |
fat32: |
268 |
/* FAT32 root dir is a cluster chain like any other directory */ |
/* FAT32 root dir is a cluster chain like any other directory */ |
273 |
next_cluster = root_cluster; |
next_cluster = root_cluster; |
274 |
maxloop = 100; |
maxloop = 100; |
275 |
while (--maxloop) { |
while (--maxloop) { |
276 |
uint32_t next_off_sct; |
uint64_t next_off_sct; |
277 |
uint64_t next_off; |
uint64_t next_off; |
278 |
uint64_t fat_entry_off; |
uint64_t fat_entry_off; |
279 |
int count; |
int count; |
280 |
|
|
281 |
dbg("next_cluster 0x%x", (unsigned)next_cluster); |
dbg("next_cluster 0x%x", (unsigned)next_cluster); |
282 |
next_off_sct = (next_cluster - 2) * vs->sectors_per_cluster; |
next_off_sct = (uint64_t)(next_cluster - 2) * vs->sectors_per_cluster; |
283 |
next_off = (start_data_sct + next_off_sct) * sector_size_bytes; |
next_off = (start_data_sct + next_off_sct) * sector_size_bytes; |
284 |
dbg("cluster offset 0x%llx", (unsigned long long) next_off); |
dbg("cluster offset 0x%llx", (unsigned long long) next_off); |
285 |
|
|
286 |
/* get cluster */ |
/* get cluster */ |
287 |
buf = volume_id_get_buffer(id, fat_partition_off + next_off, buf_size); |
buf = volume_id_get_buffer(id, fat_partition_off + next_off, buf_size); |
288 |
if (buf == NULL) |
if (buf == NULL) |
289 |
goto found; |
goto ret; |
290 |
|
|
291 |
dir = (struct vfat_dir_entry*) buf; |
dir = (struct vfat_dir_entry*) buf; |
292 |
count = buf_size / sizeof(struct vfat_dir_entry); |
count = buf_size / sizeof(struct vfat_dir_entry); |
301 |
dbg("fat_entry_off 0x%llx", (unsigned long long)fat_entry_off); |
dbg("fat_entry_off 0x%llx", (unsigned long long)fat_entry_off); |
302 |
buf = volume_id_get_buffer(id, fat_partition_off + fat_entry_off, buf_size); |
buf = volume_id_get_buffer(id, fat_partition_off + fat_entry_off, buf_size); |
303 |
if (buf == NULL) |
if (buf == NULL) |
304 |
goto found; |
goto ret; |
305 |
|
|
306 |
/* set next cluster */ |
/* set next cluster */ |
307 |
next_cluster = le32_to_cpu(*(uint32_t*)buf) & 0x0fffffff; |
next_cluster = le32_to_cpu(*(uint32_t*)buf) & 0x0fffffff; |
324 |
} |
} |
325 |
volume_id_set_uuid(id, vs->type.fat32.serno, UUID_DOS); |
volume_id_set_uuid(id, vs->type.fat32.serno, UUID_DOS); |
326 |
|
|
327 |
found: |
ret: |
328 |
// volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); |
// volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); |
329 |
// id->type = "vfat"; |
// id->type = "vfat"; |
330 |
|
|