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