source: branches/3.2/mindi-busybox/util-linux/volume_id/unused_msdos.c @ 3232

Last change on this file since 3232 was 3232, checked in by bruno, 5 years ago
  • Update mindi-busybox to 1.21.1
  • Property svn:eol-style set to native
File size: 5.1 KB
Line 
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}
Note: See TracBrowser for help on using the repository browser.