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-2006 Szabolcs Szakacsits 7 * Copyright (c) 2005-2006 Yura Pakhuchiy 8 * 9 * This program/include file is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License as published 11 * by the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program/include file is distributed in the hope that it will be 15 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 16 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program (in the main directory of the NTFS-3G 21 * distribution in the file COPYING); if not, write to the Free Software 22 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 */ 24 25 #ifdef HAVE_CONFIG_H 26 #include "config.h" 27 #endif 28 29 #ifdef HAVE_STDLIB_H 30 #include <stdlib.h> 31 #endif 32 #ifdef HAVE_ERRNO_H 33 #include <errno.h> 34 #endif 35 #ifdef HAVE_STRING_H 36 #include <string.h> 37 #endif 38 #ifdef HAVE_SYS_STAT_H 39 #include <sys/stat.h> 40 #endif 41 42 #ifdef HAVE_SYS_SYSMACROS_H 43 #include <sys/sysmacros.h> 44 #endif 45 46 #include "types.h" 47 #include "debug.h" 48 #include "attrib.h" 49 #include "inode.h" 50 #include "dir.h" 51 #include "volume.h" 52 #include "mft.h" 53 #include "index.h" 54 #include "ntfstime.h" 55 #include "lcnalloc.h" 56 #include "logging.h" 57 #include "misc.h" 58 #include "security.h" 59 60 /* 61 * The little endian Unicode strings "$I30", "$SII", "$SDH", "$O" 62 * and "$Q" as global constants. 63 */ 64 ntfschar NTFS_INDEX_I30[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('I'), 65 const_cpu_to_le16('3'), const_cpu_to_le16('0'), 66 const_cpu_to_le16('\0') }; 67 ntfschar NTFS_INDEX_SII[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('S'), 68 const_cpu_to_le16('I'), const_cpu_to_le16('I'), 69 const_cpu_to_le16('\0') }; 70 ntfschar NTFS_INDEX_SDH[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('S'), 71 const_cpu_to_le16('D'), const_cpu_to_le16('H'), 72 const_cpu_to_le16('\0') }; 73 ntfschar NTFS_INDEX_O[3] = { const_cpu_to_le16('$'), const_cpu_to_le16('O'), 74 const_cpu_to_le16('\0') }; 75 ntfschar NTFS_INDEX_Q[3] = { const_cpu_to_le16('$'), const_cpu_to_le16('Q'), 76 const_cpu_to_le16('\0') }; 77 ntfschar NTFS_INDEX_R[3] = { const_cpu_to_le16('$'), const_cpu_to_le16('R'), 78 const_cpu_to_le16('\0') }; 79 80 /** 81 * ntfs_inode_lookup_by_name - find an inode in a directory given its name 82 * @dir_ni: ntfs inode of the directory in which to search for the name 83 * @uname: Unicode name for which to search in the directory 84 * @uname_len: length of the name @uname in Unicode characters 85 * 86 * Look for an inode with name @uname in the directory with inode @dir_ni. 87 * ntfs_inode_lookup_by_name() walks the contents of the directory looking for 88 * the Unicode name. If the name is found in the directory, the corresponding 89 * inode number (>= 0) is returned as a mft reference in cpu format, i.e. it 90 * is a 64-bit number containing the sequence number. 91 * 92 * On error, return -1 with errno set to the error code. If the inode is is not 93 * found errno is ENOENT. 94 * 95 * Note, @uname_len does not include the (optional) terminating NULL character. 96 * 97 * Note, we look for a case sensitive match first but we also look for a case 98 * insensitive match at the same time. If we find a case insensitive match, we 99 * save that for the case that we don't find an exact match, where we return 100 * the mft reference of the case insensitive match. 101 * 102 * If the volume is mounted with the case sensitive flag set, then we only 103 * allow exact matches. 104 */ 105 u64 ntfs_inode_lookup_by_name(ntfs_inode *dir_ni, const ntfschar *uname, 106 const int uname_len) 107 { 108 VCN vcn; 109 u64 mref = 0; 110 s64 br; 111 ntfs_volume *vol = dir_ni->vol; 112 ntfs_attr_search_ctx *ctx; 113 INDEX_ROOT *ir; 114 INDEX_ENTRY *ie; 115 INDEX_ALLOCATION *ia; 116 u8 *index_end; 117 ntfs_attr *ia_na; 118 int eo, rc; 119 u32 index_block_size, index_vcn_size; 120 u8 index_vcn_size_bits; 121 122 ntfs_log_trace("Entering\n"); 123 124 if (!dir_ni || !dir_ni->mrec || !uname || uname_len <= 0) { 125 errno = EINVAL; 126 return -1; 127 } 128 129 ctx = ntfs_attr_get_search_ctx(dir_ni, NULL); 130 if (!ctx) 131 return -1; 132 133 /* Find the index root attribute in the mft record. */ 134 if (ntfs_attr_lookup(AT_INDEX_ROOT, NTFS_INDEX_I30, 4, CASE_SENSITIVE, 0, NULL, 135 0, ctx)) { 136 ntfs_log_perror("Index root attribute missing in directory inode " 137 "0x%llx", (unsigned long long)dir_ni->mft_no); 138 goto put_err_out; 139 } 140 /* Get to the index root value. */ 141 ir = (INDEX_ROOT*)((u8*)ctx->attr + 142 le16_to_cpu(ctx->attr->value_offset)); 143 index_block_size = le32_to_cpu(ir->index_block_size); 144 if (index_block_size < NTFS_BLOCK_SIZE || 145 index_block_size & (index_block_size - 1)) { 146 ntfs_log_debug("Index block size %u is invalid.\n", 147 (unsigned)index_block_size); 148 goto put_err_out; 149 } 150 index_end = (u8*)&ir->index + le32_to_cpu(ir->index.index_length); 151 /* The first index entry. */ 152 ie = (INDEX_ENTRY*)((u8*)&ir->index + 153 le32_to_cpu(ir->index.entries_offset)); 154 /* 155 * Loop until we exceed valid memory (corruption case) or until we 156 * reach the last entry. 157 */ 158 for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) { 159 /* Bounds checks. */ 160 if ((u8*)ie < (u8*)ctx->mrec || (u8*)ie + 161 sizeof(INDEX_ENTRY_HEADER) > index_end || 162 (u8*)ie + le16_to_cpu(ie->key_length) > 163 index_end) 164 goto put_err_out; 165 /* 166 * The last entry cannot contain a name. It can however contain 167 * a pointer to a child node in the B+tree so we just break out. 168 */ 169 if (ie->ie_flags & INDEX_ENTRY_END) 170 break; 171 /* 172 * Not a perfect match, need to do full blown collation so we 173 * know which way in the B+tree we have to go. 174 */ 175 rc = ntfs_names_collate(uname, uname_len, 176 (ntfschar*)&ie->key.file_name.file_name, 177 ie->key.file_name.file_name_length, 1, 178 IGNORE_CASE, vol->upcase, vol->upcase_len); 179 /* 180 * If uname collates before the name of the current entry, there 181 * is definitely no such name in this index but we might need to 182 * descend into the B+tree so we just break out of the loop. 183 */ 184 if (rc == -1) 185 break; 186 /* The names are not equal, continue the search. */ 187 if (rc) 188 continue; 189 /* 190 * Names match with case insensitive comparison, now try the 191 * case sensitive comparison, which is required for proper 192 * collation. 193 */ 194 rc = ntfs_names_collate(uname, uname_len, 195 (ntfschar*)&ie->key.file_name.file_name, 196 ie->key.file_name.file_name_length, 1, 197 CASE_SENSITIVE, vol->upcase, vol->upcase_len); 198 if (rc == -1) 199 break; 200 if (rc) 201 continue; 202 /* 203 * Perfect match, this will never happen as the 204 * ntfs_are_names_equal() call will have gotten a match but we 205 * still treat it correctly. 206 */ 207 mref = le64_to_cpu(ie->indexed_file); 208 ntfs_attr_put_search_ctx(ctx); 209 return mref; 210 } 211 /* 212 * We have finished with this index without success. Check for the 213 * presence of a child node and if not present return error code 214 * ENOENT, unless we have got the mft reference of a matching name 215 * cached in mref in which case return mref. 216 */ 217 if (!(ie->ie_flags & INDEX_ENTRY_NODE)) { 218 ntfs_attr_put_search_ctx(ctx); 219 if (mref) 220 return mref; 221 ntfs_log_debug("Entry not found.\n"); 222 errno = ENOENT; 223 return -1; 224 } /* Child node present, descend into it. */ 225 226 /* Open the index allocation attribute. */ 227 ia_na = ntfs_attr_open(dir_ni, AT_INDEX_ALLOCATION, NTFS_INDEX_I30, 4); 228 if (!ia_na) { 229 ntfs_log_perror("Failed to open index allocation attribute. Directory " 230 "inode 0x%llx is corrupt or driver bug", 231 (unsigned long long)dir_ni->mft_no); 232 goto put_err_out; 233 } 234 235 /* Allocate a buffer for the current index block. */ 236 ia = ntfs_malloc(index_block_size); 237 if (!ia) { 238 ntfs_attr_close(ia_na); 239 goto put_err_out; 240 } 241 242 /* Determine the size of a vcn in the directory index. */ 243 if (vol->cluster_size <= index_block_size) { 244 index_vcn_size = vol->cluster_size; 245 index_vcn_size_bits = vol->cluster_size_bits; 246 } else { 247 index_vcn_size = vol->sector_size; 248 index_vcn_size_bits = vol->sector_size_bits; 249 } 250 251 /* Get the starting vcn of the index_block holding the child node. */ 252 vcn = sle64_to_cpup((u8*)ie + le16_to_cpu(ie->length) - 8); 253 254 descend_into_child_node: 255 256 /* Read the index block starting at vcn. */ 257 br = ntfs_attr_mst_pread(ia_na, vcn << index_vcn_size_bits, 1, 258 index_block_size, ia); 259 if (br != 1) { 260 if (br != -1) 261 errno = EIO; 262 ntfs_log_perror("Failed to read vcn 0x%llx", 263 (unsigned long long)vcn); 264 goto close_err_out; 265 } 266 267 if (sle64_to_cpu(ia->index_block_vcn) != vcn) { 268 ntfs_log_debug("Actual VCN (0x%llx) of index buffer is different " 269 "from expected VCN (0x%llx).\n", 270 (long long)sle64_to_cpu(ia->index_block_vcn), 271 (long long)vcn); 272 errno = EIO; 273 goto close_err_out; 274 } 275 if (le32_to_cpu(ia->index.allocated_size) + 0x18 != index_block_size) { 276 ntfs_log_debug("Index buffer (VCN 0x%llx) of directory inode 0x%llx " 277 "has a size (%u) differing from the directory " 278 "specified size (%u).\n", (long long)vcn, 279 (unsigned long long)dir_ni->mft_no, 280 (unsigned) le32_to_cpu(ia->index.allocated_size) + 0x18, 281 (unsigned)index_block_size); 282 errno = EIO; 283 goto close_err_out; 284 } 285 index_end = (u8*)&ia->index + le32_to_cpu(ia->index.index_length); 286 if (index_end > (u8*)ia + index_block_size) { 287 ntfs_log_debug("Size of index buffer (VCN 0x%llx) of directory inode " 288 "0x%llx exceeds maximum size.\n", 289 (long long)vcn, (unsigned long long)dir_ni->mft_no); 290 errno = EIO; 291 goto close_err_out; 292 } 293 294 /* The first index entry. */ 295 ie = (INDEX_ENTRY*)((u8*)&ia->index + 296 le32_to_cpu(ia->index.entries_offset)); 297 /* 298 * Iterate similar to above big loop but applied to index buffer, thus 299 * loop until we exceed valid memory (corruption case) or until we 300 * reach the last entry. 301 */ 302 for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) { 303 /* Bounds check. */ 304 if ((u8*)ie < (u8*)ia || (u8*)ie + 305 sizeof(INDEX_ENTRY_HEADER) > index_end || 306 (u8*)ie + le16_to_cpu(ie->key_length) > 307 index_end) { 308 ntfs_log_debug("Index entry out of bounds in directory " 309 "inode 0x%llx.\n", 310 (unsigned long long)dir_ni->mft_no); 311 errno = EIO; 312 goto close_err_out; 313 } 314 /* 315 * The last entry cannot contain a name. It can however contain 316 * a pointer to a child node in the B+tree so we just break out. 317 */ 318 if (ie->ie_flags & INDEX_ENTRY_END) 319 break; 320 /* 321 * Not a perfect match, need to do full blown collation so we 322 * know which way in the B+tree we have to go. 323 */ 324 rc = ntfs_names_collate(uname, uname_len, 325 (ntfschar*)&ie->key.file_name.file_name, 326 ie->key.file_name.file_name_length, 1, 327 IGNORE_CASE, vol->upcase, vol->upcase_len); 328 /* 329 * If uname collates before the name of the current entry, there 330 * is definitely no such name in this index but we might need to 331 * descend into the B+tree so we just break out of the loop. 332 */ 333 if (rc == -1) 334 break; 335 /* The names are not equal, continue the search. */ 336 if (rc) 337 continue; 338 /* 339 * Names match with case insensitive comparison, now try the 340 * case sensitive comparison, which is required for proper 341 * collation. 342 */ 343 rc = ntfs_names_collate(uname, uname_len, 344 (ntfschar*)&ie->key.file_name.file_name, 345 ie->key.file_name.file_name_length, 1, 346 CASE_SENSITIVE, vol->upcase, vol->upcase_len); 347 if (rc == -1) 348 break; 349 if (rc) 350 continue; 351 352 mref = le64_to_cpu(ie->indexed_file); 353 free(ia); 354 ntfs_attr_close(ia_na); 355 ntfs_attr_put_search_ctx(ctx); 356 return mref; 357 } 358 /* 359 * We have finished with this index buffer without success. Check for 360 * the presence of a child node. 361 */ 362 if (ie->ie_flags & INDEX_ENTRY_NODE) { 363 if ((ia->index.ih_flags & NODE_MASK) == LEAF_NODE) { 364 ntfs_log_debug("Index entry with child node found in a leaf " 365 "node in directory inode 0x%llx.\n", 366 (unsigned long long)dir_ni->mft_no); 367 errno = EIO; 368 goto close_err_out; 369 } 370 /* Child node present, descend into it. */ 371 vcn = sle64_to_cpup((u8*)ie + le16_to_cpu(ie->length) - 8); 372 if (vcn >= 0) 373 goto descend_into_child_node; 374 ntfs_log_debug("Negative child node vcn in directory inode " 375 "0x%llx.\n", (unsigned long long)dir_ni->mft_no); 376 errno = EIO; 377 goto close_err_out; 378 } 379 free(ia); 380 ntfs_attr_close(ia_na); 381 ntfs_attr_put_search_ctx(ctx); 382 /* 383 * No child node present, return error code ENOENT, unless we have got 384 * the mft reference of a matching name cached in mref in which case 385 * return mref. 386 */ 387 if (mref) 388 return mref; 389 ntfs_log_debug("Entry not found.\n"); 390 errno = ENOENT; 391 return -1; 392 put_err_out: 393 eo = EIO; 394 ntfs_log_debug("Corrupt directory. Aborting lookup.\n"); 395 eo_put_err_out: 396 ntfs_attr_put_search_ctx(ctx); 397 errno = eo; 398 return -1; 399 close_err_out: 400 eo = errno; 401 free(ia); 402 ntfs_attr_close(ia_na); 403 goto eo_put_err_out; 404 } 405 406 /** 407 * ntfs_pathname_to_inode - Find the inode which represents the given pathname 408 * @vol: An ntfs volume obtained from ntfs_mount 409 * @parent: A directory inode to begin the search (may be NULL) 410 * @pathname: Pathname to be located 411 * 412 * Take an ASCII pathname and find the inode that represents it. The function 413 * splits the path and then descends the directory tree. If @parent is NULL, 414 * then the root directory '.' will be used as the base for the search. 415 * 416 * Return: inode Success, the pathname was valid 417 * NULL Error, the pathname was invalid, or some other error occurred 418 */ 419 ntfs_inode *ntfs_pathname_to_inode(ntfs_volume *vol, ntfs_inode *parent, 420 const char *pathname) 421 { 422 u64 inum; 423 int len, err = 0; 424 char *p, *q; 425 ntfs_inode *ni; 426 ntfs_inode *result = NULL; 427 ntfschar *unicode = NULL; 428 char *ascii = NULL; 429 430 if (!vol || !pathname) { 431 errno = EINVAL; 432 return NULL; 433 } 434 435 ntfs_log_trace("path: '%s'\n", pathname); 436 437 if (parent) { 438 ni = parent; 439 } else { 440 ni = ntfs_inode_open(vol, FILE_root); 441 if (!ni) { 442 ntfs_log_debug("Couldn't open the inode of the root " 443 "directory.\n"); 444 err = EIO; 445 goto close; 446 } 447 } 448 449 unicode = ntfs_calloc(MAX_PATH); 450 ascii = strdup(pathname); 451 if (!unicode || !ascii) { 452 ntfs_log_debug("Out of memory.\n"); 453 err = ENOMEM; 454 goto close; 455 } 456 457 p = ascii; 458 /* Remove leading /'s. */ 459 while (p && *p && *p == PATH_SEP) 460 p++; 461 while (p && *p) { 462 /* Find the end of the first token. */ 463 q = strchr(p, PATH_SEP); 464 if (q != NULL) { 465 *q = '\0'; 466 q++; 467 } 468 469 len = ntfs_mbstoucs(p, &unicode, NTFS_MAX_NAME_LEN); 470 if (len < 0) { 471 ntfs_log_debug("Couldn't convert name to Unicode: %s.\n", p); 472 err = errno; 473 goto close; 474 } 475 476 inum = ntfs_inode_lookup_by_name(ni, unicode, len); 477 if (inum == (u64) -1) { 478 ntfs_log_debug("Couldn't find name '%s' in pathname " 479 "'%s'.\n", p, pathname); 480 err = ENOENT; 481 goto close; 482 } 483 484 if (ni != parent) 485 ntfs_inode_close(ni); 486 487 inum = MREF(inum); 488 ni = ntfs_inode_open(vol, inum); 489 if (!ni) { 490 ntfs_log_debug("Cannot open inode %llu: %s.\n", 491 (unsigned long long)inum, p); 492 err = EIO; 493 goto close; 494 } 495 496 p = q; 497 while (p && *p && *p == PATH_SEP) 498 p++; 499 } 500 501 result = ni; 502 ni = NULL; 503 close: 504 if (ni && (ni != parent)) 505 ntfs_inode_close(ni); 506 free(ascii); 507 free(unicode); 508 if (err) 509 errno = err; 510 return result; 511 } 512 513 /* 514 * The little endian Unicode string ".." for ntfs_readdir(). 515 */ 516 static const ntfschar dotdot[3] = { const_cpu_to_le16('.'), 517 const_cpu_to_le16('.'), 518 const_cpu_to_le16('\0') }; 519 520 /* 521 * union index_union - 522 * More helpers for ntfs_readdir(). 523 */ 524 typedef union { 525 INDEX_ROOT *ir; 526 INDEX_ALLOCATION *ia; 527 } index_union __attribute__((__transparent_union__)); 528 529 /** 530 * enum INDEX_TYPE - 531 * More helpers for ntfs_readdir(). 532 */ 533 typedef enum { 534 INDEX_TYPE_ROOT, /* index root */ 535 INDEX_TYPE_ALLOCATION, /* index allocation */ 536 } INDEX_TYPE; 537 538 /** 539 * ntfs_filldir - ntfs specific filldir method 540 * @dir_ni: ntfs inode of current directory 541 * @pos: current position in directory 542 * @ivcn_bits: log(2) of index vcn size 543 * @index_type: specifies whether @iu is an index root or an index allocation 544 * @iu: index root or index block to which @ie belongs 545 * @ie: current index entry 546 * @dirent: context for filldir callback supplied by the caller 547 * @filldir: filldir callback supplied by the caller 548 * 549 * Pass information specifying the current directory entry @ie to the @filldir 550 * callback. 551 */ 552 static int ntfs_filldir(ntfs_inode *dir_ni, s64 *pos, u8 ivcn_bits, 553 const INDEX_TYPE index_type, index_union iu, INDEX_ENTRY *ie, 554 void *dirent, ntfs_filldir_t filldir) 555 { 556 FILE_NAME_ATTR *fn = &ie->key.file_name; 557 unsigned dt_type; 558 559 ntfs_log_trace("Entering.\n"); 560 561 /* Advance the position even if going to skip the entry. */ 562 if (index_type == INDEX_TYPE_ALLOCATION) 563 *pos = (u8*)ie - (u8*)iu.ia + (sle64_to_cpu( 564 iu.ia->index_block_vcn) << ivcn_bits) + 565 dir_ni->vol->mft_record_size; 566 else /* if (index_type == INDEX_TYPE_ROOT) */ 567 *pos = (u8*)ie - (u8*)iu.ir; 568 /* Skip root directory self reference entry. */ 569 if (MREF_LE(ie->indexed_file) == FILE_root) 570 return 0; 571 if (ie->key.file_name.file_attributes & FILE_ATTR_I30_INDEX_PRESENT) 572 dt_type = NTFS_DT_DIR; 573 else 574 dt_type = NTFS_DT_REG; 575 return filldir(dirent, fn->file_name, fn->file_name_length, 576 fn->file_name_type, *pos, 577 le64_to_cpu(ie->indexed_file), dt_type); 578 } 579 580 /** 581 * ntfs_mft_get_parent_ref - find mft reference of parent directory of an inode 582 * @ni: ntfs inode whose parent directory to find 583 * 584 * Find the parent directory of the ntfs inode @ni. To do this, find the first 585 * file name attribute in the mft record of @ni and return the parent mft 586 * reference from that. 587 * 588 * Note this only makes sense for directories, since files can be hard linked 589 * from multiple directories and there is no way for us to tell which one is 590 * being looked for. 591 * 592 * Technically directories can have hard links, too, but we consider that as 593 * illegal as Linux/UNIX do not support directory hard links. 594 * 595 * Return the mft reference of the parent directory on success or -1 on error 596 * with errno set to the error code. 597 */ 598 static MFT_REF ntfs_mft_get_parent_ref(ntfs_inode *ni) 599 { 600 MFT_REF mref; 601 ntfs_attr_search_ctx *ctx; 602 FILE_NAME_ATTR *fn; 603 int eo; 604 605 ntfs_log_trace("Entering.\n"); 606 607 if (!ni) { 608 errno = EINVAL; 609 return ERR_MREF(-1); 610 } 611 612 ctx = ntfs_attr_get_search_ctx(ni, NULL); 613 if (!ctx) 614 return ERR_MREF(-1); 615 if (ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, 0, 0, NULL, 0, ctx)) { 616 ntfs_log_debug("No file name found in inode 0x%llx. Corrupt " 617 "inode.\n", (unsigned long long)ni->mft_no); 618 goto err_out; 619 } 620 if (ctx->attr->non_resident) { 621 ntfs_log_debug("File name attribute must be resident. Corrupt inode " 622 "0x%llx.\n", (unsigned long long)ni->mft_no); 623 goto io_err_out; 624 } 625 fn = (FILE_NAME_ATTR*)((u8*)ctx->attr + 626 le16_to_cpu(ctx->attr->value_offset)); 627 if ((u8*)fn + le32_to_cpu(ctx->attr->value_length) > 628 (u8*)ctx->attr + le32_to_cpu(ctx->attr->length)) { 629 ntfs_log_debug("Corrupt file name attribute in inode 0x%llx.\n", 630 (unsigned long long)ni->mft_no); 631 goto io_err_out; 632 } 633 mref = le64_to_cpu(fn->parent_directory); 634 ntfs_attr_put_search_ctx(ctx); 635 return mref; 636 io_err_out: 637 errno = EIO; 638 err_out: 639 eo = errno; 640 ntfs_attr_put_search_ctx(ctx); 641 errno = eo; 642 return ERR_MREF(-1); 643 } 644 645 /** 646 * ntfs_readdir - read the contents of an ntfs directory 647 * @dir_ni: ntfs inode of current directory 648 * @pos: current position in directory 649 * @dirent: context for filldir callback supplied by the caller 650 * @filldir: filldir callback supplied by the caller 651 * 652 * Parse the index root and the index blocks that are marked in use in the 653 * index bitmap and hand each found directory entry to the @filldir callback 654 * supplied by the caller. 655 * 656 * Return 0 on success or -1 on error with errno set to the error code. 657 * 658 * Note: Index blocks are parsed in ascending vcn order, from which follows 659 * that the directory entries are not returned sorted. 660 */ 661 int ntfs_readdir(ntfs_inode *dir_ni, s64 *pos, 662 void *dirent, ntfs_filldir_t filldir) 663 { 664 s64 i_size, br, ia_pos, bmp_pos, ia_start; 665 ntfs_volume *vol; 666 ntfs_attr *ia_na, *bmp_na = NULL; 667 ntfs_attr_search_ctx *ctx = NULL; 668 u8 *index_end, *bmp = NULL; 669 INDEX_ROOT *ir; 670 INDEX_ENTRY *ie; 671 INDEX_ALLOCATION *ia = NULL; 672 int rc, ir_pos, bmp_buf_size, bmp_buf_pos, eo; 673 u32 index_block_size, index_vcn_size; 674 u8 index_block_size_bits, index_vcn_size_bits; 675 676 ntfs_log_trace("Entering.\n"); 677 678 if (!dir_ni || !pos || !filldir) { 679 errno = EINVAL; 680 return -1; 681 } 682 683 if (!(dir_ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) { 684 errno = ENOTDIR; 685 return -1; 686 } 687 688 vol = dir_ni->vol; 689 690 ntfs_log_trace("Entering for inode 0x%llx, *pos 0x%llx.\n", 691 (unsigned long long)dir_ni->mft_no, (long long)*pos); 692 693 /* Open the index allocation attribute. */ 694 ia_na = ntfs_attr_open(dir_ni, AT_INDEX_ALLOCATION, NTFS_INDEX_I30, 4); 695 if (!ia_na) { 696 if (errno != ENOENT) { 697 ntfs_log_perror("Failed to open index allocation attribute. " 698 "Directory inode 0x%llx is corrupt or bug", 699 (unsigned long long)dir_ni->mft_no); 700 return -1; 701 } 702 i_size = 0; 703 } else 704 i_size = ia_na->data_size; 705 706 rc = 0; 707 708 /* Are we at end of dir yet? */ 709 if (*pos >= i_size + vol->mft_record_size) 710 goto done; 711 712 /* Emulate . and .. for all directories. */ 713 if (!*pos) { 714 rc = filldir(dirent, dotdot, 1, FILE_NAME_POSIX, *pos, 715 MK_MREF(dir_ni->mft_no, 716 le16_to_cpu(dir_ni->mrec->sequence_number)), 717 NTFS_DT_DIR); 718 if (rc) 719 goto done; 720 ++*pos; 721 } 722 if (*pos == 1) { 723 MFT_REF parent_mref; 724 725 parent_mref = ntfs_mft_get_parent_ref(dir_ni); 726 if (parent_mref == ERR_MREF(-1)) { 727 ntfs_log_perror("Parent directory not found"); 728 goto dir_err_out; 729 } 730 731 rc = filldir(dirent, dotdot, 2, FILE_NAME_POSIX, *pos, 732 parent_mref, NTFS_DT_DIR); 733 if (rc) 734 goto done; 735 ++*pos; 736 } 737 738 ctx = ntfs_attr_get_search_ctx(dir_ni, NULL); 739 if (!ctx) 740 goto err_out; 741 742 /* Get the offset into the index root attribute. */ 743 ir_pos = (int)*pos; 744 /* Find the index root attribute in the mft record. */ 745 if (ntfs_attr_lookup(AT_INDEX_ROOT, NTFS_INDEX_I30, 4, CASE_SENSITIVE, 0, NULL, 746 0, ctx)) { 747 ntfs_log_debug("Index root attribute missing in directory inode " 748 "0x%llx.\n", (unsigned long long)dir_ni->mft_no); 749 goto dir_err_out; 750 } 751 /* Get to the index root value. */ 752 ir = (INDEX_ROOT*)((u8*)ctx->attr + 753 le16_to_cpu(ctx->attr->value_offset)); 754 755 /* Determine the size of a vcn in the directory index. */ 756 index_block_size = le32_to_cpu(ir->index_block_size); 757 if (index_block_size < NTFS_BLOCK_SIZE || 758 index_block_size & (index_block_size - 1)) { 759 ntfs_log_debug("Index block size %u is invalid.\n", 760 (unsigned)index_block_size); 761 goto dir_err_out; 762 } 763 index_block_size_bits = ffs(index_block_size) - 1; 764 if (vol->cluster_size <= index_block_size) { 765 index_vcn_size = vol->cluster_size; 766 index_vcn_size_bits = vol->cluster_size_bits; 767 } else { 768 index_vcn_size = vol->sector_size; 769 index_vcn_size_bits = vol->sector_size_bits; 770 } 771 772 /* Are we jumping straight into the index allocation attribute? */ 773 if (*pos >= vol->mft_record_size) { 774 ntfs_attr_put_search_ctx(ctx); 775 ctx = NULL; 776 goto skip_index_root; 777 } 778 779 index_end = (u8*)&ir->index + le32_to_cpu(ir->index.index_length); 780 /* The first index entry. */ 781 ie = (INDEX_ENTRY*)((u8*)&ir->index + 782 le32_to_cpu(ir->index.entries_offset)); 783 /* 784 * Loop until we exceed valid memory (corruption case) or until we 785 * reach the last entry or until filldir tells us it has had enough 786 * or signals an error (both covered by the rc test). 787 */ 788 for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) { 789 ntfs_log_debug("In index root, offset 0x%x.\n", (u8*)ie - (u8*)ir); 790 /* Bounds checks. */ 791 if ((u8*)ie < (u8*)ctx->mrec || (u8*)ie + 792 sizeof(INDEX_ENTRY_HEADER) > index_end || 793 (u8*)ie + le16_to_cpu(ie->key_length) > 794 index_end) 795 goto dir_err_out; 796 /* The last entry cannot contain a name. */ 797 if (ie->ie_flags & INDEX_ENTRY_END) 798 break; 799 /* Skip index root entry if continuing previous readdir. */ 800 if (ir_pos > (u8*)ie - (u8*)ir) 801 continue; 802 /* 803 * Submit the directory entry to ntfs_filldir(), which will 804 * invoke the filldir() callback as appropriate. 805 */ 806 rc = ntfs_filldir(dir_ni, pos, index_vcn_size_bits, 807 INDEX_TYPE_ROOT, ir, ie, dirent, filldir); 808 if (rc) { 809 ntfs_attr_put_search_ctx(ctx); 810 ctx = NULL; 811 goto done; 812 } 813 } 814 ntfs_attr_put_search_ctx(ctx); 815 ctx = NULL; 816 817 /* If there is no index allocation attribute we are finished. */ 818 if (!ia_na) 819 goto EOD; 820 821 /* Advance *pos to the beginning of the index allocation. */ 822 *pos = vol->mft_record_size; 823 824 skip_index_root: 825 826 if (!ia_na) 827 goto done; 828 829 /* Allocate a buffer for the current index block. */ 830 ia = ntfs_malloc(index_block_size); 831 if (!ia) 832 goto err_out; 833 834 bmp_na = ntfs_attr_open(dir_ni, AT_BITMAP, NTFS_INDEX_I30, 4); 835 if (!bmp_na) { 836 ntfs_log_perror("Failed to open index bitmap attribute"); 837 goto dir_err_out; 838 } 839 840 /* Get the offset into the index allocation attribute. */ 841 ia_pos = *pos - vol->mft_record_size; 842 843 bmp_pos = ia_pos >> index_block_size_bits; 844 if (bmp_pos >> 3 >= bmp_na->data_size) { 845 ntfs_log_debug("Current index position exceeds index bitmap " 846 "size.\n"); 847 goto dir_err_out; 848 } 849 850 bmp_buf_size = min(bmp_na->data_size - (bmp_pos >> 3), 4096); 851 bmp = ntfs_malloc(bmp_buf_size); 852 if (!bmp) 853 goto err_out; 854 855 br = ntfs_attr_pread(bmp_na, bmp_pos >> 3, bmp_buf_size, bmp); 856 if (br != bmp_buf_size) { 857 if (br != -1) 858 errno = EIO; 859 ntfs_log_perror("Failed to read from index bitmap attribute"); 860 goto err_out; 861 } 862 863 bmp_buf_pos = 0; 864 /* If the index block is not in use find the next one that is. */ 865 while (!(bmp[bmp_buf_pos >> 3] & (1 << (bmp_buf_pos & 7)))) { 866 find_next_index_buffer: 867 bmp_pos++; 868 bmp_buf_pos++; 869 /* If we have reached the end of the bitmap, we are done. */ 870 if (bmp_pos >> 3 >= bmp_na->data_size) 871 goto EOD; 872 ia_pos = bmp_pos << index_block_size_bits; 873 if (bmp_buf_pos >> 3 < bmp_buf_size) 874 continue; 875 /* Read next chunk from the index bitmap. */ 876 if ((bmp_pos >> 3) + bmp_buf_size > bmp_na->data_size) 877 bmp_buf_size = bmp_na->data_size - (bmp_pos >> 3); 878 br = ntfs_attr_pread(bmp_na, bmp_pos >> 3, bmp_buf_size, bmp); 879 if (br != bmp_buf_size) { 880 if (br != -1) 881 errno = EIO; 882 ntfs_log_perror("Failed to read from index bitmap attribute"); 883 goto err_out; 884 } 885 } 886 887 ntfs_log_debug("Handling index block 0x%llx.\n", (long long)bmp_pos); 888 889 /* Read the index block starting at bmp_pos. */ 890 br = ntfs_attr_mst_pread(ia_na, bmp_pos << index_block_size_bits, 1, 891 index_block_size, ia); 892 if (br != 1) { 893 if (br != -1) 894 errno = EIO; 895 ntfs_log_perror("Failed to read index block"); 896 goto err_out; 897 } 898 899 ia_start = ia_pos & ~(s64)(index_block_size - 1); 900 if (sle64_to_cpu(ia->index_block_vcn) != ia_start >> 901 index_vcn_size_bits) { 902 ntfs_log_debug("Actual VCN (0x%llx) of index buffer is different " 903 "from expected VCN (0x%llx) in inode 0x%llx.\n", 904 (long long)sle64_to_cpu(ia->index_block_vcn), 905 (long long)ia_start >> index_vcn_size_bits, 906 (unsigned long long)dir_ni->mft_no); 907 goto dir_err_out; 908 } 909 if (le32_to_cpu(ia->index.allocated_size) + 0x18 != index_block_size) { 910 ntfs_log_debug("Index buffer (VCN 0x%llx) of directory inode 0x%llx " 911 "has a size (%u) differing from the directory " 912 "specified size (%u).\n", (long long)ia_start >> 913 index_vcn_size_bits, 914 (unsigned long long)dir_ni->mft_no, 915 (unsigned) le32_to_cpu(ia->index.allocated_size) 916 + 0x18, (unsigned)index_block_size); 917 goto dir_err_out; 918 } 919 index_end = (u8*)&ia->index + le32_to_cpu(ia->index.index_length); 920 if (index_end > (u8*)ia + index_block_size) { 921 ntfs_log_debug("Size of index buffer (VCN 0x%llx) of directory inode " 922 "0x%llx exceeds maximum size.\n", 923 (long long)ia_start >> index_vcn_size_bits, 924 (unsigned long long)dir_ni->mft_no); 925 goto dir_err_out; 926 } 927 /* The first index entry. */ 928 ie = (INDEX_ENTRY*)((u8*)&ia->index + 929 le32_to_cpu(ia->index.entries_offset)); 930 /* 931 * Loop until we exceed valid memory (corruption case) or until we 932 * reach the last entry or until ntfs_filldir tells us it has had 933 * enough or signals an error (both covered by the rc test). 934 */ 935 for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) { 936 ntfs_log_debug("In index allocation, offset 0x%llx.\n", 937 (long long)ia_start + ((u8*)ie - (u8*)ia)); 938 /* Bounds checks. */ 939 if ((u8*)ie < (u8*)ia || (u8*)ie + 940 sizeof(INDEX_ENTRY_HEADER) > index_end || 941 (u8*)ie + le16_to_cpu(ie->key_length) > 942 index_end) { 943 ntfs_log_debug("Index entry out of bounds in directory inode " 944 "0x%llx.\n", (unsigned long long)dir_ni->mft_no); 945 goto dir_err_out; 946 } 947 /* The last entry cannot contain a name. */ 948 if (ie->ie_flags & INDEX_ENTRY_END) 949 break; 950 /* Skip index entry if continuing previous readdir. */ 951 if (ia_pos - ia_start > (u8*)ie - (u8*)ia) 952 continue; 953 /* 954 * Submit the directory entry to ntfs_filldir(), which will 955 * invoke the filldir() callback as appropriate. 956 */ 957 rc = ntfs_filldir(dir_ni, pos, index_vcn_size_bits, 958 INDEX_TYPE_ALLOCATION, ia, ie, dirent, filldir); 959 if (rc) 960 goto done; 961 } 962 goto find_next_index_buffer; 963 EOD: 964 /* We are finished, set *pos to EOD. */ 965 *pos = i_size + vol->mft_record_size; 966 done: 967 free(ia); 968 free(bmp); 969 if (bmp_na) 970 ntfs_attr_close(bmp_na); 971 if (ia_na) 972 ntfs_attr_close(ia_na); 973 #ifdef DEBUG 974 if (!rc) 975 ntfs_log_debug("EOD, *pos 0x%llx, returning 0.\n", (long long)*pos); 976 else 977 ntfs_log_debug("filldir returned %i, *pos 0x%llx, returning 0.\n", 978 rc, (long long)*pos); 979 #endif 980 return 0; 981 dir_err_out: 982 errno = EIO; 983 err_out: 984 eo = errno; 985 ntfs_log_trace("failed.\n"); 986 if (ctx) 987 ntfs_attr_put_search_ctx(ctx); 988 free(ia); 989 free(bmp); 990 if (bmp_na) 991 ntfs_attr_close(bmp_na); 992 if (ia_na) 993 ntfs_attr_close(ia_na); 994 errno = eo; 995 return -1; 996 } 997 998 999 /** 1000 * __ntfs_create - create object on ntfs volume 1001 * @dir_ni: ntfs inode for directory in which create new object 1002 * @name: unicode name of new object 1003 * @name_len: length of the name in unicode characters 1004 * @type: type of the object to create 1005 * @dev: major and minor device numbers (obtained from makedev()) 1006 * @target: target in unicode (only for symlinks) 1007 * @target_len: length of target in unicode characters 1008 * 1009 * Internal, use ntfs_create{,_device,_symlink} wrappers instead. 1010 * 1011 * @type can be: 1012 * S_IFREG to create regular file 1013 * S_IFDIR to create directory 1014 * S_IFBLK to create block device 1015 * S_IFCHR to create character device 1016 * S_IFLNK to create symbolic link 1017 * S_IFIFO to create FIFO 1018 * S_IFSOCK to create socket 1019 * other values are invalid. 1020 * 1021 * @dev is used only if @type is S_IFBLK or S_IFCHR, in other cases its value 1022 * ignored. 1023 * 1024 * @target and @target_len are used only if @type is S_IFLNK, in other cases 1025 * their value ignored. 1026 * 1027 * Return opened ntfs inode that describes created object on success or NULL 1028 * on error with errno set to the error code. 1029 */ 1030 static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, 1031 ntfschar *name, u8 name_len, dev_t type, dev_t dev, 1032 ntfschar *target, u8 target_len) 1033 { 1034 ntfs_inode *ni; 1035 int rollback_data = 0, rollback_sd = 0; 1036 FILE_NAME_ATTR *fn = NULL; 1037 STANDARD_INFORMATION *si = NULL; 1038 int err, fn_len, si_len; 1039 1040 ntfs_log_trace("Entering.\n"); 1041 1042 /* Sanity checks. */ 1043 if (!dir_ni || !name || !name_len) { 1044 ntfs_log_error("Invalid arguments.\n"); 1045 errno = EINVAL; 1046 return NULL; 1047 } 1048 /* Allocate MFT record for new file. */ 1049 ni = ntfs_mft_record_alloc(dir_ni->vol, NULL); 1050 if (!ni) { 1051 ntfs_log_perror("Could not allocate new MFT record"); 1052 return NULL; 1053 } 1054 /* 1055 * Create STANDARD_INFORMATION attribute. Write STANDARD_INFORMATION 1056 * version 1.2, windows will upgrade it to version 3 if needed. 1057 */ 1058 si_len = offsetof(STANDARD_INFORMATION, v1_end); 1059 si = ntfs_calloc(si_len); 1060 if (!si) { 1061 err = errno; 1062 goto err_out; 1063 } 1064 si->creation_time = utc2ntfs(ni->creation_time); 1065 si->last_data_change_time = utc2ntfs(ni->last_data_change_time); 1066 si->last_mft_change_time = utc2ntfs(ni->last_mft_change_time); 1067 si->last_access_time = utc2ntfs(ni->last_access_time); 1068 if (!S_ISREG(type) && !S_ISDIR(type)) { 1069 si->file_attributes = FILE_ATTR_SYSTEM; 1070 ni->flags = FILE_ATTR_SYSTEM; 1071 } 1072 /* Add STANDARD_INFORMATION to inode. */ 1073 if (ntfs_attr_add(ni, AT_STANDARD_INFORMATION, AT_UNNAMED, 0, 1074 (u8*)si, si_len)) { 1075 err = errno; 1076 ntfs_log_error("Failed to add STANDARD_INFORMATION " 1077 "attribute.\n"); 1078 goto err_out; 1079 } 1080 1081 if (ntfs_sd_add_everyone(ni)) { 1082 err = errno; 1083 goto err_out; 1084 } 1085 rollback_sd = 1; 1086 1087 if (S_ISDIR(type)) { 1088 INDEX_ROOT *ir = NULL; 1089 INDEX_ENTRY *ie; 1090 int ir_len, index_len; 1091 1092 /* Create INDEX_ROOT attribute. */ 1093 index_len = sizeof(INDEX_HEADER) + sizeof(INDEX_ENTRY_HEADER); 1094 ir_len = offsetof(INDEX_ROOT, index) + index_len; 1095 ir = ntfs_calloc(ir_len); 1096 if (!ir) { 1097 err = errno; 1098 goto err_out; 1099 } 1100 ir->type = AT_FILE_NAME; 1101 ir->collation_rule = COLLATION_FILE_NAME; 1102 ir->index_block_size = cpu_to_le32(ni->vol->indx_record_size); 1103 if (ni->vol->cluster_size <= ni->vol->indx_record_size) 1104 ir->clusters_per_index_block = 1105 ni->vol->indx_record_size >> 1106 ni->vol->cluster_size_bits; 1107 else 1108 ir->clusters_per_index_block = 1109 ni->vol->indx_record_size >> 1110 ni->vol->sector_size_bits; 1111 ir->index.entries_offset = cpu_to_le32(sizeof(INDEX_HEADER)); 1112 ir->index.index_length = cpu_to_le32(index_len); 1113 ir->index.allocated_size = cpu_to_le32(index_len); 1114 ie = (INDEX_ENTRY*)((u8*)ir + sizeof(INDEX_ROOT)); 1115 ie->length = cpu_to_le16(sizeof(INDEX_ENTRY_HEADER)); 1116 ie->key_length = 0; 1117 ie->ie_flags = INDEX_ENTRY_END; 1118 /* Add INDEX_ROOT attribute to inode. */ 1119 if (ntfs_attr_add(ni, AT_INDEX_ROOT, NTFS_INDEX_I30, 4, 1120 (u8*)ir, ir_len)) { 1121 err = errno; 1122 free(ir); 1123 ntfs_log_error("Failed to add INDEX_ROOT attribute.\n"); 1124 goto err_out; 1125 } 1126 free(ir); 1127 } else { 1128 INTX_FILE *data; 1129 int data_len; 1130 1131 switch (type) { 1132 case S_IFBLK: 1133 case S_IFCHR: 1134 data_len = offsetof(INTX_FILE, device_end); 1135 data = ntfs_malloc(data_len); 1136 if (!data) { 1137 err = errno; 1138 goto err_out; 1139 } 1140 data->major = cpu_to_le64(major(dev)); 1141 data->minor = cpu_to_le64(minor(dev)); 1142 if (type == S_IFBLK) 1143 data->magic = INTX_BLOCK_DEVICE; 1144 if (type == S_IFCHR) 1145 data->magic = INTX_CHARACTER_DEVICE; 1146 break; 1147 case S_IFLNK: 1148 data_len = sizeof(INTX_FILE_TYPES) + 1149 target_len * sizeof(ntfschar); 1150 data = ntfs_malloc(data_len); 1151 if (!data) { 1152 err = errno; 1153 goto err_out; 1154 } 1155 data->magic = INTX_SYMBOLIC_LINK; 1156 memcpy(data->target, target, 1157 target_len * sizeof(ntfschar)); 1158 break; 1159 case S_IFSOCK: 1160 data = NULL; 1161 data_len = 1; 1162 break; 1163 default: /* FIFO or regular file. */ 1164 data = NULL; 1165 data_len = 0; 1166 break; 1167 } 1168 /* Add DATA attribute to inode. */ 1169 if (ntfs_attr_add(ni, AT_DATA, AT_UNNAMED, 0, (u8*)data, 1170 data_len)) { 1171 err = errno; 1172 ntfs_log_error("Failed to add DATA attribute.\n"); 1173 free(data); 1174 goto err_out; 1175 } 1176 rollback_data = 1; 1177 free(data); 1178 } 1179 /* Create FILE_NAME attribute. */ 1180 fn_len = sizeof(FILE_NAME_ATTR) + name_len * sizeof(ntfschar); 1181 fn = ntfs_calloc(fn_len); 1182 if (!fn) { 1183 err = errno; 1184 goto err_out; 1185 } 1186 fn->parent_directory = MK_LE_MREF(dir_ni->mft_no, 1187 le16_to_cpu(dir_ni->mrec->sequence_number)); 1188 fn->file_name_length = name_len; 1189 fn->file_name_type = FILE_NAME_POSIX; 1190 if (S_ISDIR(type)) 1191 fn->file_attributes = FILE_ATTR_I30_INDEX_PRESENT; 1192 if (!S_ISREG(type) && !S_ISDIR(type)) 1193 fn->file_attributes = FILE_ATTR_SYSTEM; 1194 fn->creation_time = utc2ntfs(ni->creation_time); 1195 fn->last_data_change_time = utc2ntfs(ni->last_data_change_time); 1196 fn->last_mft_change_time = utc2ntfs(ni->last_mft_change_time); 1197 fn->last_access_time = utc2ntfs(ni->last_access_time); 1198 memcpy(fn->file_name, name, name_len * sizeof(ntfschar)); 1199 /* Add FILE_NAME attribute to inode. */ 1200 if (ntfs_attr_add(ni, AT_FILE_NAME, AT_UNNAMED, 0, (u8*)fn, fn_len)) { 1201 err = errno; 1202 ntfs_log_error("Failed to add FILE_NAME attribute.\n"); 1203 goto err_out; 1204 } 1205 /* Add FILE_NAME attribute to index. */ 1206 if (ntfs_index_add_filename(dir_ni, fn, MK_MREF(ni->mft_no, 1207 le16_to_cpu(ni->mrec->sequence_number)))) { 1208 err = errno; 1209 ntfs_log_perror("Failed to add entry to the index"); 1210 goto err_out; 1211 } 1212 /* Set hard links count and directory flag. */ 1213 ni->mrec->link_count = cpu_to_le16(1); 1214 if (S_ISDIR(type)) 1215 ni->mrec->flags |= MFT_RECORD_IS_DIRECTORY; 1216 ntfs_inode_mark_dirty(ni); 1217 /* Done! */ 1218 free(fn); 1219 free(si); 1220 ntfs_log_trace("Done.\n"); 1221 return ni; 1222 err_out: 1223 ntfs_log_trace("Failed.\n"); 1224 1225 if (rollback_sd) 1226 ntfs_attr_remove(ni, AT_SECURITY_DESCRIPTOR, AT_UNNAMED, 0); 1227 1228 if (rollback_data) 1229 ntfs_attr_remove(ni, AT_DATA, AT_UNNAMED, 0); 1230 /* 1231 * Free extent MFT records (should not exist any with current 1232 * ntfs_create implementation, but for any case if something will be 1233 * changed in the future). 1234 */ 1235 while (ni->nr_extents) 1236 if (ntfs_mft_record_free(ni->vol, *(ni->extent_nis))) { 1237 err = errno; 1238 ntfs_log_error("Failed to free extent MFT record. " 1239 "Leaving inconsistent metadata.\n"); 1240 } 1241 if (ntfs_mft_record_free(ni->vol, ni)) 1242 ntfs_log_error("Failed to free MFT record. " 1243 "Leaving inconsistent metadata. Run chkdsk.\n"); 1244 free(fn); 1245 free(si); 1246 errno = err; 1247 return NULL; 1248 } 1249 1250 /** 1251 * Some wrappers around __ntfs_create() ... 1252 */ 1253 1254 ntfs_inode *ntfs_create(ntfs_inode *dir_ni, ntfschar *name, u8 name_len, 1255 dev_t type) 1256 { 1257 if (type != S_IFREG && type != S_IFDIR && type != S_IFIFO && 1258 type != S_IFSOCK) { 1259 ntfs_log_error("Invalid arguments.\n"); 1260 return NULL; 1261 } 1262 return __ntfs_create(dir_ni, name, name_len, type, 0, NULL, 0); 1263 } 1264 1265 ntfs_inode *ntfs_create_device(ntfs_inode *dir_ni, ntfschar *name, u8 name_len, 1266 dev_t type, dev_t dev) 1267 { 1268 if (type != S_IFCHR && type != S_IFBLK) { 1269 ntfs_log_error("Invalid arguments.\n"); 1270 return NULL; 1271 } 1272 return __ntfs_create(dir_ni, name, name_len, type, dev, NULL, 0); 1273 } 1274 1275 ntfs_inode *ntfs_create_symlink(ntfs_inode *dir_ni, ntfschar *name, u8 name_len, 1276 ntfschar *target, u8 target_len) 1277 { 1278 if (!target || !target_len) { 1279 ntfs_log_error("Invalid arguments.\n"); 1280 return NULL; 1281 } 1282 return __ntfs_create(dir_ni, name, name_len, S_IFLNK, 0, 1283 target, target_len); 1284 } 1285 1286 int ntfs_check_empty_dir(ntfs_inode *ni) 1287 { 1288 ntfs_attr *na; 1289 int ret = 0; 1290 1291 if (!(ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) 1292 return 0; 1293 1294 na = ntfs_attr_open(ni, AT_INDEX_ROOT, NTFS_INDEX_I30, 4); 1295 if (!na) { 1296 errno = EIO; 1297 ntfs_log_perror("Failed to open directory"); 1298 return -1; 1299 } 1300 1301 /* Non-empty directory? */ 1302 if ((na->data_size != sizeof(INDEX_ROOT) + sizeof(INDEX_ENTRY_HEADER))) { 1303 /* Both ENOTEMPTY and EEXIST are ok. We use the more common. */ 1304 errno = EEXIST; 1305 ntfs_log_debug("Directory is not empty\n"); 1306 ret = -1; 1307 } 1308 1309 ntfs_attr_close(na); 1310 return ret; 1311 } 1312 1313 static int ntfs_check_unlinkable_dir(ntfs_inode *ni, FILE_NAME_ATTR *fn) 1314 { 1315 int link_count = le16_to_cpu(ni->mrec->link_count); 1316 int ret; 1317 1318 ret = ntfs_check_empty_dir(ni); 1319 if (!ret || errno != EEXIST) 1320 return ret; 1321 /* 1322 * Directory is non-empty, so we can unlink only if there is more than 1323 * one "real" hard link, i.e. links aren't different DOS and WIN32 names 1324 */ 1325 if ((link_count == 1) || 1326 (link_count == 2 && fn->file_name_type == FILE_NAME_DOS)) { 1327 errno = EEXIST; 1328 ntfs_log_debug("Non-empty directory without hard links\n"); 1329 goto no_hardlink; 1330 } 1331 1332 ret = 0; 1333 no_hardlink: 1334 return ret; 1335 } 1336 1337 /** 1338 * ntfs_delete - delete file or directory from ntfs volume 1339 * @ni: ntfs inode for object to delte 1340 * @dir_ni: ntfs inode for directory in which delete object 1341 * @name: unicode name of the object to delete 1342 * @name_len: length of the name in unicode characters 1343 * 1344 * @ni is always closed after the call to this function (even if it failed), 1345 * user does not need to call ntfs_inode_close himself. 1346 * 1347 * Return 0 on success or -1 on error with errno set to the error code. 1348 */ 1349 int ntfs_delete(ntfs_inode *ni, ntfs_inode *dir_ni, ntfschar *name, u8 name_len) 1350 { 1351 ntfs_attr_search_ctx *actx = NULL; 1352 ntfs_index_context *ictx = NULL; 1353 FILE_NAME_ATTR *fn = NULL; 1354 BOOL looking_for_dos_name = FALSE, looking_for_win32_name = FALSE; 1355 BOOL case_sensitive_match = TRUE; 1356 int err = 0; 1357 1358 ntfs_log_trace("Entering.\n"); 1359 1360 if (!ni || !dir_ni || !name || !name_len) { 1361 ntfs_log_error("Invalid arguments.\n"); 1362 errno = EINVAL; 1363 goto err_out; 1364 } 1365 if (ni->nr_extents == -1) 1366 ni = ni->base_ni; 1367 if (dir_ni->nr_extents == -1) 1368 dir_ni = dir_ni->base_ni; 1369 /* 1370 * Search for FILE_NAME attribute with such name. If it's in POSIX or 1371 * WIN32_AND_DOS namespace, then simply remove it from index and inode. 1372 * If filename in DOS or in WIN32 namespace, then remove DOS name first, 1373 * only then remove WIN32 name. 1374 */ 1375 actx = ntfs_attr_get_search_ctx(ni, NULL); 1376 if (!actx) 1377 goto err_out; 1378 search: 1379 while (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, CASE_SENSITIVE, 1380 0, NULL, 0, actx)) { 1381 char *s; 1382 BOOL case_sensitive = IGNORE_CASE; 1383 1384 errno = 0; 1385 fn = (FILE_NAME_ATTR*)((u8*)actx->attr + 1386 le16_to_cpu(actx->attr->value_offset)); 1387 s = ntfs_attr_name_get(fn->file_name, fn->file_name_length); 1388 ntfs_log_trace("name: '%s' type: %d dos: %d win32: %d " 1389 "case: %d\n", s, fn->file_name_type, 1390 looking_for_dos_name, looking_for_win32_name, 1391 case_sensitive_match); 1392 ntfs_attr_name_free(&s); 1393 if (looking_for_dos_name) { 1394 if (fn->file_name_type == FILE_NAME_DOS) 1395 break; 1396 else 1397 continue; 1398 } 1399 if (looking_for_win32_name) { 1400 if (fn->file_name_type == FILE_NAME_WIN32) 1401 break; 1402 else 1403 continue; 1404 } 1405 1406 /* Ignore hard links from other directories */ 1407 if (dir_ni->mft_no != MREF_LE(fn->parent_directory)) { 1408 ntfs_log_debug("MFT record numbers don't match " 1409 "(%llu != %llu)\n", dir_ni->mft_no, 1410 MREF_LE(fn->parent_directory)); 1411 continue; 1412 } 1413 1414 if (fn->file_name_type == FILE_NAME_POSIX || case_sensitive_match) 1415 case_sensitive = CASE_SENSITIVE; 1416 1417 if (ntfs_names_are_equal(fn->file_name, fn->file_name_length, 1418 name, name_len, case_sensitive, 1419 ni->vol->upcase, ni->vol->upcase_len)) { 1420 1421 if (fn->file_name_type == FILE_NAME_WIN32) { 1422 looking_for_dos_name = TRUE; 1423 ntfs_attr_reinit_search_ctx(actx); 1424 continue; 1425 } 1426 if (fn->file_name_type == FILE_NAME_DOS) 1427 looking_for_dos_name = TRUE; 1428 break; 1429 } 1430 } 1431 if (errno) { 1432 /* 1433 * If case sensitive search failed, then try once again 1434 * ignoring case. 1435 */ 1436 if (errno == ENOENT && case_sensitive_match) { 1437 case_sensitive_match = FALSE; 1438 ntfs_attr_reinit_search_ctx(actx); 1439 goto search; 1440 } 1441 goto err_out; 1442 } 1443 1444 if (ntfs_check_unlinkable_dir(ni, fn) < 0) 1445 goto err_out; 1446 1447 ictx = ntfs_index_ctx_get(dir_ni, NTFS_INDEX_I30, 4); 1448 if (!ictx) 1449 goto err_out; 1450 if (ntfs_index_lookup(fn, le32_to_cpu(actx->attr->value_length), ictx)) 1451 goto err_out; 1452 1453 if (((FILE_NAME_ATTR*)ictx->data)->file_attributes & 1454 FILE_ATTR_REPARSE_POINT) { 1455 errno = EOPNOTSUPP; 1456 goto err_out; 1457 } 1458 1459 if (ntfs_index_rm(ictx)) 1460 goto err_out; 1461 1462 if (ntfs_attr_record_rm(actx)) 1463 goto err_out; 1464 1465 ni->mrec->link_count = cpu_to_le16(le16_to_cpu( 1466 ni->mrec->link_count) - 1); 1467 1468 ntfs_inode_mark_dirty(ni); 1469 if (looking_for_dos_name) { 1470 looking_for_dos_name = FALSE; 1471 looking_for_win32_name = TRUE; 1472 ntfs_attr_reinit_search_ctx(actx); 1473 goto search; 1474 } 1475 /* TODO: Update object id, quota and securiry indexes if required. */ 1476 /* 1477 * If hard link count is not equal to zero then we are done. In other 1478 * case there are no reference to this inode left, so we should free all 1479 * non-resident attributes and mark all MFT record as not in use. 1480 */ 1481 if (ni->mrec->link_count) 1482 goto out; 1483 ntfs_attr_reinit_search_ctx(actx); 1484 while (!ntfs_attrs_walk(actx)) { 1485 if (actx->attr->non_resident) { 1486 runlist *rl; 1487 1488 rl = ntfs_mapping_pairs_decompress(ni->vol, actx->attr, 1489 NULL); 1490 if (!rl) { 1491 err = errno; 1492 ntfs_log_error("Failed to decompress runlist. " 1493 "Leaving inconsistent metadata.\n"); 1494 continue; 1495 } 1496 if (ntfs_cluster_free_from_rl(ni->vol, rl)) { 1497 err = errno; 1498 ntfs_log_error("Failed to free clusters. " 1499 "Leaving inconsistent metadata.\n"); 1500 continue; 1501 } 1502 free(rl); 1503 } 1504 } 1505 if (errno != ENOENT) { 1506 err = errno; 1507 ntfs_log_error("Attribute enumeration failed. " 1508 "Probably leaving inconsistent metadata.\n"); 1509 } 1510 /* All extents should be attached after attribute walk. */ 1511 while (ni->nr_extents) 1512 if (ntfs_mft_record_free(ni->vol, *(ni->extent_nis))) { 1513 err = errno; 1514 ntfs_log_error("Failed to free extent MFT record. " 1515 "Leaving inconsistent metadata.\n"); 1516 } 1517 if (ntfs_mft_record_free(ni->vol, ni)) { 1518 err = errno; 1519 ntfs_log_error("Failed to free base MFT record. " 1520 "Leaving inconsistent metadata.\n"); 1521 } 1522 ni = NULL; 1523 out: 1524 if (actx) 1525 ntfs_attr_put_search_ctx(actx); 1526 if (ictx) 1527 ntfs_index_ctx_put(ictx); 1528 if (ni) 1529 ntfs_inode_close(ni); 1530 if (err) { 1531 errno = err; 1532 ntfs_log_debug("Could not delete file: %s\n", strerror(errno)); 1533 return -1; 1534 } 1535 ntfs_log_trace("Done.\n"); 1536 return 0; 1537 err_out: 1538 err = errno; 1539 goto out; 1540 } 1541 1542 /** 1543 * ntfs_link - create hard link for file or directory 1544 * @ni: ntfs inode for object to create hard link 1545 * @dir_ni: ntfs inode for directory in which new link should be placed 1546 * @name: unicode name of the new link 1547 * @name_len: length of the name in unicode characters 1548 * 1549 * NOTE: At present we allow creating hardlinks to directories, we use them 1550 * in a temporary state during rename. But it's defenitely bad idea to have 1551 * hard links to directories as a result of operation. 1552 * FIXME: Create internal __ntfs_link that allows hard links to a directories 1553 * and external ntfs_link that do not. Write ntfs_rename that uses __ntfs_link. 1554 * 1555 * Return 0 on success or -1 on error with errno set to the error code. 1556 */ 1557 int ntfs_link(ntfs_inode *ni, ntfs_inode *dir_ni, ntfschar *name, u8 name_len) 1558 { 1559 FILE_NAME_ATTR *fn = NULL; 1560 int fn_len, err; 1561 1562 ntfs_log_trace("Entering.\n"); 1563 1564 if (!ni || !dir_ni || !name || !name_len || 1565 ni->mft_no == dir_ni->mft_no) { 1566 err = EINVAL; 1567 ntfs_log_perror("ntfs_link wrong arguments"); 1568 goto err_out; 1569 } 1570 /* Create FILE_NAME attribute. */ 1571 fn_len = sizeof(FILE_NAME_ATTR) + name_len * sizeof(ntfschar); 1572 fn = ntfs_calloc(fn_len); 1573 if (!fn) { 1574 err = errno; 1575 goto err_out; 1576 } 1577 fn->parent_directory = MK_LE_MREF(dir_ni->mft_no, 1578 le16_to_cpu(dir_ni->mrec->sequence_number)); 1579 fn->file_name_length = name_len; 1580 fn->file_name_type = FILE_NAME_POSIX; 1581 fn->file_attributes = ni->flags; 1582 if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) 1583 fn->file_attributes |= FILE_ATTR_I30_INDEX_PRESENT; 1584 fn->allocated_size = cpu_to_sle64(ni->allocated_size); 1585 fn->data_size = cpu_to_sle64(ni->data_size); 1586 fn->creation_time = utc2ntfs(ni->creation_time); 1587 fn->last_data_change_time = utc2ntfs(ni->last_data_change_time); 1588 fn->last_mft_change_time = utc2ntfs(ni->last_mft_change_time); 1589 fn->last_access_time = utc2ntfs(ni->last_access_time); 1590 memcpy(fn->file_name, name, name_len * sizeof(ntfschar)); 1591 /* Add FILE_NAME attribute to index. */ 1592 if (ntfs_index_add_filename(dir_ni, fn, MK_MREF(ni->mft_no, 1593 le16_to_cpu(ni->mrec->sequence_number)))) { 1594 err = errno; 1595 ntfs_log_perror("Failed to add filename to the index"); 1596 goto err_out; 1597 } 1598 /* Add FILE_NAME attribute to inode. */ 1599 if (ntfs_attr_add(ni, AT_FILE_NAME, AT_UNNAMED, 0, (u8*)fn, fn_len)) { 1600 ntfs_index_context *ictx; 1601 1602 err = errno; 1603 ntfs_log_error("Failed to add FILE_NAME attribute.\n"); 1604 /* Try to remove just added attribute from index. */ 1605 ictx = ntfs_index_ctx_get(dir_ni, NTFS_INDEX_I30, 4); 1606 if (!ictx) 1607 goto rollback_failed; 1608 if (ntfs_index_lookup(fn, fn_len, ictx)) { 1609 ntfs_index_ctx_put(ictx); 1610 goto rollback_failed; 1611 } 1612 if (ntfs_index_rm(ictx)) { 1613 ntfs_index_ctx_put(ictx); 1614 goto rollback_failed; 1615 } 1616 goto err_out; 1617 } 1618 /* Increment hard links count. */ 1619 ni->mrec->link_count = cpu_to_le16(le16_to_cpu( 1620 ni->mrec->link_count) + 1); 1621 /* Done! */ 1622 ntfs_inode_mark_dirty(ni); 1623 free(fn); 1624 ntfs_log_trace("Done.\n"); 1625 return 0; 1626 rollback_failed: 1627 ntfs_log_error("Rollback failed. Leaving inconsistent metadata.\n"); 1628 err_out: 1629 free(fn); 1630 errno = err; 1631 ntfs_log_perror("Hard link failed"); 1632 return -1; 1633 } 1634 1635