From 81149099bdc568483444cf059be876bd5ce30acf Mon Sep 17 00:00:00 2001 From: takawata Date: Fri, 26 Aug 2005 11:35:10 +0000 Subject: Add NTFS labeling function. Reviewed by:pjd --- sys/geom/label/g_label.c | 1 + sys/geom/label/g_label.h | 1 + sys/geom/label/g_label_ntfs.c | 113 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 sys/geom/label/g_label_ntfs.c (limited to 'sys/geom') diff --git a/sys/geom/label/g_label.c b/sys/geom/label/g_label.c index f04a4b5..597405c 100644 --- a/sys/geom/label/g_label.c +++ b/sys/geom/label/g_label.c @@ -81,6 +81,7 @@ const struct g_label_desc *g_labels[] = { &g_label_msdosfs, &g_label_ext2fs, &g_label_reiserfs, + &g_label_ntfs, NULL }; diff --git a/sys/geom/label/g_label.h b/sys/geom/label/g_label.h index 8144838..0647557 100644 --- a/sys/geom/label/g_label.h +++ b/sys/geom/label/g_label.h @@ -69,6 +69,7 @@ extern const struct g_label_desc g_label_iso9660; extern const struct g_label_desc g_label_msdosfs; extern const struct g_label_desc g_label_ext2fs; extern const struct g_label_desc g_label_reiserfs; +extern const struct g_label_desc g_label_ntfs; #endif /* _KERNEL */ struct g_label_metadata { diff --git a/sys/geom/label/g_label_ntfs.c b/sys/geom/label/g_label_ntfs.c new file mode 100644 index 0000000..76035fe --- /dev/null +++ b/sys/geom/label/g_label_ntfs.c @@ -0,0 +1,113 @@ +/*- + * Copyright (c) 2005 Takanori Watanabe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include + +#include +#include + +#define G_LABEL_NTFS_DIR "ntfs" + + +static void +g_label_ntfs_taste(struct g_consumer *cp, char *label, size_t size) +{ + struct g_provider *pp; + struct bootfile *bf; + struct attr *atr; + char *filerecp = NULL, *ap, vnchar; + struct filerec *fr; + char mftrecsz; + int recsize; + int error; + int j; + off_t voloff; + g_topology_assert_not(); + pp = cp->provider; + label[0] = '\0'; + + bf = (struct bootfile *)g_read_data(cp, 0, pp->sectorsize, &error); + + if (bf == NULL || strncmp(bf->bf_sysid, "NTFS ", 8) != 0) { + goto done; + } + + mftrecsz = (char)bf->bf_mftrecsz; + recsize = (mftrecsz > 0) ? (mftrecsz * bf->bf_bps * bf->bf_spc) : (1 << -mftrecsz); + + voloff = bf->bf_mftcn * bf->bf_spc * bf->bf_bps + + recsize * NTFS_VOLUMEINO; + if(voloff % pp->sectorsize != 0) + goto done; + + filerecp = g_read_data(cp, voloff, recsize, &error); + fr = (struct filerec *)filerecp; + for (ap = filerecp + fr->fr_attroff; atr = (struct attr *)ap, atr->a_hdr.a_type != -1; ap += atr->a_hdr.reclen) { + if (atr->a_hdr.a_type == NTFS_A_VOLUMENAME) { + if(atr->a_r.a_datalen >= size *2){ + label[0] = 0; + goto done; + } + /* + *UNICODE to ASCII. + * Should we need to use iconv(9)? + */ + for (j = 0; j < atr->a_r.a_datalen; j++) { + vnchar = *(ap + atr->a_r.a_dataoff + j); + if ((j & 1)) { + if (vnchar) { + label[0] = 0; + goto done; + } + } else { + label[j / 2] = vnchar; + } + } + label[j / 2] = 0; + break; + } + } +done: + if (bf != NULL) + g_free(bf); + if (filerecp != NULL) + g_free(filerecp); + return; + +} + +const struct g_label_desc g_label_ntfs = { + .ld_taste = g_label_ntfs_taste, + .ld_dir = G_LABEL_NTFS_DIR +}; -- cgit v1.1