"Fossies" - the Fresh Open Source Software Archive

Member "ntfs-3g_ntfsprogs-2017.3.23/libntfs-3g/volume.c" (23 Mar 2017, 52680 Bytes) of package /linux/misc/ntfs-3g_ntfsprogs-2017.3.23.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "volume.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3g_ntfsprogs-2016.2.22_vs_3g_ntfsprogs-2017.3.23.

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