From 214cb872e866923af431b4b445e67daca8042c4c Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Mon, 13 Oct 2008 12:16:28 +0200 Subject: [PATCH] blkid: add HTFS Signed-off-by: Karel Zak --- libs/blkid/src/probe.c | 3 +- libs/blkid/src/probers/Makefile.am | 1 + libs/blkid/src/probers/ntfs.c | 197 +++++++++++++++++++++++++++++ libs/blkid/src/probers/probers.h | 1 + 4 files changed, 201 insertions(+), 1 deletion(-) create mode 100644 libs/blkid/src/probers/ntfs.c diff --git a/libs/blkid/src/probe.c b/libs/blkid/src/probe.c index ee59c2c7..3ea81052 100644 --- a/libs/blkid/src/probe.c +++ b/libs/blkid/src/probe.c @@ -65,7 +65,8 @@ static const struct blkid_idinfo *idinfos[] = &reiser4_idinfo, &jbd_idinfo, &hfsplus_idinfo, - &hfs_idinfo + &hfs_idinfo, + &ntfs_idinfo }; #ifndef ARRAY_SIZE diff --git a/libs/blkid/src/probers/Makefile.am b/libs/blkid/src/probers/Makefile.am index 67a68183..f19a82ee 100644 --- a/libs/blkid/src/probers/Makefile.am +++ b/libs/blkid/src/probers/Makefile.am @@ -24,6 +24,7 @@ libprobers_a_SOURCES = probers.h \ ocfs.c \ reiserfs.c \ romfs.c \ + ntfs.c \ hfs.c all-local: $(lib_LIBRARIES) diff --git a/libs/blkid/src/probers/ntfs.c b/libs/blkid/src/probers/ntfs.c new file mode 100644 index 00000000..5802c5c6 --- /dev/null +++ b/libs/blkid/src/probers/ntfs.c @@ -0,0 +1,197 @@ +/* + * 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 ntfs_super_block { + uint8_t jump[3]; + uint8_t oem_id[8]; + uint8_t bios_parameter_block[25]; + uint16_t unused[2]; + uint64_t number_of_sectors; + uint64_t mft_cluster_location; + uint64_t mft_mirror_cluster_location; + int8_t cluster_per_mft_record; + uint8_t reserved1[3]; + int8_t cluster_per_index_record; + uint8_t reserved2[3]; + uint64_t volume_serial; + uint16_t checksum; +}; + +struct master_file_table_record { + uint32_t magic; + uint16_t usa_ofs; + uint16_t usa_count; + uint64_t lsn; + uint16_t sequence_number; + uint16_t link_count; + uint16_t attrs_offset; + uint16_t flags; + uint32_t bytes_in_use; + uint32_t bytes_allocated; +} __attribute__((__packed__)); + +struct file_attribute { + uint32_t type; + uint32_t len; + uint8_t non_resident; + uint8_t name_len; + uint16_t name_offset; + uint16_t flags; + uint16_t instance; + uint32_t value_len; + uint16_t value_offset; +} __attribute__((__packed__)); + +#define MFT_RECORD_VOLUME 3 +#define MFT_RECORD_ATTR_VOLUME_NAME 0x60 +#define MFT_RECORD_ATTR_VOLUME_INFO 0x70 +#define MFT_RECORD_ATTR_OBJECT_ID 0x40 +#define MFT_RECORD_ATTR_END 0xffffffffu + +static int probe_ntfs(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct ntfs_super_block *ns; + struct master_file_table_record *mft; + struct file_attribute *attr; + unsigned char label_str[129], *cp; + int bytes_per_sector, sectors_per_cluster; + int mft_record_size, attr_off, attr_len; + unsigned int i, attr_type, val_len; + int val_off; + uint64_t nr_clusters; + blkid_loff_t off; + unsigned char *buf_mft, *val; + + ns = blkid_probe_get_sb(pr, mag, struct ntfs_super_block); + if (!ns) + return -1; + + bytes_per_sector = ns->bios_parameter_block[0] + + (ns->bios_parameter_block[1] << 8); + sectors_per_cluster = ns->bios_parameter_block[2]; + + if ((bytes_per_sector < 512) || (sectors_per_cluster == 0)) + return 1; + + if (ns->cluster_per_mft_record < 0) + mft_record_size = 1 << (0 - ns->cluster_per_mft_record); + else + mft_record_size = ns->cluster_per_mft_record * + sectors_per_cluster * bytes_per_sector; + nr_clusters = le64_to_cpu(ns->number_of_sectors) / sectors_per_cluster; + + if ((le64_to_cpu(ns->mft_cluster_location) > nr_clusters) || + (le64_to_cpu(ns->mft_mirror_cluster_location) > nr_clusters)) + return 1; + + off = le64_to_cpu(ns->mft_mirror_cluster_location) * + bytes_per_sector * sectors_per_cluster; + + buf_mft = blkid_probe_get_buffer(pr, off, mft_record_size); + if (!buf_mft) + return 1; + + if (memcmp(buf_mft, "FILE", 4)) + return 1; + + off = le64_to_cpu(ns->mft_cluster_location) * bytes_per_sector * + sectors_per_cluster; + + buf_mft = blkid_probe_get_buffer(pr, off, mft_record_size); + if (!buf_mft) + return 1; + + if (memcmp(buf_mft, "FILE", 4)) + return 1; + + off += MFT_RECORD_VOLUME * mft_record_size; + + buf_mft = blkid_probe_get_buffer(pr, off, mft_record_size); + if (!buf_mft) + return 1; + + if (memcmp(buf_mft, "FILE", 4)) + return 1; + + mft = (struct master_file_table_record *) buf_mft; + + attr_off = le16_to_cpu(mft->attrs_offset); + label_str[0] = 0; + + while (1) { + attr = (struct file_attribute *) (buf_mft + attr_off); + attr_len = le16_to_cpu(attr->len); + attr_type = le32_to_cpu(attr->type); + val_off = le16_to_cpu(attr->value_offset); + val_len = le32_to_cpu(attr->value_len); + + attr_off += attr_len; + + if ((attr_off > mft_record_size) || + (attr_len == 0)) + break; + + if (attr_type == MFT_RECORD_ATTR_END) + break; + + if (attr_type == MFT_RECORD_ATTR_VOLUME_NAME) { + if (val_len > sizeof(label_str)) + val_len = sizeof(label_str)-1; + + for (i=0, cp=label_str; i < val_len; i+=2,cp++) { + val = ((uint8_t *) attr) + val_off + i; + *cp = val[0]; + if (val[1]) + *cp = '?'; + } + *cp = 0; + } + } + + blkid_probe_sprintf_uuid(pr, + (unsigned char *) &ns->volume_serial, + sizeof(ns->volume_serial), + "%016" PRIX64, le64_to_cpu(ns->volume_serial)); + if (label_str[0]) + blkid_probe_set_label(pr, label_str, strlen((char *)label_str)); + return 0; +} + + +const struct blkid_idinfo ntfs_idinfo = +{ + .name = "ntfs", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_ntfs, + .magics = + { + { .magic = "NTFS ", .len = 8, .sboff = 3 }, + { NULL } + } +}; + diff --git a/libs/blkid/src/probers/probers.h b/libs/blkid/src/probers/probers.h index 4a44a22e..35180e6a 100644 --- a/libs/blkid/src/probers/probers.h +++ b/libs/blkid/src/probers/probers.h @@ -45,6 +45,7 @@ extern const struct blkid_idinfo reiser_idinfo; extern const struct blkid_idinfo reiser4_idinfo; extern const struct blkid_idinfo hfs_idinfo; extern const struct blkid_idinfo hfsplus_idinfo; +extern const struct blkid_idinfo ntfs_idinfo; #endif /* _BLKID_PROBE_H */ -- 2.39.5