1 /** 2 * dir.c - Directory handling code. Originated from the Linux-NTFS project. 3 * 4 * Copyright (c) 2002-2005 Anton Altaparmakov 5 * Copyright (c) 2004-2005 Richard Russon 6 * Copyright (c) 2004-2008 Szabolcs Szakacsits 7 * Copyright (c) 2005-2007 Yura Pakhuchiy 8 * Copyright (c) 2008-2021 Jean-Pierre Andre 9 * 10 * This program/include file is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License as published 12 * by the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program/include file is distributed in the hope that it will be 16 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 17 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program (in the main directory of the NTFS-3G 22 * distribution in the file COPYING); if not, write to the Free Software 23 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 */ 25 26 #ifdef HAVE_CONFIG_H 27 #include "config.h" 28 #endif 29 30 #ifdef HAVE_STDLIB_H 31 #include <stdlib.h> 32 #endif 33 #ifdef HAVE_ERRNO_H 34 #include <errno.h> 35 #endif 36 #ifdef HAVE_STRING_H 37 #include <string.h> 38 #endif 39 #ifdef HAVE_SYS_STAT_H 40 #include <sys/stat.h> 41 #endif 42 43 #ifdef HAVE_SYS_TYPES_H 44 #include <sys/types.h> 45 #endif 46 #ifdef MAJOR_IN_MKDEV 47 #include <sys/mkdev.h> 48 #endif 49 #ifdef MAJOR_IN_SYSMACROS 50 #include <sys/sysmacros.h> 51 #endif 52 53 #include "param.h" 54 #include "types.h" 55 #include "debug.h" 56 #include "attrib.h" 57 #include "inode.h" 58 #include "dir.h" 59 #include "volume.h" 60 #include "mft.h" 61 #include "index.h" 62 #include "ntfstime.h" 63 #include "lcnalloc.h" 64 #include "logging.h" 65 #include "cache.h" 66 #include "misc.h" 67 #include "security.h" 68 #include "reparse.h" 69 #include "object_id.h" 70 #include "xattrs.h" 71 #include "ea.h" 72 73 /* 74 * The little endian Unicode strings "$I30", "$SII", "$SDH", "$O" 75 * and "$Q" as global constants. 76 */ 77 ntfschar NTFS_INDEX_I30[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('I'), 78 const_cpu_to_le16('3'), const_cpu_to_le16('0'), 79 const_cpu_to_le16('\0') }; 80 ntfschar NTFS_INDEX_SII[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('S'), 81 const_cpu_to_le16('I'), const_cpu_to_le16('I'), 82 const_cpu_to_le16('\0') }; 83 ntfschar NTFS_INDEX_SDH[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('S'), 84 const_cpu_to_le16('D'), const_cpu_to_le16('H'), 85 const_cpu_to_le16('\0') }; 86 ntfschar NTFS_INDEX_O[3] = { const_cpu_to_le16('$'), const_cpu_to_le16('O'), 87 const_cpu_to_le16('\0') }; 88 ntfschar NTFS_INDEX_Q[3] = { const_cpu_to_le16('$'), const_cpu_to_le16('Q'), 89 const_cpu_to_le16('\0') }; 90 ntfschar NTFS_INDEX_R[3] = { const_cpu_to_le16('$'), const_cpu_to_le16('R'), 91 const_cpu_to_le16('\0') }; 92 93 #if CACHE_INODE_SIZE 94 95 /* 96 * Pathname hashing 97 * 98 * Based on first char and second char (which may be '\0') 99 */ 100 101 int ntfs_dir_inode_hash(const struct CACHED_GENERIC *cached) 102 { 103 const char *path; 104 const unsigned char *name; 105 106 path = (const char*)cached->variable; 107 if (!path) { 108 ntfs_log_error("Bad inode cache entry\n"); 109 return (-1); 110 } 111 name = (const unsigned char*)strrchr(path,'/'); 112 if (!name) 113 name = (const unsigned char*)path; 114 return (((name[0] << 1) + name[1] + strlen((const char*)name)) 115 % (2*CACHE_INODE_SIZE)); 116 } 117 118 /* 119 * Pathname comparing for entering/fetching from cache 120 */ 121 122 static int inode_cache_compare(const struct CACHED_GENERIC *cached, 123 const struct CACHED_GENERIC *wanted) 124 { 125 return (!cached->variable 126 || strcmp(cached->variable, wanted->variable)); 127 } 128 129 /* 130 * Pathname comparing for invalidating entries in cache 131 * 132 * A partial path is compared in order to invalidate all paths 133 * related to a renamed directory 134 * inode numbers are also checked, as deleting a long name may 135 * imply deleting a short name and conversely 136 * 137 * Only use associated with a CACHE_NOHASH flag 138 */ 139 140 static int inode_cache_inv_compare(const struct CACHED_GENERIC *cached, 141 const struct CACHED_GENERIC *wanted) 142 { 143 int len; 144 BOOL different; 145 const struct CACHED_INODE *w; 146 const struct CACHED_INODE *c; 147 148 w = (const struct CACHED_INODE*)wanted; 149 c = (const struct CACHED_INODE*)cached; 150 if (w->pathname) { 151 len = strlen(w->pathname); 152 different = !cached->variable 153 || ((w->inum != MREF(c->inum)) 154 && (strncmp(c->pathname, w->pathname, len) 155 || ((c->pathname[len] != '\0') 156 && (c->pathname[len] != '/')))); 157 } else 158 different = !c->pathname 159 || (w->inum != MREF(c->inum)); 160 return (different); 161 } 162 163 #endif 164 165 #if CACHE_LOOKUP_SIZE 166 167 /* 168 * File name comparing for entering/fetching from lookup cache 169 */ 170 171 static int lookup_cache_compare(const struct CACHED_GENERIC *cached, 172 const struct CACHED_GENERIC *wanted) 173 { 174 const struct CACHED_LOOKUP *c = (const struct CACHED_LOOKUP*) cached; 175 const struct CACHED_LOOKUP *w = (const struct CACHED_LOOKUP*) wanted; 176 return (!c->name 177 || (c->parent != w->parent) 178 || (c->namesize != w->namesize) 179 || memcmp(c->name, w->name, c->namesize)); 180 } 181 182 /* 183 * Inode number comparing for invalidating lookup cache 184 * 185 * All entries with designated inode number are invalidated 186 * 187 * Only use associated with a CACHE_NOHASH flag 188 */ 189 190 static int lookup_cache_inv_compare(const struct CACHED_GENERIC *cached, 191 const struct CACHED_GENERIC *wanted) 192 { 193 const struct CACHED_LOOKUP *c = (const struct CACHED_LOOKUP*) cached; 194 const struct CACHED_LOOKUP *w = (const struct CACHED_LOOKUP*) wanted; 195 return (!c->name 196 || (c->parent != w->parent) 197 || (MREF(c->inum) != MREF(w->inum))); 198 } 199 200 /* 201 * Lookup hashing 202 * 203 * Based on first, second and and last char 204 */ 205 206 int ntfs_dir_lookup_hash(const struct CACHED_GENERIC *cached) 207 { 208 const unsigned char *name; 209 int count; 210 unsigned int val; 211 212 name = (const unsigned char*)cached->variable; 213 count = cached->varsize; 214 if (!name || !count) { 215 ntfs_log_error("Bad lookup cache entry\n"); 216 return (-1); 217 } 218 val = (name[0] << 2) + (name[1] << 1) + name[count - 1] + count; 219 return (val % (2*CACHE_LOOKUP_SIZE)); 220 } 221 222 #endif 223 224 /** 225 * ntfs_inode_lookup_by_name - find an inode in a directory given its name 226 * @dir_ni: ntfs inode of the directory in which to search for the name 227 * @uname: Unicode name for which to search in the directory 228 * @uname_len: length of the name @uname in Unicode characters 229 * 230 * Look for an inode with name @uname in the directory with inode @dir_ni. 231 * ntfs_inode_lookup_by_name() walks the contents of the directory looking for 232 * the Unicode name. If the name is found in the directory, the corresponding 233 * inode number (>= 0) is returned as a mft reference in cpu format, i.e. it 234 * is a 64-bit number containing the sequence number. 235 * 236 * On error, return -1 with errno set to the error code. If the inode is is not 237 * found errno is ENOENT. 238 * 239 * Note, @uname_len does not include the (optional) terminating NULL character. 240 * 241 * Note, we look for a case sensitive match first but we also look for a case 242 * insensitive match at the same time. If we find a case insensitive match, we 243 * save that for the case that we don't find an exact match, where we return 244 * the mft reference of the case insensitive match. 245 * 246 * If the volume is mounted with the case sensitive flag set, then we only 247 * allow exact matches. 248 */ 249 u64 ntfs_inode_lookup_by_name(ntfs_inode *dir_ni, 250 const ntfschar *uname, const int uname_len) 251 { 252 VCN vcn; 253 u64 mref = 0; 254 s64 br; 255 ntfs_volume *vol = dir_ni->vol; 256 ntfs_attr_search_ctx *ctx; 257 INDEX_ROOT *ir; 258 INDEX_ENTRY *ie; 259 INDEX_ALLOCATION *ia; 260 IGNORE_CASE_BOOL case_sensitivity; 261 u8 *index_end; 262 ntfs_attr *ia_na; 263 int eo, rc; 264 u32 index_block_size; 265 u8 index_vcn_size_bits; 266 267 ntfs_log_trace("Entering\n"); 268 269 if (!dir_ni || !dir_ni->mrec || !uname || uname_len <= 0) { 270 errno = EINVAL; 271 return -1; 272 } 273 274 ctx = ntfs_attr_get_search_ctx(dir_ni, NULL); 275 if (!ctx) 276 return -1; 277 278 /* Find the index root attribute in the mft record. */ 279 if (ntfs_attr_lookup(AT_INDEX_ROOT, NTFS_INDEX_I30, 4, CASE_SENSITIVE, 0, NULL, 280 0, ctx)) { 281 ntfs_log_perror("Index root attribute missing in directory inode " 282 "%lld", (unsigned long long)dir_ni->mft_no); 283 goto put_err_out; 284 } 285 case_sensitivity = (NVolCaseSensitive(vol) ? CASE_SENSITIVE : IGNORE_CASE); 286 /* Get to the index root value. */ 287 ir = (INDEX_ROOT*)((u8*)ctx->attr + 288 le16_to_cpu(ctx->attr->value_offset)); 289 index_block_size = le32_to_cpu(ir->index_block_size); 290 if (index_block_size < NTFS_BLOCK_SIZE || 291 index_block_size & (index_block_size - 1)) { 292 ntfs_log_error("Index block size %u is invalid.\n", 293 (unsigned)index_block_size); 294 goto put_err_out; 295 } 296 /* Consistency check of ir done while fetching attribute */ 297 index_end = (u8*)&ir->index + le32_to_cpu(ir->index.index_length); 298 /* The first index entry. */ 299 ie = (INDEX_ENTRY*)((u8*)&ir->index + 300 le32_to_cpu(ir->index.entries_offset)); 301 /* 302 * Loop until we exceed valid memory (corruption case) or until we 303 * reach the last entry. 304 */ 305 for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) { 306 /* Bounds checks. */ 307 if ((u8*)ie < (u8*)ctx->mrec || (u8*)ie + 308 sizeof(INDEX_ENTRY_HEADER) > index_end || 309 (u8*)ie + le16_to_cpu(ie->length) > 310 index_end) { 311 ntfs_log_error("Index root entry out of bounds in" 312 " inode %lld\n", 313 (unsigned long long)dir_ni->mft_no); 314 goto put_err_out; 315 } 316 /* 317 * The last entry cannot contain a name. It can however contain 318 * a pointer to a child node in the B+tree so we just break out. 319 */ 320 if (ie->ie_flags & INDEX_ENTRY_END) 321 break; 322 323 /* The file name must not overflow from the entry */ 324 if (ntfs_index_entry_inconsistent(ie, COLLATION_FILE_NAME, 325 dir_ni->mft_no)) { 326 errno = EIO; 327 goto put_err_out; 328 } 329 /* 330 * Not a perfect match, need to do full blown collation so we 331 * know which way in the B+tree we have to go. 332 */ 333 rc = ntfs_names_full_collate(uname, uname_len, 334 (ntfschar*)&ie->key.file_name.file_name, 335 ie->key.file_name.file_name_length, 336 case_sensitivity, vol->upcase, vol->upcase_len); 337 /* 338 * If uname collates before the name of the current entry, there 339 * is definitely no such name in this index but we might need to 340 * descend into the B+tree so we just break out of the loop. 341 */ 342 if (rc == -1) 343 break; 344 /* The names are not equal, continue the search. */ 345 if (rc) 346 continue; 347 /* 348 * Perfect match, this will never happen as the 349 * ntfs_are_names_equal() call will have gotten a match but we 350 * still treat it correctly. 351 */ 352 mref = le64_to_cpu(ie->indexed_file); 353 ntfs_attr_put_search_ctx(ctx); 354 return mref; 355 } 356 /* 357 * We have finished with this index without success. Check for the 358 * presence of a child node and if not present return error code 359 * ENOENT, unless we have got the mft reference of a matching name 360 * cached in mref in which case return mref. 361 */ 362 if (!(ie->ie_flags & INDEX_ENTRY_NODE)) { 363 ntfs_attr_put_search_ctx(ctx); 364 if (mref) 365 return mref; 366 ntfs_log_debug("Entry not found - between root entries.\n"); 367 errno = ENOENT; 368 return -1; 369 } /* Child node present, descend into it. */ 370 371 /* Open the index allocation attribute. */ 372 ia_na = ntfs_attr_open(dir_ni, AT_INDEX_ALLOCATION, NTFS_INDEX_I30, 4); 373 if (!ia_na) { 374 ntfs_log_perror("Failed to open index allocation (inode %lld)", 375 (unsigned long long)dir_ni->mft_no); 376 goto put_err_out; 377 } 378 379 /* Allocate a buffer for the current index block. */ 380 ia = ntfs_malloc(index_block_size); 381 if (!ia) { 382 ntfs_attr_close(ia_na); 383 goto put_err_out; 384 } 385 386 /* Determine the size of a vcn in the directory index. */ 387 if (vol->cluster_size <= index_block_size) { 388 index_vcn_size_bits = vol->cluster_size_bits; 389 } else { 390 index_vcn_size_bits = NTFS_BLOCK_SIZE_BITS; 391 } 392 393 /* Get the starting vcn of the index_block holding the child node. */ 394 vcn = sle64_to_cpup((sle64*)((u8*)ie + le16_to_cpu(ie->length) - 8)); 395 396 descend_into_child_node: 397 398 /* Read the index block starting at vcn. */ 399 br = ntfs_attr_mst_pread(ia_na, vcn << index_vcn_size_bits, 1, 400 index_block_size, ia); 401 if (br != 1) { 402 if (br != -1) 403 errno = EIO; 404 ntfs_log_perror("Failed to read vcn 0x%llx from inode %lld", 405 (unsigned long long)vcn, 406 (unsigned long long)ia_na->ni->mft_no); 407 goto close_err_out; 408 } 409 410 if (ntfs_index_block_inconsistent((INDEX_BLOCK*)ia, index_block_size, 411 ia_na->ni->mft_no, vcn)) { 412 errno = EIO; 413 goto close_err_out; 414 } 415 index_end = (u8*)&ia->index + le32_to_cpu(ia->index.index_length); 416 417 /* The first index entry. */ 418 ie = (INDEX_ENTRY*)((u8*)&ia->index + 419 le32_to_cpu(ia->index.entries_offset)); 420 /* 421 * Iterate similar to above big loop but applied to index buffer, thus 422 * loop until we exceed valid memory (corruption case) or until we 423 * reach the last entry. 424 */ 425 for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) { 426 /* Bounds check. */ 427 if ((u8*)ie < (u8*)ia || (u8*)ie + 428 sizeof(INDEX_ENTRY_HEADER) > index_end || 429 (u8*)ie + le16_to_cpu(ie->length) > 430 index_end) { 431 ntfs_log_error("Index entry out of bounds in directory " 432 "inode %lld.\n", 433 (unsigned long long)dir_ni->mft_no); 434 errno = EIO; 435 goto close_err_out; 436 } 437 /* 438 * The last entry cannot contain a name. It can however contain 439 * a pointer to a child node in the B+tree so we just break out. 440 */ 441 if (ie->ie_flags & INDEX_ENTRY_END) 442 break; 443 444 /* The file name must not overflow from the entry */ 445 if (ntfs_index_entry_inconsistent(ie, COLLATION_FILE_NAME, 446 dir_ni->mft_no)) { 447 errno = EIO; 448 goto close_err_out; 449 } 450 /* 451 * Not a perfect match, need to do full blown collation so we 452 * know which way in the B+tree we have to go. 453 */ 454 rc = ntfs_names_full_collate(uname, uname_len, 455 (ntfschar*)&ie->key.file_name.file_name, 456 ie->key.file_name.file_name_length, 457 case_sensitivity, vol->upcase, vol->upcase_len); 458 /* 459 * If uname collates before the name of the current entry, there 460 * is definitely no such name in this index but we might need to 461 * descend into the B+tree so we just break out of the loop. 462 */ 463 if (rc == -1) 464 break; 465 /* The names are not equal, continue the search. */ 466 if (rc) 467 continue; 468 mref = le64_to_cpu(ie->indexed_file); 469 free(ia); 470 ntfs_attr_close(ia_na); 471 ntfs_attr_put_search_ctx(ctx); 472 return mref; 473 } 474 /* 475 * We have finished with this index buffer without success. Check for 476 * the presence of a child node. 477 */ 478 if (ie->ie_flags & INDEX_ENTRY_NODE) { 479 if ((ia->index.ih_flags & NODE_MASK) == LEAF_NODE) { 480 ntfs_log_error("Index entry with child node found in a leaf " 481 "node in directory inode %lld.\n", 482 (unsigned long long)dir_ni->mft_no); 483 errno = EIO; 484 goto close_err_out; 485 } 486 /* Child node present, descend into it. */ 487 vcn = sle64_to_cpup((sle64*)((u8*)ie + le16_to_cpu(ie->length) - 8)); 488 if (vcn >= 0) 489 goto descend_into_child_node; 490 ntfs_log_error("Negative child node vcn in directory inode " 491 "0x%llx.\n", (unsigned long long)dir_ni->mft_no); 492 errno = EIO; 493 goto close_err_out; 494 } 495 free(ia); 496 ntfs_attr_close(ia_na); 497 ntfs_attr_put_search_ctx(ctx); 498 /* 499 * No child node present, return error code ENOENT, unless we have got 500 * the mft reference of a matching name cached in mref in which case 501 * return mref. 502 */ 503 if (mref) 504 return mref; 505 ntfs_log_debug("Entry not found.\n"); 506 errno = ENOENT; 507 return -1; 508 put_err_out: 509 eo = EIO; 510 ntfs_log_debug("Corrupt directory. Aborting lookup.\n"); 511 eo_put_err_out: 512 ntfs_attr_put_search_ctx(ctx); 513 errno = eo; 514 return -1; 515 close_err_out: 516 eo = errno; 517 free(ia); 518 ntfs_attr_close(ia_na); 519 goto eo_put_err_out; 520 } 521 522 /* 523 * Lookup a file in a directory from its UTF-8 name 524 * 525 * The name is first fetched from cache if one is defined 526 * 527 * Returns the inode number 528 * or -1 if not possible (errno tells why) 529 */ 530 531 u64 ntfs_inode_lookup_by_mbsname(ntfs_inode *dir_ni, const char *name) 532 { 533 int uname_len; 534 ntfschar *uname = (ntfschar*)NULL; 535 u64 inum; 536 char *cached_name; 537 const char *const_name; 538 539 if (!NVolCaseSensitive(dir_ni->vol)) { 540 cached_name = ntfs_uppercase_mbs(name, 541 dir_ni->vol->upcase, dir_ni->vol->upcase_len); 542 const_name = cached_name; 543 } else { 544 cached_name = (char*)NULL; 545 const_name = name; 546 } 547 if (const_name) { 548 #if CACHE_LOOKUP_SIZE 549 550 /* 551 * fetch inode from cache 552 */ 553 554 if (dir_ni->vol->lookup_cache) { 555 struct CACHED_LOOKUP item; 556 struct CACHED_LOOKUP *cached; 557 558 item.name = const_name; 559 item.namesize = strlen(const_name) + 1; 560 item.parent = dir_ni->mft_no; 561 cached = (struct CACHED_LOOKUP*)ntfs_fetch_cache( 562 dir_ni->vol->lookup_cache, 563 GENERIC(&item), lookup_cache_compare); 564 if (cached) { 565 inum = cached->inum; 566 if (inum == (u64)-1) 567 errno = ENOENT; 568 } else { 569 /* Generate unicode name. */ 570 uname_len = ntfs_mbstoucs(name, &uname); 571 if (uname_len >= 0) { 572 inum = ntfs_inode_lookup_by_name(dir_ni, 573 uname, uname_len); 574 item.inum = inum; 575 /* enter into cache, even if not found */ 576 ntfs_enter_cache(dir_ni->vol->lookup_cache, 577 GENERIC(&item), 578 lookup_cache_compare); 579 free(uname); 580 } else 581 inum = (s64)-1; 582 } 583 } else 584 #endif 585 { 586 /* Generate unicode name. */ 587 uname_len = ntfs_mbstoucs(cached_name, &uname); 588 if (uname_len >= 0) 589 inum = ntfs_inode_lookup_by_name(dir_ni, 590 uname, uname_len); 591 else 592 inum = (s64)-1; 593 } 594 if (cached_name) 595 free(cached_name); 596 } else 597 inum = (s64)-1; 598 return (inum); 599 } 600 601 /* 602 * Update a cache lookup record when a name has been defined 603 * 604 * The UTF-8 name is required 605 */ 606 607 void ntfs_inode_update_mbsname(ntfs_inode *dir_ni, const char *name, u64 inum) 608 { 609 #if CACHE_LOOKUP_SIZE 610 struct CACHED_LOOKUP item; 611 struct CACHED_LOOKUP *cached; 612 char *cached_name; 613 614 if (dir_ni->vol->lookup_cache) { 615 if (!NVolCaseSensitive(dir_ni->vol)) { 616 cached_name = ntfs_uppercase_mbs(name, 617 dir_ni->vol->upcase, dir_ni->vol->upcase_len); 618 item.name = cached_name; 619 } else { 620 cached_name = (char*)NULL; 621 item.name = name; 622 } 623 if (item.name) { 624 item.namesize = strlen(item.name) + 1; 625 item.parent = dir_ni->mft_no; 626 item.inum = inum; 627 cached = (struct CACHED_LOOKUP*)ntfs_enter_cache( 628 dir_ni->vol->lookup_cache, 629 GENERIC(&item), lookup_cache_compare); 630 if (cached) 631 cached->inum = inum; 632 if (cached_name) 633 free(cached_name); 634 } 635 } 636 #endif 637 } 638 639 /** 640 * ntfs_pathname_to_inode - Find the inode which represents the given pathname 641 * @vol: An ntfs volume obtained from ntfs_mount 642 * @parent: A directory inode to begin the search (may be NULL) 643 * @pathname: Pathname to be located 644 * 645 * Take an ASCII pathname and find the inode that represents it. The function 646 * splits the path and then descends the directory tree. If @parent is NULL, 647 * then the root directory '.' will be used as the base for the search. 648 * 649 * Return: inode Success, the pathname was valid 650 * NULL Error, the pathname was invalid, or some other error occurred 651 */ 652 ntfs_inode *ntfs_pathname_to_inode(ntfs_volume *vol, ntfs_inode *parent, 653 const char *pathname) 654 { 655 u64 inum; 656 int len, err = 0; 657 char *p, *q; 658 ntfs_inode *ni; 659 ntfs_inode *result = NULL; 660 ntfschar *unicode = NULL; 661 char *ascii = NULL; 662 #if CACHE_INODE_SIZE 663 struct CACHED_INODE item; 664 struct CACHED_INODE *cached; 665 char *fullname; 666 #endif 667 668 if (!vol || !pathname) { 669 errno = EINVAL; 670 return NULL; 671 } 672 673 ntfs_log_trace("path: '%s'\n", pathname); 674 675 ascii = strdup(pathname); 676 if (!ascii) { 677 ntfs_log_error("Out of memory.\n"); 678 err = ENOMEM; 679 goto out; 680 } 681 682 p = ascii; 683 /* Remove leading /'s. */ 684 while (p && *p && *p == PATH_SEP) 685 p++; 686 #if CACHE_INODE_SIZE 687 fullname = p; 688 if (p[0] && (p[strlen(p)-1] == PATH_SEP)) 689 ntfs_log_error("Unnormalized path %s\n",ascii); 690 #endif 691 if (parent) { 692 ni = parent; 693 } else { 694 #if CACHE_INODE_SIZE 695 /* 696 * fetch inode for full path from cache 697 */ 698 if (*fullname) { 699 item.pathname = fullname; 700 item.varsize = strlen(fullname) + 1; 701 cached = (struct CACHED_INODE*)ntfs_fetch_cache( 702 vol->xinode_cache, GENERIC(&item), 703 inode_cache_compare); 704 } else 705 cached = (struct CACHED_INODE*)NULL; 706 if (cached) { 707 /* 708 * return opened inode if found in cache 709 */ 710 inum = MREF(cached->inum); 711 ni = ntfs_inode_open(vol, inum); 712 if (!ni) { 713 ntfs_log_debug("Cannot open inode %llu: %s.\n", 714 (unsigned long long)inum, p); 715 err = EIO; 716 } 717 result = ni; 718 goto out; 719 } 720 #endif 721 ni = ntfs_inode_open(vol, FILE_root); 722 if (!ni) { 723 ntfs_log_debug("Couldn't open the inode of the root " 724 "directory.\n"); 725 err = EIO; 726 result = (ntfs_inode*)NULL; 727 goto out; 728 } 729 } 730 731 while (p && *p) { 732 /* Find the end of the first token. */ 733 q = strchr(p, PATH_SEP); 734 if (q != NULL) { 735 *q = '\0'; 736 } 737 #if CACHE_INODE_SIZE 738 /* 739 * fetch inode for partial path from cache 740 */ 741 cached = (struct CACHED_INODE*)NULL; 742 if (!parent) { 743 item.pathname = fullname; 744 item.varsize = strlen(fullname) + 1; 745 cached = (struct CACHED_INODE*)ntfs_fetch_cache( 746 vol->xinode_cache, GENERIC(&item), 747 inode_cache_compare); 748 if (cached) { 749 inum = cached->inum; 750 } 751 } 752 /* 753 * if not in cache, translate, search, then 754 * insert into cache if found 755 */ 756 if (!cached) { 757 len = ntfs_mbstoucs(p, &unicode); 758 if (len < 0) { 759 ntfs_log_perror("Could not convert filename to Unicode:" 760 " '%s'", p); 761 err = errno; 762 goto close; 763 } else if (len > NTFS_MAX_NAME_LEN) { 764 err = ENAMETOOLONG; 765 goto close; 766 } 767 inum = ntfs_inode_lookup_by_name(ni, unicode, len); 768 if (!parent && (inum != (u64) -1)) { 769 item.inum = inum; 770 ntfs_enter_cache(vol->xinode_cache, 771 GENERIC(&item), 772 inode_cache_compare); 773 } 774 } 775 #else 776 len = ntfs_mbstoucs(p, &unicode); 777 if (len < 0) { 778 ntfs_log_perror("Could not convert filename to Unicode:" 779 " '%s'", p); 780 err = errno; 781 goto close; 782 } else if (len > NTFS_MAX_NAME_LEN) { 783 err = ENAMETOOLONG; 784 goto close; 785 } 786 inum = ntfs_inode_lookup_by_name(ni, unicode, len); 787 #endif 788 if (inum == (u64) -1) { 789 ntfs_log_debug("Couldn't find name '%s' in pathname " 790 "'%s'.\n", p, pathname); 791 err = ENOENT; 792 goto close; 793 } 794 795 if (ni != parent) 796 if (ntfs_inode_close(ni)) { 797 err = errno; 798 goto out; 799 } 800 801 inum = MREF(inum); 802 ni = ntfs_inode_open(vol, inum); 803 if (!ni) { 804 ntfs_log_debug("Cannot open inode %llu: %s.\n", 805 (unsigned long long)inum, p); 806 err = EIO; 807 goto close; 808 } 809 810 free(unicode); 811 unicode = NULL; 812 813 if (q) *q++ = PATH_SEP; /* JPA */ 814 p = q; 815 while (p && *p && *p == PATH_SEP) 816 p++; 817 } 818 819 result = ni; 820 ni = NULL; 821 close: 822 if (ni && (ni != parent)) 823 if (ntfs_inode_close(ni) && !err) 824 err = errno; 825 out: 826 free(ascii); 827 free(unicode); 828 if (err) 829 errno = err; 830 return result; 831 } 832 833 /* 834 * The little endian Unicode string ".." for ntfs_readdir(). 835 */ 836 static const ntfschar dotdot[3] = { const_cpu_to_le16('.'), 837 const_cpu_to_le16('.'), 838 const_cpu_to_le16('\0') }; 839 840 /* 841 * union index_union - 842 * More helpers for ntfs_readdir(). 843 */ 844 typedef union { 845 INDEX_ROOT *ir; 846 INDEX_ALLOCATION *ia; 847 } index_union __attribute__((__transparent_union__)); 848 849 /** 850 * enum INDEX_TYPE - 851 * More helpers for ntfs_readdir(). 852 */ 853 typedef enum { 854 INDEX_TYPE_ROOT, /* index root */ 855 INDEX_TYPE_ALLOCATION, /* index allocation */ 856 } INDEX_TYPE; 857 858 /* 859 * Decode Interix file types 860 * 861 * Non-Interix types are returned as plain files, because a 862 * Windows user may force patterns very similar to Interix, 863 * and most metadata files have such similar patters. 864 */ 865 866 u32 ntfs_interix_types(ntfs_inode *ni) 867 { 868 ntfs_attr *na; 869 u32 dt_type; 870 le64 magic; 871 872 dt_type = NTFS_DT_UNKNOWN; 873 na = ntfs_attr_open(ni, AT_DATA, NULL, 0); 874 if (na) { 875 /* 876 * Unrecognized patterns (eg HID + SYST for metadata) 877 * are plain files or directories 878 */ 879 if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) 880 dt_type = NTFS_DT_DIR; 881 else 882 dt_type = NTFS_DT_REG; 883 if (na->data_size <= 1) { 884 if (!(ni->flags & FILE_ATTR_HIDDEN)) 885 dt_type = (na->data_size ? 886 NTFS_DT_SOCK : NTFS_DT_FIFO); 887 } else { 888 if ((na->data_size >= (s64)sizeof(magic)) 889 && (ntfs_attr_pread(na, 0, sizeof(magic), &magic) 890 == sizeof(magic))) { 891 if (magic == INTX_SYMBOLIC_LINK) 892 dt_type = NTFS_DT_LNK; 893 else if (magic == INTX_BLOCK_DEVICE) 894 dt_type = NTFS_DT_BLK; 895 else if (magic == INTX_CHARACTER_DEVICE) 896 dt_type = NTFS_DT_CHR; 897 } 898 } 899 ntfs_attr_close(na); 900 } 901 return (dt_type); 902 } 903 904 /* 905 * Decode file types 906 * 907 * Better only use for Interix types and junctions, 908 * unneeded complexity when used for plain files or directories 909 * 910 * Error cases are logged and returned as unknown. 911 */ 912 913 static u32 ntfs_dir_entry_type(ntfs_inode *dir_ni, MFT_REF mref, 914 FILE_ATTR_FLAGS attributes) 915 { 916 ntfs_inode *ni; 917 u32 dt_type; 918 919 dt_type = NTFS_DT_UNKNOWN; 920 ni = ntfs_inode_open(dir_ni->vol, mref); 921 if (ni) { 922 if (attributes & FILE_ATTR_REPARSE_POINT) 923 dt_type = (ntfs_possible_symlink(ni) 924 ? NTFS_DT_LNK : NTFS_DT_REPARSE); 925 else 926 if ((attributes & FILE_ATTR_SYSTEM) 927 && !(attributes & FILE_ATTR_I30_INDEX_PRESENT)) 928 dt_type = ntfs_interix_types(ni); 929 else 930 dt_type = (attributes 931 & FILE_ATTR_I30_INDEX_PRESENT 932 ? NTFS_DT_DIR : NTFS_DT_REG); 933 if (ntfs_inode_close(ni)) { 934 /* anything special worth doing ? */ 935 ntfs_log_error("Failed to close inode %lld\n", 936 (long long)MREF(mref)); 937 } 938 } 939 if (dt_type == NTFS_DT_UNKNOWN) 940 ntfs_log_error("Could not decode the type of inode %lld\n", 941 (long long)MREF(mref)); 942 return (dt_type); 943 } 944 945 /** 946 * ntfs_filldir - ntfs specific filldir method 947 * @dir_ni: ntfs inode of current directory 948 * @pos: current position in directory 949 * @ivcn_bits: log(2) of index vcn size 950 * @index_type: specifies whether @iu is an index root or an index allocation 951 * @iu: index root or index block to which @ie belongs 952 * @ie: current index entry 953 * @dirent: context for filldir callback supplied by the caller 954 * @filldir: filldir callback supplied by the caller 955 * 956 * Pass information specifying the current directory entry @ie to the @filldir 957 * callback. 958 */ 959 static int ntfs_filldir(ntfs_inode *dir_ni, s64 *pos, u8 ivcn_bits, 960 const INDEX_TYPE index_type, index_union iu, INDEX_ENTRY *ie, 961 void *dirent, ntfs_filldir_t filldir) 962 { 963 FILE_NAME_ATTR *fn = &ie->key.file_name; 964 unsigned dt_type; 965 BOOL metadata; 966 ntfschar *loname; 967 int res; 968 MFT_REF mref; 969 970 ntfs_log_trace("Entering.\n"); 971 972 /* Advance the position even if going to skip the entry. */ 973 if (index_type == INDEX_TYPE_ALLOCATION) 974 *pos = (u8*)ie - (u8*)iu.ia + (sle64_to_cpu( 975 iu.ia->index_block_vcn) << ivcn_bits) + 976 dir_ni->vol->mft_record_size; 977 else /* if (index_type == INDEX_TYPE_ROOT) */ 978 *pos = (u8*)ie - (u8*)iu.ir; 979 mref = le64_to_cpu(ie->indexed_file); 980 metadata = (MREF(mref) != FILE_root) && (MREF(mref) < FILE_first_user); 981 /* Skip root directory self reference entry. */ 982 if (MREF_LE(ie->indexed_file) == FILE_root) 983 return 0; 984 if ((ie->key.file_name.file_attributes 985 & (FILE_ATTR_REPARSE_POINT | FILE_ATTR_SYSTEM)) 986 && !metadata) 987 dt_type = ntfs_dir_entry_type(dir_ni, mref, 988 ie->key.file_name.file_attributes); 989 else if (ie->key.file_name.file_attributes 990 & FILE_ATTR_I30_INDEX_PRESENT) 991 dt_type = NTFS_DT_DIR; 992 else 993 dt_type = NTFS_DT_REG; 994 995 /* return metadata files and hidden files if requested */ 996 if ((!metadata && (NVolShowHidFiles(dir_ni->vol) 997 || !(fn->file_attributes & FILE_ATTR_HIDDEN))) 998 || (NVolShowSysFiles(dir_ni->vol) && (NVolShowHidFiles(dir_ni->vol) 999 || metadata))) { 1000 if (NVolCaseSensitive(dir_ni->vol)) { 1001 res = filldir(dirent, fn->file_name, 1002 fn->file_name_length, 1003 fn->file_name_type, *pos, 1004 mref, dt_type); 1005 } else { 1006 loname = (ntfschar*)ntfs_malloc(2*fn->file_name_length); 1007 if (loname) { 1008 memcpy(loname, fn->file_name, 1009 2*fn->file_name_length); 1010 ntfs_name_locase(loname, fn->file_name_length, 1011 dir_ni->vol->locase, 1012 dir_ni->vol->upcase_len); 1013 res = filldir(dirent, loname, 1014 fn->file_name_length, 1015 fn->file_name_type, *pos, 1016 mref, dt_type); 1017 free(loname); 1018 } else 1019 res = -1; 1020 } 1021 } else 1022 res = 0; 1023 return (res); 1024 } 1025 1026 /** 1027 * ntfs_mft_get_parent_ref - find mft reference of parent directory of an inode 1028 * @ni: ntfs inode whose parent directory to find 1029 * 1030 * Find the parent directory of the ntfs inode @ni. To do this, find the first 1031 * file name attribute in the mft record of @ni and return the parent mft 1032 * reference from that. 1033 * 1034 * Note this only makes sense for directories, since files can be hard linked 1035 * from multiple directories and there is no way for us to tell which one is 1036 * being looked for. 1037 * 1038 * Technically directories can have hard links, too, but we consider that as 1039 * illegal as Linux/UNIX do not support directory hard links. 1040 * 1041 * Return the mft reference of the parent directory on success or -1 on error 1042 * with errno set to the error code. 1043 */ 1044 #ifndef __HAIKU__ 1045 static 1046 #endif 1047 MFT_REF ntfs_mft_get_parent_ref(ntfs_inode *ni) 1048 { 1049 MFT_REF mref; 1050 ntfs_attr_search_ctx *ctx; 1051 FILE_NAME_ATTR *fn; 1052 int eo; 1053 1054 ntfs_log_trace("Entering.\n"); 1055 1056 if (!ni) { 1057 errno = EINVAL; 1058 return ERR_MREF(-1); 1059 } 1060 1061 ctx = ntfs_attr_get_search_ctx(ni, NULL); 1062 if (!ctx) 1063 return ERR_MREF(-1); 1064 if (ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, 0, 0, NULL, 0, ctx)) { 1065 ntfs_log_error("No file name found in inode %lld\n", 1066 (unsigned long long)ni->mft_no); 1067 goto err_out; 1068 } 1069 if (ctx->attr->non_resident) { 1070 ntfs_log_error("File name attribute must be resident (inode " 1071 "%lld)\n", (unsigned long long)ni->mft_no); 1072 goto io_err_out; 1073 } 1074 fn = (FILE_NAME_ATTR*)((u8*)ctx->attr + 1075 le16_to_cpu(ctx->attr->value_offset)); 1076 mref = le64_to_cpu(fn->parent_directory); 1077 ntfs_attr_put_search_ctx(ctx); 1078 return mref; 1079 io_err_out: 1080 errno = EIO; 1081 err_out: 1082 eo = errno; 1083 ntfs_attr_put_search_ctx(ctx); 1084 errno = eo; 1085 return ERR_MREF(-1); 1086 } 1087 1088 /** 1089 * ntfs_readdir - read the contents of an ntfs directory 1090 * @dir_ni: ntfs inode of current directory 1091 * @pos: current position in directory 1092 * @dirent: context for filldir callback supplied by the caller 1093 * @filldir: filldir callback supplied by the caller 1094 * 1095 * Parse the index root and the index blocks that are marked in use in the 1096 * index bitmap and hand each found directory entry to the @filldir callback 1097 * supplied by the caller. 1098 * 1099 * Return 0 on success or -1 on error with errno set to the error code. 1100 * 1101 * Note: Index blocks are parsed in ascending vcn order, from which follows 1102 * that the directory entries are not returned sorted. 1103 */ 1104 int ntfs_readdir(ntfs_inode *dir_ni, s64 *pos, 1105 void *dirent, ntfs_filldir_t filldir) 1106 { 1107 s64 i_size, br, ia_pos, bmp_pos, ia_start; 1108 ntfs_volume *vol; 1109 ntfs_attr *ia_na, *bmp_na = NULL; 1110 ntfs_attr_search_ctx *ctx = NULL; 1111 u8 *index_end, *bmp = NULL; 1112 INDEX_ROOT *ir; 1113 INDEX_ENTRY *ie; 1114 INDEX_ALLOCATION *ia = NULL; 1115 int rc, ir_pos, bmp_buf_size, bmp_buf_pos, eo; 1116 u32 index_block_size; 1117 u8 index_block_size_bits, index_vcn_size_bits; 1118 1119 ntfs_log_trace("Entering.\n"); 1120 1121 if (!dir_ni || !pos || !filldir) { 1122 errno = EINVAL; 1123 return -1; 1124 } 1125 1126 if (!(dir_ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) { 1127 errno = ENOTDIR; 1128 return -1; 1129 } 1130 1131 vol = dir_ni->vol; 1132 1133 ntfs_log_trace("Entering for inode %lld, *pos 0x%llx.\n", 1134 (unsigned long long)dir_ni->mft_no, (long long)*pos); 1135 1136 /* Open the index allocation attribute. */ 1137 ia_na = ntfs_attr_open(dir_ni, AT_INDEX_ALLOCATION, NTFS_INDEX_I30, 4); 1138 if (!ia_na) { 1139 if (errno != ENOENT) { 1140 ntfs_log_perror("Failed to open index allocation attribute. " 1141 "Directory inode %lld is corrupt or bug", 1142 (unsigned long long)dir_ni->mft_no); 1143 return -1; 1144 } 1145 i_size = 0; 1146 } else 1147 i_size = ia_na->data_size; 1148 1149 rc = 0; 1150 1151 /* Are we at end of dir yet? */ 1152 if (*pos >= i_size + vol->mft_record_size) 1153 goto done; 1154 1155 /* Emulate . and .. for all directories. */ 1156 if (!*pos) { 1157 rc = filldir(dirent, dotdot, 1, FILE_NAME_POSIX, *pos, 1158 MK_MREF(dir_ni->mft_no, 1159 le16_to_cpu(dir_ni->mrec->sequence_number)), 1160 NTFS_DT_DIR); 1161 if (rc) 1162 goto err_out; 1163 ++*pos; 1164 } 1165 if (*pos == 1) { 1166 MFT_REF parent_mref; 1167 1168 parent_mref = ntfs_mft_get_parent_ref(dir_ni); 1169 if (parent_mref == ERR_MREF(-1)) { 1170 ntfs_log_perror("Parent directory not found"); 1171 goto dir_err_out; 1172 } 1173 1174 rc = filldir(dirent, dotdot, 2, FILE_NAME_POSIX, *pos, 1175 parent_mref, NTFS_DT_DIR); 1176 if (rc) 1177 goto err_out; 1178 ++*pos; 1179 } 1180 1181 ctx = ntfs_attr_get_search_ctx(dir_ni, NULL); 1182 if (!ctx) 1183 goto err_out; 1184 1185 /* Get the offset into the index root attribute. */ 1186 ir_pos = (int)*pos; 1187 /* Find the index root attribute in the mft record. */ 1188 if (ntfs_attr_lookup(AT_INDEX_ROOT, NTFS_INDEX_I30, 4, CASE_SENSITIVE, 0, NULL, 1189 0, ctx)) { 1190 ntfs_log_perror("Index root attribute missing in directory inode " 1191 "%lld", (unsigned long long)dir_ni->mft_no); 1192 goto dir_err_out; 1193 } 1194 /* Get to the index root value. */ 1195 ir = (INDEX_ROOT*)((u8*)ctx->attr + 1196 le16_to_cpu(ctx->attr->value_offset)); 1197 1198 /* Determine the size of a vcn in the directory index. */ 1199 index_block_size = le32_to_cpu(ir->index_block_size); 1200 if (index_block_size < NTFS_BLOCK_SIZE || 1201 index_block_size & (index_block_size - 1)) { 1202 ntfs_log_error("Index block size %u is invalid.\n", 1203 (unsigned)index_block_size); 1204 goto dir_err_out; 1205 } 1206 index_block_size_bits = ffs(index_block_size) - 1; 1207 if (vol->cluster_size <= index_block_size) { 1208 index_vcn_size_bits = vol->cluster_size_bits; 1209 } else { 1210 index_vcn_size_bits = NTFS_BLOCK_SIZE_BITS; 1211 } 1212 1213 /* Are we jumping straight into the index allocation attribute? */ 1214 if (*pos >= vol->mft_record_size) { 1215 ntfs_attr_put_search_ctx(ctx); 1216 ctx = NULL; 1217 goto skip_index_root; 1218 } 1219 1220 index_end = (u8*)&ir->index + le32_to_cpu(ir->index.index_length); 1221 /* The first index entry. */ 1222 ie = (INDEX_ENTRY*)((u8*)&ir->index + 1223 le32_to_cpu(ir->index.entries_offset)); 1224 /* 1225 * Loop until we exceed valid memory (corruption case) or until we 1226 * reach the last entry or until filldir tells us it has had enough 1227 * or signals an error (both covered by the rc test). 1228 */ 1229 for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) { 1230 ntfs_log_debug("In index root, offset %d.\n", (int)((u8*)ie - (u8*)ir)); 1231 /* Bounds checks. */ 1232 if ((u8*)ie < (u8*)ctx->mrec || (u8*)ie + 1233 sizeof(INDEX_ENTRY_HEADER) > index_end || 1234 (u8*)ie + le16_to_cpu(ie->length) > 1235 index_end) { 1236 ntfs_log_error("Index root entry out of bounds in" 1237 " inode %lld\n", 1238 (unsigned long long)dir_ni->mft_no); 1239 goto dir_err_out; 1240 } 1241 /* The last entry cannot contain a name. */ 1242 if (ie->ie_flags & INDEX_ENTRY_END) 1243 break; 1244 1245 if (!le16_to_cpu(ie->length)) 1246 goto dir_err_out; 1247 1248 /* Skip index root entry if continuing previous readdir. */ 1249 if (ir_pos > (u8*)ie - (u8*)ir) 1250 continue; 1251 1252 /* The file name must not overflow from the entry */ 1253 if (ntfs_index_entry_inconsistent(ie, COLLATION_FILE_NAME, 1254 dir_ni->mft_no)) { 1255 errno = EIO; 1256 goto dir_err_out; 1257 } 1258 /* 1259 * Submit the directory entry to ntfs_filldir(), which will 1260 * invoke the filldir() callback as appropriate. 1261 */ 1262 rc = ntfs_filldir(dir_ni, pos, index_vcn_size_bits, 1263 INDEX_TYPE_ROOT, ir, ie, dirent, filldir); 1264 if (rc) { 1265 ntfs_attr_put_search_ctx(ctx); 1266 ctx = NULL; 1267 goto err_out; 1268 } 1269 } 1270 ntfs_attr_put_search_ctx(ctx); 1271 ctx = NULL; 1272 1273 /* If there is no index allocation attribute we are finished. */ 1274 if (!ia_na) 1275 goto EOD; 1276 1277 /* Advance *pos to the beginning of the index allocation. */ 1278 *pos = vol->mft_record_size; 1279 1280 skip_index_root: 1281 1282 if (!ia_na) 1283 goto done; 1284 1285 /* Allocate a buffer for the current index block. */ 1286 ia = ntfs_malloc(index_block_size); 1287 if (!ia) 1288 goto err_out; 1289 1290 bmp_na = ntfs_attr_open(dir_ni, AT_BITMAP, NTFS_INDEX_I30, 4); 1291 if (!bmp_na) { 1292 ntfs_log_perror("Failed to open index bitmap attribute"); 1293 goto dir_err_out; 1294 } 1295 1296 /* Get the offset into the index allocation attribute. */ 1297 ia_pos = *pos - vol->mft_record_size; 1298 1299 bmp_pos = ia_pos >> index_block_size_bits; 1300 if (bmp_pos >> 3 >= bmp_na->data_size) { 1301 ntfs_log_error("Current index position exceeds index bitmap " 1302 "size.\n"); 1303 goto dir_err_out; 1304 } 1305 1306 bmp_buf_size = min(bmp_na->data_size - (bmp_pos >> 3), 4096); 1307 bmp = ntfs_malloc(bmp_buf_size); 1308 if (!bmp) 1309 goto err_out; 1310 1311 br = ntfs_attr_pread(bmp_na, bmp_pos >> 3, bmp_buf_size, bmp); 1312 if (br != bmp_buf_size) { 1313 if (br != -1) 1314 errno = EIO; 1315 ntfs_log_perror("Failed to read from index bitmap attribute"); 1316 goto err_out; 1317 } 1318 1319 bmp_buf_pos = 0; 1320 /* If the index block is not in use find the next one that is. */ 1321 while (!(bmp[bmp_buf_pos >> 3] & (1 << (bmp_buf_pos & 7)))) { 1322 find_next_index_buffer: 1323 bmp_pos++; 1324 bmp_buf_pos++; 1325 /* If we have reached the end of the bitmap, we are done. */ 1326 if (bmp_pos >> 3 >= bmp_na->data_size) 1327 goto EOD; 1328 ia_pos = bmp_pos << index_block_size_bits; 1329 if (bmp_buf_pos >> 3 < bmp_buf_size) 1330 continue; 1331 /* Read next chunk from the index bitmap. */ 1332 bmp_buf_pos = 0; 1333 if ((bmp_pos >> 3) + bmp_buf_size > bmp_na->data_size) 1334 bmp_buf_size = bmp_na->data_size - (bmp_pos >> 3); 1335 br = ntfs_attr_pread(bmp_na, bmp_pos >> 3, bmp_buf_size, bmp); 1336 if (br != bmp_buf_size) { 1337 if (br != -1) 1338 errno = EIO; 1339 ntfs_log_perror("Failed to read from index bitmap attribute"); 1340 goto err_out; 1341 } 1342 } 1343 1344 ntfs_log_debug("Handling index block 0x%llx.\n", (long long)bmp_pos); 1345 1346 /* Read the index block starting at bmp_pos. */ 1347 br = ntfs_attr_mst_pread(ia_na, bmp_pos << index_block_size_bits, 1, 1348 index_block_size, ia); 1349 if (br != 1) { 1350 if (br != -1) 1351 errno = EIO; 1352 ntfs_log_perror("Failed to read index block"); 1353 goto err_out; 1354 } 1355 1356 ia_start = ia_pos & ~(s64)(index_block_size - 1); 1357 if (ntfs_index_block_inconsistent((INDEX_BLOCK*)ia, index_block_size, 1358 ia_na->ni->mft_no, ia_start >> index_vcn_size_bits)) { 1359 goto dir_err_out; 1360 } 1361 index_end = (u8*)&ia->index + le32_to_cpu(ia->index.index_length); 1362 1363 /* The first index entry. */ 1364 ie = (INDEX_ENTRY*)((u8*)&ia->index + 1365 le32_to_cpu(ia->index.entries_offset)); 1366 /* 1367 * Loop until we exceed valid memory (corruption case) or until we 1368 * reach the last entry or until ntfs_filldir tells us it has had 1369 * enough or signals an error (both covered by the rc test). 1370 */ 1371 for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) { 1372 ntfs_log_debug("In index allocation, offset 0x%llx.\n", 1373 (long long)ia_start + ((u8*)ie - (u8*)ia)); 1374 /* Bounds checks. */ 1375 if ((u8*)ie < (u8*)ia || (u8*)ie + 1376 sizeof(INDEX_ENTRY_HEADER) > index_end || 1377 (u8*)ie + le16_to_cpu(ie->length) > 1378 index_end) { 1379 ntfs_log_error("Index entry out of bounds in directory inode " 1380 "%lld.\n", (unsigned long long)dir_ni->mft_no); 1381 goto dir_err_out; 1382 } 1383 /* The last entry cannot contain a name. */ 1384 if (ie->ie_flags & INDEX_ENTRY_END) 1385 break; 1386 1387 if (!le16_to_cpu(ie->length)) 1388 goto dir_err_out; 1389 1390 /* Skip index entry if continuing previous readdir. */ 1391 if (ia_pos - ia_start > (u8*)ie - (u8*)ia) 1392 continue; 1393 1394 /* The file name must not overflow from the entry */ 1395 if (ntfs_index_entry_inconsistent(ie, COLLATION_FILE_NAME, 1396 dir_ni->mft_no)) { 1397 errno = EIO; 1398 goto dir_err_out; 1399 } 1400 /* 1401 * Submit the directory entry to ntfs_filldir(), which will 1402 * invoke the filldir() callback as appropriate. 1403 */ 1404 rc = ntfs_filldir(dir_ni, pos, index_vcn_size_bits, 1405 INDEX_TYPE_ALLOCATION, ia, ie, dirent, filldir); 1406 if (rc) 1407 goto err_out; 1408 } 1409 goto find_next_index_buffer; 1410 EOD: 1411 /* We are finished, set *pos to EOD. */ 1412 *pos = i_size + vol->mft_record_size; 1413 done: 1414 free(ia); 1415 free(bmp); 1416 if (bmp_na) 1417 ntfs_attr_close(bmp_na); 1418 if (ia_na) 1419 ntfs_attr_close(ia_na); 1420 ntfs_log_debug("EOD, *pos 0x%llx, returning 0.\n", (long long)*pos); 1421 return 0; 1422 dir_err_out: 1423 errno = EIO; 1424 err_out: 1425 eo = errno; 1426 ntfs_log_trace("failed.\n"); 1427 if (ctx) 1428 ntfs_attr_put_search_ctx(ctx); 1429 free(ia); 1430 free(bmp); 1431 if (bmp_na) 1432 ntfs_attr_close(bmp_na); 1433 if (ia_na) 1434 ntfs_attr_close(ia_na); 1435 errno = eo; 1436 return -1; 1437 } 1438 1439 1440 /** 1441 * __ntfs_create - create object on ntfs volume 1442 * @dir_ni: ntfs inode for directory in which create new object 1443 * @securid: id of inheritable security descriptor, 0 if none 1444 * @name: unicode name of new object 1445 * @name_len: length of the name in unicode characters 1446 * @type: type of the object to create 1447 * @dev: major and minor device numbers (obtained from makedev()) 1448 * @target: target in unicode (only for symlinks) 1449 * @target_len: length of target in unicode characters 1450 * 1451 * Internal, use ntfs_create{,_device,_symlink} wrappers instead. 1452 * 1453 * @type can be: 1454 * S_IFREG to create regular file 1455 * S_IFDIR to create directory 1456 * S_IFBLK to create block device 1457 * S_IFCHR to create character device 1458 * S_IFLNK to create symbolic link 1459 * S_IFIFO to create FIFO 1460 * S_IFSOCK to create socket 1461 * other values are invalid. 1462 * 1463 * @dev is used only if @type is S_IFBLK or S_IFCHR, in other cases its value 1464 * ignored. 1465 * 1466 * @target and @target_len are used only if @type is S_IFLNK, in other cases 1467 * their value ignored. 1468 * 1469 * Return opened ntfs inode that describes created object on success or NULL 1470 * on error with errno set to the error code. 1471 */ 1472 static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, le32 securid, 1473 const ntfschar *name, u8 name_len, mode_t type, dev_t dev, 1474 const ntfschar *target, int target_len) 1475 { 1476 ntfs_inode *ni; 1477 int rollback_data = 0, rollback_sd = 0; 1478 int rollback_dir = 0; 1479 FILE_NAME_ATTR *fn = NULL; 1480 STANDARD_INFORMATION *si = NULL; 1481 int err, fn_len, si_len; 1482 ntfs_volume_special_files special_files; 1483 1484 ntfs_log_trace("Entering.\n"); 1485 1486 /* Sanity checks. */ 1487 if (!dir_ni || !name || !name_len) { 1488 ntfs_log_error("Invalid arguments.\n"); 1489 errno = EINVAL; 1490 return NULL; 1491 } 1492 1493 ni = ntfs_mft_record_alloc(dir_ni->vol, NULL); 1494 if (!ni) 1495 return NULL; 1496 #if CACHE_NIDATA_SIZE 1497 ntfs_inode_invalidate(dir_ni->vol, ni->mft_no); 1498 #endif 1499 special_files = dir_ni->vol->special_files; 1500 /* 1501 * Create STANDARD_INFORMATION attribute. 1502 * JPA Depending on available inherited security descriptor, 1503 * Write STANDARD_INFORMATION v1.2 (no inheritance) or v3 1504 */ 1505 if (securid) 1506 si_len = sizeof(STANDARD_INFORMATION); 1507 else 1508 si_len = offsetof(STANDARD_INFORMATION, v1_end); 1509 si = ntfs_calloc(si_len); 1510 if (!si) { 1511 err = errno; 1512 goto err_out; 1513 } 1514 si->creation_time = ni->creation_time; 1515 si->last_data_change_time = ni->last_data_change_time; 1516 si->last_mft_change_time = ni->last_mft_change_time; 1517 si->last_access_time = ni->last_access_time; 1518 if (securid) { 1519 set_nino_flag(ni, v3_Extensions); 1520 ni->owner_id = si->owner_id = const_cpu_to_le32(0); 1521 ni->security_id = si->security_id = securid; 1522 ni->quota_charged = si->quota_charged = const_cpu_to_le64(0); 1523 ni->usn = si->usn = const_cpu_to_le64(0); 1524 } else 1525 clear_nino_flag(ni, v3_Extensions); 1526 if (!S_ISREG(type) && !S_ISDIR(type)) { 1527 switch (special_files) { 1528 case NTFS_FILES_WSL : 1529 if (!S_ISLNK(type)) { 1530 si->file_attributes 1531 = FILE_ATTRIBUTE_RECALL_ON_OPEN; 1532 ni->flags = FILE_ATTRIBUTE_RECALL_ON_OPEN; 1533 } 1534 break; 1535 default : 1536 si->file_attributes = FILE_ATTR_SYSTEM; 1537 ni->flags = FILE_ATTR_SYSTEM; 1538 break; 1539 } 1540 } 1541 ni->flags |= FILE_ATTR_ARCHIVE; 1542 if (NVolHideDotFiles(dir_ni->vol) 1543 && (name_len > 1) 1544 && (name[0] == const_cpu_to_le16('.')) 1545 && (name[1] != const_cpu_to_le16('.'))) 1546 ni->flags |= FILE_ATTR_HIDDEN; 1547 /* 1548 * Set compression flag according to parent directory 1549 * unless NTFS version < 3.0 or cluster size > 4K 1550 * or compression has been disabled 1551 */ 1552 if ((dir_ni->flags & FILE_ATTR_COMPRESSED) 1553 && (dir_ni->vol->major_ver >= 3) 1554 && NVolCompression(dir_ni->vol) 1555 && (dir_ni->vol->cluster_size <= MAX_COMPRESSION_CLUSTER_SIZE) 1556 && (S_ISREG(type) || S_ISDIR(type))) 1557 ni->flags |= FILE_ATTR_COMPRESSED; 1558 /* Add STANDARD_INFORMATION to inode. */ 1559 if (ntfs_attr_add(ni, AT_STANDARD_INFORMATION, AT_UNNAMED, 0, 1560 (u8*)si, si_len)) { 1561 err = errno; 1562 ntfs_log_error("Failed to add STANDARD_INFORMATION " 1563 "attribute.\n"); 1564 goto err_out; 1565 } 1566 1567 if (!securid) { 1568 if (ntfs_sd_add_everyone(ni)) { 1569 err = errno; 1570 goto err_out; 1571 } 1572 rollback_sd = 1; 1573 } 1574 1575 if (S_ISDIR(type)) { 1576 INDEX_ROOT *ir = NULL; 1577 INDEX_ENTRY *ie; 1578 int ir_len, index_len; 1579 1580 /* Create INDEX_ROOT attribute. */ 1581 index_len = sizeof(INDEX_HEADER) + sizeof(INDEX_ENTRY_HEADER); 1582 ir_len = offsetof(INDEX_ROOT, index) + index_len; 1583 ir = ntfs_calloc(ir_len); 1584 if (!ir) { 1585 err = errno; 1586 goto err_out; 1587 } 1588 ir->type = AT_FILE_NAME; 1589 ir->collation_rule = COLLATION_FILE_NAME; 1590 ir->index_block_size = cpu_to_le32(ni->vol->indx_record_size); 1591 if (ni->vol->cluster_size <= ni->vol->indx_record_size) 1592 ir->clusters_per_index_block = 1593 ni->vol->indx_record_size >> 1594 ni->vol->cluster_size_bits; 1595 else 1596 ir->clusters_per_index_block = 1597 ni->vol->indx_record_size >> 1598 NTFS_BLOCK_SIZE_BITS; 1599 ir->index.entries_offset = const_cpu_to_le32(sizeof(INDEX_HEADER)); 1600 ir->index.index_length = cpu_to_le32(index_len); 1601 ir->index.allocated_size = cpu_to_le32(index_len); 1602 ie = (INDEX_ENTRY*)((u8*)ir + sizeof(INDEX_ROOT)); 1603 ie->length = const_cpu_to_le16(sizeof(INDEX_ENTRY_HEADER)); 1604 ie->key_length = const_cpu_to_le16(0); 1605 ie->ie_flags = INDEX_ENTRY_END; 1606 /* Add INDEX_ROOT attribute to inode. */ 1607 if (ntfs_attr_add(ni, AT_INDEX_ROOT, NTFS_INDEX_I30, 4, 1608 (u8*)ir, ir_len)) { 1609 err = errno; 1610 free(ir); 1611 ntfs_log_error("Failed to add INDEX_ROOT attribute.\n"); 1612 goto err_out; 1613 } 1614 free(ir); 1615 } else { 1616 INTX_FILE *data; 1617 int data_len; 1618 1619 switch (type) { 1620 case S_IFBLK: 1621 case S_IFCHR: 1622 switch (special_files) { 1623 case NTFS_FILES_WSL : 1624 data_len = 0; 1625 data = (INTX_FILE*)NULL; 1626 break; 1627 default : 1628 data_len = offsetof(INTX_FILE, 1629 device_end); 1630 data = (INTX_FILE*)ntfs_malloc( 1631 data_len); 1632 if (!data) { 1633 err = errno; 1634 goto err_out; 1635 } 1636 data->major = cpu_to_le64(major(dev)); 1637 data->minor = cpu_to_le64(minor(dev)); 1638 if (type == S_IFBLK) 1639 data->magic 1640 = INTX_BLOCK_DEVICE; 1641 if (type == S_IFCHR) 1642 data->magic 1643 = INTX_CHARACTER_DEVICE; 1644 break; 1645 } 1646 break; 1647 case S_IFLNK: 1648 switch (special_files) { 1649 case NTFS_FILES_WSL : 1650 data_len = 0; 1651 data = (INTX_FILE*)NULL; 1652 break; 1653 default : 1654 data_len = sizeof(INTX_FILE_TYPES) + 1655 target_len * sizeof(ntfschar); 1656 data = (INTX_FILE*)ntfs_malloc( 1657 data_len); 1658 if (!data) { 1659 err = errno; 1660 goto err_out; 1661 } 1662 data->magic = INTX_SYMBOLIC_LINK; 1663 memcpy(data->target, target, 1664 target_len * sizeof(ntfschar)); 1665 break; 1666 } 1667 break; 1668 case S_IFSOCK: 1669 data = NULL; 1670 if (special_files == NTFS_FILES_WSL) 1671 data_len = 0; 1672 else 1673 data_len = 1; 1674 break; 1675 default: /* FIFO or regular file. */ 1676 data = NULL; 1677 data_len = 0; 1678 break; 1679 } 1680 /* Add DATA attribute to inode. */ 1681 if (ntfs_attr_add(ni, AT_DATA, AT_UNNAMED, 0, (u8*)data, 1682 data_len)) { 1683 err = errno; 1684 ntfs_log_error("Failed to add DATA attribute.\n"); 1685 free(data); 1686 goto err_out; 1687 } 1688 rollback_data = 1; 1689 free(data); 1690 } 1691 /* Create FILE_NAME attribute. */ 1692 fn_len = sizeof(FILE_NAME_ATTR) + name_len * sizeof(ntfschar); 1693 fn = ntfs_calloc(fn_len); 1694 if (!fn) { 1695 err = errno; 1696 goto err_out; 1697 } 1698 fn->parent_directory = MK_LE_MREF(dir_ni->mft_no, 1699 le16_to_cpu(dir_ni->mrec->sequence_number)); 1700 fn->file_name_length = name_len; 1701 fn->file_name_type = FILE_NAME_POSIX; 1702 if (S_ISDIR(type)) 1703 fn->file_attributes = FILE_ATTR_I30_INDEX_PRESENT; 1704 if (!S_ISREG(type) && !S_ISDIR(type)) { 1705 if (special_files == NTFS_FILES_INTERIX) 1706 fn->file_attributes = FILE_ATTR_SYSTEM; 1707 } else 1708 fn->file_attributes |= ni->flags & FILE_ATTR_COMPRESSED; 1709 fn->file_attributes |= FILE_ATTR_ARCHIVE; 1710 fn->file_attributes |= ni->flags & FILE_ATTR_HIDDEN; 1711 fn->creation_time = ni->creation_time; 1712 fn->last_data_change_time = ni->last_data_change_time; 1713 fn->last_mft_change_time = ni->last_mft_change_time; 1714 fn->last_access_time = ni->last_access_time; 1715 if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) 1716 fn->data_size = fn->allocated_size = const_cpu_to_sle64(0); 1717 else { 1718 fn->data_size = cpu_to_sle64(ni->data_size); 1719 fn->allocated_size = cpu_to_sle64(ni->allocated_size); 1720 } 1721 memcpy(fn->file_name, name, name_len * sizeof(ntfschar)); 1722 /* Add FILE_NAME attribute to inode. */ 1723 if (ntfs_attr_add(ni, AT_FILE_NAME, AT_UNNAMED, 0, (u8*)fn, fn_len)) { 1724 err = errno; 1725 ntfs_log_error("Failed to add FILE_NAME attribute.\n"); 1726 goto err_out; 1727 } 1728 /* Add FILE_NAME attribute to index. */ 1729 if (ntfs_index_add_filename(dir_ni, fn, MK_MREF(ni->mft_no, 1730 le16_to_cpu(ni->mrec->sequence_number)))) { 1731 err = errno; 1732 ntfs_log_perror("Failed to add entry to the index"); 1733 goto err_out; 1734 } 1735 rollback_dir = 1; 1736 /* Set hard links count and directory flag. */ 1737 ni->mrec->link_count = const_cpu_to_le16(1); 1738 if (S_ISDIR(type)) 1739 ni->mrec->flags |= MFT_RECORD_IS_DIRECTORY; 1740 /* Add reparse data */ 1741 if (special_files == NTFS_FILES_WSL) { 1742 switch (type) { 1743 case S_IFLNK : 1744 err = ntfs_reparse_set_wsl_symlink(ni, target, 1745 target_len); 1746 break; 1747 case S_IFIFO : 1748 case S_IFSOCK : 1749 case S_IFCHR : 1750 case S_IFBLK : 1751 err = ntfs_reparse_set_wsl_not_symlink(ni, 1752 type); 1753 if (!err) { 1754 err = ntfs_ea_set_wsl_not_symlink(ni, 1755 type, dev); 1756 if (err) 1757 ntfs_remove_ntfs_reparse_data(ni); 1758 } 1759 break; 1760 default : 1761 err = 0; 1762 break; 1763 } 1764 if (err) { 1765 err = errno; 1766 goto err_out; 1767 } 1768 } 1769 ntfs_inode_mark_dirty(ni); 1770 /* Done! */ 1771 free(fn); 1772 free(si); 1773 ntfs_log_trace("Done.\n"); 1774 return ni; 1775 err_out: 1776 ntfs_log_trace("Failed.\n"); 1777 1778 if (rollback_dir) 1779 ntfs_index_remove(dir_ni, ni, fn, fn_len); 1780 1781 if (rollback_sd) 1782 ntfs_attr_remove(ni, AT_SECURITY_DESCRIPTOR, AT_UNNAMED, 0); 1783 1784 if (rollback_data) 1785 ntfs_attr_remove(ni, AT_DATA, AT_UNNAMED, 0); 1786 /* 1787 * Free extent MFT records (should not exist any with current 1788 * ntfs_create implementation, but for any case if something will be 1789 * changed in the future). 1790 */ 1791 while (ni->nr_extents) 1792 if (ntfs_mft_record_free(ni->vol, *(ni->extent_nis))) { 1793 err = errno; 1794 ntfs_log_error("Failed to free extent MFT record. " 1795 "Leaving inconsistent metadata.\n"); 1796 } 1797 if (ntfs_mft_record_free(ni->vol, ni)) 1798 ntfs_log_error("Failed to free MFT record. " 1799 "Leaving inconsistent metadata. Run chkdsk.\n"); 1800 free(fn); 1801 free(si); 1802 errno = err; 1803 return NULL; 1804 } 1805 1806 /** 1807 * Some wrappers around __ntfs_create() ... 1808 */ 1809 1810 ntfs_inode *ntfs_create(ntfs_inode *dir_ni, le32 securid, const ntfschar *name, 1811 u8 name_len, mode_t type) 1812 { 1813 if (type != S_IFREG && type != S_IFDIR && type != S_IFIFO && 1814 type != S_IFSOCK) { 1815 ntfs_log_error("Invalid arguments.\n"); 1816 return NULL; 1817 } 1818 return __ntfs_create(dir_ni, securid, name, name_len, type, 0, NULL, 0); 1819 } 1820 1821 ntfs_inode *ntfs_create_device(ntfs_inode *dir_ni, le32 securid, 1822 const ntfschar *name, u8 name_len, mode_t type, dev_t dev) 1823 { 1824 if (type != S_IFCHR && type != S_IFBLK) { 1825 ntfs_log_error("Invalid arguments.\n"); 1826 return NULL; 1827 } 1828 return __ntfs_create(dir_ni, securid, name, name_len, type, dev, NULL, 0); 1829 } 1830 1831 ntfs_inode *ntfs_create_symlink(ntfs_inode *dir_ni, le32 securid, 1832 const ntfschar *name, u8 name_len, const ntfschar *target, 1833 int target_len) 1834 { 1835 if (!target || !target_len) { 1836 ntfs_log_error("%s: Invalid argument (%p, %d)\n", __FUNCTION__, 1837 target, target_len); 1838 return NULL; 1839 } 1840 return __ntfs_create(dir_ni, securid, name, name_len, S_IFLNK, 0, 1841 target, target_len); 1842 } 1843 1844 int ntfs_check_empty_dir(ntfs_inode *ni) 1845 { 1846 ntfs_attr *na; 1847 int ret = 0; 1848 1849 if (!(ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) 1850 return 0; 1851 1852 na = ntfs_attr_open(ni, AT_INDEX_ROOT, NTFS_INDEX_I30, 4); 1853 if (!na) { 1854 errno = EIO; 1855 ntfs_log_perror("Failed to open directory"); 1856 return -1; 1857 } 1858 1859 /* Non-empty directory? */ 1860 if ((na->data_size != sizeof(INDEX_ROOT) + sizeof(INDEX_ENTRY_HEADER))){ 1861 /* Both ENOTEMPTY and EEXIST are ok. We use the more common. */ 1862 errno = ENOTEMPTY; 1863 ntfs_log_debug("Directory is not empty\n"); 1864 ret = -1; 1865 } 1866 1867 ntfs_attr_close(na); 1868 return ret; 1869 } 1870 1871 static int ntfs_check_unlinkable_dir(ntfs_inode *ni, FILE_NAME_ATTR *fn) 1872 { 1873 int link_count = le16_to_cpu(ni->mrec->link_count); 1874 int ret; 1875 1876 ret = ntfs_check_empty_dir(ni); 1877 if (!ret || errno != ENOTEMPTY) 1878 return ret; 1879 /* 1880 * Directory is non-empty, so we can unlink only if there is more than 1881 * one "real" hard link, i.e. links aren't different DOS and WIN32 names 1882 */ 1883 if ((link_count == 1) || 1884 (link_count == 2 && fn->file_name_type == FILE_NAME_DOS)) { 1885 errno = ENOTEMPTY; 1886 ntfs_log_debug("Non-empty directory without hard links\n"); 1887 goto no_hardlink; 1888 } 1889 1890 ret = 0; 1891 no_hardlink: 1892 return ret; 1893 } 1894 1895 /** 1896 * ntfs_delete - delete file or directory from ntfs volume 1897 * @ni: ntfs inode for object to delte 1898 * @dir_ni: ntfs inode for directory in which delete object 1899 * @name: unicode name of the object to delete 1900 * @name_len: length of the name in unicode characters 1901 * 1902 * @ni is always closed after the call to this function (even if it failed), 1903 * user does not need to call ntfs_inode_close himself. 1904 * 1905 * Return 0 on success or -1 on error with errno set to the error code. 1906 */ 1907 int ntfs_delete(ntfs_volume *vol, const char *pathname, 1908 ntfs_inode *ni, ntfs_inode *dir_ni, const ntfschar *name, 1909 u8 name_len) 1910 { 1911 ntfs_attr_search_ctx *actx = NULL; 1912 FILE_NAME_ATTR *fn = NULL; 1913 BOOL looking_for_dos_name = FALSE, looking_for_win32_name = FALSE; 1914 BOOL case_sensitive_match = TRUE; 1915 int err = 0; 1916 #if CACHE_NIDATA_SIZE 1917 int i; 1918 #endif 1919 #if CACHE_INODE_SIZE 1920 struct CACHED_INODE item; 1921 const char *p; 1922 u64 inum = (u64)-1; 1923 int count; 1924 #endif 1925 #if CACHE_LOOKUP_SIZE 1926 struct CACHED_LOOKUP lkitem; 1927 #endif 1928 1929 ntfs_log_trace("Entering.\n"); 1930 1931 if (!ni || !dir_ni || !name || !name_len) { 1932 ntfs_log_error("Invalid arguments.\n"); 1933 errno = EINVAL; 1934 goto err_out; 1935 } 1936 if (ni->nr_extents == -1) 1937 ni = ni->base_ni; 1938 if (dir_ni->nr_extents == -1) 1939 dir_ni = dir_ni->base_ni; 1940 /* 1941 * Search for FILE_NAME attribute with such name. If it's in POSIX or 1942 * WIN32_AND_DOS namespace, then simply remove it from index and inode. 1943 * If filename in DOS or in WIN32 namespace, then remove DOS name first, 1944 * only then remove WIN32 name. 1945 */ 1946 actx = ntfs_attr_get_search_ctx(ni, NULL); 1947 if (!actx) 1948 goto err_out; 1949 search: 1950 while (!(err = ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, 1951 CASE_SENSITIVE, 0, NULL, 0, actx))) { 1952 #ifdef DEBUG 1953 char *s; 1954 #endif 1955 IGNORE_CASE_BOOL case_sensitive = IGNORE_CASE; 1956 1957 fn = (FILE_NAME_ATTR*)((u8*)actx->attr + 1958 le16_to_cpu(actx->attr->value_offset)); 1959 #ifdef DEBUG 1960 s = ntfs_attr_name_get(fn->file_name, fn->file_name_length); 1961 ntfs_log_trace("name: '%s' type: %d dos: %d win32: %d " 1962 "case: %d\n", s, fn->file_name_type, 1963 looking_for_dos_name, looking_for_win32_name, 1964 case_sensitive_match); 1965 ntfs_attr_name_free(&s); 1966 #endif 1967 if (looking_for_dos_name) { 1968 if (fn->file_name_type == FILE_NAME_DOS) 1969 break; 1970 else 1971 continue; 1972 } 1973 if (looking_for_win32_name) { 1974 if (fn->file_name_type == FILE_NAME_WIN32) 1975 break; 1976 else 1977 continue; 1978 } 1979 1980 /* Ignore hard links from other directories */ 1981 if (dir_ni->mft_no != MREF_LE(fn->parent_directory)) { 1982 ntfs_log_debug("MFT record numbers don't match " 1983 "(%llu != %llu)\n", 1984 (long long unsigned)dir_ni->mft_no, 1985 (long long unsigned)MREF_LE(fn->parent_directory)); 1986 continue; 1987 } 1988 if (case_sensitive_match 1989 || ((fn->file_name_type == FILE_NAME_POSIX) 1990 && NVolCaseSensitive(ni->vol))) 1991 case_sensitive = CASE_SENSITIVE; 1992 1993 if (ntfs_names_are_equal(fn->file_name, fn->file_name_length, 1994 name, name_len, case_sensitive, 1995 ni->vol->upcase, ni->vol->upcase_len)){ 1996 1997 if (fn->file_name_type == FILE_NAME_WIN32) { 1998 looking_for_dos_name = TRUE; 1999 ntfs_attr_reinit_search_ctx(actx); 2000 continue; 2001 } 2002 if (fn->file_name_type == FILE_NAME_DOS) 2003 looking_for_dos_name = TRUE; 2004 break; 2005 } 2006 } 2007 if (err) { 2008 /* 2009 * If case sensitive search failed, then try once again 2010 * ignoring case. 2011 */ 2012 if (errno == ENOENT && case_sensitive_match) { 2013 case_sensitive_match = FALSE; 2014 ntfs_attr_reinit_search_ctx(actx); 2015 goto search; 2016 } 2017 goto err_out; 2018 } 2019 2020 if (ntfs_check_unlinkable_dir(ni, fn) < 0) 2021 goto err_out; 2022 2023 if (ntfs_index_remove(dir_ni, ni, fn, le32_to_cpu(actx->attr->value_length))) 2024 goto err_out; 2025 2026 /* 2027 * Keep the last name in place, this is useful for undeletion 2028 * (Windows also does so), however delete the name if it were 2029 * in an extent, to avoid leaving an attribute list. 2030 */ 2031 if ((ni->mrec->link_count == const_cpu_to_le16(1)) && !actx->base_ntfs_ino) { 2032 /* make sure to not loop to another search */ 2033 looking_for_dos_name = FALSE; 2034 } else { 2035 if (ntfs_attr_record_rm(actx)) 2036 goto err_out; 2037 } 2038 2039 ni->mrec->link_count = cpu_to_le16(le16_to_cpu( 2040 ni->mrec->link_count) - 1); 2041 2042 ntfs_inode_mark_dirty(ni); 2043 if (looking_for_dos_name) { 2044 looking_for_dos_name = FALSE; 2045 looking_for_win32_name = TRUE; 2046 ntfs_attr_reinit_search_ctx(actx); 2047 goto search; 2048 } 2049 /* TODO: Update object id, quota and securiry indexes if required. */ 2050 /* 2051 * If hard link count is not equal to zero then we are done. In other 2052 * case there are no reference to this inode left, so we should free all 2053 * non-resident attributes and mark all MFT record as not in use. 2054 */ 2055 #if CACHE_LOOKUP_SIZE 2056 /* invalidate entry in lookup cache */ 2057 lkitem.name = (const char*)NULL; 2058 lkitem.namesize = 0; 2059 lkitem.inum = ni->mft_no; 2060 lkitem.parent = dir_ni->mft_no; 2061 ntfs_invalidate_cache(vol->lookup_cache, GENERIC(&lkitem), 2062 lookup_cache_inv_compare, CACHE_NOHASH); 2063 #endif 2064 #if CACHE_INODE_SIZE 2065 inum = ni->mft_no; 2066 if (pathname) { 2067 /* invalide cache entry, even if there was an error */ 2068 /* Remove leading /'s. */ 2069 p = pathname; 2070 while (*p == PATH_SEP) 2071 p++; 2072 if (p[0] && (p[strlen(p)-1] == PATH_SEP)) 2073 ntfs_log_error("Unnormalized path %s\n",pathname); 2074 item.pathname = p; 2075 item.varsize = strlen(p); 2076 } else { 2077 item.pathname = (const char*)NULL; 2078 item.varsize = 0; 2079 } 2080 item.inum = inum; 2081 count = ntfs_invalidate_cache(vol->xinode_cache, GENERIC(&item), 2082 inode_cache_inv_compare, CACHE_NOHASH); 2083 if (pathname && !count) 2084 ntfs_log_error("Could not delete inode cache entry for %s\n", 2085 pathname); 2086 #endif 2087 if (ni->mrec->link_count) { 2088 ntfs_inode_update_times(ni, NTFS_UPDATE_CTIME); 2089 goto ok; 2090 } 2091 if (ntfs_delete_reparse_index(ni)) { 2092 /* 2093 * Failed to remove the reparse index : proceed anyway 2094 * This is not a critical error, the entry is useless 2095 * because of sequence_number, and stopping file deletion 2096 * would be much worse as the file is not referenced now. 2097 */ 2098 err = errno; 2099 } 2100 if (ntfs_delete_object_id_index(ni)) { 2101 /* 2102 * Failed to remove the object id index : proceed anyway 2103 * This is not a critical error. 2104 */ 2105 err = errno; 2106 } 2107 ntfs_attr_reinit_search_ctx(actx); 2108 while (!ntfs_attrs_walk(actx)) { 2109 if (actx->attr->non_resident) { 2110 runlist *rl; 2111 2112 rl = ntfs_mapping_pairs_decompress(ni->vol, actx->attr, 2113 NULL); 2114 if (!rl) { 2115 err = errno; 2116 ntfs_log_error("Failed to decompress runlist. " 2117 "Leaving inconsistent metadata.\n"); 2118 continue; 2119 } 2120 if (ntfs_cluster_free_from_rl(ni->vol, rl)) { 2121 err = errno; 2122 ntfs_log_error("Failed to free clusters. " 2123 "Leaving inconsistent metadata.\n"); 2124 continue; 2125 } 2126 free(rl); 2127 } 2128 } 2129 if (errno != ENOENT) { 2130 err = errno; 2131 ntfs_log_error("Attribute enumeration failed. " 2132 "Probably leaving inconsistent metadata.\n"); 2133 } 2134 /* All extents should be attached after attribute walk. */ 2135 #if CACHE_NIDATA_SIZE 2136 /* 2137 * Disconnect extents before deleting them, so they are 2138 * not wrongly moved to cache through the chainings 2139 */ 2140 for (i=ni->nr_extents-1; i>=0; i--) { 2141 ni->extent_nis[i]->base_ni = (ntfs_inode*)NULL; 2142 ni->extent_nis[i]->nr_extents = 0; 2143 if (ntfs_mft_record_free(ni->vol, ni->extent_nis[i])) { 2144 err = errno; 2145 ntfs_log_error("Failed to free extent MFT record. " 2146 "Leaving inconsistent metadata.\n"); 2147 } 2148 } 2149 free(ni->extent_nis); 2150 ni->nr_extents = 0; 2151 ni->extent_nis = (ntfs_inode**)NULL; 2152 #else 2153 while (ni->nr_extents) 2154 if (ntfs_mft_record_free(ni->vol, *(ni->extent_nis))) { 2155 err = errno; 2156 ntfs_log_error("Failed to free extent MFT record. " 2157 "Leaving inconsistent metadata.\n"); 2158 } 2159 #endif 2160 debug_double_inode(ni->mft_no,0); 2161 if (ntfs_mft_record_free(ni->vol, ni)) { 2162 err = errno; 2163 ntfs_log_error("Failed to free base MFT record. " 2164 "Leaving inconsistent metadata.\n"); 2165 } 2166 ni = NULL; 2167 ok: 2168 ntfs_inode_update_times(dir_ni, NTFS_UPDATE_MCTIME); 2169 out: 2170 if (actx) 2171 ntfs_attr_put_search_ctx(actx); 2172 if (ntfs_inode_close(dir_ni) && !err) 2173 err = errno; 2174 if (ntfs_inode_close(ni) && !err) 2175 err = errno; 2176 if (err) { 2177 errno = err; 2178 ntfs_log_debug("Could not delete file: %s\n", strerror(errno)); 2179 return -1; 2180 } 2181 ntfs_log_trace("Done.\n"); 2182 return 0; 2183 err_out: 2184 err = errno; 2185 goto out; 2186 } 2187 2188 /** 2189 * ntfs_link - create hard link for file or directory 2190 * @ni: ntfs inode for object to create hard link 2191 * @dir_ni: ntfs inode for directory in which new link should be placed 2192 * @name: unicode name of the new link 2193 * @name_len: length of the name in unicode characters 2194 * 2195 * NOTE: At present we allow creating hardlinks to directories, we use them 2196 * in a temporary state during rename. But it's defenitely bad idea to have 2197 * hard links to directories as a result of operation. 2198 * FIXME: Create internal __ntfs_link that allows hard links to a directories 2199 * and external ntfs_link that do not. Write ntfs_rename that uses __ntfs_link. 2200 * 2201 * Return 0 on success or -1 on error with errno set to the error code. 2202 */ 2203 static int ntfs_link_i(ntfs_inode *ni, ntfs_inode *dir_ni, const ntfschar *name, 2204 u8 name_len, FILE_NAME_TYPE_FLAGS nametype) 2205 { 2206 FILE_NAME_ATTR *fn = NULL; 2207 int fn_len, err; 2208 2209 ntfs_log_trace("Entering.\n"); 2210 2211 if (!ni || !dir_ni || !name || !name_len || 2212 ni->mft_no == dir_ni->mft_no) { 2213 err = EINVAL; 2214 ntfs_log_perror("ntfs_link wrong arguments"); 2215 goto err_out; 2216 } 2217 2218 if (NVolHideDotFiles(dir_ni->vol)) { 2219 /* Set hidden flag according to the latest name */ 2220 if ((name_len > 1) 2221 && (name[0] == const_cpu_to_le16('.')) 2222 && (name[1] != const_cpu_to_le16('.'))) 2223 ni->flags |= FILE_ATTR_HIDDEN; 2224 else 2225 ni->flags &= ~FILE_ATTR_HIDDEN; 2226 } 2227 2228 /* Create FILE_NAME attribute. */ 2229 fn_len = sizeof(FILE_NAME_ATTR) + name_len * sizeof(ntfschar); 2230 fn = ntfs_calloc(fn_len); 2231 if (!fn) { 2232 err = errno; 2233 goto err_out; 2234 } 2235 fn->parent_directory = MK_LE_MREF(dir_ni->mft_no, 2236 le16_to_cpu(dir_ni->mrec->sequence_number)); 2237 fn->file_name_length = name_len; 2238 fn->file_name_type = nametype; 2239 fn->file_attributes = ni->flags; 2240 if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) { 2241 fn->file_attributes |= FILE_ATTR_I30_INDEX_PRESENT; 2242 fn->data_size = fn->allocated_size = const_cpu_to_sle64(0); 2243 } else { 2244 fn->allocated_size = cpu_to_sle64(ni->allocated_size); 2245 fn->data_size = cpu_to_sle64(ni->data_size); 2246 } 2247 fn->creation_time = ni->creation_time; 2248 fn->last_data_change_time = ni->last_data_change_time; 2249 fn->last_mft_change_time = ni->last_mft_change_time; 2250 fn->last_access_time = ni->last_access_time; 2251 memcpy(fn->file_name, name, name_len * sizeof(ntfschar)); 2252 /* Add FILE_NAME attribute to index. */ 2253 if (ntfs_index_add_filename(dir_ni, fn, MK_MREF(ni->mft_no, 2254 le16_to_cpu(ni->mrec->sequence_number)))) { 2255 err = errno; 2256 ntfs_log_perror("Failed to add filename to the index"); 2257 goto err_out; 2258 } 2259 /* Add FILE_NAME attribute to inode. */ 2260 if (ntfs_attr_add(ni, AT_FILE_NAME, AT_UNNAMED, 0, (u8*)fn, fn_len)) { 2261 ntfs_log_error("Failed to add FILE_NAME attribute.\n"); 2262 err = errno; 2263 /* Try to remove just added attribute from index. */ 2264 if (ntfs_index_remove(dir_ni, ni, fn, fn_len)) 2265 goto rollback_failed; 2266 goto err_out; 2267 } 2268 /* Increment hard links count. */ 2269 ni->mrec->link_count = cpu_to_le16(le16_to_cpu( 2270 ni->mrec->link_count) + 1); 2271 /* Done! */ 2272 ntfs_inode_mark_dirty(ni); 2273 free(fn); 2274 ntfs_log_trace("Done.\n"); 2275 return 0; 2276 rollback_failed: 2277 ntfs_log_error("Rollback failed. Leaving inconsistent metadata.\n"); 2278 err_out: 2279 free(fn); 2280 errno = err; 2281 return -1; 2282 } 2283 2284 int ntfs_link(ntfs_inode *ni, ntfs_inode *dir_ni, const ntfschar *name, 2285 u8 name_len) 2286 { 2287 return (ntfs_link_i(ni, dir_ni, name, name_len, FILE_NAME_POSIX)); 2288 } 2289 2290 /* 2291 * Get a parent directory from an inode entry 2292 * 2293 * This is only used in situations where the path used to access 2294 * the current file is not known for sure. The result may be different 2295 * from the path when the file is linked in several parent directories. 2296 * 2297 * Currently this is only used for translating ".." in the target 2298 * of a Vista relative symbolic link 2299 */ 2300 2301 ntfs_inode *ntfs_dir_parent_inode(ntfs_inode *ni) 2302 { 2303 ntfs_inode *dir_ni = (ntfs_inode*)NULL; 2304 u64 inum; 2305 FILE_NAME_ATTR *fn; 2306 ntfs_attr_search_ctx *ctx; 2307 2308 if (ni->mft_no != FILE_root) { 2309 /* find the name in the attributes */ 2310 ctx = ntfs_attr_get_search_ctx(ni, NULL); 2311 if (!ctx) 2312 return ((ntfs_inode*)NULL); 2313 2314 if (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, 2315 CASE_SENSITIVE, 0, NULL, 0, ctx)) { 2316 /* We know this will always be resident. */ 2317 fn = (FILE_NAME_ATTR*)((u8*)ctx->attr + 2318 le16_to_cpu(ctx->attr->value_offset)); 2319 inum = le64_to_cpu(fn->parent_directory); 2320 if (inum != (u64)-1) { 2321 dir_ni = ntfs_inode_open(ni->vol, MREF(inum)); 2322 } 2323 } 2324 ntfs_attr_put_search_ctx(ctx); 2325 } 2326 return (dir_ni); 2327 } 2328 2329 #define MAX_DOS_NAME_LENGTH 12 2330 2331 /* 2332 * Get a DOS name for a file in designated directory 2333 * 2334 * Not allowed if there are several non-dos names (EMLINK) 2335 * 2336 * Returns size if found 2337 * 0 if not found 2338 * -1 if there was an error (described by errno) 2339 */ 2340 2341 static int get_dos_name(ntfs_inode *ni, u64 dnum, ntfschar *dosname) 2342 { 2343 size_t outsize = 0; 2344 int namecount = 0; 2345 FILE_NAME_ATTR *fn; 2346 ntfs_attr_search_ctx *ctx; 2347 2348 /* find the name in the attributes */ 2349 ctx = ntfs_attr_get_search_ctx(ni, NULL); 2350 if (!ctx) 2351 return -1; 2352 2353 while (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, CASE_SENSITIVE, 2354 0, NULL, 0, ctx)) { 2355 /* We know this will always be resident. */ 2356 fn = (FILE_NAME_ATTR*)((u8*)ctx->attr + 2357 le16_to_cpu(ctx->attr->value_offset)); 2358 2359 if (fn->file_name_type != FILE_NAME_DOS) 2360 namecount++; 2361 if ((fn->file_name_type & FILE_NAME_DOS) 2362 && (MREF_LE(fn->parent_directory) == dnum)) { 2363 /* 2364 * Found a DOS or WIN32+DOS name for the entry 2365 * copy name, after truncation for safety 2366 */ 2367 outsize = fn->file_name_length; 2368 /* TODO : reject if name is too long ? */ 2369 if (outsize > MAX_DOS_NAME_LENGTH) 2370 outsize = MAX_DOS_NAME_LENGTH; 2371 memcpy(dosname,fn->file_name,outsize*sizeof(ntfschar)); 2372 } 2373 } 2374 ntfs_attr_put_search_ctx(ctx); 2375 if ((outsize > 0) && (namecount > 1)) { 2376 outsize = -1; 2377 errno = EMLINK; /* this error implies there is a dos name */ 2378 } 2379 return (outsize); 2380 } 2381 2382 2383 /* 2384 * Get a long name for a file in designated directory 2385 * 2386 * Not allowed if there are several non-dos names (EMLINK) 2387 * 2388 * Returns size if found 2389 * 0 if not found 2390 * -1 if there was an error (described by errno) 2391 */ 2392 2393 static int get_long_name(ntfs_inode *ni, u64 dnum, ntfschar *longname) 2394 { 2395 size_t outsize = 0; 2396 int namecount = 0; 2397 FILE_NAME_ATTR *fn; 2398 ntfs_attr_search_ctx *ctx; 2399 2400 /* find the name in the attributes */ 2401 ctx = ntfs_attr_get_search_ctx(ni, NULL); 2402 if (!ctx) 2403 return -1; 2404 2405 /* first search for WIN32 or DOS+WIN32 names */ 2406 while (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, CASE_SENSITIVE, 2407 0, NULL, 0, ctx)) { 2408 /* We know this will always be resident. */ 2409 fn = (FILE_NAME_ATTR*)((u8*)ctx->attr + 2410 le16_to_cpu(ctx->attr->value_offset)); 2411 2412 if (fn->file_name_type != FILE_NAME_DOS) 2413 namecount++; 2414 if ((fn->file_name_type & FILE_NAME_WIN32) 2415 && (MREF_LE(fn->parent_directory) == dnum)) { 2416 /* 2417 * Found a WIN32 or WIN32+DOS name for the entry 2418 * copy name 2419 */ 2420 outsize = fn->file_name_length; 2421 memcpy(longname,fn->file_name,outsize*sizeof(ntfschar)); 2422 } 2423 } 2424 if (namecount > 1) { 2425 ntfs_attr_put_search_ctx(ctx); 2426 errno = EMLINK; 2427 return -1; 2428 } 2429 /* if not found search for POSIX names */ 2430 if (!outsize) { 2431 ntfs_attr_reinit_search_ctx(ctx); 2432 while (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, CASE_SENSITIVE, 2433 0, NULL, 0, ctx)) { 2434 /* We know this will always be resident. */ 2435 fn = (FILE_NAME_ATTR*)((u8*)ctx->attr + 2436 le16_to_cpu(ctx->attr->value_offset)); 2437 2438 if ((fn->file_name_type == FILE_NAME_POSIX) 2439 && (MREF_LE(fn->parent_directory) == dnum)) { 2440 /* 2441 * Found a POSIX name for the entry 2442 * copy name 2443 */ 2444 outsize = fn->file_name_length; 2445 memcpy(longname,fn->file_name,outsize*sizeof(ntfschar)); 2446 } 2447 } 2448 } 2449 ntfs_attr_put_search_ctx(ctx); 2450 return (outsize); 2451 } 2452 2453 2454 /* 2455 * Get the ntfs DOS name into an extended attribute 2456 */ 2457 2458 int ntfs_get_ntfs_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni, 2459 char *value, size_t size) 2460 { 2461 int outsize = 0; 2462 char *outname = (char*)NULL; 2463 u64 dnum; 2464 int doslen; 2465 ntfschar dosname[MAX_DOS_NAME_LENGTH]; 2466 2467 dnum = dir_ni->mft_no; 2468 doslen = get_dos_name(ni, dnum, dosname); 2469 if (doslen > 0) { 2470 /* 2471 * Found a DOS name for the entry, make 2472 * uppercase and encode into the buffer 2473 * if there is enough space 2474 */ 2475 ntfs_name_upcase(dosname, doslen, 2476 ni->vol->upcase, ni->vol->upcase_len); 2477 outsize = ntfs_ucstombs(dosname, doslen, &outname, 0); 2478 if (outsize < 0) { 2479 ntfs_log_error("Cannot represent dosname in current locale.\n"); 2480 outsize = -errno; 2481 } else { 2482 if (value && (outsize <= (int)size)) 2483 memcpy(value, outname, outsize); 2484 else 2485 if (size && (outsize > (int)size)) 2486 outsize = -ERANGE; 2487 free(outname); 2488 } 2489 } else { 2490 if (doslen == 0) 2491 errno = ENODATA; 2492 outsize = -errno; 2493 } 2494 return (outsize); 2495 } 2496 2497 /* 2498 * Change the name space of an existing file or directory 2499 * 2500 * Returns the old namespace if successful 2501 * -1 if an error occurred (described by errno) 2502 */ 2503 2504 static int set_namespace(ntfs_inode *ni, ntfs_inode *dir_ni, 2505 const ntfschar *name, int len, 2506 FILE_NAME_TYPE_FLAGS nametype) 2507 { 2508 ntfs_attr_search_ctx *actx; 2509 ntfs_index_context *icx; 2510 FILE_NAME_ATTR *fnx; 2511 FILE_NAME_ATTR *fn = NULL; 2512 BOOL found; 2513 int lkup; 2514 int ret; 2515 2516 ret = -1; 2517 actx = ntfs_attr_get_search_ctx(ni, NULL); 2518 if (actx) { 2519 found = FALSE; 2520 do { 2521 lkup = ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, 2522 CASE_SENSITIVE, 0, NULL, 0, actx); 2523 if (!lkup) { 2524 fn = (FILE_NAME_ATTR*)((u8*)actx->attr + 2525 le16_to_cpu(actx->attr->value_offset)); 2526 found = (MREF_LE(fn->parent_directory) 2527 == dir_ni->mft_no) 2528 && !memcmp(fn->file_name, name, 2529 len*sizeof(ntfschar)); 2530 } 2531 } while (!lkup && !found); 2532 if (found) { 2533 icx = ntfs_index_ctx_get(dir_ni, NTFS_INDEX_I30, 4); 2534 if (icx) { 2535 lkup = ntfs_index_lookup((char*)fn, len, icx); 2536 if (!lkup && icx->data && icx->data_len) { 2537 fnx = (FILE_NAME_ATTR*)icx->data; 2538 ret = fn->file_name_type; 2539 fn->file_name_type = nametype; 2540 fnx->file_name_type = nametype; 2541 ntfs_inode_mark_dirty(ni); 2542 ntfs_index_entry_mark_dirty(icx); 2543 } 2544 ntfs_index_ctx_put(icx); 2545 } 2546 } 2547 ntfs_attr_put_search_ctx(actx); 2548 } 2549 return (ret); 2550 } 2551 2552 /* 2553 * Set a DOS name to a file and adjust name spaces 2554 * 2555 * If the new names are collapsible (same uppercased chars) : 2556 * 2557 * - the existing DOS name or DOS+Win32 name is made Posix 2558 * - if it was a real DOS name, the existing long name is made DOS+Win32 2559 * and the existing DOS name is deleted 2560 * - finally the existing long name is made DOS+Win32 unless already done 2561 * 2562 * If the new names are not collapsible : 2563 * 2564 * - insert the short name as a DOS name 2565 * - delete the old long name or existing short name 2566 * - insert the new long name (as a Win32 or DOS+Win32 name) 2567 * 2568 * Deleting the old long name will not delete the file 2569 * provided the old name was in the Posix name space, 2570 * because the alternate name has been set before. 2571 * 2572 * The inodes of file and parent directory are always closed 2573 * 2574 * Returns 0 if successful 2575 * -1 if failed 2576 */ 2577 2578 static int set_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni, 2579 const ntfschar *shortname, int shortlen, 2580 const ntfschar *longname, int longlen, 2581 const ntfschar *deletename, int deletelen, BOOL existed) 2582 { 2583 unsigned int linkcount; 2584 ntfs_volume *vol; 2585 BOOL collapsible; 2586 BOOL deleted; 2587 BOOL done; 2588 FILE_NAME_TYPE_FLAGS oldnametype; 2589 u64 dnum; 2590 u64 fnum; 2591 int res; 2592 2593 res = -1; 2594 vol = ni->vol; 2595 dnum = dir_ni->mft_no; 2596 fnum = ni->mft_no; 2597 /* save initial link count */ 2598 linkcount = le16_to_cpu(ni->mrec->link_count); 2599 2600 /* check whether the same name may be used as DOS and WIN32 */ 2601 collapsible = ntfs_collapsible_chars(ni->vol, shortname, shortlen, 2602 longname, longlen); 2603 if (collapsible) { 2604 deleted = FALSE; 2605 done = FALSE; 2606 if (existed) { 2607 oldnametype = set_namespace(ni, dir_ni, deletename, 2608 deletelen, FILE_NAME_POSIX); 2609 if (oldnametype == FILE_NAME_DOS) { 2610 if (set_namespace(ni, dir_ni, longname, longlen, 2611 FILE_NAME_WIN32_AND_DOS) >= 0) { 2612 if (!ntfs_delete(vol, 2613 (const char*)NULL, ni, dir_ni, 2614 deletename, deletelen)) 2615 res = 0; 2616 deleted = TRUE; 2617 } else 2618 done = TRUE; 2619 } 2620 } 2621 if (!deleted) { 2622 if (!done && (set_namespace(ni, dir_ni, 2623 longname, longlen, 2624 FILE_NAME_WIN32_AND_DOS) >= 0)) 2625 res = 0; 2626 ntfs_inode_update_times(ni, NTFS_UPDATE_CTIME); 2627 ntfs_inode_update_times(dir_ni, NTFS_UPDATE_MCTIME); 2628 if (ntfs_inode_close_in_dir(ni,dir_ni) && !res) 2629 res = -1; 2630 if (ntfs_inode_close(dir_ni) && !res) 2631 res = -1; 2632 } 2633 } else { 2634 if (!ntfs_link_i(ni, dir_ni, shortname, shortlen, 2635 FILE_NAME_DOS) 2636 /* make sure a new link was recorded */ 2637 && (le16_to_cpu(ni->mrec->link_count) > linkcount)) { 2638 /* delete the existing long name or short name */ 2639 // is it ok to not provide the path ? 2640 if (!ntfs_delete(vol, (char*)NULL, ni, dir_ni, 2641 deletename, deletelen)) { 2642 /* delete closes the inodes, so have to open again */ 2643 dir_ni = ntfs_inode_open(vol, dnum); 2644 if (dir_ni) { 2645 ni = ntfs_inode_open(vol, fnum); 2646 if (ni) { 2647 if (!ntfs_link_i(ni, dir_ni, 2648 longname, longlen, 2649 FILE_NAME_WIN32)) 2650 res = 0; 2651 if (ntfs_inode_close_in_dir(ni, 2652 dir_ni) 2653 && !res) 2654 res = -1; 2655 } 2656 if (ntfs_inode_close(dir_ni) && !res) 2657 res = -1; 2658 } 2659 } 2660 } else { 2661 ntfs_inode_close_in_dir(ni,dir_ni); 2662 ntfs_inode_close(dir_ni); 2663 } 2664 } 2665 return (res); 2666 } 2667 2668 2669 /* 2670 * Set the ntfs DOS name into an extended attribute 2671 * 2672 * The DOS name will be added as another file name attribute 2673 * using the existing file name information from the original 2674 * name or overwriting the DOS Name if one exists. 2675 * 2676 * The inode of the file is always closed 2677 */ 2678 2679 int ntfs_set_ntfs_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni, 2680 const char *value, size_t size, int flags) 2681 { 2682 int res = 0; 2683 int longlen = 0; 2684 int shortlen = 0; 2685 char newname[3*MAX_DOS_NAME_LENGTH + 1]; 2686 ntfschar oldname[MAX_DOS_NAME_LENGTH]; 2687 int oldlen; 2688 u64 dnum; 2689 BOOL closed = FALSE; 2690 ntfschar *shortname = NULL; 2691 ntfschar longname[NTFS_MAX_NAME_LEN]; 2692 2693 /* copy the string to insert a null char, and truncate */ 2694 if (size > 3*MAX_DOS_NAME_LENGTH) 2695 size = 3*MAX_DOS_NAME_LENGTH; 2696 strncpy(newname, value, size); 2697 /* a long name may be truncated badly and be untranslatable */ 2698 newname[size] = 0; 2699 /* convert the string to the NTFS wide chars, and truncate */ 2700 shortlen = ntfs_mbstoucs(newname, &shortname); 2701 if (shortlen > MAX_DOS_NAME_LENGTH) 2702 shortlen = MAX_DOS_NAME_LENGTH; 2703 2704 /* Make sure the short name has valid chars. 2705 * Note: the short name cannot end with dot or space, but the 2706 * corresponding long name can. */ 2707 if ((shortlen < 0) 2708 || ntfs_forbidden_names(ni->vol,shortname,shortlen,TRUE)) { 2709 ntfs_inode_close_in_dir(ni,dir_ni); 2710 ntfs_inode_close(dir_ni); 2711 res = -errno; 2712 return res; 2713 } 2714 dnum = dir_ni->mft_no; 2715 longlen = get_long_name(ni, dnum, longname); 2716 if (longlen > 0) { 2717 oldlen = get_dos_name(ni, dnum, oldname); 2718 if ((oldlen >= 0) 2719 && !ntfs_forbidden_names(ni->vol, longname, longlen, 2720 FALSE)) { 2721 if (oldlen > 0) { 2722 if (flags & XATTR_CREATE) { 2723 res = -1; 2724 errno = EEXIST; 2725 } else 2726 if ((shortlen == oldlen) 2727 && !memcmp(shortname,oldname, 2728 oldlen*sizeof(ntfschar))) 2729 /* already set, done */ 2730 res = 0; 2731 else { 2732 res = set_dos_name(ni, dir_ni, 2733 shortname, shortlen, 2734 longname, longlen, 2735 oldname, oldlen, TRUE); 2736 closed = TRUE; 2737 } 2738 } else { 2739 if (flags & XATTR_REPLACE) { 2740 res = -1; 2741 errno = ENODATA; 2742 } else { 2743 res = set_dos_name(ni, dir_ni, 2744 shortname, shortlen, 2745 longname, longlen, 2746 longname, longlen, FALSE); 2747 closed = TRUE; 2748 } 2749 } 2750 } else 2751 res = -1; 2752 } else { 2753 res = -1; 2754 if (!longlen) 2755 errno = ENOENT; 2756 } 2757 free(shortname); 2758 if (!closed) { 2759 ntfs_inode_close_in_dir(ni,dir_ni); 2760 ntfs_inode_close(dir_ni); 2761 } 2762 return (res ? -1 : 0); 2763 } 2764 2765 /* 2766 * Delete the ntfs DOS name 2767 */ 2768 2769 int ntfs_remove_ntfs_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni) 2770 { 2771 int res; 2772 int oldnametype; 2773 int longlen = 0; 2774 int shortlen; 2775 u64 dnum; 2776 ntfs_volume *vol; 2777 BOOL deleted = FALSE; 2778 ntfschar shortname[MAX_DOS_NAME_LENGTH]; 2779 ntfschar longname[NTFS_MAX_NAME_LEN]; 2780 2781 res = -1; 2782 vol = ni->vol; 2783 dnum = dir_ni->mft_no; 2784 longlen = get_long_name(ni, dnum, longname); 2785 if (longlen > 0) { 2786 shortlen = get_dos_name(ni, dnum, shortname); 2787 if (shortlen >= 0) { 2788 /* migrate the long name as Posix */ 2789 oldnametype = set_namespace(ni,dir_ni,longname,longlen, 2790 FILE_NAME_POSIX); 2791 switch (oldnametype) { 2792 case FILE_NAME_WIN32_AND_DOS : 2793 /* name was Win32+DOS : done */ 2794 res = 0; 2795 break; 2796 case FILE_NAME_DOS : 2797 /* name was DOS, make it back to DOS */ 2798 set_namespace(ni,dir_ni,longname,longlen, 2799 FILE_NAME_DOS); 2800 errno = ENOENT; 2801 break; 2802 case FILE_NAME_WIN32 : 2803 /* name was Win32, make it Posix and delete */ 2804 if (set_namespace(ni,dir_ni,shortname,shortlen, 2805 FILE_NAME_POSIX) >= 0) { 2806 if (!ntfs_delete(vol, 2807 (const char*)NULL, ni, 2808 dir_ni, shortname, 2809 shortlen)) 2810 res = 0; 2811 deleted = TRUE; 2812 } else { 2813 /* 2814 * DOS name has been found, but cannot 2815 * migrate to Posix : something bad 2816 * has happened 2817 */ 2818 errno = EIO; 2819 ntfs_log_error("Could not change" 2820 " DOS name of inode %lld to Posix\n", 2821 (long long)ni->mft_no); 2822 } 2823 break; 2824 default : 2825 /* name was Posix or not found : error */ 2826 errno = ENOENT; 2827 break; 2828 } 2829 } 2830 } else { 2831 if (!longlen) 2832 errno = ENOENT; 2833 res = -1; 2834 } 2835 if (!deleted) { 2836 ntfs_inode_close_in_dir(ni,dir_ni); 2837 ntfs_inode_close(dir_ni); 2838 } 2839 return (res); 2840 } 2841 2842 /* 2843 * Increment the count of subdirectories 2844 * (excluding entries with a short name) 2845 */ 2846 2847 static int nlink_increment(void *nlink_ptr, 2848 const ntfschar *name __attribute__((unused)), 2849 const int len __attribute__((unused)), 2850 const int type, 2851 const s64 pos __attribute__((unused)), 2852 const MFT_REF mref __attribute__((unused)), 2853 const unsigned int dt_type) 2854 { 2855 if ((dt_type == NTFS_DT_DIR) && (type != FILE_NAME_DOS)) 2856 (*((int*)nlink_ptr))++; 2857 return (0); 2858 } 2859 2860 /* 2861 * Compute the number of hard links according to Posix 2862 * For a directory count the subdirectories whose name is not 2863 * a short one, but count "." and ".." 2864 * Otherwise count the names, excluding the short ones. 2865 * 2866 * if there is an error, a null count is returned. 2867 */ 2868 2869 int ntfs_dir_link_cnt(ntfs_inode *ni) 2870 { 2871 ntfs_attr_search_ctx *actx; 2872 FILE_NAME_ATTR *fn; 2873 s64 pos; 2874 int err = 0; 2875 int nlink = 0; 2876 2877 if (!ni) { 2878 ntfs_log_error("Invalid argument.\n"); 2879 errno = EINVAL; 2880 goto err_out; 2881 } 2882 if (ni->nr_extents == -1) 2883 ni = ni->base_ni; 2884 if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) { 2885 /* 2886 * Directory : scan the directory and count 2887 * subdirectories whose name is not DOS-only. 2888 * The directory names are ignored, but "." and ".." 2889 * are taken into account. 2890 */ 2891 pos = 0; 2892 err = ntfs_readdir(ni, &pos, &nlink, nlink_increment); 2893 if (err) 2894 nlink = 0; 2895 } else { 2896 /* 2897 * Non-directory : search for FILE_NAME attributes, 2898 * and count those which are not DOS-only ones. 2899 */ 2900 actx = ntfs_attr_get_search_ctx(ni, NULL); 2901 if (!actx) 2902 goto err_out; 2903 while (!(err = ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, 2904 CASE_SENSITIVE, 0, NULL, 0, actx))) { 2905 fn = (FILE_NAME_ATTR*)((u8*)actx->attr + 2906 le16_to_cpu(actx->attr->value_offset)); 2907 if (fn->file_name_type != FILE_NAME_DOS) 2908 nlink++; 2909 } 2910 if (err && (errno != ENOENT)) 2911 nlink = 0; 2912 ntfs_attr_put_search_ctx(actx); 2913 } 2914 if (!nlink) 2915 ntfs_log_perror("Failed to compute nlink of inode %lld", 2916 (long long)ni->mft_no); 2917 err_out : 2918 return (nlink); 2919 } 2920