summaryrefslogtreecommitdiff
path: root/libntfs-3g/volume.c (plain)
blob: edd769796e8743d8b81a5a449cb34a913a9db4a7
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
78const 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;
913 int i, j, eo;
914 unsigned int k;
915 u32 u;
916
917 vol = ntfs_volume_startup(dev, flags);
918 if (!vol)
919 return NULL;
920
921 /* Load data from $MFT and $MFTMirr and compare the contents. */
922 m = ntfs_malloc(vol->mftmirr_size << vol->mft_record_size_bits);
923 m2 = ntfs_malloc(vol->mftmirr_size << vol->mft_record_size_bits);
924 if (!m || !m2)
925 goto error_exit;
926
927 l = ntfs_attr_mst_pread(vol->mft_na, 0, vol->mftmirr_size,
928 vol->mft_record_size, m);
929 if (l != vol->mftmirr_size) {
930 if (l == -1)
931 ntfs_log_perror("Failed to read $MFT");
932 else {
933 ntfs_log_error("Failed to read $MFT, unexpected length "
934 "(%lld != %d).\n", (long long)l,
935 vol->mftmirr_size);
936 errno = EIO;
937 }
938 goto error_exit;
939 }
940 l = ntfs_attr_mst_pread(vol->mftmirr_na, 0, vol->mftmirr_size,
941 vol->mft_record_size, m2);
942 if (l != vol->mftmirr_size) {
943 if (l == -1) {
944 ntfs_log_perror("Failed to read $MFTMirr");
945 goto error_exit;
946 }
947 vol->mftmirr_size = l;
948 }
949 ntfs_log_debug("Comparing $MFTMirr to $MFT...\n");
950 for (i = 0; i < vol->mftmirr_size; ++i) {
951 MFT_RECORD *mrec, *mrec2;
952 const char *ESTR[12] = { "$MFT", "$MFTMirr", "$LogFile",
953 "$Volume", "$AttrDef", "root directory", "$Bitmap",
954 "$Boot", "$BadClus", "$Secure", "$UpCase", "$Extend" };
955 const char *s;
956
957 if (i < 12)
958 s = ESTR[i];
959 else if (i < 16)
960 s = "system file";
961 else
962 s = "mft record";
963
964 mrec = (MFT_RECORD*)(m + i * vol->mft_record_size);
965 if (mrec->flags & MFT_RECORD_IN_USE) {
966 if (ntfs_is_baad_recordp(mrec)) {
967 ntfs_log_error("$MFT error: Incomplete multi "
968 "sector transfer detected in "
969 "'%s'.\n", s);
970 goto io_error_exit;
971 }
972 if (!ntfs_is_mft_recordp(mrec)) {
973 ntfs_log_error("$MFT error: Invalid mft "
974 "record for '%s'.\n", s);
975 goto io_error_exit;
976 }
977 }
978 mrec2 = (MFT_RECORD*)(m2 + i * vol->mft_record_size);
979 if (mrec2->flags & MFT_RECORD_IN_USE) {
980 if (ntfs_is_baad_recordp(mrec2)) {
981 ntfs_log_error("$MFTMirr error: Incomplete "
982 "multi sector transfer "
983 "detected in '%s'.\n", s);
984 goto io_error_exit;
985 }
986 if (!ntfs_is_mft_recordp(mrec2)) {
987 ntfs_log_error("$MFTMirr error: Invalid mft "
988 "record for '%s'.\n", s);
989 goto io_error_exit;
990 }
991 }
992 if (memcmp(mrec, mrec2, ntfs_mft_record_get_data_size(mrec))) {
993 ntfs_log_error("$MFTMirr does not match $MFT (record "
994 "%d).\n", i);
995 goto io_error_exit;
996 }
997 }
998
999 free(m2);
1000 free(m);
1001 m = m2 = NULL;
1002
1003 /* Now load the bitmap from $Bitmap. */
1004 ntfs_log_debug("Loading $Bitmap...\n");
1005 vol->lcnbmp_ni = ntfs_inode_open(vol, FILE_Bitmap);
1006 if (!vol->lcnbmp_ni) {
1007 ntfs_log_perror("Failed to open inode FILE_Bitmap");
1008 goto error_exit;
1009 }
1010
1011 vol->lcnbmp_na = ntfs_attr_open(vol->lcnbmp_ni, AT_DATA, AT_UNNAMED, 0);
1012 if (!vol->lcnbmp_na) {
1013 ntfs_log_perror("Failed to open ntfs attribute");
1014 goto error_exit;
1015 }
1016
1017 if (vol->lcnbmp_na->data_size > vol->lcnbmp_na->allocated_size) {
1018 ntfs_log_error("Corrupt cluster map size (%lld > %lld)\n",
1019 (long long)vol->lcnbmp_na->data_size,
1020 (long long)vol->lcnbmp_na->allocated_size);
1021 goto io_error_exit;
1022 }
1023
1024 /* Now load the upcase table from $UpCase. */
1025 ntfs_log_debug("Loading $UpCase...\n");
1026 ni = ntfs_inode_open(vol, FILE_UpCase);
1027 if (!ni) {
1028 ntfs_log_perror("Failed to open inode FILE_UpCase");
1029 goto error_exit;
1030 }
1031 /* Get an ntfs attribute for $UpCase/$DATA. */
1032 na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
1033 if (!na) {
1034 ntfs_log_perror("Failed to open ntfs attribute");
1035 goto error_exit;
1036 }
1037 /*
1038 * Note: Normally, the upcase table has a length equal to 65536
1039 * 2-byte Unicode characters but allow for different cases, so no
1040 * checks done. Just check we don't overflow 32-bits worth of Unicode
1041 * characters.
1042 */
1043 if (na->data_size & ~0x1ffffffffULL) {
1044 ntfs_log_error("Error: Upcase table is too big (max 32-bit "
1045 "allowed).\n");
1046 errno = EINVAL;
1047 goto error_exit;
1048 }
1049 if (vol->upcase_len != na->data_size >> 1) {
1050 vol->upcase_len = na->data_size >> 1;
1051 /* Throw away default table. */
1052 free(vol->upcase);
1053 vol->upcase = ntfs_malloc(na->data_size);
1054 if (!vol->upcase)
1055 goto error_exit;
1056 }
1057 /* Read in the $DATA attribute value into the buffer. */
1058 l = ntfs_attr_pread(na, 0, na->data_size, vol->upcase);
1059 if (l != na->data_size) {
1060 ntfs_log_error("Failed to read $UpCase, unexpected length "
1061 "(%lld != %lld).\n", (long long)l,
1062 (long long)na->data_size);
1063 errno = EIO;
1064 goto error_exit;
1065 }
1066 /* Done with the $UpCase mft record. */
1067 ntfs_attr_close(na);
1068 if (ntfs_inode_close(ni)) {
1069 ntfs_log_perror("Failed to close $UpCase");
1070 goto error_exit;
1071 }
1072 /* Consistency check of $UpCase, restricted to plain ASCII chars */
1073 k = 0x20;
1074 while ((k < vol->upcase_len)
1075 && (k < 0x7f)
1076 && (le16_to_cpu(vol->upcase[k])
1077 == ((k < 'a') || (k > 'z') ? k : k + 'A' - 'a')))
1078 k++;
1079 if (k < 0x7f) {
1080 ntfs_log_error("Corrupted file $UpCase\n");
1081 goto io_error_exit;
1082 }
1083
1084 /*
1085 * Now load $Volume and set the version information and flags in the
1086 * vol structure accordingly.
1087 */
1088 ntfs_log_debug("Loading $Volume...\n");
1089 vol->vol_ni = ntfs_inode_open(vol, FILE_Volume);
1090 if (!vol->vol_ni) {
1091 ntfs_log_perror("Failed to open inode FILE_Volume");
1092 goto error_exit;
1093 }
1094 /* Get a search context for the $Volume/$VOLUME_INFORMATION lookup. */
1095 ctx = ntfs_attr_get_search_ctx(vol->vol_ni, NULL);
1096 if (!ctx)
1097 goto error_exit;
1098
1099 /* Find the $VOLUME_INFORMATION attribute. */
1100 if (ntfs_attr_lookup(AT_VOLUME_INFORMATION, AT_UNNAMED, 0, 0, 0, NULL,
1101 0, ctx)) {
1102 ntfs_log_perror("$VOLUME_INFORMATION attribute not found in "
1103 "$Volume");
1104 goto error_exit;
1105 }
1106 a = ctx->attr;
1107 /* Has to be resident. */
1108 if (a->non_resident) {
1109 ntfs_log_error("Attribute $VOLUME_INFORMATION must be "
1110 "resident but it isn't.\n");
1111 errno = EIO;
1112 goto error_exit;
1113 }
1114 /* Get a pointer to the value of the attribute. */
1115 vinf = (VOLUME_INFORMATION*)(le16_to_cpu(a->value_offset) + (char*)a);
1116 /* Sanity checks. */
1117 if ((char*)vinf + le32_to_cpu(a->value_length) > (char*)ctx->mrec +
1118 le32_to_cpu(ctx->mrec->bytes_in_use) ||
1119 le16_to_cpu(a->value_offset) + le32_to_cpu(
1120 a->value_length) > le32_to_cpu(a->length)) {
1121 ntfs_log_error("$VOLUME_INFORMATION in $Volume is corrupt.\n");
1122 errno = EIO;
1123 goto error_exit;
1124 }
1125 /* Setup vol from the volume information attribute value. */
1126 vol->major_ver = vinf->major_ver;
1127 vol->minor_ver = vinf->minor_ver;
1128 /* Do not use le16_to_cpu() macro here as our VOLUME_FLAGS are
1129 defined using cpu_to_le16() macro and hence are consistent. */
1130 vol->flags = vinf->flags;
1131 /*
1132 * Reinitialize the search context for the $Volume/$VOLUME_NAME lookup.
1133 */
1134 ntfs_attr_reinit_search_ctx(ctx);
1135 if (ntfs_attr_lookup(AT_VOLUME_NAME, AT_UNNAMED, 0, 0, 0, NULL, 0,
1136 ctx)) {
1137 if (errno != ENOENT) {
1138 ntfs_log_perror("Failed to lookup of $VOLUME_NAME in "
1139 "$Volume failed");
1140 goto error_exit;
1141 }
1142 /*
1143 * Attribute not present. This has been seen in the field.
1144 * Treat this the same way as if the attribute was present but
1145 * had zero length.
1146 */
1147 vol->vol_name = ntfs_malloc(1);
1148 if (!vol->vol_name)
1149 goto error_exit;
1150 vol->vol_name[0] = '\0';
1151 } else {
1152 a = ctx->attr;
1153 /* Has to be resident. */
1154 if (a->non_resident) {
1155 ntfs_log_error("$VOLUME_NAME must be resident.\n");
1156 errno = EIO;
1157 goto error_exit;
1158 }
1159 /* Get a pointer to the value of the attribute. */
1160 vname = (ntfschar*)(le16_to_cpu(a->value_offset) + (char*)a);
1161 u = le32_to_cpu(a->value_length) / 2;
1162 /*
1163 * Convert Unicode volume name to current locale multibyte
1164 * format.
1165 */
1166 vol->vol_name = NULL;
1167 if (ntfs_ucstombs(vname, u, &vol->vol_name, 0) == -1) {
1168 ntfs_log_perror("Volume name could not be converted "
1169 "to current locale");
1170 ntfs_log_debug("Forcing name into ASCII by replacing "
1171 "non-ASCII characters with underscores.\n");
1172 vol->vol_name = ntfs_malloc(u + 1);
1173 if (!vol->vol_name)
1174 goto error_exit;
1175
1176 for (j = 0; j < (s32)u; j++) {
1177 u16 uc = le16_to_cpu(vname[j]);
1178 if (uc > 0xff)
1179 uc = (u16)'_';
1180 vol->vol_name[j] = (char)uc;
1181 }
1182 vol->vol_name[u] = '\0';
1183 }
1184 }
1185 ntfs_attr_put_search_ctx(ctx);
1186 ctx = NULL;
1187 /* Now load the attribute definitions from $AttrDef. */
1188 ntfs_log_debug("Loading $AttrDef...\n");
1189 ni = ntfs_inode_open(vol, FILE_AttrDef);
1190 if (!ni) {
1191 ntfs_log_perror("Failed to open $AttrDef");
1192 goto error_exit;
1193 }
1194 /* Get an ntfs attribute for $AttrDef/$DATA. */
1195 na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
1196 if (!na) {
1197 ntfs_log_perror("Failed to open ntfs attribute");
1198 goto error_exit;
1199 }
1200 /* Check we don't overflow 32-bits. */
1201 if (na->data_size > 0xffffffffLL) {
1202 ntfs_log_error("Attribute definition table is too big (max "
1203 "32-bit allowed).\n");
1204 errno = EINVAL;
1205 goto error_exit;
1206 }
1207 vol->attrdef_len = na->data_size;
1208 vol->attrdef = ntfs_malloc(na->data_size);
1209 if (!vol->attrdef)
1210 goto error_exit;
1211 /* Read in the $DATA attribute value into the buffer. */
1212 l = ntfs_attr_pread(na, 0, na->data_size, vol->attrdef);
1213 if (l != na->data_size) {
1214 ntfs_log_error("Failed to read $AttrDef, unexpected length "
1215 "(%lld != %lld).\n", (long long)l,
1216 (long long)na->data_size);
1217 errno = EIO;
1218 goto error_exit;
1219 }
1220 /* Done with the $AttrDef mft record. */
1221 ntfs_attr_close(na);
1222 if (ntfs_inode_close(ni)) {
1223 ntfs_log_perror("Failed to close $AttrDef");
1224 goto error_exit;
1225 }
1226 /*
1227 * Check for dirty logfile and hibernated Windows.
1228 * We care only about read-write mounts.
1229 */
1230 if (!(flags & (NTFS_MNT_RDONLY | NTFS_MNT_FORENSIC))) {
1231 if (!(flags & NTFS_MNT_IGNORE_HIBERFILE) &&
1232 ntfs_volume_check_hiberfile(vol, 1) < 0)
1233 goto error_exit;
1234 if (ntfs_volume_check_logfile(vol) < 0) {
1235 /* Always reject cached metadata for now */
1236 if (!(flags & NTFS_MNT_RECOVER) || (errno == EPERM))
1237 goto error_exit;
1238 ntfs_log_info("The file system wasn't safely "
1239 "closed on Windows. Fixing.\n");
1240 if (ntfs_logfile_reset(vol))
1241 goto error_exit;
1242 }
1243 /* make $TXF_DATA resident if present on the root directory */
1244 if (fix_txf_data(vol))
1245 goto error_exit;
1246 }
1247
1248 return vol;
1249io_error_exit:
1250 errno = EIO;
1251error_exit:
1252 eo = errno;
1253 if (ctx)
1254 ntfs_attr_put_search_ctx(ctx);
1255 free(m);
1256 free(m2);
1257 __ntfs_volume_release(vol);
1258 errno = eo;
1259 return NULL;
1260}
1261
1262/*
1263 * Set appropriate flags for showing NTFS metafiles
1264 * or files marked as hidden.
1265 * Not set in ntfs_mount() to avoid breaking existing tools.
1266 */
1267
1268int ntfs_set_shown_files(ntfs_volume *vol,
1269 BOOL show_sys_files, BOOL show_hid_files,
1270 BOOL hide_dot_files)
1271{
1272 int res;
1273
1274 res = -1;
1275 if (vol) {
1276 NVolClearShowSysFiles(vol);
1277 NVolClearShowHidFiles(vol);
1278 NVolClearHideDotFiles(vol);
1279 if (show_sys_files)
1280 NVolSetShowSysFiles(vol);
1281 if (show_hid_files)
1282 NVolSetShowHidFiles(vol);
1283 if (hide_dot_files)
1284 NVolSetHideDotFiles(vol);
1285 res = 0;
1286 }
1287 if (res)
1288 ntfs_log_error("Failed to set file visibility\n");
1289 return (res);
1290}
1291
1292/*
1293 * Set ignore case mode
1294 */
1295
1296int ntfs_set_ignore_case(ntfs_volume *vol)
1297{
1298 int res;
1299
1300 res = -1;
1301 if (vol && vol->upcase) {
1302 vol->locase = ntfs_locase_table_build(vol->upcase,
1303 vol->upcase_len);
1304 if (vol->locase) {
1305 NVolClearCaseSensitive(vol);
1306 res = 0;
1307 }
1308 }
1309 if (res)
1310 ntfs_log_error("Failed to set ignore_case mode\n");
1311 return (res);
1312}
1313
1314/**
1315 * ntfs_mount - open ntfs volume
1316 * @name: name of device/file to open
1317 * @flags: optional mount flags
1318 *
1319 * This function mounts an ntfs volume. @name should contain the name of the
1320 * device/file to mount as the ntfs volume.
1321 *
1322 * @flags is an optional second parameter. The same flags are used as for
1323 * the mount system call (man 2 mount). Currently only the following flags
1324 * is implemented:
1325 * NTFS_MNT_RDONLY - mount volume read-only
1326 *
1327 * The function opens the device or file @name and verifies that it contains a
1328 * valid bootsector. Then, it allocates an ntfs_volume structure and initializes
1329 * some of the values inside the structure from the information stored in the
1330 * bootsector. It proceeds to load the necessary system files and completes
1331 * setting up the structure.
1332 *
1333 * Return the allocated volume structure on success and NULL on error with
1334 * errno set to the error code.
1335 *
1336 * Note, that a copy is made of @name, and hence it can be discarded as
1337 * soon as the function returns.
1338 */
1339ntfs_volume *ntfs_mount(const char *name __attribute__((unused)),
1340 ntfs_mount_flags flags __attribute__((unused)))
1341{
1342#ifndef NO_NTFS_DEVICE_DEFAULT_IO_OPS
1343 struct ntfs_device *dev;
1344 ntfs_volume *vol;
1345
1346 /* Allocate an ntfs_device structure. */
1347 dev = ntfs_device_alloc(name, 0, &ntfs_device_default_io_ops, NULL);
1348 if (!dev)
1349 return NULL;
1350 /* Call ntfs_device_mount() to do the actual mount. */
1351 vol = ntfs_device_mount(dev, flags);
1352 if (!vol) {
1353 int eo = errno;
1354 ntfs_device_free(dev);
1355 errno = eo;
1356 } else
1357 ntfs_create_lru_caches(vol);
1358 return vol;
1359#else
1360 /*
1361 * ntfs_mount() makes no sense if NO_NTFS_DEVICE_DEFAULT_IO_OPS is
1362 * defined as there are no device operations available in libntfs in
1363 * this case.
1364 */
1365 errno = EOPNOTSUPP;
1366 return NULL;
1367#endif
1368}
1369
1370/**
1371 * ntfs_umount - close ntfs volume
1372 * @vol: address of ntfs_volume structure of volume to close
1373 * @force: if true force close the volume even if it is busy
1374 *
1375 * Deallocate all structures (including @vol itself) associated with the ntfs
1376 * volume @vol.
1377 *
1378 * Return 0 on success. On error return -1 with errno set appropriately
1379 * (most likely to one of EAGAIN, EBUSY or EINVAL). The EAGAIN error means that
1380 * an operation is in progress and if you try the close later the operation
1381 * might be completed and the close succeed.
1382 *
1383 * If @force is true (i.e. not zero) this function will close the volume even
1384 * if this means that data might be lost.
1385 *
1386 * @vol must have previously been returned by a call to ntfs_mount().
1387 *
1388 * @vol itself is deallocated and should no longer be dereferenced after this
1389 * function returns success. If it returns an error then nothing has been done
1390 * so it is safe to continue using @vol.
1391 */
1392int ntfs_umount(ntfs_volume *vol, const BOOL force __attribute__((unused)))
1393{
1394 struct ntfs_device *dev;
1395 int ret;
1396
1397 if (!vol) {
1398 errno = EINVAL;
1399 return -1;
1400 }
1401 dev = vol->dev;
1402 ret = __ntfs_volume_release(vol);
1403 ntfs_device_free(dev);
1404 return ret;
1405}
1406
1407#ifdef HAVE_MNTENT_H
1408
1409/**
1410 * ntfs_mntent_check - desc
1411 *
1412 * If you are wanting to use this, you actually wanted to use
1413 * ntfs_check_if_mounted(), you just didn't realize. (-:
1414 *
1415 * See description of ntfs_check_if_mounted(), below.
1416 */
1417static int ntfs_mntent_check(const char *file, unsigned long *mnt_flags)
1418{
1419 struct mntent *mnt;
1420 char *real_file = NULL, *real_fsname = NULL;
1421 FILE *f;
1422 int err = 0;
1423
1424 real_file = ntfs_malloc(PATH_MAX + 1);
1425 if (!real_file)
1426 return -1;
1427 real_fsname = ntfs_malloc(PATH_MAX + 1);
1428 if (!real_fsname) {
1429 err = errno;
1430 goto exit;
1431 }
1432 if (!ntfs_realpath_canonicalize(file, real_file)) {
1433 err = errno;
1434 goto exit;
1435 }
1436 f = setmntent("/proc/mounts", "r");
1437 if (!f && !(f = setmntent(MOUNTED, "r"))) {
1438 err = errno;
1439 goto exit;
1440 }
1441 while ((mnt = getmntent(f))) {
1442 if (!ntfs_realpath_canonicalize(mnt->mnt_fsname, real_fsname))
1443 continue;
1444 if (!strcmp(real_file, real_fsname))
1445 break;
1446 }
1447 endmntent(f);
1448 if (!mnt)
1449 goto exit;
1450 *mnt_flags = NTFS_MF_MOUNTED;
1451 if (!strcmp(mnt->mnt_dir, "/"))
1452 *mnt_flags |= NTFS_MF_ISROOT;
1453#ifdef HAVE_HASMNTOPT
1454 if (hasmntopt(mnt, "ro") && !hasmntopt(mnt, "rw"))
1455 *mnt_flags |= NTFS_MF_READONLY;
1456#endif
1457exit:
1458 free(real_file);
1459 free(real_fsname);
1460 if (err) {
1461 errno = err;
1462 return -1;
1463 }
1464 return 0;
1465}
1466
1467#else /* HAVE_MNTENT_H */
1468
1469#if defined(__sun) && defined (__SVR4)
1470
1471static int ntfs_mntent_check(const char *file, unsigned long *mnt_flags)
1472{
1473 struct mnttab *mnt = NULL;
1474 char *real_file = NULL, *real_fsname = NULL;
1475 FILE *f;
1476 int err = 0;
1477
1478 real_file = (char*)ntfs_malloc(PATH_MAX + 1);
1479 if (!real_file)
1480 return -1;
1481 real_fsname = (char*)ntfs_malloc(PATH_MAX + 1);
1482 mnt = (struct mnttab*)ntfs_malloc(MNT_LINE_MAX + 1);
1483 if (!real_fsname || !mnt) {
1484 err = errno;
1485 goto exit;
1486 }
1487 if (!ntfs_realpath_canonicalize(file, real_file)) {
1488 err = errno;
1489 goto exit;
1490 }
1491 if (!(f = fopen(MNTTAB, "r"))) {
1492 err = errno;
1493 goto exit;
1494 }
1495 while (!getmntent(f, mnt)) {
1496 if (!ntfs_realpath_canonicalize(mnt->mnt_special, real_fsname))
1497 continue;
1498 if (!strcmp(real_file, real_fsname)) {
1499 *mnt_flags = NTFS_MF_MOUNTED;
1500 if (!strcmp(mnt->mnt_mountp, "/"))
1501 *mnt_flags |= NTFS_MF_ISROOT;
1502 if (hasmntopt(mnt, "ro") && !hasmntopt(mnt, "rw"))
1503 *mnt_flags |= NTFS_MF_READONLY;
1504 break;
1505 }
1506 }
1507 fclose(f);
1508exit:
1509 free(mnt);
1510 free(real_file);
1511 free(real_fsname);
1512 if (err) {
1513 errno = err;
1514 return -1;
1515 }
1516 return 0;
1517}
1518
1519#endif /* defined(__sun) && defined (__SVR4) */
1520#endif /* HAVE_MNTENT_H */
1521
1522/**
1523 * ntfs_check_if_mounted - check if an ntfs volume is currently mounted
1524 * @file: device file to check
1525 * @mnt_flags: pointer into which to return the ntfs mount flags (see volume.h)
1526 *
1527 * If the running system does not support the {set,get,end}mntent() calls,
1528 * just return 0 and set *@mnt_flags to zero.
1529 *
1530 * When the system does support the calls, ntfs_check_if_mounted() first tries
1531 * to find the device @file in /etc/mtab (or wherever this is kept on the
1532 * running system). If it is not found, assume the device is not mounted and
1533 * return 0 and set *@mnt_flags to zero.
1534 *
1535 * If the device @file is found, set the NTFS_MF_MOUNTED flags in *@mnt_flags.
1536 *
1537 * Further if @file is mounted as the file system root ("/"), set the flag
1538 * NTFS_MF_ISROOT in *@mnt_flags.
1539 *
1540 * Finally, check if the file system is mounted read-only, and if so set the
1541 * NTFS_MF_READONLY flag in *@mnt_flags.
1542 *
1543 * On success return 0 with *@mnt_flags set to the ntfs mount flags.
1544 *
1545 * On error return -1 with errno set to the error code.
1546 */
1547int ntfs_check_if_mounted(const char *file __attribute__((unused)),
1548 unsigned long *mnt_flags)
1549{
1550 *mnt_flags = 0;
1551#if defined(HAVE_MNTENT_H) || (defined(__sun) && defined (__SVR4))
1552 return ntfs_mntent_check(file, mnt_flags);
1553#else
1554 return 0;
1555#endif
1556}
1557
1558/**
1559 * ntfs_version_is_supported - check if NTFS version is supported.
1560 * @vol: ntfs volume whose version we're interested in.
1561 *
1562 * The function checks if the NTFS volume version is known or not.
1563 * Version 1.1 and 1.2 are used by Windows NT3.x and NT4.
1564 * Version 2.x is used by Windows 2000 Betas.
1565 * Version 3.0 is used by Windows 2000.
1566 * Version 3.1 is used by Windows XP, Windows Server 2003 and Longhorn.
1567 *
1568 * Return 0 if NTFS version is supported otherwise -1 with errno set.
1569 *
1570 * The following error codes are defined:
1571 * EOPNOTSUPP - Unknown NTFS version
1572 * EINVAL - Invalid argument
1573 */
1574int ntfs_version_is_supported(ntfs_volume *vol)
1575{
1576 u8 major, minor;
1577
1578 if (!vol) {
1579 errno = EINVAL;
1580 return -1;
1581 }
1582
1583 major = vol->major_ver;
1584 minor = vol->minor_ver;
1585
1586 if (NTFS_V1_1(major, minor) || NTFS_V1_2(major, minor))
1587 return 0;
1588
1589 if (NTFS_V2_X(major, minor))
1590 return 0;
1591
1592 if (NTFS_V3_0(major, minor) || NTFS_V3_1(major, minor))
1593 return 0;
1594
1595 errno = EOPNOTSUPP;
1596 return -1;
1597}
1598
1599/**
1600 * ntfs_logfile_reset - "empty" $LogFile data attribute value
1601 * @vol: ntfs volume whose $LogFile we intend to reset.
1602 *
1603 * Fill the value of the $LogFile data attribute, i.e. the contents of
1604 * the file, with 0xff's, thus marking the journal as empty.
1605 *
1606 * FIXME(?): We might need to zero the LSN field of every single mft
1607 * record as well. (But, first try without doing that and see what
1608 * happens, since chkdsk might pickup the pieces and do it for us...)
1609 *
1610 * On success return 0.
1611 *
1612 * On error return -1 with errno set to the error code.
1613 */
1614int ntfs_logfile_reset(ntfs_volume *vol)
1615{
1616 ntfs_inode *ni;
1617 ntfs_attr *na;
1618 int eo;
1619
1620 if (!vol) {
1621 errno = EINVAL;
1622 return -1;
1623 }
1624
1625 ni = ntfs_inode_open(vol, FILE_LogFile);
1626 if (!ni) {
1627 ntfs_log_perror("Failed to open inode FILE_LogFile");
1628 return -1;
1629 }
1630
1631 na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
1632 if (!na) {
1633 eo = errno;
1634 ntfs_log_perror("Failed to open $FILE_LogFile/$DATA");
1635 goto error_exit;
1636 }
1637
1638 if (ntfs_empty_logfile(na)) {
1639 eo = errno;
1640 ntfs_attr_close(na);
1641 goto error_exit;
1642 }
1643
1644 ntfs_attr_close(na);
1645 return ntfs_inode_close(ni);
1646
1647error_exit:
1648 ntfs_inode_close(ni);
1649 errno = eo;
1650 return -1;
1651}
1652
1653/**
1654 * ntfs_volume_write_flags - set the flags of an ntfs volume
1655 * @vol: ntfs volume where we set the volume flags
1656 * @flags: new flags
1657 *
1658 * Set the on-disk volume flags in the mft record of $Volume and
1659 * on volume @vol to @flags.
1660 *
1661 * Return 0 if successful and -1 if not with errno set to the error code.
1662 */
1663int ntfs_volume_write_flags(ntfs_volume *vol, const le16 flags)
1664{
1665 ATTR_RECORD *a;
1666 VOLUME_INFORMATION *c;
1667 ntfs_attr_search_ctx *ctx;
1668 int ret = -1; /* failure */
1669
1670 if (!vol || !vol->vol_ni) {
1671 errno = EINVAL;
1672 return -1;
1673 }
1674 /* Get a pointer to the volume information attribute. */
1675 ctx = ntfs_attr_get_search_ctx(vol->vol_ni, NULL);
1676 if (!ctx)
1677 return -1;
1678
1679 if (ntfs_attr_lookup(AT_VOLUME_INFORMATION, AT_UNNAMED, 0, 0, 0, NULL,
1680 0, ctx)) {
1681 ntfs_log_error("Attribute $VOLUME_INFORMATION was not found "
1682 "in $Volume!\n");
1683 goto err_out;
1684 }
1685 a = ctx->attr;
1686 /* Sanity check. */
1687 if (a->non_resident) {
1688 ntfs_log_error("Attribute $VOLUME_INFORMATION must be resident "
1689 "but it isn't.\n");
1690 errno = EIO;
1691 goto err_out;
1692 }
1693 /* Get a pointer to the value of the attribute. */
1694 c = (VOLUME_INFORMATION*)(le16_to_cpu(a->value_offset) + (char*)a);
1695 /* Sanity checks. */
1696 if ((char*)c + le32_to_cpu(a->value_length) > (char*)ctx->mrec +
1697 le32_to_cpu(ctx->mrec->bytes_in_use) ||
1698 le16_to_cpu(a->value_offset) +
1699 le32_to_cpu(a->value_length) > le32_to_cpu(a->length)) {
1700 ntfs_log_error("Attribute $VOLUME_INFORMATION in $Volume is "
1701 "corrupt!\n");
1702 errno = EIO;
1703 goto err_out;
1704 }
1705 /* Set the volume flags. */
1706 vol->flags = c->flags = flags & VOLUME_FLAGS_MASK;
1707 /* Write them to disk. */
1708 ntfs_inode_mark_dirty(vol->vol_ni);
1709 if (ntfs_inode_sync(vol->vol_ni))
1710 goto err_out;
1711
1712 ret = 0; /* success */
1713err_out:
1714 ntfs_attr_put_search_ctx(ctx);
1715 return ret;
1716}
1717
1718int ntfs_volume_error(int err)
1719{
1720 int ret;
1721
1722 switch (err) {
1723 case 0:
1724 ret = NTFS_VOLUME_OK;
1725 break;
1726 case EINVAL:
1727 ret = NTFS_VOLUME_NOT_NTFS;
1728 break;
1729 case EIO:
1730 ret = NTFS_VOLUME_CORRUPT;
1731 break;
1732 case EPERM:
1733 /*
1734 * Hibernation and fast restarting are seen the
1735 * same way on a non Windows-system partition.
1736 */
1737 ret = NTFS_VOLUME_HIBERNATED;
1738 break;
1739 case EOPNOTSUPP:
1740 ret = NTFS_VOLUME_UNCLEAN_UNMOUNT;
1741 break;
1742 case EBUSY:
1743 ret = NTFS_VOLUME_LOCKED;
1744 break;
1745 case ENXIO:
1746 ret = NTFS_VOLUME_RAID;
1747 break;
1748 case EACCES:
1749 ret = NTFS_VOLUME_NO_PRIVILEGE;
1750 break;
1751 default:
1752 ret = NTFS_VOLUME_UNKNOWN_REASON;
1753 break;
1754 }
1755 return ret;
1756}
1757
1758
1759void ntfs_mount_error(const char *volume, const char *mntpoint, int err)
1760{
1761 switch (err) {
1762 case NTFS_VOLUME_NOT_NTFS:
1763 ntfs_log_error(invalid_ntfs_msg, volume);
1764 break;
1765 case NTFS_VOLUME_CORRUPT:
1766 ntfs_log_error("%s", corrupt_volume_msg);
1767 break;
1768 case NTFS_VOLUME_HIBERNATED:
1769 ntfs_log_error(hibernated_volume_msg, volume, mntpoint);
1770 break;
1771 case NTFS_VOLUME_UNCLEAN_UNMOUNT:
1772 ntfs_log_error("%s", unclean_journal_msg);
1773 break;
1774 case NTFS_VOLUME_LOCKED:
1775 ntfs_log_error("%s", opened_volume_msg);
1776 break;
1777 case NTFS_VOLUME_RAID:
1778 ntfs_log_error("%s", fakeraid_msg);
1779 break;
1780 case NTFS_VOLUME_NO_PRIVILEGE:
1781 ntfs_log_error(access_denied_msg, volume);
1782 break;
1783 }
1784}
1785
1786int ntfs_set_locale(void)
1787{
1788 const char *locale;
1789
1790 locale = setlocale(LC_ALL, "");
1791 if (!locale) {
1792 locale = setlocale(LC_ALL, NULL);
1793 ntfs_log_error("Couldn't set local environment, using default "
1794 "'%s'.\n", locale);
1795 return 1;
1796 }
1797 return 0;
1798}
1799
1800/*
1801 * Feed the counts of free clusters and free mft records
1802 */
1803
1804int ntfs_volume_get_free_space(ntfs_volume *vol)
1805{
1806 ntfs_attr *na;
1807 int ret;
1808
1809 ret = -1; /* default return */
1810 vol->free_clusters = ntfs_attr_get_free_bits(vol->lcnbmp_na);
1811 if (vol->free_clusters < 0) {
1812 ntfs_log_perror("Failed to read NTFS $Bitmap");
1813 } else {
1814 na = vol->mftbmp_na;
1815 vol->free_mft_records = ntfs_attr_get_free_bits(na);
1816
1817 if (vol->free_mft_records >= 0)
1818 vol->free_mft_records += (na->allocated_size - na->data_size) << 3;
1819
1820 if (vol->free_mft_records < 0)
1821 ntfs_log_perror("Failed to calculate free MFT records");
1822 else
1823 ret = 0;
1824 }
1825 return (ret);
1826}
1827
1828/**
1829 * ntfs_volume_rename - change the current label on a volume
1830 * @vol: volume to change the label on
1831 * @label: the new label
1832 * @label_len: the length of @label in ntfschars including the terminating NULL
1833 * character, which is mandatory (the value can not exceed 128)
1834 *
1835 * Change the label on the volume @vol to @label.
1836 */
1837int ntfs_volume_rename(ntfs_volume *vol, const ntfschar *label, int label_len)
1838{
1839 ntfs_attr *na;
1840 char *old_vol_name;
1841 char *new_vol_name = NULL;
1842 int new_vol_name_len;
1843 int err;
1844
1845 if (NVolReadOnly(vol)) {
1846 ntfs_log_error("Refusing to change label on read-only mounted "
1847 "volume.\n");
1848 errno = EROFS;
1849 return -1;
1850 }
1851
1852 label_len *= sizeof(ntfschar);
1853 if (label_len > 0x100) {
1854 ntfs_log_error("New label is too long. Maximum %u characters "
1855 "allowed.\n",
1856 (unsigned)(0x100 / sizeof(ntfschar)));
1857 errno = ERANGE;
1858 return -1;
1859 }
1860
1861 na = ntfs_attr_open(vol->vol_ni, AT_VOLUME_NAME, AT_UNNAMED, 0);
1862 if (!na) {
1863 if (errno != ENOENT) {
1864 err = errno;
1865 ntfs_log_perror("Lookup of $VOLUME_NAME attribute "
1866 "failed");
1867 goto err_out;
1868 }
1869
1870 /* The volume name attribute does not exist. Need to add it. */
1871 if (ntfs_attr_add(vol->vol_ni, AT_VOLUME_NAME, AT_UNNAMED, 0,
1872 (const u8*) label, label_len))
1873 {
1874 err = errno;
1875 ntfs_log_perror("Encountered error while adding "
1876 "$VOLUME_NAME attribute");
1877 goto err_out;
1878 }
1879 }
1880 else {
1881 s64 written;
1882
1883 if (NAttrNonResident(na)) {
1884 err = errno;
1885 ntfs_log_error("Error: Attribute $VOLUME_NAME must be "
1886 "resident.\n");
1887 goto err_out;
1888 }
1889
1890 if (na->data_size != label_len) {
1891 if (ntfs_attr_truncate(na, label_len)) {
1892 err = errno;
1893 ntfs_log_perror("Error resizing resident "
1894 "attribute");
1895 goto err_out;
1896 }
1897 }
1898
1899 if (label_len) {
1900 written = ntfs_attr_pwrite(na, 0, label_len, label);
1901 if (written == -1) {
1902 err = errno;
1903 ntfs_log_perror("Error when writing "
1904 "$VOLUME_NAME data");
1905 goto err_out;
1906 }
1907 else if (written != label_len) {
1908 err = EIO;
1909 ntfs_log_error("Partial write when writing "
1910 "$VOLUME_NAME data.");
1911 goto err_out;
1912
1913 }
1914 }
1915 }
1916
1917 new_vol_name_len =
1918 ntfs_ucstombs(label, label_len, &new_vol_name, 0);
1919 if (new_vol_name_len == -1) {
1920 err = errno;
1921 ntfs_log_perror("Error while decoding new volume name");
1922 goto err_out;
1923 }
1924
1925 old_vol_name = vol->vol_name;
1926 vol->vol_name = new_vol_name;
1927 free(old_vol_name);
1928
1929 err = 0;
1930err_out:
1931 if (na)
1932 ntfs_attr_close(na);
1933 if (err)
1934 errno = err;
1935 return err ? -1 : 0;
1936}
1937