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