diff options
Diffstat (limited to 'libblkid/dos.c')
-rw-r--r-- | libblkid/dos.c | 297 |
1 files changed, 0 insertions, 297 deletions
diff --git a/libblkid/dos.c b/libblkid/dos.c deleted file mode 100644 index 58877691d..000000000 --- a/libblkid/dos.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * MS-DOS partition parsing code - * - * Copyright (C) 2009 Karel Zak <kzak@redhat.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - * - * Inspired by fdisk, partx, Linux kernel and libparted. - */ -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <stdint.h> - -#include "partitions.h" -#include "dos.h" -#include "aix.h" - -/* see superblocks/vfat.c */ -extern int blkid_probe_is_vfat(blkid_probe pr); - -static const struct dos_subtypes { - unsigned char type; - const struct blkid_idinfo *id; -} dos_nested[] = { - { BLKID_FREEBSD_PARTITION, &bsd_pt_idinfo }, - { BLKID_NETBSD_PARTITION, &bsd_pt_idinfo }, - { BLKID_OPENBSD_PARTITION, &bsd_pt_idinfo }, - { BLKID_UNIXWARE_PARTITION, &unixware_pt_idinfo }, - { BLKID_SOLARIS_X86_PARTITION, &solaris_x86_pt_idinfo }, - { BLKID_MINIX_PARTITION, &minix_pt_idinfo } -}; - -static inline int is_extended(struct dos_partition *p) -{ - return (p->sys_type == BLKID_DOS_EXTENDED_PARTITION || - p->sys_type == BLKID_W95_EXTENDED_PARTITION || - p->sys_type == BLKID_LINUX_EXTENDED_PARTITION); -} - -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; -} - -static int probe_dos_pt(blkid_probe pr, - const struct blkid_idmag *mag __attribute__((__unused__))) -{ - int i; - int ssf; - blkid_parttable tab = NULL; - blkid_partlist ls; - struct dos_partition *p0, *p; - unsigned char *data; - uint32_t start, size, id; - - data = blkid_probe_get_sector(pr, 0); - if (!data) - goto nothing; - - /* ignore disks with AIX magic number -- for more details see aix.c */ - if (memcmp(data, BLKID_AIX_MAGIC_STRING, BLKID_AIX_MAGIC_STRLEN) == 0) - goto nothing; - - /* - * Now that the 55aa signature is present, this is probably - * either the boot sector of a FAT filesystem or a DOS-type - * partition table. - */ - if (blkid_probe_is_vfat(pr)) { - DBG(DEBUG_LOWPROBE, printf("probably FAT -- ignore\n")); - goto nothing; - } - - p0 = (struct dos_partition *) (data + BLKID_MSDOS_PT_OFFSET); - - /* - * Reject PT where boot indicator is not 0 or 0x80. - */ - for (p = p0, i = 0; i < 4; i++, p++) - if (p->boot_ind != 0 && p->boot_ind != 0x80) { - DBG(DEBUG_LOWPROBE, printf("missing boot indicator -- ignore\n")); - goto nothing; - } - - /* - * GPT uses valid MBR - */ - for (p = p0, i = 0; i < 4; i++, p++) { - if (p->sys_type == BLKID_GPT_PARTITION) { - DBG(DEBUG_LOWPROBE, printf("probably GPT -- ignore\n")); - goto nothing; - } - } - - blkid_probe_use_wiper(pr, BLKID_MSDOS_PT_OFFSET, - 512 - BLKID_MSDOS_PT_OFFSET); - - /* - * Well, all checks pass, it's MS-DOS partiton table - */ - if (blkid_partitions_need_typeonly(pr)) - /* caller does not ask for details about partitions */ - return 0; - - ls = blkid_probe_get_partlist(pr); - - /* sector size factor (the start and size are in the real sectors, but - * we need to convert all sizes to 512 logical sectors - */ - ssf = blkid_probe_get_sectorsize(pr) / 512; - - /* allocate a new partition table */ - tab = blkid_partlist_new_parttable(ls, "dos", BLKID_MSDOS_PT_OFFSET); - if (!tab) - goto err; - - id = dos_parttable_id(data); - if (id) { - char buf[37]; - - snprintf(buf, sizeof(buf), "0x%08x", id); - blkid_parttable_set_id(tab, (unsigned char *) buf); - } - - - /* Parse primary partitions */ - for (p = p0, i = 0; i < 4; i++, p++) { - blkid_partition par; - - start = dos_partition_start(p) * ssf; - size = dos_partition_size(p) * ssf; - - if (!size) { - /* Linux kernel ignores empty partitions, but partno for - * the empty primary partitions is not reused */ - blkid_partlist_increment_partno(ls); - continue; - } - par = blkid_partlist_add_partition(ls, tab, start, size); - if (!par) - goto err; - - blkid_partition_set_type(par, p->sys_type); - blkid_partition_set_flags(par, p->boot_ind); - } - - /* Linux uses partition numbers greater than 4 - * for all logical partition and all nested partition tables (bsd, ..) - */ - blkid_partlist_set_partno(ls, 5); - - /* Parse logical partitions */ - for (p = p0, i = 0; i < 4; i++, p++) { - start = dos_partition_start(p) * ssf; - size = dos_partition_size(p) * ssf; - - if (!size) - continue; - if (is_extended(p) && - parse_dos_extended(pr, tab, start, size, ssf) == -1) - goto err; - } - - /* Parse subtypes (nested partitions) on large disks */ - if (!blkid_probe_is_tiny(pr)) { - for (p = p0, i = 0; i < 4; i++, p++) { - size_t n; - - if (!dos_partition_size(p) || is_extended(p)) - continue; - - for (n = 0; n < ARRAY_SIZE(dos_nested); n++) { - if (dos_nested[n].type != p->sys_type) - continue; - - if (blkid_partitions_do_subprobe(pr, - blkid_partlist_get_partition(ls, i), - dos_nested[n].id) == -1) - goto err; - break; - } - } - } - return 0; - -nothing: - return 1; -err: - return -1; -} - - -const struct blkid_idinfo dos_pt_idinfo = -{ - .name = "dos", - .probefunc = probe_dos_pt, - .magics = - { - /* DOS master boot sector: - * - * 0 | Code Area - * 440 | Optional Disk signature - * 446 | Partition table - * 510 | 0x55 - * 511 | 0xAA - */ - { .magic = "\x55\xAA", .len = 2, .sboff = 510 }, - { NULL } - } -}; - |