1 /**
   2  * ntfsclone - Part of the Linux-NTFS project.
   3  *
   4  * Copyright (c) 2003-2006 Szabolcs Szakacsits
   5  * Copyright (c) 2004-2006 Anton Altaparmakov
   6  * Special image format support copyright (c) 2004 Per Olofsson
   7  *
   8  * Clone NTFS data and/or metadata to a sparse file, image, device or stdout.
   9  *
  10  * This program is free software; you can redistribute it and/or modify
  11  * it under the terms of the GNU General Public License as published by
  12  * the Free Software Foundation; either version 2 of the License, or
  13  * (at your option) any later version.
  14  */
  15 
  16 #include "config.h"
  17 
  18 #ifdef HAVE_UNISTD_H
  19 #include <unistd.h>
  20 #endif
  21 #ifdef HAVE_STDLIB_H
  22 #include <stdlib.h>
  23 #endif
  24 #ifdef HAVE_STDIO_H
  25 #include <stdio.h>
  26 #endif
  27 #ifdef HAVE_SYS_TYPES_H
  28 #include <sys/types.h>
  29 #endif
  30 #ifdef HAVE_SYS_STAT_H
  31 #include <sys/stat.h>
  32 #endif
  33 #ifdef HAVE_SYS_IOCTL_H
  34 #include <sys/ioctl.h>
  35 #endif
  36 #ifdef HAVE_SYS_VFS_H
  37 #include <sys/vfs.h>
  38 #endif
  39 #ifdef HAVE_SYS_STATVFS_H
  40 #include <sys/statvfs.h>
  41 #endif
  42 #ifdef HAVE_FCNTL_H
  43 #include <fcntl.h>
  44 #endif
  45 #ifdef HAVE_STDARG_H
  46 #include <stdarg.h>
  47 #endif
  48 #ifdef HAVE_STRING_H
  49 #include <string.h>
  50 #endif
  51 #ifdef HAVE_ERRNO_H
  52 #include <errno.h>
  53 #endif
  54 #ifdef HAVE_GETOPT_H
  55 #include <getopt.h>
  56 #endif
  57 
  58 /*
  59  * FIXME: ntfsclone do bad things about endians handling. Fix it and remove
  60  * this note and define.
  61  */
  62 #define NTFS_DO_NOT_CHECK_ENDIANS
  63 
  64 #include "compat.h"
  65 #include "debug.h"
  66 #include "types.h"
  67 #include "support.h"
  68 #include "endians.h"
  69 #include "bootsect.h"
  70 #include "device.h"
  71 #include "attrib.h"
  72 #include "mst.h"
  73 #include "volume.h"
  74 #include "mft.h"
  75 #include "bitmap.h"
  76 #include "inode.h"
  77 #include "index.h"
  78 #include "dir.h"
  79 #include "runlist.h"
  80 #include "ntfstime.h"
  81 #include "utils.h"
  82 #include "version.h"
  83 
  84 #if defined(linux) && defined(_IO) && !defined(BLKGETSIZE)
  85 #define BLKGETSIZE      _IO(0x12,96)  /* Get device size in 512-byte blocks. */
  86 #endif
  87 #if defined(linux) && defined(_IOR) && !defined(BLKGETSIZE64)
  88 #define BLKGETSIZE64    _IOR(0x12,114,size_t)   /* Get device size in bytes. */
  89 #endif
  90 
  91 static const char *EXEC_NAME = "ntfsclone";
  92 
  93 static const char *bad_sectors_warning_msg =
  94 "*************************************************************************\n"
  95 "* WARNING: The disk has bad sector. This means physical damage on the   *\n"
  96 "* disk surface caused by deterioration, manufacturing faults or other   *\n"
  97 "* reason. The reliability of the disk may stay stable or degrade fast.  *\n"
  98 "* Use the --rescue option to efficiently save as much data as possible! *\n"
  99 "*************************************************************************\n";
 100 
 101 static const char *dirty_volume_msg =
 102 "Volume '%s' is scheduled for a check or it was shutdown \n"
 103 "uncleanly. Please boot Windows or use the --force option to progress.\n";
 104 
 105 static struct {
 106         int verbose;
 107         int quiet;
 108         int debug;
 109         int force;
 110         int overwrite;
 111         int std_out;
 112         int blkdev_out;         /* output file is block device */
 113         int metadata;           /* metadata only cloning */
 114         int ignore_fs_check;
 115         int rescue;
 116         int save_image;
 117         int restore_image;
 118         char *output;
 119         char *volume;
 120 #ifdef __sun
 121         struct statvfs stfs;
 122 #else
 123         struct statfs stfs;
 124 #endif
 125 } opt;
 126 
 127 struct bitmap {
 128         s64 size;
 129         u8 *bm;
 130 };
 131 
 132 struct progress_bar {
 133         u64 start;
 134         u64 stop;
 135         int resolution;
 136         float unit;
 137 };
 138 
 139 typedef struct {
 140         ntfs_inode *ni;                 /* inode being processed */
 141         ntfs_attr_search_ctx *ctx;      /* inode attribute being processed */
 142         s64 inuse;                      /* number of clusters in use */
 143 } ntfs_walk_clusters_ctx;
 144 
 145 typedef int (ntfs_walk_op)(ntfs_inode *ni, void *data);
 146 
 147 struct ntfs_walk_cluster {
 148         ntfs_walk_op *inode_op;         /* not implemented yet */
 149         ntfs_walk_clusters_ctx *image;
 150 };
 151 
 152 
 153 static ntfs_volume *vol = NULL;
 154 static struct bitmap lcn_bitmap;
 155 
 156 static int fd_in;
 157 static int fd_out;
 158 static FILE *msg_out = NULL;
 159 
 160 static int wipe = 0;
 161 static unsigned int nr_used_mft_records   = 0;
 162 static unsigned int wiped_unused_mft_data = 0;
 163 static unsigned int wiped_unused_mft      = 0;
 164 static unsigned int wiped_resident_data   = 0;
 165 static unsigned int wiped_timestamp_data  = 0;
 166 
 167 static BOOL image_is_host_endian = FALSE;
 168 
 169 #define IMAGE_MAGIC "\0ntfsclone-image"
 170 #define IMAGE_MAGIC_SIZE 16
 171 
 172 /* This is the first endianness safe format version. */
 173 #define NTFSCLONE_IMG_VER_MAJOR_ENDIANNESS_SAFE 10
 174 #define NTFSCLONE_IMG_VER_MINOR_ENDIANNESS_SAFE 0
 175 
 176 /*
 177  * Set the version to 10.0 to avoid colisions with old ntfsclone which
 178  * stupidly used the volume version as the image version...  )-:  I hope NTFS
 179  * never reaches version 10.0 and if it does one day I hope no-one is using
 180  * such an old ntfsclone by then...
 181  *
 182  * NOTE: Only bump the minor version if the image format and header are still
 183  * backwards compatible.  Otherwise always bump the major version.  If in
 184  * doubt, bump the major version.
 185  */
 186 #define NTFSCLONE_IMG_VER_MAJOR 10
 187 #define NTFSCLONE_IMG_VER_MINOR 0
 188 
 189 /* All values are in little endian. */
 190 #ifdef __sun
 191 #pragma pack(1)
 192 #endif
 193 static struct image_hdr {
 194         char magic[IMAGE_MAGIC_SIZE];
 195         u8 major_ver;
 196         u8 minor_ver;
 197         u32 cluster_size;
 198         s64 device_size;
 199         s64 nr_clusters;
 200         s64 inuse;
 201         u32 offset_to_image_data;       /* From start of image_hdr. */
 202 } __attribute__((__packed__)) image_hdr;
 203 #ifdef __sun
 204 #pragma pack()
 205 #endif
 206 
 207 #ifdef __sun
 208 #define NTFSCLONE_IMG_HEADER_SIZE_OLD   \
 209                 (offsetof(struct image_hdr, offset_to_image_data))
 210 #else
 211 #define NTFSCLONE_IMG_HEADER_SIZE_OLD   \
 212                 (offsetof(typeof(image_hdr), offset_to_image_data))
 213 #endif
 214 
 215 #define NTFS_MBYTE (1000 * 1000)
 216 
 217 #define ERR_PREFIX   "ERROR"
 218 #define PERR_PREFIX  ERR_PREFIX "(%d): "
 219 #define NERR_PREFIX  ERR_PREFIX ": "
 220 
 221 #define LAST_METADATA_INODE     11
 222 
 223 #define NTFS_MAX_CLUSTER_SIZE   65536
 224 #define NTFS_SECTOR_SIZE          512
 225 
 226 #define rounded_up_division(a, b) (((a) + (b - 1)) / (b))
 227 
 228 #define read_all(f, p, n)  io_all((f), (p), (n), 0)
 229 #define write_all(f, p, n) io_all((f), (p), (n), 1)
 230 
 231 __attribute__((format(printf, 1, 2)))
 232 static void Printf(const char *fmt, ...)
 233 {
 234         va_list ap;
 235 
 236         va_start(ap, fmt);
 237         vfprintf(msg_out, fmt, ap);
 238         va_end(ap);
 239         fflush(msg_out);
 240 }
 241 
 242 __attribute__((format(printf, 1, 2)))
 243 static void perr_printf(const char *fmt, ...)
 244 {
 245         va_list ap;
 246         int eo = errno;
 247 
 248         Printf(PERR_PREFIX, eo);
 249         va_start(ap, fmt);
 250         vfprintf(msg_out, fmt, ap);
 251         va_end(ap);
 252         Printf(": %s\n", strerror(eo));
 253         fflush(msg_out);
 254 }
 255 
 256 __attribute__((format(printf, 1, 2)))
 257 static void err_printf(const char *fmt, ...)
 258 {
 259         va_list ap;
 260 
 261         Printf(NERR_PREFIX);
 262         va_start(ap, fmt);
 263         vfprintf(msg_out, fmt, ap);
 264         va_end(ap);
 265         fflush(msg_out);
 266 }
 267 
 268 __attribute__((noreturn))
 269 __attribute__((format(printf, 1, 2)))
 270 static int err_exit(const char *fmt, ...)
 271 {
 272         va_list ap;
 273 
 274         Printf(NERR_PREFIX);
 275         va_start(ap, fmt);
 276         vfprintf(msg_out, fmt, ap);
 277         va_end(ap);
 278         fflush(msg_out);
 279         exit(1);
 280 }
 281 
 282 __attribute__((noreturn))
 283 __attribute__((format(printf, 1, 2)))
 284 static int perr_exit(const char *fmt, ...)
 285 {
 286         va_list ap;
 287         int eo = errno;
 288 
 289         Printf(PERR_PREFIX, eo);
 290         va_start(ap, fmt);
 291         vfprintf(msg_out, fmt, ap);
 292         va_end(ap);
 293         Printf(": %s\n", strerror(eo));
 294         fflush(msg_out);
 295         exit(1);
 296 }
 297 
 298 
 299 __attribute__((noreturn))
 300 static void usage(void)
 301 {
 302         fprintf(stderr, "\nUsage: %s [OPTIONS] SOURCE\n"
 303                 "    Efficiently clone NTFS to a sparse file, image, device or standard output.\n"
 304                 "\n"
 305                 "    -o, --output FILE      Clone NTFS to the non-existent FILE\n"
 306                 "    -O, --overwrite FILE   Clone NTFS to FILE, overwriting if exists\n"
 307                 "    -s, --save-image       Save to the special image format\n"
 308                 "    -r, --restore-image    Restore from the special image format\n"
 309                 "        --rescue           Continue after disk read errors\n"
 310                 "    -m, --metadata         Clone *only* metadata (for NTFS experts)\n"
 311                 "        --ignore-fs-check  Ignore the filesystem check result\n"
 312                 "    -f, --force            Force to progress (DANGEROUS)\n"
 313                 "    -h, --help             Display this help\n"
 314 #ifdef DEBUG
 315                 "    -d, --debug            Show debug information\n"
 316 #endif
 317                 "\n"
 318                 "    If FILE is '-' then send the image to the standard output. If SOURCE is '-'\n"
 319                 "    and --restore-image is used then read the image from the standard input.\n"
 320                 "\n", EXEC_NAME);
 321         fprintf(stderr, "%s%s", ntfs_bugs, ntfs_home);
 322         exit(1);
 323 }
 324 
 325 
 326 static void parse_options(int argc, char **argv)
 327 {
 328         static const char *sopt = "-dfhmo:O:rs";
 329         static const struct option lopt[] = {
 330 #ifdef DEBUG
 331                 { "debug",            no_argument,       NULL, 'd' },
 332 #endif
 333                 { "force",            no_argument,       NULL, 'f' },
 334                 { "help",             no_argument,       NULL, 'h' },
 335                 { "metadata",         no_argument,       NULL, 'm' },
 336                 { "output",           required_argument, NULL, 'o' },
 337                 { "overwrite",        required_argument, NULL, 'O' },
 338                 { "restore-image",    no_argument,       NULL, 'r' },
 339                 { "ignore-fs-check",  no_argument,       NULL, 'C' },
 340                 { "rescue",           no_argument,       NULL, 'R' },
 341                 { "save-image",       no_argument,       NULL, 's' },
 342                 { NULL, 0, NULL, 0 }
 343         };
 344 
 345         int c;
 346 
 347         memset(&opt, 0, sizeof(opt));
 348 
 349         while ((c = getopt_long(argc, argv, sopt, lopt, NULL)) != -1) {
 350                 switch (c) {
 351                 case 1: /* A non-option argument */
 352                         if (opt.volume)
 353                                 usage();
 354                         opt.volume = argv[optind-1];
 355                         break;
 356                 case 'd':
 357                         opt.debug++;
 358                         break;
 359                 case 'f':
 360                         opt.force++;
 361                         break;
 362                 case 'h':
 363                 case '?':
 364                         usage();
 365                 case 'm':
 366                         opt.metadata++;
 367                         break;
 368                 case 'O':
 369                         opt.overwrite++;
 370                 case 'o':
 371                         if (opt.output)
 372                                 usage();
 373                         opt.output = optarg;
 374                         break;
 375                 case 'r':
 376                         opt.restore_image++;
 377                         break;
 378                 case 'C':
 379                         opt.ignore_fs_check++;
 380                         break;
 381                 case 'R':
 382                         opt.rescue++;
 383                         break;
 384                 case 's':
 385                         opt.save_image++;
 386                         break;
 387                 default:
 388                         err_printf("Unknown option '%s'.\n", argv[optind-1]);
 389                         usage();
 390                 }
 391         }
 392 
 393         if (opt.output == NULL) {
 394                 err_printf("You must specify an output file.\n");
 395                 usage();
 396         }
 397 
 398         if (strcmp(opt.output, "-") == 0)
 399                 opt.std_out++;
 400 
 401         if (opt.volume == NULL) {
 402                 err_printf("You must specify a device file.\n");
 403                 usage();
 404         }
 405 
 406         if (opt.metadata && opt.save_image)
 407                 err_exit("Saving only metadata to an image is not "
 408                          "supported!\n");
 409 
 410         if (opt.metadata && opt.restore_image)
 411                 err_exit("Restoring only metadata from an image is not "
 412                          "supported!\n");
 413 
 414         if (opt.metadata && opt.std_out)
 415                 err_exit("Cloning only metadata to stdout isn't supported!\n");
 416 
 417         if (opt.ignore_fs_check && !opt.metadata)
 418                 err_exit("Filesystem check can be ignored only for metadata "
 419                          "cloning!\n");
 420 
 421         if (opt.save_image && opt.restore_image)
 422                 err_exit("Saving and restoring an image at the same time "
 423                          "is not supported!\n");
 424 
 425         if (!opt.std_out) {
 426                 struct stat st;
 427 
 428                 if (stat(opt.output, &st) == -1) {
 429                         if (errno != ENOENT)
 430                                 perr_exit("Couldn't access '%s'", opt.output);
 431                 } else {
 432                         if (!opt.overwrite)
 433                                 err_exit("Output file '%s' already exists.\n"
 434                                          "Use option --overwrite if you want to"
 435                                          " replace its content.\n", opt.output);
 436 
 437                         if (S_ISBLK(st.st_mode)) {
 438                                 opt.blkdev_out = 1;
 439                                 if (opt.metadata)
 440                                         err_exit("Cloning only metadata to a "
 441                                              "block device isn't supported!\n");
 442                         }
 443                 }
 444         }
 445 
 446         msg_out = stdout;
 447 
 448         /* FIXME: this is a workaround for losing debug info if stdout != stderr
 449            and for the uncontrollable verbose messages in libntfs. Ughhh. */
 450         if (opt.std_out)
 451                 msg_out = stderr;
 452         else if (opt.debug) {
 453                 /* Redirect stderr to stdout, note fflush()es are essential! */
 454                 fflush(stdout);
 455                 fflush(stderr);
 456                 if (dup2(STDOUT_FILENO, STDERR_FILENO) == -1) {
 457                         perror("Failed to redirect stderr to stdout");
 458                         exit(1);
 459                 }
 460                 fflush(stdout);
 461                 fflush(stderr);
 462         } else {
 463                 fflush(stderr);
 464                 if (!freopen("/dev/null", "w", stderr))
 465                         perr_exit("Failed to redirect stderr to /dev/null");
 466         }
 467 }
 468 
 469 static void progress_init(struct progress_bar *p, u64 start, u64 stop, int res)
 470 {
 471         p->start = start;
 472         p->stop = stop;
 473         p->unit = 100.0 / (stop - start);
 474         p->resolution = res;
 475 }
 476 
 477 
 478 static void progress_update(struct progress_bar *p, u64 current)
 479 {
 480         float percent = p->unit * current;
 481 
 482         if (current != p->stop) {
 483                 if ((current - p->start) % p->resolution)
 484                         return;
 485                 Printf("%6.2f percent completed\r", percent);
 486         } else
 487                 Printf("100.00 percent completed\n");
 488         fflush(msg_out);
 489 }
 490 
 491 static s64 is_critical_metadata(ntfs_walk_clusters_ctx *image, runlist *rl)
 492 {
 493         s64 inode = image->ni->mft_no;
 494 
 495         if (inode <= LAST_METADATA_INODE) {
 496 
 497                 /* Don't save bad sectors (both $Bad and unnamed are ignored */
 498                 if (inode == FILE_BadClus && image->ctx->attr->type == AT_DATA)
 499                         return 0;
 500 
 501                 if (inode != FILE_LogFile)
 502                         return rl->length;
 503 
 504                 if (image->ctx->attr->type == AT_DATA) {
 505 
 506                         /* Save at least the first 16 KiB of FILE_LogFile */
 507                         s64 s = (s64)16384 - rl->vcn * vol->cluster_size;
 508                         if (s > 0) {
 509                                 s = rounded_up_division(s, vol->cluster_size);
 510                                 if (rl->length < s)
 511                                         s = rl->length;
 512                                 return s;
 513                         }
 514                         return 0;
 515                 }
 516         }
 517 
 518         if (image->ctx->attr->type != AT_DATA)
 519                 return rl->length;
 520 
 521         return 0;
 522 }
 523 
 524 
 525 static int io_all(void *fd, void *buf, int count, int do_write)
 526 {
 527         int i;
 528         struct ntfs_device *dev = fd;
 529 
 530         while (count > 0) {
 531                 if (do_write)
 532                         i = write(*(int *)fd, buf, count);
 533                 else if (opt.restore_image)
 534                         i = read(*(int *)fd, buf, count);
 535                 else
 536                         i = dev->d_ops->read(dev, buf, count);
 537                 if (i < 0) {
 538                         if (errno != EAGAIN && errno != EINTR)
 539                                 return -1;
 540                 } else {
 541                         count -= i;
 542                         buf = i + (char *) buf;
 543                 }
 544         }
 545         return 0;
 546 }
 547 
 548 
 549 static void rescue_sector(void *fd, off_t pos, void *buff)
 550 {
 551         const char *badsector_magic = "BadSectoR\0";
 552         struct ntfs_device *dev = fd;
 553 
 554         if (opt.restore_image) {
 555                 if (lseek(*(int *)fd, pos, SEEK_SET) == (off_t)-1)
 556                         perr_exit("lseek");
 557         } else {
 558                 if (vol->u.dev->d_ops->seek(dev, pos, SEEK_SET) == (off_t)-1)
 559                         perr_exit("seek input");
 560         }
 561 
 562         if (read_all(fd, buff, NTFS_SECTOR_SIZE) == -1) {
 563                 Printf("WARNING: Can't read sector at %llu, lost data.\n",
 564                         (unsigned long long)pos);
 565                 memset(buff, '?', NTFS_SECTOR_SIZE);
 566                 memmove(buff, badsector_magic, sizeof(badsector_magic));
 567         }
 568 }
 569 
 570 
 571 static void copy_cluster(int rescue, u64 rescue_lcn)
 572 {
 573         char buff[NTFS_MAX_CLUSTER_SIZE]; /* overflow checked at mount time */
 574         /* vol is NULL if opt.restore_image is set */
 575         u32 csize = le32_to_cpu(image_hdr.cluster_size);
 576         void *fd = (void *)&fd_in;
 577         off_t rescue_pos;
 578 
 579         if (!opt.restore_image) {
 580                 csize = vol->cluster_size;
 581                 fd = vol->u.dev;
 582         }
 583 
 584         rescue_pos = (off_t)(rescue_lcn * csize);
 585 
 586         if (read_all(fd, buff, csize) == -1) {
 587 
 588                 if (errno != EIO)
 589                         perr_exit("read_all");
 590                 else if (rescue){
 591                         u32 i;
 592                         for (i = 0; i < csize; i += NTFS_SECTOR_SIZE)
 593                                 rescue_sector(fd, rescue_pos + i, buff + i);
 594                 } else {
 595                         Printf("%s", bad_sectors_warning_msg);
 596                         err_exit("Disk is faulty, can't make full backup!");
 597                 }
 598         }
 599 
 600         if (opt.save_image) {
 601                 char cmd = 1;
 602                 if (write_all(&fd_out, &cmd, sizeof(cmd)) == -1)
 603                         perr_exit("write_all");
 604         }
 605 
 606         if (write_all(&fd_out, buff, csize) == -1) {
 607                 perr_printf("Write failed");
 608 #ifndef __sun
 609                 int err = errno;
 610                 if (errno == EIO && opt.stfs.f_type == 0x517b)
 611                         Printf("Apparently you tried to clone to a remote "
 612                                "Windows computer but they don't\nhave "
 613                                "efficient sparse file handling by default. "
 614                                "Please try a different method.\n");
 615 #endif /* !defined(__sun) */
 616                 exit(1);
 617         }
 618 }
 619 
 620 static void lseek_to_cluster(s64 lcn)
 621 {
 622         off_t pos;
 623 
 624         pos = (off_t)(lcn * vol->cluster_size);
 625 
 626         if (vol->u.dev->d_ops->seek(vol->u.dev, pos, SEEK_SET) == (off_t)-1)
 627                 perr_exit("lseek input");
 628 
 629         if (opt.std_out || opt.save_image)
 630                 return;
 631 
 632         if (lseek(fd_out, pos, SEEK_SET) == (off_t)-1)
 633                 perr_exit("lseek output");
 634 }
 635 
 636 static void image_skip_clusters(s64 count)
 637 {
 638         if (opt.save_image && count > 0) {
 639 #ifdef __sun
 640                 s64 count_buf;
 641 #else
 642                 typeof(count) count_buf;
 643 #endif
 644                 char buff[1 + sizeof(count)];
 645 
 646                 buff[0] = 0;
 647                 count_buf = cpu_to_sle64(count);
 648                 memcpy(buff + 1, &count_buf, sizeof(count_buf));
 649 
 650                 if (write_all(&fd_out, buff, sizeof(buff)) == -1)
 651                         perr_exit("write_all");
 652         }
 653 }
 654 
 655 static void dump_clusters(ntfs_walk_clusters_ctx *image, runlist *rl)
 656 {
 657         s64 i, len; /* number of clusters to copy */
 658 
 659         if (opt.std_out || !opt.metadata)
 660                 return;
 661 
 662         if (!(len = is_critical_metadata(image, rl)))
 663                 return;
 664 
 665         lseek_to_cluster(rl->lcn);
 666 
 667         /* FIXME: this could give pretty suboptimal performance */
 668         for (i = 0; i < len; i++)
 669                 copy_cluster(opt.rescue, rl->lcn + i);
 670 }
 671 
 672 static void clone_ntfs(u64 nr_clusters)
 673 {
 674         u64 cl, last_cl;  /* current and last used cluster */
 675         void *buf;
 676         u32 csize = vol->cluster_size;
 677         u64 p_counter = 0;
 678         struct progress_bar progress;
 679 
 680         if (opt.save_image)
 681                 Printf("Saving NTFS to image ...\n");
 682         else
 683                 Printf("Cloning NTFS ...\n");
 684 
 685         buf = ntfs_calloc(csize);
 686         if (!buf)
 687                 perr_exit("clone_ntfs");
 688 
 689         progress_init(&progress, p_counter, nr_clusters, 100);
 690 
 691         if (opt.save_image) {
 692                 if (write_all(&fd_out, &image_hdr,
 693                                 image_hdr.offset_to_image_data) == -1)
 694                         perr_exit("write_all");
 695         }
 696 
 697         for (last_cl = cl = 0; cl < (u64)vol->nr_clusters; cl++) {
 698 
 699                 if (ntfs_bit_get(lcn_bitmap.bm, cl)) {
 700                         progress_update(&progress, ++p_counter);
 701                         lseek_to_cluster(cl);
 702                         image_skip_clusters(cl - last_cl - 1);
 703 
 704                         copy_cluster(opt.rescue, cl);
 705                         last_cl = cl;
 706                         continue;
 707                 }
 708 
 709                 if (opt.std_out && !opt.save_image) {
 710                         progress_update(&progress, ++p_counter);
 711                         if (write_all(&fd_out, buf, csize) == -1)
 712                                 perr_exit("write_all");
 713                 }
 714         }
 715         image_skip_clusters(cl - last_cl - 1);
 716 }
 717 
 718 static void write_empty_clusters(s32 csize, s64 count,
 719                                  struct progress_bar *progress, u64 *p_counter)
 720 {
 721         s64 i;
 722         char buff[NTFS_MAX_CLUSTER_SIZE];
 723 
 724         memset(buff, 0, csize);
 725 
 726         for (i = 0; i < count; i++) {
 727                 if (write_all(&fd_out, buff, csize) == -1)
 728                         perr_exit("write_all");
 729                 progress_update(progress, ++(*p_counter));
 730         }
 731 }
 732 
 733 static void restore_image(void)
 734 {
 735         s64 pos = 0, count;
 736         s32 csize = le32_to_cpu(image_hdr.cluster_size);
 737         char cmd;
 738         u64 p_counter = 0;
 739         struct progress_bar progress;
 740 
 741         Printf("Restoring NTFS from image ...\n");
 742 
 743         progress_init(&progress, p_counter, opt.std_out ?
 744                       sle64_to_cpu(image_hdr.nr_clusters) :
 745                       sle64_to_cpu(image_hdr.inuse),
 746                       100);
 747 
 748         while (pos < sle64_to_cpu(image_hdr.nr_clusters)) {
 749                 if (read_all(&fd_in, &cmd, sizeof(cmd)) == -1)
 750                         perr_exit("read_all");
 751 
 752                 if (cmd == 0) {
 753                         if (read_all(&fd_in, &count, sizeof(count)) == -1)
 754                                 perr_exit("read_all");
 755                         if (!image_is_host_endian)
 756                                 count = sle64_to_cpu(count);
 757                         if (opt.std_out)
 758                                 write_empty_clusters(csize, count,
 759                                                      &progress, &p_counter);
 760                         else {
 761                                 if (lseek(fd_out, count * csize, SEEK_CUR) ==
 762                                                 (off_t)-1)
 763                                         perr_exit("restore_image: lseek");
 764                         }
 765                         pos += count;
 766                 } else if (cmd == 1) {
 767                         copy_cluster(0, 0);
 768                         pos++;
 769                         progress_update(&progress, ++p_counter);
 770                 } else
 771                         err_exit("Invalid command code in image\n");
 772         }
 773 }
 774 
 775 static void wipe_index_entry_timestams(INDEX_ENTRY *e)
 776 {
 777         s64 timestamp = utc2ntfs(0);
 778 
 779         /* FIXME: can fall into infinite loop if corrupted */
 780         while (!(e->flags & INDEX_ENTRY_END)) {
 781 
 782                 e->key.file_name.creation_time = timestamp;
 783                 e->key.file_name.last_data_change_time = timestamp;
 784                 e->key.file_name.last_mft_change_time = timestamp;
 785                 e->key.file_name.last_access_time = timestamp;
 786 
 787                 wiped_timestamp_data += 32;
 788 
 789                 e = (INDEX_ENTRY *)((u8 *)e + le16_to_cpu(e->length));
 790         }
 791 }
 792 
 793 static void wipe_index_allocation_timestamps(ntfs_inode *ni, ATTR_RECORD *attr)
 794 {
 795         INDEX_ALLOCATION *indexa, *tmp_indexa;
 796         INDEX_ENTRY *entry;
 797         INDEX_ROOT *indexr;
 798         u8 *bitmap, *byte;
 799         int bit;
 800         ntfs_attr *na;
 801         ntfschar *name;
 802         u32 name_len;
 803 
 804         indexr = ntfs_index_root_get(ni, attr);
 805         if (!indexr) {
 806                 perr_printf("Failed to read $INDEX_ROOT attribute of inode "
 807                             "%lld", ni->mft_no);
 808                 return;
 809         }
 810 
 811         if (indexr->type != AT_FILE_NAME)
 812                 goto out_indexr;
 813 
 814         name = (ntfschar *)((u8 *)attr + le16_to_cpu(attr->name_offset));
 815         name_len = attr->name_length;
 816 
 817         byte = bitmap = ntfs_attr_readall(ni, AT_BITMAP, name, name_len, NULL);
 818         if (!byte) {
 819                 perr_printf("Failed to read $BITMAP attribute");
 820                 goto out_indexr;
 821         }
 822 
 823         na = ntfs_attr_open(ni, AT_INDEX_ALLOCATION, name, name_len);
 824         if (!na) {
 825                 perr_printf("Failed to open $INDEX_ALLOCATION attribute");
 826                 goto out_bitmap;
 827         }
 828 
 829         if (!na->data_size)
 830                 goto out_na;
 831 
 832         tmp_indexa = indexa = ntfs_malloc(na->data_size);
 833         if (!tmp_indexa)
 834                 goto out_na;
 835 
 836         if (ntfs_attr_pread(na, 0, na->data_size, indexa) != na->data_size) {
 837                 perr_printf("Failed to read $INDEX_ALLOCATION attribute");
 838                 goto out_indexa;
 839         }
 840 
 841         bit = 0;
 842         while ((u8 *)tmp_indexa < (u8 *)indexa + na->data_size) {
 843                 if (*byte & (1 << bit)) {
 844                         if (ntfs_mst_post_read_fixup((NTFS_RECORD *)tmp_indexa,
 845                                         le32_to_cpu(
 846                                         indexr->index_block_size))) {
 847                                 perr_printf("Damaged INDX record");
 848                                 goto out_indexa;
 849                         }
 850                         entry = (INDEX_ENTRY *)((u8 *)tmp_indexa + le32_to_cpu(
 851                                 tmp_indexa->index.entries_offset) + 0x18);
 852 
 853                         wipe_index_entry_timestams(entry);
 854 
 855                         if (ntfs_mft_usn_dec((MFT_RECORD *)tmp_indexa))
 856                                 perr_exit("ntfs_mft_usn_dec");
 857 
 858                         if (ntfs_mst_pre_write_fixup((NTFS_RECORD *)tmp_indexa,
 859                                         le32_to_cpu(
 860                                         indexr->index_block_size))) {
 861                                 perr_printf("INDX write fixup failed");
 862                                 goto out_indexa;
 863                         }
 864                 }
 865                 tmp_indexa = (INDEX_ALLOCATION *)((u8 *)tmp_indexa +
 866                                 le32_to_cpu(indexr->index_block_size));
 867                 bit++;
 868                 if (bit > 7) {
 869                         bit = 0;
 870                         byte++;
 871                 }
 872         }
 873 
 874         if (ntfs_rl_pwrite(vol, na->rl, 0, na->data_size, indexa) != na->data_size)
 875                 perr_printf("ntfs_rl_pwrite failed for inode %lld", ni->mft_no);
 876 out_indexa:
 877         free(indexa);
 878 out_na:
 879         ntfs_attr_close(na);
 880 out_bitmap:
 881         free(bitmap);
 882 out_indexr:
 883         free(indexr);
 884 }
 885 
 886 static void wipe_index_root_timestamps(ATTR_RECORD *attr, s64 timestamp)
 887 {
 888         INDEX_ENTRY *entry;
 889         INDEX_ROOT *iroot;
 890 
 891         iroot = (INDEX_ROOT *)((u8 *)attr + le16_to_cpu(attr->u.res.value_offset));
 892         entry = (INDEX_ENTRY *)((u8 *)iroot +
 893                         le32_to_cpu(iroot->index.entries_offset) + 0x10);
 894 
 895         while (!(entry->flags & INDEX_ENTRY_END)) {
 896 
 897                 if (iroot->type == AT_FILE_NAME) {
 898 
 899                         entry->key.file_name.creation_time = timestamp;
 900                         entry->key.file_name.last_access_time = timestamp;
 901                         entry->key.file_name.last_data_change_time = timestamp;
 902                         entry->key.file_name.last_mft_change_time = timestamp;
 903 
 904                         wiped_timestamp_data += 32;
 905 
 906                 } else if (ntfs_names_are_equal(NTFS_INDEX_Q,
 907                                 sizeof(NTFS_INDEX_Q) / 2 - 1,
 908                                 (ntfschar *)((char *)attr +
 909                                             le16_to_cpu(attr->name_offset)),
 910                                 attr->name_length, 0, NULL, 0)) {
 911 
 912                         QUOTA_CONTROL_ENTRY *quota_q;
 913 
 914                         quota_q = (QUOTA_CONTROL_ENTRY *)((u8 *)entry +
 915                                         le16_to_cpu(entry->u.s.data_offset));
 916                         /*
 917                          *  FIXME: no guarantee it's indeed /$Extend/$Quota:$Q.
 918                          *  For now, as a minimal safeguard, we check only for
 919                          *  quota version 2 ...
 920                          */
 921                         if (le32_to_cpu(quota_q->version) == 2) {
 922                                 quota_q->change_time = timestamp;
 923                                 wiped_timestamp_data += 4;
 924                         }
 925                 }
 926 
 927                 entry = (INDEX_ENTRY*)((u8*)entry + le16_to_cpu(entry->length));
 928         }
 929 }
 930 
 931 #define WIPE_TIMESTAMPS(atype, attr, timestamp)                 \
 932 do {                                                            \
 933         atype *ats;                                             \
 934         ats = (atype *)((char *)(attr) + le16_to_cpu((attr)->u.res.value_offset)); \
 935                                                                 \
 936         ats->creation_time = (timestamp);                    \
 937         ats->last_data_change_time = (timestamp);            \
 938         ats->last_mft_change_time= (timestamp);                      \
 939         ats->last_access_time = (timestamp);                 \
 940                                                                 \
 941         wiped_timestamp_data += 32;                             \
 942                                                                 \
 943 } while (0)
 944 
 945 static void wipe_timestamps(ntfs_walk_clusters_ctx *image)
 946 {
 947         ATTR_RECORD *a = image->ctx->attr;
 948         s64 timestamp = utc2ntfs(0);
 949 
 950         if (a->type == AT_FILE_NAME)
 951                 WIPE_TIMESTAMPS(FILE_NAME_ATTR, a, timestamp);
 952 
 953         else if (a->type == AT_STANDARD_INFORMATION)
 954                 WIPE_TIMESTAMPS(STANDARD_INFORMATION, a, timestamp);
 955 
 956         else if (a->type == AT_INDEX_ROOT)
 957                 wipe_index_root_timestamps(a, timestamp);
 958 }
 959 
 960 static void wipe_resident_data(ntfs_walk_clusters_ctx *image)
 961 {
 962         ATTR_RECORD *a;
 963         u32 i;
 964         int n = 0;
 965         u8 *p;
 966 
 967         a = image->ctx->attr;
 968         p = (u8*)a + le16_to_cpu(a->u.res.value_offset);
 969 
 970         if (image->ni->mft_no <= LAST_METADATA_INODE)
 971                 return;
 972 
 973         if (a->type != AT_DATA)
 974                 return;
 975 
 976         for (i = 0; i < le32_to_cpu(a->u.res.value_length); i++) {
 977                 if (p[i]) {
 978                         p[i] = 0;
 979                         n++;
 980                 }
 981         }
 982 
 983         wiped_resident_data += n;
 984 }
 985 
 986 static void clone_logfile_parts(ntfs_walk_clusters_ctx *image, runlist *rl)
 987 {
 988         s64 offset = 0, lcn, vcn;
 989 
 990         while (1) {
 991 
 992                 vcn = offset / image->ni->vol->cluster_size;
 993                 lcn = ntfs_rl_vcn_to_lcn(rl, vcn);
 994                 if (lcn < 0)
 995                         break;
 996 
 997                 lseek_to_cluster(lcn);
 998                 copy_cluster(opt.rescue, lcn);
 999 
1000                 if (offset == 0)
1001                         offset = NTFS_BLOCK_SIZE >> 1;
1002                 else
1003                         offset <<= 1;
1004         }
1005 }
1006 
1007 static void walk_runs(struct ntfs_walk_cluster *walk)
1008 {
1009         int i, j;
1010         runlist *rl;
1011         ATTR_RECORD *a;
1012         ntfs_attr_search_ctx *ctx;
1013 
1014         ctx = walk->image->ctx;
1015         a = ctx->attr;
1016 
1017         if (!a->non_resident) {
1018                 if (wipe) {
1019                         wipe_resident_data(walk->image);
1020                         wipe_timestamps(walk->image);
1021                 }
1022                 return;
1023         }
1024 
1025         if (wipe && walk->image->ctx->attr->type == AT_INDEX_ALLOCATION)
1026                 wipe_index_allocation_timestamps(walk->image->ni, a);
1027 
1028         if (!(rl = ntfs_mapping_pairs_decompress(vol, a, NULL)))
1029                 perr_exit("ntfs_decompress_mapping_pairs");
1030 
1031         for (i = 0; rl[i].length; i++) {
1032                 s64 lcn = rl[i].lcn;
1033                 s64 lcn_length = rl[i].length;
1034 
1035                 if (lcn == LCN_HOLE || lcn == LCN_RL_NOT_MAPPED)
1036                         continue;
1037 
1038                 /* FIXME: ntfs_mapping_pairs_decompress should return error */
1039                 if (lcn < 0 || lcn_length < 0)
1040                         err_exit("Corrupt runlist in inode %lld attr %x LCN "
1041                                  "%llx length %llx\n", ctx->ntfs_ino->mft_no,
1042                                  (unsigned int)le32_to_cpu(a->type), lcn,
1043                                  lcn_length);
1044 
1045                 if (!wipe)
1046                         dump_clusters(walk->image, rl + i);
1047 
1048                 for (j = 0; j < lcn_length; j++) {
1049                         u64 k = (u64)lcn + j;
1050                         if (ntfs_bit_get_and_set(lcn_bitmap.bm, k, 1))
1051                                 err_exit("Cluster %llu referenced twice!\n"
1052                                          "You didn't shutdown your Windows"
1053                                          "properly?\n", (unsigned long long)k);
1054                 }
1055 
1056                 walk->image->inuse += lcn_length;
1057         }
1058         if (!wipe && !opt.std_out && opt.metadata &&
1059             walk->image->ni->mft_no == FILE_LogFile &&
1060             walk->image->ctx->attr->type == AT_DATA)
1061                 clone_logfile_parts(walk->image, rl);
1062 
1063         free(rl);
1064 }
1065 
1066 
1067 static void walk_attributes(struct ntfs_walk_cluster *walk)
1068 {
1069         ntfs_attr_search_ctx *ctx;
1070 
1071         if (!(ctx = ntfs_attr_get_search_ctx(walk->image->ni, NULL)))
1072                 perr_exit("ntfs_get_attr_search_ctx");
1073 
1074         while (!ntfs_attrs_walk(ctx)) {
1075                 if (ctx->attr->type == AT_END)
1076                         break;
1077 
1078                 walk->image->ctx = ctx;
1079                 walk_runs(walk);
1080         }
1081 
1082         ntfs_attr_put_search_ctx(ctx);
1083 }
1084 
1085 
1086 
1087 static void compare_bitmaps(struct bitmap *a)
1088 {
1089         s64 i, pos, count;
1090         int mismatch = 0;
1091         u8 bm[NTFS_BUF_SIZE];
1092 
1093         Printf("Accounting clusters ...\n");
1094 
1095         pos = 0;
1096         while (1) {
1097                 count = ntfs_attr_pread(vol->lcnbmp_na, pos, NTFS_BUF_SIZE, bm);
1098                 if (count == -1)
1099                         perr_exit("Couldn't get $Bitmap $DATA");
1100 
1101                 if (count == 0) {
1102                         if (a->size > pos)
1103                                 err_exit("$Bitmap size is smaller than expected"
1104                                          " (%lld != %lld)\n", a->size, pos);
1105                         break;
1106                 }
1107 
1108                 for (i = 0; i < count; i++, pos++) {
1109                         s64 cl;  /* current cluster */
1110 
1111                         if (a->size <= pos)
1112                                 goto done;
1113 
1114                         if (a->bm[pos] == bm[i])
1115                                 continue;
1116 
1117                         for (cl = pos * 8; cl < (pos + 1) * 8; cl++) {
1118                                 char bit;
1119 
1120                                 bit = ntfs_bit_get(a->bm, cl);
1121                                 if (bit == ntfs_bit_get(bm, i * 8 + cl % 8))
1122                                         continue;
1123 
1124                                 if (opt.ignore_fs_check) {
1125                                         lseek_to_cluster(cl);
1126                                         copy_cluster(opt.rescue, cl);
1127                                 }
1128 
1129                                 if (++mismatch > 10)
1130                                         continue;
1131 
1132                                 Printf("Cluster accounting failed at %lld "
1133                                        "(0x%llx): %s cluster in $Bitmap\n",
1134                                        (long long)cl, (unsigned long long)cl,
1135                                        bit ? "missing" : "extra");
1136                         }
1137                 }
1138         }
1139 done:
1140         if (mismatch) {
1141                 Printf("Totally %d cluster accounting mismatches.\n", mismatch);
1142                 if (opt.ignore_fs_check) {
1143                         Printf("WARNING: The NTFS inconsistency was overruled "
1144                                "by the --ignore-fs-check option.\n");
1145                         return;
1146                 }
1147                 err_exit("Filesystem check failed! Windows wasn't shutdown "
1148                          "properly or inconsistent\nfilesystem. Please run "
1149                          "chkdsk /f on Windows then reboot it TWICE.\n");
1150         }
1151 }
1152 
1153 
1154 static int wipe_data(char *p, int pos, int len)
1155 {
1156         int wiped = 0;
1157 
1158         for (p += pos; --len >= 0;) {
1159                 if (p[len]) {
1160                         p[len] = 0;
1161                         wiped++;
1162                 }
1163         }
1164 
1165         return wiped;
1166 }
1167 
1168 static void wipe_unused_mft_data(ntfs_inode *ni)
1169 {
1170         int unused;
1171         MFT_RECORD *m = ni->mrec;
1172 
1173         /* FIXME: broken MFTMirr update was fixed in libntfs, check if OK now */
1174         if (ni->mft_no <= LAST_METADATA_INODE)
1175                 return;
1176 
1177         unused = le32_to_cpu(m->bytes_allocated) - le32_to_cpu(m->bytes_in_use);
1178         wiped_unused_mft_data += wipe_data((char *)m,
1179                         le32_to_cpu(m->bytes_in_use), unused);
1180 }
1181 
1182 static void wipe_unused_mft(ntfs_inode *ni)
1183 {
1184         int unused;
1185         MFT_RECORD *m = ni->mrec;
1186 
1187         /* FIXME: broken MFTMirr update was fixed in libntfs, check if OK now */
1188         if (ni->mft_no <= LAST_METADATA_INODE)
1189                 return;
1190 
1191         unused = le32_to_cpu(m->bytes_in_use) - sizeof(MFT_RECORD);
1192         wiped_unused_mft += wipe_data((char *)m, sizeof(MFT_RECORD), unused);
1193 }
1194 
1195 static void mft_record_write_with_same_usn(ntfs_volume *volume, ntfs_inode *ni)
1196 {
1197         if (ntfs_mft_usn_dec(ni->mrec))
1198                 perr_exit("ntfs_mft_usn_dec");
1199 
1200         if (ntfs_mft_record_write(volume, ni->mft_no, ni->mrec))
1201                 perr_exit("ntfs_mft_record_write");
1202 }
1203 
1204 static void mft_inode_write_with_same_usn(ntfs_volume *volume, ntfs_inode *ni)
1205 {
1206         s32 i;
1207 
1208         mft_record_write_with_same_usn(volume, ni);
1209 
1210         if (ni->nr_extents <= 0)
1211                 return;
1212 
1213         for (i = 0; i < ni->nr_extents; ++i) {
1214                 ntfs_inode *eni = ni->u.extent_nis[i];
1215                 mft_record_write_with_same_usn(volume, eni);
1216         }
1217 }
1218 
1219 static int walk_clusters(ntfs_volume *volume, struct ntfs_walk_cluster *walk)
1220 {
1221         s64 inode = 0;
1222         s64 last_mft_rec;
1223         ntfs_inode *ni;
1224         struct progress_bar progress;
1225 
1226         Printf("Scanning volume ...\n");
1227 
1228         last_mft_rec = (volume->mft_na->initialized_size >>
1229                         volume->mft_record_size_bits) - 1;
1230         progress_init(&progress, inode, last_mft_rec, 100);
1231 
1232         for (; inode <= last_mft_rec; inode++) {
1233 
1234                 int err, deleted_inode;
1235                 MFT_REF mref = (MFT_REF)inode;
1236 
1237                 progress_update(&progress, inode);
1238 
1239                 /* FIXME: Terrible kludge for libntfs not being able to return
1240                    a deleted MFT record as inode */
1241                 ni = ntfs_calloc(sizeof(ntfs_inode));
1242                 if (!ni)
1243                         perr_exit("walk_clusters");
1244 
1245                 ni->vol = volume;
1246 
1247                 err = ntfs_file_record_read(volume, mref, &ni->mrec, NULL);
1248                 if (err == -1) {
1249                         free(ni);
1250                         continue;
1251                 }
1252 
1253                 deleted_inode = !(ni->mrec->flags & MFT_RECORD_IN_USE);
1254 
1255                 if (deleted_inode) {
1256 
1257                         ni->mft_no = MREF(mref);
1258                         if (wipe) {
1259                                 wipe_unused_mft(ni);
1260                                 wipe_unused_mft_data(ni);
1261                                 mft_record_write_with_same_usn(volume, ni);
1262                         }
1263                 }
1264 
1265                 free(ni->mrec);
1266                 free(ni);
1267 
1268                 if (deleted_inode)
1269                         continue;
1270 
1271                 if ((ni = ntfs_inode_open(volume, mref)) == NULL) {
1272                         /* FIXME: continue only if it make sense, e.g.
1273                            MFT record not in use based on $MFT bitmap */
1274                         if (errno == EIO || errno == ENOENT)
1275                                 continue;
1276                         perr_exit("Reading inode %lld failed", inode);
1277                 }
1278 
1279                 if (wipe)
1280                         nr_used_mft_records++;
1281 
1282                 if (ni->mrec->base_mft_record)
1283                         goto out;
1284 
1285                 walk->image->ni = ni;
1286                 walk_attributes(walk);
1287 out:
1288                 if (wipe) {
1289                         wipe_unused_mft_data(ni);
1290                         mft_inode_write_with_same_usn(volume, ni);
1291                 }
1292 
1293                 if (ntfs_inode_close(ni))
1294                         perr_exit("ntfs_inode_close for inode %lld", inode);
1295         }
1296 
1297         return 0;
1298 }
1299 
1300 
1301 /*
1302  * $Bitmap can overlap the end of the volume. Any bits in this region
1303  * must be set. This region also encompasses the backup boot sector.
1304  */
1305 static void bitmap_file_data_fixup(s64 cluster, struct bitmap *bm)
1306 {
1307         for (; cluster < bm->size << 3; cluster++)
1308                 ntfs_bit_set(bm->bm, (u64)cluster, 1);
1309 }
1310 
1311 
1312 /*
1313  * Allocate a block of memory with one bit for each cluster of the disk.
1314  * All the bits are set to 0, except those representing the region beyond the
1315  * end of the disk.
1316  */
1317 static void setup_lcn_bitmap(void)
1318 {
1319         /* Determine lcn bitmap byte size and allocate it. */
1320         lcn_bitmap.size = rounded_up_division(vol->nr_clusters, 8);
1321 
1322         lcn_bitmap.bm = ntfs_calloc(lcn_bitmap.size);
1323         if (!lcn_bitmap.bm)
1324                 perr_exit("Failed to allocate internal buffer");
1325 
1326         bitmap_file_data_fixup(vol->nr_clusters, &lcn_bitmap);
1327 }
1328 
1329 
1330 static s64 volume_size(ntfs_volume *volume, s64 nr_clusters)
1331 {
1332         return nr_clusters * volume->cluster_size;
1333 }
1334 
1335 
1336 static void print_volume_size(const char *str, s64 bytes)
1337 {
1338         Printf("%s: %lld bytes (%lld MB)\n", str, (long long)bytes,
1339                         (long long)rounded_up_division(bytes, NTFS_MBYTE));
1340 }
1341 
1342 
1343 static void print_disk_usage(const char *spacer, u32 cluster_size,
1344                 s64 nr_clusters, s64 inuse)
1345 {
1346         s64 total, used;
1347 
1348         total = nr_clusters * cluster_size;
1349         used = inuse * cluster_size;
1350 
1351         Printf("Space in use       %s: %lld MB (%.1f%%)   ", spacer,
1352                         (long long)rounded_up_division(used, NTFS_MBYTE),
1353                         100.0 * ((float)used / total));
1354 
1355         Printf("\n");
1356 }
1357 
1358 static void print_image_info(void)
1359 {
1360         Printf("Ntfsclone image version: %d.%d\n",
1361                         image_hdr.major_ver, image_hdr.minor_ver);
1362         Printf("Cluster size           : %u bytes\n",
1363                         (unsigned)le32_to_cpu(image_hdr.cluster_size));
1364         print_volume_size("Image volume size      ",
1365                         sle64_to_cpu(image_hdr.nr_clusters) *
1366                         le32_to_cpu(image_hdr.cluster_size));
1367         Printf("Image device size      : %lld bytes\n",
1368                         sle64_to_cpu(image_hdr.device_size));
1369         print_disk_usage("    ", le32_to_cpu(image_hdr.cluster_size),
1370                         sle64_to_cpu(image_hdr.nr_clusters),
1371                         sle64_to_cpu(image_hdr.inuse));
1372         Printf("Offset to image data   : %u (0x%x) bytes\n",
1373                         (unsigned)le32_to_cpu(image_hdr.offset_to_image_data),
1374                         (unsigned)le32_to_cpu(image_hdr.offset_to_image_data));
1375 }
1376 
1377 static void check_if_mounted(const char *device, unsigned long new_mntflag)
1378 {
1379         unsigned long mntflag;
1380 
1381         if (ntfs_check_if_mounted(device, &mntflag))
1382                 perr_exit("Failed to check '%s' mount state", device);
1383 
1384         if (mntflag & NTFS_MF_MOUNTED) {
1385                 if (!(mntflag & NTFS_MF_READONLY))
1386                         err_exit("Device '%s' is mounted read-write. "
1387                                  "You must 'umount' it first.\n", device);
1388                 if (!new_mntflag)
1389                         err_exit("Device '%s' is mounted. "
1390                                  "You must 'umount' it first.\n", device);
1391         }
1392 }
1393 
1394 /**
1395  * mount_volume -
1396  *
1397  * First perform some checks to determine if the volume is already mounted, or
1398  * is dirty (Windows wasn't shutdown properly).  If everything is OK, then mount
1399  * the volume (load the metadata into memory).
1400  */
1401 static void mount_volume(unsigned long new_mntflag)
1402 {
1403         check_if_mounted(opt.volume, new_mntflag);
1404 
1405         if (!(vol = ntfs_mount(opt.volume, new_mntflag))) {
1406 
1407                 int err = errno;
1408 
1409                 perr_printf("Opening '%s' as NTFS failed", opt.volume);
1410                 if (err == EINVAL) {
1411                         Printf("Apparently device '%s' doesn't have a "
1412                                "valid NTFS. Maybe you selected\nthe whole "
1413                                "disk instead of a partition (e.g. /dev/hda, "
1414                                "not /dev/hda1)?\n", opt.volume);
1415                 }
1416                 exit(1);
1417         }
1418 
1419         if (NVolWasDirty(vol))
1420                 if (opt.force-- <= 0)
1421                         err_exit(dirty_volume_msg, opt.volume);
1422 
1423         if (NTFS_MAX_CLUSTER_SIZE < vol->cluster_size)
1424                 err_exit("Cluster size %u is too large!\n",
1425                                 (unsigned int)vol->cluster_size);
1426 
1427         Printf("NTFS volume version: %d.%d\n", vol->major_ver, vol->minor_ver);
1428         if (ntfs_version_is_supported(vol))
1429                 perr_exit("Unknown NTFS version");
1430 
1431         Printf("Cluster size       : %u bytes\n",
1432                         (unsigned int)vol->cluster_size);
1433         print_volume_size("Current volume size",
1434                           volume_size(vol, vol->nr_clusters));
1435 }
1436 
1437 static struct ntfs_walk_cluster backup_clusters = { NULL, NULL };
1438 
1439 static int device_offset_valid(int fd, s64 ofs)
1440 {
1441         char ch;
1442 
1443         if (lseek(fd, ofs, SEEK_SET) >= 0 && read(fd, &ch, 1) == 1)
1444                 return 0;
1445         return -1;
1446 }
1447 
1448 static s64 device_size_get(int fd)
1449 {
1450         s64 high, low;
1451 #ifdef BLKGETSIZE64
1452         {       u64 size;
1453 
1454                 if (ioctl(fd, BLKGETSIZE64, &size) >= 0) {
1455                         ntfs_log_debug("BLKGETSIZE64 nr bytes = %llu "
1456                                 "(0x%llx).\n", (unsigned long long)size,
1457                                 (unsigned long long)size);
1458                         return (s64)size;
1459                 }
1460         }
1461 #endif
1462 #ifdef BLKGETSIZE
1463         {       unsigned long size;
1464 
1465                 if (ioctl(fd, BLKGETSIZE, &size) >= 0) {
1466                         ntfs_log_debug("BLKGETSIZE nr 512 byte blocks = %lu "
1467                                 "(0x%lx).\n", size, size);
1468                         return (s64)size * 512;
1469                 }
1470         }
1471 #endif
1472 #ifdef FDGETPRM
1473         {       struct floppy_struct this_floppy;
1474 
1475                 if (ioctl(fd, FDGETPRM, &this_floppy) >= 0) {
1476                         ntfs_log_debug("FDGETPRM nr 512 byte blocks = %lu "
1477                                 "(0x%lx).\n", this_floppy.size,
1478                                 this_floppy.size);
1479                         return (s64)this_floppy.size * 512;
1480                 }
1481         }
1482 #endif
1483         /*
1484          * We couldn't figure it out by using a specialized ioctl,
1485          * so do binary search to find the size of the device.
1486          */
1487         low = 0LL;
1488         for (high = 1024LL; !device_offset_valid(fd, high); high <<= 1)
1489                 low = high;
1490         while (low < high - 1LL) {
1491                 const s64 mid = (low + high) / 2;
1492 
1493                 if (!device_offset_valid(fd, mid))
1494                         low = mid;
1495                 else
1496                         high = mid;
1497         }
1498         lseek(fd, 0LL, SEEK_SET);
1499         return (low + 1LL);
1500 }
1501 
1502 static void fsync_clone(int fd)
1503 {
1504         Printf("Syncing ...\n");
1505         if (fsync(fd) && errno != EINVAL)
1506                 perr_exit("fsync");
1507 }
1508 
1509 static void set_filesize(s64 filesize)
1510 {
1511 
1512 #ifdef __sun
1513 
1514         if (fstatvfs(fd_out, &opt.stfs) == -1)
1515                 Printf("WARNING: Couldn't get filesystem type: "
1516                        "%s\n", strerror(errno));
1517 
1518         if (strcmp(opt.stfs.f_basetype, "pcfs") == 0)
1519                 Printf("WARNING: You're using PCFS, it does not support "
1520                         "sparse files so the next operation might take "
1521                         "a while. You should consider using the more "
1522                                "efficient --save-image option of ntfsclone. Use "
1523                                "the --restore-image option to restore the image.\n");
1524 
1525         if (ftruncate(fd_out, filesize) == -1) {
1526                 int err = errno;
1527                 perr_printf("ftruncate failed for file '%s'", opt.output);
1528                 Printf("Destination filesystem type is %s\n",
1529                                                 opt.stfs.f_basetype);
1530                 if (err == EFBIG || (err == EINVAL && filesize > 0))
1531                         Printf("Your system or the destination filesystem "
1532                                "doesn't support large files.\n");
1533                 exit(1);
1534         }
1535 
1536 #else /* !defined(__sun) */
1537 
1538         long fs_type = 0; /* Unknown filesystem type */
1539 
1540         if (fstatfs(fd_out, &opt.stfs) == -1)
1541                 Printf("WARNING: Couldn't get filesystem type: "
1542                        "%s\n", strerror(errno));
1543         else
1544                 fs_type = opt.stfs.f_type;
1545 
1546         if (fs_type == 0x52654973)
1547                 Printf("WARNING: You're using ReiserFS, it has very poor "
1548                        "performance creating\nlarge sparse files. The next "
1549                        "operation might take a very long time!\n"
1550                        "Creating sparse output file ...\n");
1551         else if (fs_type == 0x517b)
1552                 Printf("WARNING: You're using SMBFS and if the remote share "
1553                        "isn't Samba but a Windows\ncomputer then the clone "
1554                        "operation will be very inefficient and may fail!\n");
1555 
1556         if (ftruncate(fd_out, filesize) == -1) {
1557                 int err = errno;
1558                 perr_printf("ftruncate failed for file '%s'", opt.output);
1559                 if (fs_type)
1560                         Printf("Destination filesystem type is 0x%lx.\n",
1561                                (unsigned long)fs_type);
1562                 if (err == E2BIG) {
1563                         Printf("Your system or the destination filesystem "
1564                                "doesn't support large files.\n");
1565                         if (fs_type == 0x517b) {
1566                                 Printf("SMBFS needs minimum Linux kernel "
1567                                        "version 2.4.25 and\n the 'lfs' option"
1568                                        "\nfor smbmount to have large "
1569                                        "file support.\n");
1570                         }
1571                 } else if (err == EPERM) {
1572                         Printf("Apparently the destination filesystem doesn't "
1573                                "support sparse files.\nYou can overcome this "
1574                                "by using the more efficient --save-image "
1575                                "option\nof ntfsclone. Use the --restore-image "
1576                                "option to restore the image.\n");
1577                 }
1578                 exit(1);
1579         }
1580 
1581 #endif /* defined(__sun) */
1582 }
1583 
1584 static s64 open_image(void)
1585 {
1586         if (strcmp(opt.volume, "-") == 0) {
1587                 if ((fd_in = fileno(stdin)) == -1)
1588                         perr_exit("fileno for stdout failed");
1589         } else {
1590                 if ((fd_in = open(opt.volume, O_RDONLY)) == -1)
1591                         perr_exit("failed to open image");
1592         }
1593         if (read_all(&fd_in, &image_hdr, NTFSCLONE_IMG_HEADER_SIZE_OLD) == -1)
1594                 perr_exit("read_all");
1595         if (memcmp(image_hdr.magic, IMAGE_MAGIC, IMAGE_MAGIC_SIZE) != 0)
1596                 err_exit("Input file is not an image! (invalid magic)\n");
1597         if (image_hdr.major_ver < NTFSCLONE_IMG_VER_MAJOR_ENDIANNESS_SAFE) {
1598                 image_hdr.major_ver = NTFSCLONE_IMG_VER_MAJOR;
1599                 image_hdr.minor_ver = NTFSCLONE_IMG_VER_MINOR;
1600 #if (__BYTE_ORDER == __BIG_ENDIAN)
1601                 Printf("Old image format detected.  If the image was created "
1602                                 "on a little endian architecture it will not "
1603                                 "work.  Use a more recent version of "
1604                                 "ntfsclone to recreate the image.\n");
1605                 image_hdr.cluster_size = cpu_to_le32(image_hdr.cluster_size);
1606                 image_hdr.device_size = cpu_to_sle64(image_hdr.device_size);
1607                 image_hdr.nr_clusters = cpu_to_sle64(image_hdr.nr_clusters);
1608                 image_hdr.inuse = cpu_to_sle64(image_hdr.inuse);
1609 #endif
1610                 image_hdr.offset_to_image_data =
1611                                 const_cpu_to_le32((sizeof(image_hdr) + 7) & ~7);
1612                 image_is_host_endian = TRUE;
1613         } else {
1614 #ifdef __sun
1615                 u32 offset_to_image_data;
1616 #else
1617                 typeof(image_hdr.offset_to_image_data) offset_to_image_data;
1618 #endif
1619                 int delta;
1620 
1621                 if (image_hdr.major_ver > NTFSCLONE_IMG_VER_MAJOR)
1622                         err_exit("Do not know how to handle image format "
1623                                         "version %d.%d.  Please obtain a "
1624                                         "newer version of ntfsclone.\n",
1625                                         image_hdr.major_ver,
1626                                         image_hdr.minor_ver);
1627                 /* Read the image header data offset. */
1628                 if (read_all(&fd_in, &offset_to_image_data,
1629                                 sizeof(offset_to_image_data)) == -1)
1630                         perr_exit("read_all");
1631                 image_hdr.offset_to_image_data =
1632                                 le32_to_cpu(offset_to_image_data);
1633                 /*
1634                  * Read any fields from the header that we have not read yet so
1635                  * that the input stream is positioned correctly.  This means
1636                  * we can support future minor versions that just extend the
1637                  * header in a backwards compatible way.
1638                  */
1639                 delta = offset_to_image_data - (NTFSCLONE_IMG_HEADER_SIZE_OLD +
1640                                 sizeof(image_hdr.offset_to_image_data));
1641                 if (delta > 0) {
1642                         char *dummy_buf;
1643 
1644                         dummy_buf = malloc(delta);
1645                         if (!dummy_buf)
1646                                 perr_exit("malloc dummy_buffer");
1647                         if (read_all(&fd_in, dummy_buf, delta) == -1)
1648                                 perr_exit("read_all");
1649                 }
1650         }
1651         return sle64_to_cpu(image_hdr.device_size);
1652 }
1653 
1654 static s64 open_volume(void)
1655 {
1656         s64 device_size;
1657 
1658         mount_volume(NTFS_MNT_RDONLY);
1659 
1660         device_size = ntfs_device_size_get(vol->u.dev, 1);
1661         if (device_size <= 0)
1662                 err_exit("Couldn't get device size (%lld)!\n", device_size);
1663 
1664         print_volume_size("Current device size", device_size);
1665 
1666         if (device_size < vol->nr_clusters * vol->cluster_size)
1667                 err_exit("Current NTFS volume size is bigger than the device "
1668                          "size (%lld)!\nCorrupt partition table or incorrect "
1669                          "device partitioning?\n", device_size);
1670 
1671         return device_size;
1672 }
1673 
1674 static void initialise_image_hdr(s64 device_size, s64 inuse)
1675 {
1676         memcpy(image_hdr.magic, IMAGE_MAGIC, IMAGE_MAGIC_SIZE);
1677         image_hdr.major_ver = NTFSCLONE_IMG_VER_MAJOR;
1678         image_hdr.minor_ver = NTFSCLONE_IMG_VER_MINOR;
1679         image_hdr.cluster_size = cpu_to_le32(vol->cluster_size);
1680         image_hdr.device_size = cpu_to_sle64(device_size);
1681         image_hdr.nr_clusters = cpu_to_sle64(vol->nr_clusters);
1682         image_hdr.inuse = cpu_to_sle64(inuse);
1683         image_hdr.offset_to_image_data = cpu_to_le32((sizeof(image_hdr) + 7) &
1684                         ~7);
1685 }
1686 
1687 static void check_output_device(s64 input_size)
1688 {
1689         if (opt.blkdev_out) {
1690                 s64 dest_size = device_size_get(fd_out);
1691                 if (dest_size < input_size)
1692                         err_exit("Output device is too small (%lld) to fit the "
1693                                  "NTFS image (%lld).\n", dest_size, input_size);
1694 
1695                 check_if_mounted(opt.output, 0);
1696         } else
1697                 set_filesize(input_size);
1698 }
1699 
1700 static ntfs_attr_search_ctx *attr_get_search_ctx(ntfs_inode *ni)
1701 {
1702         ntfs_attr_search_ctx *ret;
1703 
1704         if ((ret = ntfs_attr_get_search_ctx(ni, NULL)) == NULL)
1705                 perr_printf("ntfs_attr_get_search_ctx");
1706 
1707         return ret;
1708 }
1709 
1710 /**
1711  * lookup_data_attr
1712  *
1713  * Find the $DATA attribute (with or without a name) for the given ntfs inode.
1714  */
1715 static ntfs_attr_search_ctx *lookup_data_attr(ntfs_inode *ni, const char *aname)
1716 {
1717         ntfs_attr_search_ctx *ctx;
1718         ntfschar *ustr;
1719         int len = 0;
1720 
1721         if ((ctx = attr_get_search_ctx(ni)) == NULL)
1722                 return NULL;
1723 
1724         if ((ustr = ntfs_str2ucs(aname, &len)) == NULL) {
1725                 perr_printf("Couldn't convert '%s' to Unicode", aname);
1726                 goto error_out;
1727         }
1728 
1729         if (ntfs_attr_lookup(AT_DATA, ustr, len, 0, 0, NULL, 0, ctx)) {
1730                 perr_printf("ntfs_attr_lookup");
1731                 goto error_out;
1732         }
1733         ntfs_ucsfree(ustr);
1734         return ctx;
1735 error_out:
1736         ntfs_attr_put_search_ctx(ctx);
1737         return NULL;
1738 }
1739 
1740 static void ignore_bad_clusters(ntfs_walk_clusters_ctx *image)
1741 {
1742         ntfs_inode *ni;
1743         ntfs_attr_search_ctx *ctx = NULL;
1744         runlist *rl, *rl_bad;
1745         s64 nr_bad_clusters = 0;
1746 
1747         if (!(ni = ntfs_inode_open(vol, FILE_BadClus)))
1748                 perr_exit("ntfs_open_inode");
1749 
1750         if ((ctx = lookup_data_attr(ni, "$Bad")) == NULL)
1751                 exit(1);
1752 
1753         if (!(rl_bad = ntfs_mapping_pairs_decompress(vol, ctx->attr, NULL)))
1754                 perr_exit("ntfs_mapping_pairs_decompress");
1755 
1756         for (rl = rl_bad; rl->length; rl++) {
1757                 s64 lcn = rl->lcn;
1758 
1759                 if (lcn == LCN_HOLE || lcn < 0)
1760                         continue;
1761 
1762                 for (; lcn < rl->lcn + rl->length; lcn++, nr_bad_clusters++) {
1763                         if (ntfs_bit_get_and_set(lcn_bitmap.bm, lcn, 0))
1764                                 image->inuse--;
1765                 }
1766         }
1767         if (nr_bad_clusters)
1768                 Printf("WARNING: The disk has %lld or more bad sectors"
1769                        " (hardware faults).\n", nr_bad_clusters);
1770         free(rl_bad);
1771 
1772         ntfs_attr_put_search_ctx(ctx);
1773         if (ntfs_inode_close(ni))
1774                 perr_exit("ntfs_inode_close failed for $BadClus");
1775 }
1776 
1777 static void check_dest_free_space(u64 src_bytes)
1778 {
1779         u64 dest_bytes;
1780         struct statvfs stvfs;
1781         struct stat st;
1782 
1783         if (opt.metadata || opt.blkdev_out || opt.std_out)
1784                 return;
1785         /*
1786          * TODO: save_image needs a bit more space than src_bytes
1787          * due to the free space encoding overhead.
1788          */
1789         if (fstatvfs(fd_out, &stvfs) == -1) {
1790                 Printf("WARNING: Unknown free space on the destination: %s\n",
1791                        strerror(errno));
1792                 return;
1793         }
1794         
1795         /* If file is a FIFO then there is no point in checking the size. */
1796         if (!fstat(fd_out, &st)) {
1797                 if (S_ISFIFO(st.st_mode))
1798                         return;
1799         } else
1800                 Printf("WARNING: fstat failed: %s\n", strerror(errno));
1801 
1802         dest_bytes = (u64)stvfs.f_frsize * stvfs.f_bfree;
1803         if (!dest_bytes)
1804                 dest_bytes = (u64)stvfs.f_bsize * stvfs.f_bfree;
1805 
1806         if (dest_bytes < src_bytes)
1807                 err_exit("Destination doesn't have enough free space: "
1808                          "%llu MB < %llu MB\n",
1809                          rounded_up_division(dest_bytes, NTFS_MBYTE),
1810                          rounded_up_division(src_bytes,  NTFS_MBYTE));
1811 }
1812 
1813 int main(int argc, char **argv)
1814 {
1815         ntfs_walk_clusters_ctx image;
1816         s64 device_size;        /* input device size in bytes */
1817         s64 ntfs_size;
1818         unsigned int wiped_total = 0;
1819 
1820         /* print to stderr, stdout can be an NTFS image ... */
1821         fprintf(stderr, "%s v%s (libntfs %s)\n", EXEC_NAME, VERSION,
1822                 ntfs_libntfs_version());
1823         msg_out = stderr;
1824 
1825         parse_options(argc, argv);
1826 
1827         utils_set_locale();
1828 
1829         if (opt.restore_image) {
1830                 device_size = open_image();
1831                 ntfs_size = sle64_to_cpu(image_hdr.nr_clusters) *
1832                                 le32_to_cpu(image_hdr.cluster_size);
1833         } else {
1834                 device_size = open_volume();
1835                 ntfs_size = vol->nr_clusters * vol->cluster_size;
1836         }
1837         // FIXME: This needs to be the cluster size...
1838         ntfs_size += 512; /* add backup boot sector */
1839 
1840         if (opt.std_out) {
1841                 if ((fd_out = fileno(stdout)) == -1)
1842                         perr_exit("fileno for stdout failed");
1843         } else {
1844                 /* device_size_get() might need to read() */
1845                 int flags = O_RDWR;
1846 
1847                 if (!opt.blkdev_out) {
1848                         flags |= O_CREAT | O_TRUNC;
1849                         if (!opt.overwrite)
1850                                 flags |= O_EXCL;
1851                 }
1852 
1853                 if ((fd_out = open(opt.output, flags, S_IRUSR | S_IWUSR)) == -1)
1854                         perr_exit("Opening file '%s' failed", opt.output);
1855 
1856                 if (!opt.save_image)
1857                         check_output_device(ntfs_size);
1858         }
1859 
1860         if (opt.restore_image) {
1861                 print_image_info();
1862                 restore_image();
1863                 fsync_clone(fd_out);
1864                 exit(0);
1865         }
1866 
1867         setup_lcn_bitmap();
1868         memset(&image, 0, sizeof(image));
1869         backup_clusters.image = &image;
1870 
1871         walk_clusters(vol, &backup_clusters);
1872         compare_bitmaps(&lcn_bitmap);
1873         print_disk_usage("", vol->cluster_size, vol->nr_clusters, image.inuse);
1874 
1875         check_dest_free_space(vol->cluster_size * image.inuse);
1876 
1877         ignore_bad_clusters(&image);
1878 
1879         if (opt.save_image)
1880                 initialise_image_hdr(device_size, image.inuse);
1881 
1882         /* FIXME: save backup boot sector */
1883 
1884         if (opt.std_out || !opt.metadata) {
1885                 s64 nr_clusters_to_save = image.inuse;
1886                 if (opt.std_out && !opt.save_image)
1887                         nr_clusters_to_save = vol->nr_clusters;
1888 
1889                 clone_ntfs(nr_clusters_to_save);
1890                 fsync_clone(fd_out);
1891                 exit(0);
1892         }
1893 
1894         wipe = 1;
1895         opt.volume = opt.output;
1896         /* 'force' again mount for dirty volumes (e.g. after resize).
1897            FIXME: use mount flags to avoid potential side-effects in future */
1898         opt.force++;
1899         mount_volume(0);
1900 
1901         free(lcn_bitmap.bm);
1902         setup_lcn_bitmap();
1903         memset(&image, 0, sizeof(image));
1904         backup_clusters.image = &image;
1905 
1906         walk_clusters(vol, &backup_clusters);
1907 
1908         Printf("Num of MFT records       = %10lld\n",
1909                         (long long)vol->mft_na->initialized_size >>
1910                         vol->mft_record_size_bits);
1911         Printf("Num of used MFT records  = %10u\n", nr_used_mft_records);
1912 
1913         Printf("Wiped unused MFT data    = %10u\n", wiped_unused_mft_data);
1914         Printf("Wiped deleted MFT data   = %10u\n", wiped_unused_mft);
1915         Printf("Wiped resident user data = %10u\n", wiped_resident_data);
1916         Printf("Wiped timestamp data     = %10u\n", wiped_timestamp_data);
1917 
1918         wiped_total += wiped_unused_mft_data;
1919         wiped_total += wiped_unused_mft;
1920         wiped_total += wiped_resident_data;
1921         wiped_total += wiped_timestamp_data;
1922         Printf("Wiped totally            = %10u\n", wiped_total);
1923 
1924         fsync_clone(fd_out);
1925         exit(0);
1926 }