From: Karel Zak Date: Tue, 4 Nov 2008 09:50:14 +0000 (+0100) Subject: blkid: add UDF support X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3aaaed25be35b2f8d95e08711d2c75367a682fbc;p=util-linux blkid: add UDF support Signed-off-by: Karel Zak --- diff --git a/libs/blkid/src/probe.c b/libs/blkid/src/probe.c index 5b7fe6fa..fcd7f61b 100644 --- a/libs/blkid/src/probe.c +++ b/libs/blkid/src/probe.c @@ -68,6 +68,7 @@ static const struct blkid_idinfo *idinfos[] = &hfs_idinfo, &ntfs_idinfo, &iso9660_idinfo, + &udf_idinfo, &lvm2_idinfo }; diff --git a/libs/blkid/src/probers/Makefile.am b/libs/blkid/src/probers/Makefile.am index 62c31fa7..b59ec313 100644 --- a/libs/blkid/src/probers/Makefile.am +++ b/libs/blkid/src/probers/Makefile.am @@ -27,6 +27,7 @@ libprobers_a_SOURCES = probers.h \ ntfs.c \ hfs.c \ iso9660.c \ + udf.c \ lvm.c all-local: $(lib_LIBRARIES) diff --git a/libs/blkid/src/probers/probers.h b/libs/blkid/src/probers/probers.h index ae6df7e6..c50e0b5b 100644 --- a/libs/blkid/src/probers/probers.h +++ b/libs/blkid/src/probers/probers.h @@ -47,6 +47,7 @@ extern const struct blkid_idinfo hfs_idinfo; extern const struct blkid_idinfo hfsplus_idinfo; extern const struct blkid_idinfo ntfs_idinfo; extern const struct blkid_idinfo iso9660_idinfo; +extern const struct blkid_idinfo udf_idinfo; extern const struct blkid_idinfo lvm2_idinfo; #endif /* _BLKID_PROBE_H */ diff --git a/libs/blkid/src/probers/udf.c b/libs/blkid/src/probers/udf.c new file mode 100644 index 00000000..ef34bb8b --- /dev/null +++ b/libs/blkid/src/probers/udf.c @@ -0,0 +1,165 @@ +/* + * Copyright (C) 1999 by Andries Brouwer + * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o + * Copyright (C) 2001 by Andreas Dilger + * Copyright (C) 2004 Kay Sievers + * Copyright (C) 2008 Karel Zak + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include + +#include "blkidP.h" + +struct volume_descriptor { + struct descriptor_tag { + uint16_t id; + uint16_t version; + uint8_t checksum; + uint8_t reserved; + uint16_t serial; + uint16_t crc; + uint16_t crc_len; + uint32_t location; + } tag; + union { + struct anchor_descriptor { + uint32_t length; + uint32_t location; + } anchor; + struct primary_descriptor { + uint32_t seq_num; + uint32_t desc_num; + struct dstring { + uint8_t clen; + uint8_t c[31]; + } ident; + } primary; + } type; +}; + +struct volume_structure_descriptor { + uint8_t type; + uint8_t id[5]; + uint8_t version; +} PACKED; + +#define UDF_VSD_OFFSET 0x8000 + +static int probe_udf(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct volume_descriptor *vd; + struct volume_structure_descriptor *vsd; + unsigned int bs; + unsigned int b; + unsigned int type; + unsigned int count; + unsigned int loc; + + /* search Volume Sequence Descriptor (VSD) to get the logical + * block size of the volume */ + for (bs = 0x800; bs < 0x8000; bs += 0x800) { + vsd = (struct volume_structure_descriptor *) + blkid_probe_get_buffer(pr, + UDF_VSD_OFFSET + bs, + sizeof(*vsd)); + if (!vsd) + return 1; + if (vsd->id[0] != '\0') + goto nsr; + } + return -1; + +nsr: + /* search the list of VSDs for a NSR descriptor */ + for (b = 0; b < 64; b++) { + vsd = (struct volume_structure_descriptor *) + blkid_probe_get_buffer(pr, + UDF_VSD_OFFSET + (b * bs), + sizeof(*vsd)); + if (!vsd) + return -1; + if (vsd->id[0] == '\0') + return -1; + if (memcmp(vsd->id, "NSR02", 5) == 0) + goto anchor; + if (memcmp(vsd->id, "NSR03", 5) == 0) + goto anchor; + } + return -1; + +anchor: + /* read Anchor Volume Descriptor (AVDP) */ + vd = (struct volume_descriptor *) + blkid_probe_get_buffer(pr, 256 * bs, sizeof(*vd)); + if (!vd) + return -1; + + type = le16_to_cpu(vd->tag.id); + if (type != 2) /* TAG_ID_AVDP */ + return 0; + + /* get desriptor list address and block count */ + count = le32_to_cpu(vd->type.anchor.length) / bs; + loc = le32_to_cpu(vd->type.anchor.location); + + /* pick the primary descriptor from the list */ + for (b = 0; b < count; b++) { + vd = (struct volume_descriptor *) + blkid_probe_get_buffer(pr, (loc + b) * bs, sizeof(*vd)); + if (!vd) + return -1; + + type = le16_to_cpu(vd->tag.id); + if (type == 0) + break; + if (le32_to_cpu(vd->tag.location) != loc + b) + break; + if (type == 1) { /* TAG_ID_PVD */ + uint8_t clen = vd->type.primary.ident.clen; + + if (clen == 8) + blkid_probe_set_label(pr, + vd->type.primary.ident.c, 31); + else if (clen == 16) + blkid_probe_set_utf8label(pr, + vd->type.primary.ident.c, + 31, BLKID_ENC_UTF16BE); + } + } + + return 0; +} + + +const struct blkid_idinfo udf_idinfo = +{ + .name = "udf", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_udf, + .magics = + { + { .magic = "BEA01", .len = 5, .kboff = 32, .sboff = 1 }, + { .magic = "BOOT2", .len = 5, .kboff = 32, .sboff = 1 }, + { .magic = "CD001", .len = 5, .kboff = 32, .sboff = 1 }, + { .magic = "CDW02", .len = 5, .kboff = 32, .sboff = 1 }, + { .magic = "NSR02", .len = 5, .kboff = 32, .sboff = 1 }, + { .magic = "NSR03", .len = 5, .kboff = 32, .sboff = 1 }, + { .magic = "TEA01", .len = 5, .kboff = 32, .sboff = 1 }, + { NULL } + } +};