⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vhd-util-read.c

📁 xen source 推出最新的VHD操作工具VHD-UTIL 实现源码,超强
💻 C
📖 第 1 页 / 共 2 页
字号:
	for (i = 0; i < count; i++) {
		cur    = block + i;
		offset = vhd->bat.bat[cur];

		printf("block: %s: ", conv(hex, cur));
		printf("offset: %s\n",
		       (offset == DD_BLK_UNUSED ? "not allocated" :
			conv(hex, vhd_sectors_to_bytes(offset))));
	}

	return 0;
}

static int
vhd_print_bitmap(vhd_context_t *vhd, uint64_t block, int count, int hex)
{
	char *buf;
	int i, err;
	uint64_t cur;

	if (check_block_range(vhd, block + count, hex))
		return -ERANGE;

	for (i = 0; i < count; i++) {
		cur = block + i;

		if (vhd->bat.bat[cur] == DD_BLK_UNUSED) {
			printf("block %s not allocated\n", conv(hex, cur));
			continue;
		}

		err = vhd_read_bitmap(vhd, cur, &buf);
		if (err)
			goto out;

		write(STDOUT_FILENO, buf, vhd_sectors_to_bytes(vhd->bm_secs));
		free(buf);
	}

	err = 0;
out:
	return err;
}

static int
vhd_test_bitmap(vhd_context_t *vhd, uint64_t sector, int count, int hex)
{
	char *buf;
	uint64_t cur;
	int i, err, bit;
	uint32_t blk, bm_blk, sec;

	if (vhd_sectors_to_bytes(sector + count) > vhd->footer.curr_size) {
		printf("sector %s past end of file\n", conv(hex, sector));
		return -ERANGE;
	}

	bm_blk = -1;
	buf    = NULL;

	for (i = 0; i < count; i++) {
		cur = sector + i;
		blk = cur / vhd->spb;
		sec = cur % vhd->spb;

		if (blk != bm_blk) {
			bm_blk = blk;
			free(buf);
			buf = NULL;

			if (vhd->bat.bat[blk] != DD_BLK_UNUSED) {
				err = vhd_read_bitmap(vhd, blk, &buf);
				if (err)
					goto out;
			}
		}

		if (vhd->bat.bat[blk] == DD_BLK_UNUSED)
			bit = 0;
		else
			bit = vhd_bitmap_test(vhd, buf, blk);

	print:
		printf("block %s: ", conv(hex, blk));
		printf("sec: %s: %d\n", conv(hex, sec), bit);
	}

	err = 0;
 out:
	free(buf);
	return err;
}

static int
vhd_print_batmap(vhd_context_t *vhd)
{
	int err;
	size_t size;

	err = vhd_get_batmap(vhd);
	if (err) {
		printf("failed to read batmap: %d\n", err);
		return err;
	}

	size = vhd_sectors_to_bytes(vhd->batmap.header.batmap_size);
	write(STDOUT_FILENO, vhd->batmap.map, size);

	return 0;
}

static int
vhd_test_batmap(vhd_context_t *vhd, uint64_t block, int count, int hex)
{
	int i, err;
	uint64_t cur;

	if (check_block_range(vhd, block + count, hex))
		return -ERANGE;

	err = vhd_get_batmap(vhd);
	if (err) {
		fprintf(stderr, "failed to get batmap\n");
		return err;
	}

	for (i = 0; i < count; i++) {
		cur = block + i;
		fprintf(stderr, "batmap for block %s: %d\n", conv(hex, cur),
			vhd_batmap_test(vhd, &vhd->batmap, cur));
	}

	return 0;
}

static int
vhd_print_data(vhd_context_t *vhd, uint64_t block, int count, int hex)
{
	char *buf;
	int i, err;
	uint64_t cur;

	err = 0;

	if (check_block_range(vhd, block + count, hex))
		return -ERANGE;

	for (i = 0; i < count; i++) {
		cur = block + i;

		if (vhd->bat.bat[cur] == DD_BLK_UNUSED) {
			printf("block %s not allocated\n", conv(hex, cur));
			continue;
		}

		err = vhd_read_block(vhd, cur, &buf);
		if (err)
			break;

		write(STDOUT_FILENO, buf, vhd->header.block_size);
		free(buf);
	}

	return err;
}

static int
vhd_read_data(vhd_context_t *vhd, uint64_t sec, int count, int hex)
{
	char *buf;
	uint64_t cur;
	int err, max, secs;

	if (vhd_sectors_to_bytes(sec + count) > vhd->footer.curr_size)
		return -ERANGE;

	max = MIN(vhd_sectors_to_bytes(count), VHD_BLOCK_SIZE);
	err = posix_memalign((void **)&buf, VHD_SECTOR_SIZE, max);
	if (err)
		return -err;

	cur = sec;
	while (count) {
		secs = MIN((max >> VHD_SECTOR_SHIFT), count);
		err  = vhd_io_read(vhd, buf, cur, secs);
		if (err)
			break;

		write(STDOUT_FILENO, buf, vhd_sectors_to_bytes(secs));

		cur   += secs;
		count -= secs;
	}

	free(buf);
	return err;
}

int
vhd_util_read(int argc, char **argv)
{
	char *name;
	vhd_context_t vhd;
	int c, err, headers, hex;
	uint64_t bat, bitmap, tbitmap, batmap, tbatmap, data, lsec, count, read;

	err     = 0;
	hex     = 0;
	headers = 0;
	count   = 1;
	bat     = -1;
	bitmap  = -1;
	tbitmap = -1;
	batmap  = -1;
	tbatmap = -1;
	data    = -1;
	lsec    = -1;
	read    = -1;
	name    = NULL;

	if (!argc || !argv)
		goto usage;

	optind = 0;
	while ((c = getopt(argc, argv, "n:pt:b:m:i:aj:d:c:r:xh")) != -1) {
		switch(c) {
		case 'n':
			name = optarg;
			break;
		case 'p':
			headers = 1;
			break;
		case 't':
			lsec = strtoul(optarg, NULL, 10);
			break;
		case 'b':
			bat = strtoull(optarg, NULL, 10);
			break;
		case 'm':
			bitmap = strtoull(optarg, NULL, 10);
			break;
		case 'i':
			tbitmap = strtoul(optarg, NULL, 10);
			break;
		case 'a':
			batmap = 1;
			break;
		case 'j':
			tbatmap = strtoull(optarg, NULL, 10);
			break;
		case 'd':
			data = strtoull(optarg, NULL, 10);
			break;
		case 'r':
			read = strtoull(optarg, NULL, 10);
			break;
		case 'c':
			count = strtoul(optarg, NULL, 10);
			break;
		case 'x':
			hex = 1;
			break;
		case 'h':
		default:
			goto usage;
		}
	}

	if (!name || optind != argc)
		goto usage;

	err = vhd_open(&vhd, name, VHD_OPEN_RDONLY | VHD_OPEN_IGNORE_DISABLED);
	if (err) {
		printf("Failed to open %s: %d\n", name, err);
		vhd_dump_headers(name, hex);
		return err;
	}

	err = vhd_get_bat(&vhd);
	if (err) {
		printf("Failed to get bat for %s: %d\n", name, err);
		goto out;
	}

	if (headers)
		vhd_print_headers(&vhd, hex);

	if (lsec != -1) {
		err = vhd_print_logical_to_physical(&vhd, lsec, count, hex);
		if (err)
			goto out;
	}

	if (bat != -1) {
		err = vhd_print_bat(&vhd, bat, count, hex);
		if (err)
			goto out;
	}

	if (bitmap != -1) {
		err = vhd_print_bitmap(&vhd, bitmap, count, hex);
		if (err)
			goto out;
	}

	if (tbitmap != -1) {
		err = vhd_test_bitmap(&vhd, tbitmap, count, hex);
		if (err)
			goto out;
	}

	if (batmap != -1) {
		err = vhd_print_batmap(&vhd);
		if (err)
			goto out;
	}

	if (tbatmap != -1) {
		err = vhd_test_batmap(&vhd, tbatmap, count, hex);
		if (err)
			goto out;
	}

	if (data != -1) {
		err = vhd_print_data(&vhd, data, count, hex);
		if (err)
			goto out;
	}

	if (read != -1) {
		err = vhd_read_data(&vhd, read, count, hex);
		if (err)
			goto out;
	}

	err = 0;

 out:
	vhd_close(&vhd);
	return err;

 usage:
	printf("options:\n"
	       "-h          help\n"
	       "-n          name\n"
	       "-p          print VHD headers\n"
	       "-t sec      translate logical sector to VHD location\n"
	       "-b blk      print bat entry\n"
	       "-m blk      print bitmap\n"
	       "-i sec      test bitmap for logical sector\n"
	       "-a          print batmap\n"
	       "-j blk      test batmap for block\n"
	       "-d blk      print data\n"
	       "-c num      num units\n"
	       "-r sec      read num sectors at sec\n"
	       "-x          print in hex\n");
	return EINVAL;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -