blob: 916f1c020af73a94dfa2772de916c3db110f049f [file] [log] [blame]
Steve Kondik2111ad72013-07-07 12:07:44 -07001/**
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
Steve Kondik2111ad72013-07-07 12:07:44 -070078const char *ntfs_home =
79"News, support and information: http://tuxera.com\n";
80
81static 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";
85
86static 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";
94
95static 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";
99
100static 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";
103
104static 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";
108
109static 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";
114
115static 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";
119
120/**
121 * ntfs_volume_alloc - Create an NTFS volume object and initialise it
122 *
123 * Description...
124 *
125 * Returns:
126 */
127ntfs_volume *ntfs_volume_alloc(void)
128{
129 return ntfs_calloc(sizeof(ntfs_volume));
130}
131
132static void ntfs_attr_free(ntfs_attr **na)
133{
134 if (na && *na) {
135 ntfs_attr_close(*na);
136 *na = NULL;
137 }
138}
139
140static int ntfs_inode_free(ntfs_inode **ni)
141{
142 int ret = -1;
143
144 if (ni && *ni) {
145 ret = ntfs_inode_close(*ni);
146 *ni = NULL;
147 }
148
149 return ret;
150}
151
152static void ntfs_error_set(int *err)
153{
154 if (!*err)
155 *err = errno;
156}
157
158/**
159 * __ntfs_volume_release - Destroy an NTFS volume object
160 * @v:
161 *
162 * Description...
163 *
164 * Returns:
165 */
166static int __ntfs_volume_release(ntfs_volume *v)
167{
168 int err = 0;
169
170 if (ntfs_inode_free(&v->vol_ni))
171 ntfs_error_set(&err);
172 /*
173 * FIXME: Inodes must be synced before closing
174 * attributes, otherwise unmount could fail.
175 */
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);
181
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);
188
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);
194
195 if (v->dev) {
196 struct ntfs_device *dev = v->dev;
197
198 if (dev->d_ops->sync(dev))
199 ntfs_error_set(&err);
200 if (dev->d_ops->close(dev))
201 ntfs_error_set(&err);
202 }
203
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);
210
211 errno = err;
212 return errno ? -1 : 0;
213}
214
215static void ntfs_attr_setup_flag(ntfs_inode *ni)
216{
217 STANDARD_INFORMATION *si;
218
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);
223 }
224}
225
226/**
227 * ntfs_mft_load - load the $MFT and setup the ntfs volume with it
228 * @vol: ntfs volume whose $MFT to load
229 *
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.
233 *
234 * Return 0 on success and -1 on error with errno set to the error code.
235 */
236static int ntfs_mft_load(ntfs_volume *vol)
237{
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;
244
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;
251 }
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;
262 }
263
264 if (ntfs_mft_record_check(vol, 0, mb))
265 goto error_exit;
266
267 ctx = ntfs_attr_get_search_ctx(vol->mft_ni, NULL);
268 if (!ctx)
269 goto error_exit;
270
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;
277 }
278 goto mft_has_no_attr_list;
279 }
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;
286 }
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;
291
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;
296 }
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;
302 }
303
304mft_has_no_attr_list:
305
306 ntfs_attr_setup_flag(vol->mft_ni);
307
308 /* We now have a fully setup ntfs inode for $MFT in vol->mft_ni. */
309
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;
315 }
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;
324
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;
330 }
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;
337 }
338 /*
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.
343 */
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;
348 }
349 vol->mft_na->rl = nrl;
350
351 /* Get the lowest vcn for the next extent. */
352 highest_vcn = sle64_to_cpu(a->highest_vcn);
353 next_vcn = highest_vcn + 1;
354
355 /* Only one extent or error, which we catch below. */
356 if (next_vcn <= 0)
357 break;
358
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;
363 }
364 }
365 if (!a) {
366 ntfs_log_error("$MFT/$DATA attribute not found.\n");
367 goto io_error_exit;
368 }
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;
374 }
375 /* Done with the $Mft mft record. */
376 ntfs_attr_put_search_ctx(ctx);
377 ctx = NULL;
378
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);
383
384 /*
385 * The volume is now setup so we can use all read access functions.
386 */
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;
391 }
392 return 0;
393io_error_exit:
394 errno = EIO;
395error_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;
402 }
403 if (vol->mft_ni) {
404 ntfs_inode_close(vol->mft_ni);
405 vol->mft_ni = NULL;
406 }
407 errno = eo;
408 return -1;
409}
410
411/**
412 * ntfs_mftmirr_load - load the $MFTMirr and setup the ntfs volume with it
413 * @vol: ntfs volume whose $MFTMirr to load
414 *
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).
419 *
420 * Return 0 on success and -1 on error with errno set to the error code.
421 */
422static int ntfs_mftmirr_load(ntfs_volume *vol)
423{
424 int err;
425
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;
430 }
431
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;
436 }
437
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;
441 }
442
443 return 0;
444
445error_exit:
446 err = errno;
447 if (vol->mftmirr_na) {
448 ntfs_attr_close(vol->mftmirr_na);
449 vol->mftmirr_na = NULL;
450 }
451 ntfs_inode_close(vol->mftmirr_ni);
452 vol->mftmirr_ni = NULL;
453 errno = err;
454 return -1;
455}
456
457/**
458 * ntfs_volume_startup - allocate and setup an ntfs volume
459 * @dev: device to open
460 * @flags: optional mount flags
461 *
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.
465 *
466 * Return the allocated volume structure on success and NULL on error with
467 * errno set to the error code.
468 */
469ntfs_volume *ntfs_volume_startup(struct ntfs_device *dev,
470 ntfs_mount_flags flags)
471{
472 LCN mft_zone_size, mft_lcn;
473 s64 br;
474 ntfs_volume *vol;
475 NTFS_BOOT_SECTOR *bs;
476 int eo;
477
478 if (!dev || !dev->d_ops || !dev->d_name) {
479 errno = EINVAL;
480 ntfs_log_perror("%s: dev = %p", __FUNCTION__, dev);
481 return NULL;
482 }
483
484 bs = ntfs_malloc(sizeof(NTFS_BOOT_SECTOR));
485 if (!bs)
486 return NULL;
487
488 /* Allocate the volume structure. */
489 vol = ntfs_volume_alloc();
490 if (!vol)
491 goto error_exit;
492
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;
497
498 /* Default with no locase table and case sensitive file names */
499 vol->locase = (ntfschar*)NULL;
500 NVolSetCaseSensitive(vol);
501
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);
514
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);
526 }
527 } else {
528 ntfs_log_perror("Error opening '%s'", dev->d_name);
529 goto error_exit;
530 }
531 }
532 /* Attach the device to the volume. */
533 vol->dev = dev;
534
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;
545 }
546 if (!ntfs_boot_sector_is_ntfs(bs)) {
547 errno = EINVAL;
548 goto error_exit;
549 }
550 if (ntfs_boot_sector_parse(vol, bs) < 0)
551 goto error_exit;
552
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));
561
562 /* We now initialize the cluster allocator. */
563 vol->full_zones = 0;
564 mft_zone_size = vol->nr_clusters >> 3; /* 12.5% */
565
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);
569
570 /*
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.
578 */
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);
586
587 /*
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.
591 */
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;
596 }
597 ntfs_log_debug("mft_zone_end = 0x%llx\n", (long long)vol->mft_zone_end);
598
599 /*
600 * Set the current position within each data zone to the start of the
601 * respective zone.
602 */
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);
607
608 /* Set the mft data allocation position to mft record 24. */
609 vol->mft_data_pos = 24;
610
611 /*
612 * The cluster allocator is now fully operational.
613 */
614
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;
619 }
620
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;
625 }
626 return vol;
627error_exit:
628 eo = errno;
629 free(bs);
630 if (vol)
631 __ntfs_volume_release(vol);
632 errno = eo;
633 return NULL;
634}
635
636/**
637 * ntfs_volume_check_logfile - check logfile on target volume
638 * @vol: volume on which to check logfile
639 *
640 * Return 0 on success and -1 on error with errno set error code.
641 */
642static int ntfs_volume_check_logfile(ntfs_volume *vol)
643{
644 ntfs_inode *ni;
645 ntfs_attr *na = NULL;
646 RESTART_PAGE_HEADER *rp = NULL;
647 int err = 0;
648
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;
654 }
655
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;
661 }
662
663 if (!ntfs_check_logfile(na, &rp) || !ntfs_is_logfile_clean(na, rp))
664 err = EOPNOTSUPP;
665 /*
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.
676 */
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;
682 }
683 free(rp);
684 ntfs_attr_close(na);
685out:
686 if (ntfs_inode_close(ni))
687 ntfs_error_set(&err);
688 if (err) {
689 errno = err;
690 return -1;
691 }
692 return 0;
693}
694
695/**
696 * ntfs_hiberfile_open - Find and open '/hiberfil.sys'
697 * @vol: An ntfs volume obtained from ntfs_mount
698 *
699 * Return: inode Success, hiberfil.sys is valid
700 * NULL hiberfil.sys doesn't exist or some other error occurred
701 */
702static ntfs_inode *ntfs_hiberfile_open(ntfs_volume *vol)
703{
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";
710
711 if (!vol) {
712 errno = EINVAL;
713 return NULL;
714 }
715
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;
720 }
721
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;
726 }
727
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;
732 }
733
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;
739 }
740out:
741 if (ntfs_inode_close(ni_root)) {
742 ntfs_inode_close(ni_hibr);
743 ni_hibr = NULL;
744 }
745 free(unicode);
746 return ni_hibr;
747}
748
749
750#define NTFS_HIBERFILE_HEADER_SIZE 4096
751
752/**
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
756 *
757 * Return: 0 if Windows isn't hibernated for sure
758 * -1 otherwise and errno is set to the appropriate value
759 */
760int ntfs_volume_check_hiberfile(ntfs_volume *vol, int verbose)
761{
762 ntfs_inode *ni;
763 ntfs_attr *na = NULL;
764 int bytes_read, err;
765 char *buf = NULL;
766
767 ni = ntfs_hiberfile_open(vol);
768 if (!ni) {
769 if (errno == ENOENT)
770 return 0;
771 return -1;
772 }
773
774 buf = ntfs_malloc(NTFS_HIBERFILE_HEADER_SIZE);
775 if (!buf)
776 goto out;
777
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;
782 }
783
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;
788 }
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;
795 }
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;
802 }
803 /* All right, all header bytes are zero */
804 errno = 0;
805out:
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;
814}
815
816/*
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)
821 *
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.
825 *
826 * Returns 0 if unneeded or successful
827 * -1 if there was an error, explained by errno
828 */
829
830static int fix_txf_data(ntfs_volume *vol)
831{
832 void *txf_data;
833 s64 txf_data_size;
834 ntfs_inode *ni;
835 ntfs_attr *na;
836 int res;
837
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)) {
849 /*
850 * Fix the attribute by truncating, then
851 * rewriting it.
852 */
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);
864 }
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");
869 }
870 ntfs_attr_close(na);
871 }
872 if (ntfs_inode_close(ni)) {
873 ntfs_log_perror("Failed to close root");
874 res = -1;
875 }
876 }
877 return (res);
878}
879
880/**
881 * ntfs_device_mount - open ntfs volume
882 * @dev: device to open
883 * @flags: optional mount flags
884 *
885 * This function mounts an ntfs volume. @dev should describe the device which
886 * to mount as the ntfs volume.
887 *
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
892 *
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.
898 *
899 * Return the allocated volume structure on success and NULL on error with
900 * errno set to the error code.
901 */
902ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, ntfs_mount_flags flags)
903{
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;
Steve Kondike68cb602016-08-28 00:45:36 -0700913 u32 record_size;
Steve Kondik2111ad72013-07-07 12:07:44 -0700914 int i, j, eo;
915 unsigned int k;
916 u32 u;
917
918 vol = ntfs_volume_startup(dev, flags);
919 if (!vol)
920 return NULL;
921
922 /* Load data from $MFT and $MFTMirr and compare the contents. */
923 m = ntfs_malloc(vol->mftmirr_size << vol->mft_record_size_bits);
924 m2 = ntfs_malloc(vol->mftmirr_size << vol->mft_record_size_bits);
925 if (!m || !m2)
926 goto error_exit;
927
928 l = ntfs_attr_mst_pread(vol->mft_na, 0, vol->mftmirr_size,
929 vol->mft_record_size, m);
930 if (l != vol->mftmirr_size) {
931 if (l == -1)
932 ntfs_log_perror("Failed to read $MFT");
933 else {
934 ntfs_log_error("Failed to read $MFT, unexpected length "
935 "(%lld != %d).\n", (long long)l,
936 vol->mftmirr_size);
937 errno = EIO;
938 }
939 goto error_exit;
940 }
941 l = ntfs_attr_mst_pread(vol->mftmirr_na, 0, vol->mftmirr_size,
942 vol->mft_record_size, m2);
943 if (l != vol->mftmirr_size) {
944 if (l == -1) {
945 ntfs_log_perror("Failed to read $MFTMirr");
946 goto error_exit;
947 }
948 vol->mftmirr_size = l;
949 }
950 ntfs_log_debug("Comparing $MFTMirr to $MFT...\n");
951 for (i = 0; i < vol->mftmirr_size; ++i) {
952 MFT_RECORD *mrec, *mrec2;
953 const char *ESTR[12] = { "$MFT", "$MFTMirr", "$LogFile",
954 "$Volume", "$AttrDef", "root directory", "$Bitmap",
955 "$Boot", "$BadClus", "$Secure", "$UpCase", "$Extend" };
956 const char *s;
957
958 if (i < 12)
959 s = ESTR[i];
960 else if (i < 16)
961 s = "system file";
962 else
963 s = "mft record";
964
965 mrec = (MFT_RECORD*)(m + i * vol->mft_record_size);
966 if (mrec->flags & MFT_RECORD_IN_USE) {
Steve Kondike68cb602016-08-28 00:45:36 -0700967 if (ntfs_is_baad_record(mrec->magic)) {
Steve Kondik2111ad72013-07-07 12:07:44 -0700968 ntfs_log_error("$MFT error: Incomplete multi "
969 "sector transfer detected in "
970 "'%s'.\n", s);
971 goto io_error_exit;
972 }
Steve Kondike68cb602016-08-28 00:45:36 -0700973 if (!ntfs_is_mft_record(mrec->magic)) {
Steve Kondik2111ad72013-07-07 12:07:44 -0700974 ntfs_log_error("$MFT error: Invalid mft "
975 "record for '%s'.\n", s);
976 goto io_error_exit;
977 }
978 }
979 mrec2 = (MFT_RECORD*)(m2 + i * vol->mft_record_size);
980 if (mrec2->flags & MFT_RECORD_IN_USE) {
Steve Kondike68cb602016-08-28 00:45:36 -0700981 if (ntfs_is_baad_record(mrec2->magic)) {
Steve Kondik2111ad72013-07-07 12:07:44 -0700982 ntfs_log_error("$MFTMirr error: Incomplete "
983 "multi sector transfer "
984 "detected in '%s'.\n", s);
985 goto io_error_exit;
986 }
Steve Kondike68cb602016-08-28 00:45:36 -0700987 if (!ntfs_is_mft_record(mrec2->magic)) {
Steve Kondik2111ad72013-07-07 12:07:44 -0700988 ntfs_log_error("$MFTMirr error: Invalid mft "
989 "record for '%s'.\n", s);
990 goto io_error_exit;
991 }
992 }
Steve Kondike68cb602016-08-28 00:45:36 -0700993 record_size = ntfs_mft_record_get_data_size(mrec);
994 if ((record_size <= sizeof(MFT_RECORD))
995 || (record_size > vol->mft_record_size)
996 || memcmp(mrec, mrec2, record_size)) {
Steve Kondik2111ad72013-07-07 12:07:44 -0700997 ntfs_log_error("$MFTMirr does not match $MFT (record "
998 "%d).\n", i);
999 goto io_error_exit;
1000 }
1001 }
1002
1003 free(m2);
1004 free(m);
1005 m = m2 = NULL;
1006
1007 /* Now load the bitmap from $Bitmap. */
1008 ntfs_log_debug("Loading $Bitmap...\n");
1009 vol->lcnbmp_ni = ntfs_inode_open(vol, FILE_Bitmap);
1010 if (!vol->lcnbmp_ni) {
1011 ntfs_log_perror("Failed to open inode FILE_Bitmap");
1012 goto error_exit;
1013 }
1014
1015 vol->lcnbmp_na = ntfs_attr_open(vol->lcnbmp_ni, AT_DATA, AT_UNNAMED, 0);
1016 if (!vol->lcnbmp_na) {
1017 ntfs_log_perror("Failed to open ntfs attribute");
1018 goto error_exit;
1019 }
1020
1021 if (vol->lcnbmp_na->data_size > vol->lcnbmp_na->allocated_size) {
1022 ntfs_log_error("Corrupt cluster map size (%lld > %lld)\n",
1023 (long long)vol->lcnbmp_na->data_size,
1024 (long long)vol->lcnbmp_na->allocated_size);
1025 goto io_error_exit;
1026 }
1027
1028 /* Now load the upcase table from $UpCase. */
1029 ntfs_log_debug("Loading $UpCase...\n");
1030 ni = ntfs_inode_open(vol, FILE_UpCase);
1031 if (!ni) {
1032 ntfs_log_perror("Failed to open inode FILE_UpCase");
1033 goto error_exit;
1034 }
1035 /* Get an ntfs attribute for $UpCase/$DATA. */
1036 na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
1037 if (!na) {
1038 ntfs_log_perror("Failed to open ntfs attribute");
1039 goto error_exit;
1040 }
1041 /*
1042 * Note: Normally, the upcase table has a length equal to 65536
1043 * 2-byte Unicode characters but allow for different cases, so no
1044 * checks done. Just check we don't overflow 32-bits worth of Unicode
1045 * characters.
1046 */
1047 if (na->data_size & ~0x1ffffffffULL) {
1048 ntfs_log_error("Error: Upcase table is too big (max 32-bit "
1049 "allowed).\n");
1050 errno = EINVAL;
1051 goto error_exit;
1052 }
1053 if (vol->upcase_len != na->data_size >> 1) {
1054 vol->upcase_len = na->data_size >> 1;
1055 /* Throw away default table. */
1056 free(vol->upcase);
1057 vol->upcase = ntfs_malloc(na->data_size);
1058 if (!vol->upcase)
1059 goto error_exit;
1060 }
1061 /* Read in the $DATA attribute value into the buffer. */
1062 l = ntfs_attr_pread(na, 0, na->data_size, vol->upcase);
1063 if (l != na->data_size) {
1064 ntfs_log_error("Failed to read $UpCase, unexpected length "
1065 "(%lld != %lld).\n", (long long)l,
1066 (long long)na->data_size);
1067 errno = EIO;
1068 goto error_exit;
1069 }
1070 /* Done with the $UpCase mft record. */
1071 ntfs_attr_close(na);
1072 if (ntfs_inode_close(ni)) {
1073 ntfs_log_perror("Failed to close $UpCase");
1074 goto error_exit;
1075 }
1076 /* Consistency check of $UpCase, restricted to plain ASCII chars */
1077 k = 0x20;
1078 while ((k < vol->upcase_len)
1079 && (k < 0x7f)
1080 && (le16_to_cpu(vol->upcase[k])
1081 == ((k < 'a') || (k > 'z') ? k : k + 'A' - 'a')))
1082 k++;
1083 if (k < 0x7f) {
1084 ntfs_log_error("Corrupted file $UpCase\n");
1085 goto io_error_exit;
1086 }
1087
1088 /*
1089 * Now load $Volume and set the version information and flags in the
1090 * vol structure accordingly.
1091 */
1092 ntfs_log_debug("Loading $Volume...\n");
1093 vol->vol_ni = ntfs_inode_open(vol, FILE_Volume);
1094 if (!vol->vol_ni) {
1095 ntfs_log_perror("Failed to open inode FILE_Volume");
1096 goto error_exit;
1097 }
1098 /* Get a search context for the $Volume/$VOLUME_INFORMATION lookup. */
1099 ctx = ntfs_attr_get_search_ctx(vol->vol_ni, NULL);
1100 if (!ctx)
1101 goto error_exit;
1102
1103 /* Find the $VOLUME_INFORMATION attribute. */
1104 if (ntfs_attr_lookup(AT_VOLUME_INFORMATION, AT_UNNAMED, 0, 0, 0, NULL,
1105 0, ctx)) {
1106 ntfs_log_perror("$VOLUME_INFORMATION attribute not found in "
1107 "$Volume");
1108 goto error_exit;
1109 }
1110 a = ctx->attr;
1111 /* Has to be resident. */
1112 if (a->non_resident) {
1113 ntfs_log_error("Attribute $VOLUME_INFORMATION must be "
1114 "resident but it isn't.\n");
1115 errno = EIO;
1116 goto error_exit;
1117 }
1118 /* Get a pointer to the value of the attribute. */
1119 vinf = (VOLUME_INFORMATION*)(le16_to_cpu(a->value_offset) + (char*)a);
1120 /* Sanity checks. */
1121 if ((char*)vinf + le32_to_cpu(a->value_length) > (char*)ctx->mrec +
1122 le32_to_cpu(ctx->mrec->bytes_in_use) ||
1123 le16_to_cpu(a->value_offset) + le32_to_cpu(
1124 a->value_length) > le32_to_cpu(a->length)) {
1125 ntfs_log_error("$VOLUME_INFORMATION in $Volume is corrupt.\n");
1126 errno = EIO;
1127 goto error_exit;
1128 }
1129 /* Setup vol from the volume information attribute value. */
1130 vol->major_ver = vinf->major_ver;
1131 vol->minor_ver = vinf->minor_ver;
1132 /* Do not use le16_to_cpu() macro here as our VOLUME_FLAGS are
1133 defined using cpu_to_le16() macro and hence are consistent. */
1134 vol->flags = vinf->flags;
1135 /*
1136 * Reinitialize the search context for the $Volume/$VOLUME_NAME lookup.
1137 */
1138 ntfs_attr_reinit_search_ctx(ctx);
1139 if (ntfs_attr_lookup(AT_VOLUME_NAME, AT_UNNAMED, 0, 0, 0, NULL, 0,
1140 ctx)) {
1141 if (errno != ENOENT) {
1142 ntfs_log_perror("Failed to lookup of $VOLUME_NAME in "
1143 "$Volume failed");
1144 goto error_exit;
1145 }
1146 /*
1147 * Attribute not present. This has been seen in the field.
1148 * Treat this the same way as if the attribute was present but
1149 * had zero length.
1150 */
1151 vol->vol_name = ntfs_malloc(1);
1152 if (!vol->vol_name)
1153 goto error_exit;
1154 vol->vol_name[0] = '\0';
1155 } else {
1156 a = ctx->attr;
1157 /* Has to be resident. */
1158 if (a->non_resident) {
1159 ntfs_log_error("$VOLUME_NAME must be resident.\n");
1160 errno = EIO;
1161 goto error_exit;
1162 }
1163 /* Get a pointer to the value of the attribute. */
1164 vname = (ntfschar*)(le16_to_cpu(a->value_offset) + (char*)a);
1165 u = le32_to_cpu(a->value_length) / 2;
1166 /*
1167 * Convert Unicode volume name to current locale multibyte
1168 * format.
1169 */
1170 vol->vol_name = NULL;
1171 if (ntfs_ucstombs(vname, u, &vol->vol_name, 0) == -1) {
1172 ntfs_log_perror("Volume name could not be converted "
1173 "to current locale");
1174 ntfs_log_debug("Forcing name into ASCII by replacing "
1175 "non-ASCII characters with underscores.\n");
1176 vol->vol_name = ntfs_malloc(u + 1);
1177 if (!vol->vol_name)
1178 goto error_exit;
1179
1180 for (j = 0; j < (s32)u; j++) {
1181 u16 uc = le16_to_cpu(vname[j]);
1182 if (uc > 0xff)
1183 uc = (u16)'_';
1184 vol->vol_name[j] = (char)uc;
1185 }
1186 vol->vol_name[u] = '\0';
1187 }
1188 }
1189 ntfs_attr_put_search_ctx(ctx);
1190 ctx = NULL;
1191 /* Now load the attribute definitions from $AttrDef. */
1192 ntfs_log_debug("Loading $AttrDef...\n");
1193 ni = ntfs_inode_open(vol, FILE_AttrDef);
1194 if (!ni) {
1195 ntfs_log_perror("Failed to open $AttrDef");
1196 goto error_exit;
1197 }
1198 /* Get an ntfs attribute for $AttrDef/$DATA. */
1199 na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
1200 if (!na) {
1201 ntfs_log_perror("Failed to open ntfs attribute");
1202 goto error_exit;
1203 }
1204 /* Check we don't overflow 32-bits. */
1205 if (na->data_size > 0xffffffffLL) {
1206 ntfs_log_error("Attribute definition table is too big (max "
1207 "32-bit allowed).\n");
1208 errno = EINVAL;
1209 goto error_exit;
1210 }
1211 vol->attrdef_len = na->data_size;
1212 vol->attrdef = ntfs_malloc(na->data_size);
1213 if (!vol->attrdef)
1214 goto error_exit;
1215 /* Read in the $DATA attribute value into the buffer. */
1216 l = ntfs_attr_pread(na, 0, na->data_size, vol->attrdef);
1217 if (l != na->data_size) {
1218 ntfs_log_error("Failed to read $AttrDef, unexpected length "
1219 "(%lld != %lld).\n", (long long)l,
1220 (long long)na->data_size);
1221 errno = EIO;
1222 goto error_exit;
1223 }
1224 /* Done with the $AttrDef mft record. */
1225 ntfs_attr_close(na);
1226 if (ntfs_inode_close(ni)) {
1227 ntfs_log_perror("Failed to close $AttrDef");
1228 goto error_exit;
1229 }
1230 /*
1231 * Check for dirty logfile and hibernated Windows.
1232 * We care only about read-write mounts.
1233 */
1234 if (!(flags & (NTFS_MNT_RDONLY | NTFS_MNT_FORENSIC))) {
1235 if (!(flags & NTFS_MNT_IGNORE_HIBERFILE) &&
1236 ntfs_volume_check_hiberfile(vol, 1) < 0)
1237 goto error_exit;
1238 if (ntfs_volume_check_logfile(vol) < 0) {
1239 /* Always reject cached metadata for now */
1240 if (!(flags & NTFS_MNT_RECOVER) || (errno == EPERM))
1241 goto error_exit;
1242 ntfs_log_info("The file system wasn't safely "
1243 "closed on Windows. Fixing.\n");
1244 if (ntfs_logfile_reset(vol))
1245 goto error_exit;
1246 }
1247 /* make $TXF_DATA resident if present on the root directory */
1248 if (fix_txf_data(vol))
1249 goto error_exit;
1250 }
1251
1252 return vol;
1253io_error_exit:
1254 errno = EIO;
1255error_exit:
1256 eo = errno;
1257 if (ctx)
1258 ntfs_attr_put_search_ctx(ctx);
1259 free(m);
1260 free(m2);
1261 __ntfs_volume_release(vol);
1262 errno = eo;
1263 return NULL;
1264}
1265
1266/*
1267 * Set appropriate flags for showing NTFS metafiles
1268 * or files marked as hidden.
1269 * Not set in ntfs_mount() to avoid breaking existing tools.
1270 */
1271
1272int ntfs_set_shown_files(ntfs_volume *vol,
1273 BOOL show_sys_files, BOOL show_hid_files,
1274 BOOL hide_dot_files)
1275{
1276 int res;
1277
1278 res = -1;
1279 if (vol) {
1280 NVolClearShowSysFiles(vol);
1281 NVolClearShowHidFiles(vol);
1282 NVolClearHideDotFiles(vol);
1283 if (show_sys_files)
1284 NVolSetShowSysFiles(vol);
1285 if (show_hid_files)
1286 NVolSetShowHidFiles(vol);
1287 if (hide_dot_files)
1288 NVolSetHideDotFiles(vol);
1289 res = 0;
1290 }
1291 if (res)
1292 ntfs_log_error("Failed to set file visibility\n");
1293 return (res);
1294}
1295
1296/*
1297 * Set ignore case mode
1298 */
1299
1300int ntfs_set_ignore_case(ntfs_volume *vol)
1301{
1302 int res;
1303
1304 res = -1;
1305 if (vol && vol->upcase) {
1306 vol->locase = ntfs_locase_table_build(vol->upcase,
1307 vol->upcase_len);
1308 if (vol->locase) {
1309 NVolClearCaseSensitive(vol);
1310 res = 0;
1311 }
1312 }
1313 if (res)
1314 ntfs_log_error("Failed to set ignore_case mode\n");
1315 return (res);
1316}
1317
1318/**
1319 * ntfs_mount - open ntfs volume
1320 * @name: name of device/file to open
1321 * @flags: optional mount flags
1322 *
1323 * This function mounts an ntfs volume. @name should contain the name of the
1324 * device/file to mount as the ntfs volume.
1325 *
1326 * @flags is an optional second parameter. The same flags are used as for
1327 * the mount system call (man 2 mount). Currently only the following flags
1328 * is implemented:
1329 * NTFS_MNT_RDONLY - mount volume read-only
1330 *
1331 * The function opens the device or file @name and verifies that it contains a
1332 * valid bootsector. Then, it allocates an ntfs_volume structure and initializes
1333 * some of the values inside the structure from the information stored in the
1334 * bootsector. It proceeds to load the necessary system files and completes
1335 * setting up the structure.
1336 *
1337 * Return the allocated volume structure on success and NULL on error with
1338 * errno set to the error code.
1339 *
1340 * Note, that a copy is made of @name, and hence it can be discarded as
1341 * soon as the function returns.
1342 */
1343ntfs_volume *ntfs_mount(const char *name __attribute__((unused)),
1344 ntfs_mount_flags flags __attribute__((unused)))
1345{
1346#ifndef NO_NTFS_DEVICE_DEFAULT_IO_OPS
1347 struct ntfs_device *dev;
1348 ntfs_volume *vol;
1349
1350 /* Allocate an ntfs_device structure. */
1351 dev = ntfs_device_alloc(name, 0, &ntfs_device_default_io_ops, NULL);
1352 if (!dev)
1353 return NULL;
1354 /* Call ntfs_device_mount() to do the actual mount. */
1355 vol = ntfs_device_mount(dev, flags);
1356 if (!vol) {
1357 int eo = errno;
1358 ntfs_device_free(dev);
1359 errno = eo;
1360 } else
1361 ntfs_create_lru_caches(vol);
1362 return vol;
1363#else
1364 /*
1365 * ntfs_mount() makes no sense if NO_NTFS_DEVICE_DEFAULT_IO_OPS is
1366 * defined as there are no device operations available in libntfs in
1367 * this case.
1368 */
1369 errno = EOPNOTSUPP;
1370 return NULL;
1371#endif
1372}
1373
1374/**
1375 * ntfs_umount - close ntfs volume
1376 * @vol: address of ntfs_volume structure of volume to close
1377 * @force: if true force close the volume even if it is busy
1378 *
1379 * Deallocate all structures (including @vol itself) associated with the ntfs
1380 * volume @vol.
1381 *
1382 * Return 0 on success. On error return -1 with errno set appropriately
1383 * (most likely to one of EAGAIN, EBUSY or EINVAL). The EAGAIN error means that
1384 * an operation is in progress and if you try the close later the operation
1385 * might be completed and the close succeed.
1386 *
1387 * If @force is true (i.e. not zero) this function will close the volume even
1388 * if this means that data might be lost.
1389 *
1390 * @vol must have previously been returned by a call to ntfs_mount().
1391 *
1392 * @vol itself is deallocated and should no longer be dereferenced after this
1393 * function returns success. If it returns an error then nothing has been done
1394 * so it is safe to continue using @vol.
1395 */
1396int ntfs_umount(ntfs_volume *vol, const BOOL force __attribute__((unused)))
1397{
1398 struct ntfs_device *dev;
1399 int ret;
1400
1401 if (!vol) {
1402 errno = EINVAL;
1403 return -1;
1404 }
1405 dev = vol->dev;
1406 ret = __ntfs_volume_release(vol);
1407 ntfs_device_free(dev);
1408 return ret;
1409}
1410
1411#ifdef HAVE_MNTENT_H
1412
1413/**
1414 * ntfs_mntent_check - desc
1415 *
1416 * If you are wanting to use this, you actually wanted to use
1417 * ntfs_check_if_mounted(), you just didn't realize. (-:
1418 *
1419 * See description of ntfs_check_if_mounted(), below.
1420 */
1421static int ntfs_mntent_check(const char *file, unsigned long *mnt_flags)
1422{
1423 struct mntent *mnt;
1424 char *real_file = NULL, *real_fsname = NULL;
1425 FILE *f;
1426 int err = 0;
1427
1428 real_file = ntfs_malloc(PATH_MAX + 1);
1429 if (!real_file)
1430 return -1;
1431 real_fsname = ntfs_malloc(PATH_MAX + 1);
1432 if (!real_fsname) {
1433 err = errno;
1434 goto exit;
1435 }
1436 if (!ntfs_realpath_canonicalize(file, real_file)) {
1437 err = errno;
1438 goto exit;
1439 }
Steve Kondik79165c32015-11-09 19:43:00 -08001440 f = setmntent("/proc/mounts", "r");
1441 if (!f && !(f = setmntent(MOUNTED, "r"))) {
Steve Kondik2111ad72013-07-07 12:07:44 -07001442 err = errno;
1443 goto exit;
1444 }
1445 while ((mnt = getmntent(f))) {
1446 if (!ntfs_realpath_canonicalize(mnt->mnt_fsname, real_fsname))
1447 continue;
1448 if (!strcmp(real_file, real_fsname))
1449 break;
1450 }
1451 endmntent(f);
1452 if (!mnt)
1453 goto exit;
1454 *mnt_flags = NTFS_MF_MOUNTED;
1455 if (!strcmp(mnt->mnt_dir, "/"))
1456 *mnt_flags |= NTFS_MF_ISROOT;
1457#ifdef HAVE_HASMNTOPT
1458 if (hasmntopt(mnt, "ro") && !hasmntopt(mnt, "rw"))
1459 *mnt_flags |= NTFS_MF_READONLY;
1460#endif
1461exit:
1462 free(real_file);
1463 free(real_fsname);
1464 if (err) {
1465 errno = err;
1466 return -1;
1467 }
1468 return 0;
1469}
1470
1471#else /* HAVE_MNTENT_H */
1472
1473#if defined(__sun) && defined (__SVR4)
1474
1475static int ntfs_mntent_check(const char *file, unsigned long *mnt_flags)
1476{
1477 struct mnttab *mnt = NULL;
1478 char *real_file = NULL, *real_fsname = NULL;
1479 FILE *f;
1480 int err = 0;
1481
1482 real_file = (char*)ntfs_malloc(PATH_MAX + 1);
1483 if (!real_file)
1484 return -1;
1485 real_fsname = (char*)ntfs_malloc(PATH_MAX + 1);
1486 mnt = (struct mnttab*)ntfs_malloc(MNT_LINE_MAX + 1);
1487 if (!real_fsname || !mnt) {
1488 err = errno;
1489 goto exit;
1490 }
1491 if (!ntfs_realpath_canonicalize(file, real_file)) {
1492 err = errno;
1493 goto exit;
1494 }
1495 if (!(f = fopen(MNTTAB, "r"))) {
1496 err = errno;
1497 goto exit;
1498 }
1499 while (!getmntent(f, mnt)) {
1500 if (!ntfs_realpath_canonicalize(mnt->mnt_special, real_fsname))
1501 continue;
1502 if (!strcmp(real_file, real_fsname)) {
1503 *mnt_flags = NTFS_MF_MOUNTED;
1504 if (!strcmp(mnt->mnt_mountp, "/"))
1505 *mnt_flags |= NTFS_MF_ISROOT;
1506 if (hasmntopt(mnt, "ro") && !hasmntopt(mnt, "rw"))
1507 *mnt_flags |= NTFS_MF_READONLY;
1508 break;
1509 }
1510 }
1511 fclose(f);
1512exit:
1513 free(mnt);
1514 free(real_file);
1515 free(real_fsname);
1516 if (err) {
1517 errno = err;
1518 return -1;
1519 }
1520 return 0;
1521}
1522
1523#endif /* defined(__sun) && defined (__SVR4) */
1524#endif /* HAVE_MNTENT_H */
1525
1526/**
1527 * ntfs_check_if_mounted - check if an ntfs volume is currently mounted
1528 * @file: device file to check
1529 * @mnt_flags: pointer into which to return the ntfs mount flags (see volume.h)
1530 *
1531 * If the running system does not support the {set,get,end}mntent() calls,
1532 * just return 0 and set *@mnt_flags to zero.
1533 *
1534 * When the system does support the calls, ntfs_check_if_mounted() first tries
1535 * to find the device @file in /etc/mtab (or wherever this is kept on the
1536 * running system). If it is not found, assume the device is not mounted and
1537 * return 0 and set *@mnt_flags to zero.
1538 *
1539 * If the device @file is found, set the NTFS_MF_MOUNTED flags in *@mnt_flags.
1540 *
1541 * Further if @file is mounted as the file system root ("/"), set the flag
1542 * NTFS_MF_ISROOT in *@mnt_flags.
1543 *
1544 * Finally, check if the file system is mounted read-only, and if so set the
1545 * NTFS_MF_READONLY flag in *@mnt_flags.
1546 *
1547 * On success return 0 with *@mnt_flags set to the ntfs mount flags.
1548 *
1549 * On error return -1 with errno set to the error code.
1550 */
1551int ntfs_check_if_mounted(const char *file __attribute__((unused)),
1552 unsigned long *mnt_flags)
1553{
1554 *mnt_flags = 0;
1555#if defined(HAVE_MNTENT_H) || (defined(__sun) && defined (__SVR4))
1556 return ntfs_mntent_check(file, mnt_flags);
1557#else
1558 return 0;
1559#endif
1560}
1561
1562/**
1563 * ntfs_version_is_supported - check if NTFS version is supported.
1564 * @vol: ntfs volume whose version we're interested in.
1565 *
1566 * The function checks if the NTFS volume version is known or not.
1567 * Version 1.1 and 1.2 are used by Windows NT3.x and NT4.
1568 * Version 2.x is used by Windows 2000 Betas.
1569 * Version 3.0 is used by Windows 2000.
1570 * Version 3.1 is used by Windows XP, Windows Server 2003 and Longhorn.
1571 *
1572 * Return 0 if NTFS version is supported otherwise -1 with errno set.
1573 *
1574 * The following error codes are defined:
1575 * EOPNOTSUPP - Unknown NTFS version
1576 * EINVAL - Invalid argument
1577 */
1578int ntfs_version_is_supported(ntfs_volume *vol)
1579{
1580 u8 major, minor;
1581
1582 if (!vol) {
1583 errno = EINVAL;
1584 return -1;
1585 }
1586
1587 major = vol->major_ver;
1588 minor = vol->minor_ver;
1589
1590 if (NTFS_V1_1(major, minor) || NTFS_V1_2(major, minor))
1591 return 0;
1592
1593 if (NTFS_V2_X(major, minor))
1594 return 0;
1595
1596 if (NTFS_V3_0(major, minor) || NTFS_V3_1(major, minor))
1597 return 0;
1598
1599 errno = EOPNOTSUPP;
1600 return -1;
1601}
1602
1603/**
1604 * ntfs_logfile_reset - "empty" $LogFile data attribute value
1605 * @vol: ntfs volume whose $LogFile we intend to reset.
1606 *
1607 * Fill the value of the $LogFile data attribute, i.e. the contents of
1608 * the file, with 0xff's, thus marking the journal as empty.
1609 *
1610 * FIXME(?): We might need to zero the LSN field of every single mft
1611 * record as well. (But, first try without doing that and see what
1612 * happens, since chkdsk might pickup the pieces and do it for us...)
1613 *
1614 * On success return 0.
1615 *
1616 * On error return -1 with errno set to the error code.
1617 */
1618int ntfs_logfile_reset(ntfs_volume *vol)
1619{
1620 ntfs_inode *ni;
1621 ntfs_attr *na;
1622 int eo;
1623
1624 if (!vol) {
1625 errno = EINVAL;
1626 return -1;
1627 }
1628
1629 ni = ntfs_inode_open(vol, FILE_LogFile);
1630 if (!ni) {
1631 ntfs_log_perror("Failed to open inode FILE_LogFile");
1632 return -1;
1633 }
1634
1635 na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
1636 if (!na) {
1637 eo = errno;
1638 ntfs_log_perror("Failed to open $FILE_LogFile/$DATA");
1639 goto error_exit;
1640 }
1641
1642 if (ntfs_empty_logfile(na)) {
1643 eo = errno;
1644 ntfs_attr_close(na);
1645 goto error_exit;
1646 }
1647
1648 ntfs_attr_close(na);
1649 return ntfs_inode_close(ni);
1650
1651error_exit:
1652 ntfs_inode_close(ni);
1653 errno = eo;
1654 return -1;
1655}
1656
1657/**
1658 * ntfs_volume_write_flags - set the flags of an ntfs volume
1659 * @vol: ntfs volume where we set the volume flags
1660 * @flags: new flags
1661 *
1662 * Set the on-disk volume flags in the mft record of $Volume and
1663 * on volume @vol to @flags.
1664 *
1665 * Return 0 if successful and -1 if not with errno set to the error code.
1666 */
1667int ntfs_volume_write_flags(ntfs_volume *vol, const le16 flags)
1668{
1669 ATTR_RECORD *a;
1670 VOLUME_INFORMATION *c;
1671 ntfs_attr_search_ctx *ctx;
1672 int ret = -1; /* failure */
1673
1674 if (!vol || !vol->vol_ni) {
1675 errno = EINVAL;
1676 return -1;
1677 }
1678 /* Get a pointer to the volume information attribute. */
1679 ctx = ntfs_attr_get_search_ctx(vol->vol_ni, NULL);
1680 if (!ctx)
1681 return -1;
1682
1683 if (ntfs_attr_lookup(AT_VOLUME_INFORMATION, AT_UNNAMED, 0, 0, 0, NULL,
1684 0, ctx)) {
1685 ntfs_log_error("Attribute $VOLUME_INFORMATION was not found "
1686 "in $Volume!\n");
1687 goto err_out;
1688 }
1689 a = ctx->attr;
1690 /* Sanity check. */
1691 if (a->non_resident) {
1692 ntfs_log_error("Attribute $VOLUME_INFORMATION must be resident "
1693 "but it isn't.\n");
1694 errno = EIO;
1695 goto err_out;
1696 }
1697 /* Get a pointer to the value of the attribute. */
1698 c = (VOLUME_INFORMATION*)(le16_to_cpu(a->value_offset) + (char*)a);
1699 /* Sanity checks. */
1700 if ((char*)c + le32_to_cpu(a->value_length) > (char*)ctx->mrec +
1701 le32_to_cpu(ctx->mrec->bytes_in_use) ||
1702 le16_to_cpu(a->value_offset) +
1703 le32_to_cpu(a->value_length) > le32_to_cpu(a->length)) {
1704 ntfs_log_error("Attribute $VOLUME_INFORMATION in $Volume is "
1705 "corrupt!\n");
1706 errno = EIO;
1707 goto err_out;
1708 }
1709 /* Set the volume flags. */
1710 vol->flags = c->flags = flags & VOLUME_FLAGS_MASK;
1711 /* Write them to disk. */
1712 ntfs_inode_mark_dirty(vol->vol_ni);
1713 if (ntfs_inode_sync(vol->vol_ni))
1714 goto err_out;
1715
1716 ret = 0; /* success */
1717err_out:
1718 ntfs_attr_put_search_ctx(ctx);
1719 return ret;
1720}
1721
1722int ntfs_volume_error(int err)
1723{
1724 int ret;
1725
1726 switch (err) {
1727 case 0:
1728 ret = NTFS_VOLUME_OK;
1729 break;
1730 case EINVAL:
1731 ret = NTFS_VOLUME_NOT_NTFS;
1732 break;
1733 case EIO:
1734 ret = NTFS_VOLUME_CORRUPT;
1735 break;
1736 case EPERM:
1737 /*
1738 * Hibernation and fast restarting are seen the
1739 * same way on a non Windows-system partition.
1740 */
1741 ret = NTFS_VOLUME_HIBERNATED;
1742 break;
1743 case EOPNOTSUPP:
1744 ret = NTFS_VOLUME_UNCLEAN_UNMOUNT;
1745 break;
1746 case EBUSY:
1747 ret = NTFS_VOLUME_LOCKED;
1748 break;
1749 case ENXIO:
1750 ret = NTFS_VOLUME_RAID;
1751 break;
1752 case EACCES:
1753 ret = NTFS_VOLUME_NO_PRIVILEGE;
1754 break;
1755 default:
1756 ret = NTFS_VOLUME_UNKNOWN_REASON;
1757 break;
1758 }
1759 return ret;
1760}
1761
1762
1763void ntfs_mount_error(const char *volume, const char *mntpoint, int err)
1764{
1765 switch (err) {
1766 case NTFS_VOLUME_NOT_NTFS:
1767 ntfs_log_error(invalid_ntfs_msg, volume);
1768 break;
1769 case NTFS_VOLUME_CORRUPT:
1770 ntfs_log_error("%s", corrupt_volume_msg);
1771 break;
1772 case NTFS_VOLUME_HIBERNATED:
1773 ntfs_log_error(hibernated_volume_msg, volume, mntpoint);
1774 break;
1775 case NTFS_VOLUME_UNCLEAN_UNMOUNT:
1776 ntfs_log_error("%s", unclean_journal_msg);
1777 break;
1778 case NTFS_VOLUME_LOCKED:
1779 ntfs_log_error("%s", opened_volume_msg);
1780 break;
1781 case NTFS_VOLUME_RAID:
1782 ntfs_log_error("%s", fakeraid_msg);
1783 break;
1784 case NTFS_VOLUME_NO_PRIVILEGE:
1785 ntfs_log_error(access_denied_msg, volume);
1786 break;
1787 }
1788}
1789
1790int ntfs_set_locale(void)
1791{
1792 const char *locale;
1793
1794 locale = setlocale(LC_ALL, "");
1795 if (!locale) {
1796 locale = setlocale(LC_ALL, NULL);
1797 ntfs_log_error("Couldn't set local environment, using default "
1798 "'%s'.\n", locale);
1799 return 1;
1800 }
1801 return 0;
1802}
1803
1804/*
1805 * Feed the counts of free clusters and free mft records
1806 */
1807
1808int ntfs_volume_get_free_space(ntfs_volume *vol)
1809{
1810 ntfs_attr *na;
1811 int ret;
1812
1813 ret = -1; /* default return */
1814 vol->free_clusters = ntfs_attr_get_free_bits(vol->lcnbmp_na);
1815 if (vol->free_clusters < 0) {
1816 ntfs_log_perror("Failed to read NTFS $Bitmap");
1817 } else {
1818 na = vol->mftbmp_na;
1819 vol->free_mft_records = ntfs_attr_get_free_bits(na);
1820
1821 if (vol->free_mft_records >= 0)
1822 vol->free_mft_records += (na->allocated_size - na->data_size) << 3;
1823
1824 if (vol->free_mft_records < 0)
1825 ntfs_log_perror("Failed to calculate free MFT records");
1826 else
1827 ret = 0;
1828 }
1829 return (ret);
1830}
1831
1832/**
1833 * ntfs_volume_rename - change the current label on a volume
1834 * @vol: volume to change the label on
1835 * @label: the new label
1836 * @label_len: the length of @label in ntfschars including the terminating NULL
1837 * character, which is mandatory (the value can not exceed 128)
1838 *
1839 * Change the label on the volume @vol to @label.
1840 */
1841int ntfs_volume_rename(ntfs_volume *vol, const ntfschar *label, int label_len)
1842{
1843 ntfs_attr *na;
1844 char *old_vol_name;
1845 char *new_vol_name = NULL;
1846 int new_vol_name_len;
1847 int err;
1848
1849 if (NVolReadOnly(vol)) {
1850 ntfs_log_error("Refusing to change label on read-only mounted "
1851 "volume.\n");
1852 errno = EROFS;
1853 return -1;
1854 }
1855
1856 label_len *= sizeof(ntfschar);
1857 if (label_len > 0x100) {
1858 ntfs_log_error("New label is too long. Maximum %u characters "
1859 "allowed.\n",
1860 (unsigned)(0x100 / sizeof(ntfschar)));
1861 errno = ERANGE;
1862 return -1;
1863 }
1864
1865 na = ntfs_attr_open(vol->vol_ni, AT_VOLUME_NAME, AT_UNNAMED, 0);
1866 if (!na) {
1867 if (errno != ENOENT) {
1868 err = errno;
1869 ntfs_log_perror("Lookup of $VOLUME_NAME attribute "
1870 "failed");
1871 goto err_out;
1872 }
1873
1874 /* The volume name attribute does not exist. Need to add it. */
1875 if (ntfs_attr_add(vol->vol_ni, AT_VOLUME_NAME, AT_UNNAMED, 0,
1876 (const u8*) label, label_len))
1877 {
1878 err = errno;
1879 ntfs_log_perror("Encountered error while adding "
1880 "$VOLUME_NAME attribute");
1881 goto err_out;
1882 }
1883 }
1884 else {
1885 s64 written;
1886
1887 if (NAttrNonResident(na)) {
1888 err = errno;
1889 ntfs_log_error("Error: Attribute $VOLUME_NAME must be "
1890 "resident.\n");
1891 goto err_out;
1892 }
1893
1894 if (na->data_size != label_len) {
1895 if (ntfs_attr_truncate(na, label_len)) {
1896 err = errno;
1897 ntfs_log_perror("Error resizing resident "
1898 "attribute");
1899 goto err_out;
1900 }
1901 }
1902
1903 if (label_len) {
1904 written = ntfs_attr_pwrite(na, 0, label_len, label);
1905 if (written == -1) {
1906 err = errno;
1907 ntfs_log_perror("Error when writing "
1908 "$VOLUME_NAME data");
1909 goto err_out;
1910 }
1911 else if (written != label_len) {
1912 err = EIO;
1913 ntfs_log_error("Partial write when writing "
1914 "$VOLUME_NAME data.");
1915 goto err_out;
1916
1917 }
1918 }
1919 }
1920
1921 new_vol_name_len =
1922 ntfs_ucstombs(label, label_len, &new_vol_name, 0);
1923 if (new_vol_name_len == -1) {
1924 err = errno;
1925 ntfs_log_perror("Error while decoding new volume name");
1926 goto err_out;
1927 }
1928
1929 old_vol_name = vol->vol_name;
1930 vol->vol_name = new_vol_name;
1931 free(old_vol_name);
1932
1933 err = 0;
1934err_out:
1935 if (na)
1936 ntfs_attr_close(na);
1937 if (err)
1938 errno = err;
1939 return err ? -1 : 0;
1940}