2 * mkntfs - Part of the Linux-NTFS project.
4 * Copyright (c) 2000-2003 Anton Altaparmakov
5 * Copyright (c) 2001-2003 Richard Russon
7 * This utility will create an NTFS 1.2 (Windows NT 4.0) volume on a user
8 * specified (block) device.
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
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.
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.
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
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
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!
42 * Anton Altaparmakov <aia21@cantab.net>
74 #ifdef HAVE_LINUX_MAJOR_H
75 # include <linux/major.h>
78 # define MAJOR(dev) ((dev) >> 8)
79 # define MINOR(dev) ((dev) & 0xff)
81 #ifndef SCSI_BLK_MAJOR
82 # define SCSI_BLK_MAJOR(m) ((m) == SCSI_DISK_MAJOR || \
83 (m) == SCSI_CDROM_MAJOR)
87 #if defined(linux) && defined(_IO) && !defined(BLKSSZGET)
88 # define BLKSSZGET _IO(0x12,104) /* Get device sector size in bytse. */
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,
107 extern void init_upcase_table(uchar_t *uc, u32 uc_len);
109 /* Page size on ia32. Can change to 8192 on Alpha. */
110 #define NTFS_PAGE_SIZE 4096
112 const char *EXEC_NAME = "mkntfs";
114 /* Need these global so mkntfs_exit can access them. */
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;
129 int sector_size; /* -s, in bytes, power of 2, default is
131 long long nr_sectors; /* size of device in sectors */
132 long long nr_clusters; /* Note: Win2k treats clusters as
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
144 char mft_zone_multiplier; /* -z, value from 1 to 4. Default is
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
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
164 int force; /* -F, force fs creation. */
165 char quick_format; /* -f or -Q, fast format, don't zero
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. */
175 * Dprintf - debugging output (-vv); overriden by quiet (-q)
177 void Dprintf(const char *fmt, ...)
181 if (!opts.quiet && opts.verbose > 1) {
190 * Eprintf - error output; ignores quiet (-q)
192 void Eprintf(const char *fmt, ...)
196 fprintf(stderr, "ERROR: ");
198 vfprintf(stderr, fmt, ap);
202 /* Generate code for Vprintf() function: Verbose output (-v). */
203 GEN_PRINTF(Vprintf, stdout, &opts.verbose, TRUE)
205 /* Generate code for Qprintf() function: Quietable output (if not -q). */
206 GEN_PRINTF(Qprintf, stdout, &opts.quiet, FALSE)
209 * err_exit - error output and terminate; ignores quiet (-q)
211 void err_exit(const char *fmt, ...)
215 fprintf(stderr, "ERROR: ");
217 vfprintf(stderr, fmt, ap);
219 fprintf(stderr, "Aborting...\n");
225 * copyright - print copyright statements
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) "
236 * license - print license statement
240 fprintf(stderr, "%s", ntfs_gpl);
244 * usage - print a list of the parameters to the program
246 void usage(void) __attribute__ ((noreturn));
250 fprintf(stderr, "Usage: %s [options] device "
251 "[number-of-sectors]\n"
252 " -s sector-size Specify the sector size "
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 "
259 " -f Perform a quick format\n"
260 " -Q Perform a quick format\n"
261 " -C Enable compression on "
263 " -I Disable indexing on the "
265 " -n Do not write to disk\n"
266 " -F Force execution despite "
268 " -q Quiet execution\n"
269 " -v Verbose execution\n"
270 " -vv Very verbose execution\n"
271 " -V Display version "
273 " -l Display licensing "
275 " -h Display this help\n",
277 fprintf(stderr, "%s%s", ntfs_bugs, ntfs_home);
284 void parse_options(int argc, char *argv[])
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, ...
295 fprintf(stderr, "%s v%s\n", EXEC_NAME, VERSION);
296 while ((c = getopt(argc, argv, "c:fh?nqs:vz:CFIL:QVl")) != EOF)
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;
309 opts.quick_format = 1;
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;
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;
330 opts.enable_compression = 1;
336 opts.disable_indexing = 1;
339 vol->vol_name = optarg;
342 /* Version number already printed, so just exit. */
355 dev_name = argv[optind++];
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",
368 * append_to_bad_blocks
370 void append_to_bad_blocks(unsigned long block)
374 if (!(opts.nr_bad_blocks & 15)) {
375 new_buf = realloc(opts.bad_blocks, (opts.nr_bad_blocks + 16) *
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;
384 opts.bad_blocks[opts.nr_bad_blocks++] = block;
390 __inline__ long long mkntfs_write(struct ntfs_device *dev, const void *buf,
393 long long bytes_written, total;
401 bytes_written = dev->d_ops->write(dev, buf, count);
402 if (bytes_written == -1LL) {
404 Eprintf("Error writing to %s: %s\n", vol->dev->d_name,
407 return bytes_written;
408 } else if (!bytes_written)
411 count -= bytes_written;
412 total += bytes_written;
414 } while (count && retry < 3);
416 Eprintf("Failed to complete writing to %s after three retries."
417 "\n", vol->dev->d_name);
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.
425 * If the @rl specifies a completely sparse file, @val is allowed to be NULL.
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.
431 * Return the number of bytes written (minus padding) or -1 on error. Errno
432 * will be set to the error code.
434 s64 ntfs_rlwrite(struct ntfs_device *dev, const runlist *rl, const char *val,
435 const s64 val_len, s64 *inited_size)
437 s64 bytes_written, total, length, delta;
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) {
452 // TODO: Check that *val is really zero at pos and len.
455 if (dev->d_ops->seek(dev, rl[i].lcn * vol->cluster_size,
456 SEEK_SET) == (off_t)-1)
460 if (total + length > val_len) {
462 length = val_len - total;
465 bytes_written = dev->d_ops->write(dev, val + total,
467 if (bytes_written == -1LL) {
469 Eprintf("Error writing to %s: %s\n",
473 return bytes_written;
476 length -= bytes_written;
477 total += bytes_written;
479 *inited_size += bytes_written;
482 } while (length && retry < 3);
484 Eprintf("Failed to complete writing to %s after three "
485 "retries.\n", vol->dev->d_name);
490 char *buf = (char*)calloc(1, delta);
492 err_exit("Error allocating internal buffer: "
493 "%s\n", strerror(errno));
494 bytes_written = mkntfs_write(dev, buf, delta);
496 if (bytes_written == -1LL)
497 return bytes_written;
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
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.
512 int ucstos(char *dest, const uchar_t *src, int maxlen)
517 /* Need one byte for null terminator. */
519 for (i = 0; i < maxlen; i++) {
520 u = le16_to_cpu(src[i]);
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
537 * Return the number of characters written to @dest, not including the
538 * terminating null unicode character.
540 int stoucs(uchar_t *dest, const char *src, int maxlen)
545 /* Need two bytes for null terminator. */
547 for (i = 0; i < maxlen; i++) {
551 dest[i] = cpu_to_le16(c);
553 dest[i] = cpu_to_le16('\0');
558 * dump_resident_attr_val
560 void dump_resident_attr_val(ATTR_TYPES type, char *val, u32 val_len)
562 const char *don_t_know = "Don't know what to do with this attribute "
564 const char *skip = "Skipping display of $%s attribute value.\n";
565 const char *todo = "This is still work in progress.";
570 case AT_STANDARD_INFORMATION:
572 printf("%s\n", todo);
574 case AT_ATTRIBUTE_LIST:
576 printf("%s\n", todo);
580 printf("%s\n", todo);
584 printf("%s\n", todo);
586 case AT_SECURITY_DESCRIPTOR:
588 printf("%s\n", todo);
591 printf("Volume name length = %i\n", val_len);
593 buf = calloc(1, val_len);
595 err_exit("Failed to allocate internal buffer: "
596 "%s\n", strerror(errno));
597 i = ucstos(buf, (uchar_t*)val, val_len);
599 printf("Volume name contains non-displayable "
600 "Unicode characters.\n");
601 printf("Volume name = %s\n", buf);
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;
611 printf("Volume flags = 0x%x: ", i);
617 if (i & VOLUME_MODIFIED_BY_CHKDSK) {
619 printf("VOLUME_MODIFIED_BY_CHKDSK");
621 if (i & VOLUME_REPAIR_OBJECT_ID) {
626 printf("VOLUME_REPAIR_OBJECT_ID");
628 if (i & VOLUME_DELETE_USN_UNDERWAY) {
633 printf("VOLUME_DELETE_USN_UNDERWAY");
635 if (i & VOLUME_MOUNTED_ON_NT4) {
640 printf("VOLUME_MOUNTED_ON_NT4");
642 if (i & VOLUME_UPGRADE_ON_MOUNT) {
647 printf("VOLUME_UPGRADE_ON_MOUNT");
649 if (i & VOLUME_RESIZE_LOG_FILE) {
654 printf("VOLUME_RESIZE_LOG_FILE");
656 if (i & VOLUME_IS_DIRTY) {
661 printf("VOLUME_IS_DIRTY");
666 printf(skip, "DATA");
670 printf("%s\n", todo);
672 case AT_INDEX_ALLOCATION:
674 printf("%s\n", todo);
677 printf(skip, "BITMAP");
679 case AT_REPARSE_POINT:
681 printf("%s\n", todo);
683 case AT_EA_INFORMATION:
685 printf("%s\n", don_t_know);
689 printf("%s\n", don_t_know);
691 case AT_LOGGED_UTILITY_STREAM:
693 printf("%s\n", don_t_know);
696 i = le32_to_cpu(type);
697 printf("Cannot display unknown %s defined attribute type 0x%x"
699 le32_to_cpu(AT_FIRST_USER_DEFINED_ATTRIBUTE) ?
700 "user" : "system", i);
707 void dump_resident_attr(ATTR_RECORD *a)
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);
719 else if (i & ~RESIDENT_ATTR_IS_INDEXED)
720 printf("UNKNOWN FLAG(S)\n");
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));
728 * dump_mapping_pairs_array
730 void dump_mapping_pairs_array(char *b, unsigned int max_len)
737 * dump_non_resident_attr
739 void dump_non_resident_attr(ATTR_RECORD *a)
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);
765 i = le16_to_cpu(a->mapping_pairs_offset);
766 dump_mapping_pairs_array((char*)a + i, le32_to_cpu(a->length) - i);
772 void dump_attr_record(ATTR_RECORD *a)
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);
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)
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]);
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",
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));
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",
820 printf("Name = %s\n", s);
822 printf("Attribute flags = 0x%x: ", le16_to_cpu(u));
827 if (u & ATTR_COMPRESSION_MASK) {
828 if (u & ATTR_IS_COMPRESSED) {
829 printf("ATTR_IS_COMPRESSED");
832 if ((u & ATTR_COMPRESSION_MASK) & ~ATTR_IS_COMPRESSED) {
837 printf("ATTR_UNKNOWN_COMPRESSION");
840 if (u & ATTR_IS_ENCRYPTED) {
845 printf("ATTR_IS_ENCRYPTED");
847 if (u & ATTR_IS_SPARSE) {
852 printf("ATTR_IS_SPARSE");
856 printf("Attribute instance = %u\n", le16_to_cpu(a->instance));
857 if (a->non_resident) {
858 dump_non_resident_attr(a);
860 dump_resident_attr(a);
867 void dump_mft_record(MFT_RECORD *m)
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");
890 printf("MFT_RECORD_NOT_IN_USE");
891 if (m->flags & MFT_RECORD_IS_DIRECTORY)
892 printf(" | MFT_RECORD_IS_DIRECTORY");
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)) {
907 if (a->type == AT_END)
909 a = (ATTR_RECORD*)((char*)a + le32_to_cpu(a->length));
911 printf("-- End of attributes. --\n");
917 void format_mft_record(MFT_RECORD *m)
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);
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.");
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);
946 * Using attrs_offset plus eight bytes (for the termination attribute),
947 * aligned to 8-byte boundary.
949 m->bytes_in_use = cpu_to_le32((le16_to_cpu(m->attrs_offset) + 8 + 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));
956 a->length = cpu_to_le32(0);
958 if (!opts.quiet && opts.verbose > 1)
964 * make_room_for_attribute - make room for an attribute inside an mft record
966 * @pos: position at which to make space
967 * @size: byte size to make available at this position
969 * @pos points to the attribute in front of which we want to make space.
971 * Return 0 on success or -errno on error. Possible error codes are:
973 * -ENOSPC There is not enough space available to complete
974 * operation. The caller has to make space before calling
976 * -EINVAL Can only occur if mkntfs was compiled with -DEBUG. Means
977 * the input parameters were faulty.
979 int make_room_for_attribute(MFT_RECORD *m, char *pos, const u32 size)
987 * Rigorous consistency checks. Always return -EINVAL even if more
988 * appropriate codes exist for simplicity of parsing the return value.
990 if (size != ((size + 7) & ~7)) {
991 Eprintf("make_room_for_attribute() received non 8-byte aligned"
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))
1001 /* The -8 is for the attribute terminator. */
1002 if (pos - (char*)m > le32_to_cpu(m->bytes_in_use) - 8)
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))
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);
1017 * deallocate_scattered_clusters
1019 void deallocate_scattered_clusters(const runlist *rl)
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)
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);
1038 * allocate_scattered_clusters
1039 * Allocate @clusters and create a runlist of the allocated clusters.
1041 * Return the allocated runlist. Caller has to free the runlist when finished
1044 * On error return NULL and errno is set to the error code.
1046 * TODO: We should be returning the size as well, but for mkntfs this is not
1049 runlist *allocate_scattered_clusters(s64 clusters)
1051 runlist *rl = NULL, *rlt;
1053 LCN lcn, end, prev_lcn = 0LL;
1056 s64 prev_run_len = 0LL;
1059 end = opts.nr_clusters;
1060 /* Loop until all clusters are allocated. */
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);
1068 * Reallocate memory if necessary. Make sure we have
1069 * enough for the terminator entry as well.
1071 if ((rlpos + 2) * sizeof(runlist) >= rlsize) {
1072 rlsize += 4096; /* PAGE_SIZE */
1073 rlt = realloc(rl, rlsize);
1078 /* Coalesce with previous run if adjacent LCNs. */
1079 if (prev_lcn == lcn - prev_run_len) {
1080 rl[rlpos - 1].length = ++prev_run_len;
1083 rl[rlpos].vcn = vcn++;
1084 rl[rlpos].lcn = prev_lcn = lcn;
1085 rl[rlpos].length = prev_run_len = 1LL;
1090 /* Add terminator element and return. */
1091 rl[rlpos].vcn = vcn;
1092 rl[rlpos].lcn = rl[rlpos].length = 0LL;
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)
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. */
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.
1125 * Return 0 on success and -errno on error.
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)
1132 ntfs_attr_search_ctx *ctx;
1135 int asize, mpa_size, err, i;
1136 s64 bw = 0, inited_size;
1145 i = (name_len + 1) * sizeof(uchar_t);
1146 uname = (uchar_t*)calloc(1, i);
1149 name_len = stoucs(uname, name, i);
1150 if (name_len > 0xff) {
1152 return -ENAMETOOLONG;
1156 /* Check if the attribute is already there. */
1157 ctx = ntfs_attr_get_search_ctx(NULL, m);
1159 Eprintf("Failed to allocate attribute search context.\n");
1163 if (ic == IGNORE_CASE) {
1164 Eprintf("FIXME: Hit unimplemented code path #1.\n");
1168 if (!ntfs_attr_lookup(type, uname, name_len, ic, 0, NULL, 0, ctx)) {
1172 if (errno != ENOENT) {
1173 Eprintf("Corrupt inode.\n");
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.
1185 if (flags & (ATTR_IS_ENCRYPTED || ATTR_IS_SPARSE)) {
1186 Eprintf("Encrypted/sparse attributes not supported yet.\n");
1190 if (flags & ATTR_COMPRESSION_MASK) {
1192 // FIXME: This compression stuff is all wrong. Never mind for
1195 mpa_size = 0; //get_size_for_compressed_mapping_pairs(rl);
1201 mpa_size = ntfs_get_size_for_mapping_pairs(vol, rl);
1204 Eprintf("Failed to get size for mapping "
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");
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
1236 // FIXME: the check for needing extension records should be
1237 // earlier on as it is very quick: asize > m->bytes_allocated?
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");
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);
1255 a->instance = m->next_attr_instance;
1256 m->next_attr_instance = cpu_to_le16((le16_to_cpu(m->next_attr_instance)
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);
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;
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();
1282 a->compression_unit = 0;
1283 bw = ntfs_rlwrite(vol->dev, rl, val, val_len, &inited_size);
1285 Eprintf("Error writing non-resident attribute value."
1287 err = ntfs_mapping_pairs_build(vol, (s8*)a + hdr_size +
1288 ((name_len + 7) & ~7), mpa_size, rl);
1290 a->initialized_size = cpu_to_le64(inited_size);
1291 if (err < 0 || bw != val_len) {
1292 // FIXME: Handle error.
1293 // deallocate clusters
1297 Eprintf("insert_positioned_attr_in_mft_record failed with "
1298 "error %i.\n", err < 0 ? err : (int)bw);
1302 ntfs_attr_put_search_ctx(ctx);
1309 * insert_non_resident_attr_in_mft_record
1310 * Return 0 on success and -errno on error.
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)
1316 ntfs_attr_search_ctx *ctx;
1319 int asize, mpa_size, err, i;
1329 i = (name_len + 1) * sizeof(uchar_t);
1330 uname = (uchar_t*)calloc(1, i);
1333 name_len = stoucs(uname, name, i);
1334 if (name_len > 0xff) {
1336 return -ENAMETOOLONG;
1340 /* Check if the attribute is already there. */
1341 ctx = ntfs_attr_get_search_ctx(NULL, m);
1343 Eprintf("Failed to allocate attribute search context.\n");
1347 if (ic == IGNORE_CASE) {
1348 Eprintf("FIXME: Hit unimplemented code path #2.\n");
1352 if (!ntfs_attr_lookup(type, uname, name_len, ic, 0, NULL, 0, ctx)) {
1356 if (errno != ENOENT) {
1357 Eprintf("Corrupt inode.\n");
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.
1369 if (flags & (ATTR_IS_ENCRYPTED || ATTR_IS_SPARSE)) {
1370 Eprintf("Encrypted/sparse attributes not supported yet.\n");
1375 rl = allocate_scattered_clusters((val_len +
1376 vol->cluster_size - 1) / vol->cluster_size);
1379 Eprintf("Failed to allocate scattered clusters: %s\n",
1385 if (flags & ATTR_COMPRESSION_MASK) {
1387 // FIXME: This compression stuff is all wrong. Never mind for
1390 mpa_size = 0; //get_size_for_compressed_mapping_pairs(rl);
1396 mpa_size = ntfs_get_size_for_mapping_pairs(vol, rl);
1399 Eprintf("Failed to get size for mapping "
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
1422 // FIXME: the check for needing extension records should be
1423 // earlier on as it is very quick: asize > m->bytes_allocated?
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");
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);
1441 a->instance = m->next_attr_instance;
1442 m->next_attr_instance = cpu_to_le16((le16_to_cpu(m->next_attr_instance)
1444 a->lowest_vcn = cpu_to_le64(0);
1445 for (i = 0; rl[i].length; i++)
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);
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;
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();
1471 a->compression_unit = 0;
1472 bw = ntfs_rlwrite(vol->dev, rl, val, val_len, NULL);
1474 Eprintf("Error writing non-resident attribute value."
1476 err = ntfs_mapping_pairs_build(vol, (s8*)a + hdr_size +
1477 ((name_len + 7) & ~7), mpa_size, rl);
1479 if (err < 0 || bw != val_len) {
1480 // FIXME: Handle error.
1481 // deallocate clusters
1485 Eprintf("insert_non_resident_attr_in_mft_record failed with "
1486 "error %lld.\n", (long long) (err < 0 ? err : bw));
1490 ntfs_attr_put_search_ctx(ctx);
1491 if (uname && (uname != AT_UNNAMED))
1499 * insert_resident_attr_in_mft_record
1500 * Return 0 on success and -errno on error.
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)
1507 ntfs_attr_search_ctx *ctx;
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;
1524 /* Check if the attribute is already there. */
1525 ctx = ntfs_attr_get_search_ctx(NULL, m);
1527 Eprintf("Failed to allocate attribute search context.\n");
1531 if (ic == IGNORE_CASE) {
1532 Eprintf("FIXME: Hit unimplemented code path #3.\n");
1536 if (!ntfs_attr_lookup(type, uname, name_len, ic, 0, val, val_len,
1541 if (errno != ENOENT) {
1542 Eprintf("Corrupt inode.\n");
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
1563 // FIXME: the check for needing extension records should be
1564 // earlier on as it is very quick: asize > m->bytes_allocated?
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");
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)
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;
1590 memcpy((char*)a + 24, uname, name_len << 1);
1592 memcpy((char*)a + le16_to_cpu(a->value_offset), val, val_len);
1595 ntfs_attr_put_search_ctx(ctx);
1596 if (uname && (uname != AT_UNNAMED))
1603 * Return 0 on success or -errno on error.
1605 int add_attr_std_info(MFT_RECORD *m, const FILE_ATTR_FLAGS flags)
1607 STANDARD_INFORMATION si;
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));
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);
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);
1634 Eprintf("add_attr_std_info failed: %s\n", strerror(-err));
1639 * add_attr_file_name
1640 * Return 0 on success or -errno on error.
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)
1648 ntfs_attr_search_ctx *ctx;
1649 STANDARD_INFORMATION *si;
1653 /* Check if the attribute is already there. */
1654 ctx = ntfs_attr_get_search_ctx(NULL, m);
1656 Eprintf("Failed to allocate attribute search context.\n");
1659 if (ntfs_attr_lookup(AT_STANDARD_INFORMATION, AT_UNNAMED, 0, 0, 0, NULL, 0,
1662 Eprintf("BUG: Standard information attribute not present in "
1664 ntfs_attr_put_search_ctx(ctx);
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);
1673 ntfs_attr_put_search_ctx(ctx);
1676 fn->parent_directory = parent_dir;
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);
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) {
1692 if (packed_ea_size) {
1693 fn->packed_ea_size = cpu_to_le16(packed_ea_size);
1694 fn->reserved = cpu_to_le16(0);
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);
1705 return -ENAMETOOLONG;
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);
1714 Eprintf("add_attr_file_name failed: %s\n", strerror(-i));
1720 * Create the security descriptor attribute adding the security descriptor @sd
1721 * of length @sd_len to the mft record @m.
1723 * Return 0 on success or -errno on error.
1725 int add_attr_sd(MFT_RECORD *m, const char *sd, const s64 sd_len)
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,
1736 err = insert_resident_attr_in_mft_record(m,
1737 AT_SECURITY_DESCRIPTOR, NULL, 0, 0, 0, 0, sd,
1740 Eprintf("add_attr_sd failed: %s\n", strerror(-err));
1746 * Return 0 on success or -errno on error.
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)
1755 * Does it fit? NO: create non-resident. YES: create resident.
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.
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);
1771 err = insert_resident_attr_in_mft_record(m, AT_DATA, name,
1772 name_len, ic, flags, 0, val, val_len);
1775 Eprintf("add_attr_data failed: %s\n", strerror(-err));
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.
1785 * Return 0 on success or -errno on error.
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)
1794 err = insert_positioned_attr_in_mft_record(m, AT_DATA, name, name_len,
1795 ic, flags, rl, val, val_len);
1797 Eprintf("add_attr_data_positioned failed: %s\n",
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).
1810 * Return 0 on success or -errno on error.
1812 int add_attr_vol_name(MFT_RECORD *m, const char *vol_name,
1813 const int vol_name_len)
1819 len = (vol_name_len + 1) * sizeof(uchar_t);
1820 uname = calloc(1, len);
1823 i = (stoucs(uname, vol_name, len) + 1) * sizeof(uchar_t);
1830 return -ENAMETOOLONG;
1836 i = insert_resident_attr_in_mft_record(m, AT_VOLUME_NAME, NULL, 0, 0,
1837 0, 0, (char*)uname, len);
1841 Eprintf("add_attr_vol_name failed: %s\n", strerror(-i));
1847 * Return 0 on success or -errno on error.
1849 int add_attr_vol_info(MFT_RECORD *m, const VOLUME_FLAGS flags,
1850 const u8 major_ver, const u8 minor_ver)
1852 VOLUME_INFORMATION vi;
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));
1862 Eprintf("add_attr_vol_info failed: %s\n", strerror(-err));
1867 * add_attr_index_root
1868 * Return 0 on success or -errno on error.
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)
1876 INDEX_ENTRY_HEADER *e;
1879 val_len = sizeof(INDEX_ROOT) + sizeof(INDEX_ENTRY_HEADER);
1880 r = (INDEX_ROOT*)malloc(val_len);
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) {
1887 Eprintf("add_attr_index_root: indexed attribute is $FILE_NAME "
1888 "but collation rule is not COLLATION_FILE_NAME.\n");
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");
1900 r->clusters_per_index_block = index_block_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 "
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");
1915 r->clusters_per_index_block = index_block_size /
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));
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.
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);
1941 Eprintf("add_attr_index_root failed: %s\n", strerror(-err));
1946 * add_attr_index_alloc
1947 * Return 0 on success or -errno on error.
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)
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);
1959 Eprintf("add_attr_index_alloc failed: %s\n", strerror(-err));
1965 * Return 0 on success or -errno on error.
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)
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);
1979 err = insert_resident_attr_in_mft_record(m, AT_BITMAP, name,
1980 name_len, ic, 0, 0, bitmap, bitmap_len);
1983 Eprintf("add_attr_bitmap failed: %s\n", strerror(-err));
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.
1993 * Return 0 on success or -errno on error.
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)
2001 err = insert_positioned_attr_in_mft_record(m, AT_BITMAP, name, name_len,
2002 ic, 0, rl, bitmap, bitmap_len);
2004 Eprintf("add_attr_bitmap_positioned failed: %s\n",
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.
2015 * Return 0 on success or -errno on error.
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)
2021 ntfs_attr_search_ctx *ctx;
2025 INDEX_ALLOCATION *ia_val = NULL;
2028 char *re_start, *re_end;
2029 int i, err, index_block_size;
2032 i = (name_len + 1) * sizeof(uchar_t);
2033 uname = (uchar_t*)calloc(1, i);
2036 name_len = stoucs(uname, name, i);
2037 if (name_len > 0xff) {
2039 return -ENAMETOOLONG;
2043 /* Find the index root attribute. */
2044 ctx = ntfs_attr_get_search_ctx(NULL, m);
2046 Eprintf("Failed to allocate attribute search context.\n");
2049 if (ic == IGNORE_CASE) {
2050 Eprintf("FIXME: Hit unimplemented code path #4.\n");
2054 err = ntfs_attr_lookup(AT_INDEX_ROOT, uname, name_len, ic, 0, NULL, 0,
2063 if (a->non_resident || a->flags) {
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));
2078 ia_val = calloc(1, index_block_size);
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);
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.");
2098 *(u16*)((char*)ia_val + le16_to_cpu(ia_val->usa_ofs)) =
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));
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;
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.
2142 /* Set VCN pointer to 0LL. */
2143 *(VCN*)((char*)re + cpu_to_le16(re->length) - sizeof(VCN)) =
2145 err = ntfs_mst_pre_write_fixup((NTFS_RECORD*)ia_val, index_block_size);
2148 Eprintf("ntfs_mst_pre_write_fixup() failed in "
2149 "upgrade_to_large_index.\n");
2152 err = add_attr_index_alloc(m, name, name_len, ic, (char*)ia_val,
2154 ntfs_mst_post_write_fixup((NTFS_RECORD*)ia_val);
2156 // TODO: Remove the added bitmap!
2157 // Revert index root from index allocation.
2164 ntfs_attr_put_search_ctx(ctx);
2171 * make_room_for_index_entry_in_index_block
2172 * Create space of @size bytes at position @pos inside the index block @index.
2174 * Return 0 on success or -errno on error.
2176 int make_room_for_index_entry_in_index_block(INDEX_BLOCK *index,
2177 INDEX_ENTRY *pos, u32 size)
2185 * Rigorous consistency checks. Always return -EINVAL even if more
2186 * appropriate codes exist for simplicity of parsing the return value.
2188 if (size != ((size + 7) & ~7)) {
2189 Eprintf("make_room_for_index_entry_in_index_block() received "
2190 "non 8-byte aligned size.\n");
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))
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))
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))
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);
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).
2227 * Return 0 on success or -errno on error.
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)
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)
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));
2247 * Loop until we exceed valid memory (corruption case) or until we
2248 * reach the last entry.
2250 while ((char*)ie < index_end && !(ie->flags & INDEX_ENTRY_END)) {
2253 Dprintf("file_name_attr1->file_name_length = %i\n",
2254 file_name->file_name_length);
2255 if (file_name->file_name_length) {
2257 __buf = (char*)calloc(1, file_name->file_name_length +
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);
2265 Dprintf("Name contains non-displayable "
2266 "Unicode characters.\n");
2267 Dprintf("file_name_attr1->file_name = %s\n", __buf);
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) {
2274 __buf = (char*)calloc(1,
2275 ie->key.file_name.file_name_length + 1);
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);
2282 Dprintf("Name contains non-displayable "
2283 "Unicode characters.\n");
2284 Dprintf("file_name_attr2->file_name = %s\n", __buf);
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);
2293 * If @file_name collates before ie->key.file_name, there is no
2294 * matching index entry.
2298 /* If file names are not equal, continue search. */
2301 /* File names are equal when compared ignoring case. */
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)
2310 if (file_name->file_name_type != FILE_NAME_POSIX ||
2311 ie->key.file_name.file_name_type != FILE_NAME_POSIX)
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);
2318 /* Complete match. Bugger. Can't insert. */
2325 Dprintf("BUG: ie->length is zero, breaking out of "
2330 ie = (INDEX_ENTRY*)((char*)ie + le16_to_cpu(ie->length));
2332 i = (sizeof(INDEX_ENTRY_HEADER) + file_name_size + 7) & ~7;
2333 err = make_room_for_index_entry_in_index_block(index, ie, i);
2335 Eprintf("make_room_for_index_entry_in_index_block failed: "
2336 "%s\n", strerror(-err));
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);
2351 * Create a file_name_attribute in the mft record @m_file which points to the
2352 * parent directory with mft reference @ref_parent.
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.
2357 * @ref_file is the mft reference of @m_file.
2359 * Return 0 on success or -errno on error.
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)
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);
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) {
2392 if (packed_ea_size) {
2393 fn->packed_ea_size = cpu_to_le16(packed_ea_size);
2394 fn->reserved = cpu_to_le16(0);
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);
2405 return -ENAMETOOLONG;
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);
2413 Eprintf("Too many hardlinks present already.\n");
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);
2422 Eprintf("create_hardlink failed adding file name attribute: "
2423 "%s\n", strerror(-i));
2425 /* Undo link count increment. */
2426 m_file->link_count = cpu_to_le16(
2427 le16_to_cpu(m_file->link_count) - 1);
2430 /* Insert the index entry for file_name in @index. */
2431 i = insert_file_link_in_dir_index(index, ref_file, fn, fn_size);
2433 Eprintf("create_hardlink failed inserting index entry: %s\n",
2435 /* FIXME: Remove the file name attribute from @m_file. */
2437 /* Undo link count increment. */
2438 m_file->link_count = cpu_to_le16(
2439 le16_to_cpu(m_file->link_count) - 1);
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);
2461 void mkntfs_exit(void)
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);
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);
2509 int main(int argc, char **argv)
2518 ntfs_attr_search_ctx *ctx;
2520 NTFS_BOOT_SECTOR *bs;
2521 unsigned long mnt_flags;
2523 /* Setup the correct locale for string output and conversion. */
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();
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);
2534 Eprintf("Could not set up exit() function because atexit() "
2535 "failed. Aborting...\n");
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));
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. */
2551 /* Parse command line options. */
2552 parse_options(argc, argv);
2554 * Allocate and initialize an ntfs device structure and attach it to
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");
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 "
2570 err_exit("Could not open %s: %s\n", vol->dev->d_name,
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));
2578 if (!S_ISBLK(sbuf.st_mode)) {
2579 Eprintf("%s is not a block device.\n", vol->dev->d_name);
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 "
2586 if (opts.sector_size) {
2588 opts.nr_sectors = sbuf.st_size /
2591 opts.nr_sectors = ((s64)sbuf.st_blocks
2592 << 9) / opts.sector_size;
2595 opts.nr_sectors = sbuf.st_size / 512;
2597 opts.nr_sectors = sbuf.st_blocks;
2598 opts.sector_size = 512;
2601 fprintf(stderr, "mkntfs forced anyway.\n");
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",
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);
2619 err_exit("Refusing to make a filesystem here!\n");
2620 fprintf(stderr, "mkntfs forced anyway. Hope /etc/mtab is "
2623 /* If user didn't specify the sector size, determine it now. */
2624 if (!opts.sector_size) {
2628 if (vol->dev->d_ops->ioctl(vol->dev, BLKSSZGET, &_sect_size)
2630 opts.sector_size = _sect_size;
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",
2638 opts.sector_size = 512;
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,
2652 if (opts.nr_sectors <= 0)
2653 err_exit("ntfs_device_size_get(%s) failed. Please "
2654 "specify it manually.\n",
2657 Dprintf("number of sectors = %Ld (0x%Lx)\n", opts.nr_sectors,
2659 /* Reserve the last sector for the backup boot sector. */
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 "
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;
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;
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) {
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;
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 "
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;
2719 * Check the cluster_size and nr_sectors for consistency with
2720 * sector_size and nr_sectors. And check both of these for consistency
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,
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);
2741 err_exit("Failed to allocate internal buffer: %s",
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.
2747 for (i = opts.nr_clusters; i < lcn_bitmap_byte_size << 3; i++)
2748 ntfs_bit_set(lcn_bitmap, (u64)i, 1);
2750 * Determine mft_size: 16 mft records or 1 cluster, which ever is
2751 * bigger, rounded to multiples of cluster size.
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);
2766 err_exit("Failed to allocate internal buffer: %s\n",
2768 /* Create runlist for mft bitmap. */
2769 rl_mft_bmp = (runlist *)malloc(2 * sizeof(runlist));
2771 err_exit("Failed to allocate internal buffer: %s\n",
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;
2778 * Size is always one cluster, even though valid data size and
2779 * initialized data size are only 8 bytes.
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) {
2789 * We start at the higher value out of 16kiB and just after the
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) /
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 */
2802 opts.mft_zone_end = opts.mft_zone_end >> 1; /* 50% */
2805 opts.mft_zone_end = opts.mft_zone_end * 3 >> 3; /* 37.5% */
2808 opts.mft_zone_end = opts.mft_zone_end >> 2; /* 25% */
2812 opts.mft_zone_end = opts.mft_zone_end >> 3; /* 12.5% */
2815 Dprintf("MFT zone size = %lukiB\n", opts.mft_zone_end / 1024);
2817 * The mft zone begins with the mft data attribute, not at the beginning
2820 opts.mft_zone_end += opts.mft_lcn;
2821 /* Create runlist for mft. */
2822 rl_mft = (runlist *)malloc(2 * sizeof(runlist));
2824 err_exit("Failed to allocate internal buffer: %s\n",
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));
2843 err_exit("Failed to allocate internal buffer: %s\n",
2845 rl_mftmirr[0].vcn = 0LL;
2846 rl_mftmirr[0].lcn = opts.mftmirr_lcn;
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).
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));
2866 err_exit("Failed to allocate internal buffer: %s\n",
2868 rl_logfile[0].vcn = 0LL;
2869 rl_logfile[0].lcn = opts.logfile_lcn;
2871 * Determine logfile_size from volume_size (rounded up to a cluster),
2872 * making sure it does not overflow the end of the volume.
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 */
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) {
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.
2892 opts.logfile_size >>= 1;
2893 j = opts.logfile_size / vol->cluster_size;
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);
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.
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));
2915 err_exit("Failed to allocate internal buffer: %s\n",
2917 rl_boot[0].vcn = 0LL;
2918 rl_boot[0].lcn = 0LL;
2920 * $Boot is always 8192 (0x2000) bytes or 1 cluster, whichever is
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);
2933 err_exit("Failed to allocate internal buffer: %s\n",
2935 /* Create runlist for $BadClus, $DATA named stream $Bad. */
2936 rl_bad = (runlist *)malloc(2 * sizeof(runlist));
2938 err_exit("Failed to allocate internal buffer: %s\n",
2940 rl_bad[0].vcn = 0LL;
2941 rl_bad[0].lcn = -1LL;
2943 * $BadClus named stream $Bad contains the whole volume as a single
2944 * sparse runlist entry.
2946 rl_bad[1].vcn = rl_bad[0].length = opts.nr_clusters;
2947 rl_bad[1].lcn = -1LL;
2948 rl_bad[1].length = 0LL;
2950 // TODO: Mark bad blocks as such.
2953 * If not quick format, fill the device with 0s.
2954 * FIXME: Except bad blocks! (AIA)
2956 if (!opts.quick_format) {
2957 unsigned long position;
2958 unsigned long mid_clust;
2959 float progress_inc = (float)opts.nr_clusters / 100;
2961 Qprintf("Initialising device with zeroes: 0%%");
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 /
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");
2975 err_exit("Error: Cluster zero is bad. "
2976 "Cannot create NTFS file "
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 "
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);
2997 Qprintf("\b\b\b\b100%%");
2998 position = (opts.volume_size & (vol->cluster_size - 1)) /
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 "
3012 /* Seek to next sector. */
3013 vol->dev->d_ops->seek(vol->dev,
3014 opts.sector_size, SEEK_CUR);
3017 Qprintf(" - Done.\n");
3019 Qprintf("Creating NTFS volume structures.\n");
3020 /* Setup an empty mft record. */
3021 format_mft_record((MFT_RECORD*)buf);
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).
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);
3033 * If a cluster contains more than the 16 system files, fill the rest
3034 * with empty, formatted records.
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);
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.
3045 for (i = 0; i < 16; i++) {
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;
3058 add_attr_std_info(m, file_attrs);
3059 // dump_mft_record(m);
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);
3072 init_system_file_sd(FILE_root, &sd, &i);
3073 err = add_attr_sd(m, sd, i);
3075 // FIXME: This should be IGNORE_CASE
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
3081 err = upgrade_to_large_index(m, "$I30", 4, 0, &index_block);
3083 ctx = ntfs_attr_get_search_ctx(NULL, m);
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,
3090 ntfs_attr_put_search_ctx(ctx);
3091 err_exit("BUG: $FILE_NAME attribute not found.\n");
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);
3101 err_exit("Couldn't create root directory: %s\n",
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,
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);
3116 init_system_file_sd(FILE_MFT, &sd, &i);
3117 err = add_attr_sd(m, sd, i);
3119 /* mft_bitmap is not modified in mkntfs; no need to sync it later. */
3121 err = add_attr_bitmap_positioned(m, NULL, 0, 0, rl_mft_bmp,
3122 mft_bitmap, mft_bitmap_byte_size);
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);
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);
3138 init_system_file_sd(FILE_MFTMirr, &sd, &i);
3139 err = add_attr_sd(m, sd, i);
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);
3148 err_exit("Failed to allocate internal buffer: %s\n",
3150 memset(buf2, -1, opts.logfile_size);
3151 err = add_attr_data_positioned(m, NULL, 0, 0, 0, rl_logfile, buf2,
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);
3162 init_system_file_sd(FILE_LogFile, &sd, &i);
3163 err = add_attr_sd(m, sd, i);
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);
3175 init_system_file_sd(FILE_Volume, &sd, &i);
3176 err = add_attr_sd(m, sd, i);
3179 err = add_attr_data(m, NULL, 0, 0, 0, NULL, 0);
3181 err = add_attr_vol_name(m, vol->vol_name, vol->vol_name ?
3182 strlen(vol->vol_name) : 0);
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,
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)
3197 buf2_size = opts.attr_defs_len;
3198 buf2 = (char*)calloc(1, buf2_size);
3200 err_exit("Failed to allocate internal buffer: %s\n",
3202 memcpy(buf2, opts.attr_defs, opts.attr_defs_len);
3203 err = add_attr_data(m, NULL, 0, 0, 0, buf2, buf2_size);
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);
3215 init_system_file_sd(FILE_AttrDef, &sd, &i);
3216 err = add_attr_sd(m, sd, i);
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);
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);
3232 init_system_file_sd(FILE_Bitmap, &sd, &i);
3233 err = add_attr_sd(m, sd, i);
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);
3242 err_exit("Failed to allocate internal buffer: %s\n",
3244 memcpy(buf2, boot_array, sizeof(boot_array));
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.
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 /
3254 bs->bpb.media_type = 0xf8; /* hard disk */
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.
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 /
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);
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 /
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);
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));
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.
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);
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);
3310 init_system_file_sd(FILE_Boot, &sd, &i);
3311 err = add_attr_sd(m, sd, i);
3314 err_exit("Couldn't create $Boot: %s\n", strerror(-err));
3315 Vprintf("Creating backup boot sector.\n");
3317 * Write the first max(512, opts.sector_size) bytes from buf2 to the
3320 if (vol->dev->d_ops->seek(vol->dev, (opts.nr_sectors + 1) *
3321 opts.sector_size - i, SEEK_SET) == (off_t)-1)
3323 bw = mkntfs_write(vol->dev, buf2, i);
3333 _s = "unknown error";
3334 if (bw != -1LL || (bw == -1LL && _e != ENOSPC)) {
3335 err_exit("Couldn't write backup boot sector: %s\n", _s);
3337 Eprintf("Seek failed: %s\n", strerror(errno));
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");
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);
3353 err = add_attr_data(m, NULL, 0, 0, 0, NULL, 0);
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);
3362 init_system_file_sd(FILE_BadClus, &sd, &i);
3363 err = add_attr_sd(m, sd, i);
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);
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);
3377 init_system_file_sd(FILE_Secure, &sd, &i);
3378 err = add_attr_sd(m, sd, i);
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);
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);
3395 init_system_file_sd(FILE_UpCase, &sd, &i);
3396 err = add_attr_sd(m, sd, i);
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);
3407 init_system_file_sd(i, &sd, &j);
3408 err = add_attr_sd(m, sd, j);
3411 err_exit("Couldn't create system file %i (0x%x): %s\n",
3412 i, i, strerror(-err));
3413 //dump_mft_record(m);
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
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);
3431 err_exit("Failed to allocate attribute search context: %s\n",
3433 // FIXME: This should be IGNORE_CASE!
3434 if (ntfs_attr_lookup(AT_INDEX_ALLOCATION, I30, 4, 0, 0,
3436 ntfs_attr_put_search_ctx(ctx);
3437 err_exit("BUG: $INDEX_ALLOCATION attribute not found.\n");
3440 rl_index = ntfs_mapping_pairs_decompress(vol, a, NULL);
3442 ntfs_attr_put_search_ctx(ctx);
3443 err_exit("Failed to decompress runlist of $INDEX_ALLOCATION "
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");
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);
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);
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);
3466 err_exit("Failed to allocate attribute search context: %s\n",
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");
3473 if (a->non_resident) {
3474 rl = ntfs_mapping_pairs_decompress(vol, a, NULL);
3475 ntfs_attr_put_search_ctx(ctx);
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) :
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);
3489 * No need to sync $MFT/$BITMAP as that has never been modified since
3492 Vprintf("Syncing $MFT.\n");
3493 pos = opts.mft_lcn * vol->cluster_size;
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);
3501 err_exit("%s\n", lw == -1 ? strerror(errno) :
3503 pos += vol->mft_record_size;
3505 Vprintf("Updating $MFTMirr.\n");
3506 pos = opts.mftmirr_lcn * vol->cluster_size;
3508 for (i = 0; i < rl_mftmirr[0].length * vol->cluster_size /
3509 vol->mft_record_size; i++) {
3511 m = (MFT_RECORD*)(buf + i * vol->mft_record_size);
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.
3518 usnp = (u16*)((char*)m + le16_to_cpu(m->usa_ofs));
3519 usn = le16_to_cpup(usnp);
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);
3528 err_exit("%s\n", lw == -1 ? strerror(errno) :
3530 pos += vol->mft_record_size;
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");
3537 * Device is unlocked and closed by the registered exit function