Allow IPv6 address entry in tools>ping - Loosens valid character check
[tomato/davidwu.git] / release / src / router / ntfs-3g / libntfs-3g / volume.c
blob5bb266ffcfe4772fd4211b177d216fa6bbdc3ff3
1 /**
2 * volume.c - NTFS volume handling code. Originated from the Linux-NTFS project.
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
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.
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.
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
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
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
57 #if defined(__sun) && defined (__SVR4)
58 #include <sys/mnttab.h>
59 #endif
61 #include "param.h"
62 #include "compat.h"
63 #include "volume.h"
64 #include "attrib.h"
65 #include "mft.h"
66 #include "bootsect.h"
67 #include "device.h"
68 #include "debug.h"
69 #include "inode.h"
70 #include "runlist.h"
71 #include "logfile.h"
72 #include "dir.h"
73 #include "logging.h"
74 #include "cache.h"
75 #include "realpath.h"
76 #include "misc.h"
78 const char *ntfs_home =
79 "News, support and information: http://tuxera.com\n";
81 static const char *invalid_ntfs_msg =
82 "The device '%s' doesn't seem to have a valid NTFS.\n"
83 "Maybe the wrong device is used? Or the whole disk instead of a\n"
84 "partition (e.g. /dev/sda, not /dev/sda1)? Or the other way around?\n";
86 static const char *corrupt_volume_msg =
87 "NTFS is either inconsistent, or there is a hardware fault, or it's a\n"
88 "SoftRAID/FakeRAID hardware. In the first case run chkdsk /f on Windows\n"
89 "then reboot into Windows twice. The usage of the /f parameter is very\n"
90 "important! If the device is a SoftRAID/FakeRAID then first activate\n"
91 "it and mount a different device under the /dev/mapper/ directory, (e.g.\n"
92 "/dev/mapper/nvidia_eahaabcc1). Please see the 'dmraid' documentation\n"
93 "for more details.\n";
95 static const char *hibernated_volume_msg =
96 "The NTFS partition is in an unsafe state. Please resume and shutdown\n"
97 "Windows fully (no hibernation or fast restarting), or mount the volume\n"
98 "read-only with the 'ro' mount option.\n";
100 static const char *unclean_journal_msg =
101 "Write access is denied because the disk wasn't safely powered\n"
102 "off and the 'norecover' mount option was specified.\n";
104 static const char *opened_volume_msg =
105 "Mount is denied because the NTFS volume is already exclusively opened.\n"
106 "The volume may be already mounted, or another software may use it which\n"
107 "could be identified for example by the help of the 'fuser' command.\n";
109 static const char *fakeraid_msg =
110 "Either the device is missing or it's powered down, or you have\n"
111 "SoftRAID hardware and must use an activated, different device under\n"
112 "/dev/mapper/, (e.g. /dev/mapper/nvidia_eahaabcc1) to mount NTFS.\n"
113 "Please see the 'dmraid' documentation for help.\n";
115 static const char *access_denied_msg =
116 "Please check '%s' and the ntfs-3g binary permissions,\n"
117 "and the mounting user ID. More explanation is provided at\n"
118 "http://tuxera.com/community/ntfs-3g-faq/#unprivileged\n";
121 * ntfs_volume_alloc - Create an NTFS volume object and initialise it
123 * Description...
125 * Returns:
127 ntfs_volume *ntfs_volume_alloc(void)
129 return ntfs_calloc(sizeof(ntfs_volume));
132 static void ntfs_attr_free(ntfs_attr **na)
134 if (na && *na) {
135 ntfs_attr_close(*na);
136 *na = NULL;
140 static int ntfs_inode_free(ntfs_inode **ni)
142 int ret = -1;
144 if (ni && *ni) {
145 ret = ntfs_inode_close(*ni);
146 *ni = NULL;
149 return ret;
152 static void ntfs_error_set(int *err)
154 if (!*err)
155 *err = errno;
159 * __ntfs_volume_release - Destroy an NTFS volume object
160 * @v:
162 * Description...
164 * Returns:
166 static int __ntfs_volume_release(ntfs_volume *v)
168 int err = 0;
170 if (ntfs_inode_free(&v->vol_ni))
171 ntfs_error_set(&err);
173 * FIXME: Inodes must be synced before closing
174 * attributes, otherwise unmount could fail.
176 if (v->lcnbmp_ni && NInoDirty(v->lcnbmp_ni))
177 ntfs_inode_sync(v->lcnbmp_ni);
178 ntfs_attr_free(&v->lcnbmp_na);
179 if (ntfs_inode_free(&v->lcnbmp_ni))
180 ntfs_error_set(&err);
182 if (v->mft_ni && NInoDirty(v->mft_ni))
183 ntfs_inode_sync(v->mft_ni);
184 ntfs_attr_free(&v->mftbmp_na);
185 ntfs_attr_free(&v->mft_na);
186 if (ntfs_inode_free(&v->mft_ni))
187 ntfs_error_set(&err);
189 if (v->mftmirr_ni && NInoDirty(v->mftmirr_ni))
190 ntfs_inode_sync(v->mftmirr_ni);
191 ntfs_attr_free(&v->mftmirr_na);
192 if (ntfs_inode_free(&v->mftmirr_ni))
193 ntfs_error_set(&err);
195 if (v->dev) {
196 struct ntfs_device *dev = v->dev;
198 if (dev->d_ops->sync(dev))
199 ntfs_error_set(&err);
200 if (dev->d_ops->close(dev))
201 ntfs_error_set(&err);
204 ntfs_free_lru_caches(v);
205 free(v->vol_name);
206 free(v->upcase);
207 if (v->locase) free(v->locase);
208 free(v->attrdef);
209 free(v);
211 errno = err;
212 return errno ? -1 : 0;
215 static void ntfs_attr_setup_flag(ntfs_inode *ni)
217 STANDARD_INFORMATION *si;
219 si = ntfs_attr_readall(ni, AT_STANDARD_INFORMATION, AT_UNNAMED, 0, NULL);
220 if (si) {
221 ni->flags = si->file_attributes;
222 free(si);
227 * ntfs_mft_load - load the $MFT and setup the ntfs volume with it
228 * @vol: ntfs volume whose $MFT to load
230 * Load $MFT from @vol and setup @vol with it. After calling this function the
231 * volume @vol is ready for use by all read access functions provided by the
232 * ntfs library.
234 * Return 0 on success and -1 on error with errno set to the error code.
236 static int ntfs_mft_load(ntfs_volume *vol)
238 VCN next_vcn, last_vcn, highest_vcn;
239 s64 l;
240 MFT_RECORD *mb = NULL;
241 ntfs_attr_search_ctx *ctx = NULL;
242 ATTR_RECORD *a;
243 int eo;
245 /* Manually setup an ntfs_inode. */
246 vol->mft_ni = ntfs_inode_allocate(vol);
247 mb = ntfs_malloc(vol->mft_record_size);
248 if (!vol->mft_ni || !mb) {
249 ntfs_log_perror("Error allocating memory for $MFT");
250 goto error_exit;
252 vol->mft_ni->mft_no = 0;
253 vol->mft_ni->mrec = mb;
254 /* Can't use any of the higher level functions yet! */
255 l = ntfs_mst_pread(vol->dev, vol->mft_lcn << vol->cluster_size_bits, 1,
256 vol->mft_record_size, mb);
257 if (l != 1) {
258 if (l != -1)
259 errno = EIO;
260 ntfs_log_perror("Error reading $MFT");
261 goto error_exit;
264 if (ntfs_mft_record_check(vol, 0, mb))
265 goto error_exit;
267 ctx = ntfs_attr_get_search_ctx(vol->mft_ni, NULL);
268 if (!ctx)
269 goto error_exit;
271 /* Find the $ATTRIBUTE_LIST attribute in $MFT if present. */
272 if (ntfs_attr_lookup(AT_ATTRIBUTE_LIST, AT_UNNAMED, 0, 0, 0, NULL, 0,
273 ctx)) {
274 if (errno != ENOENT) {
275 ntfs_log_error("$MFT has corrupt attribute list.\n");
276 goto io_error_exit;
278 goto mft_has_no_attr_list;
280 NInoSetAttrList(vol->mft_ni);
281 l = ntfs_get_attribute_value_length(ctx->attr);
282 if (l <= 0 || l > 0x40000) {
283 ntfs_log_error("$MFT/$ATTR_LIST invalid length (%lld).\n",
284 (long long)l);
285 goto io_error_exit;
287 vol->mft_ni->attr_list_size = l;
288 vol->mft_ni->attr_list = ntfs_malloc(l);
289 if (!vol->mft_ni->attr_list)
290 goto error_exit;
292 l = ntfs_get_attribute_value(vol, ctx->attr, vol->mft_ni->attr_list);
293 if (!l) {
294 ntfs_log_error("Failed to get value of $MFT/$ATTR_LIST.\n");
295 goto io_error_exit;
297 if (l != vol->mft_ni->attr_list_size) {
298 ntfs_log_error("Partial read of $MFT/$ATTR_LIST (%lld != "
299 "%u).\n", (long long)l,
300 vol->mft_ni->attr_list_size);
301 goto io_error_exit;
304 mft_has_no_attr_list:
306 ntfs_attr_setup_flag(vol->mft_ni);
308 /* We now have a fully setup ntfs inode for $MFT in vol->mft_ni. */
310 /* Get an ntfs attribute for $MFT/$DATA and set it up, too. */
311 vol->mft_na = ntfs_attr_open(vol->mft_ni, AT_DATA, AT_UNNAMED, 0);
312 if (!vol->mft_na) {
313 ntfs_log_perror("Failed to open ntfs attribute");
314 goto error_exit;
316 /* Read all extents from the $DATA attribute in $MFT. */
317 ntfs_attr_reinit_search_ctx(ctx);
318 last_vcn = vol->mft_na->allocated_size >> vol->cluster_size_bits;
319 highest_vcn = next_vcn = 0;
320 a = NULL;
321 while (!ntfs_attr_lookup(AT_DATA, AT_UNNAMED, 0, 0, next_vcn, NULL, 0,
322 ctx)) {
323 runlist_element *nrl;
325 a = ctx->attr;
326 /* $MFT must be non-resident. */
327 if (!a->non_resident) {
328 ntfs_log_error("$MFT must be non-resident.\n");
329 goto io_error_exit;
331 /* $MFT must be uncompressed and unencrypted. */
332 if (a->flags & ATTR_COMPRESSION_MASK ||
333 a->flags & ATTR_IS_ENCRYPTED) {
334 ntfs_log_error("$MFT must be uncompressed and "
335 "unencrypted.\n");
336 goto io_error_exit;
339 * Decompress the mapping pairs array of this extent and merge
340 * the result into the existing runlist. No need for locking
341 * as we have exclusive access to the inode at this time and we
342 * are a mount in progress task, too.
344 nrl = ntfs_mapping_pairs_decompress(vol, a, vol->mft_na->rl);
345 if (!nrl) {
346 ntfs_log_perror("ntfs_mapping_pairs_decompress() failed");
347 goto error_exit;
349 vol->mft_na->rl = nrl;
351 /* Get the lowest vcn for the next extent. */
352 highest_vcn = sle64_to_cpu(a->highest_vcn);
353 next_vcn = highest_vcn + 1;
355 /* Only one extent or error, which we catch below. */
356 if (next_vcn <= 0)
357 break;
359 /* Avoid endless loops due to corruption. */
360 if (next_vcn < sle64_to_cpu(a->lowest_vcn)) {
361 ntfs_log_error("$MFT has corrupt attribute list.\n");
362 goto io_error_exit;
365 if (!a) {
366 ntfs_log_error("$MFT/$DATA attribute not found.\n");
367 goto io_error_exit;
369 if (highest_vcn && highest_vcn != last_vcn - 1) {
370 ntfs_log_error("Failed to load runlist for $MFT/$DATA.\n");
371 ntfs_log_error("highest_vcn = 0x%llx, last_vcn - 1 = 0x%llx\n",
372 (long long)highest_vcn, (long long)last_vcn - 1);
373 goto io_error_exit;
375 /* Done with the $Mft mft record. */
376 ntfs_attr_put_search_ctx(ctx);
377 ctx = NULL;
379 /* Update the size fields in the inode. */
380 vol->mft_ni->data_size = vol->mft_na->data_size;
381 vol->mft_ni->allocated_size = vol->mft_na->allocated_size;
382 set_nino_flag(vol->mft_ni, KnownSize);
385 * The volume is now setup so we can use all read access functions.
387 vol->mftbmp_na = ntfs_attr_open(vol->mft_ni, AT_BITMAP, AT_UNNAMED, 0);
388 if (!vol->mftbmp_na) {
389 ntfs_log_perror("Failed to open $MFT/$BITMAP");
390 goto error_exit;
392 return 0;
393 io_error_exit:
394 errno = EIO;
395 error_exit:
396 eo = errno;
397 if (ctx)
398 ntfs_attr_put_search_ctx(ctx);
399 if (vol->mft_na) {
400 ntfs_attr_close(vol->mft_na);
401 vol->mft_na = NULL;
403 if (vol->mft_ni) {
404 ntfs_inode_close(vol->mft_ni);
405 vol->mft_ni = NULL;
407 errno = eo;
408 return -1;
412 * ntfs_mftmirr_load - load the $MFTMirr and setup the ntfs volume with it
413 * @vol: ntfs volume whose $MFTMirr to load
415 * Load $MFTMirr from @vol and setup @vol with it. After calling this function
416 * the volume @vol is ready for use by all write access functions provided by
417 * the ntfs library (assuming ntfs_mft_load() has been called successfully
418 * beforehand).
420 * Return 0 on success and -1 on error with errno set to the error code.
422 static int ntfs_mftmirr_load(ntfs_volume *vol)
424 int err;
426 vol->mftmirr_ni = ntfs_inode_open(vol, FILE_MFTMirr);
427 if (!vol->mftmirr_ni) {
428 ntfs_log_perror("Failed to open inode $MFTMirr");
429 return -1;
432 vol->mftmirr_na = ntfs_attr_open(vol->mftmirr_ni, AT_DATA, AT_UNNAMED, 0);
433 if (!vol->mftmirr_na) {
434 ntfs_log_perror("Failed to open $MFTMirr/$DATA");
435 goto error_exit;
438 if (ntfs_attr_map_runlist(vol->mftmirr_na, 0) < 0) {
439 ntfs_log_perror("Failed to map runlist of $MFTMirr/$DATA");
440 goto error_exit;
443 return 0;
445 error_exit:
446 err = errno;
447 if (vol->mftmirr_na) {
448 ntfs_attr_close(vol->mftmirr_na);
449 vol->mftmirr_na = NULL;
451 ntfs_inode_close(vol->mftmirr_ni);
452 vol->mftmirr_ni = NULL;
453 errno = err;
454 return -1;
458 * ntfs_volume_startup - allocate and setup an ntfs volume
459 * @dev: device to open
460 * @flags: optional mount flags
462 * Load, verify, and parse bootsector; load and setup $MFT and $MFTMirr. After
463 * calling this function, the volume is setup sufficiently to call all read
464 * and write access functions provided by the library.
466 * Return the allocated volume structure on success and NULL on error with
467 * errno set to the error code.
469 ntfs_volume *ntfs_volume_startup(struct ntfs_device *dev,
470 ntfs_mount_flags flags)
472 LCN mft_zone_size, mft_lcn;
473 s64 br;
474 ntfs_volume *vol;
475 NTFS_BOOT_SECTOR *bs;
476 int eo;
478 if (!dev || !dev->d_ops || !dev->d_name) {
479 errno = EINVAL;
480 ntfs_log_perror("%s: dev = %p", __FUNCTION__, dev);
481 return NULL;
484 bs = ntfs_malloc(sizeof(NTFS_BOOT_SECTOR));
485 if (!bs)
486 return NULL;
488 /* Allocate the volume structure. */
489 vol = ntfs_volume_alloc();
490 if (!vol)
491 goto error_exit;
493 /* Create the default upcase table. */
494 vol->upcase_len = ntfs_upcase_build_default(&vol->upcase);
495 if (!vol->upcase_len || !vol->upcase)
496 goto error_exit;
498 /* Default with no locase table and case sensitive file names */
499 vol->locase = (ntfschar*)NULL;
500 NVolSetCaseSensitive(vol);
502 /* by default, all files are shown and not marked hidden */
503 NVolSetShowSysFiles(vol);
504 NVolSetShowHidFiles(vol);
505 NVolClearHideDotFiles(vol);
506 /* set default compression */
507 #if DEFAULT_COMPRESSION
508 NVolSetCompression(vol);
509 #else
510 NVolClearCompression(vol);
511 #endif
512 if (flags & NTFS_MNT_RDONLY)
513 NVolSetReadOnly(vol);
515 /* ...->open needs bracketing to compile with glibc 2.7 */
516 if ((dev->d_ops->open)(dev, NVolReadOnly(vol) ? O_RDONLY: O_RDWR)) {
517 if (!NVolReadOnly(vol) && (errno == EROFS)) {
518 if ((dev->d_ops->open)(dev, O_RDONLY)) {
519 ntfs_log_perror("Error opening read-only '%s'",
520 dev->d_name);
521 goto error_exit;
522 } else {
523 ntfs_log_info("Can only open '%s' as read-only\n",
524 dev->d_name);
525 NVolSetReadOnly(vol);
527 } else {
528 ntfs_log_perror("Error opening '%s'", dev->d_name);
529 goto error_exit;
532 /* Attach the device to the volume. */
533 vol->dev = dev;
535 /* Now read the bootsector. */
536 br = ntfs_pread(dev, 0, sizeof(NTFS_BOOT_SECTOR), bs);
537 if (br != sizeof(NTFS_BOOT_SECTOR)) {
538 if (br != -1)
539 errno = EINVAL;
540 if (!br)
541 ntfs_log_error("Failed to read bootsector (size=0)\n");
542 else
543 ntfs_log_perror("Error reading bootsector");
544 goto error_exit;
546 if (!ntfs_boot_sector_is_ntfs(bs)) {
547 errno = EINVAL;
548 goto error_exit;
550 if (ntfs_boot_sector_parse(vol, bs) < 0)
551 goto error_exit;
553 free(bs);
554 bs = NULL;
555 /* Now set the device block size to the sector size. */
556 if (ntfs_device_block_size_set(vol->dev, vol->sector_size))
557 ntfs_log_debug("Failed to set the device block size to the "
558 "sector size. This may affect performance "
559 "but should be harmless otherwise. Error: "
560 "%s\n", strerror(errno));
562 /* We now initialize the cluster allocator. */
563 vol->full_zones = 0;
564 mft_zone_size = vol->nr_clusters >> 3; /* 12.5% */
566 /* Setup the mft zone. */
567 vol->mft_zone_start = vol->mft_zone_pos = vol->mft_lcn;
568 ntfs_log_debug("mft_zone_pos = 0x%llx\n", (long long)vol->mft_zone_pos);
571 * Calculate the mft_lcn for an unmodified NTFS volume (see mkntfs
572 * source) and if the actual mft_lcn is in the expected place or even
573 * further to the front of the volume, extend the mft_zone to cover the
574 * beginning of the volume as well. This is in order to protect the
575 * area reserved for the mft bitmap as well within the mft_zone itself.
576 * On non-standard volumes we don't protect it as the overhead would be
577 * higher than the speed increase we would get by doing it.
579 mft_lcn = (8192 + 2 * vol->cluster_size - 1) / vol->cluster_size;
580 if (mft_lcn * vol->cluster_size < 16 * 1024)
581 mft_lcn = (16 * 1024 + vol->cluster_size - 1) /
582 vol->cluster_size;
583 if (vol->mft_zone_start <= mft_lcn)
584 vol->mft_zone_start = 0;
585 ntfs_log_debug("mft_zone_start = 0x%llx\n", (long long)vol->mft_zone_start);
588 * Need to cap the mft zone on non-standard volumes so that it does
589 * not point outside the boundaries of the volume. We do this by
590 * halving the zone size until we are inside the volume.
592 vol->mft_zone_end = vol->mft_lcn + mft_zone_size;
593 while (vol->mft_zone_end >= vol->nr_clusters) {
594 mft_zone_size >>= 1;
595 vol->mft_zone_end = vol->mft_lcn + mft_zone_size;
597 ntfs_log_debug("mft_zone_end = 0x%llx\n", (long long)vol->mft_zone_end);
600 * Set the current position within each data zone to the start of the
601 * respective zone.
603 vol->data1_zone_pos = vol->mft_zone_end;
604 ntfs_log_debug("data1_zone_pos = %lld\n", (long long)vol->data1_zone_pos);
605 vol->data2_zone_pos = 0;
606 ntfs_log_debug("data2_zone_pos = %lld\n", (long long)vol->data2_zone_pos);
608 /* Set the mft data allocation position to mft record 24. */
609 vol->mft_data_pos = 24;
612 * The cluster allocator is now fully operational.
615 /* Need to setup $MFT so we can use the library read functions. */
616 if (ntfs_mft_load(vol) < 0) {
617 ntfs_log_perror("Failed to load $MFT");
618 goto error_exit;
621 /* Need to setup $MFTMirr so we can use the write functions, too. */
622 if (ntfs_mftmirr_load(vol) < 0) {
623 ntfs_log_perror("Failed to load $MFTMirr");
624 goto error_exit;
626 return vol;
627 error_exit:
628 eo = errno;
629 free(bs);
630 if (vol)
631 __ntfs_volume_release(vol);
632 errno = eo;
633 return NULL;
637 * ntfs_volume_check_logfile - check logfile on target volume
638 * @vol: volume on which to check logfile
640 * Return 0 on success and -1 on error with errno set error code.
642 static int ntfs_volume_check_logfile(ntfs_volume *vol)
644 ntfs_inode *ni;
645 ntfs_attr *na = NULL;
646 RESTART_PAGE_HEADER *rp = NULL;
647 int err = 0;
649 ni = ntfs_inode_open(vol, FILE_LogFile);
650 if (!ni) {
651 ntfs_log_perror("Failed to open inode FILE_LogFile");
652 errno = EIO;
653 return -1;
656 na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
657 if (!na) {
658 ntfs_log_perror("Failed to open $FILE_LogFile/$DATA");
659 err = EIO;
660 goto out;
663 if (!ntfs_check_logfile(na, &rp) || !ntfs_is_logfile_clean(na, rp))
664 err = EOPNOTSUPP;
666 * If the latest restart page was identified as version
667 * 2.0, then Windows may have kept a cached copy of
668 * metadata for fast restarting, and we should not mount.
669 * Hibernation will be seen the same way on a non
670 * Windows-system partition, so we have to use the same
671 * error code (EPERM).
672 * The restart page may also be identified as version 2.0
673 * when access to the file system is terminated abruptly
674 * by unplugging or power cut, so mounting is also rejected
675 * after such an event.
677 if (rp
678 && (rp->major_ver == const_cpu_to_le16(2))
679 && (rp->minor_ver == const_cpu_to_le16(0))) {
680 ntfs_log_error("Metadata kept in Windows cache, refused to mount.\n");
681 err = EPERM;
683 free(rp);
684 ntfs_attr_close(na);
685 out:
686 if (ntfs_inode_close(ni))
687 ntfs_error_set(&err);
688 if (err) {
689 errno = err;
690 return -1;
692 return 0;
696 * ntfs_hiberfile_open - Find and open '/hiberfil.sys'
697 * @vol: An ntfs volume obtained from ntfs_mount
699 * Return: inode Success, hiberfil.sys is valid
700 * NULL hiberfil.sys doesn't exist or some other error occurred
702 static ntfs_inode *ntfs_hiberfile_open(ntfs_volume *vol)
704 u64 inode;
705 ntfs_inode *ni_root;
706 ntfs_inode *ni_hibr = NULL;
707 ntfschar *unicode = NULL;
708 int unicode_len;
709 const char *hiberfile = "hiberfil.sys";
711 if (!vol) {
712 errno = EINVAL;
713 return NULL;
716 ni_root = ntfs_inode_open(vol, FILE_root);
717 if (!ni_root) {
718 ntfs_log_debug("Couldn't open the root directory.\n");
719 return NULL;
722 unicode_len = ntfs_mbstoucs(hiberfile, &unicode);
723 if (unicode_len < 0) {
724 ntfs_log_perror("Couldn't convert 'hiberfil.sys' to Unicode");
725 goto out;
728 inode = ntfs_inode_lookup_by_name(ni_root, unicode, unicode_len);
729 if (inode == (u64)-1) {
730 ntfs_log_debug("Couldn't find file '%s'.\n", hiberfile);
731 goto out;
734 inode = MREF(inode);
735 ni_hibr = ntfs_inode_open(vol, inode);
736 if (!ni_hibr) {
737 ntfs_log_debug("Couldn't open inode %lld.\n", (long long)inode);
738 goto out;
740 out:
741 if (ntfs_inode_close(ni_root)) {
742 ntfs_inode_close(ni_hibr);
743 ni_hibr = NULL;
745 free(unicode);
746 return ni_hibr;
750 #define NTFS_HIBERFILE_HEADER_SIZE 4096
753 * ntfs_volume_check_hiberfile - check hiberfil.sys whether Windows is
754 * hibernated on the target volume
755 * @vol: volume on which to check hiberfil.sys
757 * Return: 0 if Windows isn't hibernated for sure
758 * -1 otherwise and errno is set to the appropriate value
760 int ntfs_volume_check_hiberfile(ntfs_volume *vol, int verbose)
762 ntfs_inode *ni;
763 ntfs_attr *na = NULL;
764 int bytes_read, err;
765 char *buf = NULL;
767 ni = ntfs_hiberfile_open(vol);
768 if (!ni) {
769 if (errno == ENOENT)
770 return 0;
771 return -1;
774 buf = ntfs_malloc(NTFS_HIBERFILE_HEADER_SIZE);
775 if (!buf)
776 goto out;
778 na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
779 if (!na) {
780 ntfs_log_perror("Failed to open hiberfil.sys data attribute");
781 goto out;
784 bytes_read = ntfs_attr_pread(na, 0, NTFS_HIBERFILE_HEADER_SIZE, buf);
785 if (bytes_read == -1) {
786 ntfs_log_perror("Failed to read hiberfil.sys");
787 goto out;
789 if (bytes_read < NTFS_HIBERFILE_HEADER_SIZE) {
790 if (verbose)
791 ntfs_log_error("Hibernated non-system partition, "
792 "refused to mount.\n");
793 errno = EPERM;
794 goto out;
796 if ((memcmp(buf, "hibr", 4) == 0)
797 || (memcmp(buf, "HIBR", 4) == 0)) {
798 if (verbose)
799 ntfs_log_error("Windows is hibernated, refused to mount.\n");
800 errno = EPERM;
801 goto out;
803 /* All right, all header bytes are zero */
804 errno = 0;
805 out:
806 if (na)
807 ntfs_attr_close(na);
808 free(buf);
809 err = errno;
810 if (ntfs_inode_close(ni))
811 ntfs_error_set(&err);
812 errno = err;
813 return errno ? -1 : 0;
817 * Make sure a LOGGED_UTILITY_STREAM attribute named "$TXF_DATA"
818 * on the root directory is resident.
819 * When it is non-resident, the partition cannot be mounted on Vista
820 * (see http://support.microsoft.com/kb/974729)
822 * We take care to avoid this situation, however this can be a
823 * consequence of having used an older version (including older
824 * Windows version), so we had better fix it.
826 * Returns 0 if unneeded or successful
827 * -1 if there was an error, explained by errno
830 static int fix_txf_data(ntfs_volume *vol)
832 void *txf_data;
833 s64 txf_data_size;
834 ntfs_inode *ni;
835 ntfs_attr *na;
836 int res;
838 res = 0;
839 ntfs_log_debug("Loading root directory\n");
840 ni = ntfs_inode_open(vol, FILE_root);
841 if (!ni) {
842 ntfs_log_perror("Failed to open root directory");
843 res = -1;
844 } else {
845 /* Get the $TXF_DATA attribute */
846 na = ntfs_attr_open(ni, AT_LOGGED_UTILITY_STREAM, TXF_DATA, 9);
847 if (na) {
848 if (NAttrNonResident(na)) {
850 * Fix the attribute by truncating, then
851 * rewriting it.
853 ntfs_log_debug("Making $TXF_DATA resident\n");
854 txf_data = ntfs_attr_readall(ni,
855 AT_LOGGED_UTILITY_STREAM,
856 TXF_DATA, 9, &txf_data_size);
857 if (txf_data) {
858 if (ntfs_attr_truncate(na, 0)
859 || (ntfs_attr_pwrite(na, 0,
860 txf_data_size, txf_data)
861 != txf_data_size))
862 res = -1;
863 free(txf_data);
865 if (res)
866 ntfs_log_error("Failed to make $TXF_DATA resident\n");
867 else
868 ntfs_log_error("$TXF_DATA made resident\n");
870 ntfs_attr_close(na);
872 if (ntfs_inode_close(ni)) {
873 ntfs_log_perror("Failed to close root");
874 res = -1;
877 return (res);
881 * ntfs_device_mount - open ntfs volume
882 * @dev: device to open
883 * @flags: optional mount flags
885 * This function mounts an ntfs volume. @dev should describe the device which
886 * to mount as the ntfs volume.
888 * @flags is an optional second parameter. The same flags are used as for
889 * the mount system call (man 2 mount). Currently only the following flag
890 * is implemented:
891 * NTFS_MNT_RDONLY - mount volume read-only
893 * The function opens the device @dev and verifies that it contains a valid
894 * bootsector. Then, it allocates an ntfs_volume structure and initializes
895 * some of the values inside the structure from the information stored in the
896 * bootsector. It proceeds to load the necessary system files and completes
897 * setting up the structure.
899 * Return the allocated volume structure on success and NULL on error with
900 * errno set to the error code.
902 ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, ntfs_mount_flags flags)
904 s64 l;
905 ntfs_volume *vol;
906 u8 *m = NULL, *m2 = NULL;
907 ntfs_attr_search_ctx *ctx = NULL;
908 ntfs_inode *ni;
909 ntfs_attr *na;
910 ATTR_RECORD *a;
911 VOLUME_INFORMATION *vinf;
912 ntfschar *vname;
913 int i, j, eo;
914 unsigned int k;
915 u32 u;
917 vol = ntfs_volume_startup(dev, flags);
918 if (!vol)
919 return NULL;
921 /* Load data from $MFT and $MFTMirr and compare the contents. */
922 m = ntfs_malloc(vol->mftmirr_size << vol->mft_record_size_bits);
923 m2 = ntfs_malloc(vol->mftmirr_size << vol->mft_record_size_bits);
924 if (!m || !m2)
925 goto error_exit;
927 l = ntfs_attr_mst_pread(vol->mft_na, 0, vol->mftmirr_size,
928 vol->mft_record_size, m);
929 if (l != vol->mftmirr_size) {
930 if (l == -1)
931 ntfs_log_perror("Failed to read $MFT");
932 else {
933 ntfs_log_error("Failed to read $MFT, unexpected length "
934 "(%lld != %d).\n", (long long)l,
935 vol->mftmirr_size);
936 errno = EIO;
938 goto error_exit;
940 l = ntfs_attr_mst_pread(vol->mftmirr_na, 0, vol->mftmirr_size,
941 vol->mft_record_size, m2);
942 if (l != vol->mftmirr_size) {
943 if (l == -1) {
944 ntfs_log_perror("Failed to read $MFTMirr");
945 goto error_exit;
947 vol->mftmirr_size = l;
949 ntfs_log_debug("Comparing $MFTMirr to $MFT...\n");
950 for (i = 0; i < vol->mftmirr_size; ++i) {
951 MFT_RECORD *mrec, *mrec2;
952 const char *ESTR[12] = { "$MFT", "$MFTMirr", "$LogFile",
953 "$Volume", "$AttrDef", "root directory", "$Bitmap",
954 "$Boot", "$BadClus", "$Secure", "$UpCase", "$Extend" };
955 const char *s;
957 if (i < 12)
958 s = ESTR[i];
959 else if (i < 16)
960 s = "system file";
961 else
962 s = "mft record";
964 mrec = (MFT_RECORD*)(m + i * vol->mft_record_size);
965 if (mrec->flags & MFT_RECORD_IN_USE) {
966 if (ntfs_is_baad_recordp(mrec)) {
967 ntfs_log_error("$MFT error: Incomplete multi "
968 "sector transfer detected in "
969 "'%s'.\n", s);
970 goto io_error_exit;
972 if (!ntfs_is_mft_recordp(mrec)) {
973 ntfs_log_error("$MFT error: Invalid mft "
974 "record for '%s'.\n", s);
975 goto io_error_exit;
978 mrec2 = (MFT_RECORD*)(m2 + i * vol->mft_record_size);
979 if (mrec2->flags & MFT_RECORD_IN_USE) {
980 if (ntfs_is_baad_recordp(mrec2)) {
981 ntfs_log_error("$MFTMirr error: Incomplete "
982 "multi sector transfer "
983 "detected in '%s'.\n", s);
984 goto io_error_exit;
986 if (!ntfs_is_mft_recordp(mrec2)) {
987 ntfs_log_error("$MFTMirr error: Invalid mft "
988 "record for '%s'.\n", s);
989 goto io_error_exit;
992 if (memcmp(mrec, mrec2, ntfs_mft_record_get_data_size(mrec))) {
993 ntfs_log_error("$MFTMirr does not match $MFT (record "
994 "%d).\n", i);
995 goto io_error_exit;
999 free(m2);
1000 free(m);
1001 m = m2 = NULL;
1003 /* Now load the bitmap from $Bitmap. */
1004 ntfs_log_debug("Loading $Bitmap...\n");
1005 vol->lcnbmp_ni = ntfs_inode_open(vol, FILE_Bitmap);
1006 if (!vol->lcnbmp_ni) {
1007 ntfs_log_perror("Failed to open inode FILE_Bitmap");
1008 goto error_exit;
1011 vol->lcnbmp_na = ntfs_attr_open(vol->lcnbmp_ni, AT_DATA, AT_UNNAMED, 0);
1012 if (!vol->lcnbmp_na) {
1013 ntfs_log_perror("Failed to open ntfs attribute");
1014 goto error_exit;
1017 if (vol->lcnbmp_na->data_size > vol->lcnbmp_na->allocated_size) {
1018 ntfs_log_error("Corrupt cluster map size (%lld > %lld)\n",
1019 (long long)vol->lcnbmp_na->data_size,
1020 (long long)vol->lcnbmp_na->allocated_size);
1021 goto io_error_exit;
1024 /* Now load the upcase table from $UpCase. */
1025 ntfs_log_debug("Loading $UpCase...\n");
1026 ni = ntfs_inode_open(vol, FILE_UpCase);
1027 if (!ni) {
1028 ntfs_log_perror("Failed to open inode FILE_UpCase");
1029 goto error_exit;
1031 /* Get an ntfs attribute for $UpCase/$DATA. */
1032 na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
1033 if (!na) {
1034 ntfs_log_perror("Failed to open ntfs attribute");
1035 goto error_exit;
1038 * Note: Normally, the upcase table has a length equal to 65536
1039 * 2-byte Unicode characters but allow for different cases, so no
1040 * checks done. Just check we don't overflow 32-bits worth of Unicode
1041 * characters.
1043 if (na->data_size & ~0x1ffffffffULL) {
1044 ntfs_log_error("Error: Upcase table is too big (max 32-bit "
1045 "allowed).\n");
1046 errno = EINVAL;
1047 goto error_exit;
1049 if (vol->upcase_len != na->data_size >> 1) {
1050 vol->upcase_len = na->data_size >> 1;
1051 /* Throw away default table. */
1052 free(vol->upcase);
1053 vol->upcase = ntfs_malloc(na->data_size);
1054 if (!vol->upcase)
1055 goto error_exit;
1057 /* Read in the $DATA attribute value into the buffer. */
1058 l = ntfs_attr_pread(na, 0, na->data_size, vol->upcase);
1059 if (l != na->data_size) {
1060 ntfs_log_error("Failed to read $UpCase, unexpected length "
1061 "(%lld != %lld).\n", (long long)l,
1062 (long long)na->data_size);
1063 errno = EIO;
1064 goto error_exit;
1066 /* Done with the $UpCase mft record. */
1067 ntfs_attr_close(na);
1068 if (ntfs_inode_close(ni)) {
1069 ntfs_log_perror("Failed to close $UpCase");
1070 goto error_exit;
1072 /* Consistency check of $UpCase, restricted to plain ASCII chars */
1073 k = 0x20;
1074 while ((k < vol->upcase_len)
1075 && (k < 0x7f)
1076 && (le16_to_cpu(vol->upcase[k])
1077 == ((k < 'a') || (k > 'z') ? k : k + 'A' - 'a')))
1078 k++;
1079 if (k < 0x7f) {
1080 ntfs_log_error("Corrupted file $UpCase\n");
1081 goto io_error_exit;
1085 * Now load $Volume and set the version information and flags in the
1086 * vol structure accordingly.
1088 ntfs_log_debug("Loading $Volume...\n");
1089 vol->vol_ni = ntfs_inode_open(vol, FILE_Volume);
1090 if (!vol->vol_ni) {
1091 ntfs_log_perror("Failed to open inode FILE_Volume");
1092 goto error_exit;
1094 /* Get a search context for the $Volume/$VOLUME_INFORMATION lookup. */
1095 ctx = ntfs_attr_get_search_ctx(vol->vol_ni, NULL);
1096 if (!ctx)
1097 goto error_exit;
1099 /* Find the $VOLUME_INFORMATION attribute. */
1100 if (ntfs_attr_lookup(AT_VOLUME_INFORMATION, AT_UNNAMED, 0, 0, 0, NULL,
1101 0, ctx)) {
1102 ntfs_log_perror("$VOLUME_INFORMATION attribute not found in "
1103 "$Volume");
1104 goto error_exit;
1106 a = ctx->attr;
1107 /* Has to be resident. */
1108 if (a->non_resident) {
1109 ntfs_log_error("Attribute $VOLUME_INFORMATION must be "
1110 "resident but it isn't.\n");
1111 errno = EIO;
1112 goto error_exit;
1114 /* Get a pointer to the value of the attribute. */
1115 vinf = (VOLUME_INFORMATION*)(le16_to_cpu(a->value_offset) + (char*)a);
1116 /* Sanity checks. */
1117 if ((char*)vinf + le32_to_cpu(a->value_length) > (char*)ctx->mrec +
1118 le32_to_cpu(ctx->mrec->bytes_in_use) ||
1119 le16_to_cpu(a->value_offset) + le32_to_cpu(
1120 a->value_length) > le32_to_cpu(a->length)) {
1121 ntfs_log_error("$VOLUME_INFORMATION in $Volume is corrupt.\n");
1122 errno = EIO;
1123 goto error_exit;
1125 /* Setup vol from the volume information attribute value. */
1126 vol->major_ver = vinf->major_ver;
1127 vol->minor_ver = vinf->minor_ver;
1128 /* Do not use le16_to_cpu() macro here as our VOLUME_FLAGS are
1129 defined using cpu_to_le16() macro and hence are consistent. */
1130 vol->flags = vinf->flags;
1132 * Reinitialize the search context for the $Volume/$VOLUME_NAME lookup.
1134 ntfs_attr_reinit_search_ctx(ctx);
1135 if (ntfs_attr_lookup(AT_VOLUME_NAME, AT_UNNAMED, 0, 0, 0, NULL, 0,
1136 ctx)) {
1137 if (errno != ENOENT) {
1138 ntfs_log_perror("Failed to lookup of $VOLUME_NAME in "
1139 "$Volume failed");
1140 goto error_exit;
1143 * Attribute not present. This has been seen in the field.
1144 * Treat this the same way as if the attribute was present but
1145 * had zero length.
1147 vol->vol_name = ntfs_malloc(1);
1148 if (!vol->vol_name)
1149 goto error_exit;
1150 vol->vol_name[0] = '\0';
1151 } else {
1152 a = ctx->attr;
1153 /* Has to be resident. */
1154 if (a->non_resident) {
1155 ntfs_log_error("$VOLUME_NAME must be resident.\n");
1156 errno = EIO;
1157 goto error_exit;
1159 /* Get a pointer to the value of the attribute. */
1160 vname = (ntfschar*)(le16_to_cpu(a->value_offset) + (char*)a);
1161 u = le32_to_cpu(a->value_length) / 2;
1163 * Convert Unicode volume name to current locale multibyte
1164 * format.
1166 vol->vol_name = NULL;
1167 if (ntfs_ucstombs(vname, u, &vol->vol_name, 0) == -1) {
1168 ntfs_log_perror("Volume name could not be converted "
1169 "to current locale");
1170 ntfs_log_debug("Forcing name into ASCII by replacing "
1171 "non-ASCII characters with underscores.\n");
1172 vol->vol_name = ntfs_malloc(u + 1);
1173 if (!vol->vol_name)
1174 goto error_exit;
1176 for (j = 0; j < (s32)u; j++) {
1177 u16 uc = le16_to_cpu(vname[j]);
1178 if (uc > 0xff)
1179 uc = (u16)'_';
1180 vol->vol_name[j] = (char)uc;
1182 vol->vol_name[u] = '\0';
1185 ntfs_attr_put_search_ctx(ctx);
1186 ctx = NULL;
1187 /* Now load the attribute definitions from $AttrDef. */
1188 ntfs_log_debug("Loading $AttrDef...\n");
1189 ni = ntfs_inode_open(vol, FILE_AttrDef);
1190 if (!ni) {
1191 ntfs_log_perror("Failed to open $AttrDef");
1192 goto error_exit;
1194 /* Get an ntfs attribute for $AttrDef/$DATA. */
1195 na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
1196 if (!na) {
1197 ntfs_log_perror("Failed to open ntfs attribute");
1198 goto error_exit;
1200 /* Check we don't overflow 32-bits. */
1201 if (na->data_size > 0xffffffffLL) {
1202 ntfs_log_error("Attribute definition table is too big (max "
1203 "32-bit allowed).\n");
1204 errno = EINVAL;
1205 goto error_exit;
1207 vol->attrdef_len = na->data_size;
1208 vol->attrdef = ntfs_malloc(na->data_size);
1209 if (!vol->attrdef)
1210 goto error_exit;
1211 /* Read in the $DATA attribute value into the buffer. */
1212 l = ntfs_attr_pread(na, 0, na->data_size, vol->attrdef);
1213 if (l != na->data_size) {
1214 ntfs_log_error("Failed to read $AttrDef, unexpected length "
1215 "(%lld != %lld).\n", (long long)l,
1216 (long long)na->data_size);
1217 errno = EIO;
1218 goto error_exit;
1220 /* Done with the $AttrDef mft record. */
1221 ntfs_attr_close(na);
1222 if (ntfs_inode_close(ni)) {
1223 ntfs_log_perror("Failed to close $AttrDef");
1224 goto error_exit;
1227 * Check for dirty logfile and hibernated Windows.
1228 * We care only about read-write mounts.
1230 if (!(flags & (NTFS_MNT_RDONLY | NTFS_MNT_FORENSIC))) {
1231 if (!(flags & NTFS_MNT_IGNORE_HIBERFILE) &&
1232 ntfs_volume_check_hiberfile(vol, 1) < 0)
1233 goto error_exit;
1234 if (ntfs_volume_check_logfile(vol) < 0) {
1235 /* Always reject cached metadata for now */
1236 if (!(flags & NTFS_MNT_RECOVER) || (errno == EPERM))
1237 goto error_exit;
1238 ntfs_log_info("The file system wasn't safely "
1239 "closed on Windows. Fixing.\n");
1240 if (ntfs_logfile_reset(vol))
1241 goto error_exit;
1243 /* make $TXF_DATA resident if present on the root directory */
1244 if (fix_txf_data(vol))
1245 goto error_exit;
1248 return vol;
1249 io_error_exit:
1250 errno = EIO;
1251 error_exit:
1252 eo = errno;
1253 if (ctx)
1254 ntfs_attr_put_search_ctx(ctx);
1255 free(m);
1256 free(m2);
1257 __ntfs_volume_release(vol);
1258 errno = eo;
1259 return NULL;
1263 * Set appropriate flags for showing NTFS metafiles
1264 * or files marked as hidden.
1265 * Not set in ntfs_mount() to avoid breaking existing tools.
1268 int ntfs_set_shown_files(ntfs_volume *vol,
1269 BOOL show_sys_files, BOOL show_hid_files,
1270 BOOL hide_dot_files)
1272 int res;
1274 res = -1;
1275 if (vol) {
1276 NVolClearShowSysFiles(vol);
1277 NVolClearShowHidFiles(vol);
1278 NVolClearHideDotFiles(vol);
1279 if (show_sys_files)
1280 NVolSetShowSysFiles(vol);
1281 if (show_hid_files)
1282 NVolSetShowHidFiles(vol);
1283 if (hide_dot_files)
1284 NVolSetHideDotFiles(vol);
1285 res = 0;
1287 if (res)
1288 ntfs_log_error("Failed to set file visibility\n");
1289 return (res);
1293 * Set ignore case mode
1296 int ntfs_set_ignore_case(ntfs_volume *vol)
1298 int res;
1300 res = -1;
1301 if (vol && vol->upcase) {
1302 vol->locase = ntfs_locase_table_build(vol->upcase,
1303 vol->upcase_len);
1304 if (vol->locase) {
1305 NVolClearCaseSensitive(vol);
1306 res = 0;
1309 if (res)
1310 ntfs_log_error("Failed to set ignore_case mode\n");
1311 return (res);
1315 * ntfs_mount - open ntfs volume
1316 * @name: name of device/file to open
1317 * @flags: optional mount flags
1319 * This function mounts an ntfs volume. @name should contain the name of the
1320 * device/file to mount as the ntfs volume.
1322 * @flags is an optional second parameter. The same flags are used as for
1323 * the mount system call (man 2 mount). Currently only the following flags
1324 * is implemented:
1325 * NTFS_MNT_RDONLY - mount volume read-only
1327 * The function opens the device or file @name and verifies that it contains a
1328 * valid bootsector. Then, it allocates an ntfs_volume structure and initializes
1329 * some of the values inside the structure from the information stored in the
1330 * bootsector. It proceeds to load the necessary system files and completes
1331 * setting up the structure.
1333 * Return the allocated volume structure on success and NULL on error with
1334 * errno set to the error code.
1336 * Note, that a copy is made of @name, and hence it can be discarded as
1337 * soon as the function returns.
1339 ntfs_volume *ntfs_mount(const char *name __attribute__((unused)),
1340 ntfs_mount_flags flags __attribute__((unused)))
1342 #ifndef NO_NTFS_DEVICE_DEFAULT_IO_OPS
1343 struct ntfs_device *dev;
1344 ntfs_volume *vol;
1346 /* Allocate an ntfs_device structure. */
1347 dev = ntfs_device_alloc(name, 0, &ntfs_device_default_io_ops, NULL);
1348 if (!dev)
1349 return NULL;
1350 /* Call ntfs_device_mount() to do the actual mount. */
1351 vol = ntfs_device_mount(dev, flags);
1352 if (!vol) {
1353 int eo = errno;
1354 ntfs_device_free(dev);
1355 errno = eo;
1356 } else
1357 ntfs_create_lru_caches(vol);
1358 return vol;
1359 #else
1361 * ntfs_mount() makes no sense if NO_NTFS_DEVICE_DEFAULT_IO_OPS is
1362 * defined as there are no device operations available in libntfs in
1363 * this case.
1365 errno = EOPNOTSUPP;
1366 return NULL;
1367 #endif
1371 * ntfs_umount - close ntfs volume
1372 * @vol: address of ntfs_volume structure of volume to close
1373 * @force: if true force close the volume even if it is busy
1375 * Deallocate all structures (including @vol itself) associated with the ntfs
1376 * volume @vol.
1378 * Return 0 on success. On error return -1 with errno set appropriately
1379 * (most likely to one of EAGAIN, EBUSY or EINVAL). The EAGAIN error means that
1380 * an operation is in progress and if you try the close later the operation
1381 * might be completed and the close succeed.
1383 * If @force is true (i.e. not zero) this function will close the volume even
1384 * if this means that data might be lost.
1386 * @vol must have previously been returned by a call to ntfs_mount().
1388 * @vol itself is deallocated and should no longer be dereferenced after this
1389 * function returns success. If it returns an error then nothing has been done
1390 * so it is safe to continue using @vol.
1392 int ntfs_umount(ntfs_volume *vol, const BOOL force __attribute__((unused)))
1394 struct ntfs_device *dev;
1395 int ret;
1397 if (!vol) {
1398 errno = EINVAL;
1399 return -1;
1401 dev = vol->dev;
1402 ret = __ntfs_volume_release(vol);
1403 ntfs_device_free(dev);
1404 return ret;
1407 #ifdef HAVE_MNTENT_H
1410 * ntfs_mntent_check - desc
1412 * If you are wanting to use this, you actually wanted to use
1413 * ntfs_check_if_mounted(), you just didn't realize. (-:
1415 * See description of ntfs_check_if_mounted(), below.
1417 static int ntfs_mntent_check(const char *file, unsigned long *mnt_flags)
1419 struct mntent *mnt;
1420 char *real_file = NULL, *real_fsname = NULL;
1421 FILE *f;
1422 int err = 0;
1424 real_file = ntfs_malloc(PATH_MAX + 1);
1425 if (!real_file)
1426 return -1;
1427 real_fsname = ntfs_malloc(PATH_MAX + 1);
1428 if (!real_fsname) {
1429 err = errno;
1430 goto exit;
1432 if (!ntfs_realpath_canonicalize(file, real_file)) {
1433 err = errno;
1434 goto exit;
1436 if (!(f = setmntent(MOUNTED, "r"))) {
1437 err = errno;
1438 goto exit;
1440 while ((mnt = getmntent(f))) {
1441 if (!ntfs_realpath_canonicalize(mnt->mnt_fsname, real_fsname))
1442 continue;
1443 if (!strcmp(real_file, real_fsname))
1444 break;
1446 endmntent(f);
1447 if (!mnt)
1448 goto exit;
1449 *mnt_flags = NTFS_MF_MOUNTED;
1450 if (!strcmp(mnt->mnt_dir, "/"))
1451 *mnt_flags |= NTFS_MF_ISROOT;
1452 #ifdef HAVE_HASMNTOPT
1453 if (hasmntopt(mnt, "ro") && !hasmntopt(mnt, "rw"))
1454 *mnt_flags |= NTFS_MF_READONLY;
1455 #endif
1456 exit:
1457 free(real_file);
1458 free(real_fsname);
1459 if (err) {
1460 errno = err;
1461 return -1;
1463 return 0;
1466 #else /* HAVE_MNTENT_H */
1468 #if defined(__sun) && defined (__SVR4)
1470 static int ntfs_mntent_check(const char *file, unsigned long *mnt_flags)
1472 struct mnttab *mnt = NULL;
1473 char *real_file = NULL, *real_fsname = NULL;
1474 FILE *f;
1475 int err = 0;
1477 real_file = (char*)ntfs_malloc(PATH_MAX + 1);
1478 if (!real_file)
1479 return -1;
1480 real_fsname = (char*)ntfs_malloc(PATH_MAX + 1);
1481 mnt = (struct mnttab*)ntfs_malloc(MNT_LINE_MAX + 1);
1482 if (!real_fsname || !mnt) {
1483 err = errno;
1484 goto exit;
1486 if (!ntfs_realpath_canonicalize(file, real_file)) {
1487 err = errno;
1488 goto exit;
1490 if (!(f = fopen(MNTTAB, "r"))) {
1491 err = errno;
1492 goto exit;
1494 while (!getmntent(f, mnt)) {
1495 if (!ntfs_realpath_canonicalize(mnt->mnt_special, real_fsname))
1496 continue;
1497 if (!strcmp(real_file, real_fsname)) {
1498 *mnt_flags = NTFS_MF_MOUNTED;
1499 if (!strcmp(mnt->mnt_mountp, "/"))
1500 *mnt_flags |= NTFS_MF_ISROOT;
1501 if (hasmntopt(mnt, "ro") && !hasmntopt(mnt, "rw"))
1502 *mnt_flags |= NTFS_MF_READONLY;
1503 break;
1506 fclose(f);
1507 exit:
1508 free(mnt);
1509 free(real_file);
1510 free(real_fsname);
1511 if (err) {
1512 errno = err;
1513 return -1;
1515 return 0;
1518 #endif /* defined(__sun) && defined (__SVR4) */
1519 #endif /* HAVE_MNTENT_H */
1522 * ntfs_check_if_mounted - check if an ntfs volume is currently mounted
1523 * @file: device file to check
1524 * @mnt_flags: pointer into which to return the ntfs mount flags (see volume.h)
1526 * If the running system does not support the {set,get,end}mntent() calls,
1527 * just return 0 and set *@mnt_flags to zero.
1529 * When the system does support the calls, ntfs_check_if_mounted() first tries
1530 * to find the device @file in /etc/mtab (or wherever this is kept on the
1531 * running system). If it is not found, assume the device is not mounted and
1532 * return 0 and set *@mnt_flags to zero.
1534 * If the device @file is found, set the NTFS_MF_MOUNTED flags in *@mnt_flags.
1536 * Further if @file is mounted as the file system root ("/"), set the flag
1537 * NTFS_MF_ISROOT in *@mnt_flags.
1539 * Finally, check if the file system is mounted read-only, and if so set the
1540 * NTFS_MF_READONLY flag in *@mnt_flags.
1542 * On success return 0 with *@mnt_flags set to the ntfs mount flags.
1544 * On error return -1 with errno set to the error code.
1546 int ntfs_check_if_mounted(const char *file __attribute__((unused)),
1547 unsigned long *mnt_flags)
1549 *mnt_flags = 0;
1550 #if defined(HAVE_MNTENT_H) || (defined(__sun) && defined (__SVR4))
1551 return ntfs_mntent_check(file, mnt_flags);
1552 #else
1553 return 0;
1554 #endif
1558 * ntfs_version_is_supported - check if NTFS version is supported.
1559 * @vol: ntfs volume whose version we're interested in.
1561 * The function checks if the NTFS volume version is known or not.
1562 * Version 1.1 and 1.2 are used by Windows NT3.x and NT4.
1563 * Version 2.x is used by Windows 2000 Betas.
1564 * Version 3.0 is used by Windows 2000.
1565 * Version 3.1 is used by Windows XP, Windows Server 2003 and Longhorn.
1567 * Return 0 if NTFS version is supported otherwise -1 with errno set.
1569 * The following error codes are defined:
1570 * EOPNOTSUPP - Unknown NTFS version
1571 * EINVAL - Invalid argument
1573 int ntfs_version_is_supported(ntfs_volume *vol)
1575 u8 major, minor;
1577 if (!vol) {
1578 errno = EINVAL;
1579 return -1;
1582 major = vol->major_ver;
1583 minor = vol->minor_ver;
1585 if (NTFS_V1_1(major, minor) || NTFS_V1_2(major, minor))
1586 return 0;
1588 if (NTFS_V2_X(major, minor))
1589 return 0;
1591 if (NTFS_V3_0(major, minor) || NTFS_V3_1(major, minor))
1592 return 0;
1594 errno = EOPNOTSUPP;
1595 return -1;
1599 * ntfs_logfile_reset - "empty" $LogFile data attribute value
1600 * @vol: ntfs volume whose $LogFile we intend to reset.
1602 * Fill the value of the $LogFile data attribute, i.e. the contents of
1603 * the file, with 0xff's, thus marking the journal as empty.
1605 * FIXME(?): We might need to zero the LSN field of every single mft
1606 * record as well. (But, first try without doing that and see what
1607 * happens, since chkdsk might pickup the pieces and do it for us...)
1609 * On success return 0.
1611 * On error return -1 with errno set to the error code.
1613 int ntfs_logfile_reset(ntfs_volume *vol)
1615 ntfs_inode *ni;
1616 ntfs_attr *na;
1617 int eo;
1619 if (!vol) {
1620 errno = EINVAL;
1621 return -1;
1624 ni = ntfs_inode_open(vol, FILE_LogFile);
1625 if (!ni) {
1626 ntfs_log_perror("Failed to open inode FILE_LogFile");
1627 return -1;
1630 na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
1631 if (!na) {
1632 eo = errno;
1633 ntfs_log_perror("Failed to open $FILE_LogFile/$DATA");
1634 goto error_exit;
1637 if (ntfs_empty_logfile(na)) {
1638 eo = errno;
1639 ntfs_attr_close(na);
1640 goto error_exit;
1643 ntfs_attr_close(na);
1644 return ntfs_inode_close(ni);
1646 error_exit:
1647 ntfs_inode_close(ni);
1648 errno = eo;
1649 return -1;
1653 * ntfs_volume_write_flags - set the flags of an ntfs volume
1654 * @vol: ntfs volume where we set the volume flags
1655 * @flags: new flags
1657 * Set the on-disk volume flags in the mft record of $Volume and
1658 * on volume @vol to @flags.
1660 * Return 0 if successful and -1 if not with errno set to the error code.
1662 int ntfs_volume_write_flags(ntfs_volume *vol, const le16 flags)
1664 ATTR_RECORD *a;
1665 VOLUME_INFORMATION *c;
1666 ntfs_attr_search_ctx *ctx;
1667 int ret = -1; /* failure */
1669 if (!vol || !vol->vol_ni) {
1670 errno = EINVAL;
1671 return -1;
1673 /* Get a pointer to the volume information attribute. */
1674 ctx = ntfs_attr_get_search_ctx(vol->vol_ni, NULL);
1675 if (!ctx)
1676 return -1;
1678 if (ntfs_attr_lookup(AT_VOLUME_INFORMATION, AT_UNNAMED, 0, 0, 0, NULL,
1679 0, ctx)) {
1680 ntfs_log_error("Attribute $VOLUME_INFORMATION was not found "
1681 "in $Volume!\n");
1682 goto err_out;
1684 a = ctx->attr;
1685 /* Sanity check. */
1686 if (a->non_resident) {
1687 ntfs_log_error("Attribute $VOLUME_INFORMATION must be resident "
1688 "but it isn't.\n");
1689 errno = EIO;
1690 goto err_out;
1692 /* Get a pointer to the value of the attribute. */
1693 c = (VOLUME_INFORMATION*)(le16_to_cpu(a->value_offset) + (char*)a);
1694 /* Sanity checks. */
1695 if ((char*)c + le32_to_cpu(a->value_length) > (char*)ctx->mrec +
1696 le32_to_cpu(ctx->mrec->bytes_in_use) ||
1697 le16_to_cpu(a->value_offset) +
1698 le32_to_cpu(a->value_length) > le32_to_cpu(a->length)) {
1699 ntfs_log_error("Attribute $VOLUME_INFORMATION in $Volume is "
1700 "corrupt!\n");
1701 errno = EIO;
1702 goto err_out;
1704 /* Set the volume flags. */
1705 vol->flags = c->flags = flags & VOLUME_FLAGS_MASK;
1706 /* Write them to disk. */
1707 ntfs_inode_mark_dirty(vol->vol_ni);
1708 if (ntfs_inode_sync(vol->vol_ni))
1709 goto err_out;
1711 ret = 0; /* success */
1712 err_out:
1713 ntfs_attr_put_search_ctx(ctx);
1714 return ret;
1717 int ntfs_volume_error(int err)
1719 int ret;
1721 switch (err) {
1722 case 0:
1723 ret = NTFS_VOLUME_OK;
1724 break;
1725 case EINVAL:
1726 ret = NTFS_VOLUME_NOT_NTFS;
1727 break;
1728 case EIO:
1729 ret = NTFS_VOLUME_CORRUPT;
1730 break;
1731 case EPERM:
1733 * Hibernation and fast restarting are seen the
1734 * same way on a non Windows-system partition.
1736 ret = NTFS_VOLUME_HIBERNATED;
1737 break;
1738 case EOPNOTSUPP:
1739 ret = NTFS_VOLUME_UNCLEAN_UNMOUNT;
1740 break;
1741 case EBUSY:
1742 ret = NTFS_VOLUME_LOCKED;
1743 break;
1744 case ENXIO:
1745 ret = NTFS_VOLUME_RAID;
1746 break;
1747 case EACCES:
1748 ret = NTFS_VOLUME_NO_PRIVILEGE;
1749 break;
1750 default:
1751 ret = NTFS_VOLUME_UNKNOWN_REASON;
1752 break;
1754 return ret;
1758 void ntfs_mount_error(const char *volume, const char *mntpoint, int err)
1760 switch (err) {
1761 case NTFS_VOLUME_NOT_NTFS:
1762 ntfs_log_error(invalid_ntfs_msg, volume);
1763 break;
1764 case NTFS_VOLUME_CORRUPT:
1765 ntfs_log_error("%s", corrupt_volume_msg);
1766 break;
1767 case NTFS_VOLUME_HIBERNATED:
1768 ntfs_log_error(hibernated_volume_msg, volume, mntpoint);
1769 break;
1770 case NTFS_VOLUME_UNCLEAN_UNMOUNT:
1771 ntfs_log_error("%s", unclean_journal_msg);
1772 break;
1773 case NTFS_VOLUME_LOCKED:
1774 ntfs_log_error("%s", opened_volume_msg);
1775 break;
1776 case NTFS_VOLUME_RAID:
1777 ntfs_log_error("%s", fakeraid_msg);
1778 break;
1779 case NTFS_VOLUME_NO_PRIVILEGE:
1780 ntfs_log_error(access_denied_msg, volume);
1781 break;
1785 int ntfs_set_locale(void)
1787 const char *locale;
1789 locale = setlocale(LC_ALL, "");
1790 if (!locale) {
1791 locale = setlocale(LC_ALL, NULL);
1792 ntfs_log_error("Couldn't set local environment, using default "
1793 "'%s'.\n", locale);
1794 return 1;
1796 return 0;
1800 * Feed the counts of free clusters and free mft records
1803 int ntfs_volume_get_free_space(ntfs_volume *vol)
1805 ntfs_attr *na;
1806 int ret;
1808 ret = -1; /* default return */
1809 vol->free_clusters = ntfs_attr_get_free_bits(vol->lcnbmp_na);
1810 if (vol->free_clusters < 0) {
1811 ntfs_log_perror("Failed to read NTFS $Bitmap");
1812 } else {
1813 na = vol->mftbmp_na;
1814 vol->free_mft_records = ntfs_attr_get_free_bits(na);
1816 if (vol->free_mft_records >= 0)
1817 vol->free_mft_records += (na->allocated_size - na->data_size) << 3;
1819 if (vol->free_mft_records < 0)
1820 ntfs_log_perror("Failed to calculate free MFT records");
1821 else
1822 ret = 0;
1824 return (ret);
1828 * ntfs_volume_rename - change the current label on a volume
1829 * @vol: volume to change the label on
1830 * @label: the new label
1831 * @label_len: the length of @label in ntfschars including the terminating NULL
1832 * character, which is mandatory (the value can not exceed 128)
1834 * Change the label on the volume @vol to @label.
1836 int ntfs_volume_rename(ntfs_volume *vol, const ntfschar *label, int label_len)
1838 ntfs_attr *na;
1839 char *old_vol_name;
1840 char *new_vol_name = NULL;
1841 int new_vol_name_len;
1842 int err;
1844 if (NVolReadOnly(vol)) {
1845 ntfs_log_error("Refusing to change label on read-only mounted "
1846 "volume.\n");
1847 errno = EROFS;
1848 return -1;
1851 label_len *= sizeof(ntfschar);
1852 if (label_len > 0x100) {
1853 ntfs_log_error("New label is too long. Maximum %u characters "
1854 "allowed.\n",
1855 (unsigned)(0x100 / sizeof(ntfschar)));
1856 errno = ERANGE;
1857 return -1;
1860 na = ntfs_attr_open(vol->vol_ni, AT_VOLUME_NAME, AT_UNNAMED, 0);
1861 if (!na) {
1862 if (errno != ENOENT) {
1863 err = errno;
1864 ntfs_log_perror("Lookup of $VOLUME_NAME attribute "
1865 "failed");
1866 goto err_out;
1869 /* The volume name attribute does not exist. Need to add it. */
1870 if (ntfs_attr_add(vol->vol_ni, AT_VOLUME_NAME, AT_UNNAMED, 0,
1871 (const u8*) label, label_len))
1873 err = errno;
1874 ntfs_log_perror("Encountered error while adding "
1875 "$VOLUME_NAME attribute");
1876 goto err_out;
1879 else {
1880 s64 written;
1882 if (NAttrNonResident(na)) {
1883 err = errno;
1884 ntfs_log_error("Error: Attribute $VOLUME_NAME must be "
1885 "resident.\n");
1886 goto err_out;
1889 if (na->data_size != label_len) {
1890 if (ntfs_attr_truncate(na, label_len)) {
1891 err = errno;
1892 ntfs_log_perror("Error resizing resident "
1893 "attribute");
1894 goto err_out;
1898 if (label_len) {
1899 written = ntfs_attr_pwrite(na, 0, label_len, label);
1900 if (written == -1) {
1901 err = errno;
1902 ntfs_log_perror("Error when writing "
1903 "$VOLUME_NAME data");
1904 goto err_out;
1906 else if (written != label_len) {
1907 err = EIO;
1908 ntfs_log_error("Partial write when writing "
1909 "$VOLUME_NAME data.");
1910 goto err_out;
1916 new_vol_name_len =
1917 ntfs_ucstombs(label, label_len, &new_vol_name, 0);
1918 if (new_vol_name_len == -1) {
1919 err = errno;
1920 ntfs_log_perror("Error while decoding new volume name");
1921 goto err_out;
1924 old_vol_name = vol->vol_name;
1925 vol->vol_name = new_vol_name;
1926 free(old_vol_name);
1928 err = 0;
1929 err_out:
1930 if (na)
1931 ntfs_attr_close(na);
1932 if (err)
1933 errno = err;
1934 return err ? -1 : 0;