예제 #1
0
/*
 * This function is used by MBR partition table parser to avoid
 * misinterpretation of FAT filesystem.
 */
int blkid_probe_is_vfat(blkid_probe pr)
{
	struct vfat_super_block *vs;
	struct msdos_super_block *ms;
	const struct blkid_idmag *mag = NULL;

	if (blkid_probe_get_idmag(pr, &vfat_idinfo, NULL, &mag) || !mag)
		return 0;

	ms = blkid_probe_get_sb(pr, mag, struct msdos_super_block);
	if (!ms)
		return 0;
	vs = blkid_probe_get_sb(pr, mag, struct vfat_super_block);
	if (!vs)
		return 0;

	return fat_valid_superblock(mag, ms, vs, NULL, NULL);
}
예제 #2
0
파일: vfat.c 프로젝트: Artox/fstools
/*
 * This function is used by MBR partition table parser to avoid
 * misinterpretation of FAT filesystem.
 */
int blkid_probe_is_vfat(blkid_probe pr)
{
	struct vfat_super_block *vs;
	struct msdos_super_block *ms;
	const struct blkid_idmag *mag = NULL;
	int rc;

	rc = blkid_probe_get_idmag(pr, &vfat_idinfo, NULL, &mag);
	if (rc < 0)
		return rc;	/* error */
	if (rc != BLKID_PROBE_OK || !mag)
		return 0;

	ms = blkid_probe_get_sb(pr, mag, struct msdos_super_block);
	if (!ms)
		return errno ? -errno : 0;
	vs = blkid_probe_get_sb(pr, mag, struct vfat_super_block);
	if (!vs)
		return errno ? -errno : 0;

	return fat_valid_superblock(pr, mag, ms, vs, NULL, NULL);
}
예제 #3
0
파일: vfat.c 프로젝트: Artox/fstools
/* FAT label extraction from the root directory taken from Kay
 * Sievers's volume_id library */
static int probe_vfat(blkid_probe pr, const struct blkid_idmag *mag)
{
	struct vfat_super_block *vs;
	struct msdos_super_block *ms;
	const unsigned char *vol_label = 0;
	unsigned char *vol_serno = NULL, vol_label_buf[11];
	uint16_t sector_size = 0, reserved;
	uint32_t cluster_count, fat_size;
	const char *version = NULL;

	ms = blkid_probe_get_sb(pr, mag, struct msdos_super_block);
	if (!ms)
		return errno ? -errno : 1;

	vs = blkid_probe_get_sb(pr, mag, struct vfat_super_block);
	if (!vs)
		return errno ? -errno : 1;

	if (!fat_valid_superblock(pr, mag, ms, vs, &cluster_count, &fat_size))
		return 1;

	sector_size = unaligned_le16(&ms->ms_sector_size);
	reserved =  le16_to_cpu(ms->ms_reserved);

	if (ms->ms_fat_length) {
		/* the label may be an attribute in the root directory */
		uint32_t root_start = (reserved + fat_size) * sector_size;
		uint32_t root_dir_entries = unaligned_le16(&vs->vs_dir_entries);

		vol_label = search_fat_label(pr, root_start, root_dir_entries);
		if (vol_label) {
			memcpy(vol_label_buf, vol_label, 11);
			vol_label = vol_label_buf;
		}

		if (!vol_label || !memcmp(vol_label, no_name, 11))
			vol_label = ms->ms_label;
		vol_serno = ms->ms_serno;

		blkid_probe_set_value(pr, "SEC_TYPE", (unsigned char *) "msdos",
                              sizeof("msdos"));

		if (cluster_count < FAT12_MAX)
			version = "FAT12";
		else if (cluster_count < FAT16_MAX)
			version = "FAT16";

	} else if (vs->vs_fat32_length) {
		unsigned char *buf;
		uint16_t fsinfo_sect;
		int maxloop = 100;

		/* Search the FAT32 root dir for the label attribute */
		uint32_t buf_size = vs->vs_cluster_size * sector_size;
		uint32_t start_data_sect = reserved + fat_size;
		uint32_t entries = le32_to_cpu(vs->vs_fat32_length) *
					sector_size / sizeof(uint32_t);
		uint32_t next = le32_to_cpu(vs->vs_root_cluster);

		while (next && next < entries && --maxloop) {
			uint32_t next_sect_off;
			uint64_t next_off, fat_entry_off;
			int count;

			next_sect_off = (next - 2) * vs->vs_cluster_size;
			next_off = (uint64_t)(start_data_sect + next_sect_off) *
				sector_size;

			count = buf_size / sizeof(struct vfat_dir_entry);

			vol_label = search_fat_label(pr, next_off, count);
			if (vol_label) {
				memcpy(vol_label_buf, vol_label, 11);
				vol_label = vol_label_buf;
				break;
			}

			/* get FAT entry */
			fat_entry_off = ((uint64_t) reserved * sector_size) +
				(next * sizeof(uint32_t));
			buf = blkid_probe_get_buffer(pr, fat_entry_off, buf_size);
			if (buf == NULL)
				break;

			/* set next cluster */
			next = le32_to_cpu(*((uint32_t *) buf)) & 0x0fffffff;
		}

		version = "FAT32";

		if (!vol_label || !memcmp(vol_label, no_name, 11))
			vol_label = vs->vs_label;
		vol_serno = vs->vs_serno;

		/*
		 * FAT32 should have a valid signature in the fsinfo block,
		 * but also allow all bytes set to '\0', because some volumes
		 * do not set the signature at all.
		 */
		fsinfo_sect = le16_to_cpu(vs->vs_fsinfo_sector);
		if (fsinfo_sect) {
			struct fat32_fsinfo *fsinfo;

			buf = blkid_probe_get_buffer(pr,
					(blkid_loff_t) fsinfo_sect * sector_size,
					sizeof(struct fat32_fsinfo));
			if (buf == NULL)
				return errno ? -errno : 1;

			fsinfo = (struct fat32_fsinfo *) buf;
			if (memcmp(fsinfo->signature1, "\x52\x52\x61\x41", 4) != 0 &&
			    memcmp(fsinfo->signature1, "\x52\x52\x64\x41", 4) != 0 &&
			    memcmp(fsinfo->signature1, "\x00\x00\x00\x00", 4) != 0)
				return 1;
			if (memcmp(fsinfo->signature2, "\x72\x72\x41\x61", 4) != 0 &&
			    memcmp(fsinfo->signature2, "\x00\x00\x00\x00", 4) != 0)
				return 1;
		}
	}

	if (vol_label && memcmp(vol_label, no_name, 11))
		blkid_probe_set_label(pr, (unsigned char *) vol_label, 11);

	/* We can't just print them as %04X, because they are unaligned */
	if (vol_serno)
		blkid_probe_sprintf_uuid(pr, vol_serno, 4, "%02X%02X-%02X%02X",
			vol_serno[3], vol_serno[2], vol_serno[1], vol_serno[0]);
	if (version)
		blkid_probe_set_version(pr, version);

	return 0;
}