示例#1
0
/*
 * Protective (legacy) MBR.
 *
 * This MBR contains standard DOS partition table with a single partition, type
 * of 0xEE.  The partition usually encompassing the entire GPT drive - or 2TiB
 * for large disks.
 *
 * Note that Apple uses GPT/MBR hybrid disks, where the DOS partition table is
 * synchronized with GPT. This synchronization has many restriction of course
 * (due DOS PT limitations).
 *
 * Note that the PMBR detection is optional (enabled by default) and could be
 * disabled by BLKID_PARTS_FOPCE_GPT flag (see also blkid_paertitions_set_flags()).
 */
static int is_pmbr_valid(blkid_probe pr)
{
	int flags = blkid_partitions_get_flags(pr);
	unsigned char *data;
	struct dos_partition *p;
	int i;

	if (flags & BLKID_PARTS_FORCE_GPT)
		goto ok;			/* skip PMBR check */

	data = blkid_probe_get_sector(pr, 0);
	if (!data)
		goto failed;

	if (!is_valid_mbr_signature(data))
		goto failed;

	p = (struct dos_partition *) (data + BLKID_MSDOS_PT_OFFSET);

	for (i = 0; i < 4; i++, p++) {
		if (p->sys_type == BLKID_GPT_PARTITION)
			goto ok;
	}
failed:
	return 0;
ok:
	return 1;
}
示例#2
0
文件: dos.c 项目: Yowiee/util-linux
static int parse_dos_extended(blkid_probe pr, blkid_parttable tab,
		uint32_t ex_start, uint32_t ex_size, int ssf)
{
	blkid_partlist ls = blkid_probe_get_partlist(pr);
	uint32_t cur_start = ex_start, cur_size = ex_size;
	unsigned char *data;
	int ct_nodata = 0;	/* count ext.partitions without data partitions */
	int i;

	while (1) {
		struct dos_partition *p, *p0;
		uint32_t start, size;

		if (++ct_nodata > 100)
			return 0;
		data = blkid_probe_get_sector(pr, cur_start);
		if (!data)
			goto leave;	/* malformed partition? */

		if (!is_valid_mbr_signature(data))
			goto leave;

		p0 = (struct dos_partition *) (data + BLKID_MSDOS_PT_OFFSET);

		/* Usually, the first entry is the real data partition,
		 * the 2nd entry is the next extended partition, or empty,
		 * and the 3rd and 4th entries are unused.
		 * However, DRDOS sometimes has the extended partition as
		 * the first entry (when the data partition is empty),
		 * and OS/2 seems to use all four entries.
		 * -- Linux kernel fs/partitions/dos.c
		 *
		 * See also http://en.wikipedia.org/wiki/Extended_boot_record
		 */

		/* Parse data partition */
		for (p = p0, i = 0; i < 4; i++, p++) {
			uint32_t abs_start;
			blkid_partition par;

			/* the start is relative to the parental ext.partition */
			start = dos_partition_start(p) * ssf;
			size = dos_partition_size(p) * ssf;
			abs_start = cur_start + start;	/* absolute start */

			if (!size || is_extended(p))
				continue;
			if (i >= 2) {
				/* extra checks to detect real data on
				 * 3rd and 4th entries */
				if (start + size > cur_size)
					continue;
				if (abs_start < ex_start)
					continue;
				if (abs_start + size > ex_start + ex_size)
					continue;
			}

			par = blkid_partlist_add_partition(ls, tab, abs_start, size);
			if (!par)
				goto err;

			blkid_partition_set_type(par, p->sys_type);
			blkid_partition_set_flags(par, p->boot_ind);
			ct_nodata = 0;
		}
		/* The first nested ext.partition should be a link to the next
		 * logical partition. Everything other (recursive ext.partitions)
		 * is junk.
		 */
		for (p = p0, i = 0; i < 4; i++, p++) {
			start = dos_partition_start(p) * ssf;
			size = dos_partition_size(p) * ssf;

			if (size && is_extended(p))
				break;
		}
		if (i == 4)
			goto leave;

		cur_start = ex_start + start;
		cur_size = size;
	}
leave:
	return 0;
err:
	return -1;
}