summaryrefslogtreecommitdiff
path: root/ntfsprogs/ntfsclone.c (plain)
blob: 967dd95f2eef42634f7bf3438247681f6ed6875c
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 * Copyright (c) 2010-2013 Jean-Pierre Andre
7 * Special image format support copyright (c) 2004 Per Olofsson
8 *
9 * Clone NTFS data and/or metadata to a sparse file, image, device or stdout.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17#include "config.h"
18
19#ifdef HAVE_UNISTD_H
20#include <unistd.h>
21#endif
22#ifdef HAVE_STDLIB_H
23#include <stdlib.h>
24#endif
25#ifdef HAVE_STDIO_H
26#include <stdio.h>
27#endif
28#ifdef HAVE_SYS_TYPES_H
29#include <sys/types.h>
30#endif
31#ifdef HAVE_SYS_STAT_H
32#include <sys/stat.h>
33#endif
34#ifdef HAVE_TIME_H
35#include <time.h>
36#endif
37#ifdef HAVE_SYS_IOCTL_H
38#include <sys/ioctl.h>
39#endif
40#ifdef HAVE_SYS_VFS_H
41#include <sys/vfs.h>
42#endif
43#ifdef HAVE_SYS_STATVFS_H
44#include <sys/statvfs.h>
45#endif
46#ifdef HAVE_FCNTL_H
47#include <fcntl.h>
48#endif
49#ifdef HAVE_STDARG_H
50#include <stdarg.h>
51#endif
52#ifdef HAVE_STRING_H
53#include <string.h>
54#endif
55#ifdef HAVE_ERRNO_H
56#include <errno.h>
57#endif
58#ifdef HAVE_GETOPT_H
59#include <getopt.h>
60#endif
61#ifdef HAVE_UNISTD_H
62#include <unistd.h>
63#endif
64
65/*
66 * FIXME: ntfsclone do bad things about endians handling. Fix it and remove
67 * this note and define.
68 */
69#define NTFS_DO_NOT_CHECK_ENDIANS
70
71#include "debug.h"
72#include "types.h"
73#include "support.h"
74#include "endians.h"
75#include "bootsect.h"
76#include "device.h"
77#include "attrib.h"
78#include "mst.h"
79#include "volume.h"
80#include "mft.h"
81#include "bitmap.h"
82#include "inode.h"
83#include "index.h"
84#include "dir.h"
85#include "runlist.h"
86#include "ntfstime.h"
87#include "utils.h"
88/* #include "version.h" */
89#include "misc.h"
90
91#if defined(linux) && defined(_IO) && !defined(BLKGETSIZE)
92#define BLKGETSIZE _IO(0x12,96) /* Get device size in 512-byte blocks. */
93#endif
94#if defined(linux) && defined(_IOR) && !defined(BLKGETSIZE64)
95#define BLKGETSIZE64 _IOR(0x12,114,size_t) /* Get device size in bytes. */
96#endif
97
98#if defined(linux) || defined(__uClinux__) || defined(__sun) \
99 || defined(__APPLE__) || defined(__DARWIN__)
100 /* Make sure the presence of <windows.h> means compiling for Windows */
101#undef HAVE_WINDOWS_H
102#endif
103
104#if defined(__sun) | defined(HAVE_WINDOWS_H)
105#define NO_STATFS 1 /* statfs(2) and f_type are not universal */
106#endif
107
108#ifdef HAVE_WINDOWS_H
109/*
110 * Replacements for functions which do not exist on Windows
111 */
112int setmode(int, int); /* from msvcrt.dll */
113
114#define getpid() (0)
115#define srandom(seed) srand(seed)
116#define random() rand()
117#define fsync(fd) (0)
118#define ioctl(fd,code,buf) (0)
119#define ftruncate(fd, size) ntfs_device_win32_ftruncate(dev_out, size)
120#define BINWMODE "wb"
121#else
122#define BINWMODE "w"
123#endif
124
125#ifndef O_BINARY
126#define O_BINARY 0
127#endif
128
129static const char *EXEC_NAME = "ntfsclone";
130
131static const char *bad_sectors_warning_msg =
132"*************************************************************************\n"
133"* WARNING: The disk has one or more bad sectors. This means that damage *\n"
134"* has occurred on the disk surface, possibly caused by deterioration of *\n"
135"* the physical media, manufacturing faults or other reasons. The *\n"
136"* reliability of the disk may stay stable or degrade fast. *\n"
137"* Use the --rescue option to efficiently save as much data as possible! *\n"
138"*************************************************************************\n";
139
140static const char *dirty_volume_msg =
141"Volume '%s' is scheduled for a check or it was shutdown \n"
142"uncleanly. Please boot Windows or use the --force option to progress.\n";
143
144static struct {
145 int verbose;
146 int quiet;
147 int debug;
148 int force;
149 int overwrite;
150 int std_out;
151 int blkdev_out; /* output file is block device */
152 int metadata; /* metadata only cloning */
153 int no_action; /* do not really restore */
154 int ignore_fs_check;
155 int rescue;
156 int save_image;
157 int new_serial;
158 int metadata_image;
159 int preserve_timestamps;
160 int restore_image;
161 char *output;
162 char *volume;
163#ifndef NO_STATFS
164 struct statfs stfs;
165#endif
166} opt;
167
168struct bitmap {
169 s64 size;
170 u8 *bm;
171};
172
173struct progress_bar {
174 u64 start;
175 u64 stop;
176 int resolution;
177 float unit;
178};
179
180typedef struct {
181 ntfs_inode *ni; /* inode being processed */
182 ntfs_attr_search_ctx *ctx; /* inode attribute being processed */
183 s64 inuse; /* number of clusters in use */
184 int more_use; /* possibly allocated clusters */
185 LCN current_lcn;
186} ntfs_walk_clusters_ctx;
187
188typedef int (ntfs_walk_op)(ntfs_inode *ni, void *data);
189
190struct ntfs_walk_cluster {
191 ntfs_walk_op *inode_op; /* not implemented yet */
192 ntfs_walk_clusters_ctx *image;
193};
194
195
196static ntfs_volume *vol = NULL;
197static struct bitmap lcn_bitmap;
198
199static int fd_in;
200static int fd_out;
201static FILE *stream_out = (FILE*)NULL;
202struct ntfs_device *dev_out = (struct ntfs_device*)NULL;
203static FILE *msg_out = NULL;
204
205static int wipe = 0;
206static unsigned int nr_used_mft_records = 0;
207static unsigned int wiped_unused_mft_data = 0;
208static unsigned int wiped_unused_mft = 0;
209static unsigned int wiped_resident_data = 0;
210static unsigned int wiped_timestamp_data = 0;
211
212static le64 volume_serial_number; /* new random serial number */
213static u64 full_device_size; /* full size, including the backup boot sector */
214
215static BOOL image_is_host_endian = FALSE;
216
217#define IMAGE_MAGIC "\0ntfsclone-image"
218#define IMAGE_MAGIC_SIZE 16
219#define IMAGE_OFFSET_OFFSET 46 /* must be the same for all versions ! */
220#define IMAGE_HDR_ALIGN 8 /* alignment wanted after header */
221
222/* This is the first endianness safe format version. */
223#define NTFSCLONE_IMG_VER_MAJOR_ENDIANNESS_SAFE 10
224#define NTFSCLONE_IMG_VER_MINOR_ENDIANNESS_SAFE 0
225
226/*
227 * Set the version to 10.0 to avoid colisions with old ntfsclone which
228 * stupidly used the volume version as the image version... )-: I hope NTFS
229 * never reaches version 10.0 and if it does one day I hope no-one is using
230 * such an old ntfsclone by then...
231 *
232 * NOTE: Only bump the minor version if the image format and header are still
233 * backwards compatible. Otherwise always bump the major version. If in
234 * doubt, bump the major version.
235 *
236 * Moved to 10.1 : Alternate boot sector now saved. Still compatible.
237 */
238#define NTFSCLONE_IMG_VER_MAJOR 10
239#define NTFSCLONE_IMG_VER_MINOR 1
240
241enum { CMD_GAP, CMD_NEXT } ;
242
243/* All values are in little endian. */
244static struct image_hdr {
245 char magic[IMAGE_MAGIC_SIZE];
246 u8 major_ver;
247 u8 minor_ver;
248 /* the following is aligned dangerously (too late...) */
249 le32 cluster_size;
250 le64 device_size;
251 sle64 nr_clusters;
252 le64 inuse;
253 le32 offset_to_image_data; /* From start of image_hdr. */
254} __attribute__((__packed__)) image_hdr;
255
256static int compare_bitmaps(struct bitmap *a, BOOL copy);
257
258#define NTFSCLONE_IMG_HEADER_SIZE_OLD \
259 (offsetof(struct image_hdr, offset_to_image_data))
260
261#define NTFS_MBYTE (1000 * 1000)
262
263#define ERR_PREFIX "ERROR"
264#define PERR_PREFIX ERR_PREFIX "(%d): "
265#define NERR_PREFIX ERR_PREFIX ": "
266
267#define LAST_METADATA_INODE 11
268
269#define NTFS_MAX_CLUSTER_SIZE 65536
270#define NTFS_SECTOR_SIZE 512
271
272#define rounded_up_division(a, b) (((a) + (b - 1)) / (b))
273
274#define read_all(f, p, n) io_all((f), (p), (n), 0)
275#define write_all(f, p, n) io_all((f), (p), (n), 1)
276
277__attribute__((format(printf, 1, 2)))
278static void Printf(const char *fmt, ...)
279{
280 va_list ap;
281
282 va_start(ap, fmt);
283 vfprintf(msg_out, fmt, ap);
284 va_end(ap);
285 fflush(msg_out);
286}
287
288__attribute__((format(printf, 1, 2)))
289static void perr_printf(const char *fmt, ...)
290{
291 va_list ap;
292 int eo = errno;
293
294 Printf(PERR_PREFIX, eo);
295 va_start(ap, fmt);
296 vfprintf(msg_out, fmt, ap);
297 va_end(ap);
298 Printf(": %s\n", strerror(eo));
299 fflush(msg_out);
300}
301
302__attribute__((format(printf, 1, 2)))
303static void err_printf(const char *fmt, ...)
304{
305 va_list ap;
306
307 Printf(NERR_PREFIX);
308 va_start(ap, fmt);
309 vfprintf(msg_out, fmt, ap);
310 va_end(ap);
311 fflush(msg_out);
312}
313
314__attribute__((noreturn))
315__attribute__((format(printf, 1, 2)))
316static void err_exit(const char *fmt, ...)
317{
318 va_list ap;
319
320 Printf(NERR_PREFIX);
321 va_start(ap, fmt);
322 vfprintf(msg_out, fmt, ap);
323 va_end(ap);
324 fflush(msg_out);
325 if (vol)
326 ntfs_umount(vol,FALSE);
327 exit(1);
328}
329
330__attribute__((noreturn))
331__attribute__((format(printf, 1, 2)))
332static void perr_exit(const char *fmt, ...)
333{
334 va_list ap;
335 int eo = errno;
336
337 Printf(PERR_PREFIX, eo);
338 va_start(ap, fmt);
339 vfprintf(msg_out, fmt, ap);
340 va_end(ap);
341 Printf(": %s\n", strerror(eo));
342 fflush(msg_out);
343 if (vol)
344 ntfs_umount(vol,FALSE);
345 exit(1);
346}
347
348
349__attribute__((noreturn))
350static void usage(void)
351{
352 fprintf(stderr, "\nUsage: %s [OPTIONS] SOURCE\n"
353 " Efficiently clone NTFS to a sparse file, image, device or standard output.\n"
354 "\n"
355 " -o, --output FILE Clone NTFS to the non-existent FILE\n"
356 " -O, --overwrite FILE Clone NTFS to FILE, overwriting if exists\n"
357 " -s, --save-image Save to the special image format\n"
358 " -r, --restore-image Restore from the special image format\n"
359 " --rescue Continue after disk read errors\n"
360 " -m, --metadata Clone *only* metadata (for NTFS experts)\n"
361 " -n, --no-action Test restoring, without outputting anything\n"
362 " --ignore-fs-check Ignore the filesystem check result\n"
363 " --new-serial Set a new serial number\n"
364 " --new-half-serial Set a partial new serial number\n"
365 " -t, --preserve-timestamps Do not clear the timestamps\n"
366 " -q, --quiet Do not display any progress bars\n"
367 " -f, --force Force to progress (DANGEROUS)\n"
368 " -h, --help Display this help\n"
369#ifdef DEBUG
370 " -d, --debug Show debug information\n"
371#endif
372 "\n"
373 " If FILE is '-' then send the image to the standard output. If SOURCE is '-'\n"
374 " and --restore-image is used then read the image from the standard input.\n"
375 "\n", EXEC_NAME);
376 fprintf(stderr, "%s%s", ntfs_bugs, ntfs_home);
377 exit(1);
378}
379
380static void parse_options(int argc, char **argv)
381{
382 static const char *sopt = "-dfhmno:O:qrst";
383 static const struct option lopt[] = {
384#ifdef DEBUG
385 { "debug", no_argument, NULL, 'd' },
386#endif
387 { "quiet", no_argument, NULL, 'q' },
388 { "force", no_argument, NULL, 'f' },
389 { "help", no_argument, NULL, 'h' },
390 { "metadata", no_argument, NULL, 'm' },
391 { "no-action", no_argument, NULL, 'n' },
392 { "output", required_argument, NULL, 'o' },
393 { "overwrite", required_argument, NULL, 'O' },
394 { "restore-image", no_argument, NULL, 'r' },
395 { "ignore-fs-check", no_argument, NULL, 'C' },
396 { "rescue", no_argument, NULL, 'R' },
397 { "new-serial", no_argument, NULL, 'I' },
398 { "new-half-serial", no_argument, NULL, 'i' },
399 { "save-image", no_argument, NULL, 's' },
400 { "preserve-timestamps", no_argument, NULL, 't' },
401 { NULL, 0, NULL, 0 }
402 };
403
404 int c;
405
406 memset(&opt, 0, sizeof(opt));
407
408 while ((c = getopt_long(argc, argv, sopt, lopt, NULL)) != -1) {
409 switch (c) {
410 case 1: /* A non-option argument */
411 if (opt.volume)
412 usage();
413 opt.volume = argv[optind-1];
414 break;
415 case 'd':
416 opt.debug++;
417 break;
418 case 'q':
419 opt.quiet++;
420 break;
421 case 'f':
422 opt.force++;
423 break;
424 case 'h':
425 case '?':
426 usage();
427 case 'i': /* not proposed as a short option */
428 opt.new_serial |= 1;
429 break;
430 case 'I': /* not proposed as a short option */
431 opt.new_serial |= 2;
432 break;
433 case 'm':
434 opt.metadata++;
435 break;
436 case 'n':
437 opt.no_action++;
438 break;
439 case 'O':
440 opt.overwrite++;
441 case 'o':
442 if (opt.output)
443 usage();
444 opt.output = optarg;
445 break;
446 case 'r':
447 opt.restore_image++;
448 break;
449 case 'C':
450 opt.ignore_fs_check++;
451 break;
452 case 'R':
453 opt.rescue++;
454 break;
455 case 's':
456 opt.save_image++;
457 break;
458 case 't':
459 opt.preserve_timestamps++;
460 break;
461 default:
462 err_printf("Unknown option '%s'.\n", argv[optind-1]);
463 usage();
464 }
465 }
466
467 if (!opt.no_action && (opt.output == NULL)) {
468 err_printf("You must specify an output file.\n");
469 usage();
470 }
471
472 if (!opt.no_action && (strcmp(opt.output, "-") == 0))
473 opt.std_out++;
474
475 if (opt.volume == NULL) {
476 err_printf("You must specify a device file.\n");
477 usage();
478 }
479
480 if (!opt.restore_image && !strcmp(opt.volume, "-")) {
481 err_printf("Only special images can be read from standard input\n");
482 usage();
483 }
484
485 if (opt.metadata && opt.save_image) {
486 opt.metadata_image++;
487 opt.save_image = 0;
488 }
489
490 if (opt.metadata && opt.restore_image)
491 err_exit("Restoring only metadata from an image is not "
492 "supported!\n");
493
494 if (opt.metadata && !opt.metadata_image && opt.std_out)
495 err_exit("Cloning only metadata to stdout isn't supported!\n");
496
497 if (opt.ignore_fs_check && !opt.metadata && !opt.rescue)
498 err_exit("Filesystem check can be ignored only for metadata "
499 "cloning or rescue situations!\n");
500
501 if (opt.save_image && opt.restore_image)
502 err_exit("Saving and restoring an image at the same time "
503 "is not supported!\n");
504
505 if (opt.no_action && !opt.restore_image)
506 err_exit("A restoring test requires the restore option!\n");
507
508 if (opt.no_action && opt.output)
509 err_exit("A restoring test requires not defining any output!\n");
510
511 if (!opt.no_action && !opt.std_out) {
512 struct stat st;
513#ifdef HAVE_WINDOWS_H
514 BOOL blkdev = opt.output[0] && (opt.output[1] == ':')
515 && !opt.output[2];
516
517 if (!blkdev && (stat(opt.output, &st) == -1)) {
518#else
519 if (stat(opt.output, &st) == -1) {
520#endif
521 if (errno != ENOENT)
522 perr_exit("Couldn't access '%s'", opt.output);
523 } else {
524 if (!opt.overwrite)
525 err_exit("Output file '%s' already exists.\n"
526 "Use option --overwrite if you want to"
527 " replace its content.\n", opt.output);
528
529#ifdef HAVE_WINDOWS_H
530 if (blkdev) {
531#else
532 if (S_ISBLK(st.st_mode)) {
533#endif
534 opt.blkdev_out = 1;
535 if (opt.metadata && !opt.force)
536 err_exit("Cloning only metadata to a "
537 "block device does not usually "
538 "make sense, aborting...\n"
539 "If you were instructed to do "
540 "this by a developer and/or are "
541 "sure that this is what you want "
542 "to do, run this utility again "
543 "but this time add the force "
544 "option, i.e. add '--force' to "
545 "the command line arguments.");
546 }
547 }
548 }
549
550 /*
551 * Send messages, debug information and library messages to stdout,
552 * but, if outputing to stdout send them to stderr
553 */
554 if (opt.std_out) {
555 msg_out = stderr;
556 ntfs_log_set_handler(ntfs_log_handler_stderr);
557 } else {
558 msg_out = stdout;
559 ntfs_log_set_handler(ntfs_log_handler_outerr);
560 }
561}
562
563/*
564 * Initialize the random number generator with the current
565 * time, and generate a 64-bit random number for the serial
566 * number
567 */
568static void generate_serial_number(void) {
569 u64 sn;
570
571 /* different values for parallel processes */
572 srandom(time((time_t*)NULL) ^ (getpid() << 16));
573 sn = ((u64)random() << 32) | ((u64)random() & 0xffffffff);
574 volume_serial_number = cpu_to_le64(sn);
575}
576
577static void progress_init(struct progress_bar *p, u64 start, u64 stop, int res)
578{
579 p->start = start;
580 p->stop = stop;
581 p->unit = 100.0 / (stop - start);
582 p->resolution = res;
583}
584
585
586static void progress_update(struct progress_bar *p, u64 current)
587{
588 float percent = p->unit * current;
589
590 if (opt.quiet)
591 return;
592
593 if (current != p->stop) {
594 if ((current - p->start) % p->resolution)
595 return;
596 Printf("%6.2f percent completed\r", percent);
597 } else
598 Printf("100.00 percent completed\n");
599 fflush(msg_out);
600}
601
602static s64 is_critical_metadata(ntfs_walk_clusters_ctx *image, runlist *rl)
603{
604 s64 inode = image->ni->mft_no;
605
606 if (inode <= LAST_METADATA_INODE) {
607
608 /* Don't save bad sectors (both $Bad and unnamed are ignored */
609 if (inode == FILE_BadClus && image->ctx->attr->type == AT_DATA)
610 return 0;
611
612 if (inode != FILE_LogFile)
613 return rl->length;
614
615 if (image->ctx->attr->type == AT_DATA) {
616
617 /* Save at least the first 16 KiB of FILE_LogFile */
618 s64 s = (s64)16384 - rl->vcn * vol->cluster_size;
619 if (s > 0) {
620 s = rounded_up_division(s, vol->cluster_size);
621 if (rl->length < s)
622 s = rl->length;
623 return s;
624 }
625 return 0;
626 }
627 }
628
629 if (image->ctx->attr->type != AT_DATA)
630 return rl->length;
631
632 return 0;
633}
634
635static off_t tellin(int in)
636{
637 return (lseek(in, 0, SEEK_CUR));
638}
639
640static int io_all(void *fd, void *buf, int count, int do_write)
641{
642 int i;
643 struct ntfs_device *dev = fd;
644
645 while (count > 0) {
646 if (do_write) {
647 if (opt.no_action) {
648 i = count;
649 } else {
650 if (opt.save_image || opt.metadata_image)
651 i = fwrite(buf, 1, count, stream_out);
652#ifdef HAVE_WINDOWS_H
653 else if (dev_out)
654 i = dev_out->d_ops->write(dev_out,
655 buf, count);
656#endif
657 else
658 i = write(*(int *)fd, buf, count);
659 }
660 } else if (opt.restore_image)
661 i = read(*(int *)fd, buf, count);
662 else
663 i = dev->d_ops->read(dev, buf, count);
664 if (i < 0) {
665 if (errno != EAGAIN && errno != EINTR)
666 return -1;
667 } else if (i == 0 && !do_write && opt.restore_image) {
668 return -1;
669 } else {
670 count -= i;
671 buf = i + (char *) buf;
672 }
673 }
674 return 0;
675}
676
677
678static void rescue_sector(void *fd, u32 bytes_per_sector, off_t pos, void *buff)
679{
680 const char badsector_magic[] = "BadSectoR";
681 struct ntfs_device *dev = fd;
682
683 if (opt.restore_image) {
684 if (!opt.no_action
685 && (lseek(*(int *)fd, pos, SEEK_SET) == (off_t)-1))
686 perr_exit("lseek");
687 } else {
688 if (vol->dev->d_ops->seek(dev, pos, SEEK_SET) == (off_t)-1)
689 perr_exit("seek input");
690 }
691
692 if (read_all(fd, buff, bytes_per_sector) == -1) {
693 Printf("WARNING: Can't read sector at %llu, lost data.\n",
694 (unsigned long long)pos);
695 memset(buff, '?', bytes_per_sector);
696 memmove(buff, badsector_magic, sizeof(badsector_magic));
697 }
698}
699
700/*
701 * Read a cluster, try to rescue if cannot read
702 */
703
704static void read_rescue(void *fd, char *buff, u32 csize, u32 bytes_per_sector,
705 u64 rescue_lcn)
706{
707 off_t rescue_pos;
708
709 if (read_all(fd, buff, csize) == -1) {
710
711 if (errno != EIO)
712 perr_exit("read_all");
713 else if (opt.rescue){
714 u32 i;
715
716 rescue_pos = (off_t)(rescue_lcn * csize);
717 for (i = 0; i < csize; i += bytes_per_sector)
718 rescue_sector(fd, bytes_per_sector,
719 rescue_pos + i, buff + i);
720 } else {
721 Printf("%s", bad_sectors_warning_msg);
722 err_exit("Disk is faulty, can't make full backup!");
723 }
724 }
725}
726
727static void copy_cluster(int rescue, u64 rescue_lcn, u64 lcn)
728{
729 char buff[NTFS_MAX_CLUSTER_SIZE]; /* overflow checked at mount time */
730 /* vol is NULL if opt.restore_image is set */
731 s32 csize = le32_to_cpu(image_hdr.cluster_size);
732 BOOL backup_bootsector;
733 void *fd = (void *)&fd_in;
734 off_t rescue_pos;
735 NTFS_BOOT_SECTOR *bs;
736 le64 mask;
737 static u16 bytes_per_sector = NTFS_SECTOR_SIZE;
738
739 if (!opt.restore_image) {
740 csize = vol->cluster_size;
741 bytes_per_sector = vol->sector_size;
742 fd = vol->dev;
743 }
744
745 rescue_pos = (off_t)(rescue_lcn * csize);
746
747 /* possible partial cluster holding the backup boot sector */
748 backup_bootsector = (lcn + 1)*csize >= full_device_size;
749 if (backup_bootsector) {
750 csize = full_device_size - lcn*csize;
751 if (csize < 0) {
752 err_exit("Corrupted input, copy aborted");
753 }
754 }
755
756// need reading when not about to write ?
757 if (read_all(fd, buff, csize) == -1) {
758
759 if (errno != EIO) {
760 if (!errno && opt.restore_image)
761 err_exit("Short image file...\n");
762 else
763 perr_exit("read_all");
764 }
765 else if (rescue){
766 s32 i;
767 for (i = 0; i < csize; i += bytes_per_sector)
768 rescue_sector(fd, bytes_per_sector,
769 rescue_pos + i, buff + i);
770 } else {
771 Printf("%s", bad_sectors_warning_msg);
772 err_exit("Disk is faulty, can't make full backup!");
773 }
774 }
775
776 /* Set the new serial number if requested */
777 if (opt.new_serial
778 && !opt.save_image
779 && (!lcn || backup_bootsector)) {
780 /*
781 * For updating the backup boot sector, we need to
782 * know the sector size, but this is not recorded
783 * in the image header, so we collect it on the fly
784 * while reading the first boot sector.
785 */
786 if (!lcn) {
787 bs = (NTFS_BOOT_SECTOR*)buff;
788 bytes_per_sector = le16_to_cpu(bs->bpb.bytes_per_sector);
789 if ((bytes_per_sector > csize)
790 || (bytes_per_sector < NTFS_SECTOR_SIZE))
791 bytes_per_sector = NTFS_SECTOR_SIZE;
792 } else
793 bs = (NTFS_BOOT_SECTOR*)(buff
794 + csize - bytes_per_sector);
795 if (opt.new_serial & 2)
796 bs->volume_serial_number = volume_serial_number;
797 else {
798 mask = const_cpu_to_le64(~0x0ffffffffULL);
799 bs->volume_serial_number
800 = (volume_serial_number & mask)
801 | (bs->volume_serial_number & ~mask);
802 }
803 /* Show the new full serial after merging */
804 if (!lcn)
805 Printf("New serial number : 0x%llx\n",
806 (long long)le64_to_cpu(
807 bs->volume_serial_number));
808 }
809
810 if (opt.save_image || (opt.metadata_image && wipe)) {
811 char cmd = CMD_NEXT;
812 if (write_all(&fd_out, &cmd, sizeof(cmd)) == -1)
813 perr_exit("write_all");
814 }
815
816 if ((!opt.metadata_image || wipe)
817 && (write_all(&fd_out, buff, csize) == -1)) {
818#ifndef NO_STATFS
819 int err = errno;
820 perr_printf("Write failed");
821 if (err == EIO && opt.stfs.f_type == 0x517b)
822 Printf("Apparently you tried to clone to a remote "
823 "Windows computer but they don't\nhave "
824 "efficient sparse file handling by default. "
825 "Please try a different method.\n");
826 exit(1);
827#else
828 perr_printf("Write failed");
829#endif
830 }
831}
832
833static s64 lseek_out(int fd, s64 pos, int mode)
834{
835 s64 ret;
836
837 if (dev_out)
838 ret = (dev_out->d_ops->seek)(dev_out, pos, mode);
839 else
840 ret = lseek(fd, pos, mode);
841 return (ret);
842}
843
844static void lseek_to_cluster(s64 lcn)
845{
846 off_t pos;
847
848 pos = (off_t)(lcn * vol->cluster_size);
849
850 if (vol->dev->d_ops->seek(vol->dev, pos, SEEK_SET) == (off_t)-1)
851 perr_exit("lseek input");
852
853 if (opt.std_out || opt.save_image || opt.metadata_image)
854 return;
855
856 if (lseek_out(fd_out, pos, SEEK_SET) == (off_t)-1)
857 perr_exit("lseek output");
858}
859
860static void gap_to_cluster(s64 gap)
861{
862 sle64 count;
863 char buf[1 + sizeof(count)];
864
865 if (gap) {
866 count = cpu_to_sle64(gap);
867 buf[0] = CMD_GAP;
868 memcpy(&buf[1], &count, sizeof(count));
869 if (write_all(&fd_out, buf, sizeof(buf)) == -1)
870 perr_exit("write_all");
871 }
872}
873
874static void image_skip_clusters(s64 count)
875{
876 if (opt.save_image && count > 0) {
877 s64 count_buf;
878 char buff[1 + sizeof(count)];
879
880 buff[0] = CMD_GAP;
881 count_buf = cpu_to_sle64(count);
882 memcpy(buff + 1, &count_buf, sizeof(count_buf));
883
884 if (write_all(&fd_out, buff, sizeof(buff)) == -1)
885 perr_exit("write_all");
886 }
887}
888
889static void write_image_hdr(void)
890{
891 char alignment[IMAGE_HDR_ALIGN];
892
893 if (opt.save_image || opt.metadata_image) {
894 int alignsize = le32_to_cpu(image_hdr.offset_to_image_data)
895 - sizeof(image_hdr);
896 memset(alignment,0,IMAGE_HDR_ALIGN);
897 if ((alignsize < 0)
898 || write_all(&fd_out, &image_hdr, sizeof(image_hdr))
899 || write_all(&fd_out, alignment, alignsize))
900 perr_exit("write_all");
901 }
902}
903
904static void clone_ntfs(u64 nr_clusters, int more_use)
905{
906 u64 cl, last_cl; /* current and last used cluster */
907 void *buf;
908 u32 csize = vol->cluster_size;
909 u64 p_counter = 0;
910 char alignment[IMAGE_HDR_ALIGN];
911 struct progress_bar progress;
912
913 if (opt.save_image)
914 Printf("Saving NTFS to image ...\n");
915 else
916 Printf("Cloning NTFS ...\n");
917
918 if (opt.new_serial)
919 generate_serial_number();
920
921 buf = ntfs_calloc(csize);
922 if (!buf)
923 perr_exit("clone_ntfs");
924
925 progress_init(&progress, p_counter, nr_clusters, 100);
926
927 if (opt.save_image) {
928 int alignsize = le32_to_cpu(image_hdr.offset_to_image_data)
929 - sizeof(image_hdr);
930 memset(alignment,0,IMAGE_HDR_ALIGN);
931 if ((alignsize < 0)
932 || write_all(&fd_out, &image_hdr, sizeof(image_hdr))
933 || write_all(&fd_out, alignment, alignsize))
934 perr_exit("write_all");
935 }
936
937 /* save suspicious clusters if required */
938 if (more_use && opt.ignore_fs_check) {
939 compare_bitmaps(&lcn_bitmap, TRUE);
940 }
941 /* Examine up to the alternate boot sector */
942 for (last_cl = cl = 0; cl <= (u64)vol->nr_clusters; cl++) {
943
944 if (ntfs_bit_get(lcn_bitmap.bm, cl)) {
945 progress_update(&progress, ++p_counter);
946 lseek_to_cluster(cl);
947 image_skip_clusters(cl - last_cl - 1);
948
949 copy_cluster(opt.rescue, cl, cl);
950 last_cl = cl;
951 continue;
952 }
953
954 if (opt.std_out && !opt.save_image) {
955 progress_update(&progress, ++p_counter);
956 if (write_all(&fd_out, buf, csize) == -1)
957 perr_exit("write_all");
958 }
959 }
960 image_skip_clusters(cl - last_cl - 1);
961 free(buf);
962}
963
964static void write_empty_clusters(s32 csize, s64 count,
965 struct progress_bar *progress, u64 *p_counter)
966{
967 s64 i;
968 char buff[NTFS_MAX_CLUSTER_SIZE];
969
970 memset(buff, 0, csize);
971
972 for (i = 0; i < count; i++) {
973 if (write_all(&fd_out, buff, csize) == -1)
974 perr_exit("write_all");
975 progress_update(progress, ++(*p_counter));
976 }
977}
978
979static void restore_image(void)
980{
981 s64 pos = 0, count;
982 s32 csize = le32_to_cpu(image_hdr.cluster_size);
983 char cmd;
984 u64 p_counter = 0;
985 struct progress_bar progress;
986
987 Printf("Restoring NTFS from image ...\n");
988
989 progress_init(&progress, p_counter, opt.std_out ?
990 sle64_to_cpu(image_hdr.nr_clusters) + 1 :
991 sle64_to_cpu(image_hdr.inuse) + 1,
992 100);
993
994 if (opt.new_serial)
995 generate_serial_number();
996
997 /* Restore up to the alternate boot sector */
998 while (pos <= sle64_to_cpu(image_hdr.nr_clusters)) {
999 if (read_all(&fd_in, &cmd, sizeof(cmd)) == -1) {
1000 if (pos == sle64_to_cpu(image_hdr.nr_clusters)) {
1001 /* alternate boot sector no present in old images */
1002 Printf("Warning : no alternate boot"
1003 " sector in image\n");
1004 break;
1005 } else
1006 perr_exit("read_all");
1007 }
1008
1009 if (cmd == CMD_GAP) {
1010 if (!image_is_host_endian) {
1011 le64 lecount;
1012
1013 /* little endian image, on any computer */
1014 if (read_all(&fd_in, &lecount,
1015 sizeof(lecount)) == -1)
1016 perr_exit("read_all");
1017 count = sle64_to_cpu(lecount);
1018 } else {
1019 /* big endian image on big endian computer */
1020 if (read_all(&fd_in, &count,
1021 sizeof(count)) == -1)
1022 perr_exit("read_all");
1023 }
1024 if (!count)
1025 err_exit("Bad offset at input location 0x%llx\n",
1026 (long long)tellin(fd_in) - 9);
1027 if (opt.std_out) {
1028 if ((!p_counter && count) || (count < 0))
1029 err_exit("Cannot restore a metadata"
1030 " image to stdout\n");
1031 else
1032 write_empty_clusters(csize, count,
1033 &progress, &p_counter);
1034 } else {
1035 if (((pos + count) < 0)
1036 || ((pos + count)
1037 > sle64_to_cpu(image_hdr.nr_clusters)))
1038 err_exit("restore_image: corrupt image "
1039 "at input offset %lld\n",
1040 (long long)tellin(fd_in) - 9);
1041 else {
1042 if (!opt.no_action
1043 && (lseek_out(fd_out, count * csize,
1044 SEEK_CUR) == (off_t)-1))
1045 perr_exit("restore_image: lseek");
1046 }
1047 }
1048 pos += count;
1049 } else if (cmd == CMD_NEXT) {
1050 copy_cluster(0, 0, pos);
1051 pos++;
1052 progress_update(&progress, ++p_counter);
1053 } else
1054 err_exit("Invalid command code %d at input offset 0x%llx\n",
1055 cmd, (long long)tellin(fd_in) - 1);
1056 }
1057}
1058
1059static void wipe_index_entry_timestams(INDEX_ENTRY *e)
1060{
1061 static const struct timespec zero_time = { .tv_sec = 0, .tv_nsec = 0 };
1062 le64 timestamp = timespec2ntfs(zero_time);
1063
1064 /* FIXME: can fall into infinite loop if corrupted */
1065 while (!(e->ie_flags & INDEX_ENTRY_END)) {
1066
1067 e->key.file_name.creation_time = timestamp;
1068 e->key.file_name.last_data_change_time = timestamp;
1069 e->key.file_name.last_mft_change_time = timestamp;
1070 e->key.file_name.last_access_time = timestamp;
1071
1072 wiped_timestamp_data += 32;
1073
1074 e = (INDEX_ENTRY *)((u8 *)e + le16_to_cpu(e->length));
1075 }
1076}
1077
1078static void wipe_index_allocation_timestamps(ntfs_inode *ni, ATTR_RECORD *attr)
1079{
1080 INDEX_ALLOCATION *indexa, *tmp_indexa;
1081 INDEX_ENTRY *entry;
1082 INDEX_ROOT *indexr;
1083 u8 *bitmap, *byte;
1084 int bit;
1085 ntfs_attr *na;
1086 ntfschar *name;
1087 u32 name_len;
1088
1089 indexr = ntfs_index_root_get(ni, attr);
1090 if (!indexr) {
1091 perr_printf("Failed to read $INDEX_ROOT attribute of inode "
1092 "%lld", (long long)ni->mft_no);
1093 return;
1094 }
1095
1096 if (indexr->type != AT_FILE_NAME)
1097 goto out_indexr;
1098
1099 name = (ntfschar *)((u8 *)attr + le16_to_cpu(attr->name_offset));
1100 name_len = attr->name_length;
1101
1102 byte = bitmap = ntfs_attr_readall(ni, AT_BITMAP, name, name_len,
1103 NULL);
1104 if (!byte) {
1105 perr_printf("Failed to read $BITMAP attribute");
1106 goto out_indexr;
1107 }
1108
1109 na = ntfs_attr_open(ni, AT_INDEX_ALLOCATION, name, name_len);
1110 if (!na) {
1111 perr_printf("Failed to open $INDEX_ALLOCATION attribute");
1112 goto out_bitmap;
1113 }
1114
1115 if (!na->data_size)
1116 goto out_na;
1117
1118 tmp_indexa = indexa = ntfs_malloc(na->data_size);
1119 if (!tmp_indexa)
1120 goto out_na;
1121
1122 if (ntfs_attr_pread(na, 0, na->data_size, indexa) != na->data_size) {
1123 perr_printf("Failed to read $INDEX_ALLOCATION attribute");
1124 goto out_indexa;
1125 }
1126
1127 bit = 0;
1128 while ((u8 *)tmp_indexa < (u8 *)indexa + na->data_size) {
1129 if (*byte & (1 << bit)) {
1130 if (ntfs_mst_post_read_fixup((NTFS_RECORD *)tmp_indexa,
1131 le32_to_cpu(
1132 indexr->index_block_size))) {
1133 perr_printf("Damaged INDX record");
1134 goto out_indexa;
1135 }
1136 entry = (INDEX_ENTRY *)((u8 *)tmp_indexa + le32_to_cpu(
1137 tmp_indexa->index.entries_offset) + 0x18);
1138
1139 wipe_index_entry_timestams(entry);
1140
1141 if (ntfs_mft_usn_dec((MFT_RECORD *)tmp_indexa))
1142 perr_exit("ntfs_mft_usn_dec");
1143
1144 if (ntfs_mst_pre_write_fixup((NTFS_RECORD *)tmp_indexa,
1145 le32_to_cpu(
1146 indexr->index_block_size))) {
1147 perr_printf("INDX write fixup failed");
1148 goto out_indexa;
1149 }
1150 }
1151 tmp_indexa = (INDEX_ALLOCATION *)((u8 *)tmp_indexa +
1152 le32_to_cpu(indexr->index_block_size));
1153 bit++;
1154 if (bit > 7) {
1155 bit = 0;
1156 byte++;
1157 }
1158 }
1159 if (ntfs_rl_pwrite(vol, na->rl, 0, 0, na->data_size, indexa) != na->data_size)
1160 perr_printf("ntfs_rl_pwrite failed for inode %lld",
1161 (long long)ni->mft_no);
1162out_indexa:
1163 free(indexa);
1164out_na:
1165 ntfs_attr_close(na);
1166out_bitmap:
1167 free(bitmap);
1168out_indexr:
1169 free(indexr);
1170}
1171
1172static void wipe_index_root_timestamps(ATTR_RECORD *attr, le64 timestamp)
1173{
1174 INDEX_ENTRY *entry;
1175 INDEX_ROOT *iroot;
1176
1177 iroot = (INDEX_ROOT *)((u8 *)attr + le16_to_cpu(attr->value_offset));
1178 entry = (INDEX_ENTRY *)((u8 *)iroot +
1179 le32_to_cpu(iroot->index.entries_offset) + 0x10);
1180
1181 while (!(entry->ie_flags & INDEX_ENTRY_END)) {
1182
1183 if (iroot->type == AT_FILE_NAME) {
1184
1185 entry->key.file_name.creation_time = timestamp;
1186 entry->key.file_name.last_access_time = timestamp;
1187 entry->key.file_name.last_data_change_time = timestamp;
1188 entry->key.file_name.last_mft_change_time = timestamp;
1189
1190 wiped_timestamp_data += 32;
1191
1192 } else if (ntfs_names_are_equal(NTFS_INDEX_Q,
1193 sizeof(NTFS_INDEX_Q) / 2 - 1,
1194 (ntfschar *)((char *)attr +
1195 le16_to_cpu(attr->name_offset)),
1196 attr->name_length, CASE_SENSITIVE, NULL, 0)) {
1197
1198 QUOTA_CONTROL_ENTRY *quota_q;
1199
1200 quota_q = (QUOTA_CONTROL_ENTRY *)((u8 *)entry +
1201 le16_to_cpu(entry->data_offset));
1202 /*
1203 * FIXME: no guarantee it's indeed /$Extend/$Quota:$Q.
1204 * For now, as a minimal safeguard, we check only for
1205 * quota version 2 ...
1206 */
1207 if (le32_to_cpu(quota_q->version) == 2) {
1208 quota_q->change_time = timestamp;
1209 wiped_timestamp_data += 4;
1210 }
1211 }
1212
1213 entry = (INDEX_ENTRY*)((u8*)entry + le16_to_cpu(entry->length));
1214 }
1215}
1216
1217#define WIPE_TIMESTAMPS(atype, attr, timestamp) \
1218do { \
1219 atype *ats; \
1220 ats = (atype *)((char *)(attr) + le16_to_cpu((attr)->value_offset)); \
1221 \
1222 ats->creation_time = (timestamp); \
1223 ats->last_data_change_time = (timestamp); \
1224 ats->last_mft_change_time= (timestamp); \
1225 ats->last_access_time = (timestamp); \
1226 \
1227 wiped_timestamp_data += 32; \
1228 \
1229} while (0)
1230
1231static void wipe_timestamps(ntfs_walk_clusters_ctx *image)
1232{
1233 static const struct timespec zero_time = { .tv_sec = 0, .tv_nsec = 0 };
1234 ATTR_RECORD *a = image->ctx->attr;
1235 le64 timestamp = timespec2ntfs(zero_time);
1236
1237 if (a->type == AT_FILE_NAME)
1238 WIPE_TIMESTAMPS(FILE_NAME_ATTR, a, timestamp);
1239
1240 else if (a->type == AT_STANDARD_INFORMATION)
1241 WIPE_TIMESTAMPS(STANDARD_INFORMATION, a, timestamp);
1242
1243 else if (a->type == AT_INDEX_ROOT)
1244 wipe_index_root_timestamps(a, timestamp);
1245}
1246
1247static void wipe_resident_data(ntfs_walk_clusters_ctx *image)
1248{
1249 ATTR_RECORD *a;
1250 u32 i;
1251 int n = 0;
1252 u8 *p;
1253
1254 a = image->ctx->attr;
1255 p = (u8*)a + le16_to_cpu(a->value_offset);
1256
1257 if (image->ni->mft_no <= LAST_METADATA_INODE)
1258 return;
1259
1260 if (a->type != AT_DATA)
1261 return;
1262
1263 for (i = 0; i < le32_to_cpu(a->value_length); i++) {
1264 if (p[i]) {
1265 p[i] = 0;
1266 n++;
1267 }
1268 }
1269
1270 wiped_resident_data += n;
1271}
1272
1273static int wipe_data(char *p, int pos, int len)
1274{
1275 int wiped = 0;
1276
1277 for (p += pos; --len >= 0;) {
1278 if (p[len]) {
1279 p[len] = 0;
1280 wiped++;
1281 }
1282 }
1283
1284 return wiped;
1285}
1286
1287static void wipe_unused_mft_data(ntfs_inode *ni)
1288{
1289 int unused;
1290 MFT_RECORD *m = ni->mrec;
1291
1292 /* FIXME: broken MFTMirr update was fixed in libntfs, check if OK now */
1293 if (ni->mft_no <= LAST_METADATA_INODE)
1294 return;
1295
1296 unused = le32_to_cpu(m->bytes_allocated) - le32_to_cpu(m->bytes_in_use);
1297 wiped_unused_mft_data += wipe_data((char *)m,
1298 le32_to_cpu(m->bytes_in_use), unused);
1299}
1300
1301static void wipe_unused_mft(ntfs_inode *ni)
1302{
1303 int unused;
1304 MFT_RECORD *m = ni->mrec;
1305
1306 /* FIXME: broken MFTMirr update was fixed in libntfs, check if OK now */
1307 if (ni->mft_no <= LAST_METADATA_INODE)
1308 return;
1309
1310 unused = le32_to_cpu(m->bytes_in_use) - sizeof(MFT_RECORD);
1311 wiped_unused_mft += wipe_data((char *)m, sizeof(MFT_RECORD), unused);
1312}
1313
1314static void clone_logfile_parts(ntfs_walk_clusters_ctx *image, runlist *rl)
1315{
1316 s64 offset = 0, lcn, vcn;
1317
1318 while (1) {
1319
1320 vcn = offset / image->ni->vol->cluster_size;
1321 lcn = ntfs_rl_vcn_to_lcn(rl, vcn);
1322 if (lcn < 0)
1323 break;
1324
1325 lseek_to_cluster(lcn);
1326
1327 if ((lcn + 1) != image->current_lcn) {
1328 /* do not duplicate a cluster */
1329 if (opt.metadata_image && wipe)
1330 gap_to_cluster(lcn - image->current_lcn);
1331
1332 copy_cluster(opt.rescue, lcn, lcn);
1333 }
1334 image->current_lcn = lcn + 1;
1335 if (opt.metadata_image && !wipe)
1336 image->inuse++;
1337
1338 if (offset == 0)
1339 offset = NTFS_BLOCK_SIZE >> 1;
1340 else
1341 offset <<= 1;
1342 }
1343}
1344
1345/*
1346 * In-memory wiping of MFT record or MFTMirr record
1347 * (only for metadata images)
1348 *
1349 * The resident data and (optionally) the timestamps are wiped.
1350 */
1351
1352static void wipe_mft(char *mrec, u32 mrecsz, u64 mft_no)
1353{
1354 ntfs_walk_clusters_ctx image;
1355 ntfs_attr_search_ctx *ctx;
1356 ntfs_inode ni;
1357
1358 ni.mft_no = mft_no;
1359 ni.mrec = (MFT_RECORD*)mrec;
1360 ni.vol = vol; /* Hmm */
1361 image.ni = &ni;
1362 ntfs_mst_post_read_fixup_warn((NTFS_RECORD*)mrec,mrecsz,FALSE);
1363 wipe_unused_mft_data(&ni);
1364 if (!(((MFT_RECORD*)mrec)->flags & MFT_RECORD_IN_USE)) {
1365 wipe_unused_mft(&ni);
1366 } else {
1367 /* ctx with no ntfs_inode prevents from searching external attrs */
1368 if (!(ctx = ntfs_attr_get_search_ctx((ntfs_inode*)NULL, (MFT_RECORD*)mrec)))
1369 perr_exit("ntfs_get_attr_search_ctx");
1370
1371 while (!ntfs_attr_lookup(AT_UNUSED, NULL, 0, CASE_SENSITIVE, 0,
1372 NULL, 0, ctx)) {
1373 if (ctx->attr->type == AT_END)
1374 break;
1375
1376 image.ctx = ctx;
1377 if (!ctx->attr->non_resident
1378 && (mft_no > LAST_METADATA_INODE))
1379 wipe_resident_data(&image);
1380 if (!opt.preserve_timestamps)
1381 wipe_timestamps(&image);
1382 }
1383 ntfs_attr_put_search_ctx(ctx);
1384 }
1385 ntfs_mft_usn_dec((MFT_RECORD*)mrec);
1386 ntfs_mst_pre_write_fixup((NTFS_RECORD*)mrec,mrecsz);
1387}
1388
1389/*
1390 * In-memory wiping of a directory record (I30)
1391 * (only for metadata images)
1392 *
1393 * The timestamps are (optionally) wiped
1394 */
1395
1396static void wipe_indx(char *mrec, u32 mrecsz)
1397{
1398 INDEX_ENTRY *entry;
1399 INDEX_ALLOCATION *indexa;
1400
1401 if (ntfs_mst_post_read_fixup((NTFS_RECORD *)mrec, mrecsz)) {
1402 perr_printf("Damaged INDX record");
1403 goto out_indexa;
1404 }
1405 indexa = (INDEX_ALLOCATION*)mrec;
1406 /*
1407 * The index bitmap is not checked, obsoleted records are
1408 * wiped if they pass the safety checks
1409 */
1410 if ((indexa->magic == magic_INDX)
1411 && (le32_to_cpu(indexa->index.entries_offset) >= sizeof(INDEX_HEADER))
1412 && (le32_to_cpu(indexa->index.allocated_size) <= mrecsz)) {
1413 entry = (INDEX_ENTRY *)((u8 *)mrec + le32_to_cpu(
1414 indexa->index.entries_offset) + 0x18);
1415 wipe_index_entry_timestams(entry);
1416 }
1417
1418 if (ntfs_mft_usn_dec((MFT_RECORD *)mrec))
1419 perr_exit("ntfs_mft_usn_dec");
1420
1421 if (ntfs_mst_pre_write_fixup((NTFS_RECORD *)mrec, mrecsz)) {
1422 perr_printf("INDX write fixup failed");
1423 goto out_indexa;
1424 }
1425out_indexa : ;
1426}
1427
1428/*
1429 * Output a set of related clusters (MFT record or index block)
1430 */
1431
1432static void write_set(char *buff, u32 csize, s64 *current_lcn,
1433 runlist_element *rl, u32 wi, u32 wj, u32 cnt)
1434{
1435 u32 k;
1436 s64 target_lcn;
1437 char cmd = CMD_NEXT;
1438
1439 for (k=0; k<cnt; k++) {
1440 target_lcn = rl[wi].lcn + wj;
1441 if (target_lcn != *current_lcn)
1442 gap_to_cluster(target_lcn - *current_lcn);
1443 if ((write_all(&fd_out, &cmd, sizeof(cmd)) == -1)
1444 || (write_all(&fd_out, &buff[k*csize], csize) == -1))
1445 perr_exit("Failed to write_all");
1446 *current_lcn = target_lcn + 1;
1447
1448 if (++wj >= rl[wi].length) {
1449 wj = 0;
1450 wi++;
1451 }
1452 }
1453}
1454
1455/*
1456 * Copy and wipe the full MFT or MFTMirr data.
1457 * (only for metadata images)
1458 *
1459 * Data are read and written by full clusters, but the wiping is done
1460 * per MFT record.
1461 */
1462
1463static void copy_wipe_mft(ntfs_walk_clusters_ctx *image, runlist *rl)
1464{
1465 char buff[NTFS_MAX_CLUSTER_SIZE]; /* overflow checked at mount time */
1466 void *fd;
1467 s64 mft_no;
1468 u32 mft_record_size;
1469 u32 csize;
1470 u32 bytes_per_sector;
1471 u32 records_per_set;
1472 u32 clusters_per_set;
1473 u32 wi,wj; /* indexes for reading */
1474 u32 ri,rj; /* indexes for writing */
1475 u32 k; /* lcn within run */
1476 u32 r; /* mft_record within set */
1477 s64 current_lcn;
1478
1479 current_lcn = image->current_lcn;
1480 mft_record_size = image->ni->vol->mft_record_size;
1481 csize = image->ni->vol->cluster_size;
1482 bytes_per_sector = image->ni->vol->sector_size;
1483 fd = image->ni->vol->dev;
1484 /*
1485 * Depending on the sizes, there may be several records
1486 * per cluster, or several clusters per record.
1487 */
1488 if (csize >= mft_record_size) {
1489 records_per_set = csize/mft_record_size;
1490 clusters_per_set = 1;
1491 } else {
1492 clusters_per_set = mft_record_size/csize;
1493 records_per_set = 1;
1494 }
1495 mft_no = 0;
1496 ri = rj = 0;
1497 wi = wj = 0;
1498 if (rl[ri].length)
1499 lseek_to_cluster(rl[ri].lcn);
1500 while (rl[ri].length) {
1501 for (k=0; (k<clusters_per_set) && rl[ri].length; k++) {
1502 read_rescue(fd, &buff[k*csize], csize, bytes_per_sector,
1503 rl[ri].lcn + rj);
1504 if (++rj >= rl[ri].length) {
1505 rj = 0;
1506 if (rl[++ri].length)
1507 lseek_to_cluster(rl[ri].lcn);
1508 }
1509 }
1510 if (k == clusters_per_set) {
1511 for (r=0; r<records_per_set; r++) {
1512 if (!strncmp(&buff[r*mft_record_size],"FILE",4))
1513 wipe_mft(&buff[r*mft_record_size],
1514 mft_record_size, mft_no);
1515 mft_no++;
1516 }
1517 write_set(buff, csize, &current_lcn,
1518 rl, wi, wj, clusters_per_set);
1519 wj += clusters_per_set;
1520 while (rl[wi].length && (wj >= rl[wi].length))
1521 wj -= rl[wi++].length;
1522 } else {
1523 err_exit("Short last MFT record\n");
1524 }
1525 }
1526 image->current_lcn = current_lcn;
1527}
1528
1529/*
1530 * Copy and wipe the non-resident part of a directory index
1531 * (only for metadata images)
1532 *
1533 * Data are read and written by full clusters, but the wiping is done
1534 * per index record.
1535 */
1536
1537static void copy_wipe_i30(ntfs_walk_clusters_ctx *image, runlist *rl)
1538{
1539 char buff[NTFS_MAX_CLUSTER_SIZE]; /* overflow checked at mount time */
1540 void *fd;
1541 u32 indx_record_size;
1542 u32 csize;
1543 u32 bytes_per_sector;
1544 u32 records_per_set;
1545 u32 clusters_per_set;
1546 u32 wi,wj; /* indexes for reading */
1547 u32 ri,rj; /* indexes for writing */
1548 u32 k; /* lcn within run */
1549 u32 r; /* mft_record within set */
1550 s64 current_lcn;
1551
1552 current_lcn = image->current_lcn;
1553 csize = image->ni->vol->cluster_size;
1554 bytes_per_sector = image->ni->vol->sector_size;
1555 fd = image->ni->vol->dev;
1556 /*
1557 * Depending on the sizes, there may be several records
1558 * per cluster, or several clusters per record.
1559 */
1560 indx_record_size = image->ni->vol->indx_record_size;
1561 if (csize >= indx_record_size) {
1562 records_per_set = csize/indx_record_size;
1563 clusters_per_set = 1;
1564 } else {
1565 clusters_per_set = indx_record_size/csize;
1566 records_per_set = 1;
1567 }
1568 ri = rj = 0;
1569 wi = wj = 0;
1570 if (rl[ri].length)
1571 lseek_to_cluster(rl[ri].lcn);
1572 while (rl[ri].length) {
1573 for (k=0; (k<clusters_per_set) && rl[ri].length; k++) {
1574 read_rescue(fd, &buff[k*csize], csize, bytes_per_sector,
1575 rl[ri].lcn + rj);
1576 if (++rj >= rl[ri].length) {
1577 rj = 0;
1578 if (rl[++ri].length)
1579 lseek_to_cluster(rl[ri].lcn);
1580 }
1581 }
1582 if (k == clusters_per_set) {
1583 /* wipe records_per_set records */
1584 if (!opt.preserve_timestamps)
1585 for (r=0; r<records_per_set; r++) {
1586 if (!strncmp(&buff[r*indx_record_size],"INDX",4))
1587 wipe_indx(&buff[r*indx_record_size],
1588 indx_record_size);
1589 }
1590 write_set(buff, csize, &current_lcn,
1591 rl, wi, wj, clusters_per_set);
1592 wj += clusters_per_set;
1593 while (rl[wi].length && (wj >= rl[wi].length))
1594 wj -= rl[wi++].length;
1595 } else {
1596 err_exit("Short last directory index record\n");
1597 }
1598 }
1599 image->current_lcn = current_lcn;
1600}
1601
1602static void dump_clusters(ntfs_walk_clusters_ctx *image, runlist *rl)
1603{
1604 s64 i, len; /* number of clusters to copy */
1605
1606 if (opt.restore_image)
1607 err_exit("Bug : invalid dump_clusters()\n");
1608
1609 if ((opt.std_out && !opt.metadata_image) || !opt.metadata)
1610 return;
1611 if (!(len = is_critical_metadata(image, rl)))
1612 return;
1613
1614 lseek_to_cluster(rl->lcn);
1615 if (opt.metadata_image ? wipe : !wipe) {
1616 if (opt.metadata_image)
1617 gap_to_cluster(rl->lcn - image->current_lcn);
1618 /* FIXME: this could give pretty suboptimal performance */
1619 for (i = 0; i < len; i++)
1620 copy_cluster(opt.rescue, rl->lcn + i, rl->lcn + i);
1621 if (opt.metadata_image)
1622 image->current_lcn = rl->lcn + len;
1623 }
1624}
1625
1626static void walk_runs(struct ntfs_walk_cluster *walk)
1627{
1628 int i, j;
1629 runlist *rl;
1630 ATTR_RECORD *a;
1631 ntfs_attr_search_ctx *ctx;
1632 BOOL mft_data;
1633 BOOL index_i30;
1634
1635 ctx = walk->image->ctx;
1636 a = ctx->attr;
1637
1638 if (!a->non_resident) {
1639 if (wipe) {
1640 wipe_resident_data(walk->image);
1641 if (!opt.preserve_timestamps)
1642 wipe_timestamps(walk->image);
1643 }
1644 return;
1645 }
1646
1647 if (wipe
1648 && !opt.preserve_timestamps
1649 && walk->image->ctx->attr->type == AT_INDEX_ALLOCATION)
1650 wipe_index_allocation_timestamps(walk->image->ni, a);
1651
1652 if (!(rl = ntfs_mapping_pairs_decompress(vol, a, NULL)))
1653 perr_exit("ntfs_decompress_mapping_pairs");
1654
1655 /* special wipings for MFT records and directory indexes */
1656 mft_data = ((walk->image->ni->mft_no == FILE_MFT)
1657 || (walk->image->ni->mft_no == FILE_MFTMirr))
1658 && (a->type == AT_DATA);
1659 index_i30 = (walk->image->ctx->attr->type == AT_INDEX_ALLOCATION)
1660 && (a->name_length == 4)
1661 && !memcmp((char*)a + le16_to_cpu(a->name_offset),
1662 NTFS_INDEX_I30,8);
1663
1664 for (i = 0; rl[i].length; i++) {
1665 s64 lcn = rl[i].lcn;
1666 s64 lcn_length = rl[i].length;
1667
1668 if (lcn == LCN_HOLE || lcn == LCN_RL_NOT_MAPPED)
1669 continue;
1670
1671 /* FIXME: ntfs_mapping_pairs_decompress should return error */
1672 if (lcn < 0 || lcn_length < 0)
1673 err_exit("Corrupt runlist in inode %lld attr %x LCN "
1674 "%llx length %llx\n",
1675 (long long)ctx->ntfs_ino->mft_no,
1676 (unsigned int)le32_to_cpu(a->type),
1677 (long long)lcn, (long long)lcn_length);
1678
1679 if (opt.metadata_image ? wipe && !mft_data && !index_i30 : !wipe)
1680 dump_clusters(walk->image, rl + i);
1681
1682 for (j = 0; j < lcn_length; j++) {
1683 u64 k = (u64)lcn + j;
1684 if (ntfs_bit_get_and_set(lcn_bitmap.bm, k, 1))
1685 err_exit("Cluster %llu referenced twice!\n"
1686 "You didn't shutdown your Windows "
1687 "properly?\n", (unsigned long long)k);
1688 }
1689
1690 if (!opt.metadata_image)
1691 walk->image->inuse += lcn_length;
1692 /*
1693 * For a metadata image, we have to compute the
1694 * number of metadata clusters for the percentages
1695 * to be displayed correctly while restoring.
1696 */
1697 if (!wipe && opt.metadata_image) {
1698 if ((walk->image->ni->mft_no == FILE_LogFile)
1699 && (walk->image->ctx->attr->type == AT_DATA)) {
1700 /* 16 KiB of FILE_LogFile */
1701 walk->image->inuse
1702 += is_critical_metadata(walk->image,rl);
1703 } else {
1704 if ((walk->image->ni->mft_no
1705 <= LAST_METADATA_INODE)
1706 || (walk->image->ctx->attr->type != AT_DATA))
1707 walk->image->inuse += lcn_length;
1708 }
1709 }
1710 }
1711 if (wipe && opt.metadata_image) {
1712 ntfs_attr *na;
1713 /*
1714 * Non-resident metadata has to be wiped globally,
1715 * because its logical blocks may be larger than
1716 * a cluster and split over two extents.
1717 */
1718 if (mft_data && !a->lowest_vcn) {
1719 na = ntfs_attr_open(walk->image->ni,
1720 AT_DATA, NULL, 0);
1721 if (na) {
1722 na->rl = rl;
1723 rl = (runlist_element*)NULL;
1724 if (!ntfs_attr_map_whole_runlist(na)) {
1725 copy_wipe_mft(walk->image,na->rl);
1726 } else
1727 perr_exit("Failed to map data of inode %lld",
1728 (long long)walk->image->ni->mft_no);
1729 ntfs_attr_close(na);
1730 } else
1731 perr_exit("Failed to open data of inode %lld",
1732 (long long)walk->image->ni->mft_no);
1733 }
1734 if (index_i30 && !a->lowest_vcn) {
1735 na = ntfs_attr_open(walk->image->ni,
1736 AT_INDEX_ALLOCATION, NTFS_INDEX_I30, 4);
1737 if (na) {
1738 na->rl = rl;
1739 rl = (runlist_element*)NULL;
1740 if (!ntfs_attr_map_whole_runlist(na)) {
1741 copy_wipe_i30(walk->image,na->rl);
1742 } else
1743 perr_exit("Failed to map index of inode %lld",
1744 (long long)walk->image->ni->mft_no);
1745 ntfs_attr_close(na);
1746 } else
1747 perr_exit("Failed to open index of inode %lld",
1748 (long long)walk->image->ni->mft_no);
1749 }
1750 }
1751 if (opt.metadata
1752 && (opt.metadata_image || !wipe)
1753 && (walk->image->ni->mft_no == FILE_LogFile)
1754 && (walk->image->ctx->attr->type == AT_DATA))
1755 clone_logfile_parts(walk->image, rl);
1756
1757 free(rl);
1758}
1759
1760
1761static void walk_attributes(struct ntfs_walk_cluster *walk)
1762{
1763 ntfs_attr_search_ctx *ctx;
1764
1765 if (!(ctx = ntfs_attr_get_search_ctx(walk->image->ni, NULL)))
1766 perr_exit("ntfs_get_attr_search_ctx");
1767
1768 while (!ntfs_attrs_walk(ctx)) {
1769 if (ctx->attr->type == AT_END)
1770 break;
1771
1772 walk->image->ctx = ctx;
1773 walk_runs(walk);
1774 }
1775
1776 ntfs_attr_put_search_ctx(ctx);
1777}
1778
1779/*
1780 * Compare the actual bitmap to the list of clusters
1781 * allocated to identified files.
1782 *
1783 * Clusters found in use, though not marked in the bitmap are copied
1784 * if the option --ignore-fs-checks is set.
1785 */
1786
1787static int compare_bitmaps(struct bitmap *a, BOOL copy)
1788{
1789 s64 i, pos, count;
1790 int mismatch = 0;
1791 int more_use = 0;
1792 s64 new_cl;
1793 u8 bm[NTFS_BUF_SIZE];
1794
1795 Printf("Accounting clusters ...\n");
1796
1797 pos = 0;
1798 new_cl = 0;
1799 while (1) {
1800 count = ntfs_attr_pread(vol->lcnbmp_na, pos, NTFS_BUF_SIZE, bm);
1801 if (count == -1)
1802 perr_exit("Couldn't get $Bitmap $DATA");
1803
1804 if (count == 0) {
1805 /* the backup bootsector need not be accounted for */
1806 if (((vol->nr_clusters + 7) >> 3) > pos)
1807 err_exit("$Bitmap size is smaller than expected"
1808 " (%lld < %lld)\n",
1809 (long long)pos, (long long)a->size);
1810 break;
1811 }
1812
1813 for (i = 0; i < count; i++, pos++) {
1814 s64 cl; /* current cluster */
1815
1816 if (a->size <= pos)
1817 goto done;
1818
1819 if (a->bm[pos] == bm[i])
1820 continue;
1821
1822 for (cl = pos * 8; cl < (pos + 1) * 8; cl++) {
1823 char bit;
1824
1825 bit = ntfs_bit_get(a->bm, cl);
1826 if (bit == ntfs_bit_get(bm, i * 8 + cl % 8))
1827 continue;
1828
1829 if (!bit)
1830 more_use++;
1831 if (opt.ignore_fs_check && !bit && copy) {
1832 lseek_to_cluster(cl);
1833 if (opt.save_image
1834 || (opt.metadata
1835 && opt.metadata_image)) {
1836 gap_to_cluster(cl - new_cl);
1837 new_cl = cl + 1;
1838 }
1839 copy_cluster(opt.rescue, cl, cl);
1840 }
1841
1842 if (++mismatch > 10)
1843 continue;
1844
1845 Printf("Cluster accounting failed at %lld "
1846 "(0x%llx): %s cluster in $Bitmap\n",
1847 (long long)cl, (unsigned long long)cl,
1848 bit ? "missing" : "extra");
1849 }
1850 }
1851 }
1852done:
1853 if (mismatch) {
1854 Printf("Totally %d cluster accounting mismatches.\n", mismatch);
1855 if (opt.ignore_fs_check) {
1856 Printf("WARNING: The NTFS inconsistency was overruled "
1857 "by the --ignore-fs-check option.\n");
1858 if (new_cl) {
1859 gap_to_cluster(-new_cl);
1860 }
1861 return (more_use);
1862 }
1863 err_exit("Filesystem check failed! Windows wasn't shutdown "
1864 "properly or inconsistent\nfilesystem. Please run "
1865 "chkdsk /f on Windows then reboot it TWICE.\n");
1866 }
1867 return (more_use);
1868}
1869
1870
1871static void mft_record_write_with_same_usn(ntfs_volume *volume, ntfs_inode *ni)
1872{
1873 if (ntfs_mft_usn_dec(ni->mrec))
1874 perr_exit("ntfs_mft_usn_dec");
1875
1876 if (ntfs_mft_record_write(volume, ni->mft_no, ni->mrec))
1877 perr_exit("ntfs_mft_record_write");
1878}
1879
1880static void mft_inode_write_with_same_usn(ntfs_volume *volume, ntfs_inode *ni)
1881{
1882 s32 i;
1883
1884 mft_record_write_with_same_usn(volume, ni);
1885
1886 if (ni->nr_extents <= 0)
1887 return;
1888
1889 for (i = 0; i < ni->nr_extents; ++i) {
1890 ntfs_inode *eni = ni->extent_nis[i];
1891 mft_record_write_with_same_usn(volume, eni);
1892 }
1893}
1894
1895static int walk_clusters(ntfs_volume *volume, struct ntfs_walk_cluster *walk)
1896{
1897 s64 inode = 0;
1898 s64 last_mft_rec;
1899 u64 nr_clusters;
1900 ntfs_inode *ni;
1901 struct progress_bar progress;
1902
1903 if (opt.restore_image || (!opt.metadata && wipe))
1904 err_exit("Bug : invalid walk_clusters()\n");
1905 Printf("Scanning volume ...\n");
1906
1907 last_mft_rec = (volume->mft_na->initialized_size >>
1908 volume->mft_record_size_bits) - 1;
1909 walk->image->current_lcn = 0;
1910 progress_init(&progress, inode, last_mft_rec, 100);
1911
1912 NVolSetNoFixupWarn(volume);
1913 for (; inode <= last_mft_rec; inode++) {
1914
1915 int err, deleted_inode;
1916 MFT_REF mref = (MFT_REF)inode;
1917
1918 progress_update(&progress, inode);
1919
1920 /* FIXME: Terrible kludge for libntfs not being able to return
1921 a deleted MFT record as inode */
1922 ni = ntfs_calloc(sizeof(ntfs_inode));
1923 if (!ni)
1924 perr_exit("walk_clusters");
1925
1926 ni->vol = volume;
1927
1928 err = ntfs_file_record_read(volume, mref, &ni->mrec, NULL);
1929 if (err == -1) {
1930 free(ni);
1931 continue;
1932 }
1933
1934 deleted_inode = !(ni->mrec->flags & MFT_RECORD_IN_USE);
1935
1936 if (deleted_inode && !opt.metadata_image) {
1937
1938 ni->mft_no = MREF(mref);
1939 if (wipe) {
1940 wipe_unused_mft(ni);
1941 wipe_unused_mft_data(ni);
1942 mft_record_write_with_same_usn(volume, ni);
1943 }
1944 }
1945
1946 free(ni->mrec);
1947 free(ni);
1948
1949 if (deleted_inode)
1950 continue;
1951
1952 if ((ni = ntfs_inode_open(volume, mref)) == NULL) {
1953 /* FIXME: continue only if it make sense, e.g.
1954 MFT record not in use based on $MFT bitmap */
1955 if (errno == EIO || errno == ENOENT)
1956 continue;
1957 perr_exit("Reading inode %lld failed",
1958 (long long)inode);
1959 }
1960
1961 if (wipe)
1962 nr_used_mft_records++;
1963
1964 if (ni->mrec->base_mft_record)
1965 goto out;
1966
1967 walk->image->ni = ni;
1968 walk_attributes(walk);
1969out:
1970 if (wipe && !opt.metadata_image) {
1971 int i;
1972
1973 wipe_unused_mft_data(ni);
1974 for (i = 0; i < ni->nr_extents; ++i) {
1975 wipe_unused_mft_data(ni->extent_nis[i]);
1976 }
1977 mft_inode_write_with_same_usn(volume, ni);
1978 }
1979
1980 if (ntfs_inode_close(ni))
1981 perr_exit("ntfs_inode_close for inode %lld",
1982 (long long)inode);
1983 }
1984 if (opt.metadata) {
1985 if (opt.metadata_image && wipe && opt.ignore_fs_check) {
1986 gap_to_cluster(-walk->image->current_lcn);
1987 compare_bitmaps(&lcn_bitmap, TRUE);
1988 walk->image->current_lcn = 0;
1989 }
1990 if (opt.metadata_image ? wipe : !wipe) {
1991 /* also get the backup bootsector */
1992 nr_clusters = vol->nr_clusters;
1993 lseek_to_cluster(nr_clusters);
1994 if (opt.metadata_image && wipe)
1995 gap_to_cluster(nr_clusters
1996 - walk->image->current_lcn);
1997 copy_cluster(opt.rescue, nr_clusters, nr_clusters);
1998 walk->image->current_lcn = nr_clusters;
1999 }
2000 /* Not counted, for compatibility with older versions */
2001 if (!opt.metadata_image)
2002 walk->image->inuse++;
2003 }
2004 return 0;
2005}
2006
2007
2008/*
2009 * $Bitmap can overlap the end of the volume. Any bits in this region
2010 * must be set. This region also encompasses the backup boot sector.
2011 */
2012static void bitmap_file_data_fixup(s64 cluster, struct bitmap *bm)
2013{
2014 for (; cluster < bm->size << 3; cluster++)
2015 ntfs_bit_set(bm->bm, (u64)cluster, 1);
2016}
2017
2018
2019/*
2020 * Allocate a block of memory with one bit for each cluster of the disk.
2021 * All the bits are set to 0, except those representing the region beyond the
2022 * end of the disk.
2023 */
2024static void setup_lcn_bitmap(void)
2025{
2026 /* Determine lcn bitmap byte size and allocate it. */
2027 /* include the alternate boot sector in the bitmap count */
2028 lcn_bitmap.size = rounded_up_division(vol->nr_clusters + 1, 8);
2029
2030 lcn_bitmap.bm = ntfs_calloc(lcn_bitmap.size);
2031 if (!lcn_bitmap.bm)
2032 perr_exit("Failed to allocate internal buffer");
2033
2034 bitmap_file_data_fixup(vol->nr_clusters, &lcn_bitmap);
2035}
2036
2037
2038static s64 volume_size(ntfs_volume *volume, s64 nr_clusters)
2039{
2040 return nr_clusters * volume->cluster_size;
2041}
2042
2043
2044static void print_volume_size(const char *str, s64 bytes)
2045{
2046 Printf("%s: %lld bytes (%lld MB)\n", str, (long long)bytes,
2047 (long long)rounded_up_division(bytes, NTFS_MBYTE));
2048}
2049
2050
2051static void print_disk_usage(const char *spacer, u32 cluster_size,
2052 s64 nr_clusters, s64 inuse)
2053{
2054 s64 total, used;
2055
2056 total = nr_clusters * cluster_size;
2057 used = inuse * cluster_size;
2058
2059 Printf("Space in use %s: %lld MB (%.1f%%) ", spacer,
2060 (long long)rounded_up_division(used, NTFS_MBYTE),
2061 100.0 * ((float)used / total));
2062
2063 Printf("\n");
2064}
2065
2066static void print_image_info(void)
2067{
2068 Printf("Ntfsclone image version: %d.%d\n",
2069 image_hdr.major_ver, image_hdr.minor_ver);
2070 Printf("Cluster size : %u bytes\n",
2071 (unsigned)le32_to_cpu(image_hdr.cluster_size));
2072 print_volume_size("Image volume size ",
2073 sle64_to_cpu(image_hdr.nr_clusters) *
2074 le32_to_cpu(image_hdr.cluster_size));
2075 Printf("Image device size : %lld bytes\n",
2076 (long long)sle64_to_cpu(image_hdr.device_size));
2077 print_disk_usage(" ", le32_to_cpu(image_hdr.cluster_size),
2078 sle64_to_cpu(image_hdr.nr_clusters),
2079 sle64_to_cpu(image_hdr.inuse));
2080 Printf("Offset to image data : %u (0x%x) bytes\n",
2081 (unsigned)le32_to_cpu(image_hdr.offset_to_image_data),
2082 (unsigned)le32_to_cpu(image_hdr.offset_to_image_data));
2083}
2084
2085static void check_if_mounted(const char *device, unsigned long new_mntflag)
2086{
2087 unsigned long mntflag;
2088
2089 if (ntfs_check_if_mounted(device, &mntflag))
2090 perr_exit("Failed to check '%s' mount state", device);
2091
2092 if (mntflag & NTFS_MF_MOUNTED) {
2093 if (!(mntflag & NTFS_MF_READONLY))
2094 err_exit("Device '%s' is mounted read-write. "
2095 "You must 'umount' it first.\n", device);
2096 if (!new_mntflag)
2097 err_exit("Device '%s' is mounted. "
2098 "You must 'umount' it first.\n", device);
2099 }
2100}
2101
2102/**
2103 * mount_volume -
2104 *
2105 * First perform some checks to determine if the volume is already mounted, or
2106 * is dirty (Windows wasn't shutdown properly). If everything is OK, then mount
2107 * the volume (load the metadata into memory).
2108 */
2109static void mount_volume(unsigned long new_mntflag)
2110{
2111 check_if_mounted(opt.volume, new_mntflag);
2112
2113 if (!(vol = ntfs_mount(opt.volume, new_mntflag))) {
2114
2115 int err = errno;
2116
2117 perr_printf("Opening '%s' as NTFS failed", opt.volume);
2118 if (err == EINVAL) {
2119 Printf("Apparently device '%s' doesn't have a "
2120 "valid NTFS. Maybe you selected\nthe whole "
2121 "disk instead of a partition (e.g. /dev/hda, "
2122 "not /dev/hda1)?\n", opt.volume);
2123 }
2124 /*
2125 * Retry with recovering the log file enabled.
2126 * Normally avoided in order to get the original log file
2127 * data, but needed when remounting the metadata of a
2128 * volume improperly unmounted from Windows.
2129 */
2130 if (!(new_mntflag & (NTFS_MNT_RDONLY | NTFS_MNT_RECOVER))) {
2131 Printf("Trying to recover...\n");
2132 vol = ntfs_mount(opt.volume,
2133 new_mntflag | NTFS_MNT_RECOVER);
2134 Printf("... %s\n",(vol ? "Successful" : "Failed"));
2135 }
2136 if (!vol)
2137 exit(1);
2138 }
2139
2140 if (vol->flags & VOLUME_IS_DIRTY)
2141 if (opt.force-- <= 0)
2142 err_exit(dirty_volume_msg, opt.volume);
2143
2144 if (NTFS_MAX_CLUSTER_SIZE < vol->cluster_size)
2145 err_exit("Cluster size %u is too large!\n",
2146 (unsigned int)vol->cluster_size);
2147
2148 Printf("NTFS volume version: %d.%d\n", vol->major_ver, vol->minor_ver);
2149 if (ntfs_version_is_supported(vol))
2150 perr_exit("Unknown NTFS version");
2151
2152 Printf("Cluster size : %u bytes\n",
2153 (unsigned int)vol->cluster_size);
2154 print_volume_size("Current volume size",
2155 volume_size(vol, vol->nr_clusters));
2156}
2157
2158static struct ntfs_walk_cluster backup_clusters = { NULL, NULL };
2159
2160static int device_offset_valid(int fd, s64 ofs)
2161{
2162 char ch;
2163
2164 if (lseek(fd, ofs, SEEK_SET) >= 0 && read(fd, &ch, 1) == 1)
2165 return 0;
2166 return -1;
2167}
2168
2169static s64 device_size_get(int fd)
2170{
2171 s64 high, low;
2172#ifdef BLKGETSIZE64
2173 { u64 size;
2174
2175 if (ioctl(fd, BLKGETSIZE64, &size) >= 0) {
2176 ntfs_log_debug("BLKGETSIZE64 nr bytes = %llu "
2177 "(0x%llx).\n", (unsigned long long)size,
2178 (unsigned long long)size);
2179 return (s64)size;
2180 }
2181 }
2182#endif
2183#ifdef BLKGETSIZE
2184 { unsigned long size;
2185
2186 if (ioctl(fd, BLKGETSIZE, &size) >= 0) {
2187 ntfs_log_debug("BLKGETSIZE nr 512 byte blocks = %lu "
2188 "(0x%lx).\n", size, size);
2189 return (s64)size * 512;
2190 }
2191 }
2192#endif
2193#ifdef FDGETPRM
2194 { struct floppy_struct this_floppy;
2195
2196 if (ioctl(fd, FDGETPRM, &this_floppy) >= 0) {
2197 ntfs_log_debug("FDGETPRM nr 512 byte blocks = %lu "
2198 "(0x%lx).\n", this_floppy.size,
2199 this_floppy.size);
2200 return (s64)this_floppy.size * 512;
2201 }
2202 }
2203#endif
2204 /*
2205 * We couldn't figure it out by using a specialized ioctl,
2206 * so do binary search to find the size of the device.
2207 */
2208 low = 0LL;
2209 for (high = 1024LL; !device_offset_valid(fd, high); high <<= 1)
2210 low = high;
2211 while (low < high - 1LL) {
2212 const s64 mid = (low + high) / 2;
2213
2214 if (!device_offset_valid(fd, mid))
2215 low = mid;
2216 else
2217 high = mid;
2218 }
2219 lseek(fd, 0LL, SEEK_SET);
2220 return (low + 1LL);
2221}
2222
2223static void fsync_clone(int fd)
2224{
2225 Printf("Syncing ...\n");
2226 if (opt.save_image && stream_out && fflush(stream_out))
2227 perr_exit("fflush");
2228 if (fsync(fd) && errno != EINVAL)
2229 perr_exit("fsync");
2230}
2231
2232static void set_filesize(s64 filesize)
2233{
2234#ifndef NO_STATFS
2235 long fs_type = 0; /* Unknown filesystem type */
2236
2237 if (fstatfs(fd_out, &opt.stfs) == -1)
2238 Printf("WARNING: Couldn't get filesystem type: "
2239 "%s\n", strerror(errno));
2240 else
2241 fs_type = opt.stfs.f_type;
2242
2243 if (fs_type == 0x52654973)
2244 Printf("WARNING: You're using ReiserFS, it has very poor "
2245 "performance creating\nlarge sparse files. The next "
2246 "operation might take a very long time!\n"
2247 "Creating sparse output file ...\n");
2248 else if (fs_type == 0x517b)
2249 Printf("WARNING: You're using SMBFS and if the remote share "
2250 "isn't Samba but a Windows\ncomputer then the clone "
2251 "operation will be very inefficient and may fail!\n");
2252#endif
2253
2254 if (!opt.no_action && (ftruncate(fd_out, filesize) == -1)) {
2255 int err = errno;
2256 perr_printf("ftruncate failed for file '%s'", opt.output);
2257#ifndef NO_STATFS
2258 if (fs_type)
2259 Printf("Destination filesystem type is 0x%lx.\n",
2260 (unsigned long)fs_type);
2261#endif
2262 if (err == E2BIG) {
2263 Printf("Your system or the destination filesystem "
2264 "doesn't support large files.\n");
2265#ifndef NO_STATFS
2266 if (fs_type == 0x517b) {
2267 Printf("SMBFS needs minimum Linux kernel "
2268 "version 2.4.25 and\n the 'lfs' option"
2269 "\nfor smbmount to have large "
2270 "file support.\n");
2271 }
2272#endif
2273 } else if (err == EPERM) {
2274 Printf("Apparently the destination filesystem doesn't "
2275 "support sparse files.\nYou can overcome this "
2276 "by using the more efficient --save-image "
2277 "option\nof ntfsclone. Use the --restore-image "
2278 "option to restore the image.\n");
2279 }
2280 exit(1);
2281 }
2282}
2283
2284static s64 open_image(void)
2285{
2286 if (strcmp(opt.volume, "-") == 0) {
2287 if ((fd_in = fileno(stdin)) == -1)
2288 perr_exit("fileno for stdin failed");
2289#ifdef HAVE_WINDOWS_H
2290 if (setmode(fd_in,O_BINARY) == -1)
2291 perr_exit("setting binary stdin failed");
2292#endif
2293 } else {
2294 if ((fd_in = open(opt.volume, O_RDONLY | O_BINARY)) == -1)
2295 perr_exit("failed to open image");
2296 }
2297 if (read_all(&fd_in, &image_hdr, NTFSCLONE_IMG_HEADER_SIZE_OLD) == -1)
2298 perr_exit("read_all");
2299 if (memcmp(image_hdr.magic, IMAGE_MAGIC, IMAGE_MAGIC_SIZE) != 0)
2300 err_exit("Input file is not an image! (invalid magic)\n");
2301 if (image_hdr.major_ver < NTFSCLONE_IMG_VER_MAJOR_ENDIANNESS_SAFE) {
2302 image_hdr.major_ver = NTFSCLONE_IMG_VER_MAJOR;
2303 image_hdr.minor_ver = NTFSCLONE_IMG_VER_MINOR;
2304#if (__BYTE_ORDER == __BIG_ENDIAN)
2305 /*
2306 * old image read on a big endian computer,
2307 * assuming it was created big endian and read cpu-wise,
2308 * so we should translate to little endian
2309 */
2310 Printf("Old image format detected. If the image was created "
2311 "on a little endian architecture it will not "
2312 "work. Use a more recent version of "
2313 "ntfsclone to recreate the image.\n");
2314 image_hdr.cluster_size = cpu_to_le32(image_hdr.cluster_size);
2315 image_hdr.device_size = cpu_to_sle64(image_hdr.device_size);
2316 image_hdr.nr_clusters = cpu_to_sle64(image_hdr.nr_clusters);
2317 image_hdr.inuse = cpu_to_sle64(image_hdr.inuse);
2318#endif
2319 image_hdr.offset_to_image_data =
2320 const_cpu_to_le32((sizeof(image_hdr)
2321 + IMAGE_HDR_ALIGN - 1) & -IMAGE_HDR_ALIGN);
2322 image_is_host_endian = TRUE;
2323 } else {
2324 /* safe image : little endian data */
2325 le32 offset_to_image_data;
2326 int delta;
2327
2328 if (image_hdr.major_ver > NTFSCLONE_IMG_VER_MAJOR)
2329 err_exit("Do not know how to handle image format "
2330 "version %d.%d. Please obtain a "
2331 "newer version of ntfsclone.\n",
2332 image_hdr.major_ver,
2333 image_hdr.minor_ver);
2334 /* Read the image header data offset. */
2335 if (read_all(&fd_in, &offset_to_image_data,
2336 sizeof(offset_to_image_data)) == -1)
2337 perr_exit("read_all");
2338 /* do not translate little endian data */
2339 image_hdr.offset_to_image_data = offset_to_image_data;
2340 /*
2341 * Read any fields from the header that we have not read yet so
2342 * that the input stream is positioned correctly. This means
2343 * we can support future minor versions that just extend the
2344 * header in a backwards compatible way.
2345 */
2346 delta = le32_to_cpu(offset_to_image_data)
2347 - (NTFSCLONE_IMG_HEADER_SIZE_OLD +
2348 sizeof(image_hdr.offset_to_image_data));
2349 if (delta > 0) {
2350 char *dummy_buf;
2351
2352 dummy_buf = malloc(delta);
2353 if (!dummy_buf)
2354 perr_exit("malloc dummy_buffer");
2355 if (read_all(&fd_in, dummy_buf, delta) == -1)
2356 perr_exit("read_all");
2357 free(dummy_buf);
2358 }
2359 }
2360 return sle64_to_cpu(image_hdr.device_size);
2361}
2362
2363static s64 open_volume(void)
2364{
2365 s64 device_size;
2366
2367 mount_volume(NTFS_MNT_RDONLY);
2368
2369 device_size = ntfs_device_size_get(vol->dev, 1);
2370 if (device_size <= 0)
2371 err_exit("Couldn't get device size (%lld)!\n",
2372 (long long)device_size);
2373
2374 print_volume_size("Current device size", device_size);
2375
2376 if (device_size < vol->nr_clusters * vol->cluster_size)
2377 err_exit("Current NTFS volume size is bigger than the device "
2378 "size (%lld)!\nCorrupt partition table or incorrect "
2379 "device partitioning?\n", (long long)device_size);
2380
2381 return device_size;
2382}
2383
2384static void initialise_image_hdr(s64 device_size, s64 inuse)
2385{
2386 memcpy(image_hdr.magic, IMAGE_MAGIC, IMAGE_MAGIC_SIZE);
2387 image_hdr.major_ver = NTFSCLONE_IMG_VER_MAJOR;
2388 image_hdr.minor_ver = NTFSCLONE_IMG_VER_MINOR;
2389 image_hdr.cluster_size = cpu_to_le32(vol->cluster_size);
2390 image_hdr.device_size = cpu_to_sle64(device_size);
2391 image_hdr.nr_clusters = cpu_to_sle64(vol->nr_clusters);
2392 image_hdr.inuse = cpu_to_sle64(inuse);
2393 image_hdr.offset_to_image_data = cpu_to_le32((sizeof(image_hdr)
2394 + IMAGE_HDR_ALIGN - 1) & -IMAGE_HDR_ALIGN);
2395}
2396
2397static void check_output_device(s64 input_size)
2398{
2399 if (opt.blkdev_out) {
2400 s64 dest_size;
2401
2402 if (dev_out)
2403 dest_size = ntfs_device_size_get(dev_out, 1);
2404 else
2405 dest_size = device_size_get(fd_out);
2406 if (dest_size < input_size)
2407 err_exit("Output device is too small (%lld) to fit the "
2408 "NTFS image (%lld).\n",
2409 (long long)dest_size, (long long)input_size);
2410
2411 check_if_mounted(opt.output, 0);
2412 } else
2413 set_filesize(input_size);
2414}
2415
2416static ntfs_attr_search_ctx *attr_get_search_ctx(ntfs_inode *ni)
2417{
2418 ntfs_attr_search_ctx *ret;
2419
2420 if ((ret = ntfs_attr_get_search_ctx(ni, NULL)) == NULL)
2421 perr_printf("ntfs_attr_get_search_ctx");
2422
2423 return ret;
2424}
2425
2426/**
2427 * lookup_data_attr
2428 *
2429 * Find the $DATA attribute (with or without a name) for the given ntfs inode.
2430 */
2431static ntfs_attr_search_ctx *lookup_data_attr(ntfs_inode *ni, const char *aname)
2432{
2433 ntfs_attr_search_ctx *ctx;
2434 ntfschar *ustr;
2435 int len = 0;
2436
2437 if ((ctx = attr_get_search_ctx(ni)) == NULL)
2438 return NULL;
2439
2440 if ((ustr = ntfs_str2ucs(aname, &len)) == NULL) {
2441 perr_printf("Couldn't convert '%s' to Unicode", aname);
2442 goto error_out;
2443 }
2444
2445 if (ntfs_attr_lookup(AT_DATA, ustr, len, CASE_SENSITIVE,
2446 0, NULL, 0, ctx)) {
2447 perr_printf("ntfs_attr_lookup");
2448 goto error_out;
2449 }
2450 ntfs_ucsfree(ustr);
2451 return ctx;
2452error_out:
2453 ntfs_attr_put_search_ctx(ctx);
2454 return NULL;
2455}
2456
2457static void ignore_bad_clusters(ntfs_walk_clusters_ctx *image)
2458{
2459 ntfs_inode *ni;
2460 ntfs_attr_search_ctx *ctx = NULL;
2461 runlist *rl, *rl_bad;
2462 s64 nr_bad_clusters = 0;
2463
2464 if (!(ni = ntfs_inode_open(vol, FILE_BadClus)))
2465 perr_exit("ntfs_open_inode");
2466
2467 if ((ctx = lookup_data_attr(ni, "$Bad")) == NULL)
2468 exit(1);
2469
2470 if (!(rl_bad = ntfs_mapping_pairs_decompress(vol, ctx->attr, NULL)))
2471 perr_exit("ntfs_mapping_pairs_decompress");
2472
2473 for (rl = rl_bad; rl->length; rl++) {
2474 s64 lcn = rl->lcn;
2475
2476 if (lcn == LCN_HOLE || lcn < 0)
2477 continue;
2478
2479 for (; lcn < rl->lcn + rl->length; lcn++, nr_bad_clusters++) {
2480 if (ntfs_bit_get_and_set(lcn_bitmap.bm, lcn, 0))
2481 image->inuse--;
2482 }
2483 }
2484 if (nr_bad_clusters)
2485 Printf("WARNING: The disk has %lld or more bad sectors"
2486 " (hardware faults).\n", (long long)nr_bad_clusters);
2487 free(rl_bad);
2488
2489 ntfs_attr_put_search_ctx(ctx);
2490 if (ntfs_inode_close(ni))
2491 perr_exit("ntfs_inode_close failed for $BadClus");
2492}
2493
2494static void check_dest_free_space(u64 src_bytes)
2495{
2496#ifndef HAVE_WINDOWS_H
2497 u64 dest_bytes;
2498 struct statvfs stvfs;
2499 struct stat st;
2500
2501 if (opt.metadata || opt.blkdev_out || opt.std_out)
2502 return;
2503 /*
2504 * TODO: save_image needs a bit more space than src_bytes
2505 * due to the free space encoding overhead.
2506 */
2507 if (fstatvfs(fd_out, &stvfs) == -1) {
2508 Printf("WARNING: Unknown free space on the destination: %s\n",
2509 strerror(errno));
2510 return;
2511 }
2512
2513 /* If file is a FIFO then there is no point in checking the size. */
2514 if (!fstat(fd_out, &st)) {
2515 if (S_ISFIFO(st.st_mode))
2516 return;
2517 } else
2518 Printf("WARNING: fstat failed: %s\n", strerror(errno));
2519
2520 dest_bytes = (u64)stvfs.f_frsize * stvfs.f_bfree;
2521 if (!dest_bytes)
2522 dest_bytes = (u64)stvfs.f_bsize * stvfs.f_bfree;
2523
2524 if (dest_bytes < src_bytes)
2525 err_exit("Destination doesn't have enough free space: "
2526 "%llu MB < %llu MB\n",
2527 (unsigned long long)rounded_up_division(dest_bytes, NTFS_MBYTE),
2528 (unsigned long long)rounded_up_division(src_bytes, NTFS_MBYTE));
2529#endif
2530}
2531
2532int main(int argc, char **argv)
2533{
2534 ntfs_walk_clusters_ctx image;
2535 s64 device_size; /* input device size in bytes */
2536 s64 ntfs_size;
2537 unsigned int wiped_total = 0;
2538
2539 /* make sure the layout of header is not affected by alignments */
2540 if (offsetof(struct image_hdr, offset_to_image_data)
2541 != IMAGE_OFFSET_OFFSET) {
2542 fprintf(stderr,"ntfsclone is not compiled properly. "
2543 "Please fix\n");
2544 exit(1);
2545 }
2546 /* print to stderr, stdout can be an NTFS image ... */
2547 fprintf(stderr, "%s v%s (libntfs-3g)\n", EXEC_NAME, VERSION);
2548 msg_out = stderr;
2549
2550 parse_options(argc, argv);
2551
2552 utils_set_locale();
2553
2554 if (opt.restore_image) {
2555 device_size = open_image();
2556 ntfs_size = sle64_to_cpu(image_hdr.nr_clusters) *
2557 le32_to_cpu(image_hdr.cluster_size);
2558 } else {
2559 device_size = open_volume();
2560 ntfs_size = vol->nr_clusters * vol->cluster_size;
2561 }
2562 // FIXME: This needs to be the cluster size...
2563 ntfs_size += 512; /* add backup boot sector */
2564 full_device_size = device_size;
2565
2566 if (opt.std_out) {
2567 if ((fd_out = fileno(stdout)) == -1)
2568 perr_exit("fileno for stdout failed");
2569 stream_out = stdout;
2570#ifdef HAVE_WINDOWS_H
2571 if (setmode(fileno(stdout),O_BINARY) == -1)
2572 perr_exit("setting binary stdout failed");
2573#endif
2574 } else {
2575 /* device_size_get() might need to read() */
2576 int flags = O_RDWR | O_BINARY;
2577
2578 fd_out = 0;
2579 if (!opt.blkdev_out) {
2580 flags |= O_CREAT | O_TRUNC;
2581 if (!opt.overwrite)
2582 flags |= O_EXCL;
2583 }
2584
2585 if (opt.save_image || opt.metadata_image) {
2586 stream_out = fopen(opt.output,BINWMODE);
2587 if (!stream_out)
2588 perr_exit("Opening file '%s' failed",
2589 opt.output);
2590 fd_out = fileno(stream_out);
2591 } else {
2592#ifdef HAVE_WINDOWS_H
2593 if (!opt.no_action) {
2594 dev_out = ntfs_device_alloc(opt.output, 0,
2595 &ntfs_device_default_io_ops, NULL);
2596 if (!dev_out
2597 || (dev_out->d_ops->open)(dev_out, flags))
2598 perr_exit("Opening volume '%s' failed",
2599 opt.output);
2600 }
2601#else
2602 if (!opt.no_action
2603 && ((fd_out = open(opt.output, flags,
2604 S_IRUSR | S_IWUSR)) == -1))
2605 perr_exit("Opening file '%s' failed",
2606 opt.output);
2607#endif
2608 }
2609
2610 if (!opt.save_image && !opt.metadata_image && !opt.no_action)
2611 check_output_device(ntfs_size);
2612 }
2613
2614 if (opt.restore_image) {
2615 print_image_info();
2616 restore_image();
2617 if (!opt.no_action)
2618 fsync_clone(fd_out);
2619 exit(0);
2620 }
2621
2622 setup_lcn_bitmap();
2623 memset(&image, 0, sizeof(image));
2624 backup_clusters.image = &image;
2625
2626 walk_clusters(vol, &backup_clusters);
2627 image.more_use = compare_bitmaps(&lcn_bitmap,
2628 opt.metadata && !opt.metadata_image);
2629 print_disk_usage("", vol->cluster_size, vol->nr_clusters, image.inuse);
2630
2631 check_dest_free_space(vol->cluster_size * image.inuse);
2632
2633 ignore_bad_clusters(&image);
2634
2635 if (opt.save_image)
2636 initialise_image_hdr(device_size, image.inuse);
2637
2638 if ((opt.std_out && !opt.metadata_image) || !opt.metadata) {
2639 s64 nr_clusters_to_save = image.inuse;
2640 if (opt.std_out && !opt.save_image)
2641 nr_clusters_to_save = vol->nr_clusters;
2642 nr_clusters_to_save++; /* account for the backup boot sector */
2643
2644 clone_ntfs(nr_clusters_to_save, image.more_use);
2645 fsync_clone(fd_out);
2646 if (opt.save_image)
2647 fclose(stream_out);
2648 ntfs_umount(vol,FALSE);
2649 free(lcn_bitmap.bm);
2650 exit(0);
2651 }
2652
2653 wipe = 1;
2654 if (opt.metadata_image) {
2655 initialise_image_hdr(device_size, image.inuse);
2656 write_image_hdr();
2657 } else {
2658 if (dev_out) {
2659 (dev_out->d_ops->close)(dev_out);
2660 dev_out = NULL;
2661 } else
2662 fsync_clone(fd_out); /* sync copy before mounting */
2663 opt.volume = opt.output;
2664 /* 'force' again mount for dirty volumes (e.g. after resize).
2665 FIXME: use mount flags to avoid potential side-effects in future */
2666 opt.force++;
2667 ntfs_umount(vol,FALSE);
2668 mount_volume(0 /*NTFS_MNT_NOATIME*/);
2669 }
2670
2671 free(lcn_bitmap.bm);
2672 setup_lcn_bitmap();
2673 memset(&image, 0, sizeof(image));
2674 backup_clusters.image = &image;
2675
2676 walk_clusters(vol, &backup_clusters);
2677
2678 Printf("Num of MFT records = %10lld\n",
2679 (long long)vol->mft_na->initialized_size >>
2680 vol->mft_record_size_bits);
2681 Printf("Num of used MFT records = %10u\n", nr_used_mft_records);
2682
2683 Printf("Wiped unused MFT data = %10u\n", wiped_unused_mft_data);
2684 Printf("Wiped deleted MFT data = %10u\n", wiped_unused_mft);
2685 Printf("Wiped resident user data = %10u\n", wiped_resident_data);
2686 Printf("Wiped timestamp data = %10u\n", wiped_timestamp_data);
2687
2688 wiped_total += wiped_unused_mft_data;
2689 wiped_total += wiped_unused_mft;
2690 wiped_total += wiped_resident_data;
2691 wiped_total += wiped_timestamp_data;
2692 Printf("Wiped totally = %10u\n", wiped_total);
2693
2694 if (opt.metadata_image)
2695 fclose(stream_out);
2696 else
2697 fsync_clone(fd_out);
2698 ntfs_umount(vol,FALSE);
2699 free(lcn_bitmap.bm);
2700 return (0);
2701}
2702