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