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