Exemplo n.º 1
0
/**
 * dump_file
 */
static int dump_file(ntfs_volume *vol, ntfs_inode *ino)
{
	char buffer[1024];
	ntfs_attr_search_ctx *ctx;
	ATTR_RECORD *rec;
	int i;
	runlist *runs;

	utils_inode_get_name(ino, buffer, sizeof(buffer));

	ntfs_log_info("Dump: %s\n", buffer);

	ctx = ntfs_attr_get_search_ctx(ino, NULL);

	while ((rec = find_attribute(AT_UNUSED, ctx))) {
		ntfs_log_info("    0x%02x - ", rec->type);
		if (rec->non_resident) {
			ntfs_log_info("non-resident\n");
			runs = ntfs_mapping_pairs_decompress(vol, rec, NULL);
			if (runs) {
				ntfs_log_info("             VCN     LCN     Length\n");
				for (i = 0; runs[i].length > 0; i++) {
					ntfs_log_info("        %8lld %8lld %8lld\n",
							(long long)runs[i].vcn,
							(long long)runs[i].lcn,
							(long long)
							runs[i].length);
				}
				free(runs);
			}
		} else {
			ntfs_log_info("resident\n");
		}
	}

	ntfs_attr_put_search_ctx(ctx);
	return 0;
}
Exemplo n.º 2
0
/**
 * info
 */
static int info(ntfs_volume *vol)
{
	u64 a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u;
	int cb, sb, cps;
	u64 uc = 0, mc = 0, fc = 0;

	struct mft_search_ctx *m_ctx;
	ntfs_attr_search_ctx *a_ctx;
	runlist_element *rl;
	ATTR_RECORD *rec;
	int z;
	int inuse = 0;

	m_ctx = mft_get_search_ctx(vol);
	m_ctx->flags_search = FEMR_IN_USE | FEMR_METADATA | FEMR_BASE_RECORD | FEMR_NOT_BASE_RECORD;
	while (mft_next_record(m_ctx) == 0) {

		if (!(m_ctx->flags_match & FEMR_IN_USE))
			continue;

		inuse++;

		a_ctx = ntfs_attr_get_search_ctx(m_ctx->inode, NULL);

		while ((rec = find_attribute(AT_UNUSED, a_ctx))) {

			if (!rec->non_resident)
				continue;

			rl = ntfs_mapping_pairs_decompress(vol, rec, NULL);

			for (z = 0; rl[z].length > 0; z++)
			{
				if (rl[z].lcn >= 0) {
					if (m_ctx->flags_match & FEMR_METADATA)
						mc += rl[z].length;
					else
						uc += rl[z].length;
				}

			}

			free(rl);
		}

		ntfs_attr_put_search_ctx(a_ctx);
	}
	mft_put_search_ctx(m_ctx);

	cb  = vol->cluster_size_bits;
	sb  = vol->sector_size_bits;
	cps = cb - sb;

	fc  = vol->nr_clusters-mc-uc;
	fc  <<= cb;
	mc  <<= cb;
	uc  <<= cb;

	a = vol->sector_size;
	b = vol->cluster_size;
	c = 1 << cps;
	d = vol->nr_clusters << cb;
	e = vol->nr_clusters;
	f = vol->nr_clusters >> cps;
	g = vol->mft_na->initialized_size >> vol->mft_record_size_bits;
	h = inuse;
	i = h * 100 / g;
	j = fc;
	k = fc >> sb;
	l = fc >> cb;
	m = fc * 100 / b / e;
	n = uc;
	o = uc >> sb;
	p = uc >> cb;
	q = uc * 100 / b / e;
	r = mc;
	s = mc >> sb;
	t = mc >> cb;
	u = mc * 100 / b / e;

	ntfs_log_info("bytes per sector        : %llu\n", (unsigned long long)a);
	ntfs_log_info("bytes per cluster       : %llu\n", (unsigned long long)b);
	ntfs_log_info("sectors per cluster     : %llu\n", (unsigned long long)c);
	ntfs_log_info("bytes per volume        : %llu\n", (unsigned long long)d);
	ntfs_log_info("sectors per volume      : %llu\n", (unsigned long long)e);
	ntfs_log_info("clusters per volume     : %llu\n", (unsigned long long)f);
	ntfs_log_info("initialized mft records : %llu\n", (unsigned long long)g);
	ntfs_log_info("mft records in use      : %llu\n", (unsigned long long)h);
	ntfs_log_info("mft records percentage  : %llu\n", (unsigned long long)i);
	ntfs_log_info("bytes of free space     : %llu\n", (unsigned long long)j);
	ntfs_log_info("sectors of free space   : %llu\n", (unsigned long long)k);
	ntfs_log_info("clusters of free space  : %llu\n", (unsigned long long)l);
	ntfs_log_info("percentage free space   : %llu\n", (unsigned long long)m);
	ntfs_log_info("bytes of user data      : %llu\n", (unsigned long long)n);
	ntfs_log_info("sectors of user data    : %llu\n", (unsigned long long)o);
	ntfs_log_info("clusters of user data   : %llu\n", (unsigned long long)p);
	ntfs_log_info("percentage user data    : %llu\n", (unsigned long long)q);
	ntfs_log_info("bytes of metadata       : %llu\n", (unsigned long long)r);
	ntfs_log_info("sectors of metadata     : %llu\n", (unsigned long long)s);
	ntfs_log_info("clusters of metadata    : %llu\n", (unsigned long long)t);
	ntfs_log_info("percentage metadata     : %llu\n", (unsigned long long)u);

	return 0;
}
Exemplo n.º 3
0
/**
 * Load the runlist of the <attr_type> attribute.
 *
 * Return NULL if an error.
 * The caller is responsible on freeing the allocated memory if the result is not NULL.
 *
 * Set size_of_file_record to some reasonable size when in doubt (the Windows default is 1024.)
 *
 * attr_type must be little endian.
 *
 * This function has code duplication with check_file_record() and
 * check_attr_record() but its goal is to be less strict. Thus the
 * duplicated checks are the minimal required for not crashing.
 *
 * Assumes dev is open.
 */
static runlist *load_runlist(ntfs_volume *rawvol, s64 offset_to_file_record, u32 attr_type, u32 size_of_file_record)
{
	u8 *buf;
	u16 attrs_offset;
	u32 length;
	ATTR_RECORD *attr_rec;
	
	if (size_of_file_record<22) // offset to attrs_offset
		return NULL;

	buf = (u8*)ntfs_malloc(size_of_file_record);
	if (!buf)
		return NULL;

	if (ntfs_pread(rawvol->dev, offset_to_file_record, size_of_file_record, buf) !=
			size_of_file_record) {
		check_failed("Failed to read file record at offset %lld (0x%llx).\n",
					(long long)offset_to_file_record,
					(long long)offset_to_file_record);
		return NULL;
	}

	attrs_offset = le16_to_cpu(((MFT_RECORD*)buf)->attrs_offset);
	// first attribute must be after the header.
	if (attrs_offset<42) {
		check_failed("First attribute must be after the header (%u).\n", (int)attrs_offset);
	}
	attr_rec = (ATTR_RECORD *)(buf + attrs_offset);
	//printf("uv1.\n");

	while ((u8*)attr_rec<=buf+size_of_file_record-4) {

		//printf("Attr type: 0x%x.\n", attr_rec->type);
		// Check attribute record. (Only what is in the buffer)
		if (attr_rec->type==AT_END) {
			check_failed("Attribute 0x%x not found in file record at offset %lld (0x%llx).\n", (int)le32_to_cpu(attr_rec->type),
					(long long)offset_to_file_record,
					(long long)offset_to_file_record);
			return NULL;
		}
		if ((u8*)attr_rec>buf+size_of_file_record-8) {
			// not AT_END yet no room for the length field.
			check_failed("Attribute 0x%x is not AT_END, yet no "
					"room for the length field.\n",
					(int)le32_to_cpu(attr_rec->type));
			return NULL;
		}

		length = le32_to_cpu(attr_rec->length);

		// Check that this attribute does not overflow the mft_record
		if ((u8*)attr_rec+length >= buf+size_of_file_record) {
			check_failed("Attribute (0x%x) is larger than FILE record at offset %lld (0x%llx).\n",
					(int)le32_to_cpu(attr_rec->type),
					(long long)offset_to_file_record,
					(long long)offset_to_file_record);
			return NULL;
		}
		// todo: what ATTRIBUTE_LIST (0x20)?

		if (attr_rec->type==attr_type) {
			// Eurika!

			// ntfs_mapping_pairs_decompress only use two values from vol. Just fake it.
			// todo: it will also use vol->major_ver if defined(DEBUG). But only for printing purposes.

			// Assume ntfs_boot_sector_parse() was called.
			return ntfs_mapping_pairs_decompress(rawvol, attr_rec, NULL);
		}

		attr_rec = (ATTR_RECORD*)((u8*)attr_rec+length);
	}
	// If we got here, there was an overflow.
	check_failed("file record corrupted at offset %lld (0x%llx).\n",
			(long long)offset_to_file_record,
			(long long)offset_to_file_record);
	return NULL;
}