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