diff --git a/ntfsprogs/mkntfs.c b/ntfsprogs/mkntfs.c index 9160d54d..23171552 100644 --- a/ntfsprogs/mkntfs.c +++ b/ntfsprogs/mkntfs.c @@ -98,6 +98,8 @@ #include "mst.h" #include "dir.h" #include "runlist.h" +//#include "debug.h" +#include "utils.h" extern const unsigned char attrdef_ntfs12_array[2400]; extern const unsigned char boot_array[3429]; @@ -156,11 +158,11 @@ struct { int attr_defs_len; /* in bytes */ uchar_t *upcase; /* filename, upcase table. */ u32 upcase_len; /* Determined automatically. */ - char quiet; /* -q, quiet execution. */ - char verbose; /* -v, verbose execution, given twice, + int quiet; /* -q, quiet execution. */ + int verbose; /* -v, verbose execution, given twice, * really verbose execution (debug * mode). */ - char force; /* -F, force fs creation. */ + int force; /* -F, force fs creation. */ char quick_format; /* -f or -Q, fast format, don't zero the volume first. */ char enable_compression; /* -C, enables compression of all files @@ -168,18 +170,11 @@ struct { char disable_indexing; /* -I, disables indexing of file contents on the volume by default. */ /* -V, print version and exit. */ -} opt; +} opts; -/* Error output. Ignores quiet (-q). */ -void Eprintf(const char *fmt, ...) -{ - va_list ap; - - fprintf(stderr, "ERROR: "); - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); -} +GEN_PRINTF (Eprintf, stderr, NULL, FALSE) +GEN_PRINTF (Vprintf, stdout, &opts.verbose, TRUE) +GEN_PRINTF (Qprintf, stdout, &opts.quiet, FALSE) void err_exit(const char *fmt, ...) __attribute__ ((noreturn)); @@ -201,7 +196,7 @@ void Dprintf(const char *fmt, ...) { va_list ap; - if (!opt.quiet && opt.verbose > 1) { + if (!opts.quiet && opts.verbose > 1) { printf("DEBUG: "); va_start(ap, fmt); vprintf(fmt, ap); @@ -209,45 +204,21 @@ void Dprintf(const char *fmt, ...) } } -/* Verbose output (-v). */ -void Vprintf(const char *fmt, ...) -{ - va_list ap; - - if (!opt.quiet && opt.verbose > 0) { - va_start(ap, fmt); - vprintf(fmt, ap); - va_end(ap); - } -} - -/* Quietable output (if not -q). */ -void Qprintf(const char *fmt, ...) -{ - va_list ap; - - if (!opt.quiet) { - va_start(ap, fmt); - vprintf(fmt, ap); - va_end(ap); - } -} - void append_to_bad_blocks(unsigned long block) { long long *new_buf; - if (!(opt.nr_bad_blocks & 15)) { - new_buf = realloc(opt.bad_blocks, (opt.nr_bad_blocks + 16) * + if (!(opts.nr_bad_blocks & 15)) { + new_buf = realloc(opts.bad_blocks, (opts.nr_bad_blocks + 16) * sizeof(long long)); if (!new_buf) err_exit("Reallocating memory for bad blocks list " "failed: %s\n", strerror(errno)); - if (opt.bad_blocks != new_buf) - free(opt.bad_blocks); - opt.bad_blocks = new_buf; + if (opts.bad_blocks != new_buf) + free(opts.bad_blocks); + opts.bad_blocks = new_buf; } - opt.bad_blocks[opt.nr_bad_blocks++] = block; + opts.bad_blocks[opts.nr_bad_blocks++] = block; } __inline__ long long mkntfs_write(int fd, const void *buf, long long count) @@ -255,7 +226,7 @@ __inline__ long long mkntfs_write(int fd, const void *buf, long long count) long long bytes_written, total; int retry; - if (opt.no_action) + if (opts.no_action) return count; total = 0LL; retry = 0; @@ -301,7 +272,7 @@ s64 ntfs_rlwrite(int fd, const runlist *rl, const char *val, if (inited_size) *inited_size = 0LL; - if (opt.no_action) + if (opts.no_action) return val_len; total = delta = 0LL; for (i = 0; rl[i].length; i++) { @@ -628,15 +599,15 @@ void dump_attr_record(ATTR_RECORD *a) return; } u = le32_to_cpu(a->type); - for (i = 0; opt.attr_defs[i].type; i++) - if (le32_to_cpu(opt.attr_defs[i].type) >= u) + for (i = 0; opts.attr_defs[i].type; i++) + if (le32_to_cpu(opts.attr_defs[i].type) >= u) break; - if (opt.attr_defs[i].type) { -// printf("type = 0x%x\n", le32_to_cpu(opt.attr_defs[i].type)); -// { char *p = (char*)opt.attr_defs[i].name; + if (opts.attr_defs[i].type) { +// printf("type = 0x%x\n", le32_to_cpu(opts.attr_defs[i].type)); +// { char *p = (char*)opts.attr_defs[i].name; // printf("name = %c%c%c%c%c\n", *p, p[1], p[2], p[3], p[4]); // } - if (ucstos(s, opt.attr_defs[i].name, sizeof(s)) == -1) { + if (ucstos(s, opts.attr_defs[i].name, sizeof(s)) == -1) { Eprintf("Could not convert Unicode string to single " "byte string in current locale.\n"); strncpy(s, "Error converting Unicode string", @@ -794,7 +765,7 @@ void format_mft_record(MFT_RECORD *m) a->type = AT_END; a->length = cpu_to_le32(0); #if 0 - if (!opt.quiet && opt.verbose > 1) + if (!opts.quiet && opts.verbose > 1) dump_mft_record(m); #endif } @@ -891,11 +862,11 @@ runlist *allocate_scattered_clusters(s64 clusters) s64 prev_run_len = 0LL; char bit; - end = opt.nr_clusters; + end = opts.nr_clusters; /* Loop until all clusters are allocated. */ while (clusters) { /* Loop in current zone until we run out of free clusters. */ - for (lcn = opt.mft_zone_end; lcn < end; lcn++) { + for (lcn = opts.mft_zone_end; lcn < end; lcn++) { bit = ntfs_bit_get_and_set(lcn_bitmap, lcn, 1); if (bit) continue; @@ -930,10 +901,10 @@ runlist *allocate_scattered_clusters(s64 clusters) } /* Switch to next zone, decreasing mft zone by factor 2. */ - end = opt.mft_zone_end; - opt.mft_zone_end >>= 1; + end = opts.mft_zone_end; + opts.mft_zone_end >>= 1; /* Have we run out of space on the volume? */ - if (opt.mft_zone_end <= 0) + if (opts.mft_zone_end <= 0) goto err_end; } return rl; @@ -1129,7 +1100,7 @@ int insert_positioned_attr_in_mft_record(MFT_RECORD *m, const ATTR_TYPES type, if (err >= 0) err = -EIO; Eprintf("insert_positioned_attr_in_mft_record failed with " - "error %i.\n", err < 0 ? err : bw); + "error %lld.\n", err < 0 ? err : bw); } err_out: if (ctx) @@ -1314,7 +1285,7 @@ int insert_non_resident_attr_in_mft_record(MFT_RECORD *m, const ATTR_TYPES type, if (err >= 0) err = -EIO; Eprintf("insert_non_resident_attr_in_mft_record failed with " - "error %i.\n", err < 0 ? err : bw); + "error %lld.\n", (long long) (err < 0 ? err : bw)); } err_out: if (ctx) @@ -1722,14 +1693,14 @@ int add_attr_index_root(MFT_RECORD *m, const char *name, const u32 name_len, free(r); return -EINVAL; } - if (index_block_size < opt.sector_size) { + if (index_block_size < opts.sector_size) { Eprintf("add_attr_index_root: index block size is " "smaller than the sector size.\n"); free(r); return -EINVAL; } r->clusters_per_index_block = index_block_size / - opt.sector_size; + opts.sector_size; } memset(&r->reserved, 0, sizeof(r->reserved)); r->index.entries_offset = cpu_to_le32(sizeof(INDEX_HEADER)); @@ -2250,11 +2221,11 @@ int create_hardlink(INDEX_BLOCK *index, const MFT_REF ref_parent, void init_options() { - memset(&opt, 0, sizeof(opt)); - opt.index_block_size = 4096; - opt.attr_defs = (ATTR_DEF*)&attrdef_ntfs12_array; - opt.attr_defs_len = sizeof(attrdef_ntfs12_array); - //Dprintf("Attr_defs table length = %u\n", opt.attr_defs_len); + memset(&opts, 0, sizeof(opts)); + opts.index_block_size = 4096; + opts.attr_defs = (ATTR_DEF*)&attrdef_ntfs12_array; + opts.attr_defs_len = sizeof(attrdef_ntfs12_array); + //Dprintf("Attr_defs table length = %u\n", opts.attr_defs_len); } void usage(void) __attribute__ ((noreturn)); @@ -2285,7 +2256,7 @@ void parse_options(int argc, char *argv[]) while ((c = getopt(argc, argv, "c:fnqs:vz:CFIL:QV")) != EOF) switch (c) { case 'n': - opt.no_action = 1; + opts.no_action = 1; break; case 'c': l = strtol(optarg, &s, 0); @@ -2295,34 +2266,34 @@ void parse_options(int argc, char *argv[]) break; case 'f': case 'Q': - opt.quick_format = 1; + opts.quick_format = 1; break; case 'q': - opt.quiet = 1; + opts.quiet = 1; break; case 's': l = strtol(optarg, &s, 0); if (!l || l > INT_MAX || *s) err_exit("Invalid sector size.\n"); - opt.sector_size = l; + opts.sector_size = l; break; case 'v': - opt.verbose++; + opts.verbose++; break; case 'z': l = strtol(optarg, &s, 0); if (l < 1 || l > 4 || *s) err_exit("Invalid MFT zone multiplier.\n"); - opt.mft_zone_multiplier = l; + opts.mft_zone_multiplier = l; break; case 'C': - opt.enable_compression = 1; + opts.enable_compression = 1; break; case 'F': - opt.force = 1; + opts.force = 1; break; case 'I': - opt.disable_indexing = 1; + opts.disable_indexing = 1; break; case 'L': vol->vol_name = optarg; @@ -2341,7 +2312,7 @@ void parse_options(int argc, char *argv[]) if (*s || !u || (u >= ULONG_MAX && errno == ERANGE)) err_exit("Invalid number of sectors: %s\n", argv[optind - 1]); - opt.nr_sectors = u; + opts.nr_sectors = u; } if (optind < argc) usage(); @@ -2377,10 +2348,10 @@ void mkntfs_exit(void) free(rl_bad); if (rl_index) free(rl_index); - if (opt.bad_blocks) - free(opt.bad_blocks); - if (opt.attr_defs != (ATTR_DEF*)attrdef_ntfs12_array) - free(opt.attr_defs); + if (opts.bad_blocks) + free(opts.bad_blocks); + if (opts.attr_defs != (ATTR_DEF*)attrdef_ntfs12_array) + free(opts.attr_defs); if (vol->upcase) free(vol->upcase); flk.l_type = F_UNLCK; @@ -2396,10 +2367,10 @@ void mkntfs_exit(void) free(vol); } +// What's wrong with MK_MREF? #define MAKE_MFT_REF(_ref, _seqno) cpu_to_le64((((u64)(_seqno)) << 48) \ | ((u64)(_ref))) - int main(int argc, char **argv) { int i, j, err; @@ -2430,7 +2401,7 @@ int main(int argc, char **argv) if (!vol->upcase) err_exit("Could not allocate memory for internal buffer.\n"); init_upcase_table(vol->upcase, vol->upcase_len * sizeof(uchar_t)); - /* Initialize opt to zero / required values. */ + /* Initialize opts to zero / required values. */ init_options(); /* Parse command line options. */ parse_options(argc, argv); @@ -2444,25 +2415,25 @@ int main(int argc, char **argv) } if (!S_ISBLK(sbuf.st_mode)) { Eprintf("%s is not a block device.\n", vol->dev_name); - if (!opt.force) + if (!opts.force) err_exit("Refusing to make a filesystem here!\n"); - if (!opt.nr_sectors) { + if (!opts.nr_sectors) { if (!sbuf.st_size && !sbuf.st_blocks) err_exit("You must specify the number of " "sectors.\n"); - if (opt.sector_size) { + if (opts.sector_size) { if (sbuf.st_size) - opt.nr_sectors = sbuf.st_size / - opt.sector_size; + opts.nr_sectors = sbuf.st_size / + opts.sector_size; else - opt.nr_sectors = ((s64)sbuf.st_blocks - << 9) / opt.sector_size; + opts.nr_sectors = ((s64)sbuf.st_blocks + << 9) / opts.sector_size; } else { if (sbuf.st_size) - opt.nr_sectors = sbuf.st_size / 512; + opts.nr_sectors = sbuf.st_size / 512; else - opt.nr_sectors = sbuf.st_blocks; - opt.sector_size = 512; + opts.nr_sectors = sbuf.st_blocks; + opts.sector_size = 512; } } fprintf(stderr, "mkntfs forced anyway.\n"); @@ -2482,14 +2453,14 @@ int main(int argc, char **argv) vol->dev_name, strerror(errno)); else if (mnt_flags & NTFS_MF_MOUNTED) { Eprintf("%s is mounted.\n", vol->dev_name); - if (!opt.force) + if (!opts.force) err_exit("Refusing to make a filesystem here!\n"); fprintf(stderr, "mkntfs forced anyway. Hope /etc/mtab is " "incorrect.\n"); } /* Open the device for reading or reading and writing. */ - if (opt.no_action) { + if (opts.no_action) { Qprintf("Running in READ-ONLY mode!\n"); i = O_RDONLY; } else @@ -2500,7 +2471,7 @@ int main(int argc, char **argv) strerror(errno)); /* Acquire exlusive (mandatory) write lock on the whole device. */ memset(&flk, 0, sizeof(flk)); - if (opt.no_action) + if (opts.no_action) flk.l_type = F_RDLCK; else flk.l_type = F_WRLCK; @@ -2509,7 +2480,7 @@ int main(int argc, char **argv) err = fcntl(vol->fd, F_SETLK, &flk); if (err == -1) { Eprintf("Could not lock %s for %s: %s\n", vol->dev_name, - opt.no_action ? "reading" : "writing", + opts.no_action ? "reading" : "writing", strerror(errno)); err = close(vol->fd); if (err == -1) @@ -2526,12 +2497,12 @@ int main(int argc, char **argv) exit(1); } /* If user didn't specify the sector size, determine it now. */ - if (!opt.sector_size) { + if (!opts.sector_size) { #ifdef BLKSSZGET int _sect_size = 0; if (ioctl(vol->fd, BLKSSZGET, &_sect_size) >= 0) - opt.sector_size = _sect_size; + opts.sector_size = _sect_size; else #endif { @@ -2539,57 +2510,57 @@ int main(int argc, char **argv) "not be obtained automatically.\n" "Assuming sector size is 512 bytes.\n", vol->dev_name); - opt.sector_size = 512; + opts.sector_size = 512; } } /* Validate sector size. */ - if ((opt.sector_size - 1) & opt.sector_size || - opt.sector_size < 256 || opt.sector_size > 4096) + if ((opts.sector_size - 1) & opts.sector_size || + opts.sector_size < 256 || opts.sector_size > 4096) err_exit("Error: sector_size is invalid. It must be a power " "of two, and it must be\n greater or equal 256 and " "less than or equal 4096 bytes.\n"); - Dprintf("sector size = %i bytes\n", opt.sector_size); + Dprintf("sector size = %i bytes\n", opts.sector_size); /* If user didn't specify the number of sectors, determine it now. */ - if (!opt.nr_sectors) { - opt.nr_sectors = ntfs_device_size_get(vol->fd, opt.sector_size); - if (opt.nr_sectors <= 0) + if (!opts.nr_sectors) { + opts.nr_sectors = ntfs_device_size_get(vol->fd, opts.sector_size); + if (opts.nr_sectors <= 0) err_exit("ntfs_device_size_get(%s) failed. Please " "specify it manually.\n", vol->dev_name); } - Dprintf("number of sectors = %Ld (0x%Lx)\n", opt.nr_sectors, - opt.nr_sectors); + Dprintf("number of sectors = %Ld (0x%Lx)\n", opts.nr_sectors, + opts.nr_sectors); /* Reserve the last sector for the backup boot sector. */ - opt.nr_sectors--; + opts.nr_sectors--; /* If user didn't specify the volume size, determine it now. */ - if (!opt.volume_size) - opt.volume_size = opt.nr_sectors * opt.sector_size; - else if (opt.volume_size & (opt.sector_size - 1)) + if (!opts.volume_size) + opts.volume_size = opts.nr_sectors * opts.sector_size; + else if (opts.volume_size & (opts.sector_size - 1)) err_exit("Error: volume_size is not a multiple of " "sector_size.\n"); /* Validate volume size. */ - if (opt.volume_size < 1 << 20 /* 1MiB */) + if (opts.volume_size < 1 << 20 /* 1MiB */) err_exit("Error: device is too small (%ikiB). Minimum NTFS " - "volume size is 1MiB.\n", opt.volume_size / 1024); - Dprintf("volume size = %LikiB\n", opt.volume_size / 1024); + "volume size is 1MiB.\n", opts.volume_size / 1024); + Dprintf("volume size = %LikiB\n", opts.volume_size / 1024); /* If user didn't specify the cluster size, determine it now. */ if (!vol->cluster_size) { - if (opt.volume_size <= 512LL << 20) /* <= 512MB */ + if (opts.volume_size <= 512LL << 20) /* <= 512MB */ vol->cluster_size = 512; - else if (opt.volume_size <= 1LL << 30) /* ]512MB-1GB] */ + else if (opts.volume_size <= 1LL << 30) /* ]512MB-1GB] */ vol->cluster_size = 1024; - else if (opt.volume_size <= 2LL << 30) /* ]1GB-2GB] */ + else if (opts.volume_size <= 2LL << 30) /* ]1GB-2GB] */ vol->cluster_size = 2048; else vol->cluster_size = 4096; /* For small volumes on devices with large sector sizes. */ - if (vol->cluster_size < opt.sector_size) - vol->cluster_size = opt.sector_size; + if (vol->cluster_size < opts.sector_size) + vol->cluster_size = opts.sector_size; } /* Validate cluster size. */ if (vol->cluster_size & (vol->cluster_size - 1) || - vol->cluster_size < opt.sector_size || - vol->cluster_size > 128 * opt.sector_size || + vol->cluster_size < opts.sector_size || + vol->cluster_size > 128 * opts.sector_size || vol->cluster_size > 65536) err_exit("Error: cluster_size is invalid. It must be a power " "of two, be at least\nthe same as sector_size, be " @@ -2599,15 +2570,15 @@ int main(int argc, char **argv) vol->cluster_size_bits = ffs(vol->cluster_size) - 1; Dprintf("cluster size = %i bytes\n", vol->cluster_size); if (vol->cluster_size > 4096) { - if (opt.enable_compression) { - if (!opt.force) + if (opts.enable_compression) { + if (!opts.force) err_exit("Error: cluster_size is above 4096 " "bytes and compression is " "requested.\nThis is not " "possible due to limitations " "in the compression algorithm " "used by\nWindows.\n"); - opt.enable_compression = 0; + opts.enable_compression = 0; } Qprintf("Warning: compression will be disabled on this volume " "because it is not\nsupported when the cluster " @@ -2616,23 +2587,23 @@ int main(int argc, char **argv) "by Windows.\n"); } /* If user didn't specify the number of clusters, determine it now. */ - if (!opt.nr_clusters) - opt.nr_clusters = opt.volume_size / vol->cluster_size; + if (!opts.nr_clusters) + opts.nr_clusters = opts.volume_size / vol->cluster_size; /* * Check the cluster_size and nr_sectors for consistency with * sector_size and nr_sectors. And check both of these for consistency * with volume_size. */ - if (opt.nr_clusters != (opt.nr_sectors * opt.sector_size) / + if (opts.nr_clusters != (opts.nr_sectors * opts.sector_size) / vol->cluster_size || - opt.volume_size / opt.sector_size != opt.nr_sectors || - opt.volume_size / vol->cluster_size != opt.nr_clusters) + opts.volume_size / opts.sector_size != opts.nr_sectors || + opts.volume_size / vol->cluster_size != opts.nr_clusters) err_exit("Illegal combination of volume/cluster/sector size " "and/or cluster/sector number.\n"); - Dprintf("number of clusters = %Lu (0x%Lx)\n", opt.nr_clusters, - opt.nr_clusters); + Dprintf("number of clusters = %Lu (0x%Lx)\n", opts.nr_clusters, + opts.nr_clusters); /* Determine lcn bitmap byte size and allocate it. */ - lcn_bitmap_byte_size = (opt.nr_clusters + 7) >> 3; + lcn_bitmap_byte_size = (opts.nr_clusters + 7) >> 3; /* Needs to be multiple of 8 bytes. */ lcn_bitmap_byte_size = (lcn_bitmap_byte_size + 7) & ~7; i = (lcn_bitmap_byte_size + vol->cluster_size - 1) & @@ -2647,17 +2618,17 @@ int main(int argc, char **argv) * $Bitmap can overlap the end of the volume. Any bits in this region * must be set. This region also encompasses the backup boot sector. */ - for (i = opt.nr_clusters; i < lcn_bitmap_byte_size << 3; i++) + for (i = opts.nr_clusters; i < lcn_bitmap_byte_size << 3; i++) ntfs_bit_set(lcn_bitmap, (u64)i, 1); /* * Determine mft_size: 16 mft records or 1 cluster, which ever is * bigger, rounded to multiples of cluster size. */ - opt.mft_size = (16 * vol->mft_record_size + vol->cluster_size - 1) + opts.mft_size = (16 * vol->mft_record_size + vol->cluster_size - 1) & ~(vol->cluster_size - 1); - Dprintf("MFT size = %i (0x%x) bytes\n", opt.mft_size, opt.mft_size); + Dprintf("MFT size = %i (0x%x) bytes\n", opts.mft_size, opts.mft_size); /* Determine mft bitmap size and allocate it. */ - mft_bitmap_size = opt.mft_size / vol->mft_record_size; + mft_bitmap_size = opts.mft_size / vol->mft_record_size; /* Convert to bytes, at least one. */ mft_bitmap_byte_size = (mft_bitmap_size + 7) >> 3; /* Mft bitmap is allocated in multiples of 8 bytes. */ @@ -2687,66 +2658,66 @@ int main(int argc, char **argv) /* Allocate cluster for mft bitmap. */ ntfs_bit_set(lcn_bitmap, (s64)j, 1); /* If user didn't specify the mft lcn, determine it now. */ - if (!opt.mft_lcn) { + if (!opts.mft_lcn) { /* * We start at the higher value out of 16kiB and just after the * mft bitmap. */ - opt.mft_lcn = rl_mft_bmp[0].lcn + rl_mft_bmp[0].length; - if (opt.mft_lcn * vol->cluster_size < 16 * 1024) - opt.mft_lcn = (16 * 1024 + vol->cluster_size - 1) / + opts.mft_lcn = rl_mft_bmp[0].lcn + rl_mft_bmp[0].length; + if (opts.mft_lcn * vol->cluster_size < 16 * 1024) + opts.mft_lcn = (16 * 1024 + vol->cluster_size - 1) / vol->cluster_size; } - Dprintf("$MFT logical cluster number = 0x%x\n", opt.mft_lcn); + Dprintf("$MFT logical cluster number = 0x%x\n", opts.mft_lcn); /* Determine MFT zone size. */ - opt.mft_zone_end = opt.nr_clusters; - switch (opt.mft_zone_multiplier) { /* % of volume size in clusters */ + opts.mft_zone_end = opts.nr_clusters; + switch (opts.mft_zone_multiplier) { /* % of volume size in clusters */ case 4: - opt.mft_zone_end = opt.mft_zone_end >> 1; /* 50% */ + opts.mft_zone_end = opts.mft_zone_end >> 1; /* 50% */ break; case 3: - opt.mft_zone_end = opt.mft_zone_end * 3 >> 3; /* 37.5% */ + opts.mft_zone_end = opts.mft_zone_end * 3 >> 3; /* 37.5% */ break; case 2: - opt.mft_zone_end = opt.mft_zone_end >> 2; /* 25% */ + opts.mft_zone_end = opts.mft_zone_end >> 2; /* 25% */ break; /* case 1: */ default: - opt.mft_zone_end = opt.mft_zone_end >> 3; /* 12.5% */ + opts.mft_zone_end = opts.mft_zone_end >> 3; /* 12.5% */ break; } - Dprintf("MFT zone size = %lukiB\n", opt.mft_zone_end / 1024); + Dprintf("MFT zone size = %lukiB\n", opts.mft_zone_end / 1024); /* * The mft zone begins with the mft data attribute, not at the beginning * of the device. */ - opt.mft_zone_end += opt.mft_lcn; + opts.mft_zone_end += opts.mft_lcn; /* Create runlist for mft. */ rl_mft = (runlist *)malloc(2 * sizeof(runlist)); if (!rl_mft) err_exit("Failed to allocate internal buffer: %s\n", strerror(errno)); rl_mft[0].vcn = 0LL; - rl_mft[0].lcn = opt.mft_lcn; + rl_mft[0].lcn = opts.mft_lcn; /* We already rounded mft size up to a cluster. */ - j = opt.mft_size / vol->cluster_size; + j = opts.mft_size / vol->cluster_size; rl_mft[1].vcn = rl_mft[0].length = j; rl_mft[1].lcn = -1LL; rl_mft[1].length = 0LL; /* Allocate clusters for mft. */ for (i = 0; i < j; i++) - ntfs_bit_set(lcn_bitmap, opt.mft_lcn + i, 1); + ntfs_bit_set(lcn_bitmap, opts.mft_lcn + i, 1); /* Determine mftmirr_lcn (middle of volume). */ - opt.mftmirr_lcn = (opt.nr_sectors * opt.sector_size >> 1) + opts.mftmirr_lcn = (opts.nr_sectors * opts.sector_size >> 1) / vol->cluster_size; - Dprintf("$MFTMirr logical cluster number = 0x%x\n", opt.mftmirr_lcn); + Dprintf("$MFTMirr logical cluster number = 0x%x\n", opts.mftmirr_lcn); /* Create runlist for mft mirror. */ rl_mftmirr = (runlist *)malloc(2 * sizeof(runlist)); if (!rl_mftmirr) err_exit("Failed to allocate internal buffer: %s\n", strerror(errno)); rl_mftmirr[0].vcn = 0LL; - rl_mftmirr[0].lcn = opt.mftmirr_lcn; + rl_mftmirr[0].lcn = opts.mftmirr_lcn; /* * The mft mirror is either 4kb (the first four records) or one cluster * in size, which ever is bigger. In either case, it contains a @@ -2760,49 +2731,49 @@ int main(int argc, char **argv) rl_mftmirr[1].length = 0LL; /* Allocate clusters for mft mirror. */ for (i = 0; i < j; i++) - ntfs_bit_set(lcn_bitmap, opt.mftmirr_lcn + i, 1); - opt.logfile_lcn = opt.mftmirr_lcn + j; - Dprintf("$LogFile logical cluster number = 0x%x\n", opt.logfile_lcn); + ntfs_bit_set(lcn_bitmap, opts.mftmirr_lcn + i, 1); + opts.logfile_lcn = opts.mftmirr_lcn + j; + Dprintf("$LogFile logical cluster number = 0x%x\n", opts.logfile_lcn); /* Create runlist for log file. */ rl_logfile = (runlist *)malloc(2 * sizeof(runlist)); if (!rl_logfile) err_exit("Failed to allocate internal buffer: %s\n", strerror(errno)); rl_logfile[0].vcn = 0LL; - rl_logfile[0].lcn = opt.logfile_lcn; + rl_logfile[0].lcn = opts.logfile_lcn; /* * Determine logfile_size from volume_size (rounded up to a cluster), * making sure it does not overflow the end of the volume. */ - if (opt.volume_size < 2048LL * 1024) /* < 2MiB */ - opt.logfile_size = 256LL * 1024; /* -> 256kiB */ - else if (opt.volume_size < 4000000LL) /* < 4MB */ - opt.logfile_size = 512LL * 1024; /* -> 512kiB */ - else if (opt.volume_size <= 200LL * 1024 * 1024)/* < 200MiB */ - opt.logfile_size = 2048LL * 1024; /* -> 2MiB */ - else if (opt.volume_size >= 400LL << 20) /* > 400MiB */ - opt.logfile_size = 4 << 20; /* -> 4MiB */ + if (opts.volume_size < 2048LL * 1024) /* < 2MiB */ + opts.logfile_size = 256LL * 1024; /* -> 256kiB */ + else if (opts.volume_size < 4000000LL) /* < 4MB */ + opts.logfile_size = 512LL * 1024; /* -> 512kiB */ + else if (opts.volume_size <= 200LL * 1024 * 1024)/* < 200MiB */ + opts.logfile_size = 2048LL * 1024; /* -> 2MiB */ + else if (opts.volume_size >= 400LL << 20) /* > 400MiB */ + opts.logfile_size = 4 << 20; /* -> 4MiB */ else - opt.logfile_size = (opt.volume_size / 100) & + opts.logfile_size = (opts.volume_size / 100) & ~(vol->cluster_size - 1); - j = opt.logfile_size / vol->cluster_size; - while (rl_logfile[0].lcn + j >= opt.nr_clusters) { + j = opts.logfile_size / vol->cluster_size; + while (rl_logfile[0].lcn + j >= opts.nr_clusters) { /* * $Logfile would overflow volume. Need to make it smaller than * the standard size. It's ok as we are creating a non-standard * volume anyway if it is that small. */ - opt.logfile_size >>= 1; - j = opt.logfile_size / vol->cluster_size; + opts.logfile_size >>= 1; + j = opts.logfile_size / vol->cluster_size; } - opt.logfile_size = (opt.logfile_size + vol->cluster_size - 1) & + opts.logfile_size = (opts.logfile_size + vol->cluster_size - 1) & ~(vol->cluster_size - 1); - Dprintf("$LogFile (journal) size = %ikiB\n", opt.logfile_size / 1024); + Dprintf("$LogFile (journal) size = %ikiB\n", opts.logfile_size / 1024); /* * FIXME: The 256kiB limit is arbitrary. Should find out what the real * minimum requirement for Windows is so it doesn't blue screen. */ - if (opt.logfile_size < 256 << 10) + if (opts.logfile_size < 256 << 10) err_exit("$LogFile would be created with invalid size. This " "is not allowed as it would cause Windows to " "blue screen and during boot.\n"); @@ -2811,7 +2782,7 @@ int main(int argc, char **argv) rl_logfile[1].length = 0LL; /* Allocate clusters for log file. */ for (i = 0; i < j; i++) - ntfs_bit_set(lcn_bitmap, opt.logfile_lcn + i, 1); + ntfs_bit_set(lcn_bitmap, opts.logfile_lcn + i, 1); /* Create runlist for $Boot. */ rl_boot = (runlist *)malloc(2 * sizeof(runlist)); if (!rl_boot) @@ -2831,7 +2802,7 @@ int main(int argc, char **argv) for (i = 0; i < j; i++) ntfs_bit_set(lcn_bitmap, 0LL + i, 1); /* Allocate a buffer large enough to hold the mft. */ - buf = calloc(1, opt.mft_size); + buf = calloc(1, opts.mft_size); if (!buf) err_exit("Failed to allocate internal buffer: %s\n", strerror(errno)); @@ -2846,7 +2817,7 @@ int main(int argc, char **argv) * $BadClus named stream $Bad contains the whole volume as a single * sparse runlist entry. */ - rl_bad[1].vcn = rl_bad[0].length = opt.nr_clusters; + rl_bad[1].vcn = rl_bad[0].length = opts.nr_clusters; rl_bad[1].lcn = -1LL; rl_bad[1].length = 0LL; @@ -2856,15 +2827,15 @@ int main(int argc, char **argv) * If not quick format, fill the device with 0s. * FIXME: Except bad blocks! (AIA) */ - if (!opt.quick_format) { + if (!opts.quick_format) { unsigned long position; unsigned long mid_clust; - float progress_inc = (float)opt.nr_clusters / 100; + float progress_inc = (float)opts.nr_clusters / 100; Qprintf("Initialising device with zeroes: 0%%"); fflush(stdout); - mid_clust = (opt.volume_size >> 1) / vol->cluster_size; - for (position = 0; position < opt.nr_clusters; position++) { + mid_clust = (opts.volume_size >> 1) / vol->cluster_size; + for (position = 0; position < opts.nr_clusters; position++) { if (!(position % (int)(progress_inc+1))) { Qprintf("\b\b\b\b%3.0f%%", position / progress_inc); @@ -2889,7 +2860,7 @@ int main(int argc, char **argv) append_to_bad_blocks(position); Qprintf("\nFound bad cluster (%ld). Adding to " "list of bad blocks.\nInitialising " - "device with zeroes: %3.0i%%", position, + "device with zeroes: %3.0f%%", position, position / progress_inc); /* Seek to next cluster. */ lseek(vol->fd, ((off_t)position + 1) * @@ -2897,11 +2868,11 @@ int main(int argc, char **argv) } } Qprintf("\b\b\b\b100%%"); - position = (opt.volume_size & (vol->cluster_size - 1)) / - opt.sector_size; + position = (opts.volume_size & (vol->cluster_size - 1)) / + opts.sector_size; for (i = 0; i < position; i++) { - bw = mkntfs_write(vol->fd, buf, opt.sector_size); - if (bw != opt.sector_size) { + bw = mkntfs_write(vol->fd, buf, opts.sector_size); + if (bw != opts.sector_size) { if (bw != -1 || errno != EIO) err_exit("This should not happen.\n"); else if (i + 1 == position && @@ -2912,7 +2883,7 @@ int main(int argc, char **argv) "location reserved for system " "file $Boot.\n"); /* Seek to next sector. */ - lseek(vol->fd, opt.sector_size, SEEK_CUR); + lseek(vol->fd, opts.sector_size, SEEK_CUR); } } Qprintf(" - Done.\n"); @@ -2951,9 +2922,9 @@ int main(int argc, char **argv) ntfs_bit_set(mft_bitmap, 0LL + i, 1); file_attrs = FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM; if (i == FILE_root) { - if (opt.disable_indexing) + if (opts.disable_indexing) file_attrs |= FILE_ATTR_NOT_CONTENT_INDEXED; - if (opt.enable_compression) + if (opts.enable_compression) file_attrs |= FILE_ATTR_COMPRESSED; } add_attr_std_info(m, file_attrs); @@ -2976,7 +2947,7 @@ int main(int argc, char **argv) // FIXME: This should be IGNORE_CASE if (!err) err = add_attr_index_root(m, "$I30", 4, 0, AT_FILE_NAME, - COLLATION_FILE_NAME, opt.index_block_size); + COLLATION_FILE_NAME, opts.index_block_size); // FIXME: This should be IGNORE_CASE if (!err) err = upgrade_to_large_index(m, "$I30", 4, 0, &index_block); @@ -3006,11 +2977,11 @@ int main(int argc, char **argv) Vprintf("Creating $MFT (mft record 0)\n"); m = (MFT_RECORD*)buf; err = add_attr_data_positioned(m, NULL, 0, 0, 0, rl_mft, buf, - opt.mft_size); + opts.mft_size); if (!err) err = create_hardlink(index_block, root_ref, m, - MAKE_MFT_REF(FILE_MFT, 1), opt.mft_size, - opt.mft_size, FILE_ATTR_HIDDEN | + MAKE_MFT_REF(FILE_MFT, 1), opts.mft_size, + opts.mft_size, FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0, "$MFT", FILE_NAME_WIN32_AND_DOS); if (!err) { @@ -3044,19 +3015,19 @@ int main(int argc, char **argv) //dump_mft_record(m); Vprintf("Creating $LogFile (mft record 2)\n"); m = (MFT_RECORD*)(buf + 2 * vol->mft_record_size); - buf2 = malloc(opt.logfile_size); + buf2 = malloc(opts.logfile_size); if (!buf2) err_exit("Failed to allocate internal buffer: %s\n", strerror(errno)); - memset(buf2, -1, opt.logfile_size); + memset(buf2, -1, opts.logfile_size); err = add_attr_data_positioned(m, NULL, 0, 0, 0, rl_logfile, buf2, - opt.logfile_size); + opts.logfile_size); free(buf2); buf2 = NULL; if (!err) err = create_hardlink(index_block, root_ref, m, MAKE_MFT_REF(FILE_LogFile, FILE_LogFile), - opt.logfile_size, opt.logfile_size, + opts.logfile_size, opts.logfile_size, FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0, "$LogFile", FILE_NAME_WIN32_AND_DOS); if (!err) { @@ -3095,12 +3066,12 @@ int main(int argc, char **argv) if (vol->major_ver < 3) buf2_size = 36000; else - buf2_size = opt.attr_defs_len; + buf2_size = opts.attr_defs_len; buf2 = (char*)calloc(1, buf2_size); if (!buf2) err_exit("Failed to allocate internal buffer: %s\n", strerror(errno)); - memcpy(buf2, opt.attr_defs, opt.attr_defs_len); + memcpy(buf2, opts.attr_defs, opts.attr_defs_len); err = add_attr_data(m, NULL, 0, 0, 0, buf2, buf2_size); free(buf2); buf2 = NULL; @@ -3149,18 +3120,18 @@ int main(int argc, char **argv) * already inserted, so no need to worry about these things. */ bs = (NTFS_BOOT_SECTOR*)buf2; - bs->bpb.bytes_per_sector = cpu_to_le16(opt.sector_size); + bs->bpb.bytes_per_sector = cpu_to_le16(opts.sector_size); bs->bpb.sectors_per_cluster = (u8)(vol->cluster_size / - opt.sector_size); + opts.sector_size); bs->bpb.media_type = 0xf8; /* hard disk */ /* * If there are problems go back to bs->unused[0-3] and set them. See * ../include/bootsect.h for details. Other fields to also consider * setting are: bs->bpb.sectors_per_track, .heads, and .hidden_sectors. */ - bs->number_of_sectors = scpu_to_le64(opt.nr_sectors); - bs->mft_lcn = scpu_to_le64(opt.mft_lcn); - bs->mftmirr_lcn = scpu_to_le64(opt.mftmirr_lcn); + bs->number_of_sectors = scpu_to_le64(opts.nr_sectors); + bs->mft_lcn = scpu_to_le64(opts.mft_lcn); + bs->mftmirr_lcn = scpu_to_le64(opts.mftmirr_lcn); if (vol->mft_record_size >= vol->cluster_size) bs->clusters_per_mft_record = vol->mft_record_size / vol->cluster_size; @@ -3174,13 +3145,13 @@ int main(int argc, char **argv) Dprintf("Clusters per mft record = %i (0x%x)\n", bs->clusters_per_mft_record, bs->clusters_per_mft_record); - if (opt.index_block_size >= vol->cluster_size) - bs->clusters_per_index_record = opt.index_block_size / + if (opts.index_block_size >= vol->cluster_size) + bs->clusters_per_index_record = opts.index_block_size / vol->cluster_size; else { - bs->clusters_per_index_record = -(ffs(opt.index_block_size) - 1); + bs->clusters_per_index_record = -(ffs(opts.index_block_size) - 1); if ((1 << -bs->clusters_per_index_record) != - opt.index_block_size) + opts.index_block_size) err_exit("BUG: calculated clusters_per_index_record " "is wrong (= 0x%x)\n", bs->clusters_per_index_record); @@ -3197,7 +3168,7 @@ int main(int argc, char **argv) */ bs->checksum = cpu_to_le32(0); /* Make sure the bootsector is ok. */ - if (!ntfs_boot_sector_is_ntfs(bs, opt.verbose > 0 ? 0 : 1)) + if (!ntfs_boot_sector_is_ntfs(bs, opts.verbose > 0 ? 0 : 1)) err_exit("FATAL: Generated boot sector is invalid!\n"); err = add_attr_data_positioned(m, NULL, 0, 0, 0, rl_boot, buf2, 8192); if (!err) @@ -3215,10 +3186,10 @@ int main(int argc, char **argv) err_exit("Couldn't create $Boot: %s\n", strerror(-err)); Vprintf("Creating backup boot sector.\n"); /* - * Write the first max(512, opt.sector_size) bytes from buf2 to the + * Write the first max(512, opts.sector_size) bytes from buf2 to the * last sector. */ - if (lseek(vol->fd, (opt.nr_sectors + 1) * opt.sector_size - i, + if (lseek(vol->fd, (opts.nr_sectors + 1) * opts.sector_size - i, SEEK_SET) == (off_t)-1) goto bb_err; bw = mkntfs_write(vol->fd, buf2, i); @@ -3249,7 +3220,7 @@ bb_err: // FIXME: This should be IGNORE_CASE /* Create a sparse named stream of size equal to the volume size. */ err = add_attr_data_positioned(m, "$Bad", 4, 0, 0, rl_bad, NULL, - opt.nr_clusters * vol->cluster_size); + opts.nr_clusters * vol->cluster_size); if (!err) { err = add_attr_data(m, NULL, 0, 0, 0, NULL, 0); } @@ -3301,7 +3272,7 @@ bb_err: //dump_mft_record(m); /* NTFS 1.2 reserved system files (mft records 0xb-0xf) */ for (i = 0xb; i < 0x10; i++) { - Vprintf("Creating system file (mft record 0x%x)\n", i, i); + Vprintf("Creating system file (mft record 0x%x)\n", i); m = (MFT_RECORD*)(buf + i * vol->mft_record_size); err = add_attr_data(m, NULL, 0, 0, 0, NULL, 0); if (!err) { @@ -3391,10 +3362,10 @@ bb_err: * its creation. */ Vprintf("Syncing $MFT.\n"); - pos = opt.mft_lcn * vol->cluster_size; + pos = opts.mft_lcn * vol->cluster_size; lw = 1; - for (i = 0; i < opt.mft_size / vol->mft_record_size; i++) { - if (!opt.no_action) + for (i = 0; i < opts.mft_size / vol->mft_record_size; i++) { + if (!opts.no_action) lw = ntfs_mst_pwrite(vol->fd, pos, 1, vol->mft_record_size, buf + i * vol->mft_record_size); @@ -3404,7 +3375,7 @@ bb_err: pos += vol->mft_record_size; } Vprintf("Updating $MFTMirr.\n"); - pos = opt.mftmirr_lcn * vol->cluster_size; + pos = opts.mftmirr_lcn * vol->cluster_size; lw = 1; for (i = 0; i < rl_mftmirr[0].length * vol->cluster_size / vol->mft_record_size; i++) { @@ -3421,7 +3392,7 @@ bb_err: if (usn-- <= 1) usn = 0xfffe; *usnp = cpu_to_le16(usn); - if (!opt.no_action) + if (!opts.no_action) lw = ntfs_mst_pwrite(vol->fd, pos, 1, vol->mft_record_size, buf + i * vol->mft_record_size);