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