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