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