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 }