xref: /haiku/src/add-ons/kernel/file_systems/ntfs/libntfs/volume.c (revision 1c09002cbee8e797a0f8bbfc5678dfadd39ee1a7)
1 /**
2  * volume.c - NTFS volume handling code. Originated from the Linux-NTFS project.
3  *
4  * Copyright (c) 2000-2006 Anton Altaparmakov
5  * Copyright (c) 2002-2009 Szabolcs Szakacsits
6  * Copyright (c) 2004-2005 Richard Russon
7  * Copyright (c) 2010      Jean-Pierre Andre
8  *
9  * This program/include file is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as published
11  * by the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program/include file is distributed in the hope that it will be
15  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
16  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program (in the main directory of the NTFS-3G
21  * distribution in the file COPYING); if not, write to the Free Software
22  * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23  */
24 
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28 
29 #ifdef HAVE_STDLIB_H
30 #include <stdlib.h>
31 #endif
32 #ifdef HAVE_STDIO_H
33 #include <stdio.h>
34 #endif
35 #ifdef HAVE_STRING_H
36 #include <string.h>
37 #endif
38 #ifdef HAVE_FCNTL_H
39 #include <fcntl.h>
40 #endif
41 #ifdef HAVE_UNISTD_H
42 #include <unistd.h>
43 #endif
44 #ifdef HAVE_ERRNO_H
45 #include <errno.h>
46 #endif
47 #ifdef HAVE_SYS_STAT_H
48 #include <sys/stat.h>
49 #endif
50 #ifdef HAVE_LIMITS_H
51 #include <limits.h>
52 #endif
53 #ifdef HAVE_LOCALE_H
54 #include <locale.h>
55 #endif
56 
57 #include "compat.h"
58 #include "volume.h"
59 #include "attrib.h"
60 #include "mft.h"
61 #include "bootsect.h"
62 #include "device.h"
63 #include "debug.h"
64 #include "inode.h"
65 #include "runlist.h"
66 #include "logfile.h"
67 #include "dir.h"
68 #include "logging.h"
69 #include "cache.h"
70 #include "misc.h"
71 
72 const char *ntfs_home =
73 "Ntfs-3g news, support and information:  http://ntfs-3g.org\n";
74 
75 static const char *invalid_ntfs_msg =
76 "The device '%s' doesn't seem to have a valid NTFS.\n"
77 "Maybe the wrong device is used? Or the whole disk instead of a\n"
78 "partition (e.g. /dev/sda, not /dev/sda1)? Or the other way around?\n";
79 
80 static const char *corrupt_volume_msg =
81 "NTFS is either inconsistent, or there is a hardware fault, or it's a\n"
82 "SoftRAID/FakeRAID hardware. In the first case run chkdsk /f on Windows\n"
83 "then reboot into Windows twice. The usage of the /f parameter is very\n"
84 "important! If the device is a SoftRAID/FakeRAID then first activate\n"
85 "it and mount a different device under the /dev/mapper/ directory, (e.g.\n"
86 "/dev/mapper/nvidia_eahaabcc1). Please see the 'dmraid' documentation\n"
87 "for more details.\n";
88 
89 static const char *hibernated_volume_msg =
90 "The NTFS partition is hibernated. Please resume and shutdown Windows\n"
91 "properly, or mount the volume read-only with the 'ro' mount option, or\n"
92 "mount the volume read-write with the 'remove_hiberfile' mount option.\n"
93 "For example type on the command line:\n"
94 "\n"
95 "            mount -t ntfs-3g -o remove_hiberfile %s %s\n"
96 "\n";
97 
98 static const char *unclean_journal_msg =
99 "Write access is denied because the disk wasn't safely powered\n"
100 "off and the 'norecover' mount option was specified.\n";
101 
102 static const char *opened_volume_msg =
103 "Mount is denied because the NTFS volume is already exclusively opened.\n"
104 "The volume may be already mounted, or another software may use it which\n"
105 "could be identified for example by the help of the 'fuser' command.\n";
106 
107 static const char *fakeraid_msg =
108 "Either the device is missing or it's powered down, or you have\n"
109 "SoftRAID hardware and must use an activated, different device under\n"
110 "/dev/mapper/, (e.g. /dev/mapper/nvidia_eahaabcc1) to mount NTFS.\n"
111 "Please see the 'dmraid' documentation for help.\n";
112 
113 static const char *access_denied_msg =
114 "Please check '%s' and the ntfs-3g binary permissions,\n"
115 "and the mounting user ID. More explanation is provided at\n"
116 "http://ntfs-3g.org/support.html#unprivileged\n";
117 
118 /**
119  * ntfs_volume_alloc - Create an NTFS volume object and initialise it
120  *
121  * Description...
122  *
123  * Returns:
124  */
125 ntfs_volume *ntfs_volume_alloc(void)
126 {
127 	return ntfs_calloc(sizeof(ntfs_volume));
128 }
129 
130 static void ntfs_attr_free(ntfs_attr **na)
131 {
132 	if (na && *na) {
133 		ntfs_attr_close(*na);
134 		*na = NULL;
135 	}
136 }
137 
138 static int ntfs_inode_free(ntfs_inode **ni)
139 {
140 	int ret = -1;
141 
142 	if (ni && *ni) {
143 		ret = ntfs_inode_close(*ni);
144 		*ni = NULL;
145 	}
146 
147 	return ret;
148 }
149 
150 static void ntfs_error_set(int *err)
151 {
152 	if (!*err)
153 		*err = errno;
154 }
155 
156 /**
157  * __ntfs_volume_release - Destroy an NTFS volume object
158  * @v:
159  *
160  * Description...
161  *
162  * Returns:
163  */
164 static int __ntfs_volume_release(ntfs_volume *v)
165 {
166 	int err = 0;
167 
168 	if (ntfs_inode_free(&v->vol_ni))
169 		ntfs_error_set(&err);
170 	/*
171 	 * FIXME: Inodes must be synced before closing
172 	 * attributes, otherwise unmount could fail.
173 	 */
174 	if (v->lcnbmp_ni && NInoDirty(v->lcnbmp_ni))
175 		ntfs_inode_sync(v->lcnbmp_ni);
176 	ntfs_attr_free(&v->lcnbmp_na);
177 	if (ntfs_inode_free(&v->lcnbmp_ni))
178 		ntfs_error_set(&err);
179 
180 	if (v->mft_ni && NInoDirty(v->mft_ni))
181 		ntfs_inode_sync(v->mft_ni);
182 	ntfs_attr_free(&v->mftbmp_na);
183 	ntfs_attr_free(&v->mft_na);
184 	if (ntfs_inode_free(&v->mft_ni))
185 		ntfs_error_set(&err);
186 
187 	if (v->mftmirr_ni && NInoDirty(v->mftmirr_ni))
188 		ntfs_inode_sync(v->mftmirr_ni);
189 	ntfs_attr_free(&v->mftmirr_na);
190 	if (ntfs_inode_free(&v->mftmirr_ni))
191 		ntfs_error_set(&err);
192 
193 	if (v->dev) {
194 		struct ntfs_device *dev = v->dev;
195 
196 		if (dev->d_ops->sync(dev))
197 			ntfs_error_set(&err);
198 		if (dev->d_ops->close(dev))
199 			ntfs_error_set(&err);
200 	}
201 
202 	ntfs_free_lru_caches(v);
203 	free(v->vol_name);
204 	free(v->upcase);
205 	if (v->locase) free(v->locase);
206 	free(v->attrdef);
207 	free(v);
208 
209 	errno = err;
210 	return errno ? -1 : 0;
211 }
212 
213 static void ntfs_attr_setup_flag(ntfs_inode *ni)
214 {
215 	STANDARD_INFORMATION *si;
216 
217 	si = ntfs_attr_readall(ni, AT_STANDARD_INFORMATION, AT_UNNAMED, 0, NULL);
218 	if (si) {
219 		ni->flags = si->file_attributes;
220 		free(si);
221 	}
222 }
223 
224 /**
225  * ntfs_mft_load - load the $MFT and setup the ntfs volume with it
226  * @vol:	ntfs volume whose $MFT to load
227  *
228  * Load $MFT from @vol and setup @vol with it. After calling this function the
229  * volume @vol is ready for use by all read access functions provided by the
230  * ntfs library.
231  *
232  * Return 0 on success and -1 on error with errno set to the error code.
233  */
234 static int ntfs_mft_load(ntfs_volume *vol)
235 {
236 	VCN next_vcn, last_vcn, highest_vcn;
237 	s64 l;
238 	MFT_RECORD *mb = NULL;
239 	ntfs_attr_search_ctx *ctx = NULL;
240 	ATTR_RECORD *a;
241 	int eo;
242 
243 	/* Manually setup an ntfs_inode. */
244 	vol->mft_ni = ntfs_inode_allocate(vol);
245 	mb = ntfs_malloc(vol->mft_record_size);
246 	if (!vol->mft_ni || !mb) {
247 		ntfs_log_perror("Error allocating memory for $MFT");
248 		goto error_exit;
249 	}
250 	vol->mft_ni->mft_no = 0;
251 	vol->mft_ni->mrec = mb;
252 	/* Can't use any of the higher level functions yet! */
253 	l = ntfs_mst_pread(vol->dev, vol->mft_lcn << vol->cluster_size_bits, 1,
254 			vol->mft_record_size, mb);
255 	if (l != 1) {
256 		if (l != -1)
257 			errno = EIO;
258 		ntfs_log_perror("Error reading $MFT");
259 		goto error_exit;
260 	}
261 
262 	if (ntfs_mft_record_check(vol, 0, mb))
263 		goto error_exit;
264 
265 	ctx = ntfs_attr_get_search_ctx(vol->mft_ni, NULL);
266 	if (!ctx)
267 		goto error_exit;
268 
269 	/* Find the $ATTRIBUTE_LIST attribute in $MFT if present. */
270 	if (ntfs_attr_lookup(AT_ATTRIBUTE_LIST, AT_UNNAMED, 0, 0, 0, NULL, 0,
271 			ctx)) {
272 		if (errno != ENOENT) {
273 			ntfs_log_error("$MFT has corrupt attribute list.\n");
274 			goto io_error_exit;
275 		}
276 		goto mft_has_no_attr_list;
277 	}
278 	NInoSetAttrList(vol->mft_ni);
279 	l = ntfs_get_attribute_value_length(ctx->attr);
280 	if (l <= 0 || l > 0x40000) {
281 		ntfs_log_error("$MFT/$ATTR_LIST invalid length (%lld).\n",
282 			       (long long)l);
283 		goto io_error_exit;
284 	}
285 	vol->mft_ni->attr_list_size = l;
286 	vol->mft_ni->attr_list = ntfs_malloc(l);
287 	if (!vol->mft_ni->attr_list)
288 		goto error_exit;
289 
290 	l = ntfs_get_attribute_value(vol, ctx->attr, vol->mft_ni->attr_list);
291 	if (!l) {
292 		ntfs_log_error("Failed to get value of $MFT/$ATTR_LIST.\n");
293 		goto io_error_exit;
294 	}
295 	if (l != vol->mft_ni->attr_list_size) {
296 		ntfs_log_error("Partial read of $MFT/$ATTR_LIST (%lld != "
297 			       "%u).\n", (long long)l,
298 			       vol->mft_ni->attr_list_size);
299 		goto io_error_exit;
300 	}
301 
302 mft_has_no_attr_list:
303 
304 	ntfs_attr_setup_flag(vol->mft_ni);
305 
306 	/* We now have a fully setup ntfs inode for $MFT in vol->mft_ni. */
307 
308 	/* Get an ntfs attribute for $MFT/$DATA and set it up, too. */
309 	vol->mft_na = ntfs_attr_open(vol->mft_ni, AT_DATA, AT_UNNAMED, 0);
310 	if (!vol->mft_na) {
311 		ntfs_log_perror("Failed to open ntfs attribute");
312 		goto error_exit;
313 	}
314 	/* Read all extents from the $DATA attribute in $MFT. */
315 	ntfs_attr_reinit_search_ctx(ctx);
316 	last_vcn = vol->mft_na->allocated_size >> vol->cluster_size_bits;
317 	highest_vcn = next_vcn = 0;
318 	a = NULL;
319 	while (!ntfs_attr_lookup(AT_DATA, AT_UNNAMED, 0, 0, next_vcn, NULL, 0,
320 			ctx)) {
321 		runlist_element *nrl;
322 
323 		a = ctx->attr;
324 		/* $MFT must be non-resident. */
325 		if (!a->non_resident) {
326 			ntfs_log_error("$MFT must be non-resident.\n");
327 			goto io_error_exit;
328 		}
329 		/* $MFT must be uncompressed and unencrypted. */
330 		if (a->flags & ATTR_COMPRESSION_MASK ||
331 				a->flags & ATTR_IS_ENCRYPTED) {
332 			ntfs_log_error("$MFT must be uncompressed and "
333 				       "unencrypted.\n");
334 			goto io_error_exit;
335 		}
336 		/*
337 		 * Decompress the mapping pairs array of this extent and merge
338 		 * the result into the existing runlist. No need for locking
339 		 * as we have exclusive access to the inode at this time and we
340 		 * are a mount in progress task, too.
341 		 */
342 		nrl = ntfs_mapping_pairs_decompress(vol, a, vol->mft_na->rl);
343 		if (!nrl) {
344 			ntfs_log_perror("ntfs_mapping_pairs_decompress() failed");
345 			goto error_exit;
346 		}
347 		vol->mft_na->rl = nrl;
348 
349 		/* Get the lowest vcn for the next extent. */
350 		highest_vcn = sle64_to_cpu(a->highest_vcn);
351 		next_vcn = highest_vcn + 1;
352 
353 		/* Only one extent or error, which we catch below. */
354 		if (next_vcn <= 0)
355 			break;
356 
357 		/* Avoid endless loops due to corruption. */
358 		if (next_vcn < sle64_to_cpu(a->lowest_vcn)) {
359 			ntfs_log_error("$MFT has corrupt attribute list.\n");
360 			goto io_error_exit;
361 		}
362 	}
363 	if (!a) {
364 		ntfs_log_error("$MFT/$DATA attribute not found.\n");
365 		goto io_error_exit;
366 	}
367 	if (highest_vcn && highest_vcn != last_vcn - 1) {
368 		ntfs_log_error("Failed to load runlist for $MFT/$DATA.\n");
369 		ntfs_log_error("highest_vcn = 0x%llx, last_vcn - 1 = 0x%llx\n",
370 			       (long long)highest_vcn, (long long)last_vcn - 1);
371 		goto io_error_exit;
372 	}
373 	/* Done with the $Mft mft record. */
374 	ntfs_attr_put_search_ctx(ctx);
375 	ctx = NULL;
376 	/*
377 	 * The volume is now setup so we can use all read access functions.
378 	 */
379 	vol->mftbmp_na = ntfs_attr_open(vol->mft_ni, AT_BITMAP, AT_UNNAMED, 0);
380 	if (!vol->mftbmp_na) {
381 		ntfs_log_perror("Failed to open $MFT/$BITMAP");
382 		goto error_exit;
383 	}
384 	return 0;
385 io_error_exit:
386 	errno = EIO;
387 error_exit:
388 	eo = errno;
389 	if (ctx)
390 		ntfs_attr_put_search_ctx(ctx);
391 	if (vol->mft_na) {
392 		ntfs_attr_close(vol->mft_na);
393 		vol->mft_na = NULL;
394 	}
395 	if (vol->mft_ni) {
396 		ntfs_inode_close(vol->mft_ni);
397 		vol->mft_ni = NULL;
398 	}
399 	errno = eo;
400 	return -1;
401 }
402 
403 /**
404  * ntfs_mftmirr_load - load the $MFTMirr and setup the ntfs volume with it
405  * @vol:	ntfs volume whose $MFTMirr to load
406  *
407  * Load $MFTMirr from @vol and setup @vol with it. After calling this function
408  * the volume @vol is ready for use by all write access functions provided by
409  * the ntfs library (assuming ntfs_mft_load() has been called successfully
410  * beforehand).
411  *
412  * Return 0 on success and -1 on error with errno set to the error code.
413  */
414 static int ntfs_mftmirr_load(ntfs_volume *vol)
415 {
416 	int err;
417 
418 	vol->mftmirr_ni = ntfs_inode_open(vol, FILE_MFTMirr);
419 	if (!vol->mftmirr_ni) {
420 		ntfs_log_perror("Failed to open inode $MFTMirr");
421 		return -1;
422 	}
423 
424 	vol->mftmirr_na = ntfs_attr_open(vol->mftmirr_ni, AT_DATA, AT_UNNAMED, 0);
425 	if (!vol->mftmirr_na) {
426 		ntfs_log_perror("Failed to open $MFTMirr/$DATA");
427 		goto error_exit;
428 	}
429 
430 	if (ntfs_attr_map_runlist(vol->mftmirr_na, 0) < 0) {
431 		ntfs_log_perror("Failed to map runlist of $MFTMirr/$DATA");
432 		goto error_exit;
433 	}
434 
435 	return 0;
436 
437 error_exit:
438 	err = errno;
439 	if (vol->mftmirr_na) {
440 		ntfs_attr_close(vol->mftmirr_na);
441 		vol->mftmirr_na = NULL;
442 	}
443 	ntfs_inode_close(vol->mftmirr_ni);
444 	vol->mftmirr_ni = NULL;
445 	errno = err;
446 	return -1;
447 }
448 
449 /**
450  * ntfs_volume_startup - allocate and setup an ntfs volume
451  * @dev:	device to open
452  * @flags:	optional mount flags
453  *
454  * Load, verify, and parse bootsector; load and setup $MFT and $MFTMirr. After
455  * calling this function, the volume is setup sufficiently to call all read
456  * and write access functions provided by the library.
457  *
458  * Return the allocated volume structure on success and NULL on error with
459  * errno set to the error code.
460  */
461 ntfs_volume *ntfs_volume_startup(struct ntfs_device *dev, unsigned long flags)
462 {
463 	LCN mft_zone_size, mft_lcn;
464 	s64 br;
465 	ntfs_volume *vol;
466 	NTFS_BOOT_SECTOR *bs;
467 	int eo;
468 
469 	if (!dev || !dev->d_ops || !dev->d_name) {
470 		errno = EINVAL;
471 		ntfs_log_perror("%s: dev = %p", __FUNCTION__, dev);
472 		return NULL;
473 	}
474 
475 	bs = ntfs_malloc(sizeof(NTFS_BOOT_SECTOR));
476 	if (!bs)
477 		return NULL;
478 
479 	/* Allocate the volume structure. */
480 	vol = ntfs_volume_alloc();
481 	if (!vol)
482 		goto error_exit;
483 
484 	/* Create the default upcase table. */
485 	vol->upcase_len = 65536;
486 	vol->upcase = ntfs_malloc(vol->upcase_len * sizeof(ntfschar));
487 	if (!vol->upcase)
488 		goto error_exit;
489 
490 	ntfs_upcase_table_build(vol->upcase,
491 			vol->upcase_len * sizeof(ntfschar));
492 	/* Default with no locase table and case sensitive file names */
493 	vol->locase = (ntfschar*)NULL;
494 	NVolSetCaseSensitive(vol);
495 
496 		/* by default, all files are shown and not marked hidden */
497 	NVolSetShowSysFiles(vol);
498 	NVolSetShowHidFiles(vol);
499 	NVolClearHideDotFiles(vol);
500 	if (flags & MS_RDONLY)
501 		NVolSetReadOnly(vol);
502 
503 	/* ...->open needs bracketing to compile with glibc 2.7 */
504 	if ((dev->d_ops->open)(dev, NVolReadOnly(vol) ? O_RDONLY: O_RDWR)) {
505 		ntfs_log_perror("Error opening '%s'", dev->d_name);
506 		goto error_exit;
507 	}
508 	/* Attach the device to the volume. */
509 	vol->dev = dev;
510 
511 	/* Now read the bootsector. */
512 	br = ntfs_pread(dev, 0, sizeof(NTFS_BOOT_SECTOR), bs);
513 	if (br != sizeof(NTFS_BOOT_SECTOR)) {
514 		if (br != -1)
515 			errno = EINVAL;
516 		if (!br)
517 			ntfs_log_error("Failed to read bootsector (size=0)\n");
518 		else
519 			ntfs_log_perror("Error reading bootsector");
520 		goto error_exit;
521 	}
522 	if (!ntfs_boot_sector_is_ntfs(bs)) {
523 		errno = EINVAL;
524 		goto error_exit;
525 	}
526 	if (ntfs_boot_sector_parse(vol, bs) < 0)
527 		goto error_exit;
528 
529 	free(bs);
530 	bs = NULL;
531 	/* Now set the device block size to the sector size. */
532 	if (ntfs_device_block_size_set(vol->dev, vol->sector_size))
533 		ntfs_log_debug("Failed to set the device block size to the "
534 				"sector size.  This may affect performance "
535 				"but should be harmless otherwise.  Error: "
536 				"%s\n", strerror(errno));
537 
538 	/* We now initialize the cluster allocator. */
539 	vol->full_zones = 0;
540 	mft_zone_size = vol->nr_clusters >> 3;      /* 12.5% */
541 
542 	/* Setup the mft zone. */
543 	vol->mft_zone_start = vol->mft_zone_pos = vol->mft_lcn;
544 	ntfs_log_debug("mft_zone_pos = 0x%llx\n", (long long)vol->mft_zone_pos);
545 
546 	/*
547 	 * Calculate the mft_lcn for an unmodified NTFS volume (see mkntfs
548 	 * source) and if the actual mft_lcn is in the expected place or even
549 	 * further to the front of the volume, extend the mft_zone to cover the
550 	 * beginning of the volume as well. This is in order to protect the
551 	 * area reserved for the mft bitmap as well within the mft_zone itself.
552 	 * On non-standard volumes we don't protect it as the overhead would be
553 	 * higher than the speed increase we would get by doing it.
554 	 */
555 	mft_lcn = (8192 + 2 * vol->cluster_size - 1) / vol->cluster_size;
556 	if (mft_lcn * vol->cluster_size < 16 * 1024)
557 		mft_lcn = (16 * 1024 + vol->cluster_size - 1) /
558 				vol->cluster_size;
559 	if (vol->mft_zone_start <= mft_lcn)
560 		vol->mft_zone_start = 0;
561 	ntfs_log_debug("mft_zone_start = 0x%llx\n", (long long)vol->mft_zone_start);
562 
563 	/*
564 	 * Need to cap the mft zone on non-standard volumes so that it does
565 	 * not point outside the boundaries of the volume. We do this by
566 	 * halving the zone size until we are inside the volume.
567 	 */
568 	vol->mft_zone_end = vol->mft_lcn + mft_zone_size;
569 	while (vol->mft_zone_end >= vol->nr_clusters) {
570 		mft_zone_size >>= 1;
571 		vol->mft_zone_end = vol->mft_lcn + mft_zone_size;
572 	}
573 	ntfs_log_debug("mft_zone_end = 0x%llx\n", (long long)vol->mft_zone_end);
574 
575 	/*
576 	 * Set the current position within each data zone to the start of the
577 	 * respective zone.
578 	 */
579 	vol->data1_zone_pos = vol->mft_zone_end;
580 	ntfs_log_debug("data1_zone_pos = %lld\n", (long long)vol->data1_zone_pos);
581 	vol->data2_zone_pos = 0;
582 	ntfs_log_debug("data2_zone_pos = %lld\n", (long long)vol->data2_zone_pos);
583 
584 	/* Set the mft data allocation position to mft record 24. */
585 	vol->mft_data_pos = 24;
586 
587 	/*
588 	 * The cluster allocator is now fully operational.
589 	 */
590 
591 	/* Need to setup $MFT so we can use the library read functions. */
592 	if (ntfs_mft_load(vol) < 0) {
593 		ntfs_log_perror("Failed to load $MFT");
594 		goto error_exit;
595 	}
596 
597 	/* Need to setup $MFTMirr so we can use the write functions, too. */
598 	if (ntfs_mftmirr_load(vol) < 0) {
599 		ntfs_log_perror("Failed to load $MFTMirr");
600 		goto error_exit;
601 	}
602 	return vol;
603 error_exit:
604 	eo = errno;
605 	free(bs);
606 	if (vol)
607 		__ntfs_volume_release(vol);
608 	errno = eo;
609 	return NULL;
610 }
611 
612 /**
613  * ntfs_volume_check_logfile - check logfile on target volume
614  * @vol:	volume on which to check logfile
615  *
616  * Return 0 on success and -1 on error with errno set error code.
617  */
618 static int ntfs_volume_check_logfile(ntfs_volume *vol)
619 {
620 	ntfs_inode *ni;
621 	ntfs_attr *na = NULL;
622 	RESTART_PAGE_HEADER *rp = NULL;
623 	int err = 0;
624 
625 	ni = ntfs_inode_open(vol, FILE_LogFile);
626 	if (!ni) {
627 		ntfs_log_perror("Failed to open inode FILE_LogFile");
628 		errno = EIO;
629 		return -1;
630 	}
631 
632 	na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
633 	if (!na) {
634 		ntfs_log_perror("Failed to open $FILE_LogFile/$DATA");
635 		err = EIO;
636 		goto out;
637 	}
638 
639 	if (!ntfs_check_logfile(na, &rp) || !ntfs_is_logfile_clean(na, rp))
640 		err = EOPNOTSUPP;
641 	free(rp);
642 	ntfs_attr_close(na);
643 out:
644 	if (ntfs_inode_close(ni))
645 		ntfs_error_set(&err);
646 	if (err) {
647 		errno = err;
648 		return -1;
649 	}
650 	return 0;
651 }
652 
653 /**
654  * ntfs_hiberfile_open - Find and open '/hiberfil.sys'
655  * @vol:    An ntfs volume obtained from ntfs_mount
656  *
657  * Return:  inode  Success, hiberfil.sys is valid
658  *	    NULL   hiberfil.sys doesn't exist or some other error occurred
659  */
660 static ntfs_inode *ntfs_hiberfile_open(ntfs_volume *vol)
661 {
662 	u64 inode;
663 	ntfs_inode *ni_root;
664 	ntfs_inode *ni_hibr = NULL;
665 	ntfschar   *unicode = NULL;
666 	int unicode_len;
667 	const char *hiberfile = "hiberfil.sys";
668 
669 	if (!vol) {
670 		errno = EINVAL;
671 		return NULL;
672 	}
673 
674 	ni_root = ntfs_inode_open(vol, FILE_root);
675 	if (!ni_root) {
676 		ntfs_log_debug("Couldn't open the root directory.\n");
677 		return NULL;
678 	}
679 
680 	unicode_len = ntfs_mbstoucs(hiberfile, &unicode);
681 	if (unicode_len < 0) {
682 		ntfs_log_perror("Couldn't convert 'hiberfil.sys' to Unicode");
683 		goto out;
684 	}
685 
686 	inode = ntfs_inode_lookup_by_name(ni_root, unicode, unicode_len);
687 	if (inode == (u64)-1) {
688 		ntfs_log_debug("Couldn't find file '%s'.\n", hiberfile);
689 		goto out;
690 	}
691 
692 	inode = MREF(inode);
693 	ni_hibr = ntfs_inode_open(vol, inode);
694 	if (!ni_hibr) {
695 		ntfs_log_debug("Couldn't open inode %lld.\n", (long long)inode);
696 		goto out;
697 	}
698 out:
699 	if (ntfs_inode_close(ni_root)) {
700 		ntfs_inode_close(ni_hibr);
701 		ni_hibr = NULL;
702 	}
703 	free(unicode);
704 	return ni_hibr;
705 }
706 
707 
708 #define NTFS_HIBERFILE_HEADER_SIZE	4096
709 
710 /**
711  * ntfs_volume_check_hiberfile - check hiberfil.sys whether Windows is
712  *                               hibernated on the target volume
713  * @vol:    volume on which to check hiberfil.sys
714  *
715  * Return:  0 if Windows isn't hibernated for sure
716  *         -1 otherwise and errno is set to the appropriate value
717  */
718 int ntfs_volume_check_hiberfile(ntfs_volume *vol, int verbose)
719 {
720 	ntfs_inode *ni;
721 	ntfs_attr *na = NULL;
722 	int bytes_read, err;
723 	char *buf = NULL;
724 
725 	ni = ntfs_hiberfile_open(vol);
726 	if (!ni) {
727 		if (errno == ENOENT)
728 			return 0;
729 		return -1;
730 	}
731 
732 	buf = ntfs_malloc(NTFS_HIBERFILE_HEADER_SIZE);
733 	if (!buf)
734 		goto out;
735 
736 	na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
737 	if (!na) {
738 		ntfs_log_perror("Failed to open hiberfil.sys data attribute");
739 		goto out;
740 	}
741 
742 	bytes_read = ntfs_attr_pread(na, 0, NTFS_HIBERFILE_HEADER_SIZE, buf);
743 	if (bytes_read == -1) {
744 		ntfs_log_perror("Failed to read hiberfil.sys");
745 		goto out;
746 	}
747 	if (bytes_read < NTFS_HIBERFILE_HEADER_SIZE) {
748 		if (verbose)
749 			ntfs_log_error("Hibernated non-system partition, "
750 				       "refused to mount.\n");
751 		errno = EPERM;
752 		goto out;
753 	}
754 	if (memcmp(buf, "hibr", 4) == 0) {
755 		if (verbose)
756 			ntfs_log_error("Windows is hibernated, refused to mount.\n");
757 		errno = EPERM;
758 		goto out;
759 	}
760         /* All right, all header bytes are zero */
761 	errno = 0;
762 out:
763 	if (na)
764 		ntfs_attr_close(na);
765 	free(buf);
766 	err = errno;
767 	if (ntfs_inode_close(ni))
768 		ntfs_error_set(&err);
769 	errno = err;
770 	return errno ? -1 : 0;
771 }
772 
773 /*
774  *		Make sure a LOGGED_UTILITY_STREAM attribute named "$TXF_DATA"
775  *	on the root directory is resident.
776  *	When it is non-resident, the partition cannot be mounted on Vista
777  *	(see http://support.microsoft.com/kb/974729)
778  *
779  *	We take care to avoid this situation, however this can be a
780  *	consequence of having used an older version (including older
781  *	Windows version), so we had better fix it.
782  *
783  *	Returns 0 if unneeded or successful
784  *		-1 if there was an error, explained by errno
785  */
786 
787 static int fix_txf_data(ntfs_volume *vol)
788 {
789 	void *txf_data;
790 	s64 txf_data_size;
791 	ntfs_inode *ni;
792 	ntfs_attr *na;
793 	int res;
794 
795 	res = 0;
796 	ntfs_log_debug("Loading root directory\n");
797 	ni = ntfs_inode_open(vol, FILE_root);
798 	if (!ni) {
799 		ntfs_log_perror("Failed to open root directory");
800 		res = -1;
801 	} else {
802 		/* Get the $TXF_DATA attribute */
803 		na = ntfs_attr_open(ni, AT_LOGGED_UTILITY_STREAM, TXF_DATA, 9);
804 		if (na) {
805 			if (NAttrNonResident(na)) {
806 				/*
807 				 * Fix the attribute by truncating, then
808 				 * rewriting it.
809 				 */
810 				ntfs_log_debug("Making $TXF_DATA resident\n");
811 				txf_data = ntfs_attr_readall(ni,
812 						AT_LOGGED_UTILITY_STREAM,
813 						TXF_DATA, 9, &txf_data_size);
814 				if (txf_data) {
815 					if (ntfs_attr_truncate(na, 0)
816 					    || (ntfs_attr_pwrite(na, 0,
817 						 txf_data_size, txf_data)
818 							!= txf_data_size))
819 						res = -1;
820 					free(txf_data);
821 				}
822 			if (res)
823 				ntfs_log_error("Failed to make $TXF_DATA resident\n");
824 			else
825 				ntfs_log_error("$TXF_DATA made resident\n");
826 			}
827 			ntfs_attr_close(na);
828 		}
829 		if (ntfs_inode_close(ni)) {
830 			ntfs_log_perror("Failed to close root");
831 			res = -1;
832 		}
833 	}
834 	return (res);
835 }
836 
837 /**
838  * ntfs_device_mount - open ntfs volume
839  * @dev:	device to open
840  * @flags:	optional mount flags
841  *
842  * This function mounts an ntfs volume. @dev should describe the device which
843  * to mount as the ntfs volume.
844  *
845  * @flags is an optional second parameter. The same flags are used as for
846  * the mount system call (man 2 mount). Currently only the following flag
847  * is implemented:
848  *	MS_RDONLY	- mount volume read-only
849  *
850  * The function opens the device @dev and verifies that it contains a valid
851  * bootsector. Then, it allocates an ntfs_volume structure and initializes
852  * some of the values inside the structure from the information stored in the
853  * bootsector. It proceeds to load the necessary system files and completes
854  * setting up the structure.
855  *
856  * Return the allocated volume structure on success and NULL on error with
857  * errno set to the error code.
858  */
859 ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags)
860 {
861 	s64 l;
862 	ntfs_volume *vol;
863 	u8 *m = NULL, *m2 = NULL;
864 	ntfs_attr_search_ctx *ctx = NULL;
865 	ntfs_inode *ni;
866 	ntfs_attr *na;
867 	ATTR_RECORD *a;
868 	VOLUME_INFORMATION *vinf;
869 	ntfschar *vname;
870 	int i, j, eo;
871 	u32 u;
872 
873 	vol = ntfs_volume_startup(dev, flags);
874 	if (!vol)
875 		return NULL;
876 
877 	/* Load data from $MFT and $MFTMirr and compare the contents. */
878 	m  = ntfs_malloc(vol->mftmirr_size << vol->mft_record_size_bits);
879 	m2 = ntfs_malloc(vol->mftmirr_size << vol->mft_record_size_bits);
880 	if (!m || !m2)
881 		goto error_exit;
882 
883 	l = ntfs_attr_mst_pread(vol->mft_na, 0, vol->mftmirr_size,
884 			vol->mft_record_size, m);
885 	if (l != vol->mftmirr_size) {
886 		if (l == -1)
887 			ntfs_log_perror("Failed to read $MFT");
888 		else {
889 			ntfs_log_error("Failed to read $MFT, unexpected length "
890 				       "(%lld != %d).\n", (long long)l,
891 				       vol->mftmirr_size);
892 			errno = EIO;
893 		}
894 		goto error_exit;
895 	}
896 	l = ntfs_attr_mst_pread(vol->mftmirr_na, 0, vol->mftmirr_size,
897 			vol->mft_record_size, m2);
898 	if (l != vol->mftmirr_size) {
899 		if (l == -1) {
900 			ntfs_log_perror("Failed to read $MFTMirr");
901 			goto error_exit;
902 		}
903 		vol->mftmirr_size = l;
904 	}
905 	ntfs_log_debug("Comparing $MFTMirr to $MFT...\n");
906 	for (i = 0; i < vol->mftmirr_size; ++i) {
907 		MFT_RECORD *mrec, *mrec2;
908 		const char *ESTR[12] = { "$MFT", "$MFTMirr", "$LogFile",
909 			"$Volume", "$AttrDef", "root directory", "$Bitmap",
910 			"$Boot", "$BadClus", "$Secure", "$UpCase", "$Extend" };
911 		const char *s;
912 
913 		if (i < 12)
914 			s = ESTR[i];
915 		else if (i < 16)
916 			s = "system file";
917 		else
918 			s = "mft record";
919 
920 		mrec = (MFT_RECORD*)(m + i * vol->mft_record_size);
921 		if (mrec->flags & MFT_RECORD_IN_USE) {
922 			if (ntfs_is_baad_recordp(mrec)) {
923 				ntfs_log_error("$MFT error: Incomplete multi "
924 					       "sector transfer detected in "
925 					       "'%s'.\n", s);
926 				goto io_error_exit;
927 			}
928 			if (!ntfs_is_mft_recordp(mrec)) {
929 				ntfs_log_error("$MFT error: Invalid mft "
930 						"record for '%s'.\n", s);
931 				goto io_error_exit;
932 			}
933 		}
934 		mrec2 = (MFT_RECORD*)(m2 + i * vol->mft_record_size);
935 		if (mrec2->flags & MFT_RECORD_IN_USE) {
936 			if (ntfs_is_baad_recordp(mrec2)) {
937 				ntfs_log_error("$MFTMirr error: Incomplete "
938 						"multi sector transfer "
939 						"detected in '%s'.\n", s);
940 				goto io_error_exit;
941 			}
942 			if (!ntfs_is_mft_recordp(mrec2)) {
943 				ntfs_log_error("$MFTMirr error: Invalid mft "
944 						"record for '%s'.\n", s);
945 				goto io_error_exit;
946 			}
947 		}
948 		if (memcmp(mrec, mrec2, ntfs_mft_record_get_data_size(mrec))) {
949 			ntfs_log_error("$MFTMirr does not match $MFT (record "
950 				       "%d).\n", i);
951 			goto io_error_exit;
952 		}
953 	}
954 
955 	free(m2);
956 	free(m);
957 	m = m2 = NULL;
958 
959 	/* Now load the bitmap from $Bitmap. */
960 	ntfs_log_debug("Loading $Bitmap...\n");
961 	vol->lcnbmp_ni = ntfs_inode_open(vol, FILE_Bitmap);
962 	if (!vol->lcnbmp_ni) {
963 		ntfs_log_perror("Failed to open inode FILE_Bitmap");
964 		goto error_exit;
965 	}
966 
967 	vol->lcnbmp_na = ntfs_attr_open(vol->lcnbmp_ni, AT_DATA, AT_UNNAMED, 0);
968 	if (!vol->lcnbmp_na) {
969 		ntfs_log_perror("Failed to open ntfs attribute");
970 		goto error_exit;
971 	}
972 
973 	if (vol->lcnbmp_na->data_size > vol->lcnbmp_na->allocated_size) {
974 		ntfs_log_error("Corrupt cluster map size (%lld > %lld)\n",
975 				(long long)vol->lcnbmp_na->data_size,
976 				(long long)vol->lcnbmp_na->allocated_size);
977 		goto io_error_exit;
978 	}
979 
980 	/* Now load the upcase table from $UpCase. */
981 	ntfs_log_debug("Loading $UpCase...\n");
982 	ni = ntfs_inode_open(vol, FILE_UpCase);
983 	if (!ni) {
984 		ntfs_log_perror("Failed to open inode FILE_UpCase");
985 		goto error_exit;
986 	}
987 	/* Get an ntfs attribute for $UpCase/$DATA. */
988 	na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
989 	if (!na) {
990 		ntfs_log_perror("Failed to open ntfs attribute");
991 		goto error_exit;
992 	}
993 	/*
994 	 * Note: Normally, the upcase table has a length equal to 65536
995 	 * 2-byte Unicode characters but allow for different cases, so no
996 	 * checks done. Just check we don't overflow 32-bits worth of Unicode
997 	 * characters.
998 	 */
999 	if (na->data_size & ~0x1ffffffffULL) {
1000 		ntfs_log_error("Error: Upcase table is too big (max 32-bit "
1001 				"allowed).\n");
1002 		errno = EINVAL;
1003 		goto error_exit;
1004 	}
1005 	if (vol->upcase_len != na->data_size >> 1) {
1006 		vol->upcase_len = na->data_size >> 1;
1007 		/* Throw away default table. */
1008 		free(vol->upcase);
1009 		vol->upcase = ntfs_malloc(na->data_size);
1010 		if (!vol->upcase)
1011 			goto error_exit;
1012 	}
1013 	/* Read in the $DATA attribute value into the buffer. */
1014 	l = ntfs_attr_pread(na, 0, na->data_size, vol->upcase);
1015 	if (l != na->data_size) {
1016 		ntfs_log_error("Failed to read $UpCase, unexpected length "
1017 			       "(%lld != %lld).\n", (long long)l,
1018 			       (long long)na->data_size);
1019 		errno = EIO;
1020 		goto error_exit;
1021 	}
1022 	/* Done with the $UpCase mft record. */
1023 	ntfs_attr_close(na);
1024 	if (ntfs_inode_close(ni)) {
1025 		ntfs_log_perror("Failed to close $UpCase");
1026 		goto error_exit;
1027 	}
1028 
1029 	/*
1030 	 * Now load $Volume and set the version information and flags in the
1031 	 * vol structure accordingly.
1032 	 */
1033 	ntfs_log_debug("Loading $Volume...\n");
1034 	vol->vol_ni = ntfs_inode_open(vol, FILE_Volume);
1035 	if (!vol->vol_ni) {
1036 		ntfs_log_perror("Failed to open inode FILE_Volume");
1037 		goto error_exit;
1038 	}
1039 	/* Get a search context for the $Volume/$VOLUME_INFORMATION lookup. */
1040 	ctx = ntfs_attr_get_search_ctx(vol->vol_ni, NULL);
1041 	if (!ctx)
1042 		goto error_exit;
1043 
1044 	/* Find the $VOLUME_INFORMATION attribute. */
1045 	if (ntfs_attr_lookup(AT_VOLUME_INFORMATION, AT_UNNAMED, 0, 0, 0, NULL,
1046 			0, ctx)) {
1047 		ntfs_log_perror("$VOLUME_INFORMATION attribute not found in "
1048 				"$Volume");
1049 		goto error_exit;
1050 	}
1051 	a = ctx->attr;
1052 	/* Has to be resident. */
1053 	if (a->non_resident) {
1054 		ntfs_log_error("Attribute $VOLUME_INFORMATION must be "
1055 			       "resident but it isn't.\n");
1056 		errno = EIO;
1057 		goto error_exit;
1058 	}
1059 	/* Get a pointer to the value of the attribute. */
1060 	vinf = (VOLUME_INFORMATION*)(le16_to_cpu(a->value_offset) + (char*)a);
1061 	/* Sanity checks. */
1062 	if ((char*)vinf + le32_to_cpu(a->value_length) > (char*)ctx->mrec +
1063 			le32_to_cpu(ctx->mrec->bytes_in_use) ||
1064 			le16_to_cpu(a->value_offset) + le32_to_cpu(
1065 			a->value_length) > le32_to_cpu(a->length)) {
1066 		ntfs_log_error("$VOLUME_INFORMATION in $Volume is corrupt.\n");
1067 		errno = EIO;
1068 		goto error_exit;
1069 	}
1070 	/* Setup vol from the volume information attribute value. */
1071 	vol->major_ver = vinf->major_ver;
1072 	vol->minor_ver = vinf->minor_ver;
1073 	/* Do not use le16_to_cpu() macro here as our VOLUME_FLAGS are
1074 	   defined using cpu_to_le16() macro and hence are consistent. */
1075 	vol->flags = vinf->flags;
1076 	/*
1077 	 * Reinitialize the search context for the $Volume/$VOLUME_NAME lookup.
1078 	 */
1079 	ntfs_attr_reinit_search_ctx(ctx);
1080 	if (ntfs_attr_lookup(AT_VOLUME_NAME, AT_UNNAMED, 0, 0, 0, NULL, 0,
1081 			ctx)) {
1082 		if (errno != ENOENT) {
1083 			ntfs_log_perror("Failed to lookup of $VOLUME_NAME in "
1084 					"$Volume failed");
1085 			goto error_exit;
1086 		}
1087 		/*
1088 		 * Attribute not present.  This has been seen in the field.
1089 		 * Treat this the same way as if the attribute was present but
1090 		 * had zero length.
1091 		 */
1092 		vol->vol_name = ntfs_malloc(1);
1093 		if (!vol->vol_name)
1094 			goto error_exit;
1095 		vol->vol_name[0] = '\0';
1096 	} else {
1097 		a = ctx->attr;
1098 		/* Has to be resident. */
1099 		if (a->non_resident) {
1100 			ntfs_log_error("$VOLUME_NAME must be resident.\n");
1101 			errno = EIO;
1102 			goto error_exit;
1103 		}
1104 		/* Get a pointer to the value of the attribute. */
1105 		vname = (ntfschar*)(le16_to_cpu(a->value_offset) + (char*)a);
1106 		u = le32_to_cpu(a->value_length) / 2;
1107 		/*
1108 		 * Convert Unicode volume name to current locale multibyte
1109 		 * format.
1110 		 */
1111 		vol->vol_name = NULL;
1112 		if (ntfs_ucstombs(vname, u, &vol->vol_name, 0) == -1) {
1113 			ntfs_log_perror("Volume name could not be converted "
1114 					"to current locale");
1115 			ntfs_log_debug("Forcing name into ASCII by replacing "
1116 				"non-ASCII characters with underscores.\n");
1117 			vol->vol_name = ntfs_malloc(u + 1);
1118 			if (!vol->vol_name)
1119 				goto error_exit;
1120 
1121 			for (j = 0; j < (s32)u; j++) {
1122 				u16 uc = le16_to_cpu(vname[j]);
1123 				if (uc > 0xff)
1124 					uc = (u16)'_';
1125 				vol->vol_name[j] = (char)uc;
1126 			}
1127 			vol->vol_name[u] = '\0';
1128 		}
1129 	}
1130 	ntfs_attr_put_search_ctx(ctx);
1131 	ctx = NULL;
1132 	/* Now load the attribute definitions from $AttrDef. */
1133 	ntfs_log_debug("Loading $AttrDef...\n");
1134 	ni = ntfs_inode_open(vol, FILE_AttrDef);
1135 	if (!ni) {
1136 		ntfs_log_perror("Failed to open $AttrDef");
1137 		goto error_exit;
1138 	}
1139 	/* Get an ntfs attribute for $AttrDef/$DATA. */
1140 	na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
1141 	if (!na) {
1142 		ntfs_log_perror("Failed to open ntfs attribute");
1143 		goto error_exit;
1144 	}
1145 	/* Check we don't overflow 32-bits. */
1146 	if (na->data_size > 0xffffffffLL) {
1147 		ntfs_log_error("Attribute definition table is too big (max "
1148 			       "32-bit allowed).\n");
1149 		errno = EINVAL;
1150 		goto error_exit;
1151 	}
1152 	vol->attrdef_len = na->data_size;
1153 	vol->attrdef = ntfs_malloc(na->data_size);
1154 	if (!vol->attrdef)
1155 		goto error_exit;
1156 	/* Read in the $DATA attribute value into the buffer. */
1157 	l = ntfs_attr_pread(na, 0, na->data_size, vol->attrdef);
1158 	if (l != na->data_size) {
1159 		ntfs_log_error("Failed to read $AttrDef, unexpected length "
1160 			       "(%lld != %lld).\n", (long long)l,
1161 			       (long long)na->data_size);
1162 		errno = EIO;
1163 		goto error_exit;
1164 	}
1165 	/* Done with the $AttrDef mft record. */
1166 	ntfs_attr_close(na);
1167 	if (ntfs_inode_close(ni)) {
1168 		ntfs_log_perror("Failed to close $AttrDef");
1169 		goto error_exit;
1170 	}
1171 	/*
1172 	 * Check for dirty logfile and hibernated Windows.
1173 	 * We care only about read-write mounts.
1174 	 */
1175 	if (!(flags & MS_RDONLY)) {
1176 		if (!(flags & MS_IGNORE_HIBERFILE) &&
1177 		    ntfs_volume_check_hiberfile(vol, 1) < 0)
1178 			goto error_exit;
1179 		if (ntfs_volume_check_logfile(vol) < 0) {
1180 			if (!(flags & MS_RECOVER))
1181 				goto error_exit;
1182 			ntfs_log_info("The file system wasn't safely "
1183 				      "closed on Windows. Fixing.\n");
1184 			if (ntfs_logfile_reset(vol))
1185 				goto error_exit;
1186 		}
1187 	}
1188 		/* make $TXF_DATA resident if present on the root directory */
1189 	if (!NVolReadOnly(vol) && fix_txf_data(vol))
1190 		goto error_exit;
1191 
1192 	return vol;
1193 io_error_exit:
1194 	errno = EIO;
1195 error_exit:
1196 	eo = errno;
1197 	if (ctx)
1198 		ntfs_attr_put_search_ctx(ctx);
1199 	free(m);
1200 	free(m2);
1201 	__ntfs_volume_release(vol);
1202 	errno = eo;
1203 	return NULL;
1204 }
1205 
1206 /*
1207  *		Set appropriate flags for showing NTFS metafiles
1208  *	or files marked as hidden.
1209  *	Not set in ntfs_mount() to avoid breaking existing tools.
1210  */
1211 
1212 int ntfs_set_shown_files(ntfs_volume *vol,
1213 			BOOL show_sys_files, BOOL show_hid_files,
1214 			BOOL hide_dot_files)
1215 {
1216 	int res;
1217 
1218 	res = -1;
1219 	if (vol) {
1220 		NVolClearShowSysFiles(vol);
1221 		NVolClearShowHidFiles(vol);
1222 		NVolClearHideDotFiles(vol);
1223 		if (show_sys_files)
1224 			NVolSetShowSysFiles(vol);
1225 		if (show_hid_files)
1226 			NVolSetShowHidFiles(vol);
1227 		if (hide_dot_files)
1228 			NVolSetHideDotFiles(vol);
1229 		res = 0;
1230 	}
1231 	if (res)
1232 		ntfs_log_error("Failed to set file visibility\n");
1233 	return (res);
1234 }
1235 
1236 /*
1237  *		Set ignore case mode
1238  */
1239 
1240 int ntfs_set_ignore_case(ntfs_volume *vol)
1241 {
1242 	int res;
1243 
1244 	res = -1;
1245 	if (vol && vol->upcase) {
1246 		vol->locase = ntfs_locase_table_build(vol->upcase,
1247 					vol->upcase_len);
1248 		if (vol->locase) {
1249 			NVolClearCaseSensitive(vol);
1250 			res = 0;
1251 		}
1252 	}
1253 	if (res)
1254 		ntfs_log_error("Failed to set ignore_case mode\n");
1255 	return (res);
1256 }
1257 
1258 /**
1259  * ntfs_mount - open ntfs volume
1260  * @name:	name of device/file to open
1261  * @flags:	optional mount flags
1262  *
1263  * This function mounts an ntfs volume. @name should contain the name of the
1264  * device/file to mount as the ntfs volume.
1265  *
1266  * @flags is an optional second parameter. The same flags are used as for
1267  * the mount system call (man 2 mount). Currently only the following flags
1268  * is implemented:
1269  *	MS_RDONLY	- mount volume read-only
1270  *
1271  * The function opens the device or file @name and verifies that it contains a
1272  * valid bootsector. Then, it allocates an ntfs_volume structure and initializes
1273  * some of the values inside the structure from the information stored in the
1274  * bootsector. It proceeds to load the necessary system files and completes
1275  * setting up the structure.
1276  *
1277  * Return the allocated volume structure on success and NULL on error with
1278  * errno set to the error code.
1279  *
1280  * Note, that a copy is made of @name, and hence it can be discarded as
1281  * soon as the function returns.
1282  */
1283 ntfs_volume *ntfs_mount(const char *name __attribute__((unused)),
1284 		unsigned long flags __attribute__((unused)))
1285 {
1286 #ifndef NO_NTFS_DEVICE_DEFAULT_IO_OPS
1287 	struct ntfs_device *dev;
1288 	ntfs_volume *vol;
1289 
1290 	/* Allocate an ntfs_device structure. */
1291 	dev = ntfs_device_alloc(name, 0, &ntfs_device_default_io_ops, NULL);
1292 	if (!dev)
1293 		return NULL;
1294 	/* Call ntfs_device_mount() to do the actual mount. */
1295 	vol = ntfs_device_mount(dev, flags);
1296 	if (!vol) {
1297 		int eo = errno;
1298 		ntfs_device_free(dev);
1299 		errno = eo;
1300 	} else
1301 		ntfs_create_lru_caches(vol);
1302 	return vol;
1303 #else
1304 	/*
1305 	 * ntfs_mount() makes no sense if NO_NTFS_DEVICE_DEFAULT_IO_OPS is
1306 	 * defined as there are no device operations available in libntfs in
1307 	 * this case.
1308 	 */
1309 	errno = EOPNOTSUPP;
1310 	return NULL;
1311 #endif
1312 }
1313 
1314 /**
1315  * ntfs_umount - close ntfs volume
1316  * @vol: address of ntfs_volume structure of volume to close
1317  * @force: if true force close the volume even if it is busy
1318  *
1319  * Deallocate all structures (including @vol itself) associated with the ntfs
1320  * volume @vol.
1321  *
1322  * Return 0 on success. On error return -1 with errno set appropriately
1323  * (most likely to one of EAGAIN, EBUSY or EINVAL). The EAGAIN error means that
1324  * an operation is in progress and if you try the close later the operation
1325  * might be completed and the close succeed.
1326  *
1327  * If @force is true (i.e. not zero) this function will close the volume even
1328  * if this means that data might be lost.
1329  *
1330  * @vol must have previously been returned by a call to ntfs_mount().
1331  *
1332  * @vol itself is deallocated and should no longer be dereferenced after this
1333  * function returns success. If it returns an error then nothing has been done
1334  * so it is safe to continue using @vol.
1335  */
1336 int ntfs_umount(ntfs_volume *vol, const BOOL force __attribute__((unused)))
1337 {
1338 	struct ntfs_device *dev;
1339 	int ret;
1340 
1341 	if (!vol) {
1342 		errno = EINVAL;
1343 		return -1;
1344 	}
1345 	dev = vol->dev;
1346 	ret = __ntfs_volume_release(vol);
1347 	ntfs_device_free(dev);
1348 	return ret;
1349 }
1350 
1351 #ifdef HAVE_MNTENT_H
1352 
1353 #ifndef HAVE_REALPATH
1354 /**
1355  * realpath - If there is no realpath on the system
1356  */
1357 static char *realpath(const char *path, char *resolved_path)
1358 {
1359 	strncpy(resolved_path, path, PATH_MAX);
1360 	resolved_path[PATH_MAX] = '\0';
1361 	return resolved_path;
1362 }
1363 #endif
1364 
1365 /**
1366  * ntfs_mntent_check - desc
1367  *
1368  * If you are wanting to use this, you actually wanted to use
1369  * ntfs_check_if_mounted(), you just didn't realize. (-:
1370  *
1371  * See description of ntfs_check_if_mounted(), below.
1372  */
1373 static int ntfs_mntent_check(const char *file, unsigned long *mnt_flags)
1374 {
1375 	struct mntent *mnt;
1376 	char *real_file = NULL, *real_fsname = NULL;
1377 	FILE *f;
1378 	int err = 0;
1379 
1380 	real_file = ntfs_malloc(PATH_MAX + 1);
1381 	if (!real_file)
1382 		return -1;
1383 	real_fsname = ntfs_malloc(PATH_MAX + 1);
1384 	if (!real_fsname) {
1385 		err = errno;
1386 		goto exit;
1387 	}
1388 	if (!realpath(file, real_file)) {
1389 		err = errno;
1390 		goto exit;
1391 	}
1392 	if (!(f = setmntent(MOUNTED, "r"))) {
1393 		err = errno;
1394 		goto exit;
1395 	}
1396 	while ((mnt = getmntent(f))) {
1397 		if (!realpath(mnt->mnt_fsname, real_fsname))
1398 			continue;
1399 		if (!strcmp(real_file, real_fsname))
1400 			break;
1401 	}
1402 	endmntent(f);
1403 	if (!mnt)
1404 		goto exit;
1405 	*mnt_flags = NTFS_MF_MOUNTED;
1406 	if (!strcmp(mnt->mnt_dir, "/"))
1407 		*mnt_flags |= NTFS_MF_ISROOT;
1408 #ifdef HAVE_HASMNTOPT
1409 	if (hasmntopt(mnt, "ro") && !hasmntopt(mnt, "rw"))
1410 		*mnt_flags |= NTFS_MF_READONLY;
1411 #endif
1412 exit:
1413 	free(real_file);
1414 	free(real_fsname);
1415 	if (err) {
1416 		errno = err;
1417 		return -1;
1418 	}
1419 	return 0;
1420 }
1421 #endif /* HAVE_MNTENT_H */
1422 
1423 /**
1424  * ntfs_check_if_mounted - check if an ntfs volume is currently mounted
1425  * @file:	device file to check
1426  * @mnt_flags:	pointer into which to return the ntfs mount flags (see volume.h)
1427  *
1428  * If the running system does not support the {set,get,end}mntent() calls,
1429  * just return 0 and set *@mnt_flags to zero.
1430  *
1431  * When the system does support the calls, ntfs_check_if_mounted() first tries
1432  * to find the device @file in /etc/mtab (or wherever this is kept on the
1433  * running system). If it is not found, assume the device is not mounted and
1434  * return 0 and set *@mnt_flags to zero.
1435  *
1436  * If the device @file is found, set the NTFS_MF_MOUNTED flags in *@mnt_flags.
1437  *
1438  * Further if @file is mounted as the file system root ("/"), set the flag
1439  * NTFS_MF_ISROOT in *@mnt_flags.
1440  *
1441  * Finally, check if the file system is mounted read-only, and if so set the
1442  * NTFS_MF_READONLY flag in *@mnt_flags.
1443  *
1444  * On success return 0 with *@mnt_flags set to the ntfs mount flags.
1445  *
1446  * On error return -1 with errno set to the error code.
1447  */
1448 int ntfs_check_if_mounted(const char *file __attribute__((unused)),
1449 		unsigned long *mnt_flags)
1450 {
1451 	*mnt_flags = 0;
1452 #ifdef HAVE_MNTENT_H
1453 	return ntfs_mntent_check(file, mnt_flags);
1454 #else
1455 	return 0;
1456 #endif
1457 }
1458 
1459 /**
1460  * ntfs_version_is_supported - check if NTFS version is supported.
1461  * @vol:	ntfs volume whose version we're interested in.
1462  *
1463  * The function checks if the NTFS volume version is known or not.
1464  * Version 1.1 and 1.2 are used by Windows NT3.x and NT4.
1465  * Version 2.x is used by Windows 2000 Betas.
1466  * Version 3.0 is used by Windows 2000.
1467  * Version 3.1 is used by Windows XP, Windows Server 2003 and Longhorn.
1468  *
1469  * Return 0 if NTFS version is supported otherwise -1 with errno set.
1470  *
1471  * The following error codes are defined:
1472  *	EOPNOTSUPP - Unknown NTFS version
1473  *	EINVAL	   - Invalid argument
1474  */
1475 int ntfs_version_is_supported(ntfs_volume *vol)
1476 {
1477 	u8 major, minor;
1478 
1479 	if (!vol) {
1480 		errno = EINVAL;
1481 		return -1;
1482 	}
1483 
1484 	major = vol->major_ver;
1485 	minor = vol->minor_ver;
1486 
1487 	if (NTFS_V1_1(major, minor) || NTFS_V1_2(major, minor))
1488 		return 0;
1489 
1490 	if (NTFS_V2_X(major, minor))
1491 		return 0;
1492 
1493 	if (NTFS_V3_0(major, minor) || NTFS_V3_1(major, minor))
1494 		return 0;
1495 
1496 	errno = EOPNOTSUPP;
1497 	return -1;
1498 }
1499 
1500 /**
1501  * ntfs_logfile_reset - "empty" $LogFile data attribute value
1502  * @vol:	ntfs volume whose $LogFile we intend to reset.
1503  *
1504  * Fill the value of the $LogFile data attribute, i.e. the contents of
1505  * the file, with 0xff's, thus marking the journal as empty.
1506  *
1507  * FIXME(?): We might need to zero the LSN field of every single mft
1508  * record as well. (But, first try without doing that and see what
1509  * happens, since chkdsk might pickup the pieces and do it for us...)
1510  *
1511  * On success return 0.
1512  *
1513  * On error return -1 with errno set to the error code.
1514  */
1515 int ntfs_logfile_reset(ntfs_volume *vol)
1516 {
1517 	ntfs_inode *ni;
1518 	ntfs_attr *na;
1519 	int eo;
1520 
1521 	if (!vol) {
1522 		errno = EINVAL;
1523 		return -1;
1524 	}
1525 
1526 	ni = ntfs_inode_open(vol, FILE_LogFile);
1527 	if (!ni) {
1528 		ntfs_log_perror("Failed to open inode FILE_LogFile");
1529 		return -1;
1530 	}
1531 
1532 	na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
1533 	if (!na) {
1534 		eo = errno;
1535 		ntfs_log_perror("Failed to open $FILE_LogFile/$DATA");
1536 		goto error_exit;
1537 	}
1538 
1539 	if (ntfs_empty_logfile(na)) {
1540 		eo = errno;
1541 		ntfs_attr_close(na);
1542 		goto error_exit;
1543 	}
1544 
1545 	ntfs_attr_close(na);
1546 	return ntfs_inode_close(ni);
1547 
1548 error_exit:
1549 	ntfs_inode_close(ni);
1550 	errno = eo;
1551 	return -1;
1552 }
1553 
1554 /**
1555  * ntfs_volume_write_flags - set the flags of an ntfs volume
1556  * @vol:	ntfs volume where we set the volume flags
1557  * @flags:	new flags
1558  *
1559  * Set the on-disk volume flags in the mft record of $Volume and
1560  * on volume @vol to @flags.
1561  *
1562  * Return 0 if successful and -1 if not with errno set to the error code.
1563  */
1564 int ntfs_volume_write_flags(ntfs_volume *vol, const le16 flags)
1565 {
1566 	ATTR_RECORD *a;
1567 	VOLUME_INFORMATION *c;
1568 	ntfs_attr_search_ctx *ctx;
1569 	int ret = -1;	/* failure */
1570 
1571 	if (!vol || !vol->vol_ni) {
1572 		errno = EINVAL;
1573 		return -1;
1574 	}
1575 	/* Get a pointer to the volume information attribute. */
1576 	ctx = ntfs_attr_get_search_ctx(vol->vol_ni, NULL);
1577 	if (!ctx)
1578 		return -1;
1579 
1580 	if (ntfs_attr_lookup(AT_VOLUME_INFORMATION, AT_UNNAMED, 0, 0, 0, NULL,
1581 			0, ctx)) {
1582 		ntfs_log_error("Attribute $VOLUME_INFORMATION was not found "
1583 			       "in $Volume!\n");
1584 		goto err_out;
1585 	}
1586 	a = ctx->attr;
1587 	/* Sanity check. */
1588 	if (a->non_resident) {
1589 		ntfs_log_error("Attribute $VOLUME_INFORMATION must be resident "
1590 			       "but it isn't.\n");
1591 		errno = EIO;
1592 		goto err_out;
1593 	}
1594 	/* Get a pointer to the value of the attribute. */
1595 	c = (VOLUME_INFORMATION*)(le16_to_cpu(a->value_offset) + (char*)a);
1596 	/* Sanity checks. */
1597 	if ((char*)c + le32_to_cpu(a->value_length) > (char*)ctx->mrec +
1598 			le32_to_cpu(ctx->mrec->bytes_in_use) ||
1599 			le16_to_cpu(a->value_offset) +
1600 			le32_to_cpu(a->value_length) > le32_to_cpu(a->length)) {
1601 		ntfs_log_error("Attribute $VOLUME_INFORMATION in $Volume is "
1602 			       "corrupt!\n");
1603 		errno = EIO;
1604 		goto err_out;
1605 	}
1606 	/* Set the volume flags. */
1607 	vol->flags = c->flags = flags & VOLUME_FLAGS_MASK;
1608 	/* Write them to disk. */
1609 	ntfs_inode_mark_dirty(vol->vol_ni);
1610 	if (ntfs_inode_sync(vol->vol_ni))
1611 		goto err_out;
1612 
1613 	ret = 0; /* success */
1614 err_out:
1615 	ntfs_attr_put_search_ctx(ctx);
1616 	return ret;
1617 }
1618 
1619 int ntfs_volume_error(int err)
1620 {
1621 	int ret;
1622 
1623 	switch (err) {
1624 		case 0:
1625 			ret = NTFS_VOLUME_OK;
1626 			break;
1627 		case EINVAL:
1628 			ret = NTFS_VOLUME_NOT_NTFS;
1629 			break;
1630 		case EIO:
1631 			ret = NTFS_VOLUME_CORRUPT;
1632 			break;
1633 		case EPERM:
1634 			ret = NTFS_VOLUME_HIBERNATED;
1635 			break;
1636 		case EOPNOTSUPP:
1637 			ret = NTFS_VOLUME_UNCLEAN_UNMOUNT;
1638 			break;
1639 		case EBUSY:
1640 			ret = NTFS_VOLUME_LOCKED;
1641 			break;
1642 		case ENXIO:
1643 			ret = NTFS_VOLUME_RAID;
1644 			break;
1645 		case EACCES:
1646 			ret = NTFS_VOLUME_NO_PRIVILEGE;
1647 			break;
1648 		default:
1649 			ret = NTFS_VOLUME_UNKNOWN_REASON;
1650 			break;
1651 	}
1652 	return ret;
1653 }
1654 
1655 
1656 void ntfs_mount_error(const char *volume, const char *mntpoint, int err)
1657 {
1658 	switch (err) {
1659 		case NTFS_VOLUME_NOT_NTFS:
1660 			ntfs_log_error(invalid_ntfs_msg, volume);
1661 			break;
1662 		case NTFS_VOLUME_CORRUPT:
1663 			ntfs_log_error("%s", corrupt_volume_msg);
1664 			break;
1665 		case NTFS_VOLUME_HIBERNATED:
1666 			ntfs_log_error(hibernated_volume_msg, volume, mntpoint);
1667 			break;
1668 		case NTFS_VOLUME_UNCLEAN_UNMOUNT:
1669 			ntfs_log_error("%s", unclean_journal_msg);
1670 			break;
1671 		case NTFS_VOLUME_LOCKED:
1672 			ntfs_log_error("%s", opened_volume_msg);
1673 			break;
1674 		case NTFS_VOLUME_RAID:
1675 			ntfs_log_error("%s", fakeraid_msg);
1676 			break;
1677 		case NTFS_VOLUME_NO_PRIVILEGE:
1678 			ntfs_log_error(access_denied_msg, volume);
1679 			break;
1680 	}
1681 }
1682 
1683 int ntfs_set_locale(void)
1684 {
1685 #ifndef __HAIKU__
1686 	const char *locale;
1687 
1688 	locale = setlocale(LC_ALL, "");
1689 	if (!locale) {
1690 		locale = setlocale(LC_ALL, NULL);
1691 		ntfs_log_error("Couldn't set local environment, using default "
1692 			       "'%s'.\n", locale);
1693 		return 1;
1694 	}
1695 #endif
1696 	return 0;
1697 }
1698 
1699 /*
1700  *		Feed the counts of free clusters and free mft records
1701  */
1702 
1703 int ntfs_volume_get_free_space(ntfs_volume *vol)
1704 {
1705 	ntfs_attr *na;
1706 	int ret;
1707 
1708 	ret = -1; /* default return */
1709 	vol->free_clusters = ntfs_attr_get_free_bits(vol->lcnbmp_na);
1710 	if (vol->free_clusters < 0) {
1711 		ntfs_log_perror("Failed to read NTFS $Bitmap");
1712 	} else {
1713 		na = vol->mftbmp_na;
1714 		vol->free_mft_records = ntfs_attr_get_free_bits(na);
1715 
1716 		if (vol->free_mft_records >= 0)
1717 			vol->free_mft_records += (na->allocated_size - na->data_size) << 3;
1718 
1719 		if (vol->free_mft_records < 0)
1720 			ntfs_log_perror("Failed to calculate free MFT records");
1721 		else
1722 			ret = 0;
1723 	}
1724 	return (ret);
1725 }
1726