fat.c revision b5e694267142042228a6cac99ecad6c4b4ef8759
/*
* volume_id - reads filesystem label and uuid
*
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
*
* under the terms of the GNU General Public License as published by the
* Free Software Foundation version 2 of the License.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "libvolume_id.h"
#include "util.h"
#define FAT12_MAX 0xff5
#define FAT16_MAX 0xfff5
#define FAT_ATTR_VOLUME_ID 0x08
#define FAT_ATTR_DIR 0x10
#define FAT_ATTR_LONG_NAME 0x0f
#define FAT_ATTR_MASK 0x3f
#define FAT_ENTRY_FREE 0xe5
struct vfat_super_block {
union {
struct fat_super_block {
struct fat32_super_block {
} PACKED;
struct vfat_dir_entry {
} PACKED;
{
unsigned int i;
for (i = 0; i < count; i++) {
/* end marker */
dbg("end of dir");
break;
}
/* empty entry */
continue;
/* long name */
continue;
/* labels do not have file data */
continue;
dbg("found ATTR_VOLUME_ID id in root dir");
}
dbg("skip dir entry");
}
return NULL;
}
{
struct vfat_super_block *vs;
struct vfat_dir_entry *dir;
int maxloop;
return -1;
/* believe only that's fat, don't trust the version
* the cluster_count will tell us
*/
return -1;
goto magic;
goto magic;
goto magic;
goto magic;
goto magic;
/* some old floppies don't have a magic, so we expect the boot code to match */
/* boot jump address check */
return -1;
/* reserverd sector count */
return -1;
/* fat count*/
return -1;
/* media check */
return -1;
/* cluster size check*/
if (vs->sectors_per_cluster == 0 ||
return -1;
/* sector size check */
return -1;
if (sect_count == 0)
if (fat_length)
else if (fat32_length)
else
return -1;
/* must be FAT32 */
if (!fat_length && fat32_length)
goto fat32;
/* cluster_count tells us the format */
if (cluster_count < FAT12_MAX)
else if (cluster_count < FAT16_MAX)
else
goto fat32;
/* the label may be an attribute in the root directory */
goto found;
return -1;
}
goto found;
/* FAT32 root dir is a cluster chain like any other directory */
next = root_cluster;
maxloop = 100;
while (--maxloop) {
int count;
/* get cluster */
goto found;
if (label)
break;
/* get FAT entry */
goto found;
/* set next cluster */
if (next == 0)
break;
}
if (maxloop == 0)
dbg("reached maximum follow count of root cluster chain, give up");
return -1;
}
return 0;
}