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