📄 vhd-util-read.c
字号:
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 + -