• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * dir.c - Directory handling code. Originated from the Linux-NTFS project.
3  *
4  * Copyright (c) 2002-2005 Anton Altaparmakov
5  * Copyright (c) 2004-2005 Richard Russon
6  * Copyright (c) 2004-2008 Szabolcs Szakacsits
7  * Copyright (c) 2005-2007 Yura Pakhuchiy
8  * Copyright (c) 2008-2021 Jean-Pierre Andre
9  *
10  * This program/include file is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as published
12  * by the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program/include file is distributed in the hope that it will be
16  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
17  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program (in the main directory of the NTFS-3G
22  * distribution in the file COPYING); if not, write to the Free Software
23  * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  */
25 
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29 
30 #ifdef HAVE_STDLIB_H
31 #include <stdlib.h>
32 #endif
33 #ifdef HAVE_ERRNO_H
34 #include <errno.h>
35 #endif
36 #ifdef HAVE_STRING_H
37 #include <string.h>
38 #endif
39 #ifdef HAVE_SYS_STAT_H
40 #include <sys/stat.h>
41 #endif
42 
43 #ifdef HAVE_SYS_TYPES_H
44 #include <sys/types.h>
45 #endif
46 #ifdef MAJOR_IN_MKDEV
47 #include <sys/mkdev.h>
48 #endif
49 #ifdef MAJOR_IN_SYSMACROS
50 #include <sys/sysmacros.h>
51 #endif
52 
53 #include "param.h"
54 #include "types.h"
55 #include "debug.h"
56 #include "attrib.h"
57 #include "inode.h"
58 #include "dir.h"
59 #include "volume.h"
60 #include "mft.h"
61 #include "index.h"
62 #include "ntfstime.h"
63 #include "lcnalloc.h"
64 #include "logging.h"
65 #include "cache.h"
66 #include "misc.h"
67 #include "security.h"
68 #include "reparse.h"
69 #include "object_id.h"
70 #include "xattrs.h"
71 #include "ea.h"
72 
73 /*
74  * The little endian Unicode strings "$I30", "$SII", "$SDH", "$O"
75  *  and "$Q" as global constants.
76  */
77 ntfschar NTFS_INDEX_I30[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('I'),
78 		const_cpu_to_le16('3'), const_cpu_to_le16('0'),
79 		const_cpu_to_le16('\0') };
80 ntfschar NTFS_INDEX_SII[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('S'),
81 		const_cpu_to_le16('I'), const_cpu_to_le16('I'),
82 		const_cpu_to_le16('\0') };
83 ntfschar NTFS_INDEX_SDH[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('S'),
84 		const_cpu_to_le16('D'), const_cpu_to_le16('H'),
85 		const_cpu_to_le16('\0') };
86 ntfschar NTFS_INDEX_O[3] = { const_cpu_to_le16('$'), const_cpu_to_le16('O'),
87 		const_cpu_to_le16('\0') };
88 ntfschar NTFS_INDEX_Q[3] = { const_cpu_to_le16('$'), const_cpu_to_le16('Q'),
89 		const_cpu_to_le16('\0') };
90 ntfschar NTFS_INDEX_R[3] = { const_cpu_to_le16('$'), const_cpu_to_le16('R'),
91 		const_cpu_to_le16('\0') };
92 
93 #if CACHE_INODE_SIZE
94 
95 /*
96  *		Pathname hashing
97  *
98  *	Based on first char and second char (which may be '\0')
99  */
100 
ntfs_dir_inode_hash(const struct CACHED_GENERIC * cached)101 int ntfs_dir_inode_hash(const struct CACHED_GENERIC *cached)
102 {
103 	const char *path;
104 	const unsigned char *name;
105 
106 	path = (const char*)cached->variable;
107 	if (!path) {
108 		ntfs_log_error("Bad inode cache entry\n");
109 		return (-1);
110 	}
111 	name = (const unsigned char*)strrchr(path,'/');
112 	if (!name)
113 		name = (const unsigned char*)path;
114 	return (((name[0] << 1) + name[1] + strlen((const char*)name))
115 				% (2*CACHE_INODE_SIZE));
116 }
117 
118 /*
119  *		Pathname comparing for entering/fetching from cache
120  */
121 
inode_cache_compare(const struct CACHED_GENERIC * cached,const struct CACHED_GENERIC * wanted)122 static int inode_cache_compare(const struct CACHED_GENERIC *cached,
123 			const struct CACHED_GENERIC *wanted)
124 {
125 	return (!cached->variable
126 		    || strcmp(cached->variable, wanted->variable));
127 }
128 
129 /*
130  *		Pathname comparing for invalidating entries in cache
131  *
132  *	A partial path is compared in order to invalidate all paths
133  *	related to a renamed directory
134  *	inode numbers are also checked, as deleting a long name may
135  *	imply deleting a short name and conversely
136  *
137  *	Only use associated with a CACHE_NOHASH flag
138  */
139 
inode_cache_inv_compare(const struct CACHED_GENERIC * cached,const struct CACHED_GENERIC * wanted)140 static int inode_cache_inv_compare(const struct CACHED_GENERIC *cached,
141 			const struct CACHED_GENERIC *wanted)
142 {
143 	int len;
144 	BOOL different;
145 	const struct CACHED_INODE *w;
146 	const struct CACHED_INODE *c;
147 
148 	w = (const struct CACHED_INODE*)wanted;
149 	c = (const struct CACHED_INODE*)cached;
150 	if (w->pathname) {
151 		len = strlen(w->pathname);
152 		different = !cached->variable
153 			|| ((w->inum != MREF(c->inum))
154 			   && (strncmp(c->pathname, w->pathname, len)
155 				|| ((c->pathname[len] != '\0')
156 				   && (c->pathname[len] != '/'))));
157 	} else
158 		different = !c->pathname
159 			|| (w->inum != MREF(c->inum));
160 	return (different);
161 }
162 
163 #endif
164 
165 #if CACHE_LOOKUP_SIZE
166 
167 /*
168  *		File name comparing for entering/fetching from lookup cache
169  */
170 
lookup_cache_compare(const struct CACHED_GENERIC * cached,const struct CACHED_GENERIC * wanted)171 static int lookup_cache_compare(const struct CACHED_GENERIC *cached,
172 			const struct CACHED_GENERIC *wanted)
173 {
174 	const struct CACHED_LOOKUP *c = (const struct CACHED_LOOKUP*) cached;
175 	const struct CACHED_LOOKUP *w = (const struct CACHED_LOOKUP*) wanted;
176 	return (!c->name
177 		    || (c->parent != w->parent)
178 		    || (c->namesize != w->namesize)
179 		    || memcmp(c->name, w->name, c->namesize));
180 }
181 
182 /*
183  *		Inode number comparing for invalidating lookup cache
184  *
185  *	All entries with designated inode number are invalidated
186  *
187  *	Only use associated with a CACHE_NOHASH flag
188  */
189 
lookup_cache_inv_compare(const struct CACHED_GENERIC * cached,const struct CACHED_GENERIC * wanted)190 static int lookup_cache_inv_compare(const struct CACHED_GENERIC *cached,
191 			const struct CACHED_GENERIC *wanted)
192 {
193 	const struct CACHED_LOOKUP *c = (const struct CACHED_LOOKUP*) cached;
194 	const struct CACHED_LOOKUP *w = (const struct CACHED_LOOKUP*) wanted;
195 	return (!c->name
196 		    || (c->parent != w->parent)
197 		    || (MREF(c->inum) != MREF(w->inum)));
198 }
199 
200 /*
201  *		Lookup hashing
202  *
203  *	Based on first, second and and last char
204  */
205 
ntfs_dir_lookup_hash(const struct CACHED_GENERIC * cached)206 int ntfs_dir_lookup_hash(const struct CACHED_GENERIC *cached)
207 {
208 	const unsigned char *name;
209 	int count;
210 	unsigned int val;
211 
212 	name = (const unsigned char*)cached->variable;
213 	count = cached->varsize;
214 	if (!name || !count) {
215 		ntfs_log_error("Bad lookup cache entry\n");
216 		return (-1);
217 	}
218 	val = (name[0] << 2) + (name[1] << 1) + name[count - 1] + count;
219 	return (val % (2*CACHE_LOOKUP_SIZE));
220 }
221 
222 #endif
223 
224 /**
225  * ntfs_inode_lookup_by_name - find an inode in a directory given its name
226  * @dir_ni:	ntfs inode of the directory in which to search for the name
227  * @uname:	Unicode name for which to search in the directory
228  * @uname_len:	length of the name @uname in Unicode characters
229  *
230  * Look for an inode with name @uname in the directory with inode @dir_ni.
231  * ntfs_inode_lookup_by_name() walks the contents of the directory looking for
232  * the Unicode name. If the name is found in the directory, the corresponding
233  * inode number (>= 0) is returned as a mft reference in cpu format, i.e. it
234  * is a 64-bit number containing the sequence number.
235  *
236  * On error, return -1 with errno set to the error code. If the inode is is not
237  * found errno is ENOENT.
238  *
239  * Note, @uname_len does not include the (optional) terminating NULL character.
240  *
241  * Note, we look for a case sensitive match first but we also look for a case
242  * insensitive match at the same time. If we find a case insensitive match, we
243  * save that for the case that we don't find an exact match, where we return
244  * the mft reference of the case insensitive match.
245  *
246  * If the volume is mounted with the case sensitive flag set, then we only
247  * allow exact matches.
248  */
ntfs_inode_lookup_by_name(ntfs_inode * dir_ni,const ntfschar * uname,const int uname_len)249 u64 ntfs_inode_lookup_by_name(ntfs_inode *dir_ni,
250 		const ntfschar *uname, const int uname_len)
251 {
252 	VCN vcn;
253 	u64 mref = 0;
254 	s64 br;
255 	ntfs_volume *vol = dir_ni->vol;
256 	ntfs_attr_search_ctx *ctx;
257 	INDEX_ROOT *ir;
258 	INDEX_ENTRY *ie;
259 	INDEX_ALLOCATION *ia;
260 	IGNORE_CASE_BOOL case_sensitivity;
261 	u8 *index_end;
262 	ntfs_attr *ia_na;
263 	int eo, rc;
264 	u32 index_block_size;
265 	u8 index_vcn_size_bits;
266 
267 	ntfs_log_trace("Entering\n");
268 
269 	if (!dir_ni || !dir_ni->mrec || !uname || uname_len <= 0) {
270 		errno = EINVAL;
271 		return -1;
272 	}
273 
274 	ctx = ntfs_attr_get_search_ctx(dir_ni, NULL);
275 	if (!ctx)
276 		return -1;
277 
278 	/* Find the index root attribute in the mft record. */
279 	if (ntfs_attr_lookup(AT_INDEX_ROOT, NTFS_INDEX_I30, 4, CASE_SENSITIVE, 0, NULL,
280 			0, ctx)) {
281 		ntfs_log_perror("Index root attribute missing in directory inode "
282 				"%lld", (unsigned long long)dir_ni->mft_no);
283 		goto put_err_out;
284 	}
285 	case_sensitivity = (NVolCaseSensitive(vol) ? CASE_SENSITIVE : IGNORE_CASE);
286 	/* Get to the index root value. */
287 	ir = (INDEX_ROOT*)((u8*)ctx->attr +
288 			le16_to_cpu(ctx->attr->value_offset));
289 	index_block_size = le32_to_cpu(ir->index_block_size);
290 	if (index_block_size < NTFS_BLOCK_SIZE ||
291 			index_block_size & (index_block_size - 1)) {
292 		ntfs_log_error("Index block size %u is invalid.\n",
293 				(unsigned)index_block_size);
294 		goto put_err_out;
295 	}
296 		/* Consistency check of ir done while fetching attribute */
297 	index_end = (u8*)&ir->index + le32_to_cpu(ir->index.index_length);
298 	/* The first index entry. */
299 	ie = (INDEX_ENTRY*)((u8*)&ir->index +
300 			le32_to_cpu(ir->index.entries_offset));
301 	/*
302 	 * Loop until we exceed valid memory (corruption case) or until we
303 	 * reach the last entry.
304 	 */
305 	for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
306 		/* Bounds checks. */
307 		if ((u8*)ie < (u8*)ctx->mrec || (u8*)ie +
308 				sizeof(INDEX_ENTRY_HEADER) > index_end ||
309 				(u8*)ie + le16_to_cpu(ie->length) >
310 				index_end) {
311 			ntfs_log_error("Index root entry out of bounds in"
312 				" inode %lld\n",
313 				(unsigned long long)dir_ni->mft_no);
314 			goto put_err_out;
315 		}
316 		/*
317 		 * The last entry cannot contain a name. It can however contain
318 		 * a pointer to a child node in the B+tree so we just break out.
319 		 */
320 		if (ie->ie_flags & INDEX_ENTRY_END)
321 			break;
322 
323 		/* The file name must not overflow from the entry */
324 		if (ntfs_index_entry_inconsistent(ie, COLLATION_FILE_NAME,
325 				dir_ni->mft_no)) {
326 			errno = EIO;
327 			goto put_err_out;
328 		}
329 		/*
330 		 * Not a perfect match, need to do full blown collation so we
331 		 * know which way in the B+tree we have to go.
332 		 */
333 		rc = ntfs_names_full_collate(uname, uname_len,
334 				(ntfschar*)&ie->key.file_name.file_name,
335 				ie->key.file_name.file_name_length,
336 				case_sensitivity, vol->upcase, vol->upcase_len);
337 		/*
338 		 * If uname collates before the name of the current entry, there
339 		 * is definitely no such name in this index but we might need to
340 		 * descend into the B+tree so we just break out of the loop.
341 		 */
342 		if (rc == -1)
343 			break;
344 		/* The names are not equal, continue the search. */
345 		if (rc)
346 			continue;
347 		/*
348 		 * Perfect match, this will never happen as the
349 		 * ntfs_are_names_equal() call will have gotten a match but we
350 		 * still treat it correctly.
351 		 */
352 		mref = le64_to_cpu(ie->indexed_file);
353 		ntfs_attr_put_search_ctx(ctx);
354 		return mref;
355 	}
356 	/*
357 	 * We have finished with this index without success. Check for the
358 	 * presence of a child node and if not present return error code
359 	 * ENOENT, unless we have got the mft reference of a matching name
360 	 * cached in mref in which case return mref.
361 	 */
362 	if (!(ie->ie_flags & INDEX_ENTRY_NODE)) {
363 		ntfs_attr_put_search_ctx(ctx);
364 		if (mref)
365 			return mref;
366 		ntfs_log_debug("Entry not found - between root entries.\n");
367 		errno = ENOENT;
368 		return -1;
369 	} /* Child node present, descend into it. */
370 
371 	/* Open the index allocation attribute. */
372 	ia_na = ntfs_attr_open(dir_ni, AT_INDEX_ALLOCATION, NTFS_INDEX_I30, 4);
373 	if (!ia_na) {
374 		ntfs_log_perror("Failed to open index allocation (inode %lld)",
375 				(unsigned long long)dir_ni->mft_no);
376 		goto put_err_out;
377 	}
378 
379 	/* Allocate a buffer for the current index block. */
380 	ia = ntfs_malloc(index_block_size);
381 	if (!ia) {
382 		ntfs_attr_close(ia_na);
383 		goto put_err_out;
384 	}
385 
386 	/* Determine the size of a vcn in the directory index. */
387 	if (vol->cluster_size <= index_block_size) {
388 		index_vcn_size_bits = vol->cluster_size_bits;
389 	} else {
390 		index_vcn_size_bits = NTFS_BLOCK_SIZE_BITS;
391 	}
392 
393 	/* Get the starting vcn of the index_block holding the child node. */
394 	vcn = sle64_to_cpup((sle64*)((u8*)ie + le16_to_cpu(ie->length) - 8));
395 
396 descend_into_child_node:
397 
398 	/* Read the index block starting at vcn. */
399 	br = ntfs_attr_mst_pread(ia_na, vcn << index_vcn_size_bits, 1,
400 			index_block_size, ia);
401 	if (br != 1) {
402 		if (br != -1)
403 			errno = EIO;
404 		ntfs_log_perror("Failed to read vcn 0x%llx from inode %lld",
405 			       	(unsigned long long)vcn,
406 				(unsigned long long)ia_na->ni->mft_no);
407 		goto close_err_out;
408 	}
409 
410 	if (ntfs_index_block_inconsistent((INDEX_BLOCK*)ia, index_block_size,
411 			ia_na->ni->mft_no, vcn)) {
412 		errno = EIO;
413 		goto close_err_out;
414 	}
415 	index_end = (u8*)&ia->index + le32_to_cpu(ia->index.index_length);
416 
417 	/* The first index entry. */
418 	ie = (INDEX_ENTRY*)((u8*)&ia->index +
419 			le32_to_cpu(ia->index.entries_offset));
420 	/*
421 	 * Iterate similar to above big loop but applied to index buffer, thus
422 	 * loop until we exceed valid memory (corruption case) or until we
423 	 * reach the last entry.
424 	 */
425 	for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
426 		/* Bounds check. */
427 		if ((u8*)ie < (u8*)ia || (u8*)ie +
428 				sizeof(INDEX_ENTRY_HEADER) > index_end ||
429 				(u8*)ie + le16_to_cpu(ie->length) >
430 				index_end) {
431 			ntfs_log_error("Index entry out of bounds in directory "
432 				       "inode %lld.\n",
433 				       (unsigned long long)dir_ni->mft_no);
434 			errno = EIO;
435 			goto close_err_out;
436 		}
437 		/*
438 		 * The last entry cannot contain a name. It can however contain
439 		 * a pointer to a child node in the B+tree so we just break out.
440 		 */
441 		if (ie->ie_flags & INDEX_ENTRY_END)
442 			break;
443 
444 		/* The file name must not overflow from the entry */
445 		if (ntfs_index_entry_inconsistent(ie, COLLATION_FILE_NAME,
446 				dir_ni->mft_no)) {
447 			errno = EIO;
448 			goto close_err_out;
449 		}
450 		/*
451 		 * Not a perfect match, need to do full blown collation so we
452 		 * know which way in the B+tree we have to go.
453 		 */
454 		rc = ntfs_names_full_collate(uname, uname_len,
455 				(ntfschar*)&ie->key.file_name.file_name,
456 				ie->key.file_name.file_name_length,
457 				case_sensitivity, vol->upcase, vol->upcase_len);
458 		/*
459 		 * If uname collates before the name of the current entry, there
460 		 * is definitely no such name in this index but we might need to
461 		 * descend into the B+tree so we just break out of the loop.
462 		 */
463 		if (rc == -1)
464 			break;
465 		/* The names are not equal, continue the search. */
466 		if (rc)
467 			continue;
468 		mref = le64_to_cpu(ie->indexed_file);
469 		free(ia);
470 		ntfs_attr_close(ia_na);
471 		ntfs_attr_put_search_ctx(ctx);
472 		return mref;
473 	}
474 	/*
475 	 * We have finished with this index buffer without success. Check for
476 	 * the presence of a child node.
477 	 */
478 	if (ie->ie_flags & INDEX_ENTRY_NODE) {
479 		if ((ia->index.ih_flags & NODE_MASK) == LEAF_NODE) {
480 			ntfs_log_error("Index entry with child node found in a leaf "
481 					"node in directory inode %lld.\n",
482 					(unsigned long long)dir_ni->mft_no);
483 			errno = EIO;
484 			goto close_err_out;
485 		}
486 		/* Child node present, descend into it. */
487 		vcn = sle64_to_cpup((sle64*)((u8*)ie + le16_to_cpu(ie->length) - 8));
488 		if (vcn >= 0)
489 			goto descend_into_child_node;
490 		ntfs_log_error("Negative child node vcn in directory inode "
491 			       "0x%llx.\n", (unsigned long long)dir_ni->mft_no);
492 		errno = EIO;
493 		goto close_err_out;
494 	}
495 	free(ia);
496 	ntfs_attr_close(ia_na);
497 	ntfs_attr_put_search_ctx(ctx);
498 	/*
499 	 * No child node present, return error code ENOENT, unless we have got
500 	 * the mft reference of a matching name cached in mref in which case
501 	 * return mref.
502 	 */
503 	if (mref)
504 		return mref;
505 	ntfs_log_debug("Entry not found.\n");
506 	errno = ENOENT;
507 	return -1;
508 put_err_out:
509 	eo = EIO;
510 	ntfs_log_debug("Corrupt directory. Aborting lookup.\n");
511 eo_put_err_out:
512 	ntfs_attr_put_search_ctx(ctx);
513 	errno = eo;
514 	return -1;
515 close_err_out:
516 	eo = errno;
517 	free(ia);
518 	ntfs_attr_close(ia_na);
519 	goto eo_put_err_out;
520 }
521 
522 /*
523  *		Lookup a file in a directory from its UTF-8 name
524  *
525  *	The name is first fetched from cache if one is defined
526  *
527  *	Returns the inode number
528  *		or -1 if not possible (errno tells why)
529  */
530 
ntfs_inode_lookup_by_mbsname(ntfs_inode * dir_ni,const char * name)531 u64 ntfs_inode_lookup_by_mbsname(ntfs_inode *dir_ni, const char *name)
532 {
533 	int uname_len;
534 	ntfschar *uname = (ntfschar*)NULL;
535 	u64 inum;
536 	char *cached_name;
537 	const char *const_name;
538 
539 	if (!NVolCaseSensitive(dir_ni->vol)) {
540 		cached_name = ntfs_uppercase_mbs(name,
541 			dir_ni->vol->upcase, dir_ni->vol->upcase_len);
542 		const_name = cached_name;
543 	} else {
544 		cached_name = (char*)NULL;
545 		const_name = name;
546 	}
547 	if (const_name) {
548 #if CACHE_LOOKUP_SIZE
549 
550 		/*
551 		 * fetch inode from cache
552 		 */
553 
554 		if (dir_ni->vol->lookup_cache) {
555 			struct CACHED_LOOKUP item;
556 			struct CACHED_LOOKUP *cached;
557 
558 			item.name = const_name;
559 			item.namesize = strlen(const_name) + 1;
560 			item.parent = dir_ni->mft_no;
561 			cached = (struct CACHED_LOOKUP*)ntfs_fetch_cache(
562 					dir_ni->vol->lookup_cache,
563 					GENERIC(&item), lookup_cache_compare);
564 			if (cached) {
565 				inum = cached->inum;
566 				if (inum == (u64)-1)
567 					errno = ENOENT;
568 			} else {
569 				/* Generate unicode name. */
570 				uname_len = ntfs_mbstoucs(name, &uname);
571 				if (uname_len >= 0) {
572 					inum = ntfs_inode_lookup_by_name(dir_ni,
573 							uname, uname_len);
574 					item.inum = inum;
575 				/* enter into cache, even if not found */
576 					ntfs_enter_cache(dir_ni->vol->lookup_cache,
577 							GENERIC(&item),
578 							lookup_cache_compare);
579 					free(uname);
580 				} else
581 					inum = (s64)-1;
582 			}
583 		} else
584 #endif
585 			{
586 				/* Generate unicode name. */
587 			uname_len = ntfs_mbstoucs(cached_name, &uname);
588 			if (uname_len >= 0)
589 				inum = ntfs_inode_lookup_by_name(dir_ni,
590 						uname, uname_len);
591 			else
592 				inum = (s64)-1;
593 		}
594 		if (cached_name)
595 			free(cached_name);
596 	} else
597 		inum = (s64)-1;
598 	return (inum);
599 }
600 
601 /*
602  *		Update a cache lookup record when a name has been defined
603  *
604  *	The UTF-8 name is required
605  */
606 
ntfs_inode_update_mbsname(ntfs_inode * dir_ni,const char * name,u64 inum)607 void ntfs_inode_update_mbsname(ntfs_inode *dir_ni, const char *name, u64 inum)
608 {
609 #if CACHE_LOOKUP_SIZE
610 	struct CACHED_LOOKUP item;
611 	struct CACHED_LOOKUP *cached;
612 	char *cached_name;
613 
614 	if (dir_ni->vol->lookup_cache) {
615 		if (!NVolCaseSensitive(dir_ni->vol)) {
616 			cached_name = ntfs_uppercase_mbs(name,
617 				dir_ni->vol->upcase, dir_ni->vol->upcase_len);
618 			item.name = cached_name;
619 		} else {
620 			cached_name = (char*)NULL;
621 			item.name = name;
622 		}
623 		if (item.name) {
624 			item.namesize = strlen(item.name) + 1;
625 			item.parent = dir_ni->mft_no;
626 			item.inum = inum;
627 			cached = (struct CACHED_LOOKUP*)ntfs_enter_cache(
628 					dir_ni->vol->lookup_cache,
629 					GENERIC(&item), lookup_cache_compare);
630 			if (cached)
631 				cached->inum = inum;
632 			if (cached_name)
633 				free(cached_name);
634 		}
635 	}
636 #endif
637 }
638 
639 /**
640  * ntfs_pathname_to_inode - Find the inode which represents the given pathname
641  * @vol:       An ntfs volume obtained from ntfs_mount
642  * @parent:    A directory inode to begin the search (may be NULL)
643  * @pathname:  Pathname to be located
644  *
645  * Take an ASCII pathname and find the inode that represents it.  The function
646  * splits the path and then descends the directory tree.  If @parent is NULL,
647  * then the root directory '.' will be used as the base for the search.
648  *
649  * Return:  inode  Success, the pathname was valid
650  *	    NULL   Error, the pathname was invalid, or some other error occurred
651  */
ntfs_pathname_to_inode(ntfs_volume * vol,ntfs_inode * parent,const char * pathname)652 ntfs_inode *ntfs_pathname_to_inode(ntfs_volume *vol, ntfs_inode *parent,
653 		const char *pathname)
654 {
655 	u64 inum;
656 	int len, err = 0;
657 	char *p, *q;
658 	ntfs_inode *ni;
659 	ntfs_inode *result = NULL;
660 	ntfschar *unicode = NULL;
661 	char *ascii = NULL;
662 #if CACHE_INODE_SIZE
663 	struct CACHED_INODE item;
664 	struct CACHED_INODE *cached;
665 	char *fullname;
666 #endif
667 
668 	if (!vol || !pathname) {
669 		errno = EINVAL;
670 		return NULL;
671 	}
672 
673 	ntfs_log_trace("path: '%s'\n", pathname);
674 
675 	ascii = strdup(pathname);
676 	if (!ascii) {
677 		ntfs_log_error("Out of memory.\n");
678 		err = ENOMEM;
679 		goto out;
680 	}
681 
682 	p = ascii;
683 	/* Remove leading /'s. */
684 	while (p && *p && *p == PATH_SEP)
685 		p++;
686 #if CACHE_INODE_SIZE
687 	fullname = p;
688 	if (p[0] && (p[strlen(p)-1] == PATH_SEP))
689 		ntfs_log_error("Unnormalized path %s\n",ascii);
690 #endif
691 	if (parent) {
692 		ni = parent;
693 	} else {
694 #if CACHE_INODE_SIZE
695 			/*
696 			 * fetch inode for full path from cache
697 			 */
698 		if (*fullname) {
699 			item.pathname = fullname;
700 			item.varsize = strlen(fullname) + 1;
701 			cached = (struct CACHED_INODE*)ntfs_fetch_cache(
702 				vol->xinode_cache, GENERIC(&item),
703 				inode_cache_compare);
704 		} else
705 			cached = (struct CACHED_INODE*)NULL;
706 		if (cached) {
707 			/*
708 			 * return opened inode if found in cache
709 			 */
710 			inum = MREF(cached->inum);
711 			ni = ntfs_inode_open(vol, inum);
712 			if (!ni) {
713 				ntfs_log_debug("Cannot open inode %llu: %s.\n",
714 						(unsigned long long)inum, p);
715 				err = EIO;
716 			}
717 			result = ni;
718 			goto out;
719 		}
720 #endif
721 		ni = ntfs_inode_open(vol, FILE_root);
722 		if (!ni) {
723 			ntfs_log_debug("Couldn't open the inode of the root "
724 					"directory.\n");
725 			err = EIO;
726 			result = (ntfs_inode*)NULL;
727 			goto out;
728 		}
729 	}
730 
731 	while (p && *p) {
732 		/* Find the end of the first token. */
733 		q = strchr(p, PATH_SEP);
734 		if (q != NULL) {
735 			*q = '\0';
736 		}
737 #if CACHE_INODE_SIZE
738 			/*
739 			 * fetch inode for partial path from cache
740 			 */
741 		cached = (struct CACHED_INODE*)NULL;
742 		if (!parent) {
743 			item.pathname = fullname;
744 			item.varsize = strlen(fullname) + 1;
745 			cached = (struct CACHED_INODE*)ntfs_fetch_cache(
746 					vol->xinode_cache, GENERIC(&item),
747 					inode_cache_compare);
748 			if (cached) {
749 				inum = cached->inum;
750 			}
751 		}
752 			/*
753 			 * if not in cache, translate, search, then
754 			 * insert into cache if found
755 			 */
756 		if (!cached) {
757 			len = ntfs_mbstoucs(p, &unicode);
758 			if (len < 0) {
759 				ntfs_log_perror("Could not convert filename to Unicode:"
760 					" '%s'", p);
761 				err = errno;
762 				goto close;
763 			} else if (len > NTFS_MAX_NAME_LEN) {
764 				err = ENAMETOOLONG;
765 				goto close;
766 			}
767 			inum = ntfs_inode_lookup_by_name(ni, unicode, len);
768 			if (!parent && (inum != (u64) -1)) {
769 				item.inum = inum;
770 				ntfs_enter_cache(vol->xinode_cache,
771 						GENERIC(&item),
772 						inode_cache_compare);
773 			}
774 		}
775 #else
776 		len = ntfs_mbstoucs(p, &unicode);
777 		if (len < 0) {
778 			ntfs_log_perror("Could not convert filename to Unicode:"
779 					" '%s'", p);
780 			err = errno;
781 			goto close;
782 		} else if (len > NTFS_MAX_NAME_LEN) {
783 			err = ENAMETOOLONG;
784 			goto close;
785 		}
786 		inum = ntfs_inode_lookup_by_name(ni, unicode, len);
787 #endif
788 		if (inum == (u64) -1) {
789 			ntfs_log_debug("Couldn't find name '%s' in pathname "
790 					"'%s'.\n", p, pathname);
791 			err = ENOENT;
792 			goto close;
793 		}
794 
795 		if (ni != parent)
796 			if (ntfs_inode_close(ni)) {
797 				err = errno;
798 				goto out;
799 			}
800 
801 		inum = MREF(inum);
802 		ni = ntfs_inode_open(vol, inum);
803 		if (!ni) {
804 			ntfs_log_debug("Cannot open inode %llu: %s.\n",
805 					(unsigned long long)inum, p);
806 			err = EIO;
807 			goto close;
808 		}
809 
810 		free(unicode);
811 		unicode = NULL;
812 
813 		if (q) *q++ = PATH_SEP; /* JPA */
814 		p = q;
815 		while (p && *p && *p == PATH_SEP)
816 			p++;
817 	}
818 
819 	result = ni;
820 	ni = NULL;
821 close:
822 	if (ni && (ni != parent))
823 		if (ntfs_inode_close(ni) && !err)
824 			err = errno;
825 out:
826 	free(ascii);
827 	free(unicode);
828 	if (err)
829 		errno = err;
830 	return result;
831 }
832 
833 /*
834  * The little endian Unicode string ".." for ntfs_readdir().
835  */
836 static const ntfschar dotdot[3] = { const_cpu_to_le16('.'),
837 				   const_cpu_to_le16('.'),
838 				   const_cpu_to_le16('\0') };
839 
840 /*
841  * union index_union -
842  * More helpers for ntfs_readdir().
843  */
844 typedef union {
845 	INDEX_ROOT *ir;
846 	INDEX_ALLOCATION *ia;
847 } index_union __attribute__((__transparent_union__));
848 
849 /**
850  * enum INDEX_TYPE -
851  * More helpers for ntfs_readdir().
852  */
853 typedef enum {
854 	INDEX_TYPE_ROOT,	/* index root */
855 	INDEX_TYPE_ALLOCATION,	/* index allocation */
856 } INDEX_TYPE;
857 
858 /*
859  *		Decode Interix file types
860  *
861  *	Non-Interix types are returned as plain files, because a
862  *	Windows user may force patterns very similar to Interix,
863  *	and most metadata files have such similar patters.
864  */
865 
ntfs_interix_types(ntfs_inode * ni)866 u32 ntfs_interix_types(ntfs_inode *ni)
867 {
868 	ntfs_attr *na;
869 	u32 dt_type;
870 	le64 magic;
871 
872 	dt_type = NTFS_DT_UNKNOWN;
873 	na = ntfs_attr_open(ni, AT_DATA, NULL, 0);
874 	if (na) {
875 		/*
876 		 * Unrecognized patterns (eg HID + SYST for metadata)
877 		 * are plain files or directories
878 		 */
879 		if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)
880 			dt_type = NTFS_DT_DIR;
881 		else
882 			dt_type = NTFS_DT_REG;
883 		if (na->data_size <= 1) {
884 			if (!(ni->flags & FILE_ATTR_HIDDEN))
885 				dt_type = (na->data_size ?
886 						NTFS_DT_SOCK : NTFS_DT_FIFO);
887 		} else {
888 			if ((na->data_size >= (s64)sizeof(magic))
889 			    && (ntfs_attr_pread(na, 0, sizeof(magic), &magic)
890 				== sizeof(magic))) {
891 				if (magic == INTX_SYMBOLIC_LINK)
892 					dt_type = NTFS_DT_LNK;
893 				else if (magic == INTX_BLOCK_DEVICE)
894 					dt_type = NTFS_DT_BLK;
895 				else if (magic == INTX_CHARACTER_DEVICE)
896 					dt_type = NTFS_DT_CHR;
897 			}
898 		}
899 		ntfs_attr_close(na);
900 	}
901 	return (dt_type);
902 }
903 
904 /*
905  *		Decode file types
906  *
907  *	Better only use for Interix types and junctions,
908  *	unneeded complexity when used for plain files or directories
909  *
910  *	Error cases are logged and returned as unknown.
911  */
912 
ntfs_dir_entry_type(ntfs_inode * dir_ni,MFT_REF mref,FILE_ATTR_FLAGS attributes)913 static u32 ntfs_dir_entry_type(ntfs_inode *dir_ni, MFT_REF mref,
914 					FILE_ATTR_FLAGS attributes)
915 {
916 	ntfs_inode *ni;
917 	u32 dt_type;
918 
919 	dt_type = NTFS_DT_UNKNOWN;
920 	ni = ntfs_inode_open(dir_ni->vol, mref);
921 	if (ni) {
922 		if (attributes & FILE_ATTR_REPARSE_POINT)
923 			dt_type = (ntfs_possible_symlink(ni)
924 				? NTFS_DT_LNK : NTFS_DT_REPARSE);
925 		else
926 			if ((attributes & FILE_ATTR_SYSTEM)
927 			   && !(attributes & FILE_ATTR_I30_INDEX_PRESENT))
928 				dt_type = ntfs_interix_types(ni);
929 			else
930 				dt_type = (attributes
931 						& FILE_ATTR_I30_INDEX_PRESENT
932 					? NTFS_DT_DIR : NTFS_DT_REG);
933 		if (ntfs_inode_close(ni)) {
934 				 /* anything special worth doing ? */
935 			ntfs_log_error("Failed to close inode %lld\n",
936 				(long long)MREF(mref));
937 		}
938 	}
939 	if (dt_type == NTFS_DT_UNKNOWN)
940 		ntfs_log_error("Could not decode the type of inode %lld\n",
941 				(long long)MREF(mref));
942 	return (dt_type);
943 }
944 
945 /**
946  * ntfs_filldir - ntfs specific filldir method
947  * @dir_ni:	ntfs inode of current directory
948  * @pos:	current position in directory
949  * @ivcn_bits:	log(2) of index vcn size
950  * @index_type:	specifies whether @iu is an index root or an index allocation
951  * @iu:		index root or index block to which @ie belongs
952  * @ie:		current index entry
953  * @dirent:	context for filldir callback supplied by the caller
954  * @filldir:	filldir callback supplied by the caller
955  *
956  * Pass information specifying the current directory entry @ie to the @filldir
957  * callback.
958  */
ntfs_filldir(ntfs_inode * dir_ni,s64 * pos,u8 ivcn_bits,const INDEX_TYPE index_type,index_union iu,INDEX_ENTRY * ie,void * dirent,ntfs_filldir_t filldir)959 static int ntfs_filldir(ntfs_inode *dir_ni, s64 *pos, u8 ivcn_bits,
960 		const INDEX_TYPE index_type, index_union iu, INDEX_ENTRY *ie,
961 		void *dirent, ntfs_filldir_t filldir)
962 {
963 	FILE_NAME_ATTR *fn = &ie->key.file_name;
964 	unsigned dt_type;
965 	BOOL metadata;
966 	ntfschar *loname;
967 	int res;
968 	MFT_REF mref;
969 
970 	ntfs_log_trace("Entering.\n");
971 
972 	/* Advance the position even if going to skip the entry. */
973 	if (index_type == INDEX_TYPE_ALLOCATION)
974 		*pos = (u8*)ie - (u8*)iu.ia + (sle64_to_cpu(
975 				iu.ia->index_block_vcn) << ivcn_bits) +
976 				dir_ni->vol->mft_record_size;
977 	else /* if (index_type == INDEX_TYPE_ROOT) */
978 		*pos = (u8*)ie - (u8*)iu.ir;
979 	mref = le64_to_cpu(ie->indexed_file);
980 	metadata = (MREF(mref) != FILE_root) && (MREF(mref) < FILE_first_user);
981 	/* Skip root directory self reference entry. */
982 	if (MREF_LE(ie->indexed_file) == FILE_root)
983 		return 0;
984 	if ((ie->key.file_name.file_attributes
985 		     & (FILE_ATTR_REPARSE_POINT | FILE_ATTR_SYSTEM))
986 	    && !metadata)
987 		dt_type = ntfs_dir_entry_type(dir_ni, mref,
988 					ie->key.file_name.file_attributes);
989 	else if (ie->key.file_name.file_attributes
990 		     & FILE_ATTR_I30_INDEX_PRESENT)
991 		dt_type = NTFS_DT_DIR;
992 	else
993 		dt_type = NTFS_DT_REG;
994 
995 		/* return metadata files and hidden files if requested */
996         if ((!metadata && (NVolShowHidFiles(dir_ni->vol)
997 				|| !(fn->file_attributes & FILE_ATTR_HIDDEN)))
998             || (NVolShowSysFiles(dir_ni->vol) && (NVolShowHidFiles(dir_ni->vol)
999 				|| metadata))) {
1000 		if (NVolCaseSensitive(dir_ni->vol)) {
1001 			res = filldir(dirent, fn->file_name,
1002 					fn->file_name_length,
1003 					fn->file_name_type, *pos,
1004 					mref, dt_type);
1005 		} else {
1006 			loname = (ntfschar*)ntfs_malloc(2*fn->file_name_length);
1007 			if (loname) {
1008 				memcpy(loname, fn->file_name,
1009 					2*fn->file_name_length);
1010 				ntfs_name_locase(loname, fn->file_name_length,
1011 					dir_ni->vol->locase,
1012 					dir_ni->vol->upcase_len);
1013 				res = filldir(dirent, loname,
1014 					fn->file_name_length,
1015 					fn->file_name_type, *pos,
1016 					mref, dt_type);
1017 				free(loname);
1018 			} else
1019 				res = -1;
1020 		}
1021 	} else
1022 		res = 0;
1023 	return (res);
1024 }
1025 
1026 /**
1027  * ntfs_mft_get_parent_ref - find mft reference of parent directory of an inode
1028  * @ni:		ntfs inode whose parent directory to find
1029  *
1030  * Find the parent directory of the ntfs inode @ni. To do this, find the first
1031  * file name attribute in the mft record of @ni and return the parent mft
1032  * reference from that.
1033  *
1034  * Note this only makes sense for directories, since files can be hard linked
1035  * from multiple directories and there is no way for us to tell which one is
1036  * being looked for.
1037  *
1038  * Technically directories can have hard links, too, but we consider that as
1039  * illegal as Linux/UNIX do not support directory hard links.
1040  *
1041  * Return the mft reference of the parent directory on success or -1 on error
1042  * with errno set to the error code.
1043  */
ntfs_mft_get_parent_ref(ntfs_inode * ni)1044 static MFT_REF ntfs_mft_get_parent_ref(ntfs_inode *ni)
1045 {
1046 	MFT_REF mref;
1047 	ntfs_attr_search_ctx *ctx;
1048 	FILE_NAME_ATTR *fn;
1049 	int eo;
1050 
1051 	ntfs_log_trace("Entering.\n");
1052 
1053 	if (!ni) {
1054 		errno = EINVAL;
1055 		return ERR_MREF(-1);
1056 	}
1057 
1058 	ctx = ntfs_attr_get_search_ctx(ni, NULL);
1059 	if (!ctx)
1060 		return ERR_MREF(-1);
1061 	if (ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, 0, 0, NULL, 0, ctx)) {
1062 		ntfs_log_error("No file name found in inode %lld\n",
1063 			       (unsigned long long)ni->mft_no);
1064 		goto err_out;
1065 	}
1066 	if (ctx->attr->non_resident) {
1067 		ntfs_log_error("File name attribute must be resident (inode "
1068 			       "%lld)\n", (unsigned long long)ni->mft_no);
1069 		goto io_err_out;
1070 	}
1071 	fn = (FILE_NAME_ATTR*)((u8*)ctx->attr +
1072 			le16_to_cpu(ctx->attr->value_offset));
1073 	mref = le64_to_cpu(fn->parent_directory);
1074 	ntfs_attr_put_search_ctx(ctx);
1075 	return mref;
1076 io_err_out:
1077 	errno = EIO;
1078 err_out:
1079 	eo = errno;
1080 	ntfs_attr_put_search_ctx(ctx);
1081 	errno = eo;
1082 	return ERR_MREF(-1);
1083 }
1084 
1085 /**
1086  * ntfs_readdir - read the contents of an ntfs directory
1087  * @dir_ni:	ntfs inode of current directory
1088  * @pos:	current position in directory
1089  * @dirent:	context for filldir callback supplied by the caller
1090  * @filldir:	filldir callback supplied by the caller
1091  *
1092  * Parse the index root and the index blocks that are marked in use in the
1093  * index bitmap and hand each found directory entry to the @filldir callback
1094  * supplied by the caller.
1095  *
1096  * Return 0 on success or -1 on error with errno set to the error code.
1097  *
1098  * Note: Index blocks are parsed in ascending vcn order, from which follows
1099  * that the directory entries are not returned sorted.
1100  */
ntfs_readdir(ntfs_inode * dir_ni,s64 * pos,void * dirent,ntfs_filldir_t filldir)1101 int ntfs_readdir(ntfs_inode *dir_ni, s64 *pos,
1102 		void *dirent, ntfs_filldir_t filldir)
1103 {
1104 	s64 i_size, br, ia_pos, bmp_pos, ia_start;
1105 	ntfs_volume *vol;
1106 	ntfs_attr *ia_na, *bmp_na = NULL;
1107 	ntfs_attr_search_ctx *ctx = NULL;
1108 	u8 *index_end, *bmp = NULL;
1109 	INDEX_ROOT *ir;
1110 	INDEX_ENTRY *ie;
1111 	INDEX_ALLOCATION *ia = NULL;
1112 	int rc, ir_pos, bmp_buf_size, bmp_buf_pos, eo;
1113 	u32 index_block_size;
1114 	u8 index_block_size_bits, index_vcn_size_bits;
1115 
1116 	ntfs_log_trace("Entering.\n");
1117 
1118 	if (!dir_ni || !pos || !filldir) {
1119 		errno = EINVAL;
1120 		return -1;
1121 	}
1122 
1123 	if (!(dir_ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) {
1124 		errno = ENOTDIR;
1125 		return -1;
1126 	}
1127 
1128 	vol = dir_ni->vol;
1129 
1130 	ntfs_log_trace("Entering for inode %lld, *pos 0x%llx.\n",
1131 			(unsigned long long)dir_ni->mft_no, (long long)*pos);
1132 
1133 	/* Open the index allocation attribute. */
1134 	ia_na = ntfs_attr_open(dir_ni, AT_INDEX_ALLOCATION, NTFS_INDEX_I30, 4);
1135 	if (!ia_na) {
1136 		if (errno != ENOENT) {
1137 			ntfs_log_perror("Failed to open index allocation attribute. "
1138 				"Directory inode %lld is corrupt or bug",
1139 				(unsigned long long)dir_ni->mft_no);
1140 			return -1;
1141 		}
1142 		i_size = 0;
1143 	} else
1144 		i_size = ia_na->data_size;
1145 
1146 	rc = 0;
1147 
1148 	/* Are we at end of dir yet? */
1149 	if (*pos >= i_size + vol->mft_record_size)
1150 		goto done;
1151 
1152 	/* Emulate . and .. for all directories. */
1153 	if (!*pos) {
1154 		rc = filldir(dirent, dotdot, 1, FILE_NAME_POSIX, *pos,
1155 				MK_MREF(dir_ni->mft_no,
1156 				le16_to_cpu(dir_ni->mrec->sequence_number)),
1157 				NTFS_DT_DIR);
1158 		if (rc)
1159 			goto err_out;
1160 		++*pos;
1161 	}
1162 	if (*pos == 1) {
1163 		MFT_REF parent_mref;
1164 
1165 		parent_mref = ntfs_mft_get_parent_ref(dir_ni);
1166 		if (parent_mref == ERR_MREF(-1)) {
1167 			ntfs_log_perror("Parent directory not found");
1168 			goto dir_err_out;
1169 		}
1170 
1171 		rc = filldir(dirent, dotdot, 2, FILE_NAME_POSIX, *pos,
1172 				parent_mref, NTFS_DT_DIR);
1173 		if (rc)
1174 			goto err_out;
1175 		++*pos;
1176 	}
1177 
1178 	ctx = ntfs_attr_get_search_ctx(dir_ni, NULL);
1179 	if (!ctx)
1180 		goto err_out;
1181 
1182 	/* Get the offset into the index root attribute. */
1183 	ir_pos = (int)*pos;
1184 	/* Find the index root attribute in the mft record. */
1185 	if (ntfs_attr_lookup(AT_INDEX_ROOT, NTFS_INDEX_I30, 4, CASE_SENSITIVE, 0, NULL,
1186 			0, ctx)) {
1187 		ntfs_log_perror("Index root attribute missing in directory inode "
1188 				"%lld", (unsigned long long)dir_ni->mft_no);
1189 		goto dir_err_out;
1190 	}
1191 	/* Get to the index root value. */
1192 	ir = (INDEX_ROOT*)((u8*)ctx->attr +
1193 			le16_to_cpu(ctx->attr->value_offset));
1194 
1195 	/* Determine the size of a vcn in the directory index. */
1196 	index_block_size = le32_to_cpu(ir->index_block_size);
1197 	if (index_block_size < NTFS_BLOCK_SIZE ||
1198 			index_block_size & (index_block_size - 1)) {
1199 		ntfs_log_error("Index block size %u is invalid.\n",
1200 				(unsigned)index_block_size);
1201 		goto dir_err_out;
1202 	}
1203 	index_block_size_bits = ffs(index_block_size) - 1;
1204 	if (vol->cluster_size <= index_block_size) {
1205 		index_vcn_size_bits = vol->cluster_size_bits;
1206 	} else {
1207 		index_vcn_size_bits = NTFS_BLOCK_SIZE_BITS;
1208 	}
1209 
1210 	/* Are we jumping straight into the index allocation attribute? */
1211 	if (*pos >= vol->mft_record_size) {
1212 		ntfs_attr_put_search_ctx(ctx);
1213 		ctx = NULL;
1214 		goto skip_index_root;
1215 	}
1216 
1217 	index_end = (u8*)&ir->index + le32_to_cpu(ir->index.index_length);
1218 	/* The first index entry. */
1219 	ie = (INDEX_ENTRY*)((u8*)&ir->index +
1220 			le32_to_cpu(ir->index.entries_offset));
1221 	/*
1222 	 * Loop until we exceed valid memory (corruption case) or until we
1223 	 * reach the last entry or until filldir tells us it has had enough
1224 	 * or signals an error (both covered by the rc test).
1225 	 */
1226 	for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
1227 		ntfs_log_debug("In index root, offset %d.\n", (int)((u8*)ie - (u8*)ir));
1228 		/* Bounds checks. */
1229 		if ((u8*)ie < (u8*)ctx->mrec || (u8*)ie +
1230 				sizeof(INDEX_ENTRY_HEADER) > index_end ||
1231 				(u8*)ie + le16_to_cpu(ie->length) >
1232 				index_end) {
1233 			ntfs_log_error("Index root entry out of bounds in"
1234 					" inode %lld\n",
1235 					(unsigned long long)dir_ni->mft_no);
1236 			goto dir_err_out;
1237 		}
1238 		/* The last entry cannot contain a name. */
1239 		if (ie->ie_flags & INDEX_ENTRY_END)
1240 			break;
1241 
1242 		if (!le16_to_cpu(ie->length))
1243 			goto dir_err_out;
1244 
1245 		/* Skip index root entry if continuing previous readdir. */
1246 		if (ir_pos > (u8*)ie - (u8*)ir)
1247 			continue;
1248 
1249 		/* The file name must not overflow from the entry */
1250 		if (ntfs_index_entry_inconsistent(ie, COLLATION_FILE_NAME,
1251 				dir_ni->mft_no)) {
1252 			errno = EIO;
1253 			goto dir_err_out;
1254 		}
1255 		/*
1256 		 * Submit the directory entry to ntfs_filldir(), which will
1257 		 * invoke the filldir() callback as appropriate.
1258 		 */
1259 		rc = ntfs_filldir(dir_ni, pos, index_vcn_size_bits,
1260 				INDEX_TYPE_ROOT, ir, ie, dirent, filldir);
1261 		if (rc) {
1262 			ntfs_attr_put_search_ctx(ctx);
1263 			ctx = NULL;
1264 			goto err_out;
1265 		}
1266 	}
1267 	ntfs_attr_put_search_ctx(ctx);
1268 	ctx = NULL;
1269 
1270 	/* If there is no index allocation attribute we are finished. */
1271 	if (!ia_na)
1272 		goto EOD;
1273 
1274 	/* Advance *pos to the beginning of the index allocation. */
1275 	*pos = vol->mft_record_size;
1276 
1277 skip_index_root:
1278 
1279 	if (!ia_na)
1280 		goto done;
1281 
1282 	/* Allocate a buffer for the current index block. */
1283 	ia = ntfs_malloc(index_block_size);
1284 	if (!ia)
1285 		goto err_out;
1286 
1287 	bmp_na = ntfs_attr_open(dir_ni, AT_BITMAP, NTFS_INDEX_I30, 4);
1288 	if (!bmp_na) {
1289 		ntfs_log_perror("Failed to open index bitmap attribute");
1290 		goto dir_err_out;
1291 	}
1292 
1293 	/* Get the offset into the index allocation attribute. */
1294 	ia_pos = *pos - vol->mft_record_size;
1295 
1296 	bmp_pos = ia_pos >> index_block_size_bits;
1297 	if (bmp_pos >> 3 >= bmp_na->data_size) {
1298 		ntfs_log_error("Current index position exceeds index bitmap "
1299 				"size.\n");
1300 		goto dir_err_out;
1301 	}
1302 
1303 	bmp_buf_size = min(bmp_na->data_size - (bmp_pos >> 3), 4096);
1304 	bmp = ntfs_malloc(bmp_buf_size);
1305 	if (!bmp)
1306 		goto err_out;
1307 
1308 	br = ntfs_attr_pread(bmp_na, bmp_pos >> 3, bmp_buf_size, bmp);
1309 	if (br != bmp_buf_size) {
1310 		if (br != -1)
1311 			errno = EIO;
1312 		ntfs_log_perror("Failed to read from index bitmap attribute");
1313 		goto err_out;
1314 	}
1315 
1316 	bmp_buf_pos = 0;
1317 	/* If the index block is not in use find the next one that is. */
1318 	while (!(bmp[bmp_buf_pos >> 3] & (1 << (bmp_buf_pos & 7)))) {
1319 find_next_index_buffer:
1320 		bmp_pos++;
1321 		bmp_buf_pos++;
1322 		/* If we have reached the end of the bitmap, we are done. */
1323 		if (bmp_pos >> 3 >= bmp_na->data_size)
1324 			goto EOD;
1325 		ia_pos = bmp_pos << index_block_size_bits;
1326 		if (bmp_buf_pos >> 3 < bmp_buf_size)
1327 			continue;
1328 		/* Read next chunk from the index bitmap. */
1329 		bmp_buf_pos = 0;
1330 		if ((bmp_pos >> 3) + bmp_buf_size > bmp_na->data_size)
1331 			bmp_buf_size = bmp_na->data_size - (bmp_pos >> 3);
1332 		br = ntfs_attr_pread(bmp_na, bmp_pos >> 3, bmp_buf_size, bmp);
1333 		if (br != bmp_buf_size) {
1334 			if (br != -1)
1335 				errno = EIO;
1336 			ntfs_log_perror("Failed to read from index bitmap attribute");
1337 			goto err_out;
1338 		}
1339 	}
1340 
1341 	ntfs_log_debug("Handling index block 0x%llx.\n", (long long)bmp_pos);
1342 
1343 	/* Read the index block starting at bmp_pos. */
1344 	br = ntfs_attr_mst_pread(ia_na, bmp_pos << index_block_size_bits, 1,
1345 			index_block_size, ia);
1346 	if (br != 1) {
1347 		if (br != -1)
1348 			errno = EIO;
1349 		ntfs_log_perror("Failed to read index block");
1350 		goto err_out;
1351 	}
1352 
1353 	ia_start = ia_pos & ~(s64)(index_block_size - 1);
1354 	if (ntfs_index_block_inconsistent((INDEX_BLOCK*)ia, index_block_size,
1355 			ia_na->ni->mft_no, ia_start >> index_vcn_size_bits)) {
1356 		goto dir_err_out;
1357 	}
1358 	index_end = (u8*)&ia->index + le32_to_cpu(ia->index.index_length);
1359 
1360 	/* The first index entry. */
1361 	ie = (INDEX_ENTRY*)((u8*)&ia->index +
1362 			le32_to_cpu(ia->index.entries_offset));
1363 	/*
1364 	 * Loop until we exceed valid memory (corruption case) or until we
1365 	 * reach the last entry or until ntfs_filldir tells us it has had
1366 	 * enough or signals an error (both covered by the rc test).
1367 	 */
1368 	for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
1369 		ntfs_log_debug("In index allocation, offset 0x%llx.\n",
1370 				(long long)ia_start + ((u8*)ie - (u8*)ia));
1371 		/* Bounds checks. */
1372 		if ((u8*)ie < (u8*)ia || (u8*)ie +
1373 				sizeof(INDEX_ENTRY_HEADER) > index_end ||
1374 				(u8*)ie + le16_to_cpu(ie->length) >
1375 				index_end) {
1376 			ntfs_log_error("Index entry out of bounds in directory inode "
1377 				"%lld.\n", (unsigned long long)dir_ni->mft_no);
1378 			goto dir_err_out;
1379 		}
1380 		/* The last entry cannot contain a name. */
1381 		if (ie->ie_flags & INDEX_ENTRY_END)
1382 			break;
1383 
1384 		if (!le16_to_cpu(ie->length))
1385 			goto dir_err_out;
1386 
1387 		/* Skip index entry if continuing previous readdir. */
1388 		if (ia_pos - ia_start > (u8*)ie - (u8*)ia)
1389 			continue;
1390 
1391 		/* The file name must not overflow from the entry */
1392 		if (ntfs_index_entry_inconsistent(ie, COLLATION_FILE_NAME,
1393 				dir_ni->mft_no)) {
1394 			errno = EIO;
1395 			goto dir_err_out;
1396 		}
1397 		/*
1398 		 * Submit the directory entry to ntfs_filldir(), which will
1399 		 * invoke the filldir() callback as appropriate.
1400 		 */
1401 		rc = ntfs_filldir(dir_ni, pos, index_vcn_size_bits,
1402 				INDEX_TYPE_ALLOCATION, ia, ie, dirent, filldir);
1403 		if (rc)
1404 			goto err_out;
1405 	}
1406 	goto find_next_index_buffer;
1407 EOD:
1408 	/* We are finished, set *pos to EOD. */
1409 	*pos = i_size + vol->mft_record_size;
1410 done:
1411 	free(ia);
1412 	free(bmp);
1413 	if (bmp_na)
1414 		ntfs_attr_close(bmp_na);
1415 	if (ia_na)
1416 		ntfs_attr_close(ia_na);
1417 	ntfs_log_debug("EOD, *pos 0x%llx, returning 0.\n", (long long)*pos);
1418 	return 0;
1419 dir_err_out:
1420 	errno = EIO;
1421 err_out:
1422 	eo = errno;
1423 	ntfs_log_trace("failed.\n");
1424 	if (ctx)
1425 		ntfs_attr_put_search_ctx(ctx);
1426 	free(ia);
1427 	free(bmp);
1428 	if (bmp_na)
1429 		ntfs_attr_close(bmp_na);
1430 	if (ia_na)
1431 		ntfs_attr_close(ia_na);
1432 	errno = eo;
1433 	return -1;
1434 }
1435 
1436 
1437 /**
1438  * __ntfs_create - create object on ntfs volume
1439  * @dir_ni:	ntfs inode for directory in which create new object
1440  * @securid:	id of inheritable security descriptor, 0 if none
1441  * @name:	unicode name of new object
1442  * @name_len:	length of the name in unicode characters
1443  * @type:	type of the object to create
1444  * @dev:	major and minor device numbers (obtained from makedev())
1445  * @target:	target in unicode (only for symlinks)
1446  * @target_len:	length of target in unicode characters
1447  *
1448  * Internal, use ntfs_create{,_device,_symlink} wrappers instead.
1449  *
1450  * @type can be:
1451  *	S_IFREG		to create regular file
1452  *	S_IFDIR		to create directory
1453  *	S_IFBLK		to create block device
1454  *	S_IFCHR		to create character device
1455  *	S_IFLNK		to create symbolic link
1456  *	S_IFIFO		to create FIFO
1457  *	S_IFSOCK	to create socket
1458  * other values are invalid.
1459  *
1460  * @dev is used only if @type is S_IFBLK or S_IFCHR, in other cases its value
1461  * ignored.
1462  *
1463  * @target and @target_len are used only if @type is S_IFLNK, in other cases
1464  * their value ignored.
1465  *
1466  * Return opened ntfs inode that describes created object on success or NULL
1467  * on error with errno set to the error code.
1468  */
__ntfs_create(ntfs_inode * dir_ni,le32 securid,const ntfschar * name,u8 name_len,mode_t type,dev_t dev,const ntfschar * target,int target_len)1469 static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, le32 securid,
1470 		const ntfschar *name, u8 name_len, mode_t type, dev_t dev,
1471 		const ntfschar *target, int target_len)
1472 {
1473 	ntfs_inode *ni;
1474 	int rollback_data = 0, rollback_sd = 0;
1475 	int rollback_dir = 0;
1476 	FILE_NAME_ATTR *fn = NULL;
1477 	STANDARD_INFORMATION *si = NULL;
1478 	int err, fn_len, si_len;
1479 	ntfs_volume_special_files special_files;
1480 
1481 	ntfs_log_trace("Entering.\n");
1482 
1483 	/* Sanity checks. */
1484 	if (!dir_ni || !name || !name_len) {
1485 		ntfs_log_error("Invalid arguments.\n");
1486 		errno = EINVAL;
1487 		return NULL;
1488 	}
1489 
1490 	ni = ntfs_mft_record_alloc(dir_ni->vol, NULL);
1491 	if (!ni)
1492 		return NULL;
1493 #if CACHE_NIDATA_SIZE
1494 	ntfs_inode_invalidate(dir_ni->vol, ni->mft_no);
1495 #endif
1496 	special_files = dir_ni->vol->special_files;
1497 	/*
1498 	 * Create STANDARD_INFORMATION attribute.
1499 	 * JPA Depending on available inherited security descriptor,
1500 	 * Write STANDARD_INFORMATION v1.2 (no inheritance) or v3
1501 	 */
1502 	if (securid)
1503 		si_len = sizeof(STANDARD_INFORMATION);
1504 	else
1505 		si_len = offsetof(STANDARD_INFORMATION, v1_end);
1506 	si = ntfs_calloc(si_len);
1507 	if (!si) {
1508 		err = errno;
1509 		goto err_out;
1510 	}
1511 	si->creation_time = ni->creation_time;
1512 	si->last_data_change_time = ni->last_data_change_time;
1513 	si->last_mft_change_time = ni->last_mft_change_time;
1514 	si->last_access_time = ni->last_access_time;
1515 	if (securid) {
1516 		set_nino_flag(ni, v3_Extensions);
1517 		ni->owner_id = si->owner_id = const_cpu_to_le32(0);
1518 		ni->security_id = si->security_id = securid;
1519 		ni->quota_charged = si->quota_charged = const_cpu_to_le64(0);
1520 		ni->usn = si->usn = const_cpu_to_le64(0);
1521 	} else
1522 		clear_nino_flag(ni, v3_Extensions);
1523 	if (!S_ISREG(type) && !S_ISDIR(type)) {
1524 		switch (special_files) {
1525 		case NTFS_FILES_WSL :
1526 			if (!S_ISLNK(type)) {
1527 				si->file_attributes
1528 					= FILE_ATTRIBUTE_RECALL_ON_OPEN;
1529 				ni->flags = FILE_ATTRIBUTE_RECALL_ON_OPEN;
1530 			}
1531 			break;
1532 		default :
1533 			si->file_attributes = FILE_ATTR_SYSTEM;
1534 			ni->flags = FILE_ATTR_SYSTEM;
1535 			break;
1536 		}
1537 	}
1538 	ni->flags |= FILE_ATTR_ARCHIVE;
1539 	if (NVolHideDotFiles(dir_ni->vol)
1540 	    && (name_len > 1)
1541 	    && (name[0] == const_cpu_to_le16('.'))
1542 	    && (name[1] != const_cpu_to_le16('.')))
1543 		ni->flags |= FILE_ATTR_HIDDEN;
1544 		/*
1545 		 * Set compression flag according to parent directory
1546 		 * unless NTFS version < 3.0 or cluster size > 4K
1547 		 * or compression has been disabled
1548 		 */
1549 	if ((dir_ni->flags & FILE_ATTR_COMPRESSED)
1550 	   && (dir_ni->vol->major_ver >= 3)
1551 	   && NVolCompression(dir_ni->vol)
1552 	   && (dir_ni->vol->cluster_size <= MAX_COMPRESSION_CLUSTER_SIZE)
1553 	   && (S_ISREG(type) || S_ISDIR(type)))
1554 		ni->flags |= FILE_ATTR_COMPRESSED;
1555 	/* Add STANDARD_INFORMATION to inode. */
1556 	if (ntfs_attr_add(ni, AT_STANDARD_INFORMATION, AT_UNNAMED, 0,
1557 			(u8*)si, si_len)) {
1558 		err = errno;
1559 		ntfs_log_error("Failed to add STANDARD_INFORMATION "
1560 				"attribute.\n");
1561 		goto err_out;
1562 	}
1563 
1564 	if (!securid) {
1565 		if (ntfs_sd_add_everyone(ni)) {
1566 			err = errno;
1567 			goto err_out;
1568 		}
1569 		rollback_sd = 1;
1570 	}
1571 
1572 	if (S_ISDIR(type)) {
1573 		INDEX_ROOT *ir = NULL;
1574 		INDEX_ENTRY *ie;
1575 		int ir_len, index_len;
1576 
1577 		/* Create INDEX_ROOT attribute. */
1578 		index_len = sizeof(INDEX_HEADER) + sizeof(INDEX_ENTRY_HEADER);
1579 		ir_len = offsetof(INDEX_ROOT, index) + index_len;
1580 		ir = ntfs_calloc(ir_len);
1581 		if (!ir) {
1582 			err = errno;
1583 			goto err_out;
1584 		}
1585 		ir->type = AT_FILE_NAME;
1586 		ir->collation_rule = COLLATION_FILE_NAME;
1587 		ir->index_block_size = cpu_to_le32(ni->vol->indx_record_size);
1588 		if (ni->vol->cluster_size <= ni->vol->indx_record_size)
1589 			ir->clusters_per_index_block =
1590 					ni->vol->indx_record_size >>
1591 					ni->vol->cluster_size_bits;
1592 		else
1593 			ir->clusters_per_index_block =
1594 					ni->vol->indx_record_size >>
1595 					NTFS_BLOCK_SIZE_BITS;
1596 		ir->index.entries_offset = const_cpu_to_le32(sizeof(INDEX_HEADER));
1597 		ir->index.index_length = cpu_to_le32(index_len);
1598 		ir->index.allocated_size = cpu_to_le32(index_len);
1599 		ie = (INDEX_ENTRY*)((u8*)ir + sizeof(INDEX_ROOT));
1600 		ie->length = const_cpu_to_le16(sizeof(INDEX_ENTRY_HEADER));
1601 		ie->key_length = const_cpu_to_le16(0);
1602 		ie->ie_flags = INDEX_ENTRY_END;
1603 		/* Add INDEX_ROOT attribute to inode. */
1604 		if (ntfs_attr_add(ni, AT_INDEX_ROOT, NTFS_INDEX_I30, 4,
1605 				(u8*)ir, ir_len)) {
1606 			err = errno;
1607 			free(ir);
1608 			ntfs_log_error("Failed to add INDEX_ROOT attribute.\n");
1609 			goto err_out;
1610 		}
1611 		free(ir);
1612 	} else {
1613 		INTX_FILE *data;
1614 		int data_len;
1615 
1616 		switch (type) {
1617 			case S_IFBLK:
1618 			case S_IFCHR:
1619 				switch (special_files) {
1620 				case NTFS_FILES_WSL :
1621 					data_len = 0;
1622 					data = (INTX_FILE*)NULL;
1623 					break;
1624 				default :
1625 					data_len = offsetof(INTX_FILE,
1626 								device_end);
1627 					data = (INTX_FILE*)ntfs_malloc(
1628 								data_len);
1629 					if (!data) {
1630 						err = errno;
1631 						goto err_out;
1632 					}
1633 					data->major = cpu_to_le64(major(dev));
1634 					data->minor = cpu_to_le64(minor(dev));
1635 					if (type == S_IFBLK)
1636 						data->magic
1637 							= INTX_BLOCK_DEVICE;
1638 					if (type == S_IFCHR)
1639 						data->magic
1640 							= INTX_CHARACTER_DEVICE;
1641 					break;
1642 				}
1643 				break;
1644 			case S_IFLNK:
1645 				switch (special_files) {
1646 				case NTFS_FILES_WSL :
1647 					data_len = 0;
1648 					data = (INTX_FILE*)NULL;
1649 					break;
1650 				default :
1651 					data_len = sizeof(INTX_FILE_TYPES) +
1652 						target_len * sizeof(ntfschar);
1653 					data = (INTX_FILE*)ntfs_malloc(
1654 								data_len);
1655 					if (!data) {
1656 						err = errno;
1657 						goto err_out;
1658 					}
1659 					data->magic = INTX_SYMBOLIC_LINK;
1660 					memcpy(data->target, target,
1661 						target_len * sizeof(ntfschar));
1662 					break;
1663 				}
1664 				break;
1665 			case S_IFSOCK:
1666 				data = NULL;
1667 				if (special_files == NTFS_FILES_WSL)
1668 					data_len = 0;
1669 				else
1670 					data_len = 1;
1671 				break;
1672 			default: /* FIFO or regular file. */
1673 				data = NULL;
1674 				data_len = 0;
1675 				break;
1676 		}
1677 		/* Add DATA attribute to inode. */
1678 		if (ntfs_attr_add(ni, AT_DATA, AT_UNNAMED, 0, (u8*)data,
1679 				data_len)) {
1680 			err = errno;
1681 			ntfs_log_error("Failed to add DATA attribute.\n");
1682 			free(data);
1683 			goto err_out;
1684 		}
1685 		rollback_data = 1;
1686 		free(data);
1687 	}
1688 	/* Create FILE_NAME attribute. */
1689 	fn_len = sizeof(FILE_NAME_ATTR) + name_len * sizeof(ntfschar);
1690 	fn = ntfs_calloc(fn_len);
1691 	if (!fn) {
1692 		err = errno;
1693 		goto err_out;
1694 	}
1695 	fn->parent_directory = MK_LE_MREF(dir_ni->mft_no,
1696 			le16_to_cpu(dir_ni->mrec->sequence_number));
1697 	fn->file_name_length = name_len;
1698 	fn->file_name_type = FILE_NAME_POSIX;
1699 	if (S_ISDIR(type))
1700 		fn->file_attributes = FILE_ATTR_I30_INDEX_PRESENT;
1701 	if (!S_ISREG(type) && !S_ISDIR(type)) {
1702 		if (special_files == NTFS_FILES_INTERIX)
1703 			fn->file_attributes = FILE_ATTR_SYSTEM;
1704 	} else
1705 		fn->file_attributes |= ni->flags & FILE_ATTR_COMPRESSED;
1706 	fn->file_attributes |= FILE_ATTR_ARCHIVE;
1707 	fn->file_attributes |= ni->flags & FILE_ATTR_HIDDEN;
1708 	fn->creation_time = ni->creation_time;
1709 	fn->last_data_change_time = ni->last_data_change_time;
1710 	fn->last_mft_change_time = ni->last_mft_change_time;
1711 	fn->last_access_time = ni->last_access_time;
1712 	if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)
1713 		fn->data_size = fn->allocated_size = const_cpu_to_sle64(0);
1714 	else {
1715 		fn->data_size = cpu_to_sle64(ni->data_size);
1716 		fn->allocated_size = cpu_to_sle64(ni->allocated_size);
1717 	}
1718 	memcpy(fn->file_name, name, name_len * sizeof(ntfschar));
1719 	/* Add FILE_NAME attribute to inode. */
1720 	if (ntfs_attr_add(ni, AT_FILE_NAME, AT_UNNAMED, 0, (u8*)fn, fn_len)) {
1721 		err = errno;
1722 		ntfs_log_error("Failed to add FILE_NAME attribute.\n");
1723 		goto err_out;
1724 	}
1725 	/* Add FILE_NAME attribute to index. */
1726 	if (ntfs_index_add_filename(dir_ni, fn, MK_MREF(ni->mft_no,
1727 			le16_to_cpu(ni->mrec->sequence_number)))) {
1728 		err = errno;
1729 		ntfs_log_perror("Failed to add entry to the index");
1730 		goto err_out;
1731 	}
1732 	rollback_dir = 1;
1733 	/* Set hard links count and directory flag. */
1734 	ni->mrec->link_count = const_cpu_to_le16(1);
1735 	if (S_ISDIR(type))
1736 		ni->mrec->flags |= MFT_RECORD_IS_DIRECTORY;
1737 	/* Add reparse data */
1738 	if (special_files == NTFS_FILES_WSL) {
1739 		switch (type) {
1740 		case S_IFLNK :
1741 			err = ntfs_reparse_set_wsl_symlink(ni, target,
1742 					target_len);
1743 			break;
1744 		case S_IFIFO :
1745 		case S_IFSOCK :
1746 		case S_IFCHR :
1747 		case S_IFBLK :
1748 			err = ntfs_reparse_set_wsl_not_symlink(ni,
1749 					type);
1750 			if (!err) {
1751 				err = ntfs_ea_set_wsl_not_symlink(ni,
1752 						type, dev);
1753 				if (err)
1754 					ntfs_remove_ntfs_reparse_data(ni);
1755 			}
1756 			break;
1757 		default :
1758 			err = 0;
1759 			break;
1760 		}
1761 		if (err) {
1762 			err = errno;
1763 			goto err_out;
1764 		}
1765 	}
1766 	ntfs_inode_mark_dirty(ni);
1767 	/* Done! */
1768 	free(fn);
1769 	free(si);
1770 	ntfs_log_trace("Done.\n");
1771 	return ni;
1772 err_out:
1773 	ntfs_log_trace("Failed.\n");
1774 
1775 	if (rollback_dir)
1776 		ntfs_index_remove(dir_ni, ni, fn, fn_len);
1777 
1778 	if (rollback_sd)
1779 		ntfs_attr_remove(ni, AT_SECURITY_DESCRIPTOR, AT_UNNAMED, 0);
1780 
1781 	if (rollback_data)
1782 		ntfs_attr_remove(ni, AT_DATA, AT_UNNAMED, 0);
1783 	/*
1784 	 * Free extent MFT records (should not exist any with current
1785 	 * ntfs_create implementation, but for any case if something will be
1786 	 * changed in the future).
1787 	 */
1788 	while (ni->nr_extents)
1789 		if (ntfs_mft_record_free(ni->vol, *(ni->extent_nis))) {
1790 			err = errno;
1791 			ntfs_log_error("Failed to free extent MFT record.  "
1792 					"Leaving inconsistent metadata.\n");
1793 		}
1794 	if (ntfs_mft_record_free(ni->vol, ni))
1795 		ntfs_log_error("Failed to free MFT record.  "
1796 				"Leaving inconsistent metadata. Run chkdsk.\n");
1797 	free(fn);
1798 	free(si);
1799 	errno = err;
1800 	return NULL;
1801 }
1802 
1803 /**
1804  * Some wrappers around __ntfs_create() ...
1805  */
1806 
ntfs_create(ntfs_inode * dir_ni,le32 securid,const ntfschar * name,u8 name_len,mode_t type)1807 ntfs_inode *ntfs_create(ntfs_inode *dir_ni, le32 securid, const ntfschar *name,
1808 		u8 name_len, mode_t type)
1809 {
1810 	if (type != S_IFREG && type != S_IFDIR && type != S_IFIFO &&
1811 			type != S_IFSOCK) {
1812 		ntfs_log_error("Invalid arguments.\n");
1813 		return NULL;
1814 	}
1815 	return __ntfs_create(dir_ni, securid, name, name_len, type, 0, NULL, 0);
1816 }
1817 
ntfs_create_device(ntfs_inode * dir_ni,le32 securid,const ntfschar * name,u8 name_len,mode_t type,dev_t dev)1818 ntfs_inode *ntfs_create_device(ntfs_inode *dir_ni, le32 securid,
1819 		const ntfschar *name, u8 name_len, mode_t type, dev_t dev)
1820 {
1821 	if (type != S_IFCHR && type != S_IFBLK) {
1822 		ntfs_log_error("Invalid arguments.\n");
1823 		return NULL;
1824 	}
1825 	return __ntfs_create(dir_ni, securid, name, name_len, type, dev, NULL, 0);
1826 }
1827 
ntfs_create_symlink(ntfs_inode * dir_ni,le32 securid,const ntfschar * name,u8 name_len,const ntfschar * target,int target_len)1828 ntfs_inode *ntfs_create_symlink(ntfs_inode *dir_ni, le32 securid,
1829 		const ntfschar *name, u8 name_len, const ntfschar *target,
1830 		int target_len)
1831 {
1832 	if (!target || !target_len) {
1833 		ntfs_log_error("%s: Invalid argument (%p, %d)\n", __FUNCTION__,
1834 			       target, target_len);
1835 		return NULL;
1836 	}
1837 	return __ntfs_create(dir_ni, securid, name, name_len, S_IFLNK, 0,
1838 			target, target_len);
1839 }
1840 
ntfs_check_empty_dir(ntfs_inode * ni)1841 int ntfs_check_empty_dir(ntfs_inode *ni)
1842 {
1843 	ntfs_attr *na;
1844 	int ret = 0;
1845 
1846 	if (!(ni->mrec->flags & MFT_RECORD_IS_DIRECTORY))
1847 		return 0;
1848 
1849 	na = ntfs_attr_open(ni, AT_INDEX_ROOT, NTFS_INDEX_I30, 4);
1850 	if (!na) {
1851 		errno = EIO;
1852 		ntfs_log_perror("Failed to open directory");
1853 		return -1;
1854 	}
1855 
1856 	/* Non-empty directory? */
1857 	if ((na->data_size != sizeof(INDEX_ROOT) + sizeof(INDEX_ENTRY_HEADER))){
1858 		/* Both ENOTEMPTY and EEXIST are ok. We use the more common. */
1859 		errno = ENOTEMPTY;
1860 		ntfs_log_debug("Directory is not empty\n");
1861 		ret = -1;
1862 	}
1863 
1864 	ntfs_attr_close(na);
1865 	return ret;
1866 }
1867 
ntfs_check_unlinkable_dir(ntfs_inode * ni,FILE_NAME_ATTR * fn)1868 static int ntfs_check_unlinkable_dir(ntfs_inode *ni, FILE_NAME_ATTR *fn)
1869 {
1870 	int link_count = le16_to_cpu(ni->mrec->link_count);
1871 	int ret;
1872 
1873 	ret = ntfs_check_empty_dir(ni);
1874 	if (!ret || errno != ENOTEMPTY)
1875 		return ret;
1876 	/*
1877 	 * Directory is non-empty, so we can unlink only if there is more than
1878 	 * one "real" hard link, i.e. links aren't different DOS and WIN32 names
1879 	 */
1880 	if ((link_count == 1) ||
1881 	    (link_count == 2 && fn->file_name_type == FILE_NAME_DOS)) {
1882 		errno = ENOTEMPTY;
1883 		ntfs_log_debug("Non-empty directory without hard links\n");
1884 		goto no_hardlink;
1885 	}
1886 
1887 	ret = 0;
1888 no_hardlink:
1889 	return ret;
1890 }
1891 
1892 /**
1893  * ntfs_delete - delete file or directory from ntfs volume
1894  * @ni:		ntfs inode for object to delte
1895  * @dir_ni:	ntfs inode for directory in which delete object
1896  * @name:	unicode name of the object to delete
1897  * @name_len:	length of the name in unicode characters
1898  *
1899  * @ni is always closed after the call to this function (even if it failed),
1900  * user does not need to call ntfs_inode_close himself.
1901  *
1902  * Return 0 on success or -1 on error with errno set to the error code.
1903  */
ntfs_delete(ntfs_volume * vol,const char * pathname,ntfs_inode * ni,ntfs_inode * dir_ni,const ntfschar * name,u8 name_len)1904 int ntfs_delete(ntfs_volume *vol, const char *pathname,
1905 		ntfs_inode *ni, ntfs_inode *dir_ni, const ntfschar *name,
1906 		u8 name_len)
1907 {
1908 	ntfs_attr_search_ctx *actx = NULL;
1909 	FILE_NAME_ATTR *fn = NULL;
1910 	BOOL looking_for_dos_name = FALSE, looking_for_win32_name = FALSE;
1911 	BOOL case_sensitive_match = TRUE;
1912 	int err = 0;
1913 #if CACHE_NIDATA_SIZE
1914 	int i;
1915 #endif
1916 #if CACHE_INODE_SIZE
1917 	struct CACHED_INODE item;
1918 	const char *p;
1919 	u64 inum = (u64)-1;
1920 	int count;
1921 #endif
1922 #if CACHE_LOOKUP_SIZE
1923 	struct CACHED_LOOKUP lkitem;
1924 #endif
1925 
1926 	ntfs_log_trace("Entering.\n");
1927 
1928 	if (!ni || !dir_ni || !name || !name_len) {
1929 		ntfs_log_error("Invalid arguments.\n");
1930 		errno = EINVAL;
1931 		goto err_out;
1932 	}
1933 	if (ni->nr_extents == -1)
1934 		ni = ni->base_ni;
1935 	if (dir_ni->nr_extents == -1)
1936 		dir_ni = dir_ni->base_ni;
1937 	/*
1938 	 * Search for FILE_NAME attribute with such name. If it's in POSIX or
1939 	 * WIN32_AND_DOS namespace, then simply remove it from index and inode.
1940 	 * If filename in DOS or in WIN32 namespace, then remove DOS name first,
1941 	 * only then remove WIN32 name.
1942 	 */
1943 	actx = ntfs_attr_get_search_ctx(ni, NULL);
1944 	if (!actx)
1945 		goto err_out;
1946 search:
1947 	while (!(err = ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0,
1948 					CASE_SENSITIVE, 0, NULL, 0, actx))) {
1949 	#ifdef DEBUG
1950 		char *s;
1951 	#endif
1952 		IGNORE_CASE_BOOL case_sensitive = IGNORE_CASE;
1953 
1954 		fn = (FILE_NAME_ATTR*)((u8*)actx->attr +
1955 				le16_to_cpu(actx->attr->value_offset));
1956 	#ifdef DEBUG
1957 		s = ntfs_attr_name_get(fn->file_name, fn->file_name_length);
1958 		ntfs_log_trace("name: '%s'  type: %d  dos: %d  win32: %d  "
1959 			       "case: %d\n", s, fn->file_name_type,
1960 			       looking_for_dos_name, looking_for_win32_name,
1961 			       case_sensitive_match);
1962 		ntfs_attr_name_free(&s);
1963 	#endif
1964 		if (looking_for_dos_name) {
1965 			if (fn->file_name_type == FILE_NAME_DOS)
1966 				break;
1967 			else
1968 				continue;
1969 		}
1970 		if (looking_for_win32_name) {
1971 			if  (fn->file_name_type == FILE_NAME_WIN32)
1972 				break;
1973 			else
1974 				continue;
1975 		}
1976 
1977 		/* Ignore hard links from other directories */
1978 		if (dir_ni->mft_no != MREF_LE(fn->parent_directory)) {
1979 			ntfs_log_debug("MFT record numbers don't match "
1980 				       "(%llu != %llu)\n",
1981 				       (long long unsigned)dir_ni->mft_no,
1982 				       (long long unsigned)MREF_LE(fn->parent_directory));
1983 			continue;
1984 		}
1985 		if (case_sensitive_match
1986 		    || ((fn->file_name_type == FILE_NAME_POSIX)
1987 			&& NVolCaseSensitive(ni->vol)))
1988 			case_sensitive = CASE_SENSITIVE;
1989 
1990 		if (ntfs_names_are_equal(fn->file_name, fn->file_name_length,
1991 					 name, name_len, case_sensitive,
1992 					 ni->vol->upcase, ni->vol->upcase_len)){
1993 
1994 			if (fn->file_name_type == FILE_NAME_WIN32) {
1995 				looking_for_dos_name = TRUE;
1996 				ntfs_attr_reinit_search_ctx(actx);
1997 				continue;
1998 			}
1999 			if (fn->file_name_type == FILE_NAME_DOS)
2000 				looking_for_dos_name = TRUE;
2001 			break;
2002 		}
2003 	}
2004 	if (err) {
2005 		/*
2006 		 * If case sensitive search failed, then try once again
2007 		 * ignoring case.
2008 		 */
2009 		if (errno == ENOENT && case_sensitive_match) {
2010 			case_sensitive_match = FALSE;
2011 			ntfs_attr_reinit_search_ctx(actx);
2012 			goto search;
2013 		}
2014 		goto err_out;
2015 	}
2016 
2017 	if (ntfs_check_unlinkable_dir(ni, fn) < 0)
2018 		goto err_out;
2019 
2020 	if (ntfs_index_remove(dir_ni, ni, fn, le32_to_cpu(actx->attr->value_length)))
2021 		goto err_out;
2022 
2023 	/*
2024 	 * Keep the last name in place, this is useful for undeletion
2025 	 * (Windows also does so), however delete the name if it were
2026 	 * in an extent, to avoid leaving an attribute list.
2027 	 */
2028 	if ((ni->mrec->link_count == const_cpu_to_le16(1)) && !actx->base_ntfs_ino) {
2029 			/* make sure to not loop to another search */
2030 		looking_for_dos_name = FALSE;
2031 	} else {
2032 		if (ntfs_attr_record_rm(actx))
2033 			goto err_out;
2034 	}
2035 
2036 	ni->mrec->link_count = cpu_to_le16(le16_to_cpu(
2037 			ni->mrec->link_count) - 1);
2038 
2039 	ntfs_inode_mark_dirty(ni);
2040 	if (looking_for_dos_name) {
2041 		looking_for_dos_name = FALSE;
2042 		looking_for_win32_name = TRUE;
2043 		ntfs_attr_reinit_search_ctx(actx);
2044 		goto search;
2045 	}
2046 	/* TODO: Update object id, quota and securiry indexes if required. */
2047 	/*
2048 	 * If hard link count is not equal to zero then we are done. In other
2049 	 * case there are no reference to this inode left, so we should free all
2050 	 * non-resident attributes and mark all MFT record as not in use.
2051 	 */
2052 #if CACHE_LOOKUP_SIZE
2053 			/* invalidate entry in lookup cache */
2054 	lkitem.name = (const char*)NULL;
2055 	lkitem.namesize = 0;
2056 	lkitem.inum = ni->mft_no;
2057 	lkitem.parent = dir_ni->mft_no;
2058 	ntfs_invalidate_cache(vol->lookup_cache, GENERIC(&lkitem),
2059 			lookup_cache_inv_compare, CACHE_NOHASH);
2060 #endif
2061 #if CACHE_INODE_SIZE
2062 	inum = ni->mft_no;
2063 	if (pathname) {
2064 			/* invalide cache entry, even if there was an error */
2065 		/* Remove leading /'s. */
2066 		p = pathname;
2067 		while (*p == PATH_SEP)
2068 			p++;
2069 		if (p[0] && (p[strlen(p)-1] == PATH_SEP))
2070 			ntfs_log_error("Unnormalized path %s\n",pathname);
2071 		item.pathname = p;
2072 		item.varsize = strlen(p);
2073 	} else {
2074 		item.pathname = (const char*)NULL;
2075 		item.varsize = 0;
2076 	}
2077 	item.inum = inum;
2078 	count = ntfs_invalidate_cache(vol->xinode_cache, GENERIC(&item),
2079 				inode_cache_inv_compare, CACHE_NOHASH);
2080 	if (pathname && !count)
2081 		ntfs_log_error("Could not delete inode cache entry for %s\n",
2082 			pathname);
2083 #endif
2084 	if (ni->mrec->link_count) {
2085 		ntfs_inode_update_times(ni, NTFS_UPDATE_CTIME);
2086 		goto ok;
2087 	}
2088 	if (ntfs_delete_reparse_index(ni)) {
2089 		/*
2090 		 * Failed to remove the reparse index : proceed anyway
2091 		 * This is not a critical error, the entry is useless
2092 		 * because of sequence_number, and stopping file deletion
2093 		 * would be much worse as the file is not referenced now.
2094 		 */
2095 		err = errno;
2096 	}
2097 	if (ntfs_delete_object_id_index(ni)) {
2098 		/*
2099 		 * Failed to remove the object id index : proceed anyway
2100 		 * This is not a critical error.
2101 		 */
2102 		err = errno;
2103 	}
2104 	ntfs_attr_reinit_search_ctx(actx);
2105 	while (!ntfs_attrs_walk(actx)) {
2106 		if (actx->attr->non_resident) {
2107 			runlist *rl;
2108 
2109 			rl = ntfs_mapping_pairs_decompress(ni->vol, actx->attr,
2110 					NULL);
2111 			if (!rl) {
2112 				err = errno;
2113 				ntfs_log_error("Failed to decompress runlist.  "
2114 						"Leaving inconsistent metadata.\n");
2115 				continue;
2116 			}
2117 			if (ntfs_cluster_free_from_rl(ni->vol, rl)) {
2118 				err = errno;
2119 				ntfs_log_error("Failed to free clusters.  "
2120 						"Leaving inconsistent metadata.\n");
2121 				continue;
2122 			}
2123 			free(rl);
2124 		}
2125 	}
2126 	if (errno != ENOENT) {
2127 		err = errno;
2128 		ntfs_log_error("Attribute enumeration failed.  "
2129 				"Probably leaving inconsistent metadata.\n");
2130 	}
2131 	/* All extents should be attached after attribute walk. */
2132 #if CACHE_NIDATA_SIZE
2133 		/*
2134 		 * Disconnect extents before deleting them, so they are
2135 		 * not wrongly moved to cache through the chainings
2136 		 */
2137 	for (i=ni->nr_extents-1; i>=0; i--) {
2138 		ni->extent_nis[i]->base_ni = (ntfs_inode*)NULL;
2139 		ni->extent_nis[i]->nr_extents = 0;
2140 		if (ntfs_mft_record_free(ni->vol, ni->extent_nis[i])) {
2141 			err = errno;
2142 			ntfs_log_error("Failed to free extent MFT record.  "
2143 					"Leaving inconsistent metadata.\n");
2144 		}
2145 	}
2146 	free(ni->extent_nis);
2147 	ni->nr_extents = 0;
2148 	ni->extent_nis = (ntfs_inode**)NULL;
2149 #else
2150 	while (ni->nr_extents)
2151 		if (ntfs_mft_record_free(ni->vol, *(ni->extent_nis))) {
2152 			err = errno;
2153 			ntfs_log_error("Failed to free extent MFT record.  "
2154 					"Leaving inconsistent metadata.\n");
2155 		}
2156 #endif
2157 	debug_double_inode(ni->mft_no,0);
2158 	if (ntfs_mft_record_free(ni->vol, ni)) {
2159 		err = errno;
2160 		ntfs_log_error("Failed to free base MFT record.  "
2161 				"Leaving inconsistent metadata.\n");
2162 	}
2163 	ni = NULL;
2164 ok:
2165 	ntfs_inode_update_times(dir_ni, NTFS_UPDATE_MCTIME);
2166 out:
2167 	if (actx)
2168 		ntfs_attr_put_search_ctx(actx);
2169 	if (ntfs_inode_close(dir_ni) && !err)
2170 		err = errno;
2171 	if (ntfs_inode_close(ni) && !err)
2172 		err = errno;
2173 	if (err) {
2174 		errno = err;
2175 		ntfs_log_debug("Could not delete file: %s\n", strerror(errno));
2176 		return -1;
2177 	}
2178 	ntfs_log_trace("Done.\n");
2179 	return 0;
2180 err_out:
2181 	err = errno;
2182 	goto out;
2183 }
2184 
2185 /**
2186  * ntfs_link - create hard link for file or directory
2187  * @ni:		ntfs inode for object to create hard link
2188  * @dir_ni:	ntfs inode for directory in which new link should be placed
2189  * @name:	unicode name of the new link
2190  * @name_len:	length of the name in unicode characters
2191  *
2192  * NOTE: At present we allow creating hardlinks to directories, we use them
2193  * in a temporary state during rename. But it's defenitely bad idea to have
2194  * hard links to directories as a result of operation.
2195  * FIXME: Create internal  __ntfs_link that allows hard links to a directories
2196  * and external ntfs_link that do not. Write ntfs_rename that uses __ntfs_link.
2197  *
2198  * Return 0 on success or -1 on error with errno set to the error code.
2199  */
ntfs_link_i(ntfs_inode * ni,ntfs_inode * dir_ni,const ntfschar * name,u8 name_len,FILE_NAME_TYPE_FLAGS nametype)2200 static int ntfs_link_i(ntfs_inode *ni, ntfs_inode *dir_ni, const ntfschar *name,
2201 			 u8 name_len, FILE_NAME_TYPE_FLAGS nametype)
2202 {
2203 	FILE_NAME_ATTR *fn = NULL;
2204 	int fn_len, err;
2205 
2206 	ntfs_log_trace("Entering.\n");
2207 
2208 	if (!ni || !dir_ni || !name || !name_len ||
2209 			ni->mft_no == dir_ni->mft_no) {
2210 		err = EINVAL;
2211 		ntfs_log_perror("ntfs_link wrong arguments");
2212 		goto err_out;
2213 	}
2214 
2215 	if (NVolHideDotFiles(dir_ni->vol)) {
2216 		/* Set hidden flag according to the latest name */
2217 		if ((name_len > 1)
2218 		    && (name[0] == const_cpu_to_le16('.'))
2219 		    && (name[1] != const_cpu_to_le16('.')))
2220 			ni->flags |= FILE_ATTR_HIDDEN;
2221 		else
2222 			ni->flags &= ~FILE_ATTR_HIDDEN;
2223 	}
2224 
2225 	/* Create FILE_NAME attribute. */
2226 	fn_len = sizeof(FILE_NAME_ATTR) + name_len * sizeof(ntfschar);
2227 	fn = ntfs_calloc(fn_len);
2228 	if (!fn) {
2229 		err = errno;
2230 		goto err_out;
2231 	}
2232 	fn->parent_directory = MK_LE_MREF(dir_ni->mft_no,
2233 			le16_to_cpu(dir_ni->mrec->sequence_number));
2234 	fn->file_name_length = name_len;
2235 	fn->file_name_type = nametype;
2236 	fn->file_attributes = ni->flags;
2237 	if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) {
2238 		fn->file_attributes |= FILE_ATTR_I30_INDEX_PRESENT;
2239 		fn->data_size = fn->allocated_size = const_cpu_to_sle64(0);
2240 	} else {
2241 		fn->allocated_size = cpu_to_sle64(ni->allocated_size);
2242 		fn->data_size = cpu_to_sle64(ni->data_size);
2243 	}
2244 	fn->creation_time = ni->creation_time;
2245 	fn->last_data_change_time = ni->last_data_change_time;
2246 	fn->last_mft_change_time = ni->last_mft_change_time;
2247 	fn->last_access_time = ni->last_access_time;
2248 	memcpy(fn->file_name, name, name_len * sizeof(ntfschar));
2249 	/* Add FILE_NAME attribute to index. */
2250 	if (ntfs_index_add_filename(dir_ni, fn, MK_MREF(ni->mft_no,
2251 			le16_to_cpu(ni->mrec->sequence_number)))) {
2252 		err = errno;
2253 		ntfs_log_perror("Failed to add filename to the index");
2254 		goto err_out;
2255 	}
2256 	/* Add FILE_NAME attribute to inode. */
2257 	if (ntfs_attr_add(ni, AT_FILE_NAME, AT_UNNAMED, 0, (u8*)fn, fn_len)) {
2258 		ntfs_log_error("Failed to add FILE_NAME attribute.\n");
2259 		err = errno;
2260 		/* Try to remove just added attribute from index. */
2261 		if (ntfs_index_remove(dir_ni, ni, fn, fn_len))
2262 			goto rollback_failed;
2263 		goto err_out;
2264 	}
2265 	/* Increment hard links count. */
2266 	ni->mrec->link_count = cpu_to_le16(le16_to_cpu(
2267 			ni->mrec->link_count) + 1);
2268 	/* Done! */
2269 	ntfs_inode_mark_dirty(ni);
2270 	free(fn);
2271 	ntfs_log_trace("Done.\n");
2272 	return 0;
2273 rollback_failed:
2274 	ntfs_log_error("Rollback failed. Leaving inconsistent metadata.\n");
2275 err_out:
2276 	free(fn);
2277 	errno = err;
2278 	return -1;
2279 }
2280 
ntfs_link(ntfs_inode * ni,ntfs_inode * dir_ni,const ntfschar * name,u8 name_len)2281 int ntfs_link(ntfs_inode *ni, ntfs_inode *dir_ni, const ntfschar *name,
2282 		u8 name_len)
2283 {
2284 	return (ntfs_link_i(ni, dir_ni, name, name_len, FILE_NAME_POSIX));
2285 }
2286 
2287 /*
2288  *		Get a parent directory from an inode entry
2289  *
2290  *	This is only used in situations where the path used to access
2291  *	the current file is not known for sure. The result may be different
2292  *	from the path when the file is linked in several parent directories.
2293  *
2294  *	Currently this is only used for translating ".." in the target
2295  *	of a Vista relative symbolic link
2296  */
2297 
ntfs_dir_parent_inode(ntfs_inode * ni)2298 ntfs_inode *ntfs_dir_parent_inode(ntfs_inode *ni)
2299 {
2300 	ntfs_inode *dir_ni = (ntfs_inode*)NULL;
2301 	u64 inum;
2302 	FILE_NAME_ATTR *fn;
2303 	ntfs_attr_search_ctx *ctx;
2304 
2305 	if (ni->mft_no != FILE_root) {
2306 			/* find the name in the attributes */
2307 		ctx = ntfs_attr_get_search_ctx(ni, NULL);
2308 		if (!ctx)
2309 			return ((ntfs_inode*)NULL);
2310 
2311 		if (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0,
2312 				CASE_SENSITIVE,	0, NULL, 0, ctx)) {
2313 			/* We know this will always be resident. */
2314 			fn = (FILE_NAME_ATTR*)((u8*)ctx->attr +
2315 					le16_to_cpu(ctx->attr->value_offset));
2316 			inum = le64_to_cpu(fn->parent_directory);
2317 			if (inum != (u64)-1) {
2318 				dir_ni = ntfs_inode_open(ni->vol, MREF(inum));
2319 			}
2320 		}
2321 		ntfs_attr_put_search_ctx(ctx);
2322 	}
2323 	return (dir_ni);
2324 }
2325 
2326 #define MAX_DOS_NAME_LENGTH	 12
2327 
2328 /*
2329  *		Get a DOS name for a file in designated directory
2330  *
2331  *	Not allowed if there are several non-dos names (EMLINK)
2332  *
2333  *	Returns size if found
2334  *		0 if not found
2335  *		-1 if there was an error (described by errno)
2336  */
2337 
get_dos_name(ntfs_inode * ni,u64 dnum,ntfschar * dosname)2338 static int get_dos_name(ntfs_inode *ni, u64 dnum, ntfschar *dosname)
2339 {
2340 	size_t outsize = 0;
2341 	int namecount = 0;
2342 	FILE_NAME_ATTR *fn;
2343 	ntfs_attr_search_ctx *ctx;
2344 
2345 		/* find the name in the attributes */
2346 	ctx = ntfs_attr_get_search_ctx(ni, NULL);
2347 	if (!ctx)
2348 		return -1;
2349 
2350 	while (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, CASE_SENSITIVE,
2351 			0, NULL, 0, ctx)) {
2352 		/* We know this will always be resident. */
2353 		fn = (FILE_NAME_ATTR*)((u8*)ctx->attr +
2354 				le16_to_cpu(ctx->attr->value_offset));
2355 
2356 		if (fn->file_name_type != FILE_NAME_DOS)
2357 			namecount++;
2358 		if ((fn->file_name_type & FILE_NAME_DOS)
2359 		    && (MREF_LE(fn->parent_directory) == dnum)) {
2360 				/*
2361 				 * Found a DOS or WIN32+DOS name for the entry
2362 				 * copy name, after truncation for safety
2363 				 */
2364 			outsize = fn->file_name_length;
2365 /* TODO : reject if name is too long ? */
2366 			if (outsize > MAX_DOS_NAME_LENGTH)
2367 				outsize = MAX_DOS_NAME_LENGTH;
2368 			memcpy(dosname,fn->file_name,outsize*sizeof(ntfschar));
2369 		}
2370 	}
2371 	ntfs_attr_put_search_ctx(ctx);
2372 	if ((outsize > 0) && (namecount > 1)) {
2373 		outsize = -1;
2374 		errno = EMLINK; /* this error implies there is a dos name */
2375 	}
2376 	return (outsize);
2377 }
2378 
2379 
2380 /*
2381  *		Get a long name for a file in designated directory
2382  *
2383  *	Not allowed if there are several non-dos names (EMLINK)
2384  *
2385  *	Returns size if found
2386  *		0 if not found
2387  *		-1 if there was an error (described by errno)
2388  */
2389 
get_long_name(ntfs_inode * ni,u64 dnum,ntfschar * longname)2390 static int get_long_name(ntfs_inode *ni, u64 dnum, ntfschar *longname)
2391 {
2392 	size_t outsize = 0;
2393 	int namecount = 0;
2394 	FILE_NAME_ATTR *fn;
2395 	ntfs_attr_search_ctx *ctx;
2396 
2397 		/* find the name in the attributes */
2398 	ctx = ntfs_attr_get_search_ctx(ni, NULL);
2399 	if (!ctx)
2400 		return -1;
2401 
2402 		/* first search for WIN32 or DOS+WIN32 names */
2403 	while (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, CASE_SENSITIVE,
2404 			0, NULL, 0, ctx)) {
2405 		/* We know this will always be resident. */
2406 		fn = (FILE_NAME_ATTR*)((u8*)ctx->attr +
2407 				le16_to_cpu(ctx->attr->value_offset));
2408 
2409 		if (fn->file_name_type != FILE_NAME_DOS)
2410 			namecount++;
2411 		if ((fn->file_name_type & FILE_NAME_WIN32)
2412 		    && (MREF_LE(fn->parent_directory) == dnum)) {
2413 				/*
2414 				 * Found a WIN32 or WIN32+DOS name for the entry
2415 				 * copy name
2416 				 */
2417 			outsize = fn->file_name_length;
2418 			memcpy(longname,fn->file_name,outsize*sizeof(ntfschar));
2419 		}
2420 	}
2421 	if (namecount > 1) {
2422 		ntfs_attr_put_search_ctx(ctx);
2423 		errno = EMLINK;
2424 		return -1;
2425 	}
2426 		/* if not found search for POSIX names */
2427 	if (!outsize) {
2428 		ntfs_attr_reinit_search_ctx(ctx);
2429 	while (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, CASE_SENSITIVE,
2430 			0, NULL, 0, ctx)) {
2431 		/* We know this will always be resident. */
2432 		fn = (FILE_NAME_ATTR*)((u8*)ctx->attr +
2433 				le16_to_cpu(ctx->attr->value_offset));
2434 
2435 		if ((fn->file_name_type == FILE_NAME_POSIX)
2436 		    && (MREF_LE(fn->parent_directory) == dnum)) {
2437 				/*
2438 				 * Found a POSIX name for the entry
2439 				 * copy name
2440 				 */
2441 			outsize = fn->file_name_length;
2442 			memcpy(longname,fn->file_name,outsize*sizeof(ntfschar));
2443 		}
2444 	}
2445 	}
2446 	ntfs_attr_put_search_ctx(ctx);
2447 	return (outsize);
2448 }
2449 
2450 
2451 /*
2452  *		Get the ntfs DOS name into an extended attribute
2453  */
2454 
ntfs_get_ntfs_dos_name(ntfs_inode * ni,ntfs_inode * dir_ni,char * value,size_t size)2455 int ntfs_get_ntfs_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni,
2456 			char *value, size_t size)
2457 {
2458 	int outsize = 0;
2459 	char *outname = (char*)NULL;
2460 	u64 dnum;
2461 	int doslen;
2462 	ntfschar dosname[MAX_DOS_NAME_LENGTH];
2463 
2464 	dnum = dir_ni->mft_no;
2465 	doslen = get_dos_name(ni, dnum, dosname);
2466 	if (doslen > 0) {
2467 			/*
2468 			 * Found a DOS name for the entry, make
2469 			 * uppercase and encode into the buffer
2470 			 * if there is enough space
2471 			 */
2472 		ntfs_name_upcase(dosname, doslen,
2473 				ni->vol->upcase, ni->vol->upcase_len);
2474 		outsize = ntfs_ucstombs(dosname, doslen, &outname, 0);
2475 		if (outsize < 0) {
2476 			ntfs_log_error("Cannot represent dosname in current locale.\n");
2477 			outsize = -errno;
2478 		} else {
2479 			if (value && (outsize <= (int)size))
2480 				memcpy(value, outname, outsize);
2481 			else
2482 				if (size && (outsize > (int)size))
2483 					outsize = -ERANGE;
2484 			free(outname);
2485 		}
2486 	} else {
2487 		if (doslen == 0)
2488 			errno = ENODATA;
2489 		outsize = -errno;
2490 	}
2491 	return (outsize);
2492 }
2493 
2494 /*
2495  *		Change the name space of an existing file or directory
2496  *
2497  *	Returns the old namespace if successful
2498  *		-1 if an error occurred (described by errno)
2499  */
2500 
set_namespace(ntfs_inode * ni,ntfs_inode * dir_ni,const ntfschar * name,int len,FILE_NAME_TYPE_FLAGS nametype)2501 static int set_namespace(ntfs_inode *ni, ntfs_inode *dir_ni,
2502 			const ntfschar *name, int len,
2503 			FILE_NAME_TYPE_FLAGS nametype)
2504 {
2505 	ntfs_attr_search_ctx *actx;
2506 	ntfs_index_context *icx;
2507 	FILE_NAME_ATTR *fnx;
2508 	FILE_NAME_ATTR *fn = NULL;
2509 	BOOL found;
2510 	int lkup;
2511 	int ret;
2512 
2513 	ret = -1;
2514 	actx = ntfs_attr_get_search_ctx(ni, NULL);
2515 	if (actx) {
2516 		found = FALSE;
2517 		do {
2518 			lkup = ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0,
2519 	                        CASE_SENSITIVE, 0, NULL, 0, actx);
2520 			if (!lkup) {
2521 				fn = (FILE_NAME_ATTR*)((u8*)actx->attr +
2522 				     le16_to_cpu(actx->attr->value_offset));
2523 				found = (MREF_LE(fn->parent_directory)
2524 						== dir_ni->mft_no)
2525 					&& !memcmp(fn->file_name, name,
2526 						len*sizeof(ntfschar));
2527 			}
2528 		} while (!lkup && !found);
2529 		if (found) {
2530 			icx = ntfs_index_ctx_get(dir_ni, NTFS_INDEX_I30, 4);
2531 			if (icx) {
2532 				lkup = ntfs_index_lookup((char*)fn, len, icx);
2533 				if (!lkup && icx->data && icx->data_len) {
2534 					fnx = (FILE_NAME_ATTR*)icx->data;
2535 					ret = fn->file_name_type;
2536 					fn->file_name_type = nametype;
2537 					fnx->file_name_type = nametype;
2538 					ntfs_inode_mark_dirty(ni);
2539 					ntfs_index_entry_mark_dirty(icx);
2540 				}
2541 			ntfs_index_ctx_put(icx);
2542 			}
2543 		}
2544 		ntfs_attr_put_search_ctx(actx);
2545 	}
2546 	return (ret);
2547 }
2548 
2549 /*
2550  *		Set a DOS name to a file and adjust name spaces
2551  *
2552  *	If the new names are collapsible (same uppercased chars) :
2553  *
2554  * - the existing DOS name or DOS+Win32 name is made Posix
2555  * - if it was a real DOS name, the existing long name is made DOS+Win32
2556  *        and the existing DOS name is deleted
2557  * - finally the existing long name is made DOS+Win32 unless already done
2558  *
2559  *	If the new names are not collapsible :
2560  *
2561  * - insert the short name as a DOS name
2562  * - delete the old long name or existing short name
2563  * - insert the new long name (as a Win32 or DOS+Win32 name)
2564  *
2565  * Deleting the old long name will not delete the file
2566  * provided the old name was in the Posix name space,
2567  * because the alternate name has been set before.
2568  *
2569  * The inodes of file and parent directory are always closed
2570  *
2571  * Returns 0 if successful
2572  *	   -1 if failed
2573  */
2574 
set_dos_name(ntfs_inode * ni,ntfs_inode * dir_ni,const ntfschar * shortname,int shortlen,const ntfschar * longname,int longlen,const ntfschar * deletename,int deletelen,BOOL existed)2575 static int set_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni,
2576 			const ntfschar *shortname, int shortlen,
2577 			const ntfschar *longname, int longlen,
2578 			const ntfschar *deletename, int deletelen, BOOL existed)
2579 {
2580 	unsigned int linkcount;
2581 	ntfs_volume *vol;
2582 	BOOL collapsible;
2583 	BOOL deleted;
2584 	BOOL done;
2585 	FILE_NAME_TYPE_FLAGS oldnametype;
2586 	u64 dnum;
2587 	u64 fnum;
2588 	int res;
2589 
2590 	res = -1;
2591 	vol = ni->vol;
2592 	dnum = dir_ni->mft_no;
2593 	fnum = ni->mft_no;
2594 				/* save initial link count */
2595 	linkcount = le16_to_cpu(ni->mrec->link_count);
2596 
2597 		/* check whether the same name may be used as DOS and WIN32 */
2598 	collapsible = ntfs_collapsible_chars(ni->vol, shortname, shortlen,
2599 						longname, longlen);
2600 	if (collapsible) {
2601 		deleted = FALSE;
2602 		done = FALSE;
2603 		if (existed) {
2604 			oldnametype = set_namespace(ni, dir_ni, deletename,
2605 					deletelen, FILE_NAME_POSIX);
2606 			if (oldnametype == FILE_NAME_DOS) {
2607 				if (set_namespace(ni, dir_ni, longname, longlen,
2608 						FILE_NAME_WIN32_AND_DOS) >= 0) {
2609 					if (!ntfs_delete(vol,
2610 						(const char*)NULL, ni, dir_ni,
2611 						deletename, deletelen))
2612 						res = 0;
2613 					deleted = TRUE;
2614 				} else
2615 					done = TRUE;
2616 			}
2617 		}
2618 		if (!deleted) {
2619 			if (!done && (set_namespace(ni, dir_ni,
2620 					longname, longlen,
2621 					FILE_NAME_WIN32_AND_DOS) >= 0))
2622 				res = 0;
2623 			ntfs_inode_update_times(ni, NTFS_UPDATE_CTIME);
2624 			ntfs_inode_update_times(dir_ni, NTFS_UPDATE_MCTIME);
2625 			if (ntfs_inode_close_in_dir(ni,dir_ni) && !res)
2626 				res = -1;
2627 			if (ntfs_inode_close(dir_ni) && !res)
2628 				res = -1;
2629 		}
2630 	} else {
2631 		if (!ntfs_link_i(ni, dir_ni, shortname, shortlen,
2632 				FILE_NAME_DOS)
2633 			/* make sure a new link was recorded */
2634 		    && (le16_to_cpu(ni->mrec->link_count) > linkcount)) {
2635 			/* delete the existing long name or short name */
2636 // is it ok to not provide the path ?
2637 			if (!ntfs_delete(vol, (char*)NULL, ni, dir_ni,
2638 				 deletename, deletelen)) {
2639 			/* delete closes the inodes, so have to open again */
2640 				dir_ni = ntfs_inode_open(vol, dnum);
2641 				if (dir_ni) {
2642 					ni = ntfs_inode_open(vol, fnum);
2643 					if (ni) {
2644 						if (!ntfs_link_i(ni, dir_ni,
2645 							longname, longlen,
2646 							FILE_NAME_WIN32))
2647 							res = 0;
2648 						if (ntfs_inode_close_in_dir(ni,
2649 							dir_ni)
2650 						    && !res)
2651 							res = -1;
2652 					}
2653 				if (ntfs_inode_close(dir_ni) && !res)
2654 					res = -1;
2655 				}
2656 			}
2657 		} else {
2658 			ntfs_inode_close_in_dir(ni,dir_ni);
2659 			ntfs_inode_close(dir_ni);
2660 		}
2661 	}
2662 	return (res);
2663 }
2664 
2665 
2666 /*
2667  *		Set the ntfs DOS name into an extended attribute
2668  *
2669  *  The DOS name will be added as another file name attribute
2670  *  using the existing file name information from the original
2671  *  name or overwriting the DOS Name if one exists.
2672  *
2673  *  	The inode of the file is always closed
2674  */
2675 
ntfs_set_ntfs_dos_name(ntfs_inode * ni,ntfs_inode * dir_ni,const char * value,size_t size,int flags)2676 int ntfs_set_ntfs_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni,
2677 			const char *value, size_t size,	int flags)
2678 {
2679 	int res = 0;
2680 	int longlen = 0;
2681 	int shortlen = 0;
2682 	char newname[3*MAX_DOS_NAME_LENGTH + 1];
2683 	ntfschar oldname[MAX_DOS_NAME_LENGTH];
2684 	int oldlen;
2685 	u64 dnum;
2686 	BOOL closed = FALSE;
2687 	ntfschar *shortname = NULL;
2688 	ntfschar longname[NTFS_MAX_NAME_LEN];
2689 
2690 		/* copy the string to insert a null char, and truncate */
2691 	if (size > 3*MAX_DOS_NAME_LENGTH)
2692 		size = 3*MAX_DOS_NAME_LENGTH;
2693 	strncpy(newname, value, size);
2694 		/* a long name may be truncated badly and be untranslatable */
2695 	newname[size] = 0;
2696 		/* convert the string to the NTFS wide chars, and truncate */
2697 	shortlen = ntfs_mbstoucs(newname, &shortname);
2698 	if (shortlen > MAX_DOS_NAME_LENGTH)
2699 		shortlen = MAX_DOS_NAME_LENGTH;
2700 
2701 	/* Make sure the short name has valid chars.
2702 	 * Note: the short name cannot end with dot or space, but the
2703 	 * corresponding long name can. */
2704 	if ((shortlen < 0)
2705 	    || ntfs_forbidden_names(ni->vol,shortname,shortlen,TRUE)) {
2706 		ntfs_inode_close_in_dir(ni,dir_ni);
2707 		ntfs_inode_close(dir_ni);
2708 		res = -errno;
2709 		return res;
2710 	}
2711 	dnum = dir_ni->mft_no;
2712 	longlen = get_long_name(ni, dnum, longname);
2713 	if (longlen > 0) {
2714 		oldlen = get_dos_name(ni, dnum, oldname);
2715 		if ((oldlen >= 0)
2716 		    && !ntfs_forbidden_names(ni->vol, longname, longlen,
2717 					     FALSE)) {
2718 			if (oldlen > 0) {
2719 				if (flags & XATTR_CREATE) {
2720 					res = -1;
2721 					errno = EEXIST;
2722 				} else
2723 					if ((shortlen == oldlen)
2724 					    && !memcmp(shortname,oldname,
2725 						     oldlen*sizeof(ntfschar)))
2726 						/* already set, done */
2727 						res = 0;
2728 					else {
2729 						res = set_dos_name(ni, dir_ni,
2730 							shortname, shortlen,
2731 							longname, longlen,
2732 							oldname, oldlen, TRUE);
2733 						closed = TRUE;
2734 					}
2735 			} else {
2736 				if (flags & XATTR_REPLACE) {
2737 					res = -1;
2738 					errno = ENODATA;
2739 				} else {
2740 					res = set_dos_name(ni, dir_ni,
2741 						shortname, shortlen,
2742 						longname, longlen,
2743 						longname, longlen, FALSE);
2744 					closed = TRUE;
2745 				}
2746 			}
2747 		} else
2748 			res = -1;
2749 	} else {
2750 		res = -1;
2751 		if (!longlen)
2752 			errno = ENOENT;
2753 	}
2754 	free(shortname);
2755 	if (!closed) {
2756 		ntfs_inode_close_in_dir(ni,dir_ni);
2757 		ntfs_inode_close(dir_ni);
2758 	}
2759 	return (res ? -1 : 0);
2760 }
2761 
2762 /*
2763  *		Delete the ntfs DOS name
2764  */
2765 
ntfs_remove_ntfs_dos_name(ntfs_inode * ni,ntfs_inode * dir_ni)2766 int ntfs_remove_ntfs_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni)
2767 {
2768 	int res;
2769 	int oldnametype;
2770 	int longlen = 0;
2771 	int shortlen;
2772 	u64 dnum;
2773 	ntfs_volume *vol;
2774 	BOOL deleted = FALSE;
2775 	ntfschar shortname[MAX_DOS_NAME_LENGTH];
2776 	ntfschar longname[NTFS_MAX_NAME_LEN];
2777 
2778 	res = -1;
2779 	vol = ni->vol;
2780 	dnum = dir_ni->mft_no;
2781 	longlen = get_long_name(ni, dnum, longname);
2782 	if (longlen > 0) {
2783 		shortlen = get_dos_name(ni, dnum, shortname);
2784 		if (shortlen >= 0) {
2785 				/* migrate the long name as Posix */
2786 			oldnametype = set_namespace(ni,dir_ni,longname,longlen,
2787 					FILE_NAME_POSIX);
2788 			switch (oldnametype) {
2789 			case FILE_NAME_WIN32_AND_DOS :
2790 				/* name was Win32+DOS : done */
2791 				res = 0;
2792 				break;
2793 			case FILE_NAME_DOS :
2794 				/* name was DOS, make it back to DOS */
2795 				set_namespace(ni,dir_ni,longname,longlen,
2796 						FILE_NAME_DOS);
2797 				errno = ENOENT;
2798 				break;
2799 			case FILE_NAME_WIN32 :
2800 				/* name was Win32, make it Posix and delete */
2801 				if (set_namespace(ni,dir_ni,shortname,shortlen,
2802 						FILE_NAME_POSIX) >= 0) {
2803 					if (!ntfs_delete(vol,
2804 							(const char*)NULL, ni,
2805 							dir_ni, shortname,
2806 							shortlen))
2807 						res = 0;
2808 					deleted = TRUE;
2809 				} else {
2810 					/*
2811 					 * DOS name has been found, but cannot
2812 					 * migrate to Posix : something bad
2813 					 * has happened
2814 					 */
2815 					errno = EIO;
2816 					ntfs_log_error("Could not change"
2817 						" DOS name of inode %lld to Posix\n",
2818 						(long long)ni->mft_no);
2819 				}
2820 				break;
2821 			default :
2822 				/* name was Posix or not found : error */
2823 				errno = ENOENT;
2824 				break;
2825 			}
2826 		}
2827 	} else {
2828 		if (!longlen)
2829 			errno = ENOENT;
2830 		res = -1;
2831 	}
2832 	if (!deleted) {
2833 		ntfs_inode_close_in_dir(ni,dir_ni);
2834 		ntfs_inode_close(dir_ni);
2835 	}
2836 	return (res);
2837 }
2838 
2839 /*
2840  *		Increment the count of subdirectories
2841  *		(excluding entries with a short name)
2842  */
2843 
nlink_increment(void * nlink_ptr,const ntfschar * name,const int len,const int type,const s64 pos,const MFT_REF mref,const unsigned int dt_type)2844 static int nlink_increment(void *nlink_ptr,
2845 			const ntfschar *name __attribute__((unused)),
2846 			const int len __attribute__((unused)),
2847 			const int type,
2848 			const s64 pos __attribute__((unused)),
2849 			const MFT_REF mref __attribute__((unused)),
2850 			const unsigned int dt_type)
2851 {
2852 	if ((dt_type == NTFS_DT_DIR) && (type != FILE_NAME_DOS))
2853 		(*((int*)nlink_ptr))++;
2854 	return (0);
2855 }
2856 
2857 /*
2858  *		Compute the number of hard links according to Posix
2859  *	For a directory count the subdirectories whose name is not
2860  *		a short one, but count "." and ".."
2861  *	Otherwise count the names, excluding the short ones.
2862  *
2863  *	if there is an error, a null count is returned.
2864  */
2865 
ntfs_dir_link_cnt(ntfs_inode * ni)2866 int ntfs_dir_link_cnt(ntfs_inode *ni)
2867 {
2868 	ntfs_attr_search_ctx *actx;
2869 	FILE_NAME_ATTR *fn;
2870 	s64 pos;
2871 	int err = 0;
2872 	int nlink = 0;
2873 
2874 	if (!ni) {
2875 		ntfs_log_error("Invalid argument.\n");
2876 		errno = EINVAL;
2877 		goto err_out;
2878 	}
2879 	if (ni->nr_extents == -1)
2880 		ni = ni->base_ni;
2881 	if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) {
2882 		/*
2883 		 * Directory : scan the directory and count
2884 		 * subdirectories whose name is not DOS-only.
2885 		 * The directory names are ignored, but "." and ".."
2886 		 * are taken into account.
2887 		 */
2888 		pos = 0;
2889 		err = ntfs_readdir(ni, &pos, &nlink, nlink_increment);
2890 		if (err)
2891 			nlink = 0;
2892 	} else {
2893 		/*
2894 		 * Non-directory : search for FILE_NAME attributes,
2895 		 * and count those which are not DOS-only ones.
2896 		 */
2897 		actx = ntfs_attr_get_search_ctx(ni, NULL);
2898 		if (!actx)
2899 			goto err_out;
2900 		while (!(err = ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0,
2901 					CASE_SENSITIVE, 0, NULL, 0, actx))) {
2902 			fn = (FILE_NAME_ATTR*)((u8*)actx->attr +
2903 					le16_to_cpu(actx->attr->value_offset));
2904 			if (fn->file_name_type != FILE_NAME_DOS)
2905 				nlink++;
2906 		}
2907 		if (err && (errno != ENOENT))
2908 			nlink = 0;
2909 		ntfs_attr_put_search_ctx(actx);
2910 	}
2911 	if (!nlink)
2912 		ntfs_log_perror("Failed to compute nlink of inode %lld",
2913 			(long long)ni->mft_no);
2914 err_out :
2915 	return (nlink);
2916 }
2917