示例#1
0
文件: nilfs.c 项目: AllardJ/Tomato
int FAST_FUNC volume_id_probe_nilfs(struct volume_id *id /*,uint64_t off*/)
{
	struct nilfs2_super_block *sb;

	// Primary super block
	dbg("nilfs: probing at offset 0x%x", NILFS_SB1_OFFSET);

	sb = volume_id_get_buffer(id, NILFS_SB1_OFFSET, sizeof(*sb));

	if (sb == NULL)
		return -1;

	if (sb->s_magic != NILFS_MAGIC)
		return -1;

	// The secondary superblock is not always used, so ignore it for now.
	// When used it is at 4K from the end of the partition (sb->s_dev_size - NILFS_SB2_OFFSET).

	volume_id_set_label_string(id, sb->s_volume_name, NILFS_LABEL_SIZE < VOLUME_ID_LABEL_SIZE ?
				NILFS_LABEL_SIZE : VOLUME_ID_LABEL_SIZE);
	volume_id_set_uuid(id, sb->s_uuid, UUID_DCE);

	if (sb->s_rev_level == 2)
		IF_FEATURE_BLKID_TYPE(id->type = "nilfs2");

	return 0;
}
示例#2
0
int FAST_FUNC volume_id_probe_btrfs(struct volume_id *id /*,uint64_t off*/)
{
	// btrfs has superblocks at 64K, 64M and 256G
	// minimum btrfs size is 256M
	// so we never step out the device if we analyze
	// the first and the second superblocks
	struct btrfs_super_block *sb;
	unsigned off = 64;

	while (off < 64*1024*1024) {
		off *= 1024;
		dbg("btrfs: probing at offset 0x%x", off);

		sb = volume_id_get_buffer(id, off, sizeof(*sb));
		if (sb == NULL)
			return -1;

		if (memcmp(sb->magic, BTRFS_MAGIC, 8) != 0)
			return -1;
	}

	// N.B.: btrfs natively supports 256 (>VOLUME_ID_LABEL_SIZE) size labels
	volume_id_set_label_string(id, sb->label, VOLUME_ID_LABEL_SIZE);
	volume_id_set_uuid(id, sb->fsid, UUID_DCE);

	return 0;
}
示例#3
0
文件: romfs.c 项目: Nusince/TWRP2
int FAST_FUNC volume_id_probe_romfs(struct volume_id *id /*,uint64_t off*/)
{
#define off ((uint64_t)0)
	struct romfs_super *rfs;

	dbg("probing at offset 0x%llx", (unsigned long long) off);

	rfs = volume_id_get_buffer(id, off, 0x200);
	if (rfs == NULL)
		return -1;

	if (memcmp(rfs->magic, "-rom1fs-", 4) == 0) {
		size_t len = strlen((char *)rfs->name);

		if (len) {
//			volume_id_set_label_raw(id, rfs->name, len);
			volume_id_set_label_string(id, rfs->name, len);
		}

//		volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
		id->type = "romfs";
		return 0;
	}

	return -1;
}
示例#4
0
文件: ext.c 项目: dkg/ripe-atlas-fw
int volume_id_probe_ext(struct volume_id *id, uint64_t off)
{
    struct ext2_super_block *es;

    dbg("ext: probing at offset 0x%llx", (unsigned long long) off);

    es = volume_id_get_buffer(id, off + EXT_SUPERBLOCK_OFFSET, 0x200);
    if (es == NULL)
        return -1;

    if (es->magic[0] != 0123 || es->magic[1] != 0357) {
        dbg("ext: no magic found");
        return -1;
    }

//	volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
//	volume_id_set_label_raw(id, es->volume_name, 16);
    volume_id_set_label_string(id, es->volume_name, 16);
    volume_id_set_uuid(id, es->uuid, UUID_DCE);
    dbg("ext: label '%s' uuid '%s'", id->label, id->uuid);

//	if ((le32_to_cpu(es->feature_compat) & EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0)
//		id->type = "ext3";
//	else
//		id->type = "ext2";

    return 0;
}
示例#5
0
文件: linux_raid.c 项目: OPSF/uClinux
static int volume_id_probe_linux_raid1(struct volume_id *id, uint64_t off, uint64_t size)
{
	const uint8_t *buf;
	struct mdp1_super_block *mdp1;

	info("probing at offset 0x%" PRIx64 ", size 0x%" PRIx64 "\n", off, size);

	buf = volume_id_get_buffer(id, off, 0x800);
	if (buf == NULL)
		return -1;
	mdp1 = (struct mdp1_super_block *) buf;

	if (le32_to_cpu(mdp1->magic) != MD_SB_MAGIC)
		return -1;

	if (le32_to_cpu(mdp1->major_version) != 1)
		return -1;

	volume_id_set_uuid(id, mdp1->set_uuid, 0, UUID_MD);
	volume_id_set_label_raw(id, mdp1->set_name, 32);
	volume_id_set_label_string(id, mdp1->set_name, 32);
	volume_id_set_usage(id, VOLUME_ID_RAID);
	id->type = "linux_raid_member";
	return 0;
}
示例#6
0
文件: sysv.c 项目: AllardJ/Tomato
int volume_id_probe_sysv(struct volume_id *id, uint64_t off, uint64_t size)
{
	struct sysv_super *vs;
	struct xenix_super *xs;
	unsigned int boff;

	info("probing at offset 0x%llx", (unsigned long long) off);

	for (boff = 0x200; boff <= SYSV_MAX_BLOCKSIZE; boff <<= 1) {
		vs = (struct sysv_super *)
			volume_id_get_buffer(id, off + (boff * SYSV_SUPERBLOCK_BLOCK), 0x200);
		if (vs == NULL)
			return -1;

		if (vs->s_magic == cpu_to_le32(SYSV_MAGIC) || vs->s_magic == cpu_to_be32(SYSV_MAGIC)) {
			volume_id_set_label_raw(id, vs->s_fname, 6);
			volume_id_set_label_string(id, vs->s_fname, 6);
			id->type = "sysv";
			goto found;
		}
	}

	for (boff = 0x200; boff <= SYSV_MAX_BLOCKSIZE; boff <<= 1) {
		xs = (struct xenix_super *)
			volume_id_get_buffer(id, off + (boff + XENIX_SUPERBLOCK_BLOCK), 0x200);
		if (xs == NULL)
			return -1;

		if (xs->s_magic == cpu_to_le32(XENIX_MAGIC) || xs->s_magic == cpu_to_be32(XENIX_MAGIC)) {
			volume_id_set_label_raw(id, xs->s_fname, 6);
			volume_id_set_label_string(id, xs->s_fname, 6);
			id->type = "xenix";
			goto found;
		}
	}

	return -1;

found:
	volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
	return 0;
}
示例#7
0
文件: ufs.c 项目: OPSF/uClinux
int volume_id_probe_ufs(struct volume_id *id, uint64_t off, uint64_t size)
{
	uint32_t magic;
	int i;
	struct ufs_super_block *ufs;
	int offsets[] = {0, 8, 64, 256, -1};

	info("probing at offset 0x%" PRIx64 "\n", off);

	for (i = 0; offsets[i] >= 0; i++) {	
		ufs = (struct ufs_super_block *) volume_id_get_buffer(id, off + (offsets[i] * 0x400), 0x800);
		if (ufs == NULL)
			return -1;

		dbg("offset 0x%x\n", offsets[i] * 0x400);
		magic = be32_to_cpu(ufs->fs_magic);
		if ((magic == UFS_MAGIC) ||
		    (magic == UFS2_MAGIC) ||
		    (magic == UFS_MAGIC_FEA) ||
		    (magic == UFS_MAGIC_LFN)) {
			dbg("magic 0x%08x(be)\n", magic);
			goto found;
		}
		magic = le32_to_cpu(ufs->fs_magic);
		if ((magic == UFS_MAGIC) ||
		    (magic == UFS2_MAGIC) ||
		    (magic == UFS_MAGIC_FEA) ||
		    (magic == UFS_MAGIC_LFN)) {
			dbg("magic 0x%08x(le)\n", magic);
			goto found;
		}
	}
	return -1;

found:
	volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
	id->type = "ufs";
	switch (magic) {
	case UFS_MAGIC:
		strcpy(id->type_version, "1");
		break;
	case UFS2_MAGIC:
		strcpy(id->type_version, "2");
		volume_id_set_label_raw(id, ufs->fs_u11.fs_u2.fs_volname, 32);
		volume_id_set_label_string(id, ufs->fs_u11.fs_u2.fs_volname, 32);
		break;
	default:
		break;
	}

	return 0;
}
int FAST_FUNC volume_id_probe_linux_swap(struct volume_id *id /*,uint64_t off*/)
{
#define off ((uint64_t)0)
	struct swap_header_v1_2 *sw;
	const uint8_t *buf;
	unsigned page;

	dbg("probing at offset 0x%llx", (unsigned long long) off);

	/* the swap signature is at the end of the PAGE_SIZE */
	for (page = 0x1000; page <= LARGEST_PAGESIZE; page <<= 1) {
			buf = volume_id_get_buffer(id, off + page-10, 10);
			if (buf == NULL)
				return -1;

			if (memcmp(buf, "SWAP-SPACE", 10) == 0) {
//				id->type_version[0] = '1';
//				id->type_version[1] = '\0';
				goto found;
			}

			if (memcmp(buf, "SWAPSPACE2", 10) == 0
			 || memcmp(buf, "S1SUSPEND", 9) == 0
			 || memcmp(buf, "S2SUSPEND", 9) == 0
			 || memcmp(buf, "ULSUSPEND", 9) == 0
			) {
				sw = volume_id_get_buffer(id, off, sizeof(struct swap_header_v1_2));
				if (sw == NULL)
					return -1;
//				id->type_version[0] = '2';
//				id->type_version[1] = '\0';
//				volume_id_set_label_raw(id, sw->volume_name, 16);
				volume_id_set_label_string(id, sw->volume_name, 16);
				volume_id_set_uuid(id, sw->uuid, UUID_DCE);
				goto found;
			}
	}
	return -1;

found:
//	volume_id_set_usage(id, VOLUME_ID_OTHER);
//	id->type = "swap";

	return 0;
}
示例#9
0
文件: ext.c 项目: AllardJ/Tomato
int volume_id_probe_ext(struct volume_id *id, uint64_t off, uint64_t size)
{
	struct ext2_super_block *es;
	size_t bsize;

	info("probing at offset 0x%llx", (unsigned long long) off);

	es = (struct ext2_super_block *) volume_id_get_buffer(id, off + EXT_SUPERBLOCK_OFFSET, 0x200);
	if (es == NULL)
		return -1;

	if (es->s_magic != cpu_to_le16(EXT_SUPER_MAGIC))
		return -1;

	bsize = 0x400 << le32_to_cpu(es->s_log_block_size);
	dbg("ext blocksize 0x%zx", bsize);
	if (bsize < EXT3_MIN_BLOCK_SIZE || bsize > EXT3_MAX_BLOCK_SIZE) {
		dbg("invalid ext blocksize");
		return -1;
	}

	volume_id_set_label_raw(id, es->s_volume_name, 16);
	volume_id_set_label_string(id, es->s_volume_name, 16);
	volume_id_set_uuid(id, es->s_uuid, 0, UUID_DCE);
	snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u",
		 le32_to_cpu(es->s_rev_level), le16_to_cpu(es->s_minor_rev_level));

	/* check for external journal device */
	if ((le32_to_cpu(es->s_feature_incompat) & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) != 0) {
		volume_id_set_usage(id, VOLUME_ID_OTHER);
		id->type = "jbd";
		return 0;
	}

	/* check for ext2 / ext3 */
	volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
	if ((le32_to_cpu(es->s_feature_compat) & EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0)
		id->type = "ext3";
	else
		id->type = "ext2";

	return 0;
}
示例#10
0
文件: btrfs.c 项目: OPSF/uClinux
int volume_id_probe_btrfs(struct volume_id *id, uint64_t off, uint64_t size)
{
	const uint8_t *buf;
	struct btrfs_super_block *bfs;

	info("probing at offset 0x%" PRIx64 ", size 0x%" PRIx64 "\n", off, size);

	buf = volume_id_get_buffer(id, off + 0x10000, 0x200);
	if (buf == NULL)
		return -1;
	bfs = (struct btrfs_super_block *)buf;
	if (memcmp(bfs->magic, "_BHRfS_M", 8) != 0)
		return -1;
	volume_id_set_uuid(id, bfs->fsid, 0, UUID_DCE);
	volume_id_set_uuid_sub(id, bfs->dev_item.uuid, 0, UUID_DCE);
	volume_id_set_label_raw(id, bfs->label, 256);
	volume_id_set_label_string(id, bfs->label, 256);
	volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
	id->type = "btrfs";
	return 0;
}
示例#11
0
文件: hpfs.c 项目: OPSF/uClinux
int volume_id_probe_hpfs(struct volume_id *id, uint64_t off, uint64_t size)
{
	struct hpfs_super *hs;
	struct hpfs_spare_super *hss;
	struct hpfs_boot_block *hbb;
	uint8_t version;

	info("probing at offset 0x%" PRIx64 "\n", off);

	hs = (struct hpfs_super *) volume_id_get_buffer(id, off + HPFS_SUPERBLOCK_OFFSET, 0x400);
	if (hs == NULL)
		return -1;
	if (memcmp(hs->magic, "\x49\xe8\x95\xf9", 4) != 0)
		return -1;

	hss = (struct hpfs_spare_super *) volume_id_get_buffer(id, off + HPFS_SUPERBLOCK_SPARE_OFFSET, 0x200);
	if (hss == NULL)
		return -1;
	if (memcmp(hss->magic, "\x49\x18\x91\xf9", 4) != 0)
		return -1;

	version = hs->version;

	/* if boot block looks valid, read label and uuid from there */
	hbb = (struct hpfs_boot_block *) volume_id_get_buffer(id, off, 0x200);
	if (hbb == NULL)
		return -1;
	if (memcmp(hbb->magic, "\x55\xaa", 2) == 0 &&
	    memcmp(hbb->sig_hpfs, "HPFS", 4) == 0 &&
	    hbb->sig_28h == 0x28) {
		volume_id_set_label_raw(id, hbb->vol_label, 11);
		volume_id_set_label_string(id, hbb->vol_label, 11);
		volume_id_set_uuid(id, hbb->vol_serno, 0, UUID_DOS);
	}
	sprintf(id->type_version, "%u", version);
	volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
	id->type = "hpfs";

	return 0;
}
示例#12
0
文件: jfs.c 项目: OPSF/uClinux
int volume_id_probe_jfs(struct volume_id *id, uint64_t off, uint64_t size)
{
	struct jfs_super_block *js;

	info("probing at offset 0x%" PRIx64 "\n", off);

	js = (struct jfs_super_block *) volume_id_get_buffer(id, off + JFS_SUPERBLOCK_OFFSET, 0x200);
	if (js == NULL)
		return -1;

	if (memcmp(js->magic, "JFS1", 4) != 0)
		return -1;

	volume_id_set_label_raw(id, js->label, 16);
	volume_id_set_label_string(id, js->label, 16);
	volume_id_set_uuid(id, js->uuid, 0, UUID_DCE);

	volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
	id->type = "jfs";

	return 0;
}
示例#13
0
int volume_id_probe_jfs(struct volume_id *id, uint64_t off)
{
	struct jfs_super_block *js;

	dbg("probing at offset 0x%llx", (unsigned long long) off);

	js = volume_id_get_buffer(id, off + JFS_SUPERBLOCK_OFFSET, 0x200);
	if (js == NULL)
		return -1;

	if (memcmp(js->magic, "JFS1", 4) != 0)
		return -1;

//	volume_id_set_label_raw(id, js->label, 16);
	volume_id_set_label_string(id, js->label, 16);
	volume_id_set_uuid(id, js->uuid, UUID_DCE);

//	volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
//	id->type = "jfs";

	return 0;
}
示例#14
0
int volume_id_probe_ocfs2(struct volume_id *id, uint64_t off)
{
	struct ocfs2_super_block *os;

	dbg("probing at offset 0x%llx", (unsigned long long) off);

	os = volume_id_get_buffer(id, off + OCFS2_SUPERBLOCK_OFFSET, 0x200);
	if (os == NULL)
		return -1;

	if (memcmp(os->i_signature, "OCFSV2", 6) != 0) {
		return -1;
	}

//	volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
//	volume_id_set_label_raw(id, os->s_label, OCFS2_MAX_VOL_LABEL_LEN < VOLUME_ID_LABEL_SIZE ?
//					OCFS2_MAX_VOL_LABEL_LEN : VOLUME_ID_LABEL_SIZE);
	volume_id_set_label_string(id, os->s_label, OCFS2_MAX_VOL_LABEL_LEN < VOLUME_ID_LABEL_SIZE ?
					OCFS2_MAX_VOL_LABEL_LEN : VOLUME_ID_LABEL_SIZE);
	volume_id_set_uuid(id, os->s_uuid, UUID_DCE);
//	id->type = "ocfs2";
	return 0;
}
示例#15
0
文件: fat.c 项目: Ayyayay/busybox
int FAST_FUNC volume_id_probe_vfat(struct volume_id *id /*,uint64_t fat_partition_off*/)
{
#define fat_partition_off ((uint64_t)0)
	struct vfat_super_block *vs;
	struct vfat_dir_entry *dir;
	uint16_t sector_size_bytes;
	uint16_t dir_entries;
	uint32_t sect_count;
	uint16_t reserved_sct;
	uint32_t fat_size_sct;
	uint32_t root_cluster;
	uint32_t dir_size_sct;
	uint32_t cluster_count;
	uint64_t root_start_off;
	uint32_t start_data_sct;
	uint8_t *buf;
	uint32_t buf_size;
	uint8_t *label = NULL;
	uint32_t next_cluster;
	int maxloop;

	dbg("probing at offset 0x%llx", (unsigned long long) fat_partition_off);

	vs = volume_id_get_buffer(id, fat_partition_off, 0x200);
	if (vs == NULL)
		return -1;

	/* believe only that's fat, don't trust the version
	 * the cluster_count will tell us
	 */
	if (memcmp(vs->sysid, "NTFS", 4) == 0)
		return -1;

	if (memcmp(vs->type.fat32.magic, "MSWIN", 5) == 0)
		goto valid;

	if (memcmp(vs->type.fat32.magic, "FAT32   ", 8) == 0)
		goto valid;

	if (memcmp(vs->type.fat.magic, "FAT16   ", 8) == 0)
		goto valid;

	if (memcmp(vs->type.fat.magic, "MSDOS", 5) == 0)
		goto valid;

	if (memcmp(vs->type.fat.magic, "FAT12   ", 8) == 0)
		goto valid;

	/*
	 * There are old floppies out there without a magic, so we check
	 * for well known values and guess if it's a fat volume
	 */

	/* boot jump address check */
	if ((vs->boot_jump[0] != 0xeb || vs->boot_jump[2] != 0x90)
	 && vs->boot_jump[0] != 0xe9
	) {
		return -1;
	}

	/* heads check */
	if (vs->heads == 0)
		return -1;

	/* cluster size check */
	if (vs->sectors_per_cluster == 0
	 || (vs->sectors_per_cluster & (vs->sectors_per_cluster-1))
	) {
		return -1;
	}

	/* media check */
	if (vs->media < 0xf8 && vs->media != 0xf0)
		return -1;

	/* fat count*/
	if (vs->fats != 2)
		return -1;

 valid:
	/* sector size check */
	sector_size_bytes = le16_to_cpu(vs->sector_size_bytes);
	if (sector_size_bytes != 0x200 && sector_size_bytes != 0x400
	 && sector_size_bytes != 0x800 && sector_size_bytes != 0x1000
	) {
		return -1;
	}

	dbg("sector_size_bytes 0x%x", sector_size_bytes);
	dbg("sectors_per_cluster 0x%x", vs->sectors_per_cluster);

	reserved_sct = le16_to_cpu(vs->reserved_sct);
	dbg("reserved_sct 0x%x", reserved_sct);

	sect_count = le16_to_cpu(vs->sectors);
	if (sect_count == 0)
		sect_count = le32_to_cpu(vs->total_sect);
	dbg("sect_count 0x%x", sect_count);

	fat_size_sct = le16_to_cpu(vs->fat_length);
	if (fat_size_sct == 0)
		fat_size_sct = le32_to_cpu(vs->type.fat32.fat32_length);
	fat_size_sct *= vs->fats;
	dbg("fat_size_sct 0x%x", fat_size_sct);

	dir_entries = le16_to_cpu(vs->dir_entries);
	dir_size_sct = ((dir_entries * sizeof(struct vfat_dir_entry)) +
			(sector_size_bytes-1)) / sector_size_bytes;
	dbg("dir_size_sct 0x%x", dir_size_sct);

	cluster_count = sect_count - (reserved_sct + fat_size_sct + dir_size_sct);
	cluster_count /= vs->sectors_per_cluster;
	dbg("cluster_count 0x%x", cluster_count);

//	if (cluster_count < FAT12_MAX) {
//		strcpy(id->type_version, "FAT12");
//	} else if (cluster_count < FAT16_MAX) {
//		strcpy(id->type_version, "FAT16");
//	} else {
//		strcpy(id->type_version, "FAT32");
//		goto fat32;
//	}
	if (cluster_count >= FAT16_MAX)
		goto fat32;

	/* the label may be an attribute in the root directory */
	root_start_off = (reserved_sct + fat_size_sct) * sector_size_bytes;
	dbg("root dir start 0x%llx", (unsigned long long) root_start_off);
	dbg("expected entries 0x%x", dir_entries);

	buf_size = dir_entries * sizeof(struct vfat_dir_entry);
	buf = volume_id_get_buffer(id, fat_partition_off + root_start_off, buf_size);
	if (buf == NULL)
		goto ret;

	label = get_attr_volume_id((struct vfat_dir_entry*) buf, dir_entries);

	vs = volume_id_get_buffer(id, fat_partition_off, 0x200);
	if (vs == NULL)
		return -1;

	if (label != NULL && memcmp(label, "NO NAME    ", 11) != 0) {
//		volume_id_set_label_raw(id, label, 11);
		volume_id_set_label_string(id, label, 11);
	} else if (memcmp(vs->type.fat.label, "NO NAME    ", 11) != 0) {
//		volume_id_set_label_raw(id, vs->type.fat.label, 11);
		volume_id_set_label_string(id, vs->type.fat.label, 11);
	}
	volume_id_set_uuid(id, vs->type.fat.serno, UUID_DOS);
	goto ret;

 fat32:
	/* FAT32 root dir is a cluster chain like any other directory */
	buf_size = vs->sectors_per_cluster * sector_size_bytes;
	root_cluster = le32_to_cpu(vs->type.fat32.root_cluster);
	start_data_sct = reserved_sct + fat_size_sct;

	next_cluster = root_cluster;
	maxloop = 100;
	while (--maxloop) {
		uint64_t next_off_sct;
		uint64_t next_off;
		uint64_t fat_entry_off;
		int count;

		dbg("next_cluster 0x%x", (unsigned)next_cluster);
		next_off_sct = (uint64_t)(next_cluster - 2) * vs->sectors_per_cluster;
		next_off = (start_data_sct + next_off_sct) * sector_size_bytes;
		dbg("cluster offset 0x%llx", (unsigned long long) next_off);

		/* get cluster */
		buf = volume_id_get_buffer(id, fat_partition_off + next_off, buf_size);
		if (buf == NULL)
			goto ret;

		dir = (struct vfat_dir_entry*) buf;
		count = buf_size / sizeof(struct vfat_dir_entry);
		dbg("expected entries 0x%x", count);

		label = get_attr_volume_id(dir, count);
		if (label)
			break;

		/* get FAT entry */
		fat_entry_off = (reserved_sct * sector_size_bytes) + (next_cluster * sizeof(uint32_t));
		dbg("fat_entry_off 0x%llx", (unsigned long long)fat_entry_off);
		buf = volume_id_get_buffer(id, fat_partition_off + fat_entry_off, buf_size);
		if (buf == NULL)
			goto ret;

		/* set next cluster */
		next_cluster = le32_to_cpu(*(uint32_t*)buf) & 0x0fffffff;
		if (next_cluster < 2 || next_cluster > FAT32_MAX)
			break;
	}
	if (maxloop == 0)
		dbg("reached maximum follow count of root cluster chain, give up");

	vs = volume_id_get_buffer(id, fat_partition_off, 0x200);
	if (vs == NULL)
		return -1;

	if (label != NULL && memcmp(label, "NO NAME    ", 11) != 0) {
//		volume_id_set_label_raw(id, label, 11);
		volume_id_set_label_string(id, label, 11);
	} else if (memcmp(vs->type.fat32.label, "NO NAME    ", 11) != 0) {
//		volume_id_set_label_raw(id, vs->type.fat32.label, 11);
		volume_id_set_label_string(id, vs->type.fat32.label, 11);
	}
	volume_id_set_uuid(id, vs->type.fat32.serno, UUID_DOS);

 ret:
//	volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
//	id->type = "vfat";

	return 0;
}
示例#16
0
int volume_id_probe_iso9660(struct volume_id *id, uint64_t off, uint64_t size)
{
	uint8_t *buf;
	struct iso_volume_descriptor *is;
	struct high_sierra_volume_descriptor *hs;

	info("probing at offset 0x%llx", (unsigned long long) off);

	buf = volume_id_get_buffer(id, off + ISO_SUPERBLOCK_OFFSET, 0x200);
	if (buf == NULL)
		return -1;

	is = (struct iso_volume_descriptor *) buf;

	if (memcmp(is->id, "CD001", 5) == 0) {
		int vd_offset;
		int i;

		dbg("read label from PVD");
		volume_id_set_label_raw(id, is->volume_id, 32);
		volume_id_set_label_string(id, is->volume_id, 32);

		dbg("looking for SVDs");
		vd_offset = ISO_VD_OFFSET;
		for (i = 0; i < ISO_VD_MAX; i++) {
			uint8_t svd_label[64];

			is = (struct iso_volume_descriptor *) volume_id_get_buffer(id, off + vd_offset, 0x200);
			if (is == NULL || is->type == ISO_VD_END)
				break;
			if (is->type != ISO_VD_SUPPLEMENTARY)
				continue;

			dbg("found SVD at offset 0x%llx", (unsigned long long) (off + vd_offset));
			if (memcmp(is->escape_sequences, "%/@", 3) == 0||
			    memcmp(is->escape_sequences, "%/C", 3) == 0||
			    memcmp(is->escape_sequences, "%/E", 3) == 0) {
				dbg("Joliet extension found");
				volume_id_set_unicode16((char *)svd_label, sizeof(svd_label), is->volume_id, BE, 32);
				if (memcmp(id->label, svd_label, 16) == 0) {
					dbg("SVD label is identical, use the possibly longer PVD one");
					break;
				}

				volume_id_set_label_raw(id, is->volume_id, 32);
				volume_id_set_label_string(id, svd_label, 32);
				strcpy(id->type_version, "Joliet Extension");
				goto found;
			}
			vd_offset += ISO_SECTOR_SIZE;
		}
		goto found;
	}

	hs = (struct high_sierra_volume_descriptor *) buf;

	if (memcmp(hs->id, "CDROM", 5) == 0) {
		strcpy(id->type_version, "High Sierra");
		goto found;
	}

	return -1;

found:
	volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
	id->type = "iso9660";

	return 0;
}
示例#17
0
int FAST_FUNC volume_id_probe_udf(struct volume_id *id /*,uint64_t off*/)
{
#define off ((uint64_t)0)
	struct volume_descriptor *vd;
	struct volume_structure_descriptor *vsd;
	unsigned bs;
	unsigned b;
	unsigned type;
	unsigned count;
	unsigned loc;
	unsigned clen;

	dbg("probing at offset 0x%llx", (unsigned long long) off);

	vsd = volume_id_get_buffer(id, off + UDF_VSD_OFFSET, 0x200);
	if (vsd == NULL)
		return -1;

	if (memcmp(vsd->id, "NSR02", 5) == 0)
		goto blocksize;
	if (memcmp(vsd->id, "NSR03", 5) == 0)
		goto blocksize;
	if (memcmp(vsd->id, "BEA01", 5) == 0)
		goto blocksize;
	if (memcmp(vsd->id, "BOOT2", 5) == 0)
		goto blocksize;
	if (memcmp(vsd->id, "CD001", 5) == 0)
		goto blocksize;
	if (memcmp(vsd->id, "CDW02", 5) == 0)
		goto blocksize;
	if (memcmp(vsd->id, "TEA03", 5) == 0)
		goto blocksize;
	return -1;

blocksize:
	/* search the next VSD to get the logical block size of the volume */
	for (bs = 0x800; bs < 0x8000; bs += 0x800) {
		vsd = volume_id_get_buffer(id, off + UDF_VSD_OFFSET + bs, 0x800);
		if (vsd == NULL)
			return -1;
		dbg("test for blocksize: 0x%x", bs);
		if (vsd->id[0] != '\0')
			goto nsr;
	}
	return -1;

nsr:
	/* search the list of VSDs for a NSR descriptor */
	for (b = 0; b < 64; b++) {
		vsd = volume_id_get_buffer(id, off + UDF_VSD_OFFSET + (b * bs), 0x800);
		if (vsd == NULL)
			return -1;

		dbg("vsd: %c%c%c%c%c",
		    vsd->id[0], vsd->id[1], vsd->id[2], vsd->id[3], vsd->id[4]);

		if (vsd->id[0] == '\0')
			return -1;
		if (memcmp(vsd->id, "NSR02", 5) == 0)
			goto anchor;
		if (memcmp(vsd->id, "NSR03", 5) == 0)
			goto anchor;
	}
	return -1;

anchor:
	/* read anchor volume descriptor */
	vd = volume_id_get_buffer(id, off + (256 * bs), 0x200);
	if (vd == NULL)
		return -1;

	type = le16_to_cpu(vd->tag.id);
	if (type != 2) /* TAG_ID_AVDP */
		goto found;

	/* get desriptor list address and block count */
	count = le32_to_cpu(vd->type.anchor.length) / bs;
	loc = le32_to_cpu(vd->type.anchor.location);
	dbg("0x%x descriptors starting at logical secor 0x%x", count, loc);

	/* pick the primary descriptor from the list */
	for (b = 0; b < count; b++) {
		vd = volume_id_get_buffer(id, off + ((loc + b) * bs), 0x200);
		if (vd == NULL)
			return -1;

		type = le16_to_cpu(vd->tag.id);
		dbg("descriptor type %i", type);

		/* check validity */
		if (type == 0)
			goto found;
		if (le32_to_cpu(vd->tag.location) != loc + b)
			goto found;

		if (type == 1) /* TAG_ID_PVD */
			goto pvd;
	}
	goto found;

 pvd:
//	volume_id_set_label_raw(id, &(vd->type.primary.ident.clen), 32);

	clen = vd->type.primary.ident.clen;
	dbg("label string charsize=%i bit", clen);
	if (clen == 8)
		volume_id_set_label_string(id, vd->type.primary.ident.c, 31);
	else if (clen == 16)
		volume_id_set_label_unicode16(id, vd->type.primary.ident.c, BE, 31);

 found:
//	volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
//	id->type = "udf";

	return 0;
}