source: MondoRescue/branches/3.3/mindi-busybox/util-linux/volume_id/udf.c@ 3625

Last change on this file since 3625 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

  • Property svn:eol-style set to native
File size: 4.6 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//kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_UDF) += udf.o
22
23//config:
24//config:config FEATURE_VOLUMEID_UDF
25//config: bool "udf filesystem"
26//config: default y
27//config: depends on VOLUMEID
28//config: help
29//config: TODO
30//config:
31
32#include "volume_id_internal.h"
33
34struct volume_descriptor {
35 struct descriptor_tag {
36 uint16_t id;
37 uint16_t version;
38 uint8_t checksum;
39 uint8_t reserved;
40 uint16_t serial;
41 uint16_t crc;
42 uint16_t crc_len;
43 uint32_t location;
44 } PACKED tag;
45 union {
46 struct anchor_descriptor {
47 uint32_t length;
48 uint32_t location;
49 } PACKED anchor;
50 struct primary_descriptor {
51 uint32_t seq_num;
52 uint32_t desc_num;
53 struct dstring {
54 uint8_t clen;
55 uint8_t c[31];
56 } PACKED ident;
57 } PACKED primary;
58 } PACKED type;
59} PACKED;
60
61struct volume_structure_descriptor {
62 uint8_t type;
63 uint8_t id[5];
64 uint8_t version;
65} PACKED;
66
67#define UDF_VSD_OFFSET 0x8000
68
69int FAST_FUNC volume_id_probe_udf(struct volume_id *id /*,uint64_t off*/)
70{
71#define off ((uint64_t)0)
72 struct volume_descriptor *vd;
73 struct volume_structure_descriptor *vsd;
74 unsigned bs;
75 unsigned b;
76 unsigned type;
77 unsigned count;
78 unsigned loc;
79 unsigned clen;
80
81 dbg("probing at offset 0x%llx", (unsigned long long) off);
82
83 vsd = volume_id_get_buffer(id, off + UDF_VSD_OFFSET, 0x200);
84 if (vsd == NULL)
85 return -1;
86
87 if (memcmp(vsd->id, "NSR02", 5) == 0)
88 goto blocksize;
89 if (memcmp(vsd->id, "NSR03", 5) == 0)
90 goto blocksize;
91 if (memcmp(vsd->id, "BEA01", 5) == 0)
92 goto blocksize;
93 if (memcmp(vsd->id, "BOOT2", 5) == 0)
94 goto blocksize;
95 if (memcmp(vsd->id, "CD001", 5) == 0)
96 goto blocksize;
97 if (memcmp(vsd->id, "CDW02", 5) == 0)
98 goto blocksize;
99 if (memcmp(vsd->id, "TEA03", 5) == 0)
100 goto blocksize;
101 return -1;
102
103blocksize:
104 /* search the next VSD to get the logical block size of the volume */
105 for (bs = 0x800; bs < 0x8000; bs += 0x800) {
106 vsd = volume_id_get_buffer(id, off + UDF_VSD_OFFSET + bs, 0x800);
107 if (vsd == NULL)
108 return -1;
109 dbg("test for blocksize: 0x%x", bs);
110 if (vsd->id[0] != '\0')
111 goto nsr;
112 }
113 return -1;
114
115nsr:
116 /* search the list of VSDs for a NSR descriptor */
117 for (b = 0; b < 64; b++) {
118 vsd = volume_id_get_buffer(id, off + UDF_VSD_OFFSET + (b * bs), 0x800);
119 if (vsd == NULL)
120 return -1;
121
122 dbg("vsd: %c%c%c%c%c",
123 vsd->id[0], vsd->id[1], vsd->id[2], vsd->id[3], vsd->id[4]);
124
125 if (vsd->id[0] == '\0')
126 return -1;
127 if (memcmp(vsd->id, "NSR02", 5) == 0)
128 goto anchor;
129 if (memcmp(vsd->id, "NSR03", 5) == 0)
130 goto anchor;
131 }
132 return -1;
133
134anchor:
135 /* read anchor volume descriptor */
136 vd = volume_id_get_buffer(id, off + (256 * bs), 0x200);
137 if (vd == NULL)
138 return -1;
139
140 type = le16_to_cpu(vd->tag.id);
141 if (type != 2) /* TAG_ID_AVDP */
142 goto found;
143
144 /* get desriptor list address and block count */
145 count = le32_to_cpu(vd->type.anchor.length) / bs;
146 loc = le32_to_cpu(vd->type.anchor.location);
147 dbg("0x%x descriptors starting at logical secor 0x%x", count, loc);
148
149 /* pick the primary descriptor from the list */
150 for (b = 0; b < count; b++) {
151 vd = volume_id_get_buffer(id, off + ((loc + b) * bs), 0x200);
152 if (vd == NULL)
153 return -1;
154
155 type = le16_to_cpu(vd->tag.id);
156 dbg("descriptor type %i", type);
157
158 /* check validity */
159 if (type == 0)
160 goto found;
161 if (le32_to_cpu(vd->tag.location) != loc + b)
162 goto found;
163
164 if (type == 1) /* TAG_ID_PVD */
165 goto pvd;
166 }
167 goto found;
168
169 pvd:
170// volume_id_set_label_raw(id, &(vd->type.primary.ident.clen), 32);
171
172 clen = vd->type.primary.ident.clen;
173 dbg("label string charsize=%i bit", clen);
174 if (clen == 8)
175 volume_id_set_label_string(id, vd->type.primary.ident.c, 31);
176 else if (clen == 16)
177 volume_id_set_label_unicode16(id, vd->type.primary.ident.c, BE, 31);
178
179 found:
180// volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
181 IF_FEATURE_BLKID_TYPE(id->type = "udf";)
182 return 0;
183}
Note: See TracBrowser for help on using the repository browser.