1 /**
   2  * mkntfs - Part of the Linux-NTFS project.
   3  *
   4  * Copyright (c) 2000-2007 Anton Altaparmakov
   5  * Copyright (c) 2001-2005 Richard Russon
   6  * Copyright (c) 2002-2006 Szabolcs Szakacsits
   7  * Copyright (c) 2005      Erik Sornes
   8  * Copyright (c) 2007      Yura Pakhuchiy
   9  *
  10  * This utility will create an NTFS 1.2 or 3.1 volume on a user
  11  * specified (block) device.
  12  *
  13  * Some things (option handling and determination of mount status) have been
  14  * adapted from e2fsprogs-1.19 and lib/ext2fs/ismounted.c and misc/mke2fs.c in
  15  * particular.
  16  *
  17  * This program is free software; you can redistribute it and/or modify
  18  * it under the terms of the GNU General Public License as published by
  19  * the Free Software Foundation; either version 2 of the License, or
  20  * (at your option) any later version.
  21  *
  22  * This program is distributed in the hope that it will be useful,
  23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  25  * GNU General Public License for more details.
  26  *
  27  * You should have received a copy of the GNU General Public License
  28  * along with this program (in the main directory of the Linux-NTFS source
  29  * in the file COPYING); if not, write to the Free Software Foundation,
  30  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  31  */
  32 
  33 #ifdef HAVE_CONFIG_H
  34 #include "config.h"
  35 #endif
  36 
  37 #ifdef  HAVE_UNISTD_H
  38 #include <unistd.h>
  39 #endif
  40 #ifdef HAVE_STDLIB_H
  41 #include <stdlib.h>
  42 #endif
  43 #ifdef HAVE_STDIO_H
  44 #include <stdio.h>
  45 #endif
  46 #ifdef HAVE_STDARG_H
  47 #include <stdarg.h>
  48 #endif
  49 #ifdef HAVE_STRING_H
  50 #include <string.h>
  51 #endif
  52 #ifdef HAVE_ERRNO_H
  53 #include <errno.h>
  54 #endif
  55 #ifdef HAVE_TIME_H
  56 #include <time.h>
  57 #endif
  58 #ifdef HAVE_SYS_STAT_H
  59 #include <sys/stat.h>
  60 #endif
  61 #ifdef HAVE_FCNTL_H
  62 #include <fcntl.h>
  63 #endif
  64 #ifdef HAVE_LIMITS_H
  65 #include <limits.h>
  66 #endif
  67 #ifdef HAVE_LIBGEN_H
  68 #include <libgen.h>
  69 #endif
  70 #ifdef ENABLE_UUID
  71 #include <uuid/uuid.h>
  72 #endif
  73 
  74 
  75 #ifdef HAVE_GETOPT_H
  76 #include <getopt.h>
  77 #else
  78         extern char *optarg;
  79         extern int optind;
  80 #endif
  81 
  82 #ifdef HAVE_LINUX_MAJOR_H
  83 #       include <linux/major.h>
  84 #       ifndef MAJOR
  85 #               define MAJOR(dev)       ((dev) >> 8)
  86 #               define MINOR(dev)       ((dev) & 0xff)
  87 #       endif
  88 #       ifndef IDE_DISK_MAJOR
  89 #               ifndef IDE0_MAJOR
  90 #                       define IDE0_MAJOR       3
  91 #                       define IDE1_MAJOR       22
  92 #                       define IDE2_MAJOR       33
  93 #                       define IDE3_MAJOR       34
  94 #                       define IDE4_MAJOR       56
  95 #                       define IDE5_MAJOR       57
  96 #                       define IDE6_MAJOR       88
  97 #                       define IDE7_MAJOR       89
  98 #                       define IDE8_MAJOR       90
  99 #                       define IDE9_MAJOR       91
 100 #               endif
 101 #               define IDE_DISK_MAJOR(M) \
 102                                 ((M) == IDE0_MAJOR || (M) == IDE1_MAJOR || \
 103                                 (M) == IDE2_MAJOR || (M) == IDE3_MAJOR || \
 104                                 (M) == IDE4_MAJOR || (M) == IDE5_MAJOR || \
 105                                 (M) == IDE6_MAJOR || (M) == IDE7_MAJOR || \
 106                                 (M) == IDE8_MAJOR || (M) == IDE9_MAJOR)
 107 #       endif
 108 #       ifndef SCSI_DISK_MAJOR
 109 #               ifndef SCSI_DISK0_MAJOR
 110 #                       define SCSI_DISK0_MAJOR 8
 111 #                       define SCSI_DISK1_MAJOR 65
 112 #                       define SCSI_DISK7_MAJOR 71
 113 #               endif
 114 #               define SCSI_DISK_MAJOR(M) \
 115                                 ((M) == SCSI_DISK0_MAJOR || \
 116                                 ((M) >= SCSI_DISK1_MAJOR && \
 117                                 (M) <= SCSI_DISK7_MAJOR))
 118 #       endif
 119 #endif
 120 
 121 #include "compat.h"
 122 #include "security.h"
 123 #include "types.h"
 124 #include "attrib.h"
 125 #include "bitmap.h"
 126 #include "bootsect.h"
 127 #include "device.h"
 128 #include "dir.h"
 129 #include "mft.h"
 130 #include "mst.h"
 131 #include "runlist.h"
 132 #include "utils.h"
 133 #include "ntfstime.h"
 134 #include "sd.h"
 135 #include "boot.h"
 136 #include "attrdef.h"
 137 #include "version.h"
 138 #include "logging.h"
 139 #include "support.h"
 140 #include "unistr.h"
 141 
 142 #ifdef NO_NTFS_DEVICE_DEFAULT_IO_OPS
 143 #error "No default device io operations!  Cannot build mkntfs.  \
 144 You need to run ./configure without the --disable-default-device-io-ops \
 145 switch if you want to be able to build the NTFS utilities."
 146 #endif
 147 
 148 /* Page size on ia32. Can change to 8192 on Alpha. */
 149 #define NTFS_PAGE_SIZE  4096
 150 
 151 static char EXEC_NAME[] = "mkntfs";
 152 
 153 /**
 154  * global variables
 155  */
 156 static u8                 *g_buf                  = NULL;
 157 static int                 g_mft_bitmap_byte_size = 0;
 158 static u8                 *g_mft_bitmap           = NULL;
 159 static int                 g_lcn_bitmap_byte_size = 0;
 160 static u8                 *g_lcn_bitmap           = NULL;
 161 static runlist            *g_rl_mft               = NULL;
 162 static runlist            *g_rl_mft_bmp           = NULL;
 163 static runlist            *g_rl_mftmirr           = NULL;
 164 static runlist            *g_rl_logfile           = NULL;
 165 static runlist            *g_rl_boot              = NULL;
 166 static runlist            *g_rl_bad               = NULL;
 167 static INDEX_ALLOCATION  *g_index_block   = NULL;
 168 static ntfs_volume        *g_vol                  = NULL;
 169 static int                 g_mft_size             = 0;
 170 static long long           g_mft_lcn              = 0;          /* lcn of $MFT, $DATA attribute */
 171 static long long           g_mftmirr_lcn          = 0;          /* lcn of $MFTMirr, $DATA */
 172 static long long           g_logfile_lcn          = 0;          /* lcn of $LogFile, $DATA */
 173 static int                 g_logfile_size         = 0;          /* in bytes, determined from volume_size */
 174 static long long           g_mft_zone_end         = 0;          /* Determined from volume_size and mft_zone_multiplier, in clusters */
 175 static long long           g_num_bad_blocks       = 0;          /* Number of bad clusters */
 176 static long long          *g_bad_blocks           = NULL;       /* Array of bad clusters */
 177 
 178 /**
 179  * struct mkntfs_options
 180  */
 181 static struct mkntfs_options {
 182         char *dev_name;                 /* Name of the device, or file, to use */
 183         BOOL enable_compression;        /* -C, enables compression of all files on the volume by default. */
 184         BOOL quick_format;              /* -f or -Q, fast format, don't zero the volume first. */
 185         BOOL force;                     /* -F, force fs creation. */
 186         long heads;                     /* -H, number of heads on device */
 187         BOOL disable_indexing;          /* -I, disables indexing of file contents on the volume by default. */
 188         BOOL no_action;                 /* -n, do not write to device, only display what would be done. */
 189         long long part_start_sect;      /* -p, start sector of partition on parent device */
 190         long sector_size;               /* -s, in bytes, power of 2, default is 512 bytes. */
 191         long sectors_per_track;         /* -S, number of sectors per track on device */
 192         BOOL use_epoch_time;            /* -T, fake the time to be 00:00:00 UTC, Jan 1, 1970. */
 193         long mft_zone_multiplier;       /* -z, value from 1 to 4. Default is 1. */
 194         long long num_sectors;          /* size of device in sectors */
 195         long cluster_size;              /* -c, format with this cluster-size */
 196         char *label;                    /* -L, volume label */
 197 } opts;
 198 
 199 
 200 /**
 201  * mkntfs_license
 202  */
 203 static void mkntfs_license(void)
 204 {
 205         ntfs_log_info("%s", ntfs_gpl);
 206 }
 207 
 208 /**
 209  * mkntfs_usage
 210  */
 211 static void mkntfs_usage(void)
 212 {
 213         ntfs_log_info("\nUsage: %s [options] device [number-of-sectors]\n"
 214 "\n"
 215 "Basic options:\n"
 216 "    -f, --fast                      Perform a quick format\n"
 217 "    -Q, --quick                     Perform a quick format\n"
 218 "    -L, --label STRING              Set the volume label\n"
 219 "    -C, --enable-compression        Enable compression on the volume\n"
 220 "    -I, --no-indexing               Disable indexing on the volume\n"
 221 "    -n, --no-action                 Do not write to disk\n"
 222 "\n"
 223 "Advanced options:\n"
 224 "    -c, --cluster-size BYTES        Specify the cluster size for the volume\n"
 225 "    -s, --sector-size BYTES         Specify the sector size for the device\n"
 226 "    -p, --partition-start SECTOR    Specify the partition start sector\n"
 227 "    -H, --heads NUM                 Specify the number of heads\n"
 228 "    -S, --sectors-per-track NUM     Specify the number of sectors per track\n"
 229 "    -z, --mft-zone-multiplier NUM   Set the MFT zone multiplier\n"
 230 "    -T, --zero-time                 Fake the time to be 00:00 UTC, Jan 1, 1970\n"
 231 "    -F, --force                     Force execution despite errors\n"
 232 "\n"
 233 "Output options:\n"
 234 "    -q, --quiet                     Quiet execution\n"
 235 "    -v, --verbose                   Verbose execution\n"
 236 "        --debug                     Very verbose execution\n"
 237 "\n"
 238 "Help options:\n"
 239 "    -V, --version                   Display version\n"
 240 "    -l, --license                   Display licensing information\n"
 241 "    -h, --help                      Display this help\n"
 242 "\n", basename(EXEC_NAME));
 243         ntfs_log_info("%s%s\n", ntfs_bugs, ntfs_home);
 244 }
 245 
 246 /**
 247  * mkntfs_version
 248  */
 249 static void mkntfs_version(void)
 250 {
 251         ntfs_log_info("\n%s v%s (libntfs %s)\n\n", EXEC_NAME, VERSION,
 252                         ntfs_libntfs_version());
 253         ntfs_log_info("Create an NTFS volume on a user specified (block) "
 254                         "device.\n\n");
 255         ntfs_log_info("Copyright (c) 2000-2007 Anton Altaparmakov\n");
 256         ntfs_log_info("Copyright (c) 2001-2005 Richard Russon\n");
 257         ntfs_log_info("Copyright (c) 2002-2006 Szabolcs Szakacsits\n");
 258         ntfs_log_info("Copyright (c) 2005      Erik Sornes\n");
 259         ntfs_log_info("Copyright (c) 2007      Yura Pakhuchiy\n");
 260         ntfs_log_info("\n%s\n%s%s\n", ntfs_gpl, ntfs_bugs, ntfs_home);
 261 }
 262 
 263 
 264 /**
 265  * mkntfs_parse_long
 266  */
 267 static BOOL mkntfs_parse_long(const char *string, const char *name, long *num)
 268 {
 269         char *end = NULL;
 270         long tmp;
 271 
 272         if (!string || !name || !num)
 273                 return FALSE;
 274 
 275         if (*num >= 0) {
 276                 ntfs_log_error("You may only specify the %s once.\n", name);
 277                 return FALSE;
 278         }
 279 
 280         tmp = strtol(string, &end, 0);
 281         if (end && *end) {
 282                 ntfs_log_error("Cannot understand the %s '%s'.\n", name, string);
 283                 return FALSE;
 284         } else {
 285                 *num = tmp;
 286                 return TRUE;
 287         }
 288 }
 289 
 290 /**
 291  * mkntfs_parse_llong
 292  */
 293 static BOOL mkntfs_parse_llong(const char *string, const char *name,
 294                 long long *num)
 295 {
 296         char *end = NULL;
 297         long long tmp;
 298 
 299         if (!string || !name || !num)
 300                 return FALSE;
 301 
 302         if (*num >= 0) {
 303                 ntfs_log_error("You may only specify the %s once.\n", name);
 304                 return FALSE;
 305         }
 306 
 307         tmp = strtoll(string, &end, 0);
 308         if (end && *end) {
 309                 ntfs_log_error("Cannot understand the %s '%s'.\n", name,
 310                                 string);
 311                 return FALSE;
 312         } else {
 313                 *num = tmp;
 314                 return TRUE;
 315         }
 316 }
 317 
 318 /**
 319  * mkntfs_init_options
 320  */
 321 static void mkntfs_init_options(struct mkntfs_options *opts2)
 322 {
 323         if (!opts2)
 324                 return;
 325 
 326         memset(opts2, 0, sizeof(*opts2));
 327 
 328         /* Mark all the numeric options as "unset". */
 329         opts2->cluster_size          = -1;
 330         opts2->heads                 = -1;
 331         opts2->mft_zone_multiplier   = -1;
 332         opts2->num_sectors           = -1;
 333         opts2->part_start_sect               = -1;
 334         opts2->sector_size           = -1;
 335         opts2->sectors_per_track     = -1;
 336 }
 337 
 338 /**
 339  * mkntfs_parse_options
 340  */
 341 static BOOL mkntfs_parse_options(int argc, char *argv[], struct mkntfs_options *opts2)
 342 {
 343         static const char *sopt = "-c:CfFhH:IlL:np:qQs:S:TvVz:";
 344         static const struct option lopt[] = {
 345                 { "cluster-size",       required_argument,      NULL, 'c' },
 346                 { "debug",              no_argument,            NULL, 'Z' },
 347                 { "enable-compression", no_argument,            NULL, 'C' },
 348                 { "fast",               no_argument,            NULL, 'f' },
 349                 { "force",              no_argument,            NULL, 'F' },
 350                 { "heads",              required_argument,      NULL, 'H' },
 351                 { "help",               no_argument,            NULL, 'h' },
 352                 { "label",              required_argument,      NULL, 'L' },
 353                 { "license",            no_argument,            NULL, 'l' },
 354                 { "mft-zone-multiplier",required_argument,      NULL, 'z' },
 355                 { "no-action",          no_argument,            NULL, 'n' },
 356                 { "no-indexing",        no_argument,            NULL, 'I' },
 357                 { "partition-start",    required_argument,      NULL, 'p' },
 358                 { "quick",              no_argument,            NULL, 'Q' },
 359                 { "quiet",              no_argument,            NULL, 'q' },
 360                 { "sector-size",        required_argument,      NULL, 's' },
 361                 { "sectors-per-track",  required_argument,      NULL, 'S' },
 362                 { "verbose",            no_argument,            NULL, 'v' },
 363                 { "version",            no_argument,            NULL, 'V' },
 364                 { "zero-time",          no_argument,            NULL, 'T' },
 365                 { NULL, 0, NULL, 0 }
 366         };
 367 
 368         int c = -1;
 369         int lic = 0;
 370         int err = 0;
 371         int ver = 0;
 372 
 373         if (!argv || !opts2) {
 374                 ntfs_log_error("Internal error: invalid parameters to "
 375                                 "mkntfs_options.\n");
 376                 return FALSE;
 377         }
 378 
 379         opterr = 0; /* We'll handle the errors, thank you. */
 380 
 381         while ((c = getopt_long(argc, argv, sopt, lopt, NULL)) != -1) {
 382                 switch (c) {
 383                 case 1:         /* A device, or a number of sectors */
 384                         if (!opts2->dev_name)
 385                                 opts2->dev_name = argv[optind - 1];
 386                         else if (!mkntfs_parse_llong(optarg,
 387                                         "number of sectors",
 388                                         &opts2->num_sectors))
 389                                 err++;
 390                         break;
 391                 case 'C':
 392                         opts2->enable_compression = TRUE;
 393                         break;
 394                 case 'c':
 395                         if (!mkntfs_parse_long(optarg, "cluster size",
 396                                         &opts2->cluster_size))
 397                                 err++;
 398                         break;
 399                 case 'F':
 400                         opts2->force = TRUE;
 401                         break;
 402                 case 'f':       /* fast */
 403                 case 'Q':       /* quick */
 404                         opts2->quick_format = TRUE;
 405                         break;
 406                 case 'H':
 407                         if (!mkntfs_parse_long(optarg, "heads", &opts2->heads))
 408                                 err++;
 409                         break;
 410                 case 'h':
 411                         err++;  /* display help */
 412                         break;
 413                 case 'I':
 414                         opts2->disable_indexing = TRUE;
 415                         break;
 416                 case 'L':
 417                         if (!opts2->label) {
 418                                 opts2->label = argv[optind-1];
 419                         } else {
 420                                 ntfs_log_error("You may only specify the label "
 421                                                 "once.\n");
 422                                 err++;
 423                         }
 424                         break;
 425                 case 'l':
 426                         lic++;  /* display the license */
 427                         break;
 428                 case 'n':
 429                         opts2->no_action = TRUE;
 430                         break;
 431                 case 'p':
 432                         if (!mkntfs_parse_llong(optarg, "partition start",
 433                                                 &opts2->part_start_sect))
 434                                 err++;
 435                         break;
 436                 case 'q':
 437                         ntfs_log_clear_levels(NTFS_LOG_LEVEL_QUIET |
 438                                         NTFS_LOG_LEVEL_VERBOSE |
 439                                         NTFS_LOG_LEVEL_PROGRESS);
 440                         break;
 441                 case 's':
 442                         if (!mkntfs_parse_long(optarg, "sector size",
 443                                                 &opts2->sector_size))
 444                                 err++;
 445                         break;
 446                 case 'S':
 447                         if (!mkntfs_parse_long(optarg, "sectors per track",
 448                                                 &opts2->sectors_per_track))
 449                                 err++;
 450                         break;
 451                 case 'T':
 452                         opts2->use_epoch_time = TRUE;
 453                         break;
 454                 case 'v':
 455                         ntfs_log_set_levels(NTFS_LOG_LEVEL_QUIET |
 456                                         NTFS_LOG_LEVEL_VERBOSE |
 457                                         NTFS_LOG_LEVEL_PROGRESS);
 458                         break;
 459                 case 'V':
 460                         ver++;  /* display version info */
 461                         break;
 462                 case 'Z':       /* debug - turn on everything */
 463                         ntfs_log_set_levels(NTFS_LOG_LEVEL_DEBUG |
 464                                         NTFS_LOG_LEVEL_TRACE |
 465                                         NTFS_LOG_LEVEL_VERBOSE |
 466                                         NTFS_LOG_LEVEL_QUIET);
 467                         break;
 468                 case 'z':
 469                         if (!mkntfs_parse_long(optarg, "mft zone multiplier",
 470                                                 &opts2->mft_zone_multiplier))
 471                                 err++;
 472                         break;
 473                 default:
 474                         if (ntfs_log_parse_option (argv[optind-1]))
 475                                 break;
 476                         if (((optopt == 'c') || (optopt == 'H') ||
 477                              (optopt == 'L') || (optopt == 'p') ||
 478                              (optopt == 's') || (optopt == 'S') ||
 479                              (optopt == 'N') || (optopt == 'z')) &&
 480                              (!optarg)) {
 481                                 ntfs_log_error("Option '%s' requires an "
 482                                                 "argument.\n", argv[optind-1]);
 483                         } else if (optopt != '?') {
 484                                 ntfs_log_error("Unknown option '%s'.\n",
 485                                                 argv[optind - 1]);
 486                         }
 487                         err++;
 488                         break;
 489                 }
 490         }
 491 
 492         if (!err && !ver && !lic) {
 493                 if (opts2->dev_name == NULL) {
 494                         if (argc > 1)
 495                                 ntfs_log_error("You must specify a device.\n");
 496                         err++;
 497                 }
 498         }
 499 
 500         if (ver)
 501                 mkntfs_version();
 502         if (lic)
 503                 mkntfs_license();
 504         if (err)
 505                 mkntfs_usage();
 506 
 507         return (!err && !ver && !lic);
 508 }
 509 
 510 
 511 /**
 512  * mkntfs_time
 513  */
 514 static time_t mkntfs_time(void)
 515 {
 516         if (!opts.use_epoch_time)
 517                 return time(NULL);
 518         return 0;
 519 }
 520 
 521 /**
 522  * append_to_bad_blocks
 523  */
 524 static BOOL append_to_bad_blocks(unsigned long long block)
 525 {
 526         long long *new_buf;
 527 
 528         if (!(g_num_bad_blocks & 15)) {
 529                 new_buf = realloc(g_bad_blocks, (g_num_bad_blocks + 16) *
 530                                                         sizeof(long long));
 531                 if (!new_buf) {
 532                         ntfs_log_perror("Reallocating memory for bad blocks "
 533                                 "list failed");
 534                         return FALSE;
 535                 }
 536                 g_bad_blocks = new_buf;
 537         }
 538         g_bad_blocks[g_num_bad_blocks++] = block;
 539         return TRUE;
 540 }
 541 
 542 /**
 543  * mkntfs_write
 544  */
 545 static long long mkntfs_write(struct ntfs_device *dev,
 546                 const void *b, long long count)
 547 {
 548         long long bytes_written, total;
 549         int retry;
 550 
 551         if (opts.no_action)
 552                 return count;
 553         total = 0LL;
 554         retry = 0;
 555         do {
 556                 bytes_written = dev->d_ops->write(dev, b, count);
 557                 if (bytes_written == -1LL) {
 558                         retry = errno;
 559                         ntfs_log_perror("Error writing to %s", dev->d_name);
 560                         errno = retry;
 561                         return bytes_written;
 562                 } else if (!bytes_written) {
 563                         retry++;
 564                 } else {
 565                         count -= bytes_written;
 566                         total += bytes_written;
 567                 }
 568         } while (count && retry < 3);
 569         if (count)
 570                 ntfs_log_error("Failed to complete writing to %s after three retries."
 571                         "\n", dev->d_name);
 572         return total;
 573 }
 574 
 575 /**
 576  * ntfs_rlwrite - Write data to disk on clusters found in a runlist.
 577  *
 578  * Write to disk the clusters contained in the runlist @rl taking the data
 579  * from @val.  Take @val_len bytes from @val and pad the rest with zeroes.
 580  *
 581  * If the @rl specifies a completely sparse file, @val is allowed to be NULL.
 582  *
 583  * @inited_size if not NULL points to an output variable which will contain
 584  * the actual number of bytes written to disk. I.e. this will not include
 585  * sparse bytes for example.
 586  *
 587  * Return the number of bytes written (minus padding) or -1 on error. Errno
 588  * will be set to the error code.
 589  */
 590 static s64 ntfs_rlwrite(struct ntfs_device *dev, const runlist *rl,
 591                 const u8 *val, const s64 val_len, s64 *inited_size)
 592 {
 593         s64 bytes_written, total, length, delta;
 594         int retry, i;
 595 
 596         if (inited_size)
 597                 *inited_size = 0LL;
 598         if (opts.no_action)
 599                 return val_len;
 600         total = 0LL;
 601         delta = 0LL;
 602         for (i = 0; rl[i].length; i++) {
 603                 length = rl[i].length * g_vol->cluster_size;
 604                 /* Don't write sparse runs. */
 605                 if (rl[i].lcn == -1) {
 606                         total += length;
 607                         if (!val)
 608                                 continue;
 609                         /* TODO: Check that *val is really zero at pos and len. */
 610                         continue;
 611                 }
 612                 /*
 613                  * Break up the write into the real data write and then a write
 614                  * of zeroes between the end of the real data and the end of
 615                  * the (last) run.
 616                  */
 617                 if (total + length > val_len) {
 618                         delta = length;
 619                         length = val_len - total;
 620                         delta -= length;
 621                 }
 622                 if (dev->d_ops->seek(dev, rl[i].lcn * g_vol->cluster_size,
 623                                 SEEK_SET) == (off_t)-1)
 624                         return -1LL;
 625                 retry = 0;
 626                 do {
 627                         bytes_written = dev->d_ops->write(dev, val + total,
 628                                         length);
 629                         if (bytes_written == -1LL) {
 630                                 retry = errno;
 631                                 ntfs_log_perror("Error writing to %s",
 632                                         dev->d_name);
 633                                 errno = retry;
 634                                 return bytes_written;
 635                         }
 636                         if (bytes_written) {
 637                                 length -= bytes_written;
 638                                 total += bytes_written;
 639                                 if (inited_size)
 640                                         *inited_size += bytes_written;
 641                         } else {
 642                                 retry++;
 643                         }
 644                 } while (length && retry < 3);
 645                 if (length) {
 646                         ntfs_log_error("Failed to complete writing to %s after three "
 647                                         "retries.\n", dev->d_name);
 648                         return total;
 649                 }
 650         }
 651         if (delta) {
 652                 int eo;
 653                 char *b = ntfs_calloc(delta);
 654                 if (!b)
 655                         return -1;
 656                 bytes_written = mkntfs_write(dev, b, delta);
 657                 eo = errno;
 658                 free(b);
 659                 errno = eo;
 660                 if (bytes_written == -1LL)
 661                         return bytes_written;
 662         }
 663         return total;
 664 }
 665 
 666 /**
 667  * make_room_for_attribute - make room for an attribute inside an mft record
 668  * @m:          mft record
 669  * @pos:        position at which to make space
 670  * @size:       byte size to make available at this position
 671  *
 672  * @pos points to the attribute in front of which we want to make space.
 673  *
 674  * Return 0 on success or -errno on error. Possible error codes are:
 675  *
 676  *      -ENOSPC         There is not enough space available to complete
 677  *                      operation. The caller has to make space before calling
 678  *                      this.
 679  *      -EINVAL         Can only occur if mkntfs was compiled with -DDEBUG. Means
 680  *                      the input parameters were faulty.
 681  */
 682 static int make_room_for_attribute(MFT_RECORD *m, char *pos, const u32 size)
 683 {
 684         u32 biu;
 685 
 686         if (!size)
 687                 return 0;
 688 #ifdef DEBUG
 689         /*
 690          * Rigorous consistency checks. Always return -EINVAL even if more
 691          * appropriate codes exist for simplicity of parsing the return value.
 692          */
 693         if (size != ((size + 7) & ~7)) {
 694                 ntfs_log_error("make_room_for_attribute() received non 8-byte aligned "
 695                                 "size.\n");
 696                 return -EINVAL;
 697         }
 698         if (!m || !pos)
 699                 return -EINVAL;
 700         if (pos < (char*)m || pos + size < (char*)m ||
 701                         pos > (char*)m + le32_to_cpu(m->bytes_allocated) ||
 702                         pos + size > (char*)m + le32_to_cpu(m->bytes_allocated))
 703                 return -EINVAL;
 704         /* The -8 is for the attribute terminator. */
 705         if (pos - (char*)m > (int)le32_to_cpu(m->bytes_in_use) - 8)
 706                 return -EINVAL;
 707 #endif
 708         biu = le32_to_cpu(m->bytes_in_use);
 709         /* Do we have enough space? */
 710         if (biu + size > le32_to_cpu(m->bytes_allocated))
 711                 return -ENOSPC;
 712         /* Move everything after pos to pos + size. */
 713         memmove(pos + size, pos, biu - (pos - (char*)m));
 714         /* Update mft record. */
 715         m->bytes_in_use = cpu_to_le32(biu + size);
 716         return 0;
 717 }
 718 
 719 /**
 720  * deallocate_scattered_clusters
 721  */
 722 static void deallocate_scattered_clusters(const runlist *rl)
 723 {
 724         LCN j;
 725         int i;
 726 
 727         if (!rl)
 728                 return;
 729         /* Iterate over all runs in the runlist @rl. */
 730         for (i = 0; rl[i].length; i++) {
 731                 /* Skip sparse runs. */
 732                 if (rl[i].lcn == -1LL)
 733                         continue;
 734                 /* Deallocate the current run. */
 735                 for (j = rl[i].lcn; j < rl[i].lcn + rl[i].length; j++)
 736                         ntfs_bit_set(g_lcn_bitmap, j, 0);
 737         }
 738 }
 739 
 740 /**
 741  * allocate_scattered_clusters
 742  * @clusters: Amount of clusters to allocate.
 743  *
 744  * Allocate @clusters and create a runlist of the allocated clusters.
 745  *
 746  * Return the allocated runlist. Caller has to free the runlist when finished
 747  * with it.
 748  *
 749  * On error return NULL and errno is set to the error code.
 750  *
 751  * TODO: We should be returning the size as well, but for mkntfs this is not
 752  * necessary.
 753  */
 754 static runlist * allocate_scattered_clusters(s64 clusters)
 755 {
 756         runlist *rl = NULL, *rlt;
 757         VCN vcn = 0LL;
 758         LCN lcn, end, prev_lcn = 0LL;
 759         int rlpos = 0;
 760         int rlsize = 0;
 761         s64 prev_run_len = 0LL;
 762         char bit;
 763 
 764         end = g_vol->nr_clusters;
 765         /* Loop until all clusters are allocated. */
 766         while (clusters) {
 767                 /* Loop in current zone until we run out of free clusters. */
 768                 for (lcn = g_mft_zone_end; lcn < end; lcn++) {
 769                         bit = ntfs_bit_get_and_set(g_lcn_bitmap, lcn, 1);
 770                         if (bit)
 771                                 continue;
 772                         /*
 773                          * Reallocate memory if necessary. Make sure we have
 774                          * enough for the terminator entry as well.
 775                          */
 776                         if ((rlpos + 2) * (int)sizeof(runlist) >= rlsize) {
 777                                 rlsize += 4096; /* PAGE_SIZE */
 778                                 rlt = realloc(rl, rlsize);
 779                                 if (!rlt)
 780                                         goto err_end;
 781                                 rl = rlt;
 782                         }
 783                         /* Coalesce with previous run if adjacent LCNs. */
 784                         if (prev_lcn == lcn - prev_run_len) {
 785                                 rl[rlpos - 1].length = ++prev_run_len;
 786                                 vcn++;
 787                         } else {
 788                                 rl[rlpos].vcn = vcn++;
 789                                 rl[rlpos].lcn = lcn;
 790                                 prev_lcn = lcn;
 791                                 rl[rlpos].length = 1LL;
 792                                 prev_run_len = 1LL;
 793                                 rlpos++;
 794                         }
 795                         /* Done? */
 796                         if (!--clusters) {
 797                                 /* Add terminator element and return. */
 798                                 rl[rlpos].vcn = vcn;
 799                                 rl[rlpos].lcn = 0LL;
 800                                 rl[rlpos].length = 0LL;
 801                                 return rl;
 802                         }
 803 
 804                 }
 805                 /* Switch to next zone, decreasing mft zone by factor 2. */
 806                 end = g_mft_zone_end;
 807                 g_mft_zone_end >>= 1;
 808                 /* Have we run out of space on the volume? */
 809                 if (g_mft_zone_end <= 0)
 810                         goto err_end;
 811         }
 812         return rl;
 813 err_end:
 814         if (rl) {
 815                 /* Add terminator element. */
 816                 rl[rlpos].vcn = vcn;
 817                 rl[rlpos].lcn = -1LL;
 818                 rl[rlpos].length = 0LL;
 819                 /* Deallocate all allocated clusters. */
 820                 deallocate_scattered_clusters(rl);
 821                 /* Free the runlist. */
 822                 free(rl);
 823         }
 824         return NULL;
 825 }
 826 
 827 /**
 828  * ntfs_attr_find - find (next) attribute in mft record
 829  * @type:       attribute type to find
 830  * @name:       attribute name to find (optional, i.e. NULL means don't care)
 831  * @name_len:   attribute name length (only needed if @name present)
 832  * @ic:         IGNORE_CASE or CASE_SENSITIVE (ignored if @name not present)
 833  * @val:        attribute value to find (optional, resident attributes only)
 834  * @val_len:    attribute value length
 835  * @ctx:        search context with mft record and attribute to search from
 836  *
 837  * You shouldn't need to call this function directly. Use lookup_attr() instead.
 838  *
 839  * ntfs_attr_find() takes a search context @ctx as parameter and searches the
 840  * mft record specified by @ctx->mrec, beginning at @ctx->attr, for an
 841  * attribute of @type, optionally @name and @val. If found, ntfs_attr_find()
 842  * returns 0 and @ctx->attr will point to the found attribute.
 843  *
 844  * If not found, ntfs_attr_find() returns -1, with errno set to ENOENT and
 845  * @ctx->attr will point to the attribute before which the attribute being
 846  * searched for would need to be inserted if such an action were to be desired.
 847  *
 848  * On actual error, ntfs_attr_find() returns -1 with errno set to the error
 849  * code but not to ENOENT.  In this case @ctx->attr is undefined and in
 850  * particular do not rely on it not changing.
 851  *
 852  * If @ctx->is_first is TRUE, the search begins with @ctx->attr itself. If it
 853  * is FALSE, the search begins after @ctx->attr.
 854  *
 855  * If @type is AT_UNUSED, return the first found attribute, i.e. one can
 856  * enumerate all attributes by setting @type to AT_UNUSED and then calling
 857  * ntfs_attr_find() repeatedly until it returns -1 with errno set to ENOENT to
 858  * indicate that there are no more entries. During the enumeration, each
 859  * successful call of ntfs_attr_find() will return the next attribute in the
 860  * mft record @ctx->mrec.
 861  *
 862  * If @type is AT_END, seek to the end and return -1 with errno set to ENOENT.
 863  * AT_END is not a valid attribute, its length is zero for example, thus it is
 864  * safer to return error instead of success in this case. This also allows us
 865  * to interoperate cleanly with ntfs_external_attr_find().
 866  *
 867  * If @name is AT_UNNAMED search for an unnamed attribute. If @name is present
 868  * but not AT_UNNAMED search for a named attribute matching @name. Otherwise,
 869  * match both named and unnamed attributes.
 870  *
 871  * If @ic is IGNORE_CASE, the @name comparison is not case sensitive and
 872  * @ctx->ntfs_ino must be set to the ntfs inode to which the mft record
 873  * @ctx->mrec belongs. This is so we can get at the ntfs volume and hence at
 874  * the upcase table. If @ic is CASE_SENSITIVE, the comparison is case
 875  * sensitive. When @name is present, @name_len is the @name length in Unicode
 876  * characters.
 877  *
 878  * If @name is not present (NULL), we assume that the unnamed attribute is
 879  * being searched for.
 880  *
 881  * Finally, the resident attribute value @val is looked for, if present.
 882  * If @val is not present (NULL), @val_len is ignored.
 883  *
 884  * ntfs_attr_find() only searches the specified mft record and it ignores the
 885  * presence of an attribute list attribute (unless it is the one being searched
 886  * for, obviously). If you need to take attribute lists into consideration, use
 887  * ntfs_attr_lookup() instead (see below). This also means that you cannot use
 888  * ntfs_attr_find() to search for extent records of non-resident attributes, as
 889  * extents with lowest_vcn != 0 are usually described by the attribute list
 890  * attribute only. - Note that it is possible that the first extent is only in
 891  * the attribute list while the last extent is in the base mft record, so don't
 892  * rely on being able to find the first extent in the base mft record.
 893  *
 894  * Warning: Never use @val when looking for attribute types which can be
 895  *          non-resident as this most likely will result in a crash!
 896  */
 897 static int mkntfs_attr_find(const ATTR_TYPES type, const ntfschar *name,
 898                 const u32 name_len, const IGNORE_CASE_BOOL ic,
 899                 const u8 *val, const u32 val_len, ntfs_attr_search_ctx *ctx)
 900 {
 901         ATTR_RECORD *a;
 902         ntfschar *upcase = g_vol->upcase;
 903         u32 upcase_len = g_vol->upcase_len;
 904 
 905         /*
 906          * Iterate over attributes in mft record starting at @ctx->attr, or the
 907          * attribute following that, if @ctx->is_first is TRUE.
 908          */
 909         if (ctx->is_first) {
 910                 a = ctx->attr;
 911                 ctx->is_first = FALSE;
 912         } else {
 913                 a = (ATTR_RECORD*)((char*)ctx->attr +
 914                                 le32_to_cpu(ctx->attr->length));
 915         }
 916         for (;; a = (ATTR_RECORD*)((char*)a + le32_to_cpu(a->length))) {
 917                 if (p2n(a) < p2n(ctx->mrec) || (char*)a > (char*)ctx->mrec +
 918                                 le32_to_cpu(ctx->mrec->bytes_allocated))
 919                         break;
 920                 ctx->attr = a;
 921                 if (((type != AT_UNUSED) && (le32_to_cpu(a->type) >
 922                                 le32_to_cpu(type))) ||
 923                                 (a->type == AT_END)) {
 924                         errno = ENOENT;
 925                         return -1;
 926                 }
 927                 if (!a->length)
 928                         break;
 929                 /* If this is an enumeration return this attribute. */
 930                 if (type == AT_UNUSED)
 931                         return 0;
 932                 if (a->type != type)
 933                         continue;
 934                 /*
 935                  * If @name is AT_UNNAMED we want an unnamed attribute.
 936                  * If @name is present, compare the two names.
 937                  * Otherwise, match any attribute.
 938                  */
 939                 if (name == AT_UNNAMED) {
 940                         /* The search failed if the found attribute is named. */
 941                         if (a->name_length) {
 942                                 errno = ENOENT;
 943                                 return -1;
 944                         }
 945                 } else if (name && !ntfs_names_are_equal(name, name_len,
 946                                 (ntfschar*)((char*)a + le16_to_cpu(a->name_offset)),
 947                                 a->name_length, ic, upcase, upcase_len)) {
 948                         int rc;
 949 
 950                         rc = ntfs_names_collate(name, name_len,
 951                                         (ntfschar*)((char*)a +
 952                                         le16_to_cpu(a->name_offset)),
 953                                         a->name_length, 1, IGNORE_CASE,
 954                                         upcase, upcase_len);
 955                         /*
 956                          * If @name collates before a->name, there is no
 957                          * matching attribute.
 958                          */
 959                         if (rc == -1) {
 960                                 errno = ENOENT;
 961                                 return -1;
 962                         }
 963                         /* If the strings are not equal, continue search. */
 964                         if (rc)
 965                                 continue;
 966                         rc = ntfs_names_collate(name, name_len,
 967                                         (ntfschar*)((char*)a +
 968                                         le16_to_cpu(a->name_offset)),
 969                                         a->name_length, 1, CASE_SENSITIVE,
 970                                         upcase, upcase_len);
 971                         if (rc == -1) {
 972                                 errno = ENOENT;
 973                                 return -1;
 974                         }
 975                         if (rc)
 976                                 continue;
 977                 }
 978                 /*
 979                  * The names match or @name not present and attribute is
 980                  * unnamed. If no @val specified, we have found the attribute
 981                  * and are done.
 982                  */
 983                 if (!val) {
 984                         return 0;
 985                 /* @val is present; compare values. */
 986                 } else {
 987                         int rc;
 988 
 989                         rc = memcmp(val, (char*)a +le16_to_cpu(a->u.res.value_offset),
 990                                         min(val_len,
 991                                         le32_to_cpu(a->u.res.value_length)));
 992                         /*
 993                          * If @val collates before the current attribute's
 994                          * value, there is no matching attribute.
 995                          */
 996                         if (!rc) {
 997                                 u32 avl;
 998                                 avl = le32_to_cpu(a->u.res.value_length);
 999                                 if (val_len == avl)
1000                                         return 0;
1001                                 if (val_len < avl) {
1002                                         errno = ENOENT;
1003                                         return -1;
1004                                 }
1005                         } else if (rc < 0) {
1006                                 errno = ENOENT;
1007                                 return -1;
1008                         }
1009                 }
1010         }
1011         ntfs_log_trace("File is corrupt. Run chkdsk.\n");
1012         errno = EIO;
1013         return -1;
1014 }
1015 
1016 /**
1017  * ntfs_attr_lookup - find an attribute in an ntfs inode
1018  * @type:       attribute type to find
1019  * @name:       attribute name to find (optional, i.e. NULL means don't care)
1020  * @name_len:   attribute name length (only needed if @name present)
1021  * @ic:         IGNORE_CASE or CASE_SENSITIVE (ignored if @name not present)
1022  * @lowest_vcn: lowest vcn to find (optional, non-resident attributes only)
1023  * @val:        attribute value to find (optional, resident attributes only)
1024  * @val_len:    attribute value length
1025  * @ctx:        search context with mft record and attribute to search from
1026  *
1027  * Find an attribute in an ntfs inode. On first search @ctx->ntfs_ino must
1028  * be the base mft record and @ctx must have been obtained from a call to
1029  * ntfs_attr_get_search_ctx().
1030  *
1031  * This function transparently handles attribute lists and @ctx is used to
1032  * continue searches where they were left off at.
1033  *
1034  * If @type is AT_UNUSED, return the first found attribute, i.e. one can
1035  * enumerate all attributes by setting @type to AT_UNUSED and then calling
1036  * ntfs_attr_lookup() repeatedly until it returns -1 with errno set to ENOENT
1037  * to indicate that there are no more entries. During the enumeration, each
1038  * successful call of ntfs_attr_lookup() will return the next attribute, with
1039  * the current attribute being described by the search context @ctx.
1040  *
1041  * If @type is AT_END, seek to the end of the base mft record ignoring the
1042  * attribute list completely and return -1 with errno set to ENOENT.  AT_END is
1043  * not a valid attribute, its length is zero for example, thus it is safer to
1044  * return error instead of success in this case.  It should never be needed to
1045  * do this, but we implement the functionality because it allows for simpler
1046  * code inside ntfs_external_attr_find().
1047  *
1048  * If @name is AT_UNNAMED search for an unnamed attribute. If @name is present
1049  * but not AT_UNNAMED search for a named attribute matching @name. Otherwise,
1050  * match both named and unnamed attributes.
1051  *
1052  * After finishing with the attribute/mft record you need to call
1053  * ntfs_attr_put_search_ctx() to cleanup the search context (unmapping any
1054  * mapped extent inodes, etc).
1055  *
1056  * Return 0 if the search was successful and -1 if not, with errno set to the
1057  * error code.
1058  *
1059  * On success, @ctx->attr is the found attribute, it is in mft record
1060  * @ctx->mrec, and @ctx->al_entry is the attribute list entry for this
1061  * attribute with @ctx->base_* being the base mft record to which @ctx->attr
1062  * belongs.  If no attribute list attribute is present @ctx->al_entry and
1063  * @ctx->base_* are NULL.
1064  *
1065  * On error ENOENT, i.e. attribute not found, @ctx->attr is set to the
1066  * attribute which collates just after the attribute being searched for in the
1067  * base ntfs inode, i.e. if one wants to add the attribute to the mft record
1068  * this is the correct place to insert it into, and if there is not enough
1069  * space, the attribute should be placed in an extent mft record.
1070  * @ctx->al_entry points to the position within @ctx->base_ntfs_ino->attr_list
1071  * at which the new attribute's attribute list entry should be inserted.  The
1072  * other @ctx fields, base_ntfs_ino, base_mrec, and base_attr are set to NULL.
1073  * The only exception to this is when @type is AT_END, in which case
1074  * @ctx->al_entry is set to NULL also (see above).
1075  *
1076  * The following error codes are defined:
1077  *      ENOENT  Attribute not found, not an error as such.
1078  *      EINVAL  Invalid arguments.
1079  *      EIO     I/O error or corrupt data structures found.
1080  *      ENOMEM  Not enough memory to allocate necessary buffers.
1081  */
1082 static int mkntfs_attr_lookup(const ATTR_TYPES type, const ntfschar *name,
1083                 const u32 name_len, const IGNORE_CASE_BOOL ic,
1084                 const VCN lowest_vcn __attribute__((unused)), const u8 *val,
1085                 const u32 val_len, ntfs_attr_search_ctx *ctx)
1086 {
1087         ntfs_inode *base_ni;
1088 
1089         if (!ctx || !ctx->mrec || !ctx->attr) {
1090                 errno = EINVAL;
1091                 return -1;
1092         }
1093         if (ctx->base_ntfs_ino)
1094                 base_ni = ctx->base_ntfs_ino;
1095         else
1096                 base_ni = ctx->ntfs_ino;
1097         if (!base_ni || !NInoAttrList(base_ni) || type == AT_ATTRIBUTE_LIST)
1098                 return mkntfs_attr_find(type, name, name_len, ic, val, val_len,
1099                                 ctx);
1100         errno = EOPNOTSUPP;
1101         return -1;
1102 }
1103 
1104 /**
1105  * insert_positioned_attr_in_mft_record
1106  *
1107  * Create a non-resident attribute with a predefined on disk location
1108  * specified by the runlist @rl. The clusters specified by @rl are assumed to
1109  * be allocated already.
1110  *
1111  * Return 0 on success and -errno on error.
1112  */
1113 static int insert_positioned_attr_in_mft_record(MFT_RECORD *m,
1114                 const ATTR_TYPES type, const char *name, u32 name_len,
1115                 const IGNORE_CASE_BOOL ic, const ATTR_FLAGS flags,
1116                 const runlist *rl, const u8 *val, const s64 val_len)
1117 {
1118         ntfs_attr_search_ctx *ctx;
1119         ATTR_RECORD *a;
1120         u16 hdr_size;
1121         int asize, mpa_size, err, i;
1122         s64 bw = 0, inited_size;
1123         VCN highest_vcn;
1124         ntfschar *uname = NULL;
1125         int uname_len = 0;
1126         /*
1127         if (base record)
1128                 attr_lookup();
1129         else
1130         */
1131 
1132         uname = ntfs_str2ucs(name, &uname_len);
1133         if (!uname)
1134                 return -errno;
1135 
1136         /* Check if the attribute is already there. */
1137         ctx = ntfs_attr_get_search_ctx(NULL, m);
1138         if (!ctx) {
1139                 ntfs_log_error("Failed to allocate attribute search context.\n");
1140                 err = -ENOMEM;
1141                 goto err_out;
1142         }
1143         if (ic == IGNORE_CASE) {
1144                 ntfs_log_error("FIXME: Hit unimplemented code path #1.\n");
1145                 err = -EOPNOTSUPP;
1146                 goto err_out;
1147         }
1148         if (!mkntfs_attr_lookup(type, uname, uname_len, ic, 0, NULL, 0, ctx)) {
1149                 err = -EEXIST;
1150                 goto err_out;
1151         }
1152         if (errno != ENOENT) {
1153                 ntfs_log_error("Corrupt inode.\n");
1154                 err = -errno;
1155                 goto err_out;
1156         }
1157         a = ctx->attr;
1158         if (flags & ATTR_COMPRESSION_MASK) {
1159                 ntfs_log_error("Compressed attributes not supported yet.\n");
1160                 /* FIXME: Compress attribute into a temporary buffer, set */
1161                 /* val accordingly and save the compressed size. */
1162                 err = -EOPNOTSUPP;
1163                 goto err_out;
1164         }
1165         if (flags & (ATTR_IS_ENCRYPTED | ATTR_IS_SPARSE)) {
1166                 ntfs_log_error("Encrypted/sparse attributes not supported.\n");
1167                 err = -EOPNOTSUPP;
1168                 goto err_out;
1169         }
1170         if (flags & ATTR_COMPRESSION_MASK) {
1171                 hdr_size = 72;
1172                 /* FIXME: This compression stuff is all wrong. Never mind for */
1173                 /* now. (AIA) */
1174                 if (val_len)
1175                         mpa_size = 0; /* get_size_for_compressed_mapping_pairs(rl); */
1176                 else
1177                         mpa_size = 0;
1178         } else {
1179                 hdr_size = 64;
1180                 if (val_len) {
1181                         mpa_size = ntfs_get_size_for_mapping_pairs(g_vol, rl, 0);
1182                         if (mpa_size < 0) {
1183                                 err = -errno;
1184                                 ntfs_log_error("Failed to get size for mapping "
1185                                                 "pairs.\n");
1186                                 goto err_out;
1187                         }
1188                 } else {
1189                         mpa_size = 0;
1190                 }
1191         }
1192         /* Mapping pairs array and next attribute must be 8-byte aligned. */
1193         asize = (((int)hdr_size + ((name_len + 7) & ~7) + mpa_size) + 7) & ~7;
1194         /* Get the highest vcn. */
1195         for (i = 0, highest_vcn = 0LL; rl[i].length; i++)
1196                 highest_vcn += rl[i].length;
1197         /* Does the value fit inside the allocated size? */
1198         if (highest_vcn * g_vol->cluster_size < val_len) {
1199                 ntfs_log_error("BUG: Allocated size is smaller than data size!\n");
1200                 err = -EINVAL;
1201                 goto err_out;
1202         }
1203         err = make_room_for_attribute(m, (char*)a, asize);
1204         if (err == -ENOSPC) {
1205                 /*
1206                  * FIXME: Make space! (AIA)
1207                  * can we make it non-resident? if yes, do that.
1208                  *      does it fit now? yes -> do it.
1209                  * m's $DATA or $BITMAP+$INDEX_ALLOCATION resident?
1210                  * yes -> make non-resident
1211                  *      does it fit now? yes -> do it.
1212                  * make all attributes non-resident
1213                  *      does it fit now? yes -> do it.
1214                  * m is a base record? yes -> allocate extension record
1215                  *      does the new attribute fit in there? yes -> do it.
1216                  * split up runlist into extents and place each in an extension
1217                  * record.
1218                  * FIXME: the check for needing extension records should be
1219                  * earlier on as it is very quick: asize > m->bytes_allocated?
1220                  */
1221                 err = -EOPNOTSUPP;
1222                 goto err_out;
1223 #ifdef DEBUG
1224         } else if (err == -EINVAL) {
1225                 ntfs_log_error("BUG(): in insert_positioned_attribute_in_mft_"
1226                                 "record(): make_room_for_attribute() returned "
1227                                 "error: EINVAL!\n");
1228                 goto err_out;
1229 #endif
1230         }
1231         a->type = type;
1232         a->length = cpu_to_le32(asize);
1233         a->non_resident = 1;
1234         a->name_length = name_len;
1235         a->name_offset = cpu_to_le16(hdr_size);
1236         a->flags = flags;
1237         a->instance = m->next_attr_instance;
1238         m->next_attr_instance = cpu_to_le16((le16_to_cpu(m->next_attr_instance)
1239                         + 1) & 0xffff);
1240         a->u.nonres.lowest_vcn = 0;
1241         a->u.nonres.highest_vcn = cpu_to_sle64(highest_vcn - 1LL);
1242         a->u.nonres.mapping_pairs_offset = cpu_to_le16(hdr_size + ((name_len + 7) & ~7));
1243         memset(a->u.nonres.reserved1, 0, sizeof(a->u.nonres.reserved1));
1244         /* FIXME: Allocated size depends on compression. */
1245         a->u.nonres.allocated_size = cpu_to_sle64(highest_vcn * g_vol->cluster_size);
1246         a->u.nonres.data_size = cpu_to_sle64(val_len);
1247         if (name_len)
1248                 memcpy((char*)a + hdr_size, uname, name_len << 1);
1249         if (flags & ATTR_COMPRESSION_MASK) {
1250                 if (flags & ATTR_COMPRESSION_MASK & ~ATTR_IS_COMPRESSED) {
1251                         ntfs_log_error("Unknown compression format. Reverting "
1252                                         "to standard compression.\n");
1253                         a->flags &= ~ATTR_COMPRESSION_MASK;
1254                         a->flags |= ATTR_IS_COMPRESSED;
1255                 }
1256                 a->u.nonres.compression_unit = 4;
1257                 inited_size = val_len;
1258                 /* FIXME: Set the compressed size. */
1259                 a->u.nonres.compressed_size = 0;
1260                 /* FIXME: Write out the compressed data. */
1261                 /* FIXME: err = build_mapping_pairs_compressed(); */
1262                 err = -EOPNOTSUPP;
1263         } else {
1264                 a->u.nonres.compression_unit = 0;
1265                 bw = ntfs_rlwrite(g_vol->u.dev, rl, val, val_len, &inited_size);
1266                 if (bw != val_len) {
1267                         ntfs_log_error("Error writing non-resident attribute "
1268                                         "value.\n");
1269                         return -errno;
1270                 }
1271                 err = ntfs_mapping_pairs_build(g_vol, (u8*)a + hdr_size +
1272                                 ((name_len + 7) & ~7), mpa_size, rl, 0, NULL);
1273         }
1274         a->u.nonres.initialized_size = cpu_to_sle64(inited_size);
1275         if (err < 0 || bw != val_len) {
1276                 /* FIXME: Handle error. */
1277                 /* deallocate clusters */
1278                 /* remove attribute */
1279                 if (err >= 0)
1280                         err = -EIO;
1281                 ntfs_log_error("insert_positioned_attr_in_mft_record failed "
1282                                 "with error %i.\n", err < 0 ? err : (int)bw);
1283         }
1284 err_out:
1285         if (ctx)
1286                 ntfs_attr_put_search_ctx(ctx);
1287         ntfs_ucsfree(uname);
1288         return err;
1289 }
1290 
1291 /**
1292  * insert_non_resident_attr_in_mft_record
1293  *
1294  * Return 0 on success and -errno on error.
1295  */
1296 static int insert_non_resident_attr_in_mft_record(MFT_RECORD *m,
1297                 const ATTR_TYPES type, const char *name, u32 name_len,
1298                 const IGNORE_CASE_BOOL ic, const ATTR_FLAGS flags,
1299                 const u8 *val, const s64 val_len)
1300 {
1301         ntfs_attr_search_ctx *ctx;
1302         ATTR_RECORD *a;
1303         u16 hdr_size;
1304         int asize, mpa_size, err, i;
1305         runlist *rl = NULL;
1306         s64 bw = 0;
1307         ntfschar *uname = NULL;
1308         int uname_len = 0;
1309         /*
1310         if (base record)
1311                 attr_lookup();
1312         else
1313         */
1314 
1315         uname = ntfs_str2ucs(name, &uname_len);
1316         if (!uname)
1317                 return -errno;
1318 
1319         /* Check if the attribute is already there. */
1320         ctx = ntfs_attr_get_search_ctx(NULL, m);
1321         if (!ctx) {
1322                 ntfs_log_error("Failed to allocate attribute search context.\n");
1323                 err = -ENOMEM;
1324                 goto err_out;
1325         }
1326         if (ic == IGNORE_CASE) {
1327                 ntfs_log_error("FIXME: Hit unimplemented code path #2.\n");
1328                 err = -EOPNOTSUPP;
1329                 goto err_out;
1330         }
1331         if (!mkntfs_attr_lookup(type, uname, uname_len, ic, 0, NULL, 0, ctx)) {
1332                 err = -EEXIST;
1333                 goto err_out;
1334         }
1335         if (errno != ENOENT) {
1336                 ntfs_log_error("Corrupt inode.\n");
1337                 err = -errno;
1338                 goto err_out;
1339         }
1340         a = ctx->attr;
1341         if (flags & ATTR_COMPRESSION_MASK) {
1342                 ntfs_log_error("Compressed attributes not supported yet.\n");
1343                 /* FIXME: Compress attribute into a temporary buffer, set */
1344                 /* val accordingly and save the compressed size. */
1345                 err = -EOPNOTSUPP;
1346                 goto err_out;
1347         }
1348         if (flags & (ATTR_IS_ENCRYPTED | ATTR_IS_SPARSE)) {
1349                 ntfs_log_error("Encrypted/sparse attributes not supported.\n");
1350                 err = -EOPNOTSUPP;
1351                 goto err_out;
1352         }
1353         if (val_len) {
1354                 rl = allocate_scattered_clusters((val_len +
1355                                 g_vol->cluster_size - 1) / g_vol->cluster_size);
1356                 if (!rl) {
1357                         err = -errno;
1358                         ntfs_log_perror("Failed to allocate scattered clusters");
1359                         goto err_out;
1360                 }
1361         } else {
1362                 rl = NULL;
1363         }
1364         if (flags & ATTR_COMPRESSION_MASK) {
1365                 hdr_size = 72;
1366                 /* FIXME: This compression stuff is all wrong. Never mind for */
1367                 /* now. (AIA) */
1368                 if (val_len)
1369                         mpa_size = 0; /* get_size_for_compressed_mapping_pairs(rl); */
1370                 else
1371                         mpa_size = 0;
1372         } else {
1373                 hdr_size = 64;
1374                 if (val_len) {
1375                         mpa_size = ntfs_get_size_for_mapping_pairs(g_vol, rl, 0);
1376                         if (mpa_size < 0) {
1377                                 err = -errno;
1378                                 ntfs_log_error("Failed to get size for mapping "
1379                                                 "pairs.\n");
1380                                 goto err_out;
1381                         }
1382                 } else {
1383                         mpa_size = 0;
1384                 }
1385         }
1386         /* Mapping pairs array and next attribute must be 8-byte aligned. */
1387         asize = (((int)hdr_size + ((name_len + 7) & ~7) + mpa_size) + 7) & ~7;
1388         err = make_room_for_attribute(m, (char*)a, asize);
1389         if (err == -ENOSPC) {
1390                 /*
1391                  * FIXME: Make space! (AIA)
1392                  * can we make it non-resident? if yes, do that.
1393                  *      does it fit now? yes -> do it.
1394                  * m's $DATA or $BITMAP+$INDEX_ALLOCATION resident?
1395                  * yes -> make non-resident
1396                  *      does it fit now? yes -> do it.
1397                  * make all attributes non-resident
1398                  *      does it fit now? yes -> do it.
1399                  * m is a base record? yes -> allocate extension record
1400                  *      does the new attribute fit in there? yes -> do it.
1401                  * split up runlist into extents and place each in an extension
1402                  * record.
1403                  * FIXME: the check for needing extension records should be
1404                  * earlier on as it is very quick: asize > m->bytes_allocated?
1405                  */
1406                 err = -EOPNOTSUPP;
1407                 goto err_out;
1408 #ifdef DEBUG
1409         } else if (err == -EINVAL) {
1410                 ntfs_log_error("BUG(): in insert_non_resident_attribute_in_"
1411                                 "mft_record(): make_room_for_attribute() "
1412                                 "returned error: EINVAL!\n");
1413                 goto err_out;
1414 #endif
1415         }
1416         a->type = type;
1417         a->length = cpu_to_le32(asize);
1418         a->non_resident = 1;
1419         a->name_length = name_len;
1420         a->name_offset = cpu_to_le16(hdr_size);
1421         a->flags = flags;
1422         a->instance = m->next_attr_instance;
1423         m->next_attr_instance = cpu_to_le16((le16_to_cpu(m->next_attr_instance)
1424                         + 1) & 0xffff);
1425         a->u.nonres.lowest_vcn = 0;
1426         for (i = 0; rl[i].length; i++)
1427                 ;
1428         a->u.nonres.highest_vcn = cpu_to_sle64(rl[i].vcn - 1);
1429         a->u.nonres.mapping_pairs_offset = cpu_to_le16(hdr_size + ((name_len + 7) & ~7));
1430         memset(a->u.nonres.reserved1, 0, sizeof(a->u.nonres.reserved1));
1431         /* FIXME: Allocated size depends on compression. */
1432         a->u.nonres.allocated_size = cpu_to_sle64((val_len + (g_vol->cluster_size - 1)) &
1433                         ~(g_vol->cluster_size - 1));
1434         a->u.nonres.data_size = cpu_to_sle64(val_len);
1435         a->u.nonres.initialized_size = cpu_to_sle64(val_len);
1436         if (name_len)
1437                 memcpy((char*)a + hdr_size, uname, name_len << 1);
1438         if (flags & ATTR_COMPRESSION_MASK) {
1439                 if (flags & ATTR_COMPRESSION_MASK & ~ATTR_IS_COMPRESSED) {
1440                         ntfs_log_error("Unknown compression format. Reverting "
1441                                         "to standard compression.\n");
1442                         a->flags &= ~ATTR_COMPRESSION_MASK;
1443                         a->flags |= ATTR_IS_COMPRESSED;
1444                 }
1445                 a->u.nonres.compression_unit = 4;
1446                 /* FIXME: Set the compressed size. */
1447                 a->u.nonres.compressed_size = 0;
1448                 /* FIXME: Write out the compressed data. */
1449                 /* FIXME: err = build_mapping_pairs_compressed(); */
1450                 err = -EOPNOTSUPP;
1451         } else {
1452                 a->u.nonres.compression_unit = 0;
1453                 bw = ntfs_rlwrite(g_vol->u.dev, rl, val, val_len, NULL);
1454                 if (bw != val_len) {
1455                         ntfs_log_error("Error writing non-resident attribute "
1456                                         "value.\n");
1457                         return -errno;
1458                 }
1459                 err = ntfs_mapping_pairs_build(g_vol, (u8*)a + hdr_size +
1460                                 ((name_len + 7) & ~7), mpa_size, rl, 0, NULL);
1461         }
1462         if (err < 0 || bw != val_len) {
1463                 /* FIXME: Handle error. */
1464                 /* deallocate clusters */
1465                 /* remove attribute */
1466                 if (err >= 0)
1467                         err = -EIO;
1468                 ntfs_log_error("insert_non_resident_attr_in_mft_record failed with "
1469                         "error %lld.\n", (long long) (err < 0 ? err : bw));
1470         }
1471 err_out:
1472         if (ctx)
1473                 ntfs_attr_put_search_ctx(ctx);
1474         ntfs_ucsfree(uname);
1475         free(rl);
1476         return err;
1477 }
1478 
1479 /**
1480  * insert_resident_attr_in_mft_record
1481  *
1482  * Return 0 on success and -errno on error.
1483  */
1484 static int insert_resident_attr_in_mft_record(MFT_RECORD *m,
1485                 const ATTR_TYPES type, const char *name, u32 name_len,
1486                 const IGNORE_CASE_BOOL ic, const ATTR_FLAGS flags,
1487                 const RESIDENT_ATTR_FLAGS res_flags,
1488                 const u8 *val, const u32 val_len)
1489 {
1490         ntfs_attr_search_ctx *ctx;
1491         ATTR_RECORD *a;
1492         int asize, err;
1493         ntfschar *uname = NULL;
1494         int uname_len = 0;
1495         /*
1496         if (base record)
1497                 mkntfs_attr_lookup();
1498         else
1499         */
1500 
1501         uname = ntfs_str2ucs(name, &uname_len);
1502         if (!uname)
1503                 return -errno;
1504 
1505         /* Check if the attribute is already there. */
1506         ctx = ntfs_attr_get_search_ctx(NULL, m);
1507         if (!ctx) {
1508                 ntfs_log_error("Failed to allocate attribute search context.\n");
1509                 err = -ENOMEM;
1510                 goto err_out;
1511         }
1512         if (ic == IGNORE_CASE) {
1513                 ntfs_log_error("FIXME: Hit unimplemented code path #3.\n");
1514                 err = -EOPNOTSUPP;
1515                 goto err_out;
1516         }
1517         if (!mkntfs_attr_lookup(type, uname, uname_len, ic, 0, val, val_len,
1518                         ctx)) {
1519                 err = -EEXIST;
1520                 goto err_out;
1521         }
1522         if (errno != ENOENT) {
1523                 ntfs_log_error("Corrupt inode.\n");
1524                 err = -errno;
1525                 goto err_out;
1526         }
1527         a = ctx->attr;
1528         /* sizeof(resident attribute record header) == 24 */
1529         asize = ((24 + ((name_len + 7) & ~7) + val_len) + 7) & ~7;
1530         err = make_room_for_attribute(m, (char*)a, asize);
1531         if (err == -ENOSPC) {
1532                 /*
1533                  * FIXME: Make space! (AIA)
1534                  * can we make it non-resident? if yes, do that.
1535                  *      does it fit now? yes -> do it.
1536                  * m's $DATA or $BITMAP+$INDEX_ALLOCATION resident?
1537                  * yes -> make non-resident
1538                  *      does it fit now? yes -> do it.
1539                  * make all attributes non-resident
1540                  *      does it fit now? yes -> do it.
1541                  * m is a base record? yes -> allocate extension record
1542                  *      does the new attribute fit in there? yes -> do it.
1543                  * split up runlist into extents and place each in an extension
1544                  * record.
1545                  * FIXME: the check for needing extension records should be
1546                  * earlier on as it is very quick: asize > m->bytes_allocated?
1547                  */
1548                 err = -EOPNOTSUPP;
1549                 goto err_out;
1550         }
1551 #ifdef DEBUG
1552         if (err == -EINVAL) {
1553                 ntfs_log_error("BUG(): in insert_resident_attribute_in_mft_"
1554                                 "record(): make_room_for_attribute() returned "
1555                                 "error: EINVAL!\n");
1556                 goto err_out;
1557         }
1558 #endif
1559         a->type = type;
1560         a->length = cpu_to_le32(asize);
1561         a->non_resident = 0;
1562         a->name_length = name_len;
1563         if (type == AT_OBJECT_ID)
1564                 a->name_offset = const_cpu_to_le16(0);
1565         else
1566                 a->name_offset = const_cpu_to_le16(24);
1567         a->flags = flags;
1568         a->instance = m->next_attr_instance;
1569         m->next_attr_instance = cpu_to_le16((le16_to_cpu(m->next_attr_instance)
1570                         + 1) & 0xffff);
1571         a->u.res.value_length = cpu_to_le32(val_len);
1572         a->u.res.value_offset = cpu_to_le16(24 + ((name_len + 7) & ~7));
1573         a->u.res.resident_flags = res_flags;
1574         a->u.res.reservedR = 0;
1575         if (name_len)
1576                 memcpy((char*)a + 24, uname, name_len << 1);
1577         if (val_len)
1578                 memcpy((char*)a + le16_to_cpu(a->u.res.value_offset), val, val_len);
1579 err_out:
1580         if (ctx)
1581                 ntfs_attr_put_search_ctx(ctx);
1582         ntfs_ucsfree(uname);
1583         return err;
1584 }
1585 
1586 
1587 /**
1588  * add_attr_std_info
1589  *
1590  * Return 0 on success or -errno on error.
1591  */
1592 static int add_attr_std_info(MFT_RECORD *m, const FILE_ATTR_FLAGS flags,
1593                 le32 security_id)
1594 {
1595         STANDARD_INFORMATION si;
1596         int err, sd_size;
1597 
1598         sd_size = 48;
1599 
1600         si.creation_time = utc2ntfs(mkntfs_time());
1601         si.last_data_change_time = si.creation_time;
1602         si.last_mft_change_time = si.creation_time;
1603         si.last_access_time = si.creation_time;
1604         si.file_attributes = flags; /* already LE */
1605         si.u.v30.maximum_versions = cpu_to_le32(0);
1606         si.u.v30.version_number = cpu_to_le32(0);
1607         si.u.v30.class_id = cpu_to_le32(0);
1608         si.u.v30.security_id = security_id;
1609         if (si.u.v30.security_id != 0)
1610                 sd_size = 72;
1611         /* FIXME: $Quota support... */
1612         si.u.v30.owner_id = cpu_to_le32(0);
1613         si.u.v30.quota_charged = cpu_to_le64(0ULL);
1614         /* FIXME: $UsnJrnl support... Not needed on fresh w2k3-volume */
1615         si.u.v30.usn = cpu_to_le64(0ULL);
1616         /* NTFS 1.2: size of si = 48, NTFS 3.[01]: size of si = 72 */
1617         err = insert_resident_attr_in_mft_record(m, AT_STANDARD_INFORMATION,
1618                         NULL, 0, 0, 0, 0, (u8*)&si, sd_size);
1619         if (err < 0)
1620                 ntfs_log_perror("add_attr_std_info failed");
1621         return err;
1622 }
1623 
1624 /**
1625  * add_attr_file_name
1626  *
1627  * Return 0 on success or -errno on error.
1628  */
1629 static int add_attr_file_name(MFT_RECORD *m, const leMFT_REF parent_dir,
1630                 const s64 allocated_size, const s64 data_size,
1631                 const FILE_ATTR_FLAGS flags, const u16 packed_ea_size,
1632                 const u32 reparse_point_tag, const char *file_name,
1633                 const FILE_NAME_TYPE_FLAGS file_name_type)
1634 {
1635         ntfs_attr_search_ctx *ctx;
1636         STANDARD_INFORMATION *si;
1637         FILE_NAME_ATTR *fn;
1638         int i, fn_size;
1639         ntfschar *uname;
1640 
1641         /* Check if the attribute is already there. */
1642         ctx = ntfs_attr_get_search_ctx(NULL, m);
1643         if (!ctx) {
1644                 ntfs_log_error("Failed to get attribute search context.\n");
1645                 return -ENOMEM;
1646         }
1647         if (mkntfs_attr_lookup(AT_STANDARD_INFORMATION, AT_UNNAMED, 0, 0, 0,
1648                                 NULL, 0, ctx)) {
1649                 int eo = errno;
1650                 ntfs_log_error("BUG: Standard information attribute not "
1651                                 "present in file record.\n");
1652                 ntfs_attr_put_search_ctx(ctx);
1653                 return -eo;
1654         }
1655         si = (STANDARD_INFORMATION*)((char*)ctx->attr +
1656                         le16_to_cpu(ctx->attr->u.res.value_offset));
1657         i = (strlen(file_name) + 1) * sizeof(ntfschar);
1658         fn_size = sizeof(FILE_NAME_ATTR) + i;
1659         fn = ntfs_malloc(fn_size);
1660         if (!fn) {
1661                 ntfs_attr_put_search_ctx(ctx);
1662                 return -errno;
1663         }
1664         fn->parent_directory = parent_dir;
1665 
1666         fn->creation_time = si->creation_time;
1667         fn->last_data_change_time = si->last_data_change_time;
1668         fn->last_mft_change_time = si->last_mft_change_time;
1669         fn->last_access_time = si->last_access_time;
1670         ntfs_attr_put_search_ctx(ctx);
1671 
1672         fn->allocated_size = cpu_to_sle64(allocated_size);
1673         fn->data_size = cpu_to_sle64(data_size);
1674         fn->file_attributes = flags;
1675         /* These are in a union so can't have both. */
1676         if (packed_ea_size && reparse_point_tag) {
1677                 free(fn);
1678                 return -EINVAL;
1679         }
1680         if (packed_ea_size) {
1681                 fn->u.s.packed_ea_size = cpu_to_le16(packed_ea_size);
1682                 fn->u.s.reserved = cpu_to_le16(0);
1683         } else {
1684                 fn->u.reparse_point_tag = cpu_to_le32(reparse_point_tag);
1685         }
1686         fn->file_name_type = file_name_type;
1687         uname = fn->file_name;
1688         i = ntfs_mbstoucs(file_name, &uname, i);
1689         if (i < 1) {
1690                 free(fn);
1691                 return -EINVAL;
1692         }
1693         if (i > 0xff) {
1694                 free(fn);
1695                 return -ENAMETOOLONG;
1696         }
1697         /* No terminating null in file names. */
1698         fn->file_name_length = i;
1699         fn_size = sizeof(FILE_NAME_ATTR) + i * sizeof(ntfschar);
1700         i = insert_resident_attr_in_mft_record(m, AT_FILE_NAME, NULL, 0, 0,
1701                         0, RESIDENT_ATTR_IS_INDEXED, (u8*)fn, fn_size);
1702         free(fn);
1703         if (i < 0)
1704                 ntfs_log_error("add_attr_file_name failed: %s\n", strerror(-i));
1705         return i;
1706 }
1707 
1708 #ifdef ENABLE_UUID
1709 
1710 /**
1711  * add_attr_object_id -
1712  *
1713  * Note we insert only a basic object id which only has the GUID and none of
1714  * the extended fields.  This is because we currently only use this function
1715  * when creating the object id for the volume.
1716  *
1717  * Return 0 on success or -errno on error.
1718  */
1719 static int add_attr_object_id(MFT_RECORD *m, const GUID *object_id)
1720 {
1721         OBJECT_ID_ATTR oi;
1722         int err;
1723 
1724         oi = (OBJECT_ID_ATTR) {
1725                 .object_id = *object_id,
1726         };
1727         err = insert_resident_attr_in_mft_record(m, AT_OBJECT_ID, NULL,
1728                         0, 0, 0, 0, (u8*)&oi, sizeof(oi.object_id));
1729         if (err < 0)
1730                 ntfs_log_error("add_attr_vol_info failed: %s\n", strerror(-err));
1731         return err;
1732 }
1733 
1734 #endif
1735 
1736 /**
1737  * add_attr_sd
1738  *
1739  * Create the security descriptor attribute adding the security descriptor @sd
1740  * of length @sd_len to the mft record @m.
1741  *
1742  * Return 0 on success or -errno on error.
1743  */
1744 static int add_attr_sd(MFT_RECORD *m, const u8 *sd, const s64 sd_len)
1745 {
1746         int err;
1747 
1748         /* Does it fit? NO: create non-resident. YES: create resident. */
1749         if (le32_to_cpu(m->bytes_in_use) + 24 + sd_len >
1750                                                 le32_to_cpu(m->bytes_allocated))
1751                 err = insert_non_resident_attr_in_mft_record(m,
1752                                 AT_SECURITY_DESCRIPTOR, NULL, 0, 0, 0, sd,
1753                                 sd_len);
1754         else
1755                 err = insert_resident_attr_in_mft_record(m,
1756                                 AT_SECURITY_DESCRIPTOR, NULL, 0, 0, 0, 0, sd,
1757                                 sd_len);
1758         if (err < 0)
1759                 ntfs_log_error("add_attr_sd failed: %s\n", strerror(-err));
1760         return err;
1761 }
1762 
1763 /**
1764  * add_attr_data
1765  *
1766  * Return 0 on success or -errno on error.
1767  */
1768 static int add_attr_data(MFT_RECORD *m, const char *name, const u32 name_len,
1769                 const IGNORE_CASE_BOOL ic, const ATTR_FLAGS flags,
1770                 const u8 *val, const s64 val_len)
1771 {
1772         int err;
1773 
1774         /*
1775          * Does it fit? NO: create non-resident. YES: create resident.
1776          *
1777          * FIXME: Introduced arbitrary limit of mft record allocated size - 512.
1778          * This is to get around the problem that if $Bitmap/$DATA becomes too
1779          * big, but is just small enough to be resident, we would make it
1780          * resident, and later run out of space when creating the other
1781          * attributes and this would cause us to abort as making resident
1782          * attributes non-resident is not supported yet.
1783          * The proper fix is to support making resident attribute non-resident.
1784          */
1785         if (le32_to_cpu(m->bytes_in_use) + 24 + val_len >
1786                         min(le32_to_cpu(m->bytes_allocated),
1787                         le32_to_cpu(m->bytes_allocated) - 512))
1788                 err = insert_non_resident_attr_in_mft_record(m, AT_DATA, name,
1789                                 name_len, ic, flags, val, val_len);
1790         else
1791                 err = insert_resident_attr_in_mft_record(m, AT_DATA, name,
1792                                 name_len, ic, flags, 0, val, val_len);
1793 
1794         if (err < 0)
1795                 ntfs_log_error("add_attr_data failed: %s\n", strerror(-err));
1796         return err;
1797 }
1798 
1799 /**
1800  * add_attr_data_positioned
1801  *
1802  * Create a non-resident data attribute with a predefined on disk location
1803  * specified by the runlist @rl. The clusters specified by @rl are assumed to
1804  * be allocated already.
1805  *
1806  * Return 0 on success or -errno on error.
1807  */
1808 static int add_attr_data_positioned(MFT_RECORD *m, const char *name,
1809                 const u32 name_len, const IGNORE_CASE_BOOL ic,
1810                 const ATTR_FLAGS flags, const runlist *rl,
1811                 const u8 *val, const s64 val_len)
1812 {
1813         int err;
1814 
1815         err = insert_positioned_attr_in_mft_record(m, AT_DATA, name, name_len,
1816                         ic, flags, rl, val, val_len);
1817         if (err < 0)
1818                 ntfs_log_error("add_attr_data_positioned failed: %s\n",
1819                                 strerror(-err));
1820         return err;
1821 }
1822 
1823 /**
1824  * add_attr_vol_name
1825  *
1826  * Create volume name attribute specifying the volume name @vol_name as a null
1827  * terminated char string of length @vol_name_len (number of characters not
1828  * including the terminating null), which is converted internally to a little
1829  * endian ntfschar string. The name is at least 1 character long and at most
1830  * 0xff characters long (not counting the terminating null).
1831  *
1832  * Return 0 on success or -errno on error.
1833  */
1834 static int add_attr_vol_name(MFT_RECORD *m, const char *vol_name,
1835                 const int vol_name_len __attribute__((unused)))
1836 {
1837         ntfschar *uname = NULL;
1838         int uname_len = 0;
1839         int i;
1840 
1841         if (vol_name) {
1842                 uname_len = ntfs_mbstoucs(vol_name, &uname, 0);
1843                 if (uname_len < 0)
1844                         return -errno;
1845                 if (uname_len > 0xff) {
1846                         free(uname);
1847                         return -ENAMETOOLONG;
1848                 }
1849         }
1850         i = insert_resident_attr_in_mft_record(m, AT_VOLUME_NAME, NULL, 0, 0,
1851                         0, 0, (u8*)uname, uname_len*sizeof(ntfschar));
1852         free(uname);
1853         if (i < 0)
1854                 ntfs_log_error("add_attr_vol_name failed: %s\n", strerror(-i));
1855         return i;
1856 }
1857 
1858 /**
1859  * add_attr_vol_info
1860  *
1861  * Return 0 on success or -errno on error.
1862  */
1863 static int add_attr_vol_info(MFT_RECORD *m, const VOLUME_FLAGS flags,
1864                 const u8 major_ver, const u8 minor_ver)
1865 {
1866         VOLUME_INFORMATION vi;
1867         int err;
1868 
1869         memset(&vi, 0, sizeof(vi));
1870         vi.major_ver = major_ver;
1871         vi.minor_ver = minor_ver;
1872         vi.flags = flags & VOLUME_FLAGS_MASK;
1873         err = insert_resident_attr_in_mft_record(m, AT_VOLUME_INFORMATION, NULL,
1874                         0, 0, 0, 0, (u8*)&vi, sizeof(vi));
1875         if (err < 0)
1876                 ntfs_log_error("add_attr_vol_info failed: %s\n", strerror(-err));
1877         return err;
1878 }
1879 
1880 /**
1881  * add_attr_index_root
1882  *
1883  * Return 0 on success or -errno on error.
1884  */
1885 static int add_attr_index_root(MFT_RECORD *m, const char *name,
1886                 const u32 name_len, const IGNORE_CASE_BOOL ic,
1887                 const ATTR_TYPES indexed_attr_type,
1888                 const COLLATION_RULES collation_rule,
1889                 const u32 index_block_size)
1890 {
1891         INDEX_ROOT *r;
1892         INDEX_ENTRY_HEADER *e;
1893         int err, val_len;
1894 
1895         val_len = sizeof(INDEX_ROOT) + sizeof(INDEX_ENTRY_HEADER);
1896         r = ntfs_malloc(val_len);
1897         if (!r)
1898                 return -errno;
1899         r->type = (indexed_attr_type == AT_FILE_NAME) ? AT_FILE_NAME : 0;
1900         if (indexed_attr_type == AT_FILE_NAME &&
1901                         collation_rule != COLLATION_FILE_NAME) {
1902                 free(r);
1903                 ntfs_log_error("add_attr_index_root: indexed attribute is $FILE_NAME "
1904                         "but collation rule is not COLLATION_FILE_NAME.\n");
1905                 return -EINVAL;
1906         }
1907         r->collation_rule = collation_rule;
1908         r->index_block_size = cpu_to_le32(index_block_size);
1909         if (index_block_size >= g_vol->cluster_size) {
1910                 if (index_block_size % g_vol->cluster_size) {
1911                         ntfs_log_error("add_attr_index_root: index block size is not "
1912                                         "a multiple of the cluster size.\n");
1913                         free(r);
1914                         return -EINVAL;
1915                 }
1916                 r->clusters_per_index_block = index_block_size /
1917                                 g_vol->cluster_size;
1918         } else { /* if (g_vol->cluster_size > index_block_size) */
1919                 if (index_block_size & (index_block_size - 1)) {
1920                         ntfs_log_error("add_attr_index_root: index block size is not "
1921                                         "a power of 2.\n");
1922                         free(r);
1923                         return -EINVAL;
1924                 }
1925                 if (index_block_size < (u32)opts.sector_size) {
1926                          ntfs_log_error("add_attr_index_root: index block size "
1927                                          "is smaller than the sector size.\n");
1928                          free(r);
1929                          return -EINVAL;
1930                 }
1931                 r->clusters_per_index_block = index_block_size /
1932                                 opts.sector_size;
1933         }
1934         memset(&r->reserved, 0, sizeof(r->reserved));
1935         r->index.entries_offset = const_cpu_to_le32(sizeof(INDEX_HEADER));
1936         r->index.index_length = const_cpu_to_le32(sizeof(INDEX_HEADER) +
1937                         sizeof(INDEX_ENTRY_HEADER));
1938         r->index.allocated_size = r->index.index_length;
1939         r->index.flags = SMALL_INDEX;
1940         memset(&r->index.reserved, 0, sizeof(r->index.reserved));
1941         e = (INDEX_ENTRY_HEADER*)((u8*)&r->index +
1942                         le32_to_cpu(r->index.entries_offset));
1943         /*
1944          * No matter whether this is a file index or a view as this is a
1945          * termination entry, hence no key value / data is associated with it
1946          * at all. Thus, we just need the union to be all zero.
1947          */
1948         e->u.indexed_file = const_cpu_to_le64(0LL);
1949         e->length = const_cpu_to_le16(sizeof(INDEX_ENTRY_HEADER));
1950         e->key_length = const_cpu_to_le16(0);
1951         e->flags = INDEX_ENTRY_END;
1952         e->reserved = const_cpu_to_le16(0);
1953         err = insert_resident_attr_in_mft_record(m, AT_INDEX_ROOT, name,
1954                                 name_len, ic, 0, 0, (u8*)r, val_len);
1955         free(r);
1956         if (err < 0)
1957                 ntfs_log_error("add_attr_index_root failed: %s\n", strerror(-err));
1958         return err;
1959 }
1960 
1961 /**
1962  * add_attr_index_alloc
1963  *
1964  * Return 0 on success or -errno on error.
1965  */
1966 static int add_attr_index_alloc(MFT_RECORD *m, const char *name,
1967                 const u32 name_len, const IGNORE_CASE_BOOL ic,
1968                 const u8 *index_alloc_val, const u32 index_alloc_val_len)
1969 {
1970         int err;
1971 
1972         err = insert_non_resident_attr_in_mft_record(m, AT_INDEX_ALLOCATION,
1973                         name, name_len, ic, 0, index_alloc_val,
1974                         index_alloc_val_len);
1975         if (err < 0)
1976                 ntfs_log_error("add_attr_index_alloc failed: %s\n", strerror(-err));
1977         return err;
1978 }
1979 
1980 /**
1981  * add_attr_bitmap
1982  *
1983  * Return 0 on success or -errno on error.
1984  */
1985 static int add_attr_bitmap(MFT_RECORD *m, const char *name, const u32 name_len,
1986                 const IGNORE_CASE_BOOL ic, const u8 *bitmap,
1987                 const u32 bitmap_len)
1988 {
1989         int err;
1990 
1991         /* Does it fit? NO: create non-resident. YES: create resident. */
1992         if (le32_to_cpu(m->bytes_in_use) + 24 + bitmap_len >
1993                                                 le32_to_cpu(m->bytes_allocated))
1994                 err = insert_non_resident_attr_in_mft_record(m, AT_BITMAP, name,
1995                                 name_len, ic, 0, bitmap, bitmap_len);
1996         else
1997                 err = insert_resident_attr_in_mft_record(m, AT_BITMAP, name,
1998                                 name_len, ic, 0, 0, bitmap, bitmap_len);
1999 
2000         if (err < 0)
2001                 ntfs_log_error("add_attr_bitmap failed: %s\n", strerror(-err));
2002         return err;
2003 }
2004 
2005 /**
2006  * add_attr_bitmap_positioned
2007  *
2008  * Create a non-resident bitmap attribute with a predefined on disk location
2009  * specified by the runlist @rl. The clusters specified by @rl are assumed to
2010  * be allocated already.
2011  *
2012  * Return 0 on success or -errno on error.
2013  */
2014 static int add_attr_bitmap_positioned(MFT_RECORD *m, const char *name,
2015                 const u32 name_len, const IGNORE_CASE_BOOL ic,
2016                 const runlist *rl, const u8 *bitmap, const u32 bitmap_len)
2017 {
2018         int err;
2019 
2020         err = insert_positioned_attr_in_mft_record(m, AT_BITMAP, name, name_len,
2021                         ic, 0, rl, bitmap, bitmap_len);
2022         if (err < 0)
2023                 ntfs_log_error("add_attr_bitmap_positioned failed: %s\n",
2024                                 strerror(-err));
2025         return err;
2026 }
2027 
2028 
2029 /**
2030  * upgrade_to_large_index
2031  *
2032  * Create bitmap and index allocation attributes, modify index root
2033  * attribute accordingly and move all of the index entries from the index root
2034  * into the index allocation.
2035  *
2036  * Return 0 on success or -errno on error.
2037  */
2038 static int upgrade_to_large_index(MFT_RECORD *m, const char *name,
2039                 u32 name_len, const IGNORE_CASE_BOOL ic,
2040                 INDEX_ALLOCATION **idx)
2041 {
2042         ntfs_attr_search_ctx *ctx;
2043         ATTR_RECORD *a;
2044         INDEX_ROOT *r;
2045         INDEX_ENTRY *re;
2046         INDEX_ALLOCATION *ia_val = NULL;
2047         ntfschar *uname = NULL;
2048         int uname_len = 0;
2049         u8 bmp[8];
2050         char *re_start, *re_end;
2051         int i, err, index_block_size;
2052 
2053         uname = ntfs_str2ucs(name, &uname_len);
2054         if (!uname)
2055                 return -errno;
2056 
2057         /* Find the index root attribute. */
2058         ctx = ntfs_attr_get_search_ctx(NULL, m);
2059         if (!ctx) {
2060                 ntfs_log_error("Failed to allocate attribute search context.\n");
2061                 ntfs_ucsfree(uname);
2062                 return -ENOMEM;
2063         }
2064         if (ic == IGNORE_CASE) {
2065                 ntfs_log_error("FIXME: Hit unimplemented code path #4.\n");
2066                 err = -EOPNOTSUPP;
2067                 ntfs_ucsfree(uname);
2068                 goto err_out;
2069         }
2070         err = mkntfs_attr_lookup(AT_INDEX_ROOT, uname, uname_len, ic, 0, NULL, 0,
2071                         ctx);
2072         ntfs_ucsfree(uname);
2073         if (err) {
2074                 err = -ENOTDIR;
2075                 goto err_out;
2076         }
2077         a = ctx->attr;
2078         if (a->non_resident || a->flags) {
2079                 err = -EINVAL;
2080                 goto err_out;
2081         }
2082         r = (INDEX_ROOT*)((char*)a + le16_to_cpu(a->u.res.value_offset));
2083         re_end = (char*)r + le32_to_cpu(a->u.res.value_length);
2084         re_start = (char*)&r->index + le32_to_cpu(r->index.entries_offset);
2085         re = (INDEX_ENTRY*)re_start;
2086         index_block_size = le32_to_cpu(r->index_block_size);
2087         memset(bmp, 0, sizeof(bmp));
2088         ntfs_bit_set(bmp, 0ULL, 1);
2089         /* Bitmap has to be at least 8 bytes in size. */
2090         err = add_attr_bitmap(m, name, name_len, ic, bmp, sizeof(bmp));
2091         if (err)
2092                 goto err_out;
2093         ia_val = ntfs_calloc(index_block_size);
2094         if (!ia_val) {
2095                 err = -errno;
2096                 goto err_out;
2097         }
2098         /* Setup header. */
2099         ia_val->magic = magic_INDX;
2100         ia_val->usa_ofs = cpu_to_le16(sizeof(INDEX_ALLOCATION));
2101         if (index_block_size >= NTFS_BLOCK_SIZE) {
2102                 ia_val->usa_count = cpu_to_le16(index_block_size /
2103                                 NTFS_BLOCK_SIZE + 1);
2104         } else {
2105                 ia_val->usa_count = cpu_to_le16(1);
2106                 ntfs_log_error("Sector size is bigger than index block size. "
2107                                 "Setting usa_count to 1. If Windows chkdsk "
2108                                 "reports this as corruption, please email %s "
2109                                 "stating that you saw this message and that "
2110                                 "the filesystem created was corrupt.  "
2111                                 "Thank you.", NTFS_DEV_LIST);
2112         }
2113         /* Set USN to 1. */
2114         *(le16*)((char*)ia_val + le16_to_cpu(ia_val->usa_ofs)) =
2115                         cpu_to_le16(1);
2116         ia_val->lsn = 0;
2117         ia_val->index_block_vcn = 0;
2118         ia_val->index.flags = LEAF_NODE;
2119         /* Align to 8-byte boundary. */
2120         ia_val->index.entries_offset = cpu_to_le32((sizeof(INDEX_HEADER) +
2121                         le16_to_cpu(ia_val->usa_count) * 2 + 7) & ~7);
2122         ia_val->index.allocated_size = cpu_to_le32(index_block_size -
2123                         (sizeof(INDEX_ALLOCATION) - sizeof(INDEX_HEADER)));
2124         /* Find the last entry in the index root and save it in re. */
2125         while ((char*)re < re_end && !(re->flags & INDEX_ENTRY_END)) {
2126                 /* Next entry in index root. */
2127                 re = (INDEX_ENTRY*)((char*)re + le16_to_cpu(re->length));
2128         }
2129         /* Copy all the entries including the termination entry. */
2130         i = (char*)re - re_start + le16_to_cpu(re->length);
2131         memcpy((char*)&ia_val->index +
2132                         le32_to_cpu(ia_val->index.entries_offset), re_start, i);
2133         /* Finish setting up index allocation. */
2134         ia_val->index.index_length = cpu_to_le32(i +
2135                         le32_to_cpu(ia_val->index.entries_offset));
2136         /* Move the termination entry forward to the beginning if necessary. */
2137         if ((char*)re > re_start) {
2138                 memmove(re_start, (char*)re, le16_to_cpu(re->length));
2139                 re = (INDEX_ENTRY*)re_start;
2140         }
2141         /* Now fixup empty index root with pointer to index allocation VCN 0. */
2142         r->index.flags = LARGE_INDEX;
2143         re->flags |= INDEX_ENTRY_NODE;
2144         if (le16_to_cpu(re->length) < sizeof(INDEX_ENTRY_HEADER) + sizeof(VCN))
2145                 re->length = cpu_to_le16(le16_to_cpu(re->length) + sizeof(VCN));
2146         r->index.index_length = cpu_to_le32(le32_to_cpu(r->index.entries_offset)
2147                         + le16_to_cpu(re->length));
2148         r->index.allocated_size = r->index.index_length;
2149         /* Resize index root attribute. */
2150         if (ntfs_resident_attr_value_resize(m, a, sizeof(INDEX_ROOT) -
2151                         sizeof(INDEX_HEADER) +
2152                         le32_to_cpu(r->index.allocated_size))) {
2153                 /* TODO: Remove the added bitmap! */
2154                 /* Revert index root from index allocation. */
2155                 err = -errno;
2156                 goto err_out;
2157         }
2158         /* Set VCN pointer to 0LL. */
2159         *(leVCN*)((char*)re + le16_to_cpu(re->length) - sizeof(VCN)) = 0;
2160         err = ntfs_mst_pre_write_fixup((NTFS_RECORD*)ia_val, index_block_size);
2161         if (err) {
2162                 err = -errno;
2163                 ntfs_log_error("ntfs_mst_pre_write_fixup() failed in "
2164                                 "upgrade_to_large_index.\n");
2165                 goto err_out;
2166         }
2167         err = add_attr_index_alloc(m, name, name_len, ic, (u8*)ia_val,
2168                         index_block_size);
2169         ntfs_mst_post_write_fixup((NTFS_RECORD*)ia_val);
2170         if (err) {
2171                 /* TODO: Remove the added bitmap! */
2172                 /* Revert index root from index allocation. */
2173                 goto err_out;
2174         }
2175         *idx = ia_val;
2176         ntfs_attr_put_search_ctx(ctx);
2177         return 0;
2178 err_out:
2179         ntfs_attr_put_search_ctx(ctx);
2180         free(ia_val);
2181         return err;
2182 }
2183 
2184 /**
2185  * make_room_for_index_entry_in_index_block
2186  *
2187  * Create space of @size bytes at position @pos inside the index block @idx.
2188  *
2189  * Return 0 on success or -errno on error.
2190  */
2191 static int make_room_for_index_entry_in_index_block(INDEX_BLOCK *idx,
2192                 INDEX_ENTRY *pos, u32 size)
2193 {
2194         u32 biu;
2195 
2196         if (!size)
2197                 return 0;
2198 #ifdef DEBUG
2199         /*
2200          * Rigorous consistency checks. Always return -EINVAL even if more
2201          * appropriate codes exist for simplicity of parsing the return value.
2202          */
2203         if (size != ((size + 7) & ~7)) {
2204                 ntfs_log_error("make_room_for_index_entry_in_index_block() received "
2205                                 "non 8-byte aligned size.\n");
2206                 return -EINVAL;
2207         }
2208         if (!idx || !pos)
2209                 return -EINVAL;
2210         if ((char*)pos < (char*)idx || (char*)pos + size < (char*)idx ||
2211                         (char*)pos > (char*)idx + sizeof(INDEX_BLOCK) -
2212                                 sizeof(INDEX_HEADER) +
2213                                 le32_to_cpu(idx->index.allocated_size) ||
2214                         (char*)pos + size > (char*)idx + sizeof(INDEX_BLOCK) -
2215                                 sizeof(INDEX_HEADER) +
2216                                 le32_to_cpu(idx->index.allocated_size))
2217                 return -EINVAL;
2218         /* The - sizeof(INDEX_ENTRY_HEADER) is for the index terminator. */
2219         if ((char*)pos - (char*)&idx->index >
2220                         (int)le32_to_cpu(idx->index.index_length)
2221                         - (int)sizeof(INDEX_ENTRY_HEADER))
2222                 return -EINVAL;
2223 #endif
2224         biu = le32_to_cpu(idx->index.index_length);
2225         /* Do we have enough space? */
2226         if (biu + size > le32_to_cpu(idx->index.allocated_size))
2227                 return -ENOSPC;
2228         /* Move everything after pos to pos + size. */
2229         memmove((char*)pos + size, (char*)pos, biu - ((char*)pos -
2230                         (char*)&idx->index));
2231         /* Update index block. */
2232         idx->index.index_length = cpu_to_le32(biu + size);
2233         return 0;
2234 }
2235 
2236 /**
2237  * ntfs_index_keys_compare
2238  *
2239  * not all types of COLLATION_RULES supported yet...
2240  * added as needed.. (remove this comment when all are added)
2241  */
2242 static int ntfs_index_keys_compare(u8 *key1, u8 *key2, int key1_length,
2243                 int key2_length, COLLATION_RULES collation_rule)
2244 {
2245         u32 u1, u2;
2246         int i;
2247 
2248         if (collation_rule == COLLATION_NTOFS_ULONG) {
2249                 /* i.e. $SII or $QUOTA-$Q */
2250                 u1 = le32_to_cpup(key1);
2251                 u2 = le32_to_cpup(key2);
2252                 if (u1 < u2)
2253                         return -1;
2254                 if (u1 > u2)
2255                         return 1;
2256                 /* u1 == u2 */
2257                 return 0;
2258         }
2259         if (collation_rule == COLLATION_NTOFS_ULONGS) {
2260                 /* i.e $OBJID-$O */
2261                 i = 0;
2262                 while (i < min(key1_length, key2_length)) {
2263                         u1 = le32_to_cpup(key1 + i);
2264                         u2 = le32_to_cpup(key2 + i);
2265                         if (u1 < u2)
2266                                 return -1;
2267                         if (u1 > u2)
2268                                 return 1;
2269                         /* u1 == u2 */
2270                         i += sizeof(u32);
2271                 }
2272                 if (key1_length < key2_length)
2273                         return -1;
2274                 if (key1_length > key2_length)
2275                         return 1;
2276                 return 0;
2277         }
2278         if (collation_rule == COLLATION_NTOFS_SECURITY_HASH) {
2279                 /* i.e. $SDH */
2280                 u1 = le32_to_cpu(((SDH_INDEX_KEY*)key1)->hash);
2281                 u2 = le32_to_cpu(((SDH_INDEX_KEY*)key2)->hash);
2282                 if (u1 < u2)
2283                         return -1;
2284                 if (u1 > u2)
2285                         return 1;
2286                 /* u1 == u2 */
2287                 u1 = le32_to_cpu(((SDH_INDEX_KEY*)key1)->security_id);
2288                 u2 = le32_to_cpu(((SDH_INDEX_KEY*)key2)->security_id);
2289                 if (u1 < u2)
2290                         return -1;
2291                 if (u1 > u2)
2292                         return 1;
2293                 return 0;
2294         }
2295         if (collation_rule == COLLATION_NTOFS_SID) {
2296                 /* i.e. $QUOTA-O */
2297                 i = memcmp(key1, key2, min(key1_length, key2_length));
2298                 if (!i) {
2299                         if (key1_length < key2_length)
2300                                 return -1;
2301                         if (key1_length > key2_length)
2302                                 return 1;
2303                 }
2304                 return i;
2305         }
2306         ntfs_log_critical("ntfs_index_keys_compare called without supported "
2307                         "collation rule.\n");
2308         return 0;       /* Claim they're equal.  What else can we do? */
2309 }
2310 
2311 /**
2312  * insert_index_entry_in_res_dir_index
2313  *
2314  * i.e. insert an index_entry in some named index_root
2315  * simplified search method, works for mkntfs
2316  */
2317 static int insert_index_entry_in_res_dir_index(INDEX_ENTRY *idx, u32 idx_size,
2318                 MFT_RECORD *m, ntfschar *name, u32 name_size, ATTR_TYPES type)
2319 {
2320         ntfs_attr_search_ctx *ctx;
2321         INDEX_HEADER *idx_header;
2322         INDEX_ENTRY *idx_entry, *idx_end;
2323         ATTR_RECORD *a;
2324         COLLATION_RULES collation_rule;
2325         int err, i;
2326 
2327         err = 0;
2328         /* does it fit ?*/
2329         if (g_vol->mft_record_size > idx_size + le32_to_cpu(m->bytes_allocated))
2330                 return -ENOSPC;
2331         /* find the INDEX_ROOT attribute:*/
2332         ctx = ntfs_attr_get_search_ctx(NULL, m);
2333         if (!ctx) {
2334                 ntfs_log_error("Failed to allocate attribute search "
2335                                 "context.\n");
2336                 err = -ENOMEM;
2337                 goto err_out;
2338         }
2339         if (mkntfs_attr_lookup(AT_INDEX_ROOT, name, name_size, 0, 0, NULL, 0,
2340                         ctx)) {
2341                 err = -EEXIST;
2342                 goto err_out;
2343         }
2344         /* found attribute */
2345         a = (ATTR_RECORD*)ctx->attr;
2346         collation_rule = ((INDEX_ROOT*)((u8*)a +
2347                         le16_to_cpu(a->u.res.value_offset)))->collation_rule;
2348         idx_header = (INDEX_HEADER*)((u8*)a + le16_to_cpu(a->u.res.value_offset)
2349                         + 0x10);
2350         idx_entry = (INDEX_ENTRY*)((u8*)idx_header +
2351                         le32_to_cpu(idx_header->entries_offset));
2352         idx_end = (INDEX_ENTRY*)((u8*)idx_entry +
2353                         le32_to_cpu(idx_header->index_length));
2354         /*
2355          * Loop until we exceed valid memory (corruption case) or until we
2356          * reach the last entry.
2357          */
2358         if (type == AT_FILE_NAME) {
2359                 while (((u8*)idx_entry < (u8*)idx_end) &&
2360                                 !(idx_entry->flags & INDEX_ENTRY_END)) {
2361                         i = ntfs_file_values_compare(&idx->key.file_name,
2362                                         &idx_entry->key.file_name, 1,
2363                                         IGNORE_CASE, g_vol->upcase,
2364                                         g_vol->upcase_len);
2365                         /*
2366                          * If @file_name collates before ie->key.file_name,
2367                          * there is no matching index entry.
2368                          */
2369                         if (i == -1)
2370                                 break;
2371                         /* If file names are not equal, continue search. */
2372                         if (i)
2373                                 goto do_next;
2374                         if (idx->key.file_name.file_name_type !=
2375                                         FILE_NAME_POSIX ||
2376                                         idx_entry->key.file_name.file_name_type
2377                                         != FILE_NAME_POSIX)
2378                                 return -EEXIST;
2379                         i = ntfs_file_values_compare(&idx->key.file_name,
2380                                         &idx_entry->key.file_name, 1,
2381                                         CASE_SENSITIVE, g_vol->upcase,
2382                                         g_vol->upcase_len);
2383                         if (!i)
2384                                 return -EEXIST;
2385                         if (i == -1)
2386                                 break;
2387 do_next:
2388                         idx_entry = (INDEX_ENTRY*)((u8*)idx_entry +
2389                                         le16_to_cpu(idx_entry->length));
2390                 }
2391         } else if (type == AT_UNUSED) {  /* case view */
2392                 while (((u8*)idx_entry < (u8*)idx_end) &&
2393                                 !(idx_entry->flags & INDEX_ENTRY_END)) {
2394                         i = ntfs_index_keys_compare((u8*)idx + 0x10,
2395                                         (u8*)idx_entry + 0x10,
2396                                         le16_to_cpu(idx->key_length),
2397                                         le16_to_cpu(idx_entry->key_length),
2398                                         collation_rule);
2399                         if (!i)
2400                                 return -EEXIST;
2401                         if (i == -1)
2402                                 break;
2403                         idx_entry = (INDEX_ENTRY*)((u8*)idx_entry +
2404                                         le16_to_cpu(idx_entry->length));
2405                 }
2406         } else
2407                 return -EINVAL;
2408         memmove((u8*)idx_entry + idx_size, (u8*)idx_entry,
2409                         le32_to_cpu(m->bytes_in_use) -
2410                         ((u8*)idx_entry - (u8*)m));
2411         memcpy((u8*)idx_entry, (u8*)idx, idx_size);
2412         /* Adjust various offsets, etc... */
2413         m->bytes_in_use = cpu_to_le32(le32_to_cpu(m->bytes_in_use) + idx_size);
2414         a->length = cpu_to_le32(le32_to_cpu(a->length) + idx_size);
2415         a->u.res.value_length = cpu_to_le32(le32_to_cpu(a->u.res.value_length) + idx_size);
2416         idx_header->index_length = cpu_to_le32(
2417                         le32_to_cpu(idx_header->index_length) + idx_size);
2418         idx_header->allocated_size = cpu_to_le32(
2419                         le32_to_cpu(idx_header->allocated_size) + idx_size);
2420 err_out:
2421         if (ctx)
2422                 ntfs_attr_put_search_ctx(ctx);
2423         return err;
2424 }
2425 
2426 /**
2427  * initialize_secure
2428  *
2429  * initializes $Secure's $SDH and $SII indexes from $SDS datastream
2430  */
2431 static int initialize_secure(char *sds, u32 sds_size, MFT_RECORD *m)
2432 {
2433         int err, sdh_size, sii_size;
2434         SECURITY_DESCRIPTOR_HEADER *sds_header;
2435         INDEX_ENTRY *idx_entry_sdh, *idx_entry_sii;
2436         SDH_INDEX_DATA *sdh_data;
2437         SII_INDEX_DATA *sii_data;
2438 
2439         sds_header = (SECURITY_DESCRIPTOR_HEADER*)sds;
2440         sdh_size  = sizeof(INDEX_ENTRY_HEADER);
2441         sdh_size += sizeof(SDH_INDEX_KEY) + sizeof(SDH_INDEX_DATA);
2442         sii_size  = sizeof(INDEX_ENTRY_HEADER);
2443         sii_size += sizeof(SII_INDEX_KEY) + sizeof(SII_INDEX_DATA);
2444         idx_entry_sdh = ntfs_calloc(sizeof(INDEX_ENTRY));
2445         if (!idx_entry_sdh)
2446                 return -errno;
2447         idx_entry_sii = ntfs_calloc(sizeof(INDEX_ENTRY));
2448         if (!idx_entry_sii) {
2449                 free(idx_entry_sdh);
2450                 return -errno;
2451         }
2452         err = 0;
2453 
2454         while ((char*)sds_header < (char*)sds + sds_size) {
2455                 if (!sds_header->length)
2456                         break;
2457                 /* SDH index entry */
2458                 idx_entry_sdh->u.s.data_offset = const_cpu_to_le16(0x18);
2459                 idx_entry_sdh->u.s.data_length = const_cpu_to_le16(0x14);
2460                 idx_entry_sdh->u.s.reservedV = const_cpu_to_le32(0x00);
2461                 idx_entry_sdh->length = const_cpu_to_le16(0x30);
2462                 idx_entry_sdh->key_length = const_cpu_to_le16(0x08);
2463                 idx_entry_sdh->flags = const_cpu_to_le16(0x00);
2464                 idx_entry_sdh->reserved = const_cpu_to_le16(0x00);
2465                 idx_entry_sdh->key.sdh.hash = sds_header->hash;
2466                 idx_entry_sdh->key.sdh.security_id = sds_header->security_id;
2467                 sdh_data = (SDH_INDEX_DATA*)((u8*)idx_entry_sdh +
2468                                 le16_to_cpu(idx_entry_sdh->u.s.data_offset));
2469                 sdh_data->hash = sds_header->hash;
2470                 sdh_data->security_id = sds_header->security_id;
2471                 sdh_data->offset = sds_header->offset;
2472                 sdh_data->length = sds_header->length;
2473                 sdh_data->reserved_II = const_cpu_to_le32(0x00490049);
2474 
2475                 /* SII index entry */
2476                 idx_entry_sii->u.s.data_offset = const_cpu_to_le16(0x14);
2477                 idx_entry_sii->u.s.data_length = const_cpu_to_le16(0x14);
2478                 idx_entry_sii->u.s.reservedV = const_cpu_to_le32(0x00);
2479                 idx_entry_sii->length = const_cpu_to_le16(0x28);
2480                 idx_entry_sii->key_length = const_cpu_to_le16(0x04);
2481                 idx_entry_sii->flags = const_cpu_to_le16(0x00);
2482                 idx_entry_sii->reserved = const_cpu_to_le16(0x00);
2483                 idx_entry_sii->key.sii.security_id = sds_header->security_id;
2484                 sii_data = (SII_INDEX_DATA*)((u8*)idx_entry_sii +
2485                                 le16_to_cpu(idx_entry_sii->u.s.data_offset));
2486                 sii_data->hash = sds_header->hash;
2487                 sii_data->security_id = sds_header->security_id;
2488                 sii_data->offset = sds_header->offset;
2489                 sii_data->length = sds_header->length;
2490                 if ((err = insert_index_entry_in_res_dir_index(idx_entry_sdh,
2491                                 sdh_size, m, NTFS_INDEX_SDH, 4, AT_UNUSED)))
2492                         break;
2493                 if ((err = insert_index_entry_in_res_dir_index(idx_entry_sii,
2494                                 sii_size, m, NTFS_INDEX_SII, 4, AT_UNUSED)))
2495                         break;
2496                 sds_header = (SECURITY_DESCRIPTOR_HEADER*)((u8*)sds_header +
2497                                 ((le32_to_cpu(sds_header->length) + 15) & ~15));
2498         }
2499         free(idx_entry_sdh);
2500         free(idx_entry_sii);
2501         return err;
2502 }
2503 
2504 /**
2505  * initialize_quota
2506  *
2507  * initialize $Quota with the default quota index-entries.
2508  */
2509 static int initialize_quota(MFT_RECORD *m)
2510 {
2511         int o_size, q1_size, q2_size, err, i;
2512         INDEX_ENTRY *idx_entry_o, *idx_entry_q1, *idx_entry_q2;
2513         QUOTA_O_INDEX_DATA *idx_entry_o_data;
2514         QUOTA_CONTROL_ENTRY *idx_entry_q1_data, *idx_entry_q2_data;
2515 
2516         err = 0;
2517         /* q index entry num 1 */
2518         q1_size = 0x48;
2519         idx_entry_q1 = ntfs_calloc(q1_size);
2520         if (!idx_entry_q1)
2521                 return errno;
2522         idx_entry_q1->u.s.data_offset = const_cpu_to_le16(0x14);
2523         idx_entry_q1->u.s.data_length = const_cpu_to_le16(0x30);
2524         idx_entry_q1->u.s.reservedV = const_cpu_to_le32(0x00);
2525         idx_entry_q1->length = const_cpu_to_le16(0x48);
2526         idx_entry_q1->key_length = const_cpu_to_le16(0x04);
2527         idx_entry_q1->flags = const_cpu_to_le16(0x00);
2528         idx_entry_q1->reserved = const_cpu_to_le16(0x00);
2529         idx_entry_q1->key.owner_id = const_cpu_to_le32(0x01);
2530         idx_entry_q1_data = (QUOTA_CONTROL_ENTRY*)((char*)idx_entry_q1
2531                         + le16_to_cpu(idx_entry_q1->u.s.data_offset));
2532         idx_entry_q1_data->version = const_cpu_to_le32(0x02);
2533         idx_entry_q1_data->flags = QUOTA_FLAG_DEFAULT_LIMITS;
2534         idx_entry_q1_data->bytes_used = const_cpu_to_le64(0x00);
2535         idx_entry_q1_data->change_time = utc2ntfs(mkntfs_time());
2536         idx_entry_q1_data->threshold = cpu_to_sle64(-1);
2537         idx_entry_q1_data->limit = cpu_to_sle64(-1);
2538         idx_entry_q1_data->exceeded_time = 0;
2539         err = insert_index_entry_in_res_dir_index(idx_entry_q1, q1_size, m,
2540                         NTFS_INDEX_Q, 2, AT_UNUSED);
2541         free(idx_entry_q1);
2542         if (err)
2543                 return err;
2544         /* q index entry num 2 */
2545         q2_size = 0x58;
2546         idx_entry_q2 = ntfs_calloc(q2_size);
2547         if (!idx_entry_q2)
2548                 return errno;
2549         idx_entry_q2->u.s.data_offset = const_cpu_to_le16(0x14);
2550         idx_entry_q2->u.s.data_length = const_cpu_to_le16(0x40);
2551         idx_entry_q2->u.s.reservedV = const_cpu_to_le32(0x00);
2552         idx_entry_q2->length = const_cpu_to_le16(0x58);
2553         idx_entry_q2->key_length = const_cpu_to_le16(0x04);
2554         idx_entry_q2->flags = const_cpu_to_le16(0x00);
2555         idx_entry_q2->reserved = const_cpu_to_le16(0x00);
2556         idx_entry_q2->key.owner_id = QUOTA_FIRST_USER_ID;
2557         idx_entry_q2_data = (QUOTA_CONTROL_ENTRY*)((char*)idx_entry_q2
2558                         + le16_to_cpu(idx_entry_q2->u.s.data_offset));
2559         idx_entry_q2_data->version = const_cpu_to_le32(0x02);
2560         idx_entry_q2_data->flags = QUOTA_FLAG_DEFAULT_LIMITS;
2561         idx_entry_q2_data->bytes_used = const_cpu_to_le64(0x00);
2562         idx_entry_q2_data->change_time = utc2ntfs(mkntfs_time());;
2563         idx_entry_q2_data->threshold = cpu_to_sle64(-1);
2564         idx_entry_q2_data->limit = cpu_to_sle64(-1);
2565         idx_entry_q2_data->exceeded_time = 0;
2566         idx_entry_q2_data->sid.revision = 1;
2567         idx_entry_q2_data->sid.sub_authority_count = 2;
2568         for (i = 0; i < 5; i++)
2569                 idx_entry_q2_data->sid.identifier_authority.value[i] = 0;
2570         idx_entry_q2_data->sid.identifier_authority.value[5] = 0x05;
2571         idx_entry_q2_data->sid.sub_authority[0] =
2572                         const_cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
2573         idx_entry_q2_data->sid.sub_authority[1] =
2574                         const_cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);
2575         err = insert_index_entry_in_res_dir_index(idx_entry_q2, q2_size, m,
2576                         NTFS_INDEX_Q, 2, AT_UNUSED);
2577         free(idx_entry_q2);
2578         if (err)
2579                 return err;
2580         o_size = 0x28;
2581         idx_entry_o = ntfs_calloc(o_size);
2582         if (!idx_entry_o)
2583                 return errno;
2584         idx_entry_o->u.s.data_offset = const_cpu_to_le16(0x20);
2585         idx_entry_o->u.s.data_length = const_cpu_to_le16(0x04);
2586         idx_entry_o->u.s.reservedV = const_cpu_to_le32(0x00);
2587         idx_entry_o->length = const_cpu_to_le16(0x28);
2588         idx_entry_o->key_length = const_cpu_to_le16(0x10);
2589         idx_entry_o->flags = const_cpu_to_le16(0x00);
2590         idx_entry_o->reserved = const_cpu_to_le16(0x00);
2591         idx_entry_o->key.sid.revision = 0x01;
2592         idx_entry_o->key.sid.sub_authority_count = 0x02;
2593         for (i = 0; i < 5; i++)
2594                 idx_entry_o->key.sid.identifier_authority.value[i] = 0;
2595         idx_entry_o->key.sid.identifier_authority.value[5] = 0x05;
2596         idx_entry_o->key.sid.sub_authority[0] =
2597                         const_cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
2598         idx_entry_o->key.sid.sub_authority[1] =
2599                         const_cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);
2600         idx_entry_o_data = (QUOTA_O_INDEX_DATA*)((char*)idx_entry_o
2601                         + le16_to_cpu(idx_entry_o->u.s.data_offset));
2602         idx_entry_o_data->owner_id  = QUOTA_FIRST_USER_ID;
2603         /* 20 00 00 00 padding after here on ntfs 3.1. 3.0 is unchecked. */
2604         idx_entry_o_data->unknown = const_cpu_to_le32(32);
2605         err = insert_index_entry_in_res_dir_index(idx_entry_o, o_size, m,
2606                         NTFS_INDEX_O, 2, AT_UNUSED);
2607         free(idx_entry_o);
2608 
2609         return err;
2610 }
2611 
2612 /**
2613  * insert_file_link_in_dir_index
2614  *
2615  * Insert the fully completed FILE_NAME_ATTR @file_name which is inside
2616  * the file with mft reference @file_ref into the index (allocation) block
2617  * @idx (which belongs to @file_ref's parent directory).
2618  *
2619  * Return 0 on success or -errno on error.
2620  */
2621 static int insert_file_link_in_dir_index(INDEX_BLOCK *idx, leMFT_REF file_ref,
2622                 FILE_NAME_ATTR *file_name, u32 file_name_size)
2623 {
2624         int err, i;
2625         INDEX_ENTRY *ie;
2626         char *index_end;
2627 
2628         /*
2629          * Lookup dir entry @file_name in dir @idx to determine correct
2630          * insertion location. FIXME: Using a very oversimplified lookup
2631          * method which is sufficient for mkntfs but no good whatsoever in
2632          * real world scenario. (AIA)
2633          */
2634 
2635         index_end = (char*)&idx->index + le32_to_cpu(idx->index.index_length);
2636         ie = (INDEX_ENTRY*)((char*)&idx->index +
2637                         le32_to_cpu(idx->index.entries_offset));
2638         /*
2639          * Loop until we exceed valid memory (corruption case) or until we
2640          * reach the last entry.
2641          */
2642         while ((char*)ie < index_end && !(ie->flags & INDEX_ENTRY_END)) {
2643 #if 0
2644 #ifdef DEBUG
2645                 ntfs_log_debug("file_name_attr1->file_name_length = %i\n",
2646                                 file_name->file_name_length);
2647                 if (file_name->file_name_length) {
2648                         char *__buf = NULL;
2649                         i = ntfs_ucstombs((ntfschar*)&file_name->file_name,
2650                                 file_name->file_name_length, &__buf, 0);
2651                         if (i < 0)
2652                                 ntfs_log_debug("Name contains non-displayable "
2653                                                 "Unicode characters.\n");
2654                         ntfs_log_debug("file_name_attr1->file_name = %s\n",
2655                                         __buf);
2656                         free(__buf);
2657                 }
2658                 ntfs_log_debug("file_name_attr2->file_name_length = %i\n",
2659                                 ie->key.file_name.file_name_length);
2660                 if (ie->key.file_name.file_name_length) {
2661                         char *__buf = NULL;
2662                         i = ntfs_ucstombs(ie->key.file_name.file_name,
2663                                 ie->key.file_name.file_name_length + 1, &__buf,
2664                                 0);
2665                         if (i < 0)
2666                                 ntfs_log_debug("Name contains non-displayable "
2667                                                 "Unicode characters.\n");
2668                         ntfs_log_debug("file_name_attr2->file_name = %s\n",
2669                                         __buf);
2670                         free(__buf);
2671                 }
2672 #endif
2673 #endif
2674                 i = ntfs_file_values_compare(file_name,
2675                                 (FILE_NAME_ATTR*)&ie->key.file_name, 1,
2676                                 IGNORE_CASE, g_vol->upcase, g_vol->upcase_len);
2677                 /*
2678                  * If @file_name collates before ie->key.file_name, there is no
2679                  * matching index entry.
2680                  */
2681                 if (i == -1)
2682                         break;
2683                 /* If file names are not equal, continue search. */
2684                 if (i)
2685                         goto do_next;
2686                 /* File names are equal when compared ignoring case. */
2687                 /*
2688                  * If BOTH file names are in the POSIX namespace, do a case
2689                  * sensitive comparison as well. Otherwise the names match so
2690                  * we return -EEXIST. FIXME: There are problems with this in a
2691                  * real world scenario, when one is POSIX and one isn't, but
2692                  * fine for mkntfs where we don't use POSIX namespace at all
2693                  * and hence this following code is luxury. (AIA)
2694                  */
2695                 if (file_name->file_name_type != FILE_NAME_POSIX ||
2696                     ie->key.file_name.file_name_type != FILE_NAME_POSIX)
2697                         return -EEXIST;
2698                 i = ntfs_file_values_compare(file_name,
2699                                 (FILE_NAME_ATTR*)&ie->key.file_name, 1,
2700                                 CASE_SENSITIVE, g_vol->upcase,
2701                                 g_vol->upcase_len);
2702                 if (i == -1)
2703                         break;
2704                 /* Complete match. Bugger. Can't insert. */
2705                 if (!i)
2706                         return -EEXIST;
2707 do_next:
2708 #ifdef DEBUG
2709                 /* Next entry. */
2710                 if (!ie->length) {
2711                         ntfs_log_debug("BUG: ie->length is zero, breaking out "
2712                                         "of loop.\n");
2713                         break;
2714                 }
2715 #endif
2716                 ie = (INDEX_ENTRY*)((char*)ie + le16_to_cpu(ie->length));
2717         };
2718         i = (sizeof(INDEX_ENTRY_HEADER) + file_name_size + 7) & ~7;
2719         err = make_room_for_index_entry_in_index_block(idx, ie, i);
2720         if (err) {
2721                 ntfs_log_error("make_room_for_index_entry_in_index_block "
2722                                 "failed: %s\n", strerror(-err));
2723                 return err;
2724         }
2725         /* Create entry in place and copy file name attribute value. */
2726         ie->u.indexed_file = file_ref;
2727         ie->length = cpu_to_le16(i);
2728         ie->key_length = cpu_to_le16(file_name_size);
2729         ie->flags = cpu_to_le16(0);
2730         ie->reserved = cpu_to_le16(0);
2731         memcpy((char*)&ie->key.file_name, (char*)file_name, file_name_size);
2732         return 0;
2733 }
2734 
2735 /**
2736  * create_hardlink_res
2737  *
2738  * Create a file_name_attribute in the mft record @m_file which points to the
2739  * parent directory with mft reference @ref_parent.
2740  *
2741  * Then, insert an index entry with this file_name_attribute in the index
2742  * root @idx of the index_root attribute of the parent directory.
2743  *
2744  * @ref_file is the mft reference of @m_file.
2745  *
2746  * Return 0 on success or -errno on error.
2747  */
2748 static int create_hardlink_res(MFT_RECORD *m_parent, const leMFT_REF ref_parent,
2749                 MFT_RECORD *m_file, const leMFT_REF ref_file,
2750                 const s64 allocated_size, const s64 data_size,
2751                 const FILE_ATTR_FLAGS flags, const u16 packed_ea_size,
2752                 const u32 reparse_point_tag, const char *file_name,
2753                 const FILE_NAME_TYPE_FLAGS file_name_type)
2754 {
2755         FILE_NAME_ATTR *fn;
2756         int i, fn_size, idx_size;
2757         INDEX_ENTRY *idx_entry_new;
2758         ntfschar *uname;
2759 
2760         /* Create the file_name attribute. */
2761         i = (strlen(file_name) + 1) * sizeof(ntfschar);
2762         fn_size = sizeof(FILE_NAME_ATTR) + i;
2763         fn = ntfs_malloc(fn_size);
2764         if (!fn)
2765                 return -errno;
2766         fn->parent_directory = ref_parent;
2767         /* FIXME: copy the creation_time from the std info */
2768         fn->creation_time = utc2ntfs(mkntfs_time());
2769         fn->last_data_change_time = fn->creation_time;
2770         fn->last_mft_change_time = fn->creation_time;
2771         fn->last_access_time = fn->creation_time;
2772         fn->allocated_size = cpu_to_sle64(allocated_size);
2773         fn->data_size = cpu_to_sle64(data_size);
2774         fn->file_attributes = flags;
2775         /* These are in a union so can't have both. */
2776         if (packed_ea_size && reparse_point_tag) {
2777                 free(fn);
2778                 return -EINVAL;
2779         }
2780         if (packed_ea_size) {
2781                 free(fn);
2782                 return -EINVAL;
2783         }
2784         if (packed_ea_size) {
2785                 fn->u.s.packed_ea_size = cpu_to_le16(packed_ea_size);
2786                 fn->u.s.reserved = cpu_to_le16(0);
2787         } else {
2788                 fn->u.reparse_point_tag = cpu_to_le32(reparse_point_tag);
2789         }
2790         fn->file_name_type = file_name_type;
2791         uname = fn->file_name;
2792         i = ntfs_mbstoucs(file_name, &uname, i);
2793         if (i < 1) {
2794                 free(fn);
2795                 return -EINVAL;
2796         }
2797         if (i > 0xff) {
2798                 free(fn);
2799                 return -ENAMETOOLONG;
2800         }
2801         /* No terminating null in file names. */
2802         fn->file_name_length = i;
2803         fn_size = sizeof(FILE_NAME_ATTR) + i * sizeof(ntfschar);
2804         /* Increment the link count of @m_file. */
2805         i = le16_to_cpu(m_file->link_count);
2806         if (i == 0xffff) {
2807                 ntfs_log_error("Too many hardlinks present already.\n");
2808                 free(fn);
2809                 return -EINVAL;
2810         }
2811         m_file->link_count = cpu_to_le16(i + 1);
2812         /* Add the file_name to @m_file. */
2813         i = insert_resident_attr_in_mft_record(m_file, AT_FILE_NAME, NULL, 0, 0,
2814                         0, RESIDENT_ATTR_IS_INDEXED, (u8*)fn, fn_size);
2815         if (i < 0) {
2816                 ntfs_log_error("create_hardlink failed adding file name "
2817                                 "attribute: %s\n", strerror(-i));
2818                 free(fn);
2819                 /* Undo link count increment. */
2820                 m_file->link_count = cpu_to_le16(
2821                                 le16_to_cpu(m_file->link_count) - 1);
2822                 return i;
2823         }
2824         /* Insert the index entry for file_name in @idx. */
2825         idx_size = (fn_size + 7)  & ~7;
2826         idx_entry_new = ntfs_calloc(idx_size + 0x10);
2827         if (!idx_entry_new)
2828                 return -errno;
2829         idx_entry_new->u.indexed_file = ref_file;
2830         idx_entry_new->length = cpu_to_le16(idx_size + 0x10);
2831         idx_entry_new->key_length = cpu_to_le16(fn_size);
2832         memcpy((u8*)idx_entry_new + 0x10, (u8*)fn, fn_size);
2833         i = insert_index_entry_in_res_dir_index(idx_entry_new, idx_size + 0x10,
2834                         m_parent, NTFS_INDEX_I30, 4, AT_FILE_NAME);
2835         if (i < 0) {
2836                 ntfs_log_error("create_hardlink failed inserting index entry: "
2837                                 "%s\n", strerror(-i));
2838                 /* FIXME: Remove the file name attribute from @m_file. */
2839                 free(idx_entry_new);
2840                 free(fn);
2841                 /* Undo link count increment. */
2842                 m_file->link_count = cpu_to_le16(
2843                                 le16_to_cpu(m_file->link_count) - 1);
2844                 return i;
2845         }
2846         free(idx_entry_new);
2847         free(fn);
2848         return 0;
2849 }
2850 
2851 /**
2852  * create_hardlink
2853  *
2854  * Create a file_name_attribute in the mft record @m_file which points to the
2855  * parent directory with mft reference @ref_parent.
2856  *
2857  * Then, insert an index entry with this file_name_attribute in the index
2858  * block @idx of the index allocation attribute of the parent directory.
2859  *
2860  * @ref_file is the mft reference of @m_file.
2861  *
2862  * Return 0 on success or -errno on error.
2863  */
2864 static int create_hardlink(INDEX_BLOCK *idx, const leMFT_REF ref_parent,
2865                 MFT_RECORD *m_file, const leMFT_REF ref_file,
2866                 const s64 allocated_size, const s64 data_size,
2867                 const FILE_ATTR_FLAGS flags, const u16 packed_ea_size,
2868                 const u32 reparse_point_tag, const char *file_name,
2869                 const FILE_NAME_TYPE_FLAGS file_name_type)
2870 {
2871         FILE_NAME_ATTR *fn;
2872         int i, fn_size;
2873         ntfschar *uname;
2874 
2875         /* Create the file_name attribute. */
2876         i = (strlen(file_name) + 1) * sizeof(ntfschar);
2877         fn_size = sizeof(FILE_NAME_ATTR) + i;
2878         fn = ntfs_malloc(fn_size);
2879         if (!fn)
2880                 return -errno;
2881         fn->parent_directory = ref_parent;
2882         /* FIXME: Is this correct? Or do we have to copy the creation_time */
2883         /* from the std info? */
2884         fn->creation_time = utc2ntfs(mkntfs_time());
2885         fn->last_data_change_time = fn->creation_time;
2886         fn->last_mft_change_time = fn->creation_time;
2887         fn->last_access_time = fn->creation_time;
2888         fn->allocated_size = cpu_to_sle64(allocated_size);
2889         fn->data_size = cpu_to_sle64(data_size);
2890         fn->file_attributes = flags;
2891         /* These are in a union so can't have both. */
2892         if (packed_ea_size && reparse_point_tag) {
2893                 free(fn);
2894                 return -EINVAL;
2895         }
2896         if (packed_ea_size) {
2897                 fn->u.s.packed_ea_size = cpu_to_le16(packed_ea_size);
2898                 fn->u.s.reserved = cpu_to_le16(0);
2899         } else {
2900                 fn->u.reparse_point_tag = cpu_to_le32(reparse_point_tag);
2901         }
2902         fn->file_name_type = file_name_type;
2903         uname = fn->file_name;
2904         i = ntfs_mbstoucs(file_name, &uname, i);
2905         if (i < 1) {
2906                 free(fn);
2907                 return -EINVAL;
2908         }
2909         if (i > 0xff) {
2910                 free(fn);
2911                 return -ENAMETOOLONG;
2912         }
2913         /* No terminating null in file names. */
2914         fn->file_name_length = i;
2915         fn_size = sizeof(FILE_NAME_ATTR) + i * sizeof(ntfschar);
2916         /* Increment the link count of @m_file. */
2917         i = le16_to_cpu(m_file->link_count);
2918         if (i == 0xffff) {
2919                 ntfs_log_error("Too many hardlinks present already.\n");
2920                 free(fn);
2921                 return -EINVAL;
2922         }
2923         m_file->link_count = cpu_to_le16(i + 1);
2924         /* Add the file_name to @m_file. */
2925         i = insert_resident_attr_in_mft_record(m_file, AT_FILE_NAME, NULL, 0, 0,
2926                         0, RESIDENT_ATTR_IS_INDEXED, (u8*)fn, fn_size);
2927         if (i < 0) {
2928                 ntfs_log_error("create_hardlink failed adding file name attribute: "
2929                                 "%s\n", strerror(-i));
2930                 free(fn);
2931                 /* Undo link count increment. */
2932                 m_file->link_count = cpu_to_le16(
2933                                 le16_to_cpu(m_file->link_count) - 1);
2934                 return i;
2935         }
2936         /* Insert the index entry for file_name in @idx. */
2937         i = insert_file_link_in_dir_index(idx, ref_file, fn, fn_size);
2938         if (i < 0) {
2939                 ntfs_log_error("create_hardlink failed inserting index entry: %s\n",
2940                                 strerror(-i));
2941                 /* FIXME: Remove the file name attribute from @m_file. */
2942                 free(fn);
2943                 /* Undo link count increment. */
2944                 m_file->link_count = cpu_to_le16(
2945                                 le16_to_cpu(m_file->link_count) - 1);
2946                 return i;
2947         }
2948         free(fn);
2949         return 0;
2950 }
2951 
2952 #ifdef ENABLE_UUID
2953 
2954 /**
2955  * index_obj_id_insert
2956  *
2957  * Insert an index entry with the key @guid and data pointing to the mft record
2958  * @ref in the $O index root of the mft record @m (which must be the mft record
2959  * for $ObjId).
2960  *
2961  * Return 0 on success or -errno on error.
2962  */
2963 static int index_obj_id_insert(MFT_RECORD *m, const GUID *guid,
2964                 const leMFT_REF ref)
2965 {
2966         INDEX_ENTRY *idx_entry_new;
2967         int data_ofs, idx_size, err;
2968         OBJ_ID_INDEX_DATA *oi;
2969 
2970         /*
2971          * Insert the index entry for the object id in the index.
2972          *
2973          * First determine the size of the index entry to be inserted.  This
2974          * consists of the index entry header, followed by the index key, i.e.
2975          * the GUID, followed by the index data, i.e. OBJ_ID_INDEX_DATA.
2976          */
2977         data_ofs = (sizeof(INDEX_ENTRY_HEADER) + sizeof(GUID) + 7) & ~7;
2978         idx_size = (data_ofs + sizeof(OBJ_ID_INDEX_DATA) + 7) & ~7;
2979         idx_entry_new = ntfs_calloc(idx_size);
2980         if (!idx_entry_new)
2981                 return -errno;
2982         idx_entry_new->u.s.data_offset = cpu_to_le16(data_ofs);
2983         idx_entry_new->u.s.data_length = cpu_to_le16(sizeof(OBJ_ID_INDEX_DATA));
2984         idx_entry_new->length = cpu_to_le16(idx_size);
2985         idx_entry_new->key_length = cpu_to_le16(sizeof(GUID));
2986         idx_entry_new->key.object_id = *guid;
2987         oi = (OBJ_ID_INDEX_DATA*)((u8*)idx_entry_new + data_ofs);
2988         oi->mft_reference = ref;
2989         err = insert_index_entry_in_res_dir_index(idx_entry_new, idx_size, m,
2990                         NTFS_INDEX_O, 2, AT_UNUSED);
2991         free(idx_entry_new);
2992         if (err < 0) {
2993                 ntfs_log_error("index_obj_id_insert failed inserting index "
2994                                 "entry: %s\n", strerror(-err));
2995                 return err;
2996         }
2997         return 0;
2998 }
2999 
3000 #endif
3001 
3002 /**
3003  * mkntfs_cleanup
3004  */
3005 static void mkntfs_cleanup(void)
3006 {
3007         /* Close the volume */
3008         if (g_vol) {
3009                 if (g_vol->u.dev) {
3010                         if (NDevOpen(g_vol->u.dev) && g_vol->u.dev->d_ops->close(g_vol->u.dev))
3011                                 ntfs_log_perror("Warning: Could not close %s", g_vol->u.dev->d_name);
3012                         ntfs_device_free(g_vol->u.dev);
3013                 }
3014                 free(g_vol->vol_name);
3015                 free(g_vol->attrdef);
3016                 free(g_vol->upcase);
3017                 free(g_vol);
3018                 g_vol = NULL;
3019         }
3020 
3021         /* Free any memory we've used */
3022         free(g_bad_blocks);     g_bad_blocks    = NULL;
3023         free(g_buf);            g_buf           = NULL;
3024         free(g_index_block);    g_index_block   = NULL;
3025         free(g_lcn_bitmap);     g_lcn_bitmap    = NULL;
3026         free(g_mft_bitmap);     g_mft_bitmap    = NULL;
3027         free(g_rl_bad);         g_rl_bad        = NULL;
3028         free(g_rl_boot);        g_rl_boot       = NULL;
3029         free(g_rl_logfile);     g_rl_logfile    = NULL;
3030         free(g_rl_mft);         g_rl_mft        = NULL;
3031         free(g_rl_mft_bmp);     g_rl_mft_bmp    = NULL;
3032         free(g_rl_mftmirr);     g_rl_mftmirr    = NULL;
3033 }
3034 
3035 
3036 /**
3037  * mkntfs_open_partition -
3038  */
3039 static BOOL mkntfs_open_partition(ntfs_volume *vol)
3040 {
3041         BOOL result = FALSE;
3042         int i;
3043         struct stat sbuf;
3044         unsigned long mnt_flags;
3045 
3046         /*
3047          * Allocate and initialize an ntfs device structure and attach it to
3048          * the volume.
3049          */
3050         vol->u.dev = ntfs_device_alloc(opts.dev_name, 0, &ntfs_device_default_io_ops, NULL);
3051         if (!vol->u.dev) {
3052                 ntfs_log_perror("Could not create device");
3053                 goto done;
3054         }
3055 
3056         /* Open the device for reading or reading and writing. */
3057         if (opts.no_action) {
3058                 ntfs_log_quiet("Running in READ-ONLY mode!\n");
3059                 i = O_RDONLY;
3060         } else {
3061                 i = O_RDWR;
3062         }
3063         if (vol->u.dev->d_ops->open(vol->u.dev, i)) {
3064                 if (errno == ENOENT)
3065                         ntfs_log_error("The device doesn't exist; did you specify it correctly?\n");
3066                 else
3067                         ntfs_log_perror("Could not open %s", vol->u.dev->d_name);
3068                 goto done;
3069         }
3070         /* Verify we are dealing with a block device. */
3071         if (vol->u.dev->d_ops->stat(vol->u.dev, &sbuf)) {
3072                 ntfs_log_perror("Error getting information about %s", vol->u.dev->d_name);
3073                 goto done;
3074         }
3075 
3076         if (!S_ISBLK(sbuf.st_mode)) {
3077                 ntfs_log_error("%s is not a block device.\n", vol->u.dev->d_name);
3078                 if (!opts.force) {
3079                         ntfs_log_error("Refusing to make a filesystem here!\n");
3080                         goto done;
3081                 }
3082                 if (!opts.num_sectors) {
3083                         if (!sbuf.st_size && !sbuf.st_blocks) {
3084                                 ntfs_log_error("You must specify the number of sectors.\n");
3085                                 goto done;
3086                         }
3087                         if (opts.sector_size) {
3088                                 if (sbuf.st_size)
3089                                         opts.num_sectors = sbuf.st_size / opts.sector_size;
3090                                 else
3091                                         opts.num_sectors = ((s64)sbuf.st_blocks << 9) / opts.sector_size;
3092                         } else {
3093                                 if (sbuf.st_size)
3094                                         opts.num_sectors = sbuf.st_size / 512;
3095                                 else
3096                                         opts.num_sectors = sbuf.st_blocks;
3097                                 opts.sector_size = 512;
3098                         }
3099                 }
3100                 ntfs_log_warning("mkntfs forced anyway.\n");
3101 #ifdef HAVE_LINUX_MAJOR_H
3102         } else if ((IDE_DISK_MAJOR(MAJOR(sbuf.st_rdev)) &&
3103                         MINOR(sbuf.st_rdev) % 64 == 0) ||
3104                         (SCSI_DISK_MAJOR(MAJOR(sbuf.st_rdev)) &&
3105                         MINOR(sbuf.st_rdev) % 16 == 0)) {
3106                 ntfs_log_error("%s is entire device, not just one partition.\n", vol->u.dev->d_name);
3107                 if (!opts.force) {
3108                         ntfs_log_error("Refusing to make a filesystem here!\n");
3109                         goto done;
3110                 }
3111                 ntfs_log_warning("mkntfs forced anyway.\n");
3112 #endif
3113         }
3114         /* Make sure the file system is not mounted. */
3115         if (ntfs_check_if_mounted(vol->u.dev->d_name, &mnt_flags)) {
3116                 ntfs_log_perror("Failed to determine whether %s is mounted", vol->u.dev->d_name);
3117         } else if (mnt_flags & NTFS_MF_MOUNTED) {
3118                 ntfs_log_error("%s is mounted.\n", vol->u.dev->d_name);
3119                 if (!opts.force) {
3120                         ntfs_log_error("Refusing to make a filesystem here!\n");
3121                         goto done;
3122                 }
3123                 ntfs_log_warning("mkntfs forced anyway. Hope /etc/mtab is incorrect.\n");
3124         }
3125         result = TRUE;
3126 done:
3127         return result;
3128 }
3129 
3130 /**
3131  * mkntfs_get_page_size - detect the system's memory page size.
3132  */
3133 static long mkntfs_get_page_size(void)
3134 {
3135         long page_size;
3136 #ifdef _SC_PAGESIZE
3137         page_size = sysconf(_SC_PAGESIZE);
3138         if (page_size < 0)
3139 #endif
3140 #ifdef _SC_PAGE_SIZE
3141                 page_size = sysconf(_SC_PAGE_SIZE);
3142         if (page_size < 0)
3143 #endif
3144         {
3145                 ntfs_log_warning("Failed to determine system page size.  "
3146                                 "Assuming safe default of 4096 bytes.\n");
3147                 return 4096;
3148         }
3149         ntfs_log_debug("System page size is %li bytes.\n", page_size);
3150         return page_size;
3151 }
3152 
3153 /**
3154  * mkntfs_override_vol_params -
3155  */
3156 static BOOL mkntfs_override_vol_params(ntfs_volume *vol)
3157 {
3158         s64 volume_size;
3159         long page_size;
3160         int i;
3161         BOOL winboot = TRUE;
3162 
3163         /* If user didn't specify the sector size, determine it now. */
3164         if (opts.sector_size < 0) {
3165                 opts.sector_size = ntfs_device_sector_size_get(vol->u.dev);
3166                 if (opts.sector_size < 0) {
3167                         ntfs_log_warning("The sector size was not specified "
3168                                 "for %s and it could not be obtained "
3169                                 "automatically.  It has been set to 512 "
3170                                 "bytes.\n", vol->u.dev->d_name);
3171                         opts.sector_size = 512;
3172                 }
3173         }
3174         /* Validate sector size. */
3175         if ((opts.sector_size - 1) & opts.sector_size) {
3176                 ntfs_log_error("The sector size is invalid.  It must be a "
3177                         "power of two, e.g. 512, 1024.\n");
3178                 return FALSE;
3179         }
3180         if (opts.sector_size < 256 || opts.sector_size > 4096) {
3181                 ntfs_log_error("The sector size is invalid.  The minimum size "
3182                         "is 256 bytes and the maximum is 4096 bytes.\n");
3183                 return FALSE;
3184         }
3185         ntfs_log_debug("sector size = %ld bytes\n", opts.sector_size);
3186         /* Now set the device block size to the sector size. */
3187         if (ntfs_device_block_size_set(vol->u.dev, opts.sector_size))
3188                 ntfs_log_debug("Failed to set the device block size to the "
3189                                 "sector size.  This may cause problems when "
3190                                 "creating the backup boot sector and also may "
3191                                 "affect performance but should be harmless "
3192                                 "otherwise.  Error: %s\n", strerror(errno));
3193         /* If user didn't specify the number of sectors, determine it now. */
3194         if (opts.num_sectors < 0) {
3195                 opts.num_sectors = ntfs_device_size_get(vol->u.dev,
3196                                 opts.sector_size);
3197                 if (opts.num_sectors <= 0) {
3198                         ntfs_log_error("Couldn't determine the size of %s.  "
3199                                 "Please specify the number of sectors "
3200                                 "manually.\n", vol->u.dev->d_name);
3201                         return FALSE;
3202                 }
3203         }
3204         ntfs_log_debug("number of sectors = %lld (0x%llx)\n", opts.num_sectors,
3205                         opts.num_sectors);
3206         /*
3207          * Reserve the last sector for the backup boot sector unless the
3208          * sector size is less than 512 bytes in which case reserve 512 bytes
3209          * worth of sectors.
3210          */
3211         i = 1;
3212         if (opts.sector_size < 512)
3213                 i = 512 / opts.sector_size;
3214         opts.num_sectors -= i;
3215         /* If user didn't specify the partition start sector, determine it. */
3216         if (opts.part_start_sect < 0) {
3217                 opts.part_start_sect = ntfs_device_partition_start_sector_get(
3218                                 vol->u.dev);
3219                 if (opts.part_start_sect < 0) {
3220                         ntfs_log_warning("The partition start sector was not "
3221                                 "specified for %s and it could not be obtained "
3222                                 "automatically.  It has been set to 0.\n",
3223                                 vol->u.dev->d_name);
3224                         opts.part_start_sect = 0;
3225                         winboot = FALSE;
3226                 } else if (opts.part_start_sect >> 32) {
3227                         ntfs_log_warning("The partition start sector specified "
3228                                 "for %s and the automatically determined value "
3229                                 "is too large.  It has been set to 0.\n",
3230                                 vol->u.dev->d_name);
3231                         opts.part_start_sect = 0;
3232                         winboot = FALSE;
3233                 }
3234         } else if (opts.part_start_sect >> 32) {
3235                 ntfs_log_error("Invalid partition start sector.  Maximum is "
3236                         "4294967295 (2^32-1).\n");
3237                 return FALSE;
3238         }
3239         /* If user didn't specify the sectors per track, determine it now. */
3240         if (opts.sectors_per_track < 0) {
3241                 opts.sectors_per_track = ntfs_device_sectors_per_track_get(
3242                                 vol->u.dev);
3243                 if (opts.sectors_per_track < 0) {
3244                         ntfs_log_warning("The number of sectors per track was "
3245                                 "not specified for %s and it could not be "
3246                                 "obtained automatically.  It has been set to "
3247                                 "0.\n", vol->u.dev->d_name);
3248                         opts.sectors_per_track = 0;
3249                         winboot = FALSE;
3250                 } else if (opts.sectors_per_track > 65535) {
3251                         ntfs_log_warning("The number of sectors per track was "
3252                                 "not specified for %s and the automatically "
3253                                 "determined value is too large.  It has been "
3254                                 "set to 0.\n", vol->u.dev->d_name);
3255                         opts.sectors_per_track = 0;
3256                         winboot = FALSE;
3257                 }
3258         } else if (opts.sectors_per_track > 65535) {
3259                 ntfs_log_error("Invalid number of sectors per track.  Maximum "
3260                         "is 65535.\n");
3261                 return FALSE;
3262         }
3263         /* If user didn't specify the number of heads, determine it now. */
3264         if (opts.heads < 0) {
3265                 opts.heads = ntfs_device_heads_get(vol->u.dev);
3266                 if (opts.heads < 0) {
3267                         ntfs_log_warning("The number of heads was not "
3268                                 "specified for %s and it could not be obtained "
3269                                 "automatically.  It has been set to 0.\n",
3270                                 vol->u.dev->d_name);
3271                         opts.heads = 0;
3272                         winboot = FALSE;
3273                 } else if (opts.heads > 65535) {
3274                         ntfs_log_warning("The number of heads was not "
3275                                 "specified for %s and the automatically "
3276                                 "determined value is too large.  It has been "
3277                                 "set to 0.\n", vol->u.dev->d_name);
3278                         opts.heads = 0;
3279                         winboot = FALSE;
3280                 }
3281         } else if (opts.heads > 65535) {
3282                 ntfs_log_error("Invalid number of heads.  Maximum is 65535.\n");
3283                 return FALSE;
3284         }
3285         volume_size = opts.num_sectors * opts.sector_size;
3286         /* Validate volume size. */
3287         if (volume_size < (1 << 20)) {                 /* 1MiB */
3288                 ntfs_log_error("Device is too small (%llikiB).  Minimum NTFS "
3289                                 "volume size is 1MiB.\n", volume_size / 1024);
3290                 return FALSE;
3291         }
3292         ntfs_log_debug("volume size = %llikiB\n", volume_size / 1024);
3293         /* If user didn't specify the cluster size, determine it now. */
3294         if (!vol->cluster_size) {
3295                 /*
3296                  * Windows Vista always uses 4096 bytes as the default cluster
3297                  * size regardless of the volume size so we do it, too.
3298                  */
3299                 vol->cluster_size = 4096;
3300                 /* For small volumes on devices with large sector sizes. */
3301                 if (vol->cluster_size < (u32)opts.sector_size)
3302                         vol->cluster_size = opts.sector_size;
3303                 /*
3304                  * For huge volumes, grow the cluster size until the number of
3305                  * clusters fits into 32 bits or the cluster size exceeds the
3306                  * maximum limit of 64kiB.
3307                  */
3308                 while (volume_size >> (ffs(vol->cluster_size) - 1 + 32)) {
3309                         vol->cluster_size <<= 1;
3310                         if (vol->cluster_size > 65535) {
3311                                 ntfs_log_error("Device is too large to hold an "
3312                                                 "NTFS volume (maximum size is "
3313                                                 "256TiB).\n");
3314                                 return FALSE;
3315                         }
3316                 }
3317                 ntfs_log_quiet("Cluster size has been automatically set to %u "
3318                                 "bytes.\n", (unsigned)vol->cluster_size);
3319         }
3320         /* Validate cluster size. */
3321         if (vol->cluster_size & (vol->cluster_size - 1)) {
3322                 ntfs_log_error("The cluster size is invalid.  It must be a "
3323                                 "power of two, e.g. 1024, 4096.\n");
3324                 return FALSE;
3325         }
3326         if (vol->cluster_size < (u32)opts.sector_size) {
3327                 ntfs_log_error("The cluster size is invalid.  It must be equal "
3328                                 "to, or larger than, the sector size.\n");
3329                 return FALSE;
3330         }
3331         if (vol->cluster_size > 128 * (u32)opts.sector_size) {
3332                 ntfs_log_error("The cluster size is invalid.  It cannot be "
3333                                 "more that 128 times the size of the sector "
3334                                 "size.\n");
3335                 return FALSE;
3336         }
3337         if (vol->cluster_size > 65536) {
3338                 ntfs_log_error("The cluster size is invalid.  The maximum "
3339                         "cluster size is 65536 bytes (64kiB).\n");
3340                 return FALSE;
3341         }
3342         vol->cluster_size_bits = ffs(vol->cluster_size) - 1;
3343         ntfs_log_debug("cluster size = %u bytes\n",
3344                         (unsigned int)vol->cluster_size);
3345         if (vol->cluster_size > 4096) {
3346                 if (opts.enable_compression) {
3347                         if (!opts.force) {
3348                                 ntfs_log_error("Windows cannot use compression "
3349                                                 "when the cluster size is "
3350                                                 "larger than 4096 bytes.\n");
3351                                 return FALSE;
3352                         }
3353                         opts.enable_compression = 0;
3354                 }
3355                 ntfs_log_warning("Windows cannot use compression when the "
3356                                 "cluster size is larger than 4096 bytes.  "
3357                                 "Compression has been disabled for this "
3358                                 "volume.\n");
3359         }
3360         vol->nr_clusters = volume_size / vol->cluster_size;
3361         /*
3362          * Check the cluster_size and num_sectors for consistency with
3363          * sector_size and num_sectors. And check both of these for consistency
3364          * with volume_size.
3365          */
3366         if ((vol->nr_clusters != ((opts.num_sectors * opts.sector_size) /
3367                         vol->cluster_size) ||
3368                         (volume_size / opts.sector_size) != opts.num_sectors ||
3369                         (volume_size / vol->cluster_size) !=
3370                         vol->nr_clusters)) {
3371                 /* XXX is this code reachable? */
3372                 ntfs_log_error("Illegal combination of volume/cluster/sector "
3373                                 "size and/or cluster/sector number.\n");
3374                 return FALSE;
3375         }
3376         ntfs_log_debug("number of clusters = %llu (0x%llx)\n",
3377                         vol->nr_clusters, vol->nr_clusters);
3378         /* Number of clusters must fit within 32 bits (Win2k limitation). */
3379         if (vol->nr_clusters >> 32) {
3380                 if (vol->cluster_size >= 65536) {
3381                         ntfs_log_error("Device is too large to hold an NTFS "
3382                                         "volume (maximum size is 256TiB).\n");
3383                         return FALSE;
3384                 }
3385                 ntfs_log_error("Number of clusters exceeds 32 bits.  Please "
3386                                 "try again with a larger\ncluster size or "
3387                                 "leave the cluster size unspecified and the "
3388                                 "smallest possible cluster size for the size "
3389                                 "of the device will be used.\n");
3390                 return FALSE;
3391         }
3392         page_size = mkntfs_get_page_size();
3393         /*
3394          * Set the mft record size.  By default this is 1024 but it has to be
3395          * at least as big as a sector and not bigger than a page on the system
3396          * or the NTFS kernel driver will not be able to mount the volume.
3397          * TODO: The mft record size should be user specifiable just like the
3398          * "inode size" can be specified on other Linux/Unix file systems.
3399          */
3400         vol->mft_record_size = 1024;
3401         if (vol->mft_record_size < (u32)opts.sector_size)
3402                 vol->mft_record_size = opts.sector_size;
3403         if (vol->mft_record_size > (unsigned long)page_size)
3404                 ntfs_log_warning("Mft record size (%u bytes) exceeds system "
3405                                 "page size (%li bytes).  You will not be able "
3406                                 "to mount this volume using the NTFS kernel "
3407                                 "driver.\n", (unsigned)vol->mft_record_size,
3408                                 page_size);
3409         vol->mft_record_size_bits = ffs(vol->mft_record_size) - 1;
3410         ntfs_log_debug("mft record size = %u bytes\n",
3411                         (unsigned)vol->mft_record_size);
3412         /*
3413          * Set the index record size.  By default this is 4096 but it has to be
3414          * at least as big as a sector and not bigger than a page on the system
3415          * or the NTFS kernel driver will not be able to mount the volume.
3416          * FIXME: Should we make the index record size to be user specifiable?
3417          */
3418         vol->indx_record_size = 4096;
3419         if (vol->indx_record_size < (u32)opts.sector_size)
3420                 vol->indx_record_size = opts.sector_size;
3421         if (vol->indx_record_size > (unsigned long)page_size)
3422                 ntfs_log_warning("Index record size (%u bytes) exceeds system "
3423                                 "page size (%li bytes).  You will not be able "
3424                                 "to mount this volume using the NTFS kernel "
3425                                 "driver.\n", (unsigned)vol->indx_record_size,
3426                                 page_size);
3427         vol->indx_record_size_bits = ffs(vol->indx_record_size) - 1;
3428         ntfs_log_debug("index record size = %u bytes\n",
3429                         (unsigned)vol->indx_record_size);
3430         if (!winboot) {
3431                 ntfs_log_warning("To boot from a device, Windows needs the "
3432                                 "'partition start sector', the 'sectors per "
3433                                 "track' and the 'number of heads' to be "
3434                                 "set.\n");
3435                 ntfs_log_warning("Windows will not be able to boot from this "
3436                                 "device.\n");
3437         }
3438         return TRUE;
3439 }
3440 
3441 /**
3442  * mkntfs_initialize_bitmaps -
3443  */
3444 static BOOL mkntfs_initialize_bitmaps(void)
3445 {
3446         u64 i;
3447         int mft_bitmap_size;
3448 
3449         /* Determine lcn bitmap byte size and allocate it. */
3450         g_lcn_bitmap_byte_size = (g_vol->nr_clusters + 7) >> 3;
3451         /* Needs to be multiple of 8 bytes. */
3452         g_lcn_bitmap_byte_size = (g_lcn_bitmap_byte_size + 7) & ~7;
3453         i = (g_lcn_bitmap_byte_size + g_vol->cluster_size - 1) &
3454                         ~(g_vol->cluster_size - 1);
3455         ntfs_log_debug("g_lcn_bitmap_byte_size = %i, allocated = %llu\n",
3456                         g_lcn_bitmap_byte_size, i);
3457         g_lcn_bitmap = ntfs_calloc(g_lcn_bitmap_byte_size);
3458         if (!g_lcn_bitmap)
3459                 return FALSE;
3460         /*
3461          * $Bitmap can overlap the end of the volume. Any bits in this region
3462          * must be set. This region also encompasses the backup boot sector.
3463          */
3464         for (i = g_vol->nr_clusters; i < (u64)g_lcn_bitmap_byte_size << 3; i++)
3465                 ntfs_bit_set(g_lcn_bitmap, i, 1);
3466         /*
3467          * Mft size is 27 (NTFS 3.0+) mft records or one cluster, whichever is
3468          * bigger.
3469          */
3470         g_mft_size = 27;
3471         g_mft_size *= g_vol->mft_record_size;
3472         if (g_mft_size < (s32)g_vol->cluster_size)
3473                 g_mft_size = g_vol->cluster_size;
3474         ntfs_log_debug("MFT size = %i (0x%x) bytes\n", g_mft_size, g_mft_size);
3475         /* Determine mft bitmap size and allocate it. */
3476         mft_bitmap_size = g_mft_size / g_vol->mft_record_size;
3477         /* Convert to bytes, at least one. */
3478         g_mft_bitmap_byte_size = (mft_bitmap_size + 7) >> 3;
3479         /* Mft bitmap is allocated in multiples of 8 bytes. */
3480         g_mft_bitmap_byte_size = (g_mft_bitmap_byte_size + 7) & ~7;
3481         ntfs_log_debug("mft_bitmap_size = %i, g_mft_bitmap_byte_size = %i\n",
3482                         mft_bitmap_size, g_mft_bitmap_byte_size);
3483         g_mft_bitmap = ntfs_calloc(g_mft_bitmap_byte_size);
3484         if (!g_mft_bitmap)
3485                 return FALSE;
3486         /* Create runlist for mft bitmap. */
3487         g_rl_mft_bmp = ntfs_malloc(2 * sizeof(runlist));
3488         if (!g_rl_mft_bmp)
3489                 return FALSE;
3490 
3491         g_rl_mft_bmp[0].vcn = 0LL;
3492         /* Mft bitmap is right after $Boot's data. */
3493         i = (8192 + g_vol->cluster_size - 1) / g_vol->cluster_size;
3494         g_rl_mft_bmp[0].lcn = i;
3495         /*
3496          * Size is always one cluster, even though valid data size and
3497          * initialized data size are only 8 bytes.
3498          */
3499         g_rl_mft_bmp[1].vcn = 1LL;
3500         g_rl_mft_bmp[0].length = 1LL;
3501         g_rl_mft_bmp[1].lcn = -1LL;
3502         g_rl_mft_bmp[1].length = 0LL;
3503         /* Allocate cluster for mft bitmap. */
3504         ntfs_bit_set(g_lcn_bitmap, i, 1);
3505         return TRUE;
3506 }
3507 
3508 /**
3509  * mkntfs_initialize_rl_mft -
3510  */
3511 static BOOL mkntfs_initialize_rl_mft(void)
3512 {
3513         int i, j;
3514 
3515         /* If user didn't specify the mft lcn, determine it now. */
3516         if (!g_mft_lcn) {
3517                 /*
3518                  * We start at the higher value out of 16kiB and just after the
3519                  * mft bitmap.
3520                  */
3521                 g_mft_lcn = g_rl_mft_bmp[0].lcn + g_rl_mft_bmp[0].length;
3522                 if (g_mft_lcn * g_vol->cluster_size < 16 * 1024)
3523                         g_mft_lcn = (16 * 1024 + g_vol->cluster_size - 1) /
3524                                         g_vol->cluster_size;
3525         }
3526         ntfs_log_debug("$MFT logical cluster number = 0x%llx\n", g_mft_lcn);
3527         /* Determine MFT zone size. */
3528         g_mft_zone_end = g_vol->nr_clusters;
3529         switch (opts.mft_zone_multiplier) {  /* % of volume size in clusters */
3530         case 4:
3531                 g_mft_zone_end = g_mft_zone_end >> 1;     /* 50%   */
3532                 break;
3533         case 3:
3534                 g_mft_zone_end = g_mft_zone_end * 3 >> 3;/* 37.5% */
3535                 break;
3536         case 2:
3537                 g_mft_zone_end = g_mft_zone_end >> 2;     /* 25%   */
3538                 break;
3539         case 1:
3540         default:
3541                 g_mft_zone_end = g_mft_zone_end >> 3;     /* 12.5% */
3542                 break;
3543         }
3544         ntfs_log_debug("MFT zone size = %lldkiB\n", g_mft_zone_end <<
3545                         g_vol->cluster_size_bits >> 10 /* >> 10 == / 1024 */);
3546         /*
3547          * The mft zone begins with the mft data attribute, not at the beginning
3548          * of the device.
3549          */
3550         g_mft_zone_end += g_mft_lcn;
3551         /* Create runlist for mft. */
3552         g_rl_mft = ntfs_malloc(2 * sizeof(runlist));
3553         if (!g_rl_mft)
3554                 return FALSE;
3555 
3556         g_rl_mft[0].vcn = 0LL;
3557         g_rl_mft[0].lcn = g_mft_lcn;
3558         /* rounded up division by cluster size */
3559         j = (g_mft_size + g_vol->cluster_size - 1) / g_vol->cluster_size;
3560         g_rl_mft[1].vcn = j;
3561         g_rl_mft[0].length = j;
3562         g_rl_mft[1].lcn = -1LL;
3563         g_rl_mft[1].length = 0LL;
3564         /* Allocate clusters for mft. */
3565         for (i = 0; i < j; i++)
3566                 ntfs_bit_set(g_lcn_bitmap, g_mft_lcn + i, 1);
3567         /* Determine mftmirr_lcn (middle of volume). */
3568         g_mftmirr_lcn = (opts.num_sectors * opts.sector_size >> 1)
3569                         / g_vol->cluster_size;
3570         ntfs_log_debug("$MFTMirr logical cluster number = 0x%llx\n",
3571                         g_mftmirr_lcn);
3572         /* Create runlist for mft mirror. */
3573         g_rl_mftmirr = ntfs_malloc(2 * sizeof(runlist));
3574         if (!g_rl_mftmirr)
3575                 return FALSE;
3576 
3577         g_rl_mftmirr[0].vcn = 0LL;
3578         g_rl_mftmirr[0].lcn = g_mftmirr_lcn;
3579         /*
3580          * The mft mirror is either 4kb (the first four records) or one cluster
3581          * in size, which ever is bigger. In either case, it contains a
3582          * byte-for-byte identical copy of the beginning of the mft (i.e. either
3583          * the first four records (4kb) or the first cluster worth of records,
3584          * whichever is bigger).
3585          */
3586         j = (4 * g_vol->mft_record_size + g_vol->cluster_size - 1) / g_vol->cluster_size;
3587         g_rl_mftmirr[1].vcn = j;
3588         g_rl_mftmirr[0].length = j;
3589         g_rl_mftmirr[1].lcn = -1LL;
3590         g_rl_mftmirr[1].length = 0LL;
3591         /* Allocate clusters for mft mirror. */
3592         for (i = 0; i < j; i++)
3593                 ntfs_bit_set(g_lcn_bitmap, g_mftmirr_lcn + i, 1);
3594         g_logfile_lcn = g_mftmirr_lcn + j;
3595         ntfs_log_debug("$LogFile logical cluster number = 0x%llx\n",
3596                         g_logfile_lcn);
3597         return TRUE;
3598 }
3599 
3600 /**
3601  * mkntfs_initialize_rl_logfile -
3602  */
3603 static BOOL mkntfs_initialize_rl_logfile(void)
3604 {
3605         int i, j;
3606         u64 volume_size;
3607 
3608         /* Create runlist for log file. */
3609         g_rl_logfile = ntfs_malloc(2 * sizeof(runlist));
3610         if (!g_rl_logfile)
3611                 return FALSE;
3612 
3613 
3614         volume_size = g_vol->nr_clusters << g_vol->cluster_size_bits;
3615 
3616         g_rl_logfile[0].vcn = 0LL;
3617         g_rl_logfile[0].lcn = g_logfile_lcn;
3618         /*
3619          * Determine logfile_size from volume_size (rounded up to a cluster),
3620          * making sure it does not overflow the end of the volume.
3621          */
3622         if (volume_size < 2048LL * 1024)             /* < 2MiB    */
3623                 g_logfile_size = 256LL * 1024;          /*   -> 256kiB       */
3624         else if (volume_size < 4000000LL)            /* < 4MB     */
3625                 g_logfile_size = 512LL * 1024;          /*   -> 512kiB       */
3626         else if (volume_size <= 200LL * 1024 * 1024) /* < 200MiB  */
3627                 g_logfile_size = 2048LL * 1024;         /*   -> 2MiB */
3628         else    {
3629                 /*
3630                  * FIXME: The $LogFile size is 64 MiB upwards from 12GiB but
3631                  * the "200" divider below apparently approximates "100" or
3632                  * some other value as the volume size decreases. For example:
3633                  *      Volume size   LogFile size    Ratio
3634                  *        8799808        46048       191.100
3635                  *        8603248        45072       190.877
3636                  *        7341704        38768       189.375
3637                  *        6144828        32784       187.433
3638                  *        4192932        23024       182.111
3639                  */
3640                 if (volume_size >= 12LL << 30)         /* > 12GiB   */
3641                         g_logfile_size = 64 << 20;        /*   -> 64MiB        */
3642                 else
3643                         g_logfile_size = (volume_size / 200) &
3644                                         ~(g_vol->cluster_size - 1);
3645         }
3646         j = g_logfile_size / g_vol->cluster_size;
3647         while (g_rl_logfile[0].lcn + j >= g_vol->nr_clusters) {
3648                 /*
3649                  * $Logfile would overflow volume. Need to make it smaller than
3650                  * the standard size. It's ok as we are creating a non-standard
3651                  * volume anyway if it is that small.
3652                  */
3653                 g_logfile_size >>= 1;
3654                 j = g_logfile_size / g_vol->cluster_size;
3655         }
3656         g_logfile_size = (g_logfile_size + g_vol->cluster_size - 1) &
3657                         ~(g_vol->cluster_size - 1);
3658         ntfs_log_debug("$LogFile (journal) size = %ikiB\n",
3659                         g_logfile_size / 1024);
3660         /*
3661          * FIXME: The 256kiB limit is arbitrary. Should find out what the real
3662          * minimum requirement for Windows is so it doesn't blue screen.
3663          */
3664         if (g_logfile_size < 256 << 10) {
3665                 ntfs_log_error("$LogFile would be created with invalid size. "
3666                                 "This is not allowed as it would cause Windows "
3667                                 "to blue screen and during boot.\n");
3668                 return FALSE;
3669         }
3670         g_rl_logfile[1].vcn = j;
3671         g_rl_logfile[0].length = j;
3672         g_rl_logfile[1].lcn = -1LL;
3673         g_rl_logfile[1].length = 0LL;
3674         /* Allocate clusters for log file. */
3675         for (i = 0; i < j; i++)
3676                 ntfs_bit_set(g_lcn_bitmap, g_logfile_lcn + i, 1);
3677         return TRUE;
3678 }
3679 
3680 /**
3681  * mkntfs_initialize_rl_boot -
3682  */
3683 static BOOL mkntfs_initialize_rl_boot(void)
3684 {
3685         int i, j;
3686         /* Create runlist for $Boot. */
3687         g_rl_boot = ntfs_malloc(2 * sizeof(runlist));
3688         if (!g_rl_boot)
3689                 return FALSE;
3690 
3691         g_rl_boot[0].vcn = 0LL;
3692         g_rl_boot[0].lcn = 0LL;
3693         /*
3694          * $Boot is always 8192 (0x2000) bytes or 1 cluster, whichever is
3695          * bigger.
3696          */
3697         j = (8192 + g_vol->cluster_size - 1) / g_vol->cluster_size;
3698         g_rl_boot[1].vcn = j;
3699         g_rl_boot[0].length = j;
3700         g_rl_boot[1].lcn = -1LL;
3701         g_rl_boot[1].length = 0LL;
3702         /* Allocate clusters for $Boot. */
3703         for (i = 0; i < j; i++)
3704                 ntfs_bit_set(g_lcn_bitmap, 0LL + i, 1);
3705         return TRUE;
3706 }
3707 
3708 /**
3709  * mkntfs_initialize_rl_bad -
3710  */
3711 static BOOL mkntfs_initialize_rl_bad(void)
3712 {
3713         /* Create runlist for $BadClus, $DATA named stream $Bad. */
3714         g_rl_bad = ntfs_malloc(2 * sizeof(runlist));
3715         if (!g_rl_bad)
3716                 return FALSE;
3717 
3718         g_rl_bad[0].vcn = 0LL;
3719         g_rl_bad[0].lcn = -1LL;
3720         /*
3721          * $BadClus named stream $Bad contains the whole volume as a single
3722          * sparse runlist entry.
3723          */
3724         g_rl_bad[1].vcn = g_vol->nr_clusters;
3725         g_rl_bad[0].length = g_vol->nr_clusters;
3726         g_rl_bad[1].lcn = -1LL;
3727         g_rl_bad[1].length = 0LL;
3728 
3729         /* TODO: Mark bad blocks as such. */
3730         return TRUE;
3731 }
3732 
3733 /**
3734  * mkntfs_fill_device_with_zeroes -
3735  */
3736 static BOOL mkntfs_fill_device_with_zeroes(void)
3737 {
3738         /*
3739          * If not quick format, fill the device with 0s.
3740          * FIXME: Except bad blocks! (AIA)
3741          */
3742         int i;
3743         ssize_t bw;
3744         unsigned long long position;
3745         float progress_inc = (float)g_vol->nr_clusters / 100;
3746         u64 volume_size;
3747 
3748         volume_size = g_vol->nr_clusters << g_vol->cluster_size_bits;
3749 
3750         ntfs_log_progress("Initializing device with zeroes:   0%%");
3751         for (position = 0; position < (unsigned long long)g_vol->nr_clusters;
3752                         position++) {
3753                 if (!(position % (int)(progress_inc+1))) {
3754                         ntfs_log_progress("\b\b\b\b%3.0f%%", position /
3755                                         progress_inc);
3756                 }
3757                 bw = mkntfs_write(g_vol->u.dev, g_buf, g_vol->cluster_size);
3758                 if (bw != (ssize_t)g_vol->cluster_size) {
3759                         if (bw != -1 || errno != EIO) {
3760                                 ntfs_log_error("This should not happen.\n");
3761                                 return FALSE;
3762                         }
3763                         if (!position) {
3764                                 ntfs_log_error("Error: Cluster zero is bad. "
3765                                         "Cannot create NTFS file "
3766                                         "system.\n");
3767                                 return FALSE;
3768                         }
3769                         /* Add the baddie to our bad blocks list. */
3770                         if (!append_to_bad_blocks(position))
3771                                 return FALSE;
3772                         ntfs_log_quiet("\nFound bad cluster (%lld). Adding to "
3773                                 "list of bad blocks.\nInitializing "
3774                                 "device with zeroes: %3.0f%%", position,
3775                                 position / progress_inc);
3776                         /* Seek to next cluster. */
3777                         g_vol->u.dev->d_ops->seek(g_vol->u.dev,
3778                                         ((off_t)position + 1) *
3779                                         g_vol->cluster_size, SEEK_SET);
3780                 }
3781         }
3782         ntfs_log_progress("\b\b\b\b100%%");
3783         position = (volume_size & (g_vol->cluster_size - 1)) /
3784                         opts.sector_size;
3785         for (i = 0; (unsigned long)i < position; i++) {
3786                 bw = mkntfs_write(g_vol->u.dev, g_buf, opts.sector_size);
3787                 if (bw != opts.sector_size) {
3788                         if (bw != -1 || errno != EIO) {
3789                                 ntfs_log_error("This should not happen.\n");
3790                                 return FALSE;
3791                         } else if (i + 1ull == position) {
3792                                 ntfs_log_error("Error: Bad cluster found in "
3793                                         "location reserved for system "
3794                                         "file $Boot.\n");
3795                                 return FALSE;
3796                         }
3797                         /* Seek to next sector. */
3798                         g_vol->u.dev->d_ops->seek(g_vol->u.dev,
3799                                         opts.sector_size, SEEK_CUR);
3800                 }
3801         }
3802         ntfs_log_progress(" - Done.\n");
3803         return TRUE;
3804 }
3805 
3806 /**
3807  * mkntfs_sync_index_record
3808  *
3809  * (ERSO) made a function out of this, but the reason for doing that
3810  * disappeared during coding....
3811  */
3812 static BOOL mkntfs_sync_index_record(INDEX_ALLOCATION* idx, MFT_RECORD* m,
3813                 ntfschar* name, u32 name_len)
3814 {
3815         int i, err;
3816         ntfs_attr_search_ctx *ctx;
3817         ATTR_RECORD *a;
3818         long long lw;
3819         runlist *rl_index = NULL;
3820 
3821         i = 5 * sizeof(ntfschar);
3822         ctx = ntfs_attr_get_search_ctx(NULL, m);
3823         if (!ctx) {
3824                 ntfs_log_perror("Failed to allocate attribute search context");
3825                 return FALSE;
3826         }
3827         /* FIXME: This should be IGNORE_CASE! */
3828         if (mkntfs_attr_lookup(AT_INDEX_ALLOCATION, name, name_len, 0, 0,
3829                         NULL, 0, ctx)) {
3830                 ntfs_attr_put_search_ctx(ctx);
3831                 ntfs_log_error("BUG: $INDEX_ALLOCATION attribute not found.\n");
3832                 return FALSE;
3833         }
3834         a = ctx->attr;
3835         rl_index = ntfs_mapping_pairs_decompress(g_vol, a, NULL);
3836         if (!rl_index) {
3837                 ntfs_attr_put_search_ctx(ctx);
3838                 ntfs_log_error("Failed to decompress runlist of $INDEX_ALLOCATION "
3839                                 "attribute.\n");
3840                 return FALSE;
3841         }
3842         if (sle64_to_cpu(a->u.nonres.initialized_size) < i) {
3843                 ntfs_attr_put_search_ctx(ctx);
3844                 free(rl_index);
3845                 ntfs_log_error("BUG: $INDEX_ALLOCATION attribute too short.\n");
3846                 return FALSE;
3847         }
3848         ntfs_attr_put_search_ctx(ctx);
3849         i = sizeof(INDEX_BLOCK) - sizeof(INDEX_HEADER) +
3850                         le32_to_cpu(idx->index.allocated_size);
3851         err = ntfs_mst_pre_write_fixup((NTFS_RECORD*)idx, i);
3852         if (err) {
3853                 free(rl_index);
3854                 ntfs_log_error("ntfs_mst_pre_write_fixup() failed while "
3855                         "syncing index block.\n");
3856                 return FALSE;
3857         }
3858         lw = ntfs_rlwrite(g_vol->u.dev, rl_index, (u8*)idx, i, NULL);
3859         free(rl_index);
3860         if (lw != i) {
3861                 ntfs_log_error("Error writing $INDEX_ALLOCATION.\n");
3862                 return FALSE;
3863         }
3864         /* No more changes to @idx below here so no need for fixup: */
3865         /* ntfs_mst_post_write_fixup((NTFS_RECORD*)idx); */
3866         return TRUE;
3867 }
3868 
3869 /**
3870  * create_file_volume -
3871  */
3872 static BOOL create_file_volume(MFT_RECORD *m, leMFT_REF root_ref,
3873                 VOLUME_FLAGS fl, const GUID *volume_guid
3874 #ifndef ENABLE_UUID
3875                 __attribute__((unused))
3876 #endif
3877                 )
3878 {
3879         int i, err;
3880         u8 *sd;
3881 
3882         ntfs_log_verbose("Creating $Volume (mft record 3)\n");
3883         m = (MFT_RECORD*)(g_buf + 3 * g_vol->mft_record_size);
3884         err = create_hardlink(g_index_block, root_ref, m,
3885                         MK_LE_MREF(FILE_Volume, FILE_Volume), 0LL, 0LL,
3886                         FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
3887                         "$Volume", FILE_NAME_WIN32_AND_DOS);
3888         if (!err) {
3889                 init_system_file_sd(FILE_Volume, &sd, &i);
3890                 err = add_attr_sd(m, sd, i);
3891         }
3892         if (!err)
3893                 err = add_attr_data(m, NULL, 0, 0, 0, NULL, 0);
3894         if (!err)
3895                 err = add_attr_vol_name(m, g_vol->vol_name, g_vol->vol_name ?
3896                                 strlen(g_vol->vol_name) : 0);
3897         if (!err) {
3898                 if (fl & VOLUME_IS_DIRTY)
3899                         ntfs_log_quiet("Setting the volume dirty so check "
3900                                         "disk runs on next reboot into "
3901                                         "Windows.\n");
3902                 err = add_attr_vol_info(m, fl, g_vol->major_ver,
3903                                 g_vol->minor_ver);
3904         }
3905 #ifdef ENABLE_UUID
3906         if (!err)
3907                 err = add_attr_object_id(m, volume_guid);
3908 #endif
3909         if (err < 0) {
3910                 ntfs_log_error("Couldn't create $Volume: %s\n",
3911                                 strerror(-err));
3912                 return FALSE;
3913         }
3914         return TRUE;
3915 }
3916 
3917 /**
3918  * create_backup_boot_sector
3919  *
3920  * Return 0 on success or -1 if it couldn't be created.
3921  */
3922 static int create_backup_boot_sector(u8 *buff)
3923 {
3924         const char *s;
3925         ssize_t bw;
3926         int size, e;
3927 
3928         ntfs_log_verbose("Creating backup boot sector.\n");
3929         /*
3930          * Write the first max(512, opts.sector_size) bytes from buf to the
3931          * last sector, but limit that to 8192 bytes of written data since that
3932          * is how big $Boot is (and how big our buffer is)..
3933          */
3934         size = 512;
3935         if (size < opts.sector_size)
3936                 size = opts.sector_size;
3937         if (size < opts.cluster_size)
3938                 size = opts.cluster_size;
3939         if (g_vol->u.dev->d_ops->seek(g_vol->u.dev, (opts.num_sectors + 1) *
3940                         opts.sector_size - size, SEEK_SET) == (off_t)-1) {
3941                 ntfs_log_perror("Seek failed");
3942                 goto bb_err;
3943         }
3944         if (size > 8192)
3945                 size = 8192;
3946         bw = mkntfs_write(g_vol->u.dev, buff, size);
3947         if (bw == size)
3948                 return 0;
3949         e = errno;
3950         if (bw == -1LL)
3951                 s = strerror(e);
3952         else
3953                 s = "unknown error";
3954         /* At least some 2.4 kernels return EIO instead of ENOSPC. */
3955         if (bw != -1LL || (bw == -1LL && e != ENOSPC && e != EIO)) {
3956                 ntfs_log_critical("Couldn't write backup boot sector: %s\n", s);
3957                 return -1;
3958         }
3959 bb_err:
3960         ntfs_log_error("Couldn't write backup boot sector. This is due to a "
3961                         "limitation in the\nLinux kernel. This is not a major "
3962                         "problem as Windows check disk will create the\n"
3963                         "backup boot sector when it is run on your next boot "
3964                         "into Windows.\n");
3965         return -1;
3966 }
3967 
3968 /**
3969  * mkntfs_create_root_structures -
3970  */
3971 static BOOL mkntfs_create_root_structures(void)
3972 {
3973         NTFS_BOOT_SECTOR *bs;
3974         MFT_RECORD *m;
3975         leMFT_REF root_ref;
3976         leMFT_REF extend_ref;
3977         int i;
3978         int j;
3979         int err;
3980         u8 *sd;
3981         FILE_ATTR_FLAGS extend_flags;
3982         VOLUME_FLAGS volume_flags = 0;
3983         int nr_sysfiles;
3984         u8 *buf_log = NULL;
3985         int buf_sds_first_size;
3986         char *buf_sds;
3987 
3988         ntfs_log_quiet("Creating NTFS volume structures.\n");
3989         nr_sysfiles = 27;
3990         /*
3991          * Setup an empty mft record.  Note, we can just give 0 as the mft
3992          * reference as we are creating an NTFS 1.2 volume for which the mft
3993          * reference is ignored by ntfs_mft_record_layout().
3994          *
3995          * Copy the mft record onto all 16 records in the buffer and setup the
3996          * sequence numbers of each system file to equal the mft record number
3997          * of that file (only for $MFT is the sequence number 1 rather than 0).
3998          */
3999         for (i = 0; i < nr_sysfiles; i++) {
4000                 if (ntfs_mft_record_layout(g_vol, 0, m = (MFT_RECORD *)(g_buf +
4001                                 i * g_vol->mft_record_size))) {
4002                         ntfs_log_error("Failed to layout system mft records."
4003                                         "\n");
4004                         return FALSE;
4005                 }
4006                 if (i == 0 || i > 23)
4007                         m->sequence_number = cpu_to_le16(1);
4008                 else
4009                         m->sequence_number = cpu_to_le16(i);
4010         }
4011         /*
4012          * If only one cluster contains all system files then
4013          * fill the rest of it with empty, formatted records.
4014          */
4015         if (nr_sysfiles * (s32)g_vol->mft_record_size < g_mft_size) {
4016                 for (i = nr_sysfiles;
4017                       i * (s32)g_vol->mft_record_size < g_mft_size; i++) {
4018                         m = (MFT_RECORD *)(g_buf + i * g_vol->mft_record_size);
4019                         if (ntfs_mft_record_layout(g_vol, 0, m)) {
4020                                 ntfs_log_error("Failed to layout mft record."
4021                                                 "\n");
4022                                 return FALSE;
4023                         }
4024                         m->flags = cpu_to_le16(0);
4025                         m->sequence_number = cpu_to_le16(i);
4026                 }
4027         }
4028         /*
4029          * Create the 16 system files, adding the system information attribute
4030          * to each as well as marking them in use in the mft bitmap.
4031          */
4032         for (i = 0; i < nr_sysfiles; i++) {
4033                 le32 file_attrs;
4034 
4035                 m = (MFT_RECORD*)(g_buf + i * g_vol->mft_record_size);
4036                 if (i < 16 || i > 23) {
4037                         m->mft_record_number = cpu_to_le32(i);
4038                         m->flags |= MFT_RECORD_IN_USE;
4039                         ntfs_bit_set(g_mft_bitmap, 0LL + i, 1);
4040                 }
4041                 file_attrs = FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM;
4042                 if (i == FILE_root) {
4043                         file_attrs |= FILE_ATTR_ARCHIVE;
4044                         if (opts.disable_indexing)
4045                                 file_attrs |= FILE_ATTR_NOT_CONTENT_INDEXED;
4046                         if (opts.enable_compression)
4047                                 file_attrs |= FILE_ATTR_COMPRESSED;
4048                 }
4049                 /* setting specific security_id flag and */
4050                 /* file permissions for ntfs 3.x */
4051                 if (i == 0 || i == 1 || i == 2 || i == 6 || i == 8 ||
4052                                 i == 10) {
4053                         add_attr_std_info(m, file_attrs,
4054                                 cpu_to_le32(0x0100));
4055                 } else if (i == 9) {
4056                         file_attrs |= FILE_ATTR_VIEW_INDEX_PRESENT;
4057                         add_attr_std_info(m, file_attrs,
4058                                 cpu_to_le32(0x0101));
4059                 } else if (i == 11) {
4060                         add_attr_std_info(m, file_attrs,
4061                                 cpu_to_le32(0x0101));
4062                 } else if (i == 24 || i == 25 || i == 26) {
4063                         file_attrs |= FILE_ATTR_ARCHIVE;
4064                         file_attrs |= FILE_ATTR_VIEW_INDEX_PRESENT;
4065                         add_attr_std_info(m, file_attrs,
4066                                 cpu_to_le32(0x0101));
4067                 } else {
4068                         add_attr_std_info(m, file_attrs,
4069                                 cpu_to_le32(0x00));
4070                 }
4071         }
4072         /* The root directory mft reference. */
4073         root_ref = MK_LE_MREF(FILE_root, FILE_root);
4074         extend_ref = MK_LE_MREF(11,11);
4075         ntfs_log_verbose("Creating root directory (mft record 5)\n");
4076         m = (MFT_RECORD*)(g_buf + 5 * g_vol->mft_record_size);
4077         m->flags |= MFT_RECORD_IS_DIRECTORY;
4078         m->link_count = cpu_to_le16(le16_to_cpu(m->link_count) + 1);
4079         err = add_attr_file_name(m, root_ref, 0LL, 0LL,
4080                         FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM |
4081                         FILE_ATTR_I30_INDEX_PRESENT, 0, 0, ".",
4082                         FILE_NAME_WIN32_AND_DOS);
4083         if (!err) {
4084                 init_root_sd(&sd, &i);
4085                 err = add_attr_sd(m, sd, i);
4086         }
4087         /* FIXME: This should be IGNORE_CASE */
4088         if (!err)
4089                 err = add_attr_index_root(m, "$I30", 4, 0, AT_FILE_NAME,
4090                                 COLLATION_FILE_NAME, g_vol->indx_record_size);
4091         /* FIXME: This should be IGNORE_CASE */
4092         if (!err)
4093                 err = upgrade_to_large_index(m, "$I30", 4, 0, &g_index_block);
4094         if (!err) {
4095                 ntfs_attr_search_ctx *ctx;
4096                 ATTR_RECORD *a;
4097                 ctx = ntfs_attr_get_search_ctx(NULL, m);
4098                 if (!ctx) {
4099                         ntfs_log_perror("Failed to allocate attribute search "
4100                                         "context");
4101                         return FALSE;
4102                 }
4103                 /* There is exactly one file name so this is ok. */
4104                 if (mkntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, 0, 0, NULL,
4105                                 0, ctx)) {
4106                         ntfs_attr_put_search_ctx(ctx);
4107                         ntfs_log_error("BUG: $FILE_NAME attribute not found."
4108                                         "\n");
4109                         return FALSE;
4110                 }
4111                 a = ctx->attr;
4112                 err = insert_file_link_in_dir_index(g_index_block, root_ref,
4113                                 (FILE_NAME_ATTR*)((char*)a +
4114                                 le16_to_cpu(a->u.res.value_offset)),
4115                                 le32_to_cpu(a->u.res.value_length));
4116                 ntfs_attr_put_search_ctx(ctx);
4117         }
4118         if (err) {
4119                 ntfs_log_error("Couldn't create root directory: %s\n",
4120                         strerror(-err));
4121                 return FALSE;
4122         }
4123         /* Add all other attributes, on a per-file basis for clarity. */
4124         ntfs_log_verbose("Creating $MFT (mft record 0)\n");
4125         m = (MFT_RECORD*)g_buf;
4126         err = add_attr_data_positioned(m, NULL, 0, 0, 0, g_rl_mft, g_buf,
4127                         g_mft_size);
4128         if (!err)
4129                 err = create_hardlink(g_index_block, root_ref, m,
4130                                 MK_LE_MREF(FILE_MFT, 1), g_mft_size,
4131                                 g_mft_size, FILE_ATTR_HIDDEN |
4132                                 FILE_ATTR_SYSTEM, 0, 0, "$MFT",
4133                                 FILE_NAME_WIN32_AND_DOS);
4134         /* mft_bitmap is not modified in mkntfs; no need to sync it later. */
4135         if (!err)
4136                 err = add_attr_bitmap_positioned(m, NULL, 0, 0, g_rl_mft_bmp,
4137                                 g_mft_bitmap, g_mft_bitmap_byte_size);
4138         if (err < 0) {
4139                 ntfs_log_error("Couldn't create $MFT: %s\n", strerror(-err));
4140                 return FALSE;
4141         }
4142         ntfs_log_verbose("Creating $MFTMirr (mft record 1)\n");
4143         m = (MFT_RECORD*)(g_buf + 1 * g_vol->mft_record_size);
4144         err = add_attr_data_positioned(m, NULL, 0, 0, 0, g_rl_mftmirr, g_buf,
4145                         g_rl_mftmirr[0].length * g_vol->cluster_size);
4146         if (!err)
4147                 err = create_hardlink(g_index_block, root_ref, m,
4148                                 MK_LE_MREF(FILE_MFTMirr, FILE_MFTMirr),
4149                                 g_rl_mftmirr[0].length * g_vol->cluster_size,
4150                                 g_rl_mftmirr[0].length * g_vol->cluster_size,
4151                                 FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
4152                                 "$MFTMirr", FILE_NAME_WIN32_AND_DOS);
4153         if (err < 0) {
4154                 ntfs_log_error("Couldn't create $MFTMirr: %s\n",
4155                                 strerror(-err));
4156                 return FALSE;
4157         }
4158         ntfs_log_verbose("Creating $LogFile (mft record 2)\n");
4159         m = (MFT_RECORD*)(g_buf + 2 * g_vol->mft_record_size);
4160         buf_log = ntfs_malloc(g_logfile_size);
4161         if (!buf_log)
4162                 return FALSE;
4163         memset(buf_log, -1, g_logfile_size);
4164         err = add_attr_data_positioned(m, NULL, 0, 0, 0, g_rl_logfile, buf_log,
4165                         g_logfile_size);
4166         free(buf_log);
4167         buf_log = NULL;
4168         if (!err)
4169                 err = create_hardlink(g_index_block, root_ref, m,
4170                                 MK_LE_MREF(FILE_LogFile, FILE_LogFile),
4171                                 g_logfile_size, g_logfile_size,
4172                                 FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
4173                                 "$LogFile", FILE_NAME_WIN32_AND_DOS);
4174         if (err < 0) {
4175                 ntfs_log_error("Couldn't create $LogFile: %s\n",
4176                                 strerror(-err));
4177                 return FALSE;
4178         }
4179         ntfs_log_verbose("Creating $AttrDef (mft record 4)\n");
4180         m = (MFT_RECORD*)(g_buf + 4 * g_vol->mft_record_size);
4181         err = add_attr_data(m, NULL, 0, 0, 0, (u8*)g_vol->attrdef,
4182                         g_vol->attrdef_len);
4183         if (!err)
4184                 err = create_hardlink(g_index_block, root_ref, m,
4185                                 MK_LE_MREF(FILE_AttrDef, FILE_AttrDef),
4186                                 (g_vol->attrdef_len + g_vol->cluster_size - 1) &
4187                                 ~(g_vol->cluster_size - 1), g_vol->attrdef_len,
4188                                 FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
4189                                 "$AttrDef", FILE_NAME_WIN32_AND_DOS);
4190         if (!err) {
4191                 init_system_file_sd(FILE_AttrDef, &sd, &i);
4192                 err = add_attr_sd(m, sd, i);
4193         }
4194         if (err < 0) {
4195                 ntfs_log_error("Couldn't create $AttrDef: %s\n",
4196                                 strerror(-err));
4197                 return FALSE;
4198         }
4199         ntfs_log_verbose("Creating $Bitmap (mft record 6)\n");
4200         m = (MFT_RECORD*)(g_buf + 6 * g_vol->mft_record_size);
4201         /* the data attribute of $Bitmap must be non-resident or otherwise */
4202         /* windows 2003 will regard the volume as corrupt (ERSO) */
4203         if (!err)
4204                 err = insert_non_resident_attr_in_mft_record(m,
4205                         AT_DATA,  NULL, 0, 0, 0,
4206                         g_lcn_bitmap, g_lcn_bitmap_byte_size);
4207 
4208 
4209         if (!err)
4210                 err = create_hardlink(g_index_block, root_ref, m,
4211                                 MK_LE_MREF(FILE_Bitmap, FILE_Bitmap),
4212                                 (g_lcn_bitmap_byte_size + g_vol->cluster_size -
4213                                 1) & ~(g_vol->cluster_size - 1),
4214                                 g_lcn_bitmap_byte_size,
4215                                 FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
4216                                 "$Bitmap", FILE_NAME_WIN32_AND_DOS);
4217         if (err < 0) {
4218                 ntfs_log_error("Couldn't create $Bitmap: %s\n", strerror(-err));
4219                 return FALSE;
4220         }
4221         ntfs_log_verbose("Creating $Boot (mft record 7)\n");
4222         m = (MFT_RECORD*)(g_buf + 7 * g_vol->mft_record_size);
4223         bs = ntfs_calloc(8192);
4224         if (!bs)
4225                 return FALSE;
4226         memcpy(bs, boot_array, sizeof(boot_array));
4227         /*
4228          * Create the boot sector in bs. Note, that bs is already zeroed
4229          * in the boot sector section and that it has the NTFS OEM id/magic
4230          * already inserted, so no need to worry about these things.
4231          */
4232         bs->bpb.bytes_per_sector = cpu_to_le16(opts.sector_size);
4233         bs->bpb.sectors_per_cluster = (u8)(g_vol->cluster_size /
4234                         opts.sector_size);
4235         bs->bpb.media_type = 0xf8; /* hard disk */
4236         bs->bpb.sectors_per_track = cpu_to_le16(opts.sectors_per_track);
4237         ntfs_log_debug("sectors per track = %ld (0x%lx)\n",
4238                         opts.sectors_per_track, opts.sectors_per_track);
4239         bs->bpb.heads = cpu_to_le16(opts.heads);
4240         ntfs_log_debug("heads = %ld (0x%lx)\n", opts.heads, opts.heads);
4241         bs->bpb.hidden_sectors = cpu_to_le32(opts.part_start_sect);
4242         ntfs_log_debug("hidden sectors = %llu (0x%llx)\n", opts.part_start_sect,
4243                         opts.part_start_sect);
4244         bs->physical_drive = 0x80;       /* boot from hard disk */
4245         bs->extended_boot_signature = 0x80; /* everybody sets this, so we do */
4246         bs->number_of_sectors = cpu_to_sle64(opts.num_sectors);
4247         bs->mft_lcn = cpu_to_sle64(g_mft_lcn);
4248         bs->mftmirr_lcn = cpu_to_sle64(g_mftmirr_lcn);
4249         if (g_vol->mft_record_size >= g_vol->cluster_size) {
4250                 bs->clusters_per_mft_record = g_vol->mft_record_size /
4251                         g_vol->cluster_size;
4252         } else {
4253                 bs->clusters_per_mft_record = -(ffs(g_vol->mft_record_size) -
4254                                 1);
4255                 if ((u32)(1 << -bs->clusters_per_mft_record) !=
4256                                 g_vol->mft_record_size) {
4257                         free(bs);
4258                         ntfs_log_error("BUG: calculated clusters_per_mft_record"
4259                                         " is wrong (= 0x%x)\n",
4260                                         bs->clusters_per_mft_record);
4261                         return FALSE;
4262                 }
4263         }
4264         ntfs_log_debug("clusters per mft record = %i (0x%x)\n",
4265                         bs->clusters_per_mft_record,
4266                         bs->clusters_per_mft_record);
4267         if (g_vol->indx_record_size >= g_vol->cluster_size) {
4268                 bs->clusters_per_index_record = g_vol->indx_record_size /
4269                         g_vol->cluster_size;
4270         } else {
4271                 bs->clusters_per_index_record = -g_vol->indx_record_size_bits;
4272                 if ((1 << -bs->clusters_per_index_record) !=
4273                                 (s32)g_vol->indx_record_size) {
4274                         free(bs);
4275                         ntfs_log_error("BUG: calculated "
4276                                         "clusters_per_index_record is wrong "
4277                                         "(= 0x%x)\n",
4278                                         bs->clusters_per_index_record);
4279                         return FALSE;
4280                 }
4281         }
4282         ntfs_log_debug("clusters per index block = %i (0x%x)\n",
4283                         bs->clusters_per_index_record,
4284                         bs->clusters_per_index_record);
4285         /* Generate a 64-bit random number for the serial number. */
4286         bs->volume_serial_number = cpu_to_le64(((u64)random() << 32) |
4287                         ((u64)random() & 0xffffffff));
4288         /*
4289          * Leave zero for now as NT4 leaves it zero, too. If want it later, see
4290          * ../libntfs/bootsect.c for how to calculate it.
4291          */
4292         bs->checksum = cpu_to_le32(0);
4293         /* Make sure the bootsector is ok. */
4294         if (!ntfs_boot_sector_is_ntfs(bs, TRUE)) {
4295                 free(bs);
4296                 ntfs_log_error("FATAL: Generated boot sector is invalid!\n");
4297                 return FALSE;
4298         }
4299         err = add_attr_data_positioned(m, NULL, 0, 0, 0, g_rl_boot, (u8*)bs,
4300                         8192);
4301         if (!err)
4302                 err = create_hardlink(g_index_block, root_ref, m,
4303                                 MK_LE_MREF(FILE_Boot, FILE_Boot),
4304                                 (8192 + g_vol->cluster_size - 1) &
4305                                 ~(g_vol->cluster_size - 1), 8192,
4306                                 FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
4307                                 "$Boot", FILE_NAME_WIN32_AND_DOS);
4308         if (!err) {
4309                 init_system_file_sd(FILE_Boot, &sd, &i);
4310                 err = add_attr_sd(m, sd, i);
4311         }
4312         if (err < 0) {
4313                 free(bs);
4314                 ntfs_log_error("Couldn't create $Boot: %s\n", strerror(-err));
4315                 return FALSE;
4316         }
4317         if (create_backup_boot_sector((u8*)bs)) {
4318                 /*
4319                  * Pre-2.6 kernels couldn't access the last sector if it was
4320                  * odd and we failed to set the device block size to the sector
4321                  * size, hence we schedule chkdsk to create it.
4322                  */
4323                 volume_flags |= VOLUME_IS_DIRTY;
4324         }
4325         free(bs);
4326 #ifdef ENABLE_UUID
4327         /*
4328          * We cheat a little here and if the user has requested all times to be
4329          * set to zero then we set the GUID to zero as well.  This options is
4330          * only used for development purposes so that should be fine.
4331          */
4332         if (!opts.use_epoch_time) {
4333                 /* Generate a GUID for the volume. */
4334                 uuid_generate((void*)&g_vol->guid);
4335         } else
4336                 memset(&g_vol->guid, 0, sizeof(g_vol->guid));
4337 #endif
4338         if (!create_file_volume(m, root_ref, volume_flags, &g_vol->guid))
4339                 return FALSE;
4340         ntfs_log_verbose("Creating $BadClus (mft record 8)\n");
4341         m = (MFT_RECORD*)(g_buf + 8 * g_vol->mft_record_size);
4342         /* FIXME: This should be IGNORE_CASE */
4343         /* Create a sparse named stream of size equal to the volume size. */
4344         err = add_attr_data_positioned(m, "$Bad", 4, 0, 0, g_rl_bad, NULL,
4345                         g_vol->nr_clusters * g_vol->cluster_size);
4346         if (!err) {
4347                 err = add_attr_data(m, NULL, 0, 0, 0, NULL, 0);
4348         }
4349         if (!err) {
4350                 err = create_hardlink(g_index_block, root_ref, m,
4351                                 MK_LE_MREF(FILE_BadClus, FILE_BadClus),
4352                                 0LL, 0LL, FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM,
4353                                 0, 0, "$BadClus", FILE_NAME_WIN32_AND_DOS);
4354         }
4355         if (err < 0) {
4356                 ntfs_log_error("Couldn't create $BadClus: %s\n",
4357                                 strerror(-err));
4358                 return FALSE;
4359         }
4360         /* create $Secure (NTFS 3.0+) */
4361         ntfs_log_verbose("Creating $Secure (mft record 9)\n");
4362         m = (MFT_RECORD*)(g_buf + 9 * g_vol->mft_record_size);
4363         m->flags |= MFT_RECORD_IS_VIEW_INDEX;
4364         if (!err)
4365                 err = create_hardlink(g_index_block, root_ref, m,
4366                                 MK_LE_MREF(9, 9), 0LL, 0LL,
4367                                 FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM |
4368                                 FILE_ATTR_VIEW_INDEX_PRESENT, 0, 0,
4369                                 "$Secure", FILE_NAME_WIN32_AND_DOS);
4370         buf_sds = NULL;
4371         buf_sds_first_size = 0;
4372         if (!err) {
4373                 int buf_sds_size;
4374 
4375                 buf_sds_first_size = 0xfc;
4376                 buf_sds_size = 0x40000 + buf_sds_first_size;
4377                 buf_sds = ntfs_calloc(buf_sds_size);
4378                 if (!buf_sds)
4379                         return FALSE;
4380                 init_secure_sds(buf_sds);
4381                 memcpy(buf_sds + 0x40000, buf_sds, buf_sds_first_size);
4382                 err = add_attr_data(m, "$SDS", 4, 0, 0, (u8*)buf_sds,
4383                                 buf_sds_size);
4384         }
4385         /* FIXME: This should be IGNORE_CASE */
4386         if (!err)
4387                 err = add_attr_index_root(m, "$SDH", 4, 0, AT_UNUSED,
4388                         COLLATION_NTOFS_SECURITY_HASH,
4389                         g_vol->indx_record_size);
4390         /* FIXME: This should be IGNORE_CASE */
4391         if (!err)
4392                 err = add_attr_index_root(m, "$SII", 4, 0, AT_UNUSED,
4393                         COLLATION_NTOFS_ULONG, g_vol->indx_record_size);
4394         if (!err)
4395                 err = initialize_secure(buf_sds, buf_sds_first_size, m);
4396         free(buf_sds);
4397         if (err < 0) {
4398                 ntfs_log_error("Couldn't create $Secure: %s\n",
4399                         strerror(-err));
4400                 return FALSE;
4401         }
4402         ntfs_log_verbose("Creating $UpCase (mft record 0xa)\n");
4403         m = (MFT_RECORD*)(g_buf + 0xa * g_vol->mft_record_size);
4404         err = add_attr_data(m, NULL, 0, 0, 0, (u8*)g_vol->upcase,
4405                         g_vol->upcase_len << 1);
4406         if (!err)
4407                 err = create_hardlink(g_index_block, root_ref, m,
4408                                 MK_LE_MREF(FILE_UpCase, FILE_UpCase),
4409                                 ((g_vol->upcase_len << 1) +
4410                                 g_vol->cluster_size - 1) &
4411                                 ~(g_vol->cluster_size - 1),
4412                                 g_vol->upcase_len << 1,
4413                                 FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
4414                                 "$UpCase", FILE_NAME_WIN32_AND_DOS);
4415         if (err < 0) {
4416                 ntfs_log_error("Couldn't create $UpCase: %s\n", strerror(-err));
4417                 return FALSE;
4418         }
4419         ntfs_log_verbose("Creating $Extend (mft record 11)\n");
4420         /*
4421          * $Extend index must be resident.  Otherwise, w2k3 will regard the
4422          * volume as corrupt. (ERSO)
4423          */
4424         m = (MFT_RECORD*)(g_buf + 11 * g_vol->mft_record_size);
4425         m->flags |= MFT_RECORD_IS_DIRECTORY;
4426         if (!err)
4427                 err = create_hardlink(g_index_block, root_ref, m,
4428                                 MK_LE_MREF(11, 11), 0LL, 0LL,
4429                                 FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM |
4430                                 FILE_ATTR_I30_INDEX_PRESENT, 0, 0,
4431                                 "$Extend", FILE_NAME_WIN32_AND_DOS);
4432         /* FIXME: This should be IGNORE_CASE */
4433         if (!err)
4434                 err = add_attr_index_root(m, "$I30", 4, 0, AT_FILE_NAME,
4435                         COLLATION_FILE_NAME, g_vol->indx_record_size);
4436         if (err < 0) {
4437                 ntfs_log_error("Couldn't create $Extend: %s\n",
4438                         strerror(-err));
4439                 return FALSE;
4440         }
4441         /* NTFS reserved system files (mft records 0xc-0xf) */
4442         for (i = 0xc; i < 0x10; i++) {
4443                 ntfs_log_verbose("Creating system file (mft record 0x%x)\n", i);
4444                 m = (MFT_RECORD*)(g_buf + i * g_vol->mft_record_size);
4445                 err = add_attr_data(m, NULL, 0, 0, 0, NULL, 0);
4446                 if (!err) {
4447                         init_system_file_sd(i, &sd, &j);
4448                         err = add_attr_sd(m, sd, j);
4449                 }
4450                 if (err < 0) {
4451                         ntfs_log_error("Couldn't create system file %i (0x%x): "
4452                                         "%s\n", i, i, strerror(-err));
4453                         return FALSE;
4454                 }
4455         }
4456         /* create systemfiles for ntfs volumes (3.1) */
4457         /* starting with file 24 (ignoring file 16-23) */
4458         extend_flags = FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM |
4459                 FILE_ATTR_ARCHIVE | FILE_ATTR_VIEW_INDEX_PRESENT;
4460         ntfs_log_verbose("Creating $Quota (mft record 24)\n");
4461         m = (MFT_RECORD*)(g_buf + 24 * g_vol->mft_record_size);
4462         m->flags |= MFT_RECORD_IS_4;
4463         m->flags |= MFT_RECORD_IS_VIEW_INDEX;
4464         if (!err)
4465                 err = create_hardlink_res((MFT_RECORD*)(g_buf +
4466                         11 * g_vol->mft_record_size), extend_ref, m,
4467                         MK_LE_MREF(24, 1), 0LL, 0LL, extend_flags,
4468                         0, 0, "$Quota", FILE_NAME_WIN32_AND_DOS);
4469         /* FIXME: This should be IGNORE_CASE */
4470         if (!err)
4471                 err = add_attr_index_root(m, "$Q", 2, 0, AT_UNUSED,
4472                         COLLATION_NTOFS_ULONG, g_vol->indx_record_size);
4473         /* FIXME: This should be IGNORE_CASE */
4474         if (!err)
4475                 err = add_attr_index_root(m, "$O", 2, 0, AT_UNUSED,
4476                         COLLATION_NTOFS_SID, g_vol->indx_record_size);
4477         if (!err)
4478                 err = initialize_quota(m);
4479         if (err < 0) {
4480                 ntfs_log_error("Couldn't create $Quota: %s\n", strerror(-err));
4481                 return FALSE;
4482         }
4483         ntfs_log_verbose("Creating $ObjId (mft record 25)\n");
4484         m = (MFT_RECORD*)(g_buf + 25 * g_vol->mft_record_size);
4485         m->flags |= MFT_RECORD_IS_4;
4486         m->flags |= MFT_RECORD_IS_VIEW_INDEX;
4487         if (!err)
4488                 err = create_hardlink_res((MFT_RECORD*)(g_buf +
4489                                 11 * g_vol->mft_record_size), extend_ref,
4490                                 m, MK_LE_MREF(25, 1), 0LL, 0LL,
4491                                 extend_flags, 0, 0, "$ObjId",
4492                                 FILE_NAME_WIN32_AND_DOS);
4493 
4494         /* FIXME: This should be IGNORE_CASE */
4495         if (!err)
4496                 err = add_attr_index_root(m, "$O", 2, 0, AT_UNUSED,
4497                         COLLATION_NTOFS_ULONGS,
4498                         g_vol->indx_record_size);
4499 #ifdef ENABLE_UUID
4500         if (!err)
4501                 err = index_obj_id_insert(m, &g_vol->guid,
4502                                 MK_LE_MREF(FILE_Volume, FILE_Volume));
4503 #endif
4504         if (err < 0) {
4505                 ntfs_log_error("Couldn't create $ObjId: %s\n",
4506                                 strerror(-err));
4507                 return FALSE;
4508         }
4509         ntfs_log_verbose("Creating $Reparse (mft record 26)\n");
4510         m = (MFT_RECORD*)(g_buf + 26 * g_vol->mft_record_size);
4511         m->flags |= MFT_RECORD_IS_4;
4512         m->flags |= MFT_RECORD_IS_VIEW_INDEX;
4513         if (!err)
4514                 err = create_hardlink_res((MFT_RECORD*)(g_buf +
4515                                 11 * g_vol->mft_record_size),
4516                                 extend_ref, m, MK_LE_MREF(26, 1),
4517                                 0LL, 0LL, extend_flags, 0, 0,
4518                                 "$Reparse", FILE_NAME_WIN32_AND_DOS);
4519         /* FIXME: This should be IGNORE_CASE */
4520         if (!err)
4521                 err = add_attr_index_root(m, "$R", 2, 0, AT_UNUSED,
4522                         COLLATION_NTOFS_ULONGS, g_vol->indx_record_size);
4523         if (err < 0) {
4524                 ntfs_log_error("Couldn't create $Reparse: %s\n",
4525                         strerror(-err));
4526                 return FALSE;
4527         }
4528         return TRUE;
4529 }
4530 
4531 /**
4532  * mkntfs_redirect
4533  */
4534 static int mkntfs_redirect(struct mkntfs_options *opts2)
4535 {
4536         int result = 1;
4537         ntfs_attr_search_ctx *ctx = NULL;
4538         long long lw, pos;
4539         ATTR_RECORD *a;
4540         MFT_RECORD *m;
4541         int i, err;
4542 
4543         if (!opts2) {
4544                 ntfs_log_error("Internal error: invalid parameters to mkntfs_options.\n");
4545                 goto done;
4546         }
4547         /* Initialize the random number generator with the current time. */
4548         srandom(mkntfs_time());
4549         /* Allocate and initialize ntfs_volume structure g_vol. */
4550         g_vol = ntfs_volume_alloc();
4551         if (!g_vol) {
4552                 ntfs_log_perror("Could not create volume");
4553                 goto done;
4554         }
4555         /* Create NTFS 3.1 (Windows XP/Vista) volumes. */
4556         g_vol->major_ver = 3;
4557         g_vol->minor_ver = 1;
4558         /* Transfer some options to the volume. */
4559         if (opts.label) {
4560                 g_vol->vol_name = strdup(opts.label);
4561                 if (!g_vol->vol_name) {
4562                         ntfs_log_perror("Could not copy volume name");
4563                         goto done;
4564                 }
4565         }
4566         if (opts.cluster_size >= 0)
4567                 g_vol->cluster_size = opts.cluster_size;
4568         /* Length is in unicode characters. */
4569         g_vol->upcase_len = 65536;
4570         g_vol->upcase = ntfs_malloc(g_vol->upcase_len * sizeof(ntfschar));
4571         if (!g_vol->upcase)
4572                 goto done;
4573         ntfs_upcase_table_build(g_vol->upcase,
4574                         g_vol->upcase_len * sizeof(ntfschar));
4575         g_vol->attrdef = ntfs_malloc(sizeof(attrdef_ntfs3x_array));
4576         if (!g_vol->attrdef) {
4577                 ntfs_log_perror("Could not create attrdef structure");
4578                 goto done;
4579         }
4580         memcpy(g_vol->attrdef, attrdef_ntfs3x_array,
4581                         sizeof(attrdef_ntfs3x_array));
4582         g_vol->attrdef_len = sizeof(attrdef_ntfs3x_array);
4583         /* Open the partition. */
4584         if (!mkntfs_open_partition(g_vol))
4585                 goto done;
4586         /*
4587          * Decide on the sector size, cluster size, mft record and index record
4588          * sizes as well as the number of sectors/tracks/heads/size, etc.
4589          */
4590         if (!mkntfs_override_vol_params(g_vol))
4591                 goto done;
4592         /* Initialize $Bitmap and $MFT/$BITMAP related stuff. */
4593         if (!mkntfs_initialize_bitmaps())
4594                 goto done;
4595         /* Initialize MFT & set g_logfile_lcn. */
4596         if (!mkntfs_initialize_rl_mft())
4597                 goto done;
4598         /* Initialize $LogFile. */
4599         if (!mkntfs_initialize_rl_logfile())
4600                 goto done;
4601         /* Initialize $Boot. */
4602         if (!mkntfs_initialize_rl_boot())
4603                 goto done;
4604         /* Allocate a buffer large enough to hold the mft. */
4605         g_buf = ntfs_calloc(g_mft_size);
4606         if (!g_buf)
4607                 goto done;
4608         /* Create runlist for $BadClus, $DATA named stream $Bad. */
4609         if (!mkntfs_initialize_rl_bad())
4610                 goto done;
4611         /* If not quick format, fill the device with 0s. */
4612         if (!opts.quick_format) {
4613                 if (!mkntfs_fill_device_with_zeroes())
4614                         goto done;
4615         }
4616         /* Create NTFS volume structures. */
4617         if (!mkntfs_create_root_structures())
4618                 goto done;
4619         /*
4620          * - Do not step onto bad blocks!!!
4621          * - If any bad blocks were specified or found, modify $BadClus,
4622          *   allocating the bad clusters in $Bitmap.
4623          * - C&w bootsector backup bootsector (backup in last sector of the
4624          *   partition).
4625          * - If NTFS 3.0+, c&w $Secure file and $Extend directory with the
4626          *   corresponding special files in it, i.e. $ObjId, $Quota, $Reparse,
4627          *   and $UsnJrnl. And others? Or not all necessary?
4628          * - RE: Populate $root with the system files (and $Extend directory if
4629          *   applicable). Possibly should move this as far to the top as
4630          *   possible and update during each subsequent c&w of each system file.
4631          */
4632         ntfs_log_verbose("Syncing root directory index record.\n");
4633         if (!mkntfs_sync_index_record(g_index_block, (MFT_RECORD*)(g_buf + 5 *
4634                         g_vol->mft_record_size), NTFS_INDEX_I30, 4))
4635                 goto done;
4636 
4637         ntfs_log_verbose("Syncing $Bitmap.\n");
4638         m = (MFT_RECORD*)(g_buf + 6 * g_vol->mft_record_size);
4639 
4640         ctx = ntfs_attr_get_search_ctx(NULL, m);
4641         if (!ctx) {
4642                 ntfs_log_perror("Could not create an attribute search context");
4643                 goto done;
4644         }
4645 
4646         if (mkntfs_attr_lookup(AT_DATA, AT_UNNAMED, 0, 0, 0, NULL, 0, ctx)) {
4647                 ntfs_log_error("BUG: $DATA attribute not found.\n");
4648                 goto done;
4649         }
4650 
4651         a = ctx->attr;
4652         if (a->non_resident) {
4653                 runlist *rl = ntfs_mapping_pairs_decompress(g_vol, a, NULL);
4654                 if (!rl) {
4655                         ntfs_log_error("ntfs_mapping_pairs_decompress() failed\n");
4656                         goto done;
4657                 }
4658                 lw = ntfs_rlwrite(g_vol->u.dev, rl, g_lcn_bitmap, g_lcn_bitmap_byte_size, NULL);
4659                 err = errno;
4660                 free(rl);
4661                 if (lw != g_lcn_bitmap_byte_size) {
4662                         ntfs_log_error("ntfs_rlwrite: %s\n", lw == -1 ?
4663                                        strerror(err) : "unknown error");
4664                         goto done;
4665                 }
4666         } else {
4667                 memcpy((char*)a + le16_to_cpu(a->u.res.value_offset), g_lcn_bitmap, le32_to_cpu(a->u.res.value_length));
4668         }
4669 
4670         /*
4671          * No need to sync $MFT/$BITMAP as that has never been modified since
4672          * its creation.
4673          */
4674         ntfs_log_verbose("Syncing $MFT.\n");
4675         pos = g_mft_lcn * g_vol->cluster_size;
4676         lw = 1;
4677         for (i = 0; i < g_mft_size / (s32)g_vol->mft_record_size; i++) {
4678                 if (!opts.no_action)
4679                         lw = ntfs_mst_pwrite(g_vol->u.dev, pos, 1, g_vol->mft_record_size, g_buf + i * g_vol->mft_record_size);
4680                 if (lw != 1) {
4681                         ntfs_log_error("ntfs_mst_pwrite: %s\n", lw == -1 ?
4682                                        strerror(errno) : "unknown error");
4683                         goto done;
4684                 }
4685                 pos += g_vol->mft_record_size;
4686         }
4687         ntfs_log_verbose("Updating $MFTMirr.\n");
4688         pos = g_mftmirr_lcn * g_vol->cluster_size;
4689         lw = 1;
4690         for (i = 0; i < g_rl_mftmirr[0].length * g_vol->cluster_size / g_vol->mft_record_size; i++) {
4691                 m = (MFT_RECORD*)(g_buf + i * g_vol->mft_record_size);
4692                 /*
4693                  * Decrement the usn by one, so it becomes the same as the one
4694                  * in $MFT once it is mst protected. - This is as we need the
4695                  * $MFTMirr to have the exact same byte by byte content as
4696                  * $MFT, rather than just equivalent meaning content.
4697                  */
4698                 if (ntfs_mft_usn_dec(m)) {
4699                         ntfs_log_error("ntfs_mft_usn_dec");
4700                         goto done;
4701                 }
4702                 if (!opts.no_action)
4703                         lw = ntfs_mst_pwrite(g_vol->u.dev, pos, 1, g_vol->mft_record_size, g_buf + i * g_vol->mft_record_size);
4704                 if (lw != 1) {
4705                         ntfs_log_error("ntfs_mst_pwrite: %s\n", lw == -1 ?
4706                                        strerror(errno) : "unknown error");
4707                         goto done;
4708                 }
4709                 pos += g_vol->mft_record_size;
4710         }
4711         ntfs_log_verbose("Syncing device.\n");
4712         if (g_vol->u.dev->d_ops->sync(g_vol->u.dev)) {
4713                 ntfs_log_error("Syncing device. FAILED");
4714                 goto done;
4715         }
4716         ntfs_log_quiet("mkntfs completed successfully. Have a nice day.\n");
4717         result = 0;
4718 done:
4719         ntfs_attr_put_search_ctx(ctx);
4720         mkntfs_cleanup();       /* Device is unlocked and closed here */
4721         return result;
4722 }
4723 
4724 
4725 /**
4726  * main - Begin here
4727  *
4728  * Start from here.
4729  *
4730  * Return:  0  Success, the program worked
4731  *          1  Error, something went wrong
4732  */
4733 int main(int argc, char *argv[])
4734 {
4735         int result = 1;
4736 
4737         ntfs_log_set_handler(ntfs_log_handler_outerr);
4738         utils_set_locale();
4739 
4740         mkntfs_init_options(&opts);                 /* Set up the options */
4741 
4742         if (!mkntfs_parse_options(argc, argv, &opts))       /* Read the command line options */
4743                 goto done;
4744 
4745         result = mkntfs_redirect(&opts);
4746 done:
4747         return result;
4748 }