diff --git a/drivers/td.c b/drivers/td.c index 304fa780..7923abfb 100644 --- a/drivers/td.c +++ b/drivers/td.c @@ -399,8 +399,9 @@ td_query(int type, int argc, char *argv[]) { char *name; int c, size = 0, parent = 0, fields = 0, depth = 0, err = 0; + int flags = VHD_OPEN_RDONLY; - while ((c = getopt(argc, argv, "hvpfd")) != -1) { + while ((c = getopt(argc, argv, "hvpfdb")) != -1) { switch(c) { case 'v': size = 1; @@ -417,6 +418,9 @@ td_query(int type, int argc, char *argv[]) case 'h': err = 0; goto usage; + case 'b': + flags |= VHD_OPEN_USE_BKP_FOOTER; + break; default: err = EINVAL; goto usage; @@ -438,7 +442,7 @@ td_query(int type, int argc, char *argv[]) if (type == TD_TYPE_VHD) { vhd_context_t vhd; - err = vhd_open(&vhd, name, VHD_OPEN_RDONLY); + err = vhd_open(&vhd, name, flags); if (err) { printf("failed opening %s: %d\n", name, err); return err; @@ -531,7 +535,8 @@ td_query(int type, int argc, char *argv[]) usage: fprintf(stderr, "usage: td-util query %s [-h help] [-v virtsize] " - "[-p parent] [-f fields] \n", td_disk_types[type]); + "[-p parent] [-f fields] [-b don't trust the footer, use the back-up " + "one instead] \n", td_disk_types[type]); return err; } diff --git a/include/libvhd.h b/include/libvhd.h index aa2d0b3e..10809d78 100644 --- a/include/libvhd.h +++ b/include/libvhd.h @@ -22,6 +22,7 @@ #include #include #include +#include #include "vhd.h" #include "list.h" @@ -63,6 +64,7 @@ #define VHD_OPEN_IGNORE_DISABLED 0x00010 #define VHD_OPEN_CACHED 0x00020 #define VHD_OPEN_IO_WRITE_SPARSE 0x00040 +#define VHD_OPEN_USE_BKP_FOOTER 0x00080 #define VHD_FLAG_CREAT_FILE_SIZE_FIXED 0x00001 #define VHD_FLAG_CREAT_PARENT_RAW 0x00002 @@ -312,7 +314,7 @@ int vhd_change_parent(vhd_context_t *, char *parent_path, int raw); int vhd_macx_encode_location(char *name, char **out, int *outlen); int vhd_w2u_encode_location(char *name, char **out, int *outlen); -int vhd_read_footer(vhd_context_t *, vhd_footer_t *); +int vhd_read_footer(vhd_context_t *, vhd_footer_t *, bool use_bkp_footer); int vhd_read_footer_at(vhd_context_t *, vhd_footer_t *, off64_t); int vhd_read_footer_strict(vhd_context_t *, vhd_footer_t *); int vhd_read_header(vhd_context_t *, vhd_header_t *); diff --git a/vhd/lib/libvhd.c b/vhd/lib/libvhd.c index efb00a20..c9a04759 100644 --- a/vhd/lib/libvhd.c +++ b/vhd/lib/libvhd.c @@ -769,7 +769,7 @@ vhd_get_footer(vhd_context_t *ctx) if (!vhd_validate_footer(&ctx->footer)) return 0; - return vhd_read_footer(ctx, &ctx->footer); + return vhd_read_footer(ctx, &ctx->footer, false); } int @@ -935,7 +935,7 @@ vhd_read_footer_at(vhd_context_t *ctx, vhd_footer_t *footer, off64_t off) } int -vhd_read_footer(vhd_context_t *ctx, vhd_footer_t *footer) +vhd_read_footer(vhd_context_t *ctx, vhd_footer_t *footer, bool use_bkp_footer) { int err; off64_t off; @@ -948,13 +948,15 @@ vhd_read_footer(vhd_context_t *ctx, vhd_footer_t *footer) if (off == (off64_t)-1) return -errno; - err = vhd_read_footer_at(ctx, footer, off - 512); - if (err != -EINVAL) - return err; + if (!use_bkp_footer) { + err = vhd_read_footer_at(ctx, footer, off - 512); + if (err != -EINVAL) + return err; - err = vhd_read_short_footer(ctx, footer); - if (err != -EINVAL) - return err; + err = vhd_read_short_footer(ctx, footer); + if (err != -EINVAL) + return err; + } /* * Disable the enforcement of VHD_OPEN_STRICT until we figure out how @@ -2523,7 +2525,8 @@ vhd_open(vhd_context_t *ctx, const char *file, int flags) return 0; } - err = vhd_read_footer(ctx, &ctx->footer); + err = vhd_read_footer(ctx, &ctx->footer, + (flags & VHD_OPEN_USE_BKP_FOOTER) == VHD_OPEN_USE_BKP_FOOTER); if (err) goto fail; diff --git a/vhd/lib/vhd-util-read.c b/vhd/lib/vhd-util-read.c index 84f35ca0..55ce695c 100644 --- a/vhd/lib/vhd-util-read.c +++ b/vhd/lib/vhd-util-read.c @@ -309,7 +309,7 @@ vhd_dump_headers(const char *name, int hex) vhd.file = strdup(name); - vhd_read_footer(&vhd, &vhd.footer); + vhd_read_footer(&vhd, &vhd.footer, false); vhd_read_header(&vhd, &vhd.header); vhd_print_footer(&vhd.footer, hex); diff --git a/vhd/lib/vhd-util-repair.c b/vhd/lib/vhd-util-repair.c index 16a486da..3125ee5a 100644 --- a/vhd/lib/vhd-util-repair.c +++ b/vhd/lib/vhd-util-repair.c @@ -33,6 +33,7 @@ vhd_util_repair(int argc, char **argv) char *name; int err, c; vhd_context_t vhd; + int flags = VHD_OPEN_RDWR; name = NULL; @@ -40,11 +41,14 @@ vhd_util_repair(int argc, char **argv) goto usage; optind = 0; - while ((c = getopt(argc, argv, "n:h")) != -1) { + while ((c = getopt(argc, argv, "n:bh")) != -1) { switch (c) { case 'n': name = optarg; break; + case 'b': + flags |= VHD_OPEN_USE_BKP_FOOTER; + break; case 'h': default: goto usage; @@ -54,7 +58,7 @@ vhd_util_repair(int argc, char **argv) if (!name || optind != argc) goto usage; - err = vhd_open(&vhd, name, VHD_OPEN_RDWR); + err = vhd_open(&vhd, name, flags); if (err) { printf("error opening %s: %d\n", name, err); return err; @@ -68,6 +72,6 @@ vhd_util_repair(int argc, char **argv) return err; usage: - printf("options: <-n name> [-h help]\n"); + printf("options: <-n name> <-b use the back-up footer> [-h help]\n"); return -EINVAL; }