busybox/util-linux/volume_id/unused_msdos.c
<<
>>
Prefs
   1/*
   2 * volume_id - reads filesystem label and uuid
   3 *
   4 * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
   5 *
   6 *      This library is free software; you can redistribute it and/or
   7 *      modify it under the terms of the GNU Lesser General Public
   8 *      License as published by the Free Software Foundation; either
   9 *      version 2.1 of the License, or (at your option) any later version.
  10 *
  11 *      This library is distributed in the hope that it will be useful,
  12 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14 *      Lesser General Public License for more details.
  15 *
  16 *      You should have received a copy of the GNU Lesser General Public
  17 *      License along with this library; if not, write to the Free Software
  18 *      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19 */
  20
  21#include "volume_id_internal.h"
  22
  23struct msdos_partition_entry {
  24        uint8_t         boot_ind;
  25        uint8_t         head;
  26        uint8_t         sector;
  27        uint8_t         cyl;
  28        uint8_t         sys_ind;
  29        uint8_t         end_head;
  30        uint8_t         end_sector;
  31        uint8_t         end_cyl;
  32        uint32_t        start_sect;
  33        uint32_t        nr_sects;
  34} PACKED;
  35
  36#define MSDOS_PARTTABLE_OFFSET          0x1be
  37#define MSDOS_SIG_OFF                   0x1fe
  38#define BSIZE                           0x200
  39#define DOS_EXTENDED_PARTITION          0x05
  40#define LINUX_EXTENDED_PARTITION        0x85
  41#define WIN98_EXTENDED_PARTITION        0x0f
  42#define LINUX_RAID_PARTITION            0xfd
  43#define is_extended(type) \
  44        (type == DOS_EXTENDED_PARTITION ||      \
  45         type == WIN98_EXTENDED_PARTITION ||    \
  46         type == LINUX_EXTENDED_PARTITION)
  47#define is_raid(type) \
  48        (type == LINUX_RAID_PARTITION)
  49
  50int FAST_FUNC volume_id_probe_msdos_part_table(struct volume_id *id, uint64_t off)
  51{
  52        const uint8_t *buf;
  53        int i;
  54        uint64_t poff;
  55        uint64_t plen;
  56        uint64_t extended = 0;
  57        uint64_t current;
  58        uint64_t next;
  59        int limit;
  60        int empty = 1;
  61        struct msdos_partition_entry *part;
  62        struct volume_id_partition *p;
  63
  64        dbg("probing at offset 0x%llx", (unsigned long long) off);
  65
  66        buf = volume_id_get_buffer(id, off, 0x200);
  67        if (buf == NULL)
  68                return -1;
  69
  70        if (buf[MSDOS_SIG_OFF] != 0x55 || buf[MSDOS_SIG_OFF + 1] != 0xaa)
  71                return -1;
  72
  73        /* check flags on all entries for a valid partition table */
  74        part = (struct msdos_partition_entry*) &buf[MSDOS_PARTTABLE_OFFSET];
  75        for (i = 0; i < 4; i++) {
  76                if (part[i].boot_ind != 0
  77                 && part[i].boot_ind != 0x80
  78                ) {
  79                        return -1;
  80                }
  81
  82                if (part[i].nr_sects != 0)
  83                        empty = 0;
  84        }
  85        if (empty == 1)
  86                return -1;
  87
  88        if (id->partitions != NULL)
  89                free(id->partitions);
  90        id->partitions = xzalloc(VOLUME_ID_PARTITIONS_MAX *
  91                                sizeof(struct volume_id_partition));
  92
  93        for (i = 0; i < 4; i++) {
  94                poff = (uint64_t) le32_to_cpu(part[i].start_sect) * BSIZE;
  95                plen = (uint64_t) le32_to_cpu(part[i].nr_sects) * BSIZE;
  96
  97                if (plen == 0)
  98                        continue;
  99
 100                p = &id->partitions[i];
 101
 102//              p->pt_type_raw = part[i].sys_ind;
 103
 104                if (is_extended(part[i].sys_ind)) {
 105                        dbg("found extended partition at 0x%llx", (unsigned long long) poff);
 106//                      volume_id_set_usage_part(p, VOLUME_ID_PARTITIONTABLE);
 107//                      p->type = "msdos_extended_partition";
 108                        if (extended == 0)
 109                                extended = off + poff;
 110                } else {
 111                        dbg("found 0x%x data partition at 0x%llx, len 0x%llx",
 112                            part[i].sys_ind, (unsigned long long) poff, (unsigned long long) plen);
 113
 114//                      if (is_raid(part[i].sys_ind))
 115//                              volume_id_set_usage_part(p, VOLUME_ID_RAID);
 116//                      else
 117//                              volume_id_set_usage_part(p, VOLUME_ID_UNPROBED);
 118                }
 119
 120//              p->pt_off = off + poff;
 121//              p->pt_len = plen;
 122                id->partition_count = i+1;
 123        }
 124
 125        next = extended;
 126        current = extended;
 127        limit = 50;
 128
 129        /* follow extended partition chain and add data partitions */
 130        while (next != 0) {
 131                if (limit-- == 0) {
 132                        dbg("extended chain limit reached");
 133                        break;
 134                }
 135
 136                buf = volume_id_get_buffer(id, current, 0x200);
 137                if (buf == NULL)
 138                        break;
 139
 140                part = (struct msdos_partition_entry*) &buf[MSDOS_PARTTABLE_OFFSET];
 141
 142                if (buf[MSDOS_SIG_OFF] != 0x55 || buf[MSDOS_SIG_OFF + 1] != 0xaa)
 143                        break;
 144
 145                next = 0;
 146
 147                for (i = 0; i < 4; i++) {
 148                        poff = (uint64_t) le32_to_cpu(part[i].start_sect) * BSIZE;
 149                        plen = (uint64_t) le32_to_cpu(part[i].nr_sects) * BSIZE;
 150
 151                        if (plen == 0)
 152                                continue;
 153
 154                        if (is_extended(part[i].sys_ind)) {
 155                                dbg("found extended partition at 0x%llx", (unsigned long long) poff);
 156                                if (next == 0)
 157                                        next = extended + poff;
 158                        } else {
 159                                dbg("found 0x%x data partition at 0x%llx, len 0x%llx",
 160                                        part[i].sys_ind, (unsigned long long) poff, (unsigned long long) plen);
 161
 162                                /* we always start at the 5th entry */
 163//                              while (id->partition_count < 4)
 164//                                      volume_id_set_usage_part(&id->partitions[id->partition_count++], VOLUME_ID_UNUSED);
 165                                if (id->partition_count < 4)
 166                                        id->partition_count = 4;
 167
 168                                p = &id->partitions[id->partition_count];
 169
 170//                              if (is_raid(part[i].sys_ind))
 171//                                      volume_id_set_usage_part(p, VOLUME_ID_RAID);
 172//                              else
 173//                                      volume_id_set_usage_part(p, VOLUME_ID_UNPROBED);
 174
 175//                              p->pt_off = current + poff;
 176//                              p->pt_len = plen;
 177                                id->partition_count++;
 178
 179//                              p->pt_type_raw = part[i].sys_ind;
 180
 181                                if (id->partition_count >= VOLUME_ID_PARTITIONS_MAX) {
 182                                        dbg("too many partitions");
 183                                        next = 0;
 184                                }
 185                        }
 186                }
 187
 188                current = next;
 189        }
 190
 191//      volume_id_set_usage(id, VOLUME_ID_PARTITIONTABLE);
 192//      id->type = "msdos_partition_table";
 193
 194        return 0;
 195}
 196