*
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2 of the License.
*/
#ifndef _GNU_SOURCE
uint32_t root_cluster;
uint32_t dir_size;
uint32_t cluster_count;
- uint32_t fat_length;
+ uint16_t fat_length;
+ uint32_t fat32_length;
uint64_t root_start;
uint32_t start_data_sect;
uint16_t root_dir_entries;
dbg("sect_count 0x%x", sect_count);
fat_length = le16_to_cpu(vs->fat_length);
- if (fat_length == 0)
- fat_length = le32_to_cpu(vs->type.fat32.fat32_length);
dbg("fat_length 0x%x", fat_length);
+ fat32_length = le32_to_cpu(vs->type.fat32.fat32_length);
+ dbg("fat32_length 0x%x", fat32_length);
+
+ if (fat_length)
+ fat_size = fat_length * vs->fats;
+ else if (fat32_length)
+ fat_size = fat32_length * vs->fats;
+ else
+ return -1;
+ dbg("fat_size 0x%x", fat_size);
- fat_size = fat_length * vs->fats;
dir_size = ((dir_entries * sizeof(struct vfat_dir_entry)) +
(sector_size-1)) / sector_size;
dbg("dir_size 0x%x", dir_size);
cluster_count /= vs->sectors_per_cluster;
dbg("cluster_count 0x%x", cluster_count);
- if (cluster_count < FAT12_MAX) {
+ /* must be FAT32 */
+ if (!fat_length && fat32_length)
+ goto fat32;
+
+ /* cluster_count tells us the format */
+ if (cluster_count < FAT12_MAX)
strcpy(id->type_version, "FAT12");
- } else if (cluster_count < FAT16_MAX) {
+ else if (cluster_count < FAT16_MAX)
strcpy(id->type_version, "FAT16");
- } else {
- strcpy(id->type_version, "FAT32");
+ else
goto fat32;
- }
/* the label may be an attribute in the root directory */
root_start = (reserved + fat_size) * sector_size;
goto found;
fat32:
+ strcpy(id->type_version, "FAT32");
+
/* FAT32 root dir is a cluster chain like any other directory */
buf_size = vs->sectors_per_cluster * sector_size;
root_cluster = le32_to_cpu(vs->type.fat32.root_cluster);