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