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