http://linux-ntfs.sourceforge.net/snapshots/ntfsprogs-200307311516.tar.bz2
[ntfsprogs.git] / ntfsprogs / mkntfs.c
1 /**
2  * mkntfs - Part of the Linux-NTFS project.
3  *
4  * Copyright (c) 2000-2003 Anton Altaparmakov
5  * Copyright (c) 2001-2003 Richard Russon
6  *
7  * This utility will create an NTFS 1.2 (Windows NT 4.0) volume on a user
8  * specified (block) device.
9  *
10  * Some things (option handling and determination of mount status) have been
11  * adapted from e2fsprogs-1.19 and lib/ext2fs/ismounted.c and misc/mke2fs.c in
12  * particular.
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program (in the main directory of the Linux-NTFS source
26  * in the file COPYING); if not, write to the Free Software Foundation,
27  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28  */
29
30 /*
31  * WARNING: This program might not work on architectures which do not allow
32  * unaligned access. For those, the program would need to start using
33  * get/put_unaligned macros (#include <asm/unaligned.h>), but not doing it yet,
34  * since NTFS really mostly applies to ia32 only, which does allow unaligned
35  * accesses. We might not actually have a problem though, since the structs are
36  * defined as being packed so that might be enough for gcc to insert the
37  * correct code.
38  *
39  * If anyone using a non-little endian and/or an aligned access only CPU tries
40  * this program please let me know whether it works or not!
41  *
42  *      Anton Altaparmakov <aia21@cantab.net>
43  */
44
45 #include "config.h"
46
47 #ifdef HAVE_UNISTD_H
48 #       include <unistd.h>
49 #endif
50 #ifdef HAVE_STDLIB_H
51 #       include <stdlib.h>
52 #endif
53 #ifdef HAVE_STDIO_H
54 #       include <stdio.h>
55 #endif
56 #ifdef HAVE_STDARG_H
57 #       include <stdarg.h>
58 #endif
59 #ifdef HAVE_STRING_H
60 #       include <string.h>
61 #endif
62 #ifdef HAVE_ERRNO_H
63 #       include <errno.h>
64 #endif
65 #include <time.h>
66 #ifdef HAVE_GETOPT_H
67 #       include <getopt.h>
68 #else
69         extern char *optarg;
70         extern int optind;
71 #endif
72 #include <sys/stat.h>
73 #include <fcntl.h>
74 #ifdef HAVE_LINUX_MAJOR_H
75 #       include <linux/major.h>
76 #endif
77 #ifndef MAJOR
78 #       define MAJOR(dev)       ((dev) >> 8)
79 #       define MINOR(dev)       ((dev) & 0xff)
80 #endif
81 #ifndef SCSI_BLK_MAJOR
82 #       define SCSI_BLK_MAJOR(m)        ((m) == SCSI_DISK_MAJOR || \
83                                          (m) == SCSI_CDROM_MAJOR)
84 #endif
85 #include <limits.h>
86
87 #if defined(linux) && defined(_IO) && !defined(BLKSSZGET)
88 #       define BLKSSZGET _IO(0x12,104) /* Get device sector size in bytse. */
89 #endif
90
91 #include "types.h"
92 #include "bootsect.h"
93 #include "disk_io.h"
94 #include "device.h"
95 #include "attrib.h"
96 #include "bitmap.h"
97 #include "mst.h"
98 #include "dir.h"
99 #include "runlist.h"
100 //#include "debug.h"
101 #include "utils.h"
102
103 extern const unsigned char attrdef_ntfs12_array[2400];
104 extern const unsigned char boot_array[3429];
105 extern void init_system_file_sd(int sys_file_no, char **sd_val,
106                 int *sd_val_len);
107 extern void init_upcase_table(uchar_t *uc, u32 uc_len);
108
109 /* Page size on ia32. Can change to 8192 on Alpha. */
110 #define NTFS_PAGE_SIZE  4096
111
112 const char *EXEC_NAME = "mkntfs";
113
114 /* Need these global so mkntfs_exit can access them. */
115 char *buf = NULL;
116 char *buf2 = NULL;
117 int buf2_size = 0;
118 int mft_bitmap_size, mft_bitmap_byte_size;
119 unsigned char *mft_bitmap = NULL;
120 int lcn_bitmap_byte_size;
121 unsigned char *lcn_bitmap = NULL;
122 runlist *rl = NULL, *rl_mft = NULL, *rl_mft_bmp = NULL, *rl_mftmirr = NULL;
123 runlist *rl_logfile = NULL, *rl_boot = NULL, *rl_bad = NULL, *rl_index;
124 INDEX_ALLOCATION *index_block = NULL;
125 ntfs_volume *vol;
126 char *dev_name;
127
128 struct {
129         int sector_size;                /* -s, in bytes, power of 2, default is
130                                            512 bytes. */
131         long long nr_sectors;           /* size of device in sectors */
132         long long nr_clusters;          /* Note: Win2k treats clusters as
133                                            32-bit entities! */
134         long long volume_size;          /* in bytes, or suffixed
135                                            with k for kB, m or M for MB, or
136                                            g or G for GB, or t or T for TB */
137         int index_block_size;           /* in bytes. */
138         int mft_size;                   /* The bigger of 16kB & one cluster. */
139         long long mft_lcn;              /* lcn of $MFT, $DATA attribute. */
140         long long mftmirr_lcn;          /* lcn of $MFTMirr, $DATA. */
141         long long logfile_lcn;          /* lcn of $LogFile, $DATA. */
142         int logfile_size;               /* in bytes, determined from
143                                            volume_size. */
144         char mft_zone_multiplier;       /* -z, value from 1 to 4. Default is
145                                            1. */
146         long long mft_zone_end;         /* Determined from volume_size and
147                                            mft_zone_multiplier, in clusters. */
148         char no_action;                 /* -n, do not write to device, only
149                                            display what would be done. */
150         char check_bad_blocks;          /* read-only test for bad
151                                            clusters. */
152         long long *bad_blocks;          /* Array of bad clusters. */
153         long long nr_bad_blocks;        /* Number of bad clusters. */
154         char *bad_blocks_filename;      /* filename, file to read list of
155                                            bad clusters from. */
156         ATTR_DEF *attr_defs;            /* filename, attribute defs. */
157         int attr_defs_len;              /* in bytes */
158         uchar_t *upcase;                /* filename, upcase table. */
159         u32 upcase_len;                 /* Determined automatically. */
160         int quiet;                      /* -q, quiet execution. */
161         int verbose;                    /* -v, verbose execution, given twice,
162                                          * really verbose execution (debug
163                                          * mode). */
164         int force;                      /* -F, force fs creation. */
165         char quick_format;              /* -f or -Q, fast format, don't zero
166                                            the volume first. */
167         char enable_compression;        /* -C, enables compression of all files
168                                            on the volume by default. */
169         char disable_indexing;          /* -I, disables indexing of file
170                                            contents on the volume by default. */
171                                         /* -V, print version and exit. */
172 } opts;
173
174 /**
175  * Dprintf - debugging output (-vv); overriden by quiet (-q)
176  */
177 void Dprintf(const char *fmt, ...)
178 {
179         va_list ap;
180
181         if (!opts.quiet && opts.verbose > 1) {
182                 printf("DEBUG: ");
183                 va_start(ap, fmt);
184                 vprintf(fmt, ap);
185                 va_end(ap);
186         }
187 }
188
189 /**
190  * Eprintf - error output; ignores quiet (-q)
191  */
192 void Eprintf(const char *fmt, ...)
193 {
194         va_list ap;
195
196         fprintf(stderr, "ERROR: ");
197         va_start(ap, fmt);
198         vfprintf(stderr, fmt, ap);
199         va_end(ap);
200 }
201
202 /* Generate code for Vprintf() function: Verbose output (-v). */
203 GEN_PRINTF(Vprintf, stdout, &opts.verbose, TRUE)
204
205 /* Generate code for Qprintf() function: Quietable output (if not -q). */
206 GEN_PRINTF(Qprintf, stdout, &opts.quiet,   FALSE)
207
208 /**
209  * err_exit - error output and terminate; ignores quiet (-q)
210  */
211 void err_exit(const char *fmt, ...)
212 {
213         va_list ap;
214
215         fprintf(stderr, "ERROR: ");
216         va_start(ap, fmt);
217         vfprintf(stderr, fmt, ap);
218         va_end(ap);
219         fprintf(stderr, "Aborting...\n");
220         exit(1);
221
222 }
223
224 /**
225  * copyright - print copyright statements
226  */
227 void copyright(void)
228 {
229         fprintf(stderr, "Copyright (c) 2000-2003 Anton Altaparmakov\n"
230                         "Copyright (c) 2001-2003 Richard Russon\n"
231                         "Create an NTFS volume on a user specified (block) "
232                         "device.\n");
233 }
234
235 /**
236  * license - print license statement
237  */
238 void license(void)
239 {
240         fprintf(stderr, "%s", ntfs_gpl);
241 }
242
243 /**
244  * usage - print a list of the parameters to the program
245  */
246 void usage(void) __attribute__ ((noreturn));
247 void usage(void)
248 {
249         copyright();
250         fprintf(stderr, "Usage: %s [options] device "
251                         "[number-of-sectors]\n"
252                         "    -s sector-size           Specify the sector size "
253                         "for the device\n"
254                         "    -c cluster-size          Specify the cluster "
255                         "size for the volume\n"
256                         "    -L volume-label          Set the volume label\n"
257                         "    -z mft-zone-multiplier   Set the MFT zone "
258                         "multiplier\n"
259                         "    -f                       Perform a quick format\n"
260                         "    -Q                       Perform a quick format\n"
261                         "    -C                       Enable compression on "
262                         "the volume\n"
263                         "    -I                       Disable indexing on the "
264                         "volume\n"
265                         "    -n                       Do not write to disk\n"
266                         "    -F                       Force execution despite "
267                         "errors\n"
268                         "    -q                       Quiet execution\n"
269                         "    -v                       Verbose execution\n"
270                         "    -vv                      Very verbose execution\n"
271                         "    -V                       Display version "
272                         "information\n"
273                         "    -l                       Display licensing "
274                         "information\n"
275                         "    -h                       Display this help\n",
276                         EXEC_NAME);
277         fprintf(stderr, "%s%s", ntfs_bugs, ntfs_home);
278         exit(1);
279 }
280
281 /**
282  * parse_options
283  */
284 void parse_options(int argc, char *argv[])
285 {
286         int c;
287         long l;
288         unsigned long u;
289         char *s;
290
291 // Need to have: mft record size, index record size, ntfs version, mft size,
292 //               logfile size, list of bad blocks, check for bad blocks, ...
293         if (argc && *argv)
294                 EXEC_NAME = *argv;
295         fprintf(stderr, "%s v%s\n", EXEC_NAME, VERSION);
296         while ((c = getopt(argc, argv, "c:fh?nqs:vz:CFIL:QVl")) != EOF)
297                 switch (c) {
298                 case 'n':
299                         opts.no_action = 1;
300                         break;
301                 case 'c':
302                         l = strtol(optarg, &s, 0);
303                         if (!l || l > INT_MAX || *s)
304                                 err_exit("Invalid cluster size.\n");
305                         vol->cluster_size = l;
306                         break;
307                 case 'f':
308                 case 'Q':
309                         opts.quick_format = 1;
310                         break;
311                 case 'q':
312                         opts.quiet = 1;
313                         break;
314                 case 's':
315                         l = strtol(optarg, &s, 0);
316                         if (!l || l > INT_MAX || *s)
317                                 err_exit("Invalid sector size.\n");
318                         opts.sector_size = l;
319                         break;
320                 case 'v':
321                         opts.verbose++;
322                         break;
323                 case 'z':
324                         l = strtol(optarg, &s, 0);
325                         if (l < 1 || l > 4 || *s)
326                                 err_exit("Invalid MFT zone multiplier.\n");
327                         opts.mft_zone_multiplier = l;
328                         break;
329                 case 'C':
330                         opts.enable_compression = 1;
331                         break;
332                 case 'F':
333                         opts.force = 1;
334                         break;
335                 case 'I':
336                         opts.disable_indexing = 1;
337                         break;
338                 case 'L':
339                         vol->vol_name = optarg;
340                         break;
341                 case 'V':
342                         /* Version number already printed, so just exit. */
343                         exit(0);
344                 case 'l':
345                         copyright();
346                         license();
347                         exit(0);
348                 case 'h':
349                 case '?':
350                 default:
351                         usage();
352                 }
353         if (optind == argc)
354                 usage();
355         dev_name = argv[optind++];
356         if (optind < argc) {
357                 u = strtoul(argv[optind++], &s, 0);
358                 if (*s || !u || (u >= ULONG_MAX && errno == ERANGE))
359                         err_exit("Invalid number of sectors: %s\n",
360                                         argv[optind - 1]);
361                 opts.nr_sectors = u;
362         }
363         if (optind < argc)
364                 usage();
365 }
366
367 /**
368  * append_to_bad_blocks
369  */
370 void append_to_bad_blocks(unsigned long block)
371 {
372         long long *new_buf;
373
374         if (!(opts.nr_bad_blocks & 15)) {
375                 new_buf = realloc(opts.bad_blocks, (opts.nr_bad_blocks + 16) *
376                                                         sizeof(long long));
377                 if (!new_buf)
378                         err_exit("Reallocating memory for bad blocks list "
379                                  "failed: %s\n", strerror(errno));
380                 if (opts.bad_blocks != new_buf)
381                         free(opts.bad_blocks);
382                 opts.bad_blocks = new_buf;
383         }
384         opts.bad_blocks[opts.nr_bad_blocks++] = block;
385 }
386
387 /**
388  * mkntfs_write
389  */
390 __inline__ long long mkntfs_write(struct ntfs_device *dev, const void *buf,
391                 long long count)
392 {
393         long long bytes_written, total;
394         int retry;
395
396         if (opts.no_action)
397                 return count;
398         total = 0LL;
399         retry = 0;
400         do {
401                 bytes_written = dev->d_ops->write(dev, buf, count);
402                 if (bytes_written == -1LL) {
403                         retry = errno;
404                         Eprintf("Error writing to %s: %s\n", vol->dev->d_name,
405                                         strerror(errno));
406                         errno = retry;
407                         return bytes_written;
408                 } else if (!bytes_written)
409                         ++retry;
410                 else {
411                         count -= bytes_written;
412                         total += bytes_written;
413                 }
414         } while (count && retry < 3);
415         if (count)
416                 Eprintf("Failed to complete writing to %s after three retries."
417                         "\n", vol->dev->d_name);
418         return total;
419 }
420
421 /**
422  * Write to disk the clusters contained in the runlist @rl taking the data
423  * from @val. Take @val_len bytes from @val and pad the rest with zeroes.
424  *
425  * If the @rl specifies a completely sparse file, @val is allowed to be NULL.
426  *
427  * @inited_size if not NULL points to an output variable which will contain
428  * the actual number of bytes written to disk. I.e. this will not include
429  * sparse bytes for example.
430  *
431  * Return the number of bytes written (minus padding) or -1 on error. Errno
432  * will be set to the error code.
433  */
434 s64 ntfs_rlwrite(struct ntfs_device *dev, const runlist *rl, const char *val,
435                 const s64 val_len, s64 *inited_size)
436 {
437         s64 bytes_written, total, length, delta;
438         int retry, i;
439
440         if (inited_size)
441                 *inited_size = 0LL;
442         if (opts.no_action)
443                 return val_len;
444         total = delta = 0LL;
445         for (i = 0; rl[i].length; i++) {
446                 length = rl[i].length * vol->cluster_size;
447                 /* Don't write sparse runs. */
448                 if (rl[i].lcn == -1) {
449                         total += length;
450                         if (!val)
451                                 continue;
452                         // TODO: Check that *val is really zero at pos and len.
453                         continue;
454                 }
455                 if (dev->d_ops->seek(dev, rl[i].lcn * vol->cluster_size,
456                                 SEEK_SET) == (off_t)-1)
457                         return -1LL;
458                 retry = 0;
459                 do {
460                         if (total + length > val_len) {
461                                 delta = length;
462                                 length = val_len - total;
463                                 delta -= length;
464                         }
465                         bytes_written = dev->d_ops->write(dev, val + total,
466                                         length);
467                         if (bytes_written == -1LL) {
468                                 retry = errno;
469                                 Eprintf("Error writing to %s: %s\n",
470                                                 vol->dev->d_name,
471                                                 strerror(errno));
472                                 errno = retry;
473                                 return bytes_written;
474                         }
475                         if (bytes_written) {
476                                 length -= bytes_written;
477                                 total += bytes_written;
478                                 if (inited_size)
479                                         *inited_size += bytes_written;
480                         } else
481                                 ++retry;
482                 } while (length && retry < 3);
483                 if (length) {
484                         Eprintf("Failed to complete writing to %s after three "
485                                         "retries.\n", vol->dev->d_name);
486                         return total;
487                 }
488         }
489         if (delta) {
490                 char *buf = (char*)calloc(1, delta);
491                 if (!buf)
492                         err_exit("Error allocating internal buffer: "
493                                         "%s\n", strerror(errno));
494                 bytes_written = mkntfs_write(dev, buf, delta);
495                 free(buf);
496                 if (bytes_written == -1LL)
497                         return bytes_written;
498         }
499         return total;
500 }
501
502 /**
503  * ucstos - convert unicode-character string to ASCII
504  * @dest:       points to buffer to receive the converted string
505  * @src:        points to string to convert
506  * @maxlen:     size of @dest buffer in bytes
507  *
508  * Return the number of characters written to @dest, not including the
509  * terminating null byte. If a unicode character was encountered which could
510  * not be converted -1 is returned.
511  */
512 int ucstos(char *dest, const uchar_t *src, int maxlen)
513 {
514         uchar_t u;
515         int i;
516
517         /* Need one byte for null terminator. */
518         maxlen--;
519         for (i = 0; i < maxlen; i++) {
520                 u = le16_to_cpu(src[i]);
521                 if (!u)
522                         break;
523                 if (u & 0xff00)
524                         return -1;
525                 dest[i] = u & 0xff;
526         }
527         dest[i] = 0;
528         return i;
529 }
530
531 /**
532  * stoucs - convert ASCII string to unicode-character string
533  * @dest:       points to buffer to receive the converted string
534  * @src:        points to string to convert
535  * @maxlen:     size of @dest buffer in bytes
536  *
537  * Return the number of characters written to @dest, not including the
538  * terminating null unicode character.
539  */
540 int stoucs(uchar_t *dest, const char *src, int maxlen)
541 {
542         char c;
543         int i;
544
545         /* Need two bytes for null terminator. */
546         maxlen -= 2;
547         for (i = 0; i < maxlen; i++) {
548                 c = src[i];
549                 if (!c)
550                         break;
551                 dest[i] = cpu_to_le16(c);
552         }
553         dest[i] = cpu_to_le16('\0');
554         return i;
555 }
556
557 /**
558  * dump_resident_attr_val
559  */
560 void dump_resident_attr_val(ATTR_TYPES type, char *val, u32 val_len)
561 {
562         const char *don_t_know = "Don't know what to do with this attribute "
563                         "type yet.";
564         const char *skip = "Skipping display of $%s attribute value.\n";
565         const char *todo = "This is still work in progress.";
566         char *buf;
567         int i, j;
568
569         switch (type) {
570         case AT_STANDARD_INFORMATION:
571                 // TODO
572                 printf("%s\n", todo);
573                 return;
574         case AT_ATTRIBUTE_LIST:
575                 // TODO
576                 printf("%s\n", todo);
577                 return;
578         case AT_FILE_NAME:
579                 // TODO
580                 printf("%s\n", todo);
581                 return;
582         case AT_OBJECT_ID:
583                 // TODO
584                 printf("%s\n", todo);
585                 return;
586         case AT_SECURITY_DESCRIPTOR:
587                 // TODO
588                 printf("%s\n", todo);
589                 return;
590         case AT_VOLUME_NAME:
591                 printf("Volume name length = %i\n", val_len);
592                 if (val_len) {
593                         buf = calloc(1, val_len);
594                         if (!buf)
595                                 err_exit("Failed to allocate internal buffer: "
596                                                 "%s\n", strerror(errno));
597                         i = ucstos(buf, (uchar_t*)val, val_len);
598                         if (i == -1)
599                                 printf("Volume name contains non-displayable "
600                                                 "Unicode characters.\n");
601                         printf("Volume name = %s\n", buf);
602                         free(buf);
603                 }
604                 return;
605         case AT_VOLUME_INFORMATION:
606 #define VOL_INF(x) ((VOLUME_INFORMATION *)(x))
607                 printf("NTFS version %i.%i\n", VOL_INF(val)->major_ver,
608                                 VOL_INF(val)->minor_ver);
609                 i = VOL_INF(val)->flags;
610 #undef VOL_INF
611                 printf("Volume flags = 0x%x: ", i);
612                 if (!i) {
613                         printf("NONE\n");
614                         return;
615                 }
616                 j = 0;
617                 if (i & VOLUME_MODIFIED_BY_CHKDSK) {
618                         j = 1;
619                         printf("VOLUME_MODIFIED_BY_CHKDSK");
620                 }
621                 if (i & VOLUME_REPAIR_OBJECT_ID) {
622                         if (j)
623                                 printf(" | ");
624                         else
625                                 j = 0;
626                         printf("VOLUME_REPAIR_OBJECT_ID");
627                 }
628                 if (i & VOLUME_DELETE_USN_UNDERWAY) {
629                         if (j)
630                                 printf(" | ");
631                         else
632                                 j = 0;
633                         printf("VOLUME_DELETE_USN_UNDERWAY");
634                 }
635                 if (i & VOLUME_MOUNTED_ON_NT4) {
636                         if (j)
637                                 printf(" | ");
638                         else
639                                 j = 0;
640                         printf("VOLUME_MOUNTED_ON_NT4");
641                 }
642                 if (i & VOLUME_UPGRADE_ON_MOUNT) {
643                         if (j)
644                                 printf(" | ");
645                         else
646                                 j = 0;
647                         printf("VOLUME_UPGRADE_ON_MOUNT");
648                 }
649                 if (i & VOLUME_RESIZE_LOG_FILE) {
650                         if (j)
651                                 printf(" | ");
652                         else
653                                 j = 0;
654                         printf("VOLUME_RESIZE_LOG_FILE");
655                 }
656                 if (i & VOLUME_IS_DIRTY) {
657                         if (j)
658                                 printf(" | ");
659                         else
660                                 j = 0;
661                         printf("VOLUME_IS_DIRTY");
662                 }
663                 printf("\n");
664                 return;
665         case AT_DATA:
666                 printf(skip, "DATA");
667                 return;
668         case AT_INDEX_ROOT:
669                 // TODO
670                 printf("%s\n", todo);
671                 return;
672         case AT_INDEX_ALLOCATION:
673                 // TODO
674                 printf("%s\n", todo);
675                 return;
676         case AT_BITMAP:
677                 printf(skip, "BITMAP");
678                 return;
679         case AT_REPARSE_POINT:
680                 // TODO
681                 printf("%s\n", todo);
682                 return;
683         case AT_EA_INFORMATION:
684                 // TODO
685                 printf("%s\n", don_t_know);
686                 return;
687         case AT_EA:
688                 // TODO
689                 printf("%s\n", don_t_know);
690                 return;
691         case AT_LOGGED_UTILITY_STREAM:
692                 // TODO
693                 printf("%s\n", don_t_know);
694                 return;
695         default:
696                 i = le32_to_cpu(type);
697                 printf("Cannot display unknown %s defined attribute type 0x%x"
698                                 ".\n", i >=
699                                 le32_to_cpu(AT_FIRST_USER_DEFINED_ATTRIBUTE) ?
700                                 "user" : "system", i);
701         }
702 }
703
704 /**
705  * dump_resident_attr
706  */
707 void dump_resident_attr(ATTR_RECORD *a)
708 {
709         int i;
710
711         i = le32_to_cpu(a->value_length);
712         printf("Attribute value length = %u (0x%x)\n", i, i);
713         i = le16_to_cpu(a->value_offset);
714         printf("Attribute value offset = %u (0x%x)\n", i, i);
715         i = a->resident_flags;
716         printf("Resident flags = 0x%x: ", i);
717         if (!i)
718                 printf("NONE\n");
719         else if (i & ~RESIDENT_ATTR_IS_INDEXED)
720                 printf("UNKNOWN FLAG(S)\n");
721         else
722                 printf("RESIDENT_ATTR_IS_INDEXED\n");
723         dump_resident_attr_val(a->type, (char*)a + le16_to_cpu(a->value_offset),
724                         le32_to_cpu(a->value_length));
725 }
726
727 /**
728  * dump_mapping_pairs_array
729  */
730 void dump_mapping_pairs_array(char *b, unsigned int max_len)
731 {
732         // TODO
733         return;
734 }
735
736 /**
737  * dump_non_resident_attr
738  */
739 void dump_non_resident_attr(ATTR_RECORD *a)
740 {
741         s64 l;
742         int i;
743
744         l = sle64_to_cpu(a->lowest_vcn);
745         printf("Lowest VCN = %Li (0x%Lx)\n", l, l);
746         l = sle64_to_cpu(a->highest_vcn);
747         printf("Highest VCN = %Li (0x%Lx)\n", l, l);
748         printf("Mapping pairs array offset = 0x%x\n",
749                         le16_to_cpu(a->mapping_pairs_offset));
750         printf("Compression unit = 0x%x: %sCOMPRESSED\n", a->compression_unit,
751                         a->compression_unit ? "" : "NOT ");
752         if (sle64_to_cpu(a->lowest_vcn))
753                 printf("Attribute is not the first extent. The following "
754                                 "sizes are meaningless:\n");
755         l = sle64_to_cpu(a->allocated_size);
756         printf("Allocated size = %Li (0x%Lx)\n", l, l);
757         l = sle64_to_cpu(a->data_size);
758         printf("Data size = %Li (0x%Lx)\n", l, l);
759         l = sle64_to_cpu(a->initialized_size);
760         printf("Initialized size = %Li (0x%Lx)\n", l, l);
761         if (a->flags & ATTR_COMPRESSION_MASK) {
762                 l = sle64_to_cpu(a->compressed_size);
763                 printf("Compressed size = %Li (0x%Lx)\n", l, l);
764         }
765         i = le16_to_cpu(a->mapping_pairs_offset);
766         dump_mapping_pairs_array((char*)a + i, le32_to_cpu(a->length) - i);
767 }
768
769 /**
770  * dump_attr_record
771  */
772 void dump_attr_record(ATTR_RECORD *a)
773 {
774         unsigned int u;
775         char s[0x200];
776         int i;
777
778         printf("-- Beginning dump of attribute record. --\n");
779         if (a->type == AT_END) {
780                 printf("Attribute type = 0x%x ($END)\n", le32_to_cpu(AT_END));
781                 u = le32_to_cpu(a->length);
782                 printf("Length of resident part = %u (0x%x)\n", u, u);
783                 return;
784         }
785         u = le32_to_cpu(a->type);
786         for (i = 0; opts.attr_defs[i].type; i++)
787                 if (le32_to_cpu(opts.attr_defs[i].type) >= u)
788                         break;
789         if (opts.attr_defs[i].type) {
790 //              printf("type = 0x%x\n", le32_to_cpu(opts.attr_defs[i].type));
791 //              { char *p = (char*)opts.attr_defs[i].name;
792 //              printf("name = %c%c%c%c%c\n", *p, p[1], p[2], p[3], p[4]);
793 //              }
794                 if (ucstos(s, opts.attr_defs[i].name, sizeof(s)) == -1) {
795                         Eprintf("Could not convert Unicode string to single "
796                                 "byte string in current locale.\n");
797                         strncpy(s, "Error converting Unicode string",
798                                         sizeof(s));
799                 }
800         } else
801                 strncpy(s, "UNKNOWN_TYPE", sizeof(s));
802         printf("Attribute type = 0x%x (%s)\n", u, s);
803         u = le32_to_cpu(a->length);
804         printf("Length of resident part = %u (0x%x)\n", u, u);
805         printf("Attribute is %sresident\n", a->non_resident ? "non-" : "");
806         printf("Name length = %u unicode characters\n", a->name_length);
807         printf("Name offset = %u (0x%x)\n", cpu_to_le16(a->name_offset),
808                         cpu_to_le16(a->name_offset));
809         u = a->flags;
810         if (a->name_length) {
811                 if (ucstos(s, (uchar_t*)((char*)a +
812                                 cpu_to_le16(a->name_offset)),
813                                 min(sizeof(s), a->name_length + 1)) == -1) {
814                         Eprintf("Could not convert Unicode string to single "
815                                 "byte string in current locale.\n");
816                         strncpy(s, "Error converting Unicode string",
817                                         sizeof(s));
818
819                 }
820                 printf("Name = %s\n", s);
821         }
822         printf("Attribute flags = 0x%x: ", le16_to_cpu(u));
823         if (!u)
824                 printf("NONE");
825         else {
826                 int first = TRUE;
827                 if (u & ATTR_COMPRESSION_MASK) {
828                         if (u & ATTR_IS_COMPRESSED) {
829                                 printf("ATTR_IS_COMPRESSED");
830                                 first = FALSE;
831                         }
832                         if ((u & ATTR_COMPRESSION_MASK) & ~ATTR_IS_COMPRESSED) {
833                                 if (!first)
834                                         printf(" | ");
835                                 else
836                                         first = FALSE;
837                                 printf("ATTR_UNKNOWN_COMPRESSION");
838                         }
839                 }
840                 if (u & ATTR_IS_ENCRYPTED) {
841                         if (!first)
842                                 printf(" | ");
843                         else
844                                 first = FALSE;
845                         printf("ATTR_IS_ENCRYPTED");
846                 }
847                 if (u & ATTR_IS_SPARSE) {
848                         if (!first)
849                                 printf(" | ");
850                         else
851                                 first = FALSE;
852                         printf("ATTR_IS_SPARSE");
853                 }
854         }
855         printf("\n");
856         printf("Attribute instance = %u\n", le16_to_cpu(a->instance));
857         if (a->non_resident) {
858                 dump_non_resident_attr(a);
859         } else {
860                 dump_resident_attr(a);
861         }
862 }
863
864 /**
865  * dump_mft_record
866  */
867 void dump_mft_record(MFT_RECORD *m)
868 {
869         ATTR_RECORD *a;
870         unsigned int u;
871         MFT_REF r;
872
873         printf("-- Beginning dump of mft record. --\n");
874         u = le32_to_cpu(m->magic);
875         printf("Mft record signature (magic) = %c%c%c%c\n", u & 0xff,
876                         u >> 8 & 0xff, u >> 16 & 0xff, u >> 24 & 0xff);
877         u = le16_to_cpu(m->usa_ofs);
878         printf("Update sequence array offset = %u (0x%x)\n", u, u);
879         printf("Update sequence array size = %u\n", le16_to_cpu(m->usa_count));
880         printf("$LogFile sequence number (lsn) = %Lu\n", le64_to_cpu(m->lsn));
881         printf("Sequence number = %u\n", le16_to_cpu(m->sequence_number));
882         printf("Reference (hard link) count = %u\n",
883                                                 le16_to_cpu(m->link_count));
884         u = le16_to_cpu(m->attrs_offset);
885         printf("First attribute offset = %u (0x%x)\n", u, u);
886         printf("Flags = %u: ", le16_to_cpu(m->flags));
887         if (m->flags & MFT_RECORD_IN_USE)
888                 printf("MFT_RECORD_IN_USE");
889         else
890                 printf("MFT_RECORD_NOT_IN_USE");
891         if (m->flags & MFT_RECORD_IS_DIRECTORY)
892                 printf(" | MFT_RECORD_IS_DIRECTORY");
893         printf("\n");
894         u = le32_to_cpu(m->bytes_in_use);
895         printf("Bytes in use = %u (0x%x)\n", u, u);
896         u = le32_to_cpu(m->bytes_allocated);
897         printf("Bytes allocated = %u (0x%x)\n", u, u);
898         r = le64_to_cpu(m->base_mft_record);
899         printf("Base mft record reference:\n\tMft record number = %Lu\n\t"
900                         "Sequence number = %u\n", MREF(r), MSEQNO(r));
901         printf("Next attribute instance = %u\n",
902                         le16_to_cpu(m->next_attr_instance));
903         a = (ATTR_RECORD*)((char*)m + le16_to_cpu(m->attrs_offset));
904         printf("-- Beginning dump of attributes within mft record. --\n");
905         while ((char*)a < (char*)m + le32_to_cpu(m->bytes_in_use)) {
906                 dump_attr_record(a);
907                 if (a->type == AT_END)
908                         break;
909                 a = (ATTR_RECORD*)((char*)a + le32_to_cpu(a->length));
910         };
911         printf("-- End of attributes. --\n");
912 }
913
914 /**
915  * format_mft_record
916  */
917 void format_mft_record(MFT_RECORD *m)
918 {
919         ATTR_RECORD *a;
920
921         memset(m, 0, vol->mft_record_size);
922         m->magic = magic_FILE;
923         /* Aligned to 2-byte boundary. */
924         m->usa_ofs = cpu_to_le16((sizeof(MFT_RECORD) + 1) & ~1);
925         if (vol->mft_record_size >= NTFS_SECTOR_SIZE)
926                 m->usa_count = cpu_to_le16(vol->mft_record_size /
927                                 NTFS_SECTOR_SIZE + 1);
928         else {
929                 m->usa_count = cpu_to_le16(1);
930                 Qprintf("Sector size is bigger than MFT record size. Setting "
931                         "usa_count to 1. If Windows\nchkdsk reports this as "
932                         "corruption, please email linux-ntfs-dev@lists.sf.net\n"
933                         "stating that you saw this message and that the file "
934                         "system created was corrupt.\nThank you.");
935         }
936         /* Set the update sequence number to 1. */
937         *(u16*)((char*)m + ((sizeof(MFT_RECORD) + 1) & ~1)) = cpu_to_le16(1);
938         m->lsn = cpu_to_le64(0LL);
939         m->sequence_number = cpu_to_le16(1);
940         m->link_count = cpu_to_le16(0);
941         /* Aligned to 8-byte boundary. */
942         m->attrs_offset = cpu_to_le16((le16_to_cpu(m->usa_ofs) +
943                         (le16_to_cpu(m->usa_count) << 1) + 7) & ~7);
944         m->flags = cpu_to_le16(0);
945         /*
946          * Using attrs_offset plus eight bytes (for the termination attribute),
947          * aligned to 8-byte boundary.
948          */
949         m->bytes_in_use = cpu_to_le32((le16_to_cpu(m->attrs_offset) + 8 + 7) &
950                         ~7);
951         m->bytes_allocated = cpu_to_le32(vol->mft_record_size);
952         m->base_mft_record = cpu_to_le64((MFT_REF)0);
953         m->next_attr_instance = cpu_to_le16(0);
954         a = (ATTR_RECORD*)((char*)m + le16_to_cpu(m->attrs_offset));
955         a->type = AT_END;
956         a->length = cpu_to_le32(0);
957 #if 0
958         if (!opts.quiet && opts.verbose > 1)
959                 dump_mft_record(m);
960 #endif
961 }
962
963 /**
964  * make_room_for_attribute - make room for an attribute inside an mft record
965  * @m:          mft record
966  * @pos:        position at which to make space
967  * @size:       byte size to make available at this position
968  *
969  * @pos points to the attribute in front of which we want to make space.
970  *
971  * Return 0 on success or -errno on error. Possible error codes are:
972  *
973  *      -ENOSPC         There is not enough space available to complete
974  *                      operation. The caller has to make space before calling
975  *                      this.
976  *      -EINVAL         Can only occur if mkntfs was compiled with -DEBUG. Means
977  *                      the input parameters were faulty.
978  */
979 int make_room_for_attribute(MFT_RECORD *m, char *pos, const u32 size)
980 {
981         u32 biu;
982
983         if (!size)
984                 return 0;
985 #ifdef DEBUG
986         /*
987          * Rigorous consistency checks. Always return -EINVAL even if more
988          * appropriate codes exist for simplicity of parsing the return value.
989          */
990         if (size != ((size + 7) & ~7)) {
991                 Eprintf("make_room_for_attribute() received non 8-byte aligned"
992                                 "size.\n");
993                 return -EINVAL;
994         }
995         if (!m || !pos)
996                 return -EINVAL;
997         if (pos < (char*)m || pos + size < (char*)m ||
998                         pos > (char*)m + le32_to_cpu(m->bytes_allocated) ||
999                         pos + size > (char*)m + le32_to_cpu(m->bytes_allocated))
1000                 return -EINVAL;
1001         /* The -8 is for the attribute terminator. */
1002         if (pos - (char*)m > le32_to_cpu(m->bytes_in_use) - 8)
1003                 return -EINVAL;
1004 #endif
1005         biu = le32_to_cpu(m->bytes_in_use);
1006         /* Do we have enough space? */
1007         if (biu + size > le32_to_cpu(m->bytes_allocated))
1008                 return -ENOSPC;
1009         /* Move everything after pos to pos + size. */
1010         memmove(pos + size, pos, biu - (pos - (char*)m));
1011         /* Update mft record. */
1012         m->bytes_in_use = cpu_to_le32(biu + size);
1013         return 0;
1014 }
1015
1016 /**
1017  * deallocate_scattered_clusters
1018  */
1019 void deallocate_scattered_clusters(const runlist *rl)
1020 {
1021         LCN j;
1022         int i;
1023
1024         if (!rl)
1025                 return;
1026         /* Iterate over all runs in the runlist @rl. */
1027         for (i = 0; rl[i].length; i++) {
1028                 /* Skip sparse runs. */
1029                 if (rl[i].lcn == -1LL)
1030                         continue;
1031                 /* Deallocate the current run. */
1032                 for (j = rl[i].lcn; j < rl[i].lcn + rl[i].length; j++)
1033                         ntfs_bit_set(lcn_bitmap, j, 0);
1034         }
1035 }
1036
1037 /**
1038  * allocate_scattered_clusters
1039  * Allocate @clusters and create a runlist of the allocated clusters.
1040  *
1041  * Return the allocated runlist. Caller has to free the runlist when finished
1042  * with it.
1043  *
1044  * On error return NULL and errno is set to the error code.
1045  *
1046  * TODO: We should be returning the size as well, but for mkntfs this is not
1047  * necessary.
1048  */
1049 runlist *allocate_scattered_clusters(s64 clusters)
1050 {
1051         runlist *rl = NULL, *rlt;
1052         VCN vcn = 0LL;
1053         LCN lcn, end, prev_lcn = 0LL;
1054         int rlpos = 0;
1055         int rlsize = 0;
1056         s64 prev_run_len = 0LL;
1057         char bit;
1058
1059         end = opts.nr_clusters;
1060         /* Loop until all clusters are allocated. */
1061         while (clusters) {
1062                 /* Loop in current zone until we run out of free clusters. */
1063                 for (lcn = opts.mft_zone_end; lcn < end; lcn++) {
1064                         bit = ntfs_bit_get_and_set(lcn_bitmap, lcn, 1);
1065                         if (bit)
1066                                 continue;
1067                         /*
1068                          * Reallocate memory if necessary. Make sure we have
1069                          * enough for the terminator entry as well.
1070                          */
1071                         if ((rlpos + 2) * sizeof(runlist) >= rlsize) {
1072                                 rlsize += 4096; /* PAGE_SIZE */
1073                                 rlt = realloc(rl, rlsize);
1074                                 if (!rlt)
1075                                         goto err_end;
1076                                 rl = rlt;
1077                         }
1078                         /* Coalesce with previous run if adjacent LCNs. */
1079                         if (prev_lcn == lcn - prev_run_len) {
1080                                 rl[rlpos - 1].length = ++prev_run_len;
1081                                 vcn++;
1082                         } else {
1083                                 rl[rlpos].vcn = vcn++;
1084                                 rl[rlpos].lcn = prev_lcn = lcn;
1085                                 rl[rlpos].length = prev_run_len = 1LL;
1086                                 rlpos++;
1087                         }
1088                         /* Done? */
1089                         if (!--clusters) {
1090                                 /* Add terminator element and return. */
1091                                 rl[rlpos].vcn = vcn;
1092                                 rl[rlpos].lcn = rl[rlpos].length = 0LL;
1093                                 return rl;
1094                         }
1095
1096                 }
1097                 /* Switch to next zone, decreasing mft zone by factor 2. */
1098                 end = opts.mft_zone_end;
1099                 opts.mft_zone_end >>= 1;
1100                 /* Have we run out of space on the volume? */
1101                 if (opts.mft_zone_end <= 0)
1102                         goto err_end;
1103         }
1104         return rl;
1105 err_end:
1106         if (rl) {
1107                 /* Add terminator element. */
1108                 rl[rlpos].vcn = vcn;
1109                 rl[rlpos].lcn = -1LL;
1110                 rl[rlpos].length = 0LL;
1111                 /* Deallocate all allocated clusters. */
1112                 deallocate_scattered_clusters(rl);
1113                 /* Free the runlist. */
1114                 free(rl);
1115         }
1116         return NULL;
1117 }
1118
1119 /**
1120  * insert_positioned_attr_in_mft_record
1121  * Create a non-resident attribute with a predefined on disk location
1122  * specified by the runlist @rl. The clusters specified by @rl are assumed to
1123  * be allocated already.
1124  *
1125  * Return 0 on success and -errno on error.
1126  */
1127 int insert_positioned_attr_in_mft_record(MFT_RECORD *m, const ATTR_TYPES type,
1128                 const char *name, u32 name_len, const IGNORE_CASE_BOOL ic,
1129                 const ATTR_FLAGS flags, const runlist *rl,
1130                 const char *val, const s64 val_len)
1131 {
1132         ntfs_attr_search_ctx *ctx;
1133         ATTR_RECORD *a;
1134         u16 hdr_size;
1135         int asize, mpa_size, err, i;
1136         s64 bw = 0, inited_size;
1137         VCN highest_vcn;
1138         uchar_t *uname;
1139 /*
1140         if (base record)
1141                 attr_lookup();
1142         else
1143 */
1144         if (name_len) {
1145                 i = (name_len + 1) * sizeof(uchar_t);
1146                 uname = (uchar_t*)calloc(1, i);
1147                 if (!uname)
1148                         return -errno;
1149                 name_len = stoucs(uname, name, i);
1150                 if (name_len > 0xff) {
1151                         free(uname);
1152                         return -ENAMETOOLONG;
1153                 }
1154         } else
1155                 uname = NULL;
1156         /* Check if the attribute is already there. */
1157         ctx = ntfs_attr_get_search_ctx(NULL, m);
1158         if (!ctx) {
1159                 Eprintf("Failed to allocate attribute search context.\n");
1160                 err = -ENOMEM;
1161                 goto err_out;
1162         }
1163         if (ic == IGNORE_CASE) {
1164                 Eprintf("FIXME: Hit unimplemented code path #1.\n");
1165                 err = -ENOTSUP;
1166                 goto err_out;
1167         }
1168         if (!ntfs_attr_lookup(type, uname, name_len, ic, 0, NULL, 0, ctx)) {
1169                 err = -EEXIST;
1170                 goto err_out;
1171         }
1172         if (errno != ENOENT) {
1173                 Eprintf("Corrupt inode.\n");
1174                 err = -errno;
1175                 goto err_out;
1176         }
1177         a = ctx->attr;
1178         if (flags & ATTR_COMPRESSION_MASK) {
1179                 Eprintf("Compressed attributes not supported yet.\n");
1180                 // FIXME: Compress attribute into a temporary buffer, set
1181                 // val accordingly and save the compressed size.
1182                 err = -ENOTSUP;
1183                 goto err_out;
1184         }
1185         if (flags & (ATTR_IS_ENCRYPTED || ATTR_IS_SPARSE)) {
1186                 Eprintf("Encrypted/sparse attributes not supported yet.\n");
1187                 err = -ENOTSUP;
1188                 goto err_out;
1189         }
1190         if (flags & ATTR_COMPRESSION_MASK) {
1191                 hdr_size = 72;
1192                 // FIXME: This compression stuff is all wrong. Never mind for
1193                 // now. (AIA)
1194                 if (val_len)
1195                         mpa_size = 0; //get_size_for_compressed_mapping_pairs(rl);
1196                 else
1197                         mpa_size = 0;
1198         } else {
1199                 hdr_size = 64;
1200                 if (val_len) {
1201                         mpa_size = ntfs_get_size_for_mapping_pairs(vol, rl);
1202                         if (mpa_size < 0) {
1203                                 err = -errno;
1204                                 Eprintf("Failed to get size for mapping "
1205                                                 "pairs.\n");
1206                                 goto err_out;
1207                         }
1208                 } else
1209                         mpa_size = 0;
1210         }
1211         /* Mapping pairs array and next attribute must be 8-byte aligned. */
1212         asize = (((int)hdr_size + ((name_len + 7) & ~7) + mpa_size) + 7) & ~7;
1213         /* Get the highest vcn. */
1214         for (i = 0, highest_vcn = 0LL; rl[i].length; i++)
1215                 highest_vcn += rl[i].length;
1216         /* Does the value fit inside the allocated size? */
1217         if (highest_vcn * vol->cluster_size < val_len) {
1218                 Eprintf("BUG: Allocated size is smaller than data size!\n");
1219                 err = -EINVAL;
1220                 goto err_out;
1221         }
1222         err = make_room_for_attribute(m, (char*)a, asize);
1223         if (err == -ENOSPC) {
1224                 // FIXME: Make space! (AIA)
1225                 // can we make it non-resident? if yes, do that.
1226                 //      does it fit now? yes -> do it.
1227                 // m's $DATA or $BITMAP+$INDEX_ALLOCATION resident?
1228                 // yes -> make non-resident
1229                 //      does it fit now? yes -> do it.
1230                 // make all attributes non-resident
1231                 //      does it fit now? yes -> do it.
1232                 // m is a base record? yes -> allocate extension record
1233                 //      does the new attribute fit in there? yes -> do it.
1234                 // split up runlist into extents and place each in an extension
1235                 // record.
1236                 // FIXME: the check for needing extension records should be
1237                 // earlier on as it is very quick: asize > m->bytes_allocated?
1238                 err = -ENOTSUP;
1239                 goto err_out;
1240         }
1241 #ifdef DEBUG
1242         else if (err == -EINVAL) {
1243                 fprintf(stderr, "BUG(): in insert_positioned_attribute_in_mft_"
1244                                 "record(): make_room_for_attribute() returned "
1245                                 "error: EINVAL!\n");
1246                 goto err_out;
1247         }
1248 #endif
1249         a->type = type;
1250         a->length = cpu_to_le32(asize);
1251         a->non_resident = 1;
1252         a->name_length = name_len;
1253         a->name_offset = cpu_to_le16(hdr_size);
1254         a->flags = flags;
1255         a->instance = m->next_attr_instance;
1256         m->next_attr_instance = cpu_to_le16((le16_to_cpu(m->next_attr_instance)
1257                         + 1) & 0xffff);
1258         a->lowest_vcn = cpu_to_le64(0);
1259         a->highest_vcn = cpu_to_le64(highest_vcn - 1LL);
1260         a->mapping_pairs_offset = cpu_to_le16(hdr_size + ((name_len + 7) & ~7));
1261         memset(a->reserved1, 0, sizeof(a->reserved1));
1262         // FIXME: Allocated size depends on compression.
1263         a->allocated_size = cpu_to_le64(highest_vcn * vol->cluster_size);
1264         a->data_size = cpu_to_le64(val_len);
1265         if (name_len)
1266                 memcpy((char*)a + hdr_size, uname, name_len << 1);
1267         if (flags & ATTR_COMPRESSION_MASK) {
1268                 if (flags & ATTR_COMPRESSION_MASK & ~ATTR_IS_COMPRESSED) {
1269                         Eprintf("Unknown compression format. Reverting to "
1270                                         "standard compression.\n");
1271                         a->flags &= ~ATTR_COMPRESSION_MASK;
1272                         a->flags |= ATTR_IS_COMPRESSED;
1273                 }
1274                 a->compression_unit = 4;
1275                 inited_size = val_len;
1276                 // FIXME: Set the compressed size.
1277                 a->compressed_size = cpu_to_le64(0);
1278                 // FIXME: Write out the compressed data.
1279                 // FIXME: err = build_mapping_pairs_compressed();
1280                 err = -ENOTSUP;
1281         } else {
1282                 a->compression_unit = 0;
1283                 bw = ntfs_rlwrite(vol->dev, rl, val, val_len, &inited_size);
1284                 if (bw != val_len)
1285                         Eprintf("Error writing non-resident attribute value."
1286                                 "\n");
1287                 err = ntfs_mapping_pairs_build(vol, (s8*)a + hdr_size +
1288                                 ((name_len + 7) & ~7), mpa_size, rl);
1289         }
1290         a->initialized_size = cpu_to_le64(inited_size);
1291         if (err < 0 || bw != val_len) {
1292                 // FIXME: Handle error.
1293                 // deallocate clusters
1294                 // remove attribute
1295                 if (err >= 0)
1296                         err = -EIO;
1297                 Eprintf("insert_positioned_attr_in_mft_record failed with "
1298                                 "error %i.\n", err < 0 ? err : (int)bw);
1299         }
1300 err_out:
1301         if (ctx)
1302                 ntfs_attr_put_search_ctx(ctx);
1303         if (uname)
1304                 free(uname);
1305         return err;
1306 }
1307
1308 /**
1309  * insert_non_resident_attr_in_mft_record
1310  * Return 0 on success and -errno on error.
1311  */
1312 int insert_non_resident_attr_in_mft_record(MFT_RECORD *m, const ATTR_TYPES type,
1313                 const char *name, u32 name_len, const IGNORE_CASE_BOOL ic,
1314                 const ATTR_FLAGS flags, const char *val, const s64 val_len)
1315 {
1316         ntfs_attr_search_ctx *ctx;
1317         ATTR_RECORD *a;
1318         u16 hdr_size;
1319         int asize, mpa_size, err, i;
1320         runlist *rl = NULL;
1321         s64 bw = 0;
1322         uchar_t *uname;
1323 /*
1324         if (base record)
1325                 attr_lookup();
1326         else
1327 */
1328         if (name_len) {
1329                 i = (name_len + 1) * sizeof(uchar_t);
1330                 uname = (uchar_t*)calloc(1, i);
1331                 if (!uname)
1332                         return -errno;
1333                 name_len = stoucs(uname, name, i);
1334                 if (name_len > 0xff) {
1335                         free(uname);
1336                         return -ENAMETOOLONG;
1337                 }
1338         } else
1339                 uname = AT_UNNAMED;
1340         /* Check if the attribute is already there. */
1341         ctx = ntfs_attr_get_search_ctx(NULL, m);
1342         if (!ctx) {
1343                 Eprintf("Failed to allocate attribute search context.\n");
1344                 err = -ENOMEM;
1345                 goto err_out;
1346         }
1347         if (ic == IGNORE_CASE) {
1348                 Eprintf("FIXME: Hit unimplemented code path #2.\n");
1349                 err = -ENOTSUP;
1350                 goto err_out;
1351         }
1352         if (!ntfs_attr_lookup(type, uname, name_len, ic, 0, NULL, 0, ctx)) {
1353                 err = -EEXIST;
1354                 goto err_out;
1355         }
1356         if (errno != ENOENT) {
1357                 Eprintf("Corrupt inode.\n");
1358                 err = -errno;
1359                 goto err_out;
1360         }
1361         a = ctx->attr;
1362         if (flags & ATTR_COMPRESSION_MASK) {
1363                 Eprintf("Compressed attributes not supported yet.\n");
1364                 // FIXME: Compress attribute into a temporary buffer, set
1365                 // val accordingly and save the compressed size.
1366                 err = -ENOTSUP;
1367                 goto err_out;
1368         }
1369         if (flags & (ATTR_IS_ENCRYPTED || ATTR_IS_SPARSE)) {
1370                 Eprintf("Encrypted/sparse attributes not supported yet.\n");
1371                 err = -ENOTSUP;
1372                 goto err_out;
1373         }
1374         if (val_len) {
1375                 rl = allocate_scattered_clusters((val_len +
1376                                 vol->cluster_size - 1) / vol->cluster_size);
1377                 if (!rl) {
1378                         err = -errno;
1379                         Eprintf("Failed to allocate scattered clusters: %s\n",
1380                                         strerror(-err));
1381                         goto err_out;
1382                 }
1383         } else
1384                 rl = NULL;
1385         if (flags & ATTR_COMPRESSION_MASK) {
1386                 hdr_size = 72;
1387                 // FIXME: This compression stuff is all wrong. Never mind for
1388                 // now. (AIA)
1389                 if (val_len)
1390                         mpa_size = 0; //get_size_for_compressed_mapping_pairs(rl);
1391                 else
1392                         mpa_size = 0;
1393         } else {
1394                 hdr_size = 64;
1395                 if (val_len) {
1396                         mpa_size = ntfs_get_size_for_mapping_pairs(vol, rl);
1397                         if (mpa_size < 0) {
1398                                 err = -errno;
1399                                 Eprintf("Failed to get size for mapping "
1400                                                 "pairs.\n");
1401                                 goto err_out;
1402                         }
1403                 } else
1404                         mpa_size = 0;
1405         }
1406         /* Mapping pairs array and next attribute must be 8-byte aligned. */
1407         asize = (((int)hdr_size + ((name_len + 7) & ~7) + mpa_size) + 7) & ~7;
1408         err = make_room_for_attribute(m, (char*)a, asize);
1409         if (err == -ENOSPC) {
1410                 // FIXME: Make space! (AIA)
1411                 // can we make it non-resident? if yes, do that.
1412                 //      does it fit now? yes -> do it.
1413                 // m's $DATA or $BITMAP+$INDEX_ALLOCATION resident?
1414                 // yes -> make non-resident
1415                 //      does it fit now? yes -> do it.
1416                 // make all attributes non-resident
1417                 //      does it fit now? yes -> do it.
1418                 // m is a base record? yes -> allocate extension record
1419                 //      does the new attribute fit in there? yes -> do it.
1420                 // split up runlist into extents and place each in an extension
1421                 // record.
1422                 // FIXME: the check for needing extension records should be
1423                 // earlier on as it is very quick: asize > m->bytes_allocated?
1424                 err = -ENOTSUP;
1425                 goto err_out;
1426         }
1427 #ifdef DEBUG
1428         else if (err == -EINVAL) {
1429                 fprintf(stderr, "BUG(): in insert_non_resident_attribute_in_"
1430                                 "mft_record(): make_room_for_attribute() "
1431                                 "returned error: EINVAL!\n");
1432                 goto err_out;
1433         }
1434 #endif
1435         a->type = type;
1436         a->length = cpu_to_le32(asize);
1437         a->non_resident = 1;
1438         a->name_length = name_len;
1439         a->name_offset = cpu_to_le16(hdr_size);
1440         a->flags = flags;
1441         a->instance = m->next_attr_instance;
1442         m->next_attr_instance = cpu_to_le16((le16_to_cpu(m->next_attr_instance)
1443                         + 1) & 0xffff);
1444         a->lowest_vcn = cpu_to_le64(0);
1445         for (i = 0; rl[i].length; i++)
1446                 ;
1447         a->highest_vcn = cpu_to_le64(rl[i].vcn - 1);
1448         a->mapping_pairs_offset = cpu_to_le16(hdr_size + ((name_len + 7) & ~7));
1449         memset(a->reserved1, 0, sizeof(a->reserved1));
1450         // FIXME: Allocated size depends on compression.
1451         a->allocated_size = cpu_to_le64((val_len + (vol->cluster_size - 1)) &
1452                         ~(vol->cluster_size - 1));
1453         a->data_size = cpu_to_le64(val_len);
1454         a->initialized_size = cpu_to_le64(val_len);
1455         if (name_len)
1456                 memcpy((char*)a + hdr_size, uname, name_len << 1);
1457         if (flags & ATTR_COMPRESSION_MASK) {
1458                 if (flags & ATTR_COMPRESSION_MASK & ~ATTR_IS_COMPRESSED) {
1459                         Eprintf("Unknown compression format. Reverting to "
1460                                         "standard compression.\n");
1461                         a->flags &= ~ATTR_COMPRESSION_MASK;
1462                         a->flags |= ATTR_IS_COMPRESSED;
1463                 }
1464                 a->compression_unit = 4;
1465                 // FIXME: Set the compressed size.
1466                 a->compressed_size = cpu_to_le64(0);
1467                 // FIXME: Write out the compressed data.
1468                 // FIXME: err = build_mapping_pairs_compressed();
1469                 err = -ENOTSUP;
1470         } else {
1471                 a->compression_unit = 0;
1472                 bw = ntfs_rlwrite(vol->dev, rl, val, val_len, NULL);
1473                 if (bw != val_len)
1474                         Eprintf("Error writing non-resident attribute value."
1475                                 "\n");
1476                 err = ntfs_mapping_pairs_build(vol, (s8*)a + hdr_size +
1477                                 ((name_len + 7) & ~7), mpa_size, rl);
1478         }
1479         if (err < 0 || bw != val_len) {
1480                 // FIXME: Handle error.
1481                 // deallocate clusters
1482                 // remove attribute
1483                 if (err >= 0)
1484                         err = -EIO;
1485                 Eprintf("insert_non_resident_attr_in_mft_record failed with "
1486                         "error %lld.\n", (long long) (err < 0 ? err : bw));
1487         }
1488 err_out:
1489         if (ctx)
1490                 ntfs_attr_put_search_ctx(ctx);
1491         if (uname && (uname != AT_UNNAMED))
1492                 free(uname);
1493         if (rl)
1494                 free(rl);
1495         return err;
1496 }
1497
1498 /**
1499  * insert_resident_attr_in_mft_record
1500  * Return 0 on success and -errno on error.
1501  */
1502 int insert_resident_attr_in_mft_record(MFT_RECORD *m, const ATTR_TYPES type,
1503                 const char *name, u32 name_len, const IGNORE_CASE_BOOL ic,
1504                 const ATTR_FLAGS flags, const RESIDENT_ATTR_FLAGS res_flags,
1505                 const char *val, const u32 val_len)
1506 {
1507         ntfs_attr_search_ctx *ctx;
1508         ATTR_RECORD *a;
1509         int asize, err, i;
1510         uchar_t *uname;
1511 /*
1512         if (base record)
1513                 ntfs_attr_lookup();
1514         else
1515 */
1516         if (name_len) {
1517                 i = (name_len + 1) * sizeof(uchar_t);
1518                 uname = (uchar_t*)calloc(1, i);
1519                 name_len = stoucs(uname, name, i);
1520                 if (name_len > 0xff)
1521                         return -ENAMETOOLONG;
1522         } else
1523                 uname = AT_UNNAMED;
1524         /* Check if the attribute is already there. */
1525         ctx = ntfs_attr_get_search_ctx(NULL, m);
1526         if (!ctx) {
1527                 Eprintf("Failed to allocate attribute search context.\n");
1528                 err = -ENOMEM;
1529                 goto err_out;
1530         }
1531         if (ic == IGNORE_CASE) {
1532                 Eprintf("FIXME: Hit unimplemented code path #3.\n");
1533                 err = -ENOTSUP;
1534                 goto err_out;
1535         }
1536         if (!ntfs_attr_lookup(type, uname, name_len, ic, 0, val, val_len,
1537                         ctx)) {
1538                 err = -EEXIST;
1539                 goto err_out;
1540         }
1541         if (errno != ENOENT) {
1542                 Eprintf("Corrupt inode.\n");
1543                 err = -errno;
1544                 goto err_out;
1545         }
1546         a = ctx->attr;
1547         /* sizeof(resident attribute record header) == 24 */
1548         asize = ((24 + ((name_len + 7) & ~7) + val_len) + 7) & ~7;
1549         err = make_room_for_attribute(m, (char*)a, asize);
1550         if (err == -ENOSPC) {
1551                 // FIXME: Make space! (AIA)
1552                 // can we make it non-resident? if yes, do that.
1553                 //      does it fit now? yes -> do it.
1554                 // m's $DATA or $BITMAP+$INDEX_ALLOCATION resident?
1555                 // yes -> make non-resident
1556                 //      does it fit now? yes -> do it.
1557                 // make all attributes non-resident
1558                 //      does it fit now? yes -> do it.
1559                 // m is a base record? yes -> allocate extension record
1560                 //      does the new attribute fit in there? yes -> do it.
1561                 // split up runlist into extents and place each in an extension
1562                 // record.
1563                 // FIXME: the check for needing extension records should be
1564                 // earlier on as it is very quick: asize > m->bytes_allocated?
1565                 err = -ENOTSUP;
1566                 goto err_out;
1567         }
1568 #ifdef DEBUG
1569         if (err == -EINVAL) {
1570                 fprintf(stderr, "BUG(): in insert_resident_attribute_in_mft_"
1571                                 "record(): make_room_for_attribute() returned "
1572                                 "error: EINVAL!\n");
1573                 goto err_out;
1574         }
1575 #endif
1576         a->type = type;
1577         a->length = cpu_to_le32(asize);
1578         a->non_resident = 0;
1579         a->name_length = name_len;
1580         a->name_offset = cpu_to_le16(24);
1581         a->flags = cpu_to_le16(flags);
1582         a->instance = m->next_attr_instance;
1583         m->next_attr_instance = cpu_to_le16((le16_to_cpu(m->next_attr_instance)
1584                         + 1) & 0xffff);
1585         a->value_length = cpu_to_le32(val_len);
1586         a->value_offset = cpu_to_le16(24 + ((name_len + 7) & ~7));
1587         a->resident_flags = res_flags;
1588         a->reservedR = 0;
1589         if (name_len)
1590                 memcpy((char*)a + 24, uname, name_len << 1);
1591         if (val_len)
1592                 memcpy((char*)a + le16_to_cpu(a->value_offset), val, val_len);
1593 err_out:
1594         if (ctx)
1595                 ntfs_attr_put_search_ctx(ctx);
1596         if (uname && (uname != AT_UNNAMED))
1597                 free(uname);
1598         return err;
1599 }
1600
1601 /**
1602  * add_attr_std_info
1603  * Return 0 on success or -errno on error.
1604  */
1605 int add_attr_std_info(MFT_RECORD *m, const FILE_ATTR_FLAGS flags)
1606 {
1607         STANDARD_INFORMATION si;
1608         int err;
1609
1610         si.creation_time = utc2ntfs(time(NULL));
1611         si.last_data_change_time = si.creation_time;
1612         si.last_mft_change_time = si.creation_time;
1613         si.last_access_time = si.creation_time;
1614         si.file_attributes = flags; /* already LE */
1615         if (vol->major_ver < 3)
1616                 memset(&si.reserved12, 0, sizeof(si.reserved12));
1617         else {
1618                 si.maximum_versions = cpu_to_le32(0);
1619                 si.version_number = cpu_to_le32(0);
1620                 si.class_id = cpu_to_le32(0);
1621                 /* FIXME: $Secure support... */
1622                 si.security_id = cpu_to_le32(0);
1623                 /* FIXME: $Quota support... */
1624                 si.owner_id = cpu_to_le32(0);
1625                 si.quota_charged = cpu_to_le64(0ULL);
1626                 /* FIXME: $UsnJrnl support... */
1627                 si.usn = cpu_to_le64(0ULL);
1628         }
1629         /* NTFS 1.2: size of si = 48, NTFS 3.0: size of si = 72 */
1630         err = insert_resident_attr_in_mft_record(m, AT_STANDARD_INFORMATION,
1631                         NULL, 0, 0, 0, 0, (char*)&si,
1632                         vol->major_ver < 3 ? 48 : 72);
1633         if (err < 0)
1634                 Eprintf("add_attr_std_info failed: %s\n", strerror(-err));
1635         return err;
1636 }
1637
1638 /**
1639  * add_attr_file_name
1640  * Return 0 on success or -errno on error.
1641  */
1642 int add_attr_file_name(MFT_RECORD *m, const MFT_REF parent_dir,
1643                 const s64 allocated_size, const s64 data_size,
1644                 const FILE_ATTR_FLAGS flags, const u16 packed_ea_size,
1645                 const u32 reparse_point_tag, const char *file_name,
1646                 const FILE_NAME_TYPE_FLAGS file_name_type)
1647 {
1648         ntfs_attr_search_ctx *ctx;
1649         STANDARD_INFORMATION *si;
1650         FILE_NAME_ATTR *fn;
1651         int i, fn_size;
1652
1653         /* Check if the attribute is already there. */
1654         ctx = ntfs_attr_get_search_ctx(NULL, m);
1655         if (!ctx) {
1656                 Eprintf("Failed to allocate attribute search context.\n");
1657                 return -ENOMEM;
1658         }
1659         if (ntfs_attr_lookup(AT_STANDARD_INFORMATION, AT_UNNAMED, 0, 0, 0, NULL, 0,
1660                         ctx)) {
1661                 int eo = errno;
1662                 Eprintf("BUG: Standard information attribute not present in "
1663                                 "file record\n");
1664                 ntfs_attr_put_search_ctx(ctx);
1665                 return -eo;
1666         }
1667         si = (STANDARD_INFORMATION*)((char*)ctx->attr +
1668                         le16_to_cpu(ctx->attr->value_offset));
1669         i = (strlen(file_name) + 1) * sizeof(uchar_t);
1670         fn_size = sizeof(FILE_NAME_ATTR) + i;
1671         fn = (FILE_NAME_ATTR*)malloc(fn_size);
1672         if (!fn) {
1673                 ntfs_attr_put_search_ctx(ctx);
1674                 return -errno;
1675         }
1676         fn->parent_directory = parent_dir;
1677
1678         fn->creation_time = si->creation_time;
1679         fn->last_data_change_time = si->last_data_change_time;
1680         fn->last_mft_change_time = si->last_mft_change_time;
1681         fn->last_access_time = si->last_access_time;
1682         ntfs_attr_put_search_ctx(ctx);
1683
1684         fn->allocated_size = cpu_to_le64(allocated_size);
1685         fn->data_size = cpu_to_le64(data_size);
1686         fn->file_attributes = flags;
1687         /* These are in a union so can't have both. */
1688         if (packed_ea_size && reparse_point_tag) {
1689                 free(fn);
1690                 return -EINVAL;
1691         }
1692         if (packed_ea_size) {
1693                 fn->packed_ea_size = cpu_to_le16(packed_ea_size);
1694                 fn->reserved = cpu_to_le16(0);
1695         } else
1696                 fn->reparse_point_tag = cpu_to_le32(reparse_point_tag);
1697         fn->file_name_type = file_name_type;
1698         i = stoucs(fn->file_name, file_name, i);
1699         if (i < 1) {
1700                 free(fn);
1701                 return -EINVAL;
1702         }
1703         if (i > 0xff) {
1704                 free(fn);
1705                 return -ENAMETOOLONG;
1706         }
1707         /* No terminating null in file names. */
1708         fn->file_name_length = i;
1709         fn_size = sizeof(FILE_NAME_ATTR) + i * sizeof(uchar_t);
1710         i = insert_resident_attr_in_mft_record(m, AT_FILE_NAME, NULL, 0, 0,
1711                         0, RESIDENT_ATTR_IS_INDEXED, (char*)fn, fn_size);
1712         free(fn);
1713         if (i < 0)
1714                 Eprintf("add_attr_file_name failed: %s\n", strerror(-i));
1715         return i;
1716 }
1717
1718 /**
1719  * add_attr_sd
1720  * Create the security descriptor attribute adding the security descriptor @sd
1721  * of length @sd_len to the mft record @m.
1722  *
1723  * Return 0 on success or -errno on error.
1724  */
1725 int add_attr_sd(MFT_RECORD *m, const char *sd, const s64 sd_len)
1726 {
1727         int err;
1728
1729         /* Does it fit? NO: create non-resident. YES: create resident. */
1730         if (le32_to_cpu(m->bytes_in_use) + 24 + sd_len >
1731                                                 le32_to_cpu(m->bytes_allocated))
1732                 err = insert_non_resident_attr_in_mft_record(m,
1733                                 AT_SECURITY_DESCRIPTOR, NULL, 0, 0, 0, sd,
1734                                 sd_len);
1735         else
1736                 err = insert_resident_attr_in_mft_record(m,
1737                                 AT_SECURITY_DESCRIPTOR, NULL, 0, 0, 0, 0, sd,
1738                                 sd_len);
1739         if (err < 0)
1740                 Eprintf("add_attr_sd failed: %s\n", strerror(-err));
1741         return err;
1742 }
1743
1744 /**
1745  * add_attr_data
1746  * Return 0 on success or -errno on error.
1747  */
1748 int add_attr_data(MFT_RECORD *m, const char *name, const u32 name_len,
1749                 const IGNORE_CASE_BOOL ic, const ATTR_FLAGS flags,
1750                 const char *val, const s64 val_len)
1751 {
1752         int err;
1753
1754         /*
1755          * Does it fit? NO: create non-resident. YES: create resident.
1756          *
1757          * FIXME: Introduced arbitrary limit of mft record allocated size - 512.
1758          * This is to get around the problem that if $Bitmap/$DATA becomes too
1759          * big, but is just small enough to be resident, we would make it
1760          * resident, and later run out of space when creating the other
1761          * attributes and this would cause us to abort as making resident
1762          * attributes non-resident is not supported yet.
1763          * The proper fix is to support making resident attribute non-resident.
1764          */
1765         if (le32_to_cpu(m->bytes_in_use) + 24 + val_len >
1766                         min(le32_to_cpu(m->bytes_allocated),
1767                         le32_to_cpu(m->bytes_allocated) - 512))
1768                 err = insert_non_resident_attr_in_mft_record(m, AT_DATA, name,
1769                                 name_len, ic, flags, val, val_len);
1770         else
1771                 err = insert_resident_attr_in_mft_record(m, AT_DATA, name,
1772                                 name_len, ic, flags, 0, val, val_len);
1773
1774         if (err < 0)
1775                 Eprintf("add_attr_data failed: %s\n", strerror(-err));
1776         return err;
1777 }
1778
1779 /**
1780  * add_attr_data_positioned
1781  * Create a non-resident data attribute with a predefined on disk location
1782  * specified by the runlist @rl. The clusters specified by @rl are assumed to
1783  * be allocated already.
1784  *
1785  * Return 0 on success or -errno on error.
1786  */
1787 int add_attr_data_positioned(MFT_RECORD *m, const char *name,
1788                 const u32 name_len, const IGNORE_CASE_BOOL ic,
1789                 const ATTR_FLAGS flags, const runlist *rl,
1790                 const char *val, const s64 val_len)
1791 {
1792         int err;
1793
1794         err = insert_positioned_attr_in_mft_record(m, AT_DATA, name, name_len,
1795                         ic, flags, rl, val, val_len);
1796         if (err < 0)
1797                 Eprintf("add_attr_data_positioned failed: %s\n",
1798                                 strerror(-err));
1799         return err;
1800 }
1801
1802 /**
1803  * add_attr_vol_name
1804  * Create volume name attribute specifying the volume name @vol_name as a null
1805  * terminated char string of length @vol_name_len (number of characters not
1806  * including the terminating null), which is converted internally to a little
1807  * endian uchar_t string. The name is at least 1 character long and at most
1808  * 0xff characters long (not counting the terminating null).
1809  *
1810  * Return 0 on success or -errno on error.
1811  */
1812 int add_attr_vol_name(MFT_RECORD *m, const char *vol_name,
1813                 const int vol_name_len)
1814 {
1815         uchar_t *uname;
1816         int i, len;
1817
1818         if (vol_name_len) {
1819                 len = (vol_name_len + 1) * sizeof(uchar_t);
1820                 uname = calloc(1, len);
1821                 if (!uname)
1822                         return -errno;
1823                 i = (stoucs(uname, vol_name, len) + 1) * sizeof(uchar_t);
1824                 if (!i) {
1825                         free(uname);
1826                         return -EINVAL;
1827                 }
1828                 if (i > 0xff) {
1829                         free(uname);
1830                         return -ENAMETOOLONG;
1831                 }
1832         } else {
1833                 uname = NULL;
1834                 len = 0;
1835         }
1836         i = insert_resident_attr_in_mft_record(m, AT_VOLUME_NAME, NULL, 0, 0,
1837                         0, 0, (char*)uname, len);
1838         if (uname)
1839                 free(uname);
1840         if (i < 0)
1841                 Eprintf("add_attr_vol_name failed: %s\n", strerror(-i));
1842         return i;
1843 }
1844
1845 /**
1846  * add_attr_vol_info
1847  * Return 0 on success or -errno on error.
1848  */
1849 int add_attr_vol_info(MFT_RECORD *m, const VOLUME_FLAGS flags,
1850                 const u8 major_ver, const u8 minor_ver)
1851 {
1852         VOLUME_INFORMATION vi;
1853         int err;
1854
1855         memset(&vi, 0, sizeof(vi));
1856         vi.major_ver = major_ver;
1857         vi.minor_ver = minor_ver;
1858         vi.flags = flags & VOLUME_FLAGS_MASK;
1859         err = insert_resident_attr_in_mft_record(m, AT_VOLUME_INFORMATION, NULL,
1860                         0, 0, 0, 0, (char*)&vi, sizeof(vi));
1861         if (err < 0)
1862                 Eprintf("add_attr_vol_info failed: %s\n", strerror(-err));
1863         return err;
1864 }
1865
1866 /**
1867  * add_attr_index_root
1868  * Return 0 on success or -errno on error.
1869  */
1870 int add_attr_index_root(MFT_RECORD *m, const char *name, const u32 name_len,
1871                 const IGNORE_CASE_BOOL ic, const ATTR_TYPES indexed_attr_type,
1872                 const COLLATION_RULES collation_rule,
1873                 const u32 index_block_size)
1874 {
1875         INDEX_ROOT *r;
1876         INDEX_ENTRY_HEADER *e;
1877         int err, val_len;
1878
1879         val_len = sizeof(INDEX_ROOT) + sizeof(INDEX_ENTRY_HEADER);
1880         r = (INDEX_ROOT*)malloc(val_len);
1881         if (!r)
1882                 return -errno;
1883         r->type = indexed_attr_type == AT_FILE_NAME ? AT_FILE_NAME : 0;
1884         if (indexed_attr_type == AT_FILE_NAME &&
1885                         collation_rule != COLLATION_FILE_NAME) {
1886                 free(r);
1887                 Eprintf("add_attr_index_root: indexed attribute is $FILE_NAME "
1888                         "but collation rule is not COLLATION_FILE_NAME.\n");
1889                 return -EINVAL;
1890         }
1891         r->collation_rule = collation_rule;
1892         r->index_block_size = cpu_to_le32(index_block_size);
1893         if (index_block_size >= vol->cluster_size) {
1894                 if (index_block_size % vol->cluster_size) {
1895                         Eprintf("add_attr_index_root: index block size is not "
1896                                         "a multiple of the cluster size.\n");
1897                         free(r);
1898                         return -EINVAL;
1899                 }
1900                 r->clusters_per_index_block = index_block_size /
1901                                 vol->cluster_size;
1902         } else /* if (vol->cluster_size > index_block_size) */ {
1903                 if (index_block_size & (index_block_size - 1)) {
1904                         Eprintf("add_attr_index_root: index block size is not "
1905                                         "a power of 2.\n");
1906                         free(r);
1907                         return -EINVAL;
1908                 }
1909                 if (index_block_size < opts.sector_size) {
1910                          Eprintf("add_attr_index_root: index block size is "
1911                                          "smaller than the sector size.\n");
1912                          free(r);
1913                          return -EINVAL;
1914                 }
1915                 r->clusters_per_index_block = index_block_size /
1916                                 opts.sector_size;
1917         }
1918         memset(&r->reserved, 0, sizeof(r->reserved));
1919         r->index.entries_offset = cpu_to_le32(sizeof(INDEX_HEADER));
1920         r->index.index_length = cpu_to_le32(sizeof(INDEX_HEADER) +
1921                         sizeof(INDEX_ENTRY_HEADER));
1922         r->index.allocated_size = r->index.index_length;
1923         r->index.flags = SMALL_INDEX;
1924         memset(&r->index.reserved, 0, sizeof(r->index.reserved));
1925         e = (INDEX_ENTRY_HEADER*)((char*)&r->index +
1926                         le32_to_cpu(r->index.entries_offset));
1927         /*
1928          * No matter whether this is a file index or a view as this is a
1929          * termination entry, hence no key value / data is associated with it
1930          * at all. Thus, we just need the union to be all zero.
1931          */
1932         e->indexed_file = cpu_to_le64(0LL);
1933         e->length = cpu_to_le16(sizeof(INDEX_ENTRY_HEADER));
1934         e->key_length = cpu_to_le16(0);
1935         e->flags = INDEX_ENTRY_END;
1936         e->reserved = cpu_to_le16(0);
1937         err = insert_resident_attr_in_mft_record(m, AT_INDEX_ROOT, name,
1938                                 name_len, ic, 0, 0, (char*)r, val_len);
1939         free(r);
1940         if (err < 0)
1941                 Eprintf("add_attr_index_root failed: %s\n", strerror(-err));
1942         return err;
1943 }
1944
1945 /**
1946  * add_attr_index_alloc
1947  * Return 0 on success or -errno on error.
1948  */
1949 int add_attr_index_alloc(MFT_RECORD *m, const char *name, const u32 name_len,
1950                 const IGNORE_CASE_BOOL ic, const char *index_alloc_val,
1951                 const u32 index_alloc_val_len)
1952 {
1953         int err;
1954
1955         err = insert_non_resident_attr_in_mft_record(m, AT_INDEX_ALLOCATION,
1956                         name, name_len, ic, 0, index_alloc_val,
1957                         index_alloc_val_len);
1958         if (err < 0)
1959                 Eprintf("add_attr_index_alloc failed: %s\n", strerror(-err));
1960         return err;
1961 }
1962
1963 /**
1964  * add_attr_bitmap
1965  * Return 0 on success or -errno on error.
1966  */
1967 int add_attr_bitmap(MFT_RECORD *m, const char *name, const u32 name_len,
1968                 const IGNORE_CASE_BOOL ic, const char *bitmap,
1969                 const u32 bitmap_len)
1970 {
1971         int err;
1972
1973         /* Does it fit? NO: create non-resident. YES: create resident. */
1974         if (le32_to_cpu(m->bytes_in_use) + 24 + bitmap_len >
1975                                                 le32_to_cpu(m->bytes_allocated))
1976                 err = insert_non_resident_attr_in_mft_record(m, AT_BITMAP, name,
1977                                 name_len, ic, 0, bitmap, bitmap_len);
1978         else
1979                 err = insert_resident_attr_in_mft_record(m, AT_BITMAP, name,
1980                                 name_len, ic, 0, 0, bitmap, bitmap_len);
1981
1982         if (err < 0)
1983                 Eprintf("add_attr_bitmap failed: %s\n", strerror(-err));
1984         return err;
1985 }
1986
1987 /**
1988  * add_attr_bitmap_positioned
1989  * Create a non-resident bitmap attribute with a predefined on disk location
1990  * specified by the runlist @rl. The clusters specified by @rl are assumed to
1991  * be allocated already.
1992  *
1993  * Return 0 on success or -errno on error.
1994  */
1995 int add_attr_bitmap_positioned(MFT_RECORD *m, const char *name,
1996                 const u32 name_len, const IGNORE_CASE_BOOL ic,
1997                 const runlist *rl, const char *bitmap, const u32 bitmap_len)
1998 {
1999         int err;
2000
2001         err = insert_positioned_attr_in_mft_record(m, AT_BITMAP, name, name_len,
2002                         ic, 0, rl, bitmap, bitmap_len);
2003         if (err < 0)
2004                 Eprintf("add_attr_bitmap_positioned failed: %s\n",
2005                                 strerror(-err));
2006         return err;
2007 }
2008
2009 /**
2010  * upgrade_to_large_index
2011  * Create bitmap and index allocation attributes, modify index root
2012  * attribute accordingly and move all of the index entries from the index root
2013  * into the index allocation.
2014  *
2015  * Return 0 on success or -errno on error.
2016  */
2017 int upgrade_to_large_index(MFT_RECORD *m, const char *name,
2018                 u32 name_len, const IGNORE_CASE_BOOL ic,
2019                 INDEX_ALLOCATION **index)
2020 {
2021         ntfs_attr_search_ctx *ctx;
2022         ATTR_RECORD *a;
2023         INDEX_ROOT *r;
2024         INDEX_ENTRY *re;
2025         INDEX_ALLOCATION *ia_val = NULL;
2026         uchar_t *uname;
2027         char bmp[8];
2028         char *re_start, *re_end;
2029         int i, err, index_block_size;
2030
2031         if (name_len) {
2032                 i = (name_len + 1) * sizeof(uchar_t);
2033                 uname = (uchar_t*)calloc(1, i);
2034                 if (!uname)
2035                         return -errno;
2036                 name_len = stoucs(uname, name, i);
2037                 if (name_len > 0xff) {
2038                         free(uname);
2039                         return -ENAMETOOLONG;
2040                 }
2041         } else
2042                 uname = NULL;
2043         /* Find the index root attribute. */
2044         ctx = ntfs_attr_get_search_ctx(NULL, m);
2045         if (!ctx) {
2046                 Eprintf("Failed to allocate attribute search context.\n");
2047                 return -ENOMEM;
2048         }
2049         if (ic == IGNORE_CASE) {
2050                 Eprintf("FIXME: Hit unimplemented code path #4.\n");
2051                 err = -ENOTSUP;
2052                 goto err_out;
2053         }
2054         err = ntfs_attr_lookup(AT_INDEX_ROOT, uname, name_len, ic, 0, NULL, 0,
2055                         ctx);
2056         if (uname)
2057                 free(uname);
2058         if (err) {
2059                 err = -ENOTDIR;
2060                 goto err_out;
2061         }
2062         a = ctx->attr;
2063         if (a->non_resident || a->flags) {
2064                 err = -EINVAL;
2065                 goto err_out;
2066         }
2067         r = (INDEX_ROOT*)((char*)a + le16_to_cpu(a->value_offset));
2068         re_end = (char*)r + le32_to_cpu(a->value_length);
2069         re_start = (char*)&r->index + le32_to_cpu(r->index.entries_offset);
2070         re = (INDEX_ENTRY*)re_start;
2071         index_block_size = le32_to_cpu(r->index_block_size);
2072         memset(bmp, 0, sizeof(bmp));
2073         ntfs_bit_set(bmp, 0ULL, 1);
2074         /* Bitmap has to be at least 8 bytes in size. */
2075         err = add_attr_bitmap(m, name, name_len, ic, (char*)&bmp, sizeof(bmp));
2076         if (err)
2077                 goto err_out;
2078         ia_val = calloc(1, index_block_size);
2079         if (!ia_val) {
2080                 err = -errno;
2081                 goto err_out;
2082         }
2083         /* Setup header. */
2084         ia_val->magic = magic_INDX;
2085         ia_val->usa_ofs = cpu_to_le16(sizeof(INDEX_ALLOCATION));
2086         if (index_block_size >= NTFS_SECTOR_SIZE)
2087                 ia_val->usa_count = cpu_to_le16(index_block_size /
2088                                 NTFS_SECTOR_SIZE + 1);
2089         else {
2090                 ia_val->usa_count = cpu_to_le16(1);
2091                 Qprintf("Sector size is bigger than index block size. Setting "
2092                         "usa_count to 1. If Windows\nchkdsk reports this as "
2093                         "corruption, please email linux-ntfs-dev@lists.sf.net\n"
2094                         "stating that you saw this message and that the file "
2095                         "system created was corrupt.\nThank you.");
2096         }
2097         /* Set USN to 1. */
2098         *(u16*)((char*)ia_val + le16_to_cpu(ia_val->usa_ofs)) =
2099                         cpu_to_le16(1);
2100         ia_val->lsn = cpu_to_le64(0);
2101         ia_val->index_block_vcn = cpu_to_le64(0);
2102         ia_val->index.flags = LEAF_NODE;
2103         /* Align to 8-byte boundary. */
2104         ia_val->index.entries_offset = cpu_to_le32((sizeof(INDEX_HEADER) +
2105                         le16_to_cpu(ia_val->usa_count) * 2 + 7) & ~7);
2106         ia_val->index.allocated_size = cpu_to_le32(index_block_size -
2107                         (sizeof(INDEX_ALLOCATION) - sizeof(INDEX_HEADER)));
2108         /* Find the last entry in the index root and save it in re. */
2109         while ((char*)re < re_end && !(re->flags & INDEX_ENTRY_END)) {
2110                 /* Next entry in index root. */
2111                 re = (INDEX_ENTRY*)((char*)re + le16_to_cpu(re->length));
2112         }
2113         /* Copy all the entries including the termination entry. */
2114         i = (char*)re - re_start + le16_to_cpu(re->length);
2115         memcpy((char*)&ia_val->index +
2116                         le32_to_cpu(ia_val->index.entries_offset), re_start, i);
2117         /* Finish setting up index allocation. */
2118         ia_val->index.index_length = cpu_to_le32(i +
2119                         le32_to_cpu(ia_val->index.entries_offset));
2120         /* Move the termination entry forward to the beginning if necessary. */
2121         if ((char*)re > re_start) {
2122                 memmove(re_start, (char*)re, le16_to_cpu(re->length));
2123                 re = (INDEX_ENTRY*)re_start;
2124         }
2125         /* Now fixup empty index root with pointer to index allocation VCN 0. */
2126         r->index.flags = LARGE_INDEX;
2127         re->flags |= INDEX_ENTRY_NODE;
2128         if (le16_to_cpu(re->length) < sizeof(INDEX_ENTRY_HEADER) + sizeof(VCN))
2129                 re->length = cpu_to_le16(le16_to_cpu(re->length) + sizeof(VCN));
2130         r->index.index_length = cpu_to_le32(le32_to_cpu(r->index.entries_offset)
2131                         + le16_to_cpu(re->length));
2132         r->index.allocated_size = r->index.index_length;
2133         /* Resize index root attribute. */
2134         if (ntfs_resident_attr_value_resize(m, a, sizeof(INDEX_ROOT) -
2135                         sizeof(INDEX_HEADER) +
2136                         le32_to_cpu(r->index.allocated_size))) {
2137                 // TODO: Remove the added bitmap!
2138                 // Revert index root from index allocation.
2139                 err = -errno;
2140                 goto err_out;
2141         }
2142         /* Set VCN pointer to 0LL. */
2143         *(VCN*)((char*)re + cpu_to_le16(re->length) - sizeof(VCN)) =
2144                         cpu_to_le64(0);
2145         err = ntfs_mst_pre_write_fixup((NTFS_RECORD*)ia_val, index_block_size);
2146         if (err) {
2147                 err = -errno;
2148                 Eprintf("ntfs_mst_pre_write_fixup() failed in "
2149                                 "upgrade_to_large_index.\n");
2150                 goto err_out;
2151         }
2152         err = add_attr_index_alloc(m, name, name_len, ic, (char*)ia_val,
2153                         index_block_size);
2154         ntfs_mst_post_write_fixup((NTFS_RECORD*)ia_val);
2155         if (err) {
2156                 // TODO: Remove the added bitmap!
2157                 // Revert index root from index allocation.
2158                 goto err_out;
2159         }
2160         *index = ia_val;
2161         return 0;
2162 err_out:
2163         if (ctx)
2164                 ntfs_attr_put_search_ctx(ctx);
2165         if (ia_val)
2166                 free(ia_val);
2167         return err;
2168 }
2169
2170 /**
2171  * make_room_for_index_entry_in_index_block
2172  * Create space of @size bytes at position @pos inside the index block @index.
2173  *
2174  * Return 0 on success or -errno on error.
2175  */
2176 int make_room_for_index_entry_in_index_block(INDEX_BLOCK *index,
2177                 INDEX_ENTRY *pos, u32 size)
2178 {
2179         u32 biu;
2180
2181         if (!size)
2182                 return 0;
2183 #ifdef DEBUG
2184         /*
2185          * Rigorous consistency checks. Always return -EINVAL even if more
2186          * appropriate codes exist for simplicity of parsing the return value.
2187          */
2188         if (size != ((size + 7) & ~7)) {
2189                 Eprintf("make_room_for_index_entry_in_index_block() received "
2190                                 "non 8-byte aligned size.\n");
2191                 return -EINVAL;
2192         }
2193         if (!index || !pos)
2194                 return -EINVAL;
2195         if ((char*)pos < (char*)index || (char*)pos + size < (char*)index ||
2196                         (char*)pos > (char*)index + sizeof(INDEX_BLOCK) -
2197                                 sizeof(INDEX_HEADER) +
2198                                 le32_to_cpu(index->index.allocated_size) ||
2199                         (char*)pos + size > (char*)index + sizeof(INDEX_BLOCK) -
2200                                 sizeof(INDEX_HEADER) +
2201                                 le32_to_cpu(index->index.allocated_size))
2202                 return -EINVAL;
2203         /* The - sizeof(INDEX_ENTRY_HEADER) is for the index terminator. */
2204         if ((char*)pos - (char*)&index->index >
2205                         le32_to_cpu(index->index.index_length)
2206                         - sizeof(INDEX_ENTRY_HEADER))
2207                 return -EINVAL;
2208 #endif
2209         biu = le32_to_cpu(index->index.index_length);
2210         /* Do we have enough space? */
2211         if (biu + size > le32_to_cpu(index->index.allocated_size))
2212                 return -ENOSPC;
2213         /* Move everything after pos to pos + size. */
2214         memmove((char*)pos + size, (char*)pos, biu - ((char*)pos -
2215                         (char*)&index->index));
2216         /* Update index block. */
2217         index->index.index_length = cpu_to_le32(biu + size);
2218         return 0;
2219 }
2220
2221 /**
2222  * insert_file_link_in_dir_index
2223  * Insert the fully completed FILE_NAME_ATTR @file_name which is inside
2224  * the file with mft reference @file_ref into the index (allocation) block
2225  * @index (which belongs to @file_ref's parent directory).
2226  *
2227  * Return 0 on success or -errno on error.
2228  */
2229 int insert_file_link_in_dir_index(INDEX_BLOCK *index, MFT_REF file_ref,
2230                 FILE_NAME_ATTR *file_name, u32 file_name_size)
2231 {
2232         int err, i;
2233         INDEX_ENTRY *ie;
2234         char *index_end;
2235
2236         /*
2237          * Lookup dir entry @file_name in dir @index to determine correct
2238          * insertion location. FIXME: Using a very oversimplified lookup
2239          * method which is sufficient for mkntfs but no good whatsoever in
2240          * real world scenario. (AIA)
2241          */
2242         index_end = (char*)&index->index +
2243                         le32_to_cpu(index->index.index_length);
2244         ie = (INDEX_ENTRY*)((char*)&index->index +
2245                         le32_to_cpu(index->index.entries_offset));
2246         /*
2247          * Loop until we exceed valid memory (corruption case) or until we
2248          * reach the last entry.
2249          */
2250         while ((char*)ie < index_end && !(ie->flags & INDEX_ENTRY_END)) {
2251 /*
2252 #ifdef DEBUG
2253                 Dprintf("file_name_attr1->file_name_length = %i\n",
2254                                 file_name->file_name_length);
2255                 if (file_name->file_name_length) {
2256                         char *__buf;
2257                         __buf = (char*)calloc(1, file_name->file_name_length +
2258                                         1);
2259                         if (!__buf)
2260                                 err_exit("Failed to allocate internal buffer: "
2261                                                 "%s\n", strerror(errno));
2262                         i = ucstos(__buf, (uchar_t*)&file_name->file_name,
2263                                         file_name->file_name_length + 1);
2264                         if (i == -1)
2265                                 Dprintf("Name contains non-displayable "
2266                                                 "Unicode characters.\n");
2267                         Dprintf("file_name_attr1->file_name = %s\n", __buf);
2268                         free(__buf);
2269                 }
2270                 Dprintf("file_name_attr2->file_name_length = %i\n",
2271                                 ie->key.file_name.file_name_length);
2272                 if (ie->key.file_name.file_name_length) {
2273                         char *__buf;
2274                         __buf = (char*)calloc(1,
2275                                         ie->key.file_name.file_name_length + 1);
2276                         if (!__buf)
2277                                 err_exit("Failed to allocate internal buffer: "
2278                                                 "%s\n", strerror(errno));
2279                         i = ucstos(__buf, ie->key.file_name.file_name,
2280                                         ie->key.file_name.file_name_length + 1);
2281                         if (i == -1)
2282                                 Dprintf("Name contains non-displayable "
2283                                                 "Unicode characters.\n");
2284                         Dprintf("file_name_attr2->file_name = %s\n", __buf);
2285                         free(__buf);
2286                 }
2287 #endif
2288 */
2289                 i = ntfs_file_values_compare(file_name,
2290                                 (FILE_NAME_ATTR*)&ie->key.file_name, 1,
2291                                 IGNORE_CASE, vol->upcase, vol->upcase_len);
2292                 /*
2293                  * If @file_name collates before ie->key.file_name, there is no
2294                  * matching index entry.
2295                  */
2296                 if (i == -1)
2297                         break;
2298                 /* If file names are not equal, continue search. */
2299                 if (i)
2300                         goto do_next;
2301                 /* File names are equal when compared ignoring case. */
2302                 /*
2303                  * If BOTH file names are in the POSIX namespace, do a case
2304                  * sensitive comparison as well. Otherwise the names match so
2305                  * we return -EEXIST. FIXME: There are problems with this in a
2306                  * real world scenario, when one is POSIX and one isn't, but
2307                  * fine for mkntfs where we don't use POSIX namespace at all
2308                  * and hence this following code is luxury. (AIA)
2309                  */
2310                 if (file_name->file_name_type != FILE_NAME_POSIX ||
2311                     ie->key.file_name.file_name_type != FILE_NAME_POSIX)
2312                         return -EEXIST;
2313                 i = ntfs_file_values_compare(file_name,
2314                                 (FILE_NAME_ATTR*)&ie->key.file_name, 1,
2315                                 CASE_SENSITIVE, vol->upcase, vol->upcase_len);
2316                 if (i == -1)
2317                         break;
2318                 /* Complete match. Bugger. Can't insert. */
2319                 if (!i)
2320                         return -EEXIST;
2321 do_next:
2322 #ifdef DEBUG
2323                 /* Next entry. */
2324                 if (!ie->length) {
2325                         Dprintf("BUG: ie->length is zero, breaking out of "
2326                                         "loop.\n");
2327                         break;
2328                 }
2329 #endif
2330                 ie = (INDEX_ENTRY*)((char*)ie + le16_to_cpu(ie->length));
2331         };
2332         i = (sizeof(INDEX_ENTRY_HEADER) + file_name_size + 7) & ~7;
2333         err = make_room_for_index_entry_in_index_block(index, ie, i);
2334         if (err) {
2335                 Eprintf("make_room_for_index_entry_in_index_block failed: "
2336                                 "%s\n", strerror(-err));
2337                 return err;
2338         }
2339         /* Create entry in place and copy file name attribute value. */
2340         ie->indexed_file = file_ref;
2341         ie->length = cpu_to_le16(i);
2342         ie->key_length = cpu_to_le16(file_name_size);
2343         ie->flags = cpu_to_le16(0);
2344         ie->reserved = cpu_to_le16(0);
2345         memcpy((char*)&ie->key.file_name, (char*)file_name, file_name_size);
2346         return 0;
2347 }
2348
2349 /**
2350  * create_hardlink
2351  * Create a file_name_attribute in the mft record @m_file which points to the
2352  * parent directory with mft reference @ref_parent.
2353  *
2354  * Then, insert an index entry with this file_name_attribute in the index
2355  * block @index of the index allocation attribute of the parent directory.
2356  *
2357  * @ref_file is the mft reference of @m_file.
2358  *
2359  * Return 0 on success or -errno on error.
2360  */
2361 int create_hardlink(INDEX_BLOCK *index, const MFT_REF ref_parent,
2362                 MFT_RECORD *m_file, const MFT_REF ref_file,
2363                 const s64 allocated_size, const s64 data_size,
2364                 const FILE_ATTR_FLAGS flags, const u16 packed_ea_size,
2365                 const u32 reparse_point_tag, const char *file_name,
2366                 const FILE_NAME_TYPE_FLAGS file_name_type)
2367 {
2368         FILE_NAME_ATTR *fn;
2369         int i, fn_size;
2370
2371         /* Create the file_name attribute. */
2372         i = (strlen(file_name) + 1) * sizeof(uchar_t);
2373         fn_size = sizeof(FILE_NAME_ATTR) + i;
2374         fn = (FILE_NAME_ATTR*)malloc(fn_size);
2375         if (!fn)
2376                 return -errno;
2377         fn->parent_directory = ref_parent;
2378         // FIXME: Is this correct? Or do we have to copy the creation_time
2379         // from the std info?
2380         fn->creation_time = utc2ntfs(time(NULL));
2381         fn->last_data_change_time = fn->creation_time;
2382         fn->last_mft_change_time = fn->creation_time;
2383         fn->last_access_time = fn->creation_time;
2384         fn->allocated_size = cpu_to_le64(allocated_size);
2385         fn->data_size = cpu_to_le64(data_size);
2386         fn->file_attributes = flags;
2387         /* These are in a union so can't have both. */
2388         if (packed_ea_size && reparse_point_tag) {
2389                 free(fn);
2390                 return -EINVAL;
2391         }
2392         if (packed_ea_size) {
2393                 fn->packed_ea_size = cpu_to_le16(packed_ea_size);
2394                 fn->reserved = cpu_to_le16(0);
2395         } else
2396                 fn->reparse_point_tag = cpu_to_le32(reparse_point_tag);
2397         fn->file_name_type = file_name_type;
2398         i = stoucs(fn->file_name, file_name, i);
2399         if (i < 1) {
2400                 free(fn);
2401                 return -EINVAL;
2402         }
2403         if (i > 0xff) {
2404                 free(fn);
2405                 return -ENAMETOOLONG;
2406         }
2407         /* No terminating null in file names. */
2408         fn->file_name_length = i;
2409         fn_size = sizeof(FILE_NAME_ATTR) + i * sizeof(uchar_t);
2410         /* Increment the link count of @m_file. */
2411         i = le16_to_cpu(m_file->link_count);
2412         if (i == 0xffff) {
2413                 Eprintf("Too many hardlinks present already.\n");
2414                 free(fn);
2415                 return -EINVAL;
2416         }
2417         m_file->link_count = cpu_to_le16(i + 1);
2418         /* Add the file_name to @m_file. */
2419         i = insert_resident_attr_in_mft_record(m_file, AT_FILE_NAME, NULL, 0, 0,
2420                         0, RESIDENT_ATTR_IS_INDEXED, (char*)fn, fn_size);
2421         if (i < 0) {
2422                 Eprintf("create_hardlink failed adding file name attribute: "
2423                                 "%s\n", strerror(-i));
2424                 free(fn);
2425                 /* Undo link count increment. */
2426                 m_file->link_count = cpu_to_le16(
2427                                 le16_to_cpu(m_file->link_count) - 1);
2428                 return i;
2429         }
2430         /* Insert the index entry for file_name in @index. */
2431         i = insert_file_link_in_dir_index(index, ref_file, fn, fn_size);
2432         if (i < 0) {
2433                 Eprintf("create_hardlink failed inserting index entry: %s\n",
2434                                 strerror(-i));
2435                 /* FIXME: Remove the file name attribute from @m_file. */
2436                 free(fn);
2437                 /* Undo link count increment. */
2438                 m_file->link_count = cpu_to_le16(
2439                                 le16_to_cpu(m_file->link_count) - 1);
2440                 return i;
2441         }
2442         free(fn);
2443         return 0;
2444 }
2445
2446 /**
2447  * init_options
2448  */
2449 void init_options()
2450 {
2451         memset(&opts, 0, sizeof(opts));
2452         opts.index_block_size = 4096;
2453         opts.attr_defs = (ATTR_DEF*)&attrdef_ntfs12_array;
2454         opts.attr_defs_len = sizeof(attrdef_ntfs12_array);
2455         //Dprintf("Attr_defs table length = %u\n", opts.attr_defs_len);
2456 }
2457
2458 /**
2459  * mkntfs_exit
2460  */
2461 void mkntfs_exit(void)
2462 {
2463         if (index_block)
2464                 free(index_block);
2465         if (buf)
2466                 free(buf);
2467         if (buf2)
2468                 free(buf2);
2469         if (lcn_bitmap)
2470                 free(lcn_bitmap);
2471         if (mft_bitmap)
2472                 free(mft_bitmap);
2473         if (rl)
2474                 free(rl);
2475         if (rl_mft)
2476                 free(rl_mft);
2477         if (rl_mft_bmp)
2478                 free(rl_mft_bmp);
2479         if (rl_mftmirr)
2480                 free(rl_mftmirr);
2481         if (rl_logfile)
2482                 free(rl_logfile);
2483         if (rl_boot)
2484                 free(rl_boot);
2485         if (rl_bad)
2486                 free(rl_bad);
2487         if (rl_index)
2488                 free(rl_index);
2489         if (opts.bad_blocks)
2490                 free(opts.bad_blocks);
2491         if (opts.attr_defs != (ATTR_DEF*)attrdef_ntfs12_array)
2492                 free(opts.attr_defs);
2493         if (!vol)
2494                 return;
2495         if (vol->upcase)
2496                 free(vol->upcase);
2497         if (vol->dev) {
2498                 if (NDevOpen(vol->dev) && vol->dev->d_ops->close(vol->dev))
2499                         Eprintf("Warning: Could not close %s: %s\n",
2500                                         vol->dev->d_name, strerror(errno));
2501                 ntfs_device_free(vol->dev);
2502         }
2503         free(vol);
2504 }
2505
2506 /**
2507  * main
2508  */
2509 int main(int argc, char **argv)
2510 {
2511         int i, j, err;
2512         ssize_t bw;
2513         struct stat sbuf;
2514         long long lw, pos;
2515         MFT_RECORD *m;
2516         ATTR_RECORD *a;
2517         MFT_REF root_ref;
2518         ntfs_attr_search_ctx *ctx;
2519         char *sd;
2520         NTFS_BOOT_SECTOR *bs;
2521         unsigned long mnt_flags;
2522
2523         /* Setup the correct locale for string output and conversion. */
2524         utils_set_locale();
2525         /* Initialize the random number generator with the current time. */
2526         srandom(time(NULL));
2527         /* Allocate and initialize ntfs_volume structure vol. */
2528         vol = ntfs_volume_alloc();
2529         if (!vol)
2530                 err_exit("Could not allocate memory for internal buffer.\n");
2531         /* Register our exit function which will cleanup everything. */
2532         err = atexit(&mkntfs_exit);
2533         if (err == -1) {
2534                 Eprintf("Could not set up exit() function because atexit() "
2535                                 "failed. Aborting...\n");
2536                 mkntfs_exit();
2537                 exit(1);
2538         }
2539         vol->major_ver = 1;
2540         vol->minor_ver = 2;
2541         vol->mft_record_size = 1024;
2542         vol->mft_record_size_bits = 10;
2543         /* Length is in unicode characters. */
2544         vol->upcase_len = 65536;
2545         vol->upcase = (uchar_t*)malloc(vol->upcase_len * sizeof(uchar_t));
2546         if (!vol->upcase)
2547                 err_exit("Could not allocate memory for internal buffer.\n");
2548         init_upcase_table(vol->upcase, vol->upcase_len * sizeof(uchar_t));
2549         /* Initialize opts to zero / required values. */
2550         init_options();
2551         /* Parse command line options. */
2552         parse_options(argc, argv);
2553         /*
2554          * Allocate and initialize an ntfs device structure and attach it to
2555          * the volume.
2556          */
2557         if (!(vol->dev = ntfs_device_alloc(dev_name, 0,
2558                         &ntfs_device_disk_io_ops, NULL)))
2559                 err_exit("Could not allocate memory for internal buffer.\n");
2560         /* Open the device for reading or reading and writing. */
2561         if (opts.no_action) {
2562                 Qprintf("Running in READ-ONLY mode!\n");
2563                 i = O_RDONLY;
2564         } else
2565                 i = O_RDWR;
2566         if (vol->dev->d_ops->open(vol->dev, i)) {
2567                 if (errno == ENOENT)
2568                         err_exit("The device doesn't exist; did you specify "
2569                                         "it correctly?\n");
2570                 err_exit("Could not open %s: %s\n", vol->dev->d_name,
2571                                 strerror(errno));
2572         }
2573         /* Verify we are dealing with a block device. */
2574         if (vol->dev->d_ops->stat(vol->dev, &sbuf)) {
2575                 err_exit("Error getting information about %s: %s\n",
2576                                 vol->dev->d_name, strerror(errno));
2577         }
2578         if (!S_ISBLK(sbuf.st_mode)) {
2579                 Eprintf("%s is not a block device.\n", vol->dev->d_name);
2580                 if (!opts.force)
2581                         err_exit("Refusing to make a filesystem here!\n");
2582                 if (!opts.nr_sectors) {
2583                         if (!sbuf.st_size && !sbuf.st_blocks)
2584                                 err_exit("You must specify the number of "
2585                                                 "sectors.\n");
2586                         if (opts.sector_size) {
2587                                 if (sbuf.st_size)
2588                                         opts.nr_sectors = sbuf.st_size /
2589                                                         opts.sector_size;
2590                                 else
2591                                         opts.nr_sectors = ((s64)sbuf.st_blocks
2592                                                         << 9) / opts.sector_size;
2593                         } else {
2594                                 if (sbuf.st_size)
2595                                         opts.nr_sectors = sbuf.st_size / 512;
2596                                 else
2597                                         opts.nr_sectors = sbuf.st_blocks;
2598                                 opts.sector_size = 512;
2599                         }
2600                 }
2601                 fprintf(stderr, "mkntfs forced anyway.\n");
2602         }
2603 #ifdef HAVE_LINUX_MAJOR_H
2604         else if ((MAJOR(sbuf.st_rdev) == HD_MAJOR &&
2605                         MINOR(sbuf.st_rdev) % 64 == 0) ||
2606                         (SCSI_BLK_MAJOR(MAJOR(sbuf.st_rdev)) &&
2607                         MINOR(sbuf.st_rdev) % 16 == 0)) {
2608                 err_exit("%s is entire device, not just one partition!\n",
2609                                 vol->dev->d_name);
2610         }
2611 #endif
2612         /* Make sure the file system is not mounted. */
2613         if (ntfs_check_if_mounted(vol->dev->d_name, &mnt_flags))
2614                 Eprintf("Failed to determine whether %s is mounted: %s\n",
2615                                 vol->dev->d_name, strerror(errno));
2616         else if (mnt_flags & NTFS_MF_MOUNTED) {
2617                 Eprintf("%s is mounted.\n", vol->dev->d_name);
2618                 if (!opts.force)
2619                         err_exit("Refusing to make a filesystem here!\n");
2620                 fprintf(stderr, "mkntfs forced anyway. Hope /etc/mtab is "
2621                                 "incorrect.\n");
2622         }
2623         /* If user didn't specify the sector size, determine it now. */
2624         if (!opts.sector_size) {
2625 #ifdef BLKSSZGET
2626                 int _sect_size = 0;
2627
2628                 if (vol->dev->d_ops->ioctl(vol->dev, BLKSSZGET, &_sect_size)
2629                                 >= 0)
2630                         opts.sector_size = _sect_size;
2631                 else
2632 #endif
2633                 {
2634                         Eprintf("No sector size specified for %s and it could "
2635                                         "not be obtained automatically.\n"
2636                                         "Assuming sector size is 512 bytes.\n",
2637                                         vol->dev->d_name);
2638                         opts.sector_size = 512;
2639                 }
2640         }
2641         /* Validate sector size. */
2642         if ((opts.sector_size - 1) & opts.sector_size ||
2643                         opts.sector_size < 256 || opts.sector_size > 4096)
2644                 err_exit("Error: sector_size is invalid. It must be a power "
2645                          "of two, and it must be\n greater or equal 256 and "
2646                          "less than or equal 4096 bytes.\n");
2647         Dprintf("sector size = %i bytes\n", opts.sector_size);
2648         /* If user didn't specify the number of sectors, determine it now. */
2649         if (!opts.nr_sectors) {
2650                 opts.nr_sectors = ntfs_device_size_get(vol->dev,
2651                                 opts.sector_size);
2652                 if (opts.nr_sectors <= 0)
2653                         err_exit("ntfs_device_size_get(%s) failed. Please "
2654                                         "specify it manually.\n",
2655                                         vol->dev->d_name);
2656         }
2657         Dprintf("number of sectors = %Ld (0x%Lx)\n", opts.nr_sectors,
2658                         opts.nr_sectors);
2659         /* Reserve the last sector for the backup boot sector. */
2660         opts.nr_sectors--;
2661         /* If user didn't specify the volume size, determine it now. */
2662         if (!opts.volume_size)
2663                 opts.volume_size = opts.nr_sectors * opts.sector_size;
2664         else if (opts.volume_size & (opts.sector_size - 1))
2665                 err_exit("Error: volume_size is not a multiple of "
2666                          "sector_size.\n");
2667         /* Validate volume size. */
2668         if (opts.volume_size < 1 << 20 /* 1MiB */)
2669                 err_exit("Error: device is too small (%ikiB). Minimum NTFS "
2670                          "volume size is 1MiB.\n", opts.volume_size / 1024);
2671         Dprintf("volume size = %LikiB\n", opts.volume_size / 1024);
2672         /* If user didn't specify the cluster size, determine it now. */
2673         if (!vol->cluster_size) {
2674                 if (opts.volume_size <= 512LL << 20)    /* <= 512MB */
2675                         vol->cluster_size = 512;
2676                 else if (opts.volume_size <= 1LL << 30) /* ]512MB-1GB] */
2677                         vol->cluster_size = 1024;
2678                 else if (opts.volume_size <= 2LL << 30) /* ]1GB-2GB] */
2679                         vol->cluster_size = 2048;
2680                 else
2681                         vol->cluster_size = 4096;
2682                 /* For small volumes on devices with large sector sizes. */
2683                 if (vol->cluster_size < opts.sector_size)
2684                         vol->cluster_size = opts.sector_size;
2685         }
2686         /* Validate cluster size. */
2687         if (vol->cluster_size & (vol->cluster_size - 1) ||
2688             vol->cluster_size < opts.sector_size ||
2689             vol->cluster_size > 128 * opts.sector_size ||
2690             vol->cluster_size > 65536)
2691                 err_exit("Error: cluster_size is invalid. It must be a power "
2692                          "of two, be at least\nthe same as sector_size, be "
2693                          "maximum 64kB, and the sectors per cluster value "
2694                          "has\nto fit inside eight bits. (We do not support "
2695                          "larger cluster sizes yet.)\n");
2696         vol->cluster_size_bits = ffs(vol->cluster_size) - 1;
2697         Dprintf("cluster size = %i bytes\n", vol->cluster_size);
2698         if (vol->cluster_size > 4096) {
2699                 if (opts.enable_compression) {
2700                         if (!opts.force)
2701                                 err_exit("Error: cluster_size is above 4096 "
2702                                                 "bytes and compression is "
2703                                                 "requested.\nThis is not "
2704                                                 "possible due to limitations "
2705                                                 "in the compression algorithm "
2706                                                 "used by\nWindows.\n");
2707                         opts.enable_compression = 0;
2708                 }
2709                 Qprintf("Warning: compression will be disabled on this volume "
2710                                 "because it is not\nsupported when the cluster "
2711                                 "size is above 4096 bytes. This is due to \n"
2712                                 "limitations in the compression algorithm used "
2713                                 "by Windows.\n");
2714         }
2715         /* If user didn't specify the number of clusters, determine it now. */
2716         if (!opts.nr_clusters)
2717                 opts.nr_clusters = opts.volume_size / vol->cluster_size;
2718         /*
2719          * Check the cluster_size and nr_sectors for consistency with
2720          * sector_size and nr_sectors. And check both of these for consistency
2721          * with volume_size.
2722          */
2723         if (opts.nr_clusters != (opts.nr_sectors * opts.sector_size) /
2724                         vol->cluster_size ||
2725             opts.volume_size / opts.sector_size != opts.nr_sectors ||
2726             opts.volume_size / vol->cluster_size != opts.nr_clusters)
2727                 err_exit("Illegal combination of volume/cluster/sector size "
2728                          "and/or cluster/sector number.\n");
2729         Dprintf("number of clusters = %Lu (0x%Lx)\n", opts.nr_clusters,
2730                         opts.nr_clusters);
2731         /* Determine lcn bitmap byte size and allocate it. */
2732         lcn_bitmap_byte_size = (opts.nr_clusters + 7) >> 3;
2733         /* Needs to be multiple of 8 bytes. */
2734         lcn_bitmap_byte_size = (lcn_bitmap_byte_size + 7) & ~7;
2735         i = (lcn_bitmap_byte_size + vol->cluster_size - 1) &
2736                         ~(vol->cluster_size - 1);
2737         Dprintf("lcn_bitmap_byte_size = %i, allocated = %i\n",
2738                         lcn_bitmap_byte_size, i);
2739         lcn_bitmap = (unsigned char *)calloc(1, lcn_bitmap_byte_size);
2740         if (!lcn_bitmap)
2741                 err_exit("Failed to allocate internal buffer: %s",
2742                                 strerror(errno));
2743         /*
2744          * $Bitmap can overlap the end of the volume. Any bits in this region
2745          * must be set. This region also encompasses the backup boot sector.
2746          */
2747         for (i = opts.nr_clusters; i < lcn_bitmap_byte_size << 3; i++)
2748                 ntfs_bit_set(lcn_bitmap, (u64)i, 1);
2749         /*
2750          * Determine mft_size: 16 mft records or 1 cluster, which ever is
2751          * bigger, rounded to multiples of cluster size.
2752          */
2753         opts.mft_size = (16 * vol->mft_record_size + vol->cluster_size - 1)
2754                         & ~(vol->cluster_size - 1);
2755         Dprintf("MFT size = %i (0x%x) bytes\n", opts.mft_size, opts.mft_size);
2756         /* Determine mft bitmap size and allocate it. */
2757         mft_bitmap_size = opts.mft_size / vol->mft_record_size;
2758         /* Convert to bytes, at least one. */
2759         mft_bitmap_byte_size = (mft_bitmap_size + 7) >> 3;
2760         /* Mft bitmap is allocated in multiples of 8 bytes. */
2761         mft_bitmap_byte_size = (mft_bitmap_byte_size + 7) & ~7;
2762         Dprintf("mft_bitmap_size = %i, mft_bitmap_byte_size = %i\n",
2763                         mft_bitmap_size, mft_bitmap_byte_size);
2764         mft_bitmap = (unsigned char *)calloc(1, mft_bitmap_byte_size);
2765         if (!mft_bitmap)
2766                 err_exit("Failed to allocate internal buffer: %s\n",
2767                                 strerror(errno));
2768         /* Create runlist for mft bitmap. */
2769         rl_mft_bmp = (runlist *)malloc(2 * sizeof(runlist));
2770         if (!rl_mft_bmp)
2771                 err_exit("Failed to allocate internal buffer: %s\n",
2772                                 strerror(errno));
2773         rl_mft_bmp[0].vcn = 0LL;
2774         /* Mft bitmap is right after $Boot's data. */
2775         j = (8192 + vol->cluster_size - 1) / vol->cluster_size;
2776         rl_mft_bmp[0].lcn = j;
2777         /*
2778          * Size is always one cluster, even though valid data size and
2779          * initialized data size are only 8 bytes.
2780          */
2781         rl_mft_bmp[1].vcn = rl_mft_bmp[0].length = 1LL;
2782         rl_mft_bmp[1].lcn = -1LL;
2783         rl_mft_bmp[1].length = 0LL;
2784         /* Allocate cluster for mft bitmap. */
2785         ntfs_bit_set(lcn_bitmap, (s64)j, 1);
2786         /* If user didn't specify the mft lcn, determine it now. */
2787         if (!opts.mft_lcn) {
2788                 /*
2789                  * We start at the higher value out of 16kiB and just after the
2790                  * mft bitmap.
2791                  */
2792                 opts.mft_lcn = rl_mft_bmp[0].lcn + rl_mft_bmp[0].length;
2793                 if (opts.mft_lcn * vol->cluster_size < 16 * 1024)
2794                         opts.mft_lcn = (16 * 1024 + vol->cluster_size - 1) /
2795                                         vol->cluster_size;
2796         }
2797         Dprintf("$MFT logical cluster number = 0x%x\n", opts.mft_lcn);
2798         /* Determine MFT zone size. */
2799         opts.mft_zone_end = opts.nr_clusters;
2800         switch (opts.mft_zone_multiplier) {  /* % of volume size in clusters */
2801         case 4:
2802                 opts.mft_zone_end = opts.mft_zone_end >> 1;     /* 50%   */
2803                 break;
2804         case 3:
2805                 opts.mft_zone_end = opts.mft_zone_end * 3 >> 3; /* 37.5% */
2806                 break;
2807         case 2:
2808                 opts.mft_zone_end = opts.mft_zone_end >> 2;     /* 25%   */
2809                 break;
2810         /* case 1: */
2811         default:
2812                 opts.mft_zone_end = opts.mft_zone_end >> 3;     /* 12.5% */
2813                 break;
2814         }
2815         Dprintf("MFT zone size = %lukiB\n", opts.mft_zone_end / 1024);
2816         /*
2817          * The mft zone begins with the mft data attribute, not at the beginning
2818          * of the device.
2819          */
2820         opts.mft_zone_end += opts.mft_lcn;
2821         /* Create runlist for mft. */
2822         rl_mft = (runlist *)malloc(2 * sizeof(runlist));
2823         if (!rl_mft)
2824                 err_exit("Failed to allocate internal buffer: %s\n",
2825                                 strerror(errno));
2826         rl_mft[0].vcn = 0LL;
2827         rl_mft[0].lcn = opts.mft_lcn;
2828         /* We already rounded mft size up to a cluster. */
2829         j = opts.mft_size / vol->cluster_size;
2830         rl_mft[1].vcn = rl_mft[0].length = j;
2831         rl_mft[1].lcn = -1LL;
2832         rl_mft[1].length = 0LL;
2833         /* Allocate clusters for mft. */
2834         for (i = 0; i < j; i++)
2835                 ntfs_bit_set(lcn_bitmap, opts.mft_lcn + i, 1);
2836         /* Determine mftmirr_lcn (middle of volume). */
2837         opts.mftmirr_lcn = (opts.nr_sectors * opts.sector_size >> 1)
2838                                                         / vol->cluster_size;
2839         Dprintf("$MFTMirr logical cluster number = 0x%x\n", opts.mftmirr_lcn);
2840         /* Create runlist for mft mirror. */
2841         rl_mftmirr = (runlist *)malloc(2 * sizeof(runlist));
2842         if (!rl_mftmirr)
2843                 err_exit("Failed to allocate internal buffer: %s\n",
2844                                 strerror(errno));
2845         rl_mftmirr[0].vcn = 0LL;
2846         rl_mftmirr[0].lcn = opts.mftmirr_lcn;
2847         /*
2848          * The mft mirror is either 4kb (the first four records) or one cluster
2849          * in size, which ever is bigger. In either case, it contains a
2850          * byte-for-byte identical copy of the beginning of the mft (i.e. either
2851          * ther first four records (4kb) or the first cluster worth of records,
2852          * whichever is bigger).
2853          */
2854         j = (4 * vol->mft_record_size + vol->cluster_size - 1) / vol->cluster_size;
2855         rl_mftmirr[1].vcn = rl_mftmirr[0].length = j;
2856         rl_mftmirr[1].lcn = -1LL;
2857         rl_mftmirr[1].length = 0LL;
2858         /* Allocate clusters for mft mirror. */
2859         for (i = 0; i < j; i++)
2860                 ntfs_bit_set(lcn_bitmap, opts.mftmirr_lcn + i, 1);
2861         opts.logfile_lcn = opts.mftmirr_lcn + j;
2862         Dprintf("$LogFile logical cluster number = 0x%x\n", opts.logfile_lcn);
2863         /* Create runlist for log file. */
2864         rl_logfile = (runlist *)malloc(2 * sizeof(runlist));
2865         if (!rl_logfile)
2866                 err_exit("Failed to allocate internal buffer: %s\n",
2867                                 strerror(errno));
2868         rl_logfile[0].vcn = 0LL;
2869         rl_logfile[0].lcn = opts.logfile_lcn;
2870         /*
2871          * Determine logfile_size from volume_size (rounded up to a cluster),
2872          * making sure it does not overflow the end of the volume.
2873          */
2874         if (opts.volume_size < 2048LL * 1024)           /* < 2MiB       */
2875                 opts.logfile_size = 256LL * 1024;       /*   -> 256kiB  */
2876         else if (opts.volume_size < 4000000LL)          /* < 4MB        */
2877                 opts.logfile_size = 512LL * 1024;       /*   -> 512kiB  */
2878         else if (opts.volume_size <= 200LL * 1024 * 1024)/* < 200MiB    */
2879                 opts.logfile_size = 2048LL * 1024;      /*   -> 2MiB    */
2880         else if (opts.volume_size >= 400LL << 20)       /* > 400MiB     */
2881                 opts.logfile_size = 4 << 20;            /*   -> 4MiB    */
2882         else
2883                 opts.logfile_size = (opts.volume_size / 100) &
2884                                 ~(vol->cluster_size - 1);
2885         j = opts.logfile_size / vol->cluster_size;
2886         while (rl_logfile[0].lcn + j >= opts.nr_clusters) {
2887                 /*
2888                  * $Logfile would overflow volume. Need to make it smaller than
2889                  * the standard size. It's ok as we are creating a non-standard
2890                  * volume anyway if it is that small.
2891                  */
2892                 opts.logfile_size >>= 1;
2893                 j = opts.logfile_size / vol->cluster_size;
2894         }
2895         opts.logfile_size = (opts.logfile_size + vol->cluster_size - 1) &
2896                         ~(vol->cluster_size - 1);
2897         Dprintf("$LogFile (journal) size = %ikiB\n", opts.logfile_size / 1024);
2898         /*
2899          * FIXME: The 256kiB limit is arbitrary. Should find out what the real
2900          * minimum requirement for Windows is so it doesn't blue screen.
2901          */
2902         if (opts.logfile_size < 256 << 10)
2903                 err_exit("$LogFile would be created with invalid size. This "
2904                                 "is not allowed as it would cause Windows to "
2905                                 "blue screen and during boot.\n");
2906         rl_logfile[1].vcn = rl_logfile[0].length = j;
2907         rl_logfile[1].lcn = -1LL;
2908         rl_logfile[1].length = 0LL;
2909         /* Allocate clusters for log file. */
2910         for (i = 0; i < j; i++)
2911                 ntfs_bit_set(lcn_bitmap, opts.logfile_lcn + i, 1);
2912         /* Create runlist for $Boot. */
2913         rl_boot = (runlist *)malloc(2 * sizeof(runlist));
2914         if (!rl_boot)
2915                 err_exit("Failed to allocate internal buffer: %s\n",
2916                                 strerror(errno));
2917         rl_boot[0].vcn = 0LL;
2918         rl_boot[0].lcn = 0LL;
2919         /*
2920          * $Boot is always 8192 (0x2000) bytes or 1 cluster, whichever is
2921          * bigger.
2922          */
2923         j = (8192 + vol->cluster_size - 1) / vol->cluster_size;
2924         rl_boot[1].vcn = rl_boot[0].length = j;
2925         rl_boot[1].lcn = -1LL;
2926         rl_boot[1].length = 0LL;
2927         /* Allocate clusters for $Boot. */
2928         for (i = 0; i < j; i++)
2929                 ntfs_bit_set(lcn_bitmap, 0LL + i, 1);
2930         /* Allocate a buffer large enough to hold the mft. */
2931         buf = calloc(1, opts.mft_size);
2932         if (!buf)
2933                 err_exit("Failed to allocate internal buffer: %s\n",
2934                                                         strerror(errno));
2935         /* Create runlist for $BadClus, $DATA named stream $Bad. */
2936         rl_bad = (runlist *)malloc(2 * sizeof(runlist));
2937         if (!rl_bad)
2938                 err_exit("Failed to allocate internal buffer: %s\n",
2939                                 strerror(errno));
2940         rl_bad[0].vcn = 0LL;
2941         rl_bad[0].lcn = -1LL;
2942         /*
2943          * $BadClus named stream $Bad contains the whole volume as a single
2944          * sparse runlist entry.
2945          */
2946         rl_bad[1].vcn = rl_bad[0].length = opts.nr_clusters;
2947         rl_bad[1].lcn = -1LL;
2948         rl_bad[1].length = 0LL;
2949
2950         // TODO: Mark bad blocks as such.
2951
2952         /*
2953          * If not quick format, fill the device with 0s.
2954          * FIXME: Except bad blocks! (AIA)
2955          */
2956         if (!opts.quick_format) {
2957                 unsigned long position;
2958                 unsigned long mid_clust;
2959                 float progress_inc = (float)opts.nr_clusters / 100;
2960
2961                 Qprintf("Initialising device with zeroes:   0%%");
2962                 fflush(stdout);
2963                 mid_clust = (opts.volume_size >> 1) / vol->cluster_size;
2964                 for (position = 0; position < opts.nr_clusters; position++) {
2965                         if (!(position % (int)(progress_inc+1))) {
2966                                 Qprintf("\b\b\b\b%3.0f%%", position /
2967                                                 progress_inc);
2968                                 fflush(stdout);
2969                         }
2970                         bw = mkntfs_write(vol->dev, buf, vol->cluster_size);
2971                         if (bw != vol->cluster_size) {
2972                                 if (bw != -1 || errno != EIO)
2973                                         err_exit("This should not happen.\n");
2974                                 if (!position)
2975                                         err_exit("Error: Cluster zero is bad. "
2976                                                 "Cannot create NTFS file "
2977                                                 "system.\n");
2978                                 if (position == mid_clust &&
2979                                                 (vol->major_ver < 1 ||
2980                                                  (vol->major_ver == 1 &&
2981                                                   vol->minor_ver < 2)))
2982                                         err_exit("Error: Bad cluster found in "
2983                                                 "location reserved for system "
2984                                                 "file $Boot.\n");
2985                                 /* Add the baddie to our bad blocks list. */
2986                                 append_to_bad_blocks(position);
2987                                 Qprintf("\nFound bad cluster (%ld). Adding to "
2988                                         "list of bad blocks.\nInitialising "
2989                                         "device with zeroes: %3.0f%%", position,
2990                                         position / progress_inc);
2991                                 /* Seek to next cluster. */
2992                                 vol->dev->d_ops->seek(vol->dev,
2993                                                 ((off_t)position + 1) *
2994                                                 vol->cluster_size, SEEK_SET);
2995                         }
2996                 }
2997                 Qprintf("\b\b\b\b100%%");
2998                 position = (opts.volume_size & (vol->cluster_size - 1)) /
2999                                 opts.sector_size;
3000                 for (i = 0; i < position; i++) {
3001                         bw = mkntfs_write(vol->dev, buf, opts.sector_size);
3002                         if (bw != opts.sector_size) {
3003                                 if (bw != -1 || errno != EIO)
3004                                         err_exit("This should not happen.\n");
3005                                 else if (i + 1 == position &&
3006                                                 (vol->major_ver >= 2 ||
3007                                                  (vol->major_ver == 1 &&
3008                                                   vol->minor_ver >= 2)))
3009                                         err_exit("Error: Bad cluster found in "
3010                                                 "location reserved for system "
3011                                                 "file $Boot.\n");
3012                                 /* Seek to next sector. */
3013                                 vol->dev->d_ops->seek(vol->dev,
3014                                                 opts.sector_size, SEEK_CUR);
3015                         }
3016                 }
3017                 Qprintf(" - Done.\n");
3018         }
3019         Qprintf("Creating NTFS volume structures.\n");
3020         /* Setup an empty mft record. */
3021         format_mft_record((MFT_RECORD*)buf);
3022         /*
3023          * Copy the mft record onto all 16 records in the buffer and setup the
3024          * sequence numbers of each system file to equal the mft record number
3025          * of that file (only for $MFT is the sequence number 1 rather than 0).
3026          */
3027         for (i = 1; i < 16; i++) {
3028                 m = (MFT_RECORD*)(buf + i * vol->mft_record_size);
3029                 memcpy(m, buf, vol->mft_record_size);
3030                 m->sequence_number = cpu_to_le16(i);
3031         }
3032         /*
3033          * If a cluster contains more than the 16 system files, fill the rest
3034          * with empty, formatted records.
3035          */
3036         if (vol->cluster_size > 16 * vol->mft_record_size) {
3037                 for (i = 16; i * vol->mft_record_size < vol->cluster_size; i++)
3038                         memcpy(buf + i * vol->mft_record_size, buf,
3039                                         vol->mft_record_size);
3040         }
3041         /*
3042          * Create the 16 system files, adding the system information attribute
3043          * to each as well as marking them in use in the mft bitmap.
3044          */
3045         for (i = 0; i < 16; i++) {
3046                 u32 file_attrs;
3047
3048                 m = (MFT_RECORD*)(buf + i * vol->mft_record_size);
3049                 m->flags |= MFT_RECORD_IN_USE;
3050                 ntfs_bit_set(mft_bitmap, 0LL + i, 1);
3051                 file_attrs = FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM;
3052                 if (i == FILE_root) {
3053                         if (opts.disable_indexing)
3054                                 file_attrs |= FILE_ATTR_NOT_CONTENT_INDEXED;
3055                         if (opts.enable_compression)
3056                                 file_attrs |= FILE_ATTR_COMPRESSED;
3057                 }
3058                 add_attr_std_info(m, file_attrs);
3059                 // dump_mft_record(m);
3060         }
3061         /* The root directory mft reference. */
3062         root_ref = MK_LE_MREF(FILE_root, FILE_root);
3063         Vprintf("Creating root directory (mft record 5)\n");
3064         m = (MFT_RECORD*)(buf + 5 * vol->mft_record_size);
3065         m->flags |= MFT_RECORD_IS_DIRECTORY;
3066         m->link_count = cpu_to_le16(le16_to_cpu(m->link_count) + 1);
3067         err = add_attr_file_name(m, root_ref, 0LL, 0LL,
3068                         FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM |
3069                         FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT, 0, 0,
3070                         ".", FILE_NAME_WIN32_AND_DOS);
3071         if (!err) {
3072                 init_system_file_sd(FILE_root, &sd, &i);
3073                 err = add_attr_sd(m, sd, i);
3074         }
3075         // FIXME: This should be IGNORE_CASE
3076         if (!err)
3077                 err = add_attr_index_root(m, "$I30", 4, 0, AT_FILE_NAME,
3078                                 COLLATION_FILE_NAME, opts.index_block_size);
3079         // FIXME: This should be IGNORE_CASE
3080         if (!err)
3081                 err = upgrade_to_large_index(m, "$I30", 4, 0, &index_block);
3082         if (!err) {
3083                 ctx = ntfs_attr_get_search_ctx(NULL, m);
3084                 if (!ctx)
3085                         err_exit("Failed to allocate attribute search "
3086                                         "context: %s\n", strerror(errno));
3087                 /* There is exactly one file name so this is ok. */
3088                 if (ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, 0, 0, NULL, 0,
3089                                 ctx)) {
3090                         ntfs_attr_put_search_ctx(ctx);
3091                         err_exit("BUG: $FILE_NAME attribute not found.\n");
3092                 }
3093                 a = ctx->attr;
3094                 err = insert_file_link_in_dir_index(index_block, root_ref,
3095                                 (FILE_NAME_ATTR*)((char*)a +
3096                                 le16_to_cpu(a->value_offset)),
3097                                 le32_to_cpu(a->value_length));
3098                 ntfs_attr_put_search_ctx(ctx);
3099         }
3100         if (err)
3101                 err_exit("Couldn't create root directory: %s\n",
3102                                 strerror(-err));
3103         // dump_mft_record(m);
3104         /* Add all other attributes, on a per-file basis for clarity. */
3105         Vprintf("Creating $MFT (mft record 0)\n");
3106         m = (MFT_RECORD*)buf;
3107         err = add_attr_data_positioned(m, NULL, 0, 0, 0, rl_mft, buf,
3108                         opts.mft_size);
3109         if (!err)
3110                 err = create_hardlink(index_block, root_ref, m,
3111                                 MK_LE_MREF(FILE_MFT, 1), opts.mft_size,
3112                                 opts.mft_size, FILE_ATTR_HIDDEN |
3113                                 FILE_ATTR_SYSTEM, 0, 0, "$MFT",
3114                                 FILE_NAME_WIN32_AND_DOS);
3115         if (!err) {
3116                 init_system_file_sd(FILE_MFT, &sd, &i);
3117                 err = add_attr_sd(m, sd, i);
3118         }
3119         /* mft_bitmap is not modified in mkntfs; no need to sync it later. */
3120         if (!err)
3121                 err = add_attr_bitmap_positioned(m, NULL, 0, 0, rl_mft_bmp,
3122                                 mft_bitmap, mft_bitmap_byte_size);
3123         if (err < 0)
3124                 err_exit("Couldn't create $MFT: %s\n", strerror(-err));
3125         //dump_mft_record(m);
3126         Vprintf("Creating $MFTMirr (mft record 1)\n");
3127         m = (MFT_RECORD*)(buf + 1 * vol->mft_record_size);
3128         err = add_attr_data_positioned(m, NULL, 0, 0, 0, rl_mftmirr, buf,
3129                         rl_mftmirr[0].length * vol->cluster_size);
3130         if (!err)
3131                 err = create_hardlink(index_block, root_ref, m,
3132                                 MK_LE_MREF(FILE_MFTMirr, FILE_MFTMirr),
3133                                 rl_mftmirr[0].length * vol->cluster_size,
3134                                 rl_mftmirr[0].length * vol->cluster_size,
3135                                 FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
3136                                 "$MFTMirr", FILE_NAME_WIN32_AND_DOS);
3137         if (!err) {
3138                 init_system_file_sd(FILE_MFTMirr, &sd, &i);
3139                 err = add_attr_sd(m, sd, i);
3140         }
3141         if (err < 0)
3142                 err_exit("Couldn't create $MFTMirr: %s\n", strerror(-err));
3143         //dump_mft_record(m);
3144         Vprintf("Creating $LogFile (mft record 2)\n");
3145         m = (MFT_RECORD*)(buf + 2 * vol->mft_record_size);
3146         buf2 = malloc(opts.logfile_size);
3147         if (!buf2)
3148                 err_exit("Failed to allocate internal buffer: %s\n",
3149                                 strerror(errno));
3150         memset(buf2, -1, opts.logfile_size);
3151         err = add_attr_data_positioned(m, NULL, 0, 0, 0, rl_logfile, buf2,
3152                         opts.logfile_size);
3153         free(buf2);
3154         buf2 = NULL;
3155         if (!err)
3156                 err = create_hardlink(index_block, root_ref, m,
3157                                 MK_LE_MREF(FILE_LogFile, FILE_LogFile),
3158                                 opts.logfile_size, opts.logfile_size,
3159                                 FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
3160                                 "$LogFile", FILE_NAME_WIN32_AND_DOS);
3161         if (!err) {
3162                 init_system_file_sd(FILE_LogFile, &sd, &i);
3163                 err = add_attr_sd(m, sd, i);
3164         }
3165         if (err < 0)
3166                 err_exit("Couldn't create $LogFile: %s\n", strerror(-err));
3167         //dump_mft_record(m);
3168         Vprintf("Creating $Volume (mft record 3)\n");
3169         m = (MFT_RECORD*)(buf + 3 * vol->mft_record_size);
3170         err = create_hardlink(index_block, root_ref, m,
3171                         MK_LE_MREF(FILE_Volume, FILE_Volume), 0LL, 0LL,
3172                         FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
3173                         "$Volume", FILE_NAME_WIN32_AND_DOS);
3174         if (!err) {
3175                 init_system_file_sd(FILE_Volume, &sd, &i);
3176                 err = add_attr_sd(m, sd, i);
3177         }
3178         if (!err)
3179                 err = add_attr_data(m, NULL, 0, 0, 0, NULL, 0);
3180         if (!err)
3181                 err = add_attr_vol_name(m, vol->vol_name, vol->vol_name ?
3182                                 strlen(vol->vol_name) : 0);
3183         if (!err) {
3184                 Qprintf("Setting the volume dirty so check disk runs on next "
3185                                 "reboot into Windows.\n");
3186                 err = add_attr_vol_info(m, VOLUME_IS_DIRTY, vol->major_ver,
3187                                 vol->minor_ver);
3188         }
3189         if (err < 0)
3190                 err_exit("Couldn't create $Volume: %s\n", strerror(-err));
3191         //dump_mft_record(m);
3192         Vprintf("Creating $AttrDef (mft record 4)\n");
3193         m = (MFT_RECORD*)(buf + 4 * vol->mft_record_size);
3194         if (vol->major_ver < 3)
3195                 buf2_size = 36000;
3196         else
3197                 buf2_size = opts.attr_defs_len;
3198         buf2 = (char*)calloc(1, buf2_size);
3199         if (!buf2)
3200                 err_exit("Failed to allocate internal buffer: %s\n",
3201                                 strerror(errno));
3202         memcpy(buf2, opts.attr_defs, opts.attr_defs_len);
3203         err = add_attr_data(m, NULL, 0, 0, 0, buf2, buf2_size);
3204         free(buf2);
3205         buf2 = NULL;
3206         if (!err)
3207                 err = create_hardlink(index_block, root_ref, m,
3208                                 MK_LE_MREF(FILE_AttrDef, FILE_AttrDef),
3209                                 (buf2_size + vol->cluster_size - 1) &
3210                                 ~(vol->cluster_size - 1), buf2_size,
3211                                 FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
3212                                 "$AttrDef", FILE_NAME_WIN32_AND_DOS);
3213         buf2_size = 0;
3214         if (!err) {
3215                 init_system_file_sd(FILE_AttrDef, &sd, &i);
3216                 err = add_attr_sd(m, sd, i);
3217         }
3218         if (err < 0)
3219                 err_exit("Couldn't create $AttrDef: %s\n", strerror(-err));
3220         //dump_mft_record(m);
3221         Vprintf("Creating $Bitmap (mft record 6)\n");
3222         m = (MFT_RECORD*)(buf + 6 * vol->mft_record_size);
3223         err = add_attr_data(m, NULL, 0, 0, 0, lcn_bitmap, lcn_bitmap_byte_size);
3224         if (!err)
3225                 err = create_hardlink(index_block, root_ref, m,
3226                                 MK_LE_MREF(FILE_Bitmap, FILE_Bitmap),
3227                                 (lcn_bitmap_byte_size + vol->cluster_size - 1) &
3228                                 ~(vol->cluster_size - 1), lcn_bitmap_byte_size,
3229                                 FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
3230                                 "$Bitmap", FILE_NAME_WIN32_AND_DOS);
3231         if (!err) {
3232                 init_system_file_sd(FILE_Bitmap, &sd, &i);
3233                 err = add_attr_sd(m, sd, i);
3234         }
3235         if (err < 0)
3236                 err_exit("Couldn't create $Bitmap: %s\n", strerror(-err));
3237         //dump_mft_record(m);
3238         Vprintf("Creating $Boot (mft record 7)\n");
3239         m = (MFT_RECORD*)(buf + 7 * vol->mft_record_size);
3240         buf2 = calloc(1, 8192);
3241         if (!buf2)
3242                 err_exit("Failed to allocate internal buffer: %s\n",
3243                                 strerror(errno));
3244         memcpy(buf2, boot_array, sizeof(boot_array));
3245         /*
3246          * Create the boot sector into buf2. Note, that buf2 already is zeroed
3247          * in the boot sector section and that it has the NTFS OEM id/magic
3248          * already inserted, so no need to worry about these things.
3249          */
3250         bs = (NTFS_BOOT_SECTOR*)buf2;
3251         bs->bpb.bytes_per_sector = cpu_to_le16(opts.sector_size);
3252         bs->bpb.sectors_per_cluster = (u8)(vol->cluster_size /
3253                         opts.sector_size);
3254         bs->bpb.media_type = 0xf8; /* hard disk */
3255         /*
3256          * If there are problems go back to bs->unused[0-3] and set them. See
3257          * ../include/bootsect.h for details. Other fields to also consider
3258          * setting are: bs->bpb.sectors_per_track, .heads, and .hidden_sectors.
3259          */
3260         bs->number_of_sectors = scpu_to_le64(opts.nr_sectors);
3261         bs->mft_lcn = scpu_to_le64(opts.mft_lcn);
3262         bs->mftmirr_lcn = scpu_to_le64(opts.mftmirr_lcn);
3263         if (vol->mft_record_size >= vol->cluster_size)
3264                 bs->clusters_per_mft_record = vol->mft_record_size /
3265                         vol->cluster_size;
3266         else {
3267                 bs->clusters_per_mft_record = -(ffs(vol->mft_record_size) - 1);
3268                 if ((1 << -bs->clusters_per_mft_record) != vol->mft_record_size)
3269                         err_exit("BUG: calculated clusters_per_mft_record "
3270                                         "is wrong (= 0x%x)\n",
3271                                         bs->clusters_per_mft_record);
3272         }
3273         Dprintf("Clusters per mft record = %i (0x%x)\n",
3274                         bs->clusters_per_mft_record,
3275                         bs->clusters_per_mft_record);
3276         if (opts.index_block_size >= vol->cluster_size)
3277                 bs->clusters_per_index_record = opts.index_block_size /
3278                         vol->cluster_size;
3279         else {
3280                 bs->clusters_per_index_record = -(ffs(opts.index_block_size) - 1);
3281                 if ((1 << -bs->clusters_per_index_record) !=
3282                                 opts.index_block_size)
3283                         err_exit("BUG: calculated clusters_per_index_record "
3284                                         "is wrong (= 0x%x)\n",
3285                                         bs->clusters_per_index_record);
3286         }
3287         Dprintf("Clusters per index block = %i (0x%x)\n",
3288                         bs->clusters_per_index_record,
3289                         bs->clusters_per_index_record);
3290         /* Generate a 64-bit random number for the serial number. */
3291         bs->volume_serial_number = scpu_to_le64(((s64)random() << 32) |
3292                         ((s64)random() & 0xffffffff));
3293         /*
3294          * Leave zero for now as NT4 leaves it zero, too. If want it later, see
3295          * ../libntfs/bootsect.c for how to calculate it.
3296          */
3297         bs->checksum = cpu_to_le32(0);
3298         /* Make sure the bootsector is ok. */
3299         if (!ntfs_boot_sector_is_ntfs(bs, opts.verbose > 0 ? 0 : 1))
3300                 err_exit("FATAL: Generated boot sector is invalid!\n");
3301         err = add_attr_data_positioned(m, NULL, 0, 0, 0, rl_boot, buf2, 8192);
3302         if (!err)
3303                 err = create_hardlink(index_block, root_ref, m,
3304                                 MK_LE_MREF(FILE_Boot, FILE_Boot),
3305                                 (8192 + vol->cluster_size - 1) &
3306                                 ~(vol->cluster_size - 1), 8192,
3307                                 FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
3308                                 "$Boot", FILE_NAME_WIN32_AND_DOS);
3309         if (!err) {
3310                 init_system_file_sd(FILE_Boot, &sd, &i);
3311                 err = add_attr_sd(m, sd, i);
3312         }
3313         if (err < 0)
3314                 err_exit("Couldn't create $Boot: %s\n", strerror(-err));
3315         Vprintf("Creating backup boot sector.\n");
3316         /*
3317          * Write the first max(512, opts.sector_size) bytes from buf2 to the
3318          * last sector.
3319          */
3320         if (vol->dev->d_ops->seek(vol->dev, (opts.nr_sectors + 1) *
3321                         opts.sector_size - i, SEEK_SET) == (off_t)-1)
3322                 goto bb_err;
3323         bw = mkntfs_write(vol->dev, buf2, i);
3324         free(buf2);
3325         buf2 = NULL;
3326         if (bw != i) {
3327                 int _e = errno;
3328                 char *_s;
3329
3330                 if (bw == -1LL)
3331                         _s = strerror(_e);
3332                 else
3333                         _s = "unknown error";
3334                 if (bw != -1LL || (bw == -1LL && _e != ENOSPC)) {
3335                         err_exit("Couldn't write backup boot sector: %s\n", _s);
3336 bb_err:
3337                         Eprintf("Seek failed: %s\n", strerror(errno));
3338                 }
3339                 Eprintf("Couldn't write backup boot sector. This is due to a "
3340                                 "limitation in the\nLinux kernel. This is not "
3341                                 "a major problem as Windows check disk will "
3342                                 "create the\nbackup boot sector when it "
3343                                 "is run on your next boot into Windows.\n");
3344         }
3345         //dump_mft_record(m);
3346         Vprintf("Creating $BadClus (mft record 8)\n");
3347         m = (MFT_RECORD*)(buf + 8 * vol->mft_record_size);
3348         // FIXME: This should be IGNORE_CASE
3349         /* Create a sparse named stream of size equal to the volume size. */
3350         err = add_attr_data_positioned(m, "$Bad", 4, 0, 0, rl_bad, NULL,
3351                         opts.nr_clusters * vol->cluster_size);
3352         if (!err) {
3353                 err = add_attr_data(m, NULL, 0, 0, 0, NULL, 0);
3354         }
3355         if (!err) {
3356                 err = create_hardlink(index_block, root_ref, m,
3357                                 MK_LE_MREF(FILE_BadClus, FILE_BadClus),
3358                                 0LL, 0LL, FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM,
3359                                 0, 0, "$BadClus", FILE_NAME_WIN32_AND_DOS);
3360         }
3361         if (!err) {
3362                 init_system_file_sd(FILE_BadClus, &sd, &i);
3363                 err = add_attr_sd(m, sd, i);
3364         }
3365         if (err < 0)
3366                 err_exit("Couldn't create $BadClus: %s\n", strerror(-err));
3367         //dump_mft_record(m);
3368         Vprintf("Creating $Quota (mft record 9)\n");
3369         m = (MFT_RECORD*)(buf + 9 * vol->mft_record_size);
3370         err = add_attr_data(m, NULL, 0, 0, 0, NULL, 0);
3371         if (!err)
3372                 err = create_hardlink(index_block, root_ref, m,
3373                                 MK_LE_MREF(9, 9), 0LL, 0LL, FILE_ATTR_HIDDEN
3374                                 | FILE_ATTR_SYSTEM, 0, 0, "$Quota",
3375                                 FILE_NAME_WIN32_AND_DOS);
3376         if (!err) {
3377                 init_system_file_sd(FILE_Secure, &sd, &i);
3378                 err = add_attr_sd(m, sd, i);
3379         }
3380         if (err < 0)
3381                 err_exit("Couldn't create $Quota: %s\n", strerror(-err));
3382         //dump_mft_record(m);
3383         Vprintf("Creating $UpCase (mft record 0xa)\n");
3384         m = (MFT_RECORD*)(buf + 0xa * vol->mft_record_size);
3385         err = add_attr_data(m, NULL, 0, 0, 0, (char*)vol->upcase,
3386                         vol->upcase_len << 1);
3387         if (!err)
3388                 err = create_hardlink(index_block, root_ref, m,
3389                                 MK_LE_MREF(FILE_UpCase, FILE_UpCase),
3390                                 ((vol->upcase_len << 1) + vol->cluster_size - 1) &
3391                                 ~(vol->cluster_size - 1), vol->upcase_len << 1,
3392                                 FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
3393                                 "$UpCase", FILE_NAME_WIN32_AND_DOS);
3394         if (!err) {
3395                 init_system_file_sd(FILE_UpCase, &sd, &i);
3396                 err = add_attr_sd(m, sd, i);
3397         }
3398         if (err < 0)
3399                 err_exit("Couldn't create $UpCase: %s\n", strerror(-err));
3400         //dump_mft_record(m);
3401         /* NTFS 1.2 reserved system files (mft records 0xb-0xf) */
3402         for (i = 0xb; i < 0x10; i++) {
3403                 Vprintf("Creating system file (mft record 0x%x)\n", i);
3404                 m = (MFT_RECORD*)(buf + i * vol->mft_record_size);
3405                 err = add_attr_data(m, NULL, 0, 0, 0, NULL, 0);
3406                 if (!err) {
3407                         init_system_file_sd(i, &sd, &j);
3408                         err = add_attr_sd(m, sd, j);
3409                 }
3410                 if (err < 0)
3411                         err_exit("Couldn't create system file %i (0x%x): %s\n",
3412                                         i, i, strerror(-err));
3413                 //dump_mft_record(m);
3414         }
3415 // - Do not step onto bad blocks!!!
3416 // - If any bad blocks were specified or found, modify $BadClus, allocating the
3417 //   bad clusters in $Bitmap.
3418 // - C&w bootsector backup bootsector (backup in last sector of the
3419 //   partition).
3420 // - If NTFS 3.0+, c&w $Secure file and $Extend directory with the
3421 //   corresponding special files in it, i.e. $ObjId, $Quota, $Reparse, and
3422 //   $UsnJrnl. And others? Or not all necessary?
3423 // - RE: Populate $root with the system files (and $Extend directory if
3424 //   applicable). Possibly should move this as far to the top as possible and
3425 //   update during each subsequent c&w of each system file.
3426         Vprintf("Syncing root directory index record.\n");
3427         m = (MFT_RECORD*)(buf + 5 * vol->mft_record_size);
3428         i = 5 * sizeof(uchar_t);
3429         ctx = ntfs_attr_get_search_ctx(NULL, m);
3430         if (!ctx)
3431                 err_exit("Failed to allocate attribute search context: %s\n",
3432                                 strerror(errno));
3433         // FIXME: This should be IGNORE_CASE!
3434         if (ntfs_attr_lookup(AT_INDEX_ALLOCATION, I30, 4, 0, 0,
3435                         NULL, 0, ctx)) {
3436                 ntfs_attr_put_search_ctx(ctx);
3437                 err_exit("BUG: $INDEX_ALLOCATION attribute not found.\n");
3438         }
3439         a = ctx->attr;
3440         rl_index = ntfs_mapping_pairs_decompress(vol, a, NULL);
3441         if (!rl_index) {
3442                 ntfs_attr_put_search_ctx(ctx);
3443                 err_exit("Failed to decompress runlist of $INDEX_ALLOCATION "
3444                                 "attribute.\n");
3445         }
3446         if (sle64_to_cpu(a->initialized_size) < i) {
3447                 ntfs_attr_put_search_ctx(ctx);
3448                 err_exit("BUG: $INDEX_ALLOCATION attribute too short.\n");
3449         }
3450         ntfs_attr_put_search_ctx(ctx);
3451         i = sizeof(INDEX_BLOCK) - sizeof(INDEX_HEADER) +
3452                         le32_to_cpu(index_block->index.allocated_size);
3453         err = ntfs_mst_pre_write_fixup((NTFS_RECORD*)index_block, i);
3454         if (err)
3455                 err_exit("ntfs_mst_pre_write_fixup() failed while syncing "
3456                                 "root directory index block.\n");
3457         lw = ntfs_rlwrite(vol->dev, rl_index, (char*)index_block, i, NULL);
3458         if (lw != i)
3459                 err_exit("Error writing $INDEX_ALLOCATION.\n");
3460         /* No more changes to @index_block below here so no need for fixup: */
3461         // ntfs_mst_post_write_fixup((NTFS_RECORD*)index_block);
3462         Vprintf("Syncing $Bitmap.\n");
3463         m = (MFT_RECORD*)(buf + 6 * vol->mft_record_size);
3464         ctx = ntfs_attr_get_search_ctx(NULL, m);
3465         if (!ctx)
3466                 err_exit("Failed to allocate attribute search context: %s\n",
3467                                 strerror(errno));
3468         if (ntfs_attr_lookup(AT_DATA, AT_UNNAMED, 0, 0, 0, NULL, 0, ctx)) {
3469                 ntfs_attr_put_search_ctx(ctx);
3470                 err_exit("BUG: $DATA attribute not found.\n");
3471         }
3472         a = ctx->attr;
3473         if (a->non_resident) {
3474                 rl = ntfs_mapping_pairs_decompress(vol, a, NULL);
3475                 ntfs_attr_put_search_ctx(ctx);
3476                 if (!rl)
3477                         err_exit("ntfs_mapping_pairs_decompress() failed\n");
3478                 lw = ntfs_rlwrite(vol->dev, rl, lcn_bitmap,
3479                                 lcn_bitmap_byte_size, NULL);
3480                 if (lw != lcn_bitmap_byte_size)
3481                         err_exit("%s\n", lw == -1 ? strerror(errno) :
3482                                         "unknown error");
3483         } else {
3484                 memcpy((char*)a + le16_to_cpu(a->value_offset), lcn_bitmap,
3485                                 le32_to_cpu(a->value_length));
3486                 ntfs_attr_put_search_ctx(ctx);
3487         }
3488         /*
3489          * No need to sync $MFT/$BITMAP as that has never been modified since
3490          * its creation.
3491          */
3492         Vprintf("Syncing $MFT.\n");
3493         pos = opts.mft_lcn * vol->cluster_size;
3494         lw = 1;
3495         for (i = 0; i < opts.mft_size / vol->mft_record_size; i++) {
3496                 if (!opts.no_action)
3497                         lw = ntfs_mst_pwrite(vol->dev, pos, 1,
3498                                         vol->mft_record_size,
3499                                         buf + i * vol->mft_record_size);
3500                 if (lw != 1)
3501                         err_exit("%s\n", lw == -1 ? strerror(errno) :
3502                                                 "unknown error");
3503                 pos += vol->mft_record_size;
3504         }
3505         Vprintf("Updating $MFTMirr.\n");
3506         pos = opts.mftmirr_lcn * vol->cluster_size;
3507         lw = 1;
3508         for (i = 0; i < rl_mftmirr[0].length * vol->cluster_size /
3509                         vol->mft_record_size; i++) {
3510                 u16 usn, *usnp;
3511                 m = (MFT_RECORD*)(buf + i * vol->mft_record_size);
3512                 /*
3513                  * Decrement the usn by one, so it becomes the same as the one
3514                  * in $MFT once it is mst protected. - This is as we need the
3515                  * $MFTMirr to have the exact same byte by byte content as
3516                  * $MFT, rather than just equivalent meaning content.
3517                  */
3518                 usnp = (u16*)((char*)m + le16_to_cpu(m->usa_ofs));
3519                 usn = le16_to_cpup(usnp);
3520                 if (usn-- <= 1)
3521                         usn = 0xfffe;
3522                 *usnp = cpu_to_le16(usn);
3523                 if (!opts.no_action)
3524                         lw = ntfs_mst_pwrite(vol->dev, pos, 1,
3525                                         vol->mft_record_size,
3526                                         buf + i * vol->mft_record_size);
3527                 if (lw != 1)
3528                         err_exit("%s\n", lw == -1 ? strerror(errno) :
3529                                         "unknown error");
3530                 pos += vol->mft_record_size;
3531         }
3532         Vprintf("Syncing device.\n");
3533         if (vol->dev->d_ops->sync(vol->dev))
3534                 err_exit("Syncing device. FAILED: %s", strerror(errno));
3535         Qprintf("mkntfs completed successfully. Have a nice day.\n");
3536         /*
3537          * Device is unlocked and closed by the registered exit function
3538          * mkntfs_exit().
3539          */
3540         return 0;
3541 }
3542