📄 index.c
字号:
} ictx = ntfs_index_ctx_get(ni, NTFS_INDEX_I30, 4); if (!ictx) return -1; fn_size = (fn->file_name_length * sizeof(ntfschar)) + sizeof(FILE_NAME_ATTR); ie_size = (sizeof(INDEX_ENTRY_HEADER) + fn_size + 7) & ~7;retry: /* Find place where insert new entry. */ if (!ntfs_index_lookup(fn, fn_size, ictx)) { err = EEXIST; ntfs_log_error("Index already have such entry.\n"); goto err_out; } if (errno != ENOENT) { err = errno; ntfs_log_error("Failed to find place where to insert new entry.\n"); goto err_out; } /* Some setup. */ if (ictx->is_in_root) ih = &ictx->ir->index; else ih = &ictx->ia->index; if (!allocated_size) allocated_size = le16_to_cpu(ih->allocated_size); /* Check whether we have enough space in the index. */ if (le16_to_cpu(ih->index_length) + ie_size > allocated_size) { /* If we in the index root try to resize it. */ if (ictx->is_in_root) { ntfs_attr *na; allocated_size = le16_to_cpu(ih->index_length) + ie_size; na = ntfs_attr_open(ictx->ni, AT_INDEX_ROOT, ictx->name, ictx->name_len); if (!na) { err = errno; ntfs_log_error("Failed to open INDEX_ROOT.\n"); goto err_out; } if (ntfs_attr_truncate(na, allocated_size + offsetof( INDEX_ROOT, index))) { err = EOPNOTSUPP; ntfs_attr_close(na); ntfs_log_debug("Failed to truncate " "INDEX_ROOT.\n"); goto err_out; } ntfs_attr_close(na); ntfs_index_ctx_reinit(ictx); goto retry; } ntfs_log_debug("Not implemented case.\n"); err = EOPNOTSUPP; goto err_out; } /* Update allocated size if we in INDEX_ROOT. */ if (ictx->is_in_root) ih->allocated_size = cpu_to_le16(allocated_size); /* Create entry. */ ie = calloc(1, ie_size); if (!ie) { err = errno; goto err_out; } ie->indexed_file = cpu_to_le64(mref); ie->length = cpu_to_le16(ie_size); ie->key_length = cpu_to_le16(fn_size); memcpy(&ie->key, fn, fn_size); /* Update index length, move following entries forard and copy entry. */ ih->index_length = cpu_to_le16(le16_to_cpu(ih->index_length) + ie_size); memmove((u8*)ictx->entry + ie_size, ictx->entry, le16_to_cpu(ih->index_length) - ((u8*)ictx->entry - (u8*)ih) - ie_size); memcpy(ictx->entry, ie, ie_size); /* Done! */ ntfs_index_entry_mark_dirty(ictx); ntfs_index_ctx_put(ictx); free(ie); ntfs_log_trace("Done.\n"); return 0;err_out: ntfs_log_trace("Failed.\n"); ntfs_index_ctx_put(ictx); errno = err; return -1;}/** * ntfs_index_rm - remove entry from the index * @ictx: index context describing entry to delete * * Delete entry described by @ictx from the index. NOTE: This function does not * support all cases, so it can fail with EOPNOTSUPP error code. In any case * index context is always reinitialized after use of this function, so it can * be used for index lookup once again. * * Return 0 on success or -1 on error with errno set to the error code. */int ntfs_index_rm(ntfs_index_context *ictx){ INDEX_HEADER *ih; u32 new_index_length; int err; ntfs_log_trace("Entering.\n"); if (!ictx || (!ictx->ia && !ictx->ir) || ictx->entry->flags & INDEX_ENTRY_END) { ntfs_log_error("Invalid arguments.\n"); err = EINVAL; goto err_out; } if (ictx->is_in_root) ih = &ictx->ir->index; else ih = &ictx->ia->index; /* Don't support deletion of entries with subnodes yet. */ if (ictx->entry->flags & INDEX_ENTRY_NODE) { err = EOPNOTSUPP; goto err_out; } /* Calculate new length of the index. */ new_index_length = le32_to_cpu(ih->index_length) - le16_to_cpu(ictx->entry->length); /* Don't support deletion of the last entry in the allocation block. */ if (!ictx->is_in_root && (new_index_length <= le32_to_cpu(ih->entries_offset) + sizeof(INDEX_ENTRY_HEADER) + sizeof(VCN))) { err = EOPNOTSUPP; goto err_out; } /* Update index length and remove index entry. */ ih->index_length = cpu_to_le32(new_index_length); if (ictx->is_in_root) ih->allocated_size = ih->index_length; memmove(ictx->entry, (u8*)ictx->entry + le16_to_cpu( ictx->entry->length), new_index_length - ((u8*)ictx->entry - (u8*)ih)); ntfs_index_entry_mark_dirty(ictx); /* Resize INDEX_ROOT attribute. */ if (ictx->is_in_root) { ntfs_attr *na; na = ntfs_attr_open(ictx->ni, AT_INDEX_ROOT, ictx->name, ictx->name_len); if (!na) { err = errno; ntfs_log_error("Failed to open INDEX_ROOT attribute. " "Leaving inconsistent metadata.\n"); goto err_out; } if (ntfs_attr_truncate(na, new_index_length + offsetof( INDEX_ROOT, index))) { err = errno; ntfs_log_error("Failed to truncate INDEX_ROOT " "attribute. Leaving inconsistent " "metadata.\n"); goto err_out; } ntfs_attr_close(na); } ntfs_index_ctx_reinit(ictx); ntfs_log_trace("Done.\n"); return 0;err_out: ntfs_index_ctx_reinit(ictx); ntfs_log_trace("Failed.\n"); errno = err; return -1;}#ifdef NTFS_RICH#ifdef HAVE_STRING_H#include <string.h>#endif#include "rich.h"/** * ntfs_ie_free - Destroy an index entry object * @ie: * * Description... * * Returns: */void ntfs_ie_free(INDEX_ENTRY *ie){ ntfs_log_trace ("ie %p, inode %lld\n", ie, MREF(ie->indexed_file)); free(ie);}/** * ntfs_ie_create - Create a representation of an directory index entry * * Description... * * Returns: */INDEX_ENTRY * ntfs_ie_create(void){ int length; INDEX_ENTRY *ie; ntfs_log_trace ("\n"); length = 16; ie = calloc(1, length); if (!ie) return NULL; ie->indexed_file = 0; ie->length = length; ie->key_length = 0; ie->flags = INDEX_ENTRY_END; ie->reserved = 0; return ie;}/** * ntfs_ie_get_vcn - Get the VCN associated with an index entry * @ie: * * Description... * * Returns: */VCN ntfs_ie_get_vcn(INDEX_ENTRY *ie){ if (!ie) return -1; if (!(ie->flags & INDEX_ENTRY_NODE)) return -1; ntfs_log_trace ("\n"); return *((VCN*) ((u8*) ie + ie->length - 8));}/** * ntfs_ie_copy - Create a copy of an index entry * @ie: * * Description... * * Returns: */INDEX_ENTRY * ntfs_ie_copy(INDEX_ENTRY *ie){ INDEX_ENTRY *copy = NULL; if (!ie) return NULL; ntfs_log_trace ("\n"); copy = malloc(ie->length); if (!copy) return NULL; memcpy(copy, ie, ie->length); return copy;}/** * ntfs_ie_set_vcn - Set VCN associated with an index entry * @ie: * @vcn: * * Description... * * Returns: */INDEX_ENTRY * ntfs_ie_set_vcn(INDEX_ENTRY *ie, VCN vcn){ if (!ie) return 0; ntfs_log_trace ("\n"); if (!(ie->flags & INDEX_ENTRY_NODE)) { ie->length += 8; ie = realloc(ie, ie->length); if (!ie) return NULL; ie->flags |= INDEX_ENTRY_NODE; } *((VCN*) ((u8*) ie + ie->length - 8)) = vcn; return ie;}/** * ntfs_ie_remove_vcn - Remove the VCN associated with an index entry * @ie: * * Description... * * Returns: */INDEX_ENTRY * ntfs_ie_remove_vcn(INDEX_ENTRY *ie){ if (!ie) return NULL; if (!(ie->flags & INDEX_ENTRY_NODE)) return ie; ntfs_log_trace ("\n"); ie->length -= 8; ie->flags &= ~INDEX_ENTRY_NODE; ie = realloc(ie, ie->length); return ie;}/** * ntfs_ie_set_name - Associate a name with an index entry * @ie: * @name: * @namelen: * @nametype: * * Description... * * Returns: */INDEX_ENTRY * ntfs_ie_set_name(INDEX_ENTRY *ie, ntfschar *name, int namelen, FILE_NAME_TYPE_FLAGS nametype){ FILE_NAME_ATTR *file; int need; BOOL wipe = FALSE; VCN vcn = 0; if (!ie || !name) return NULL; ntfs_log_trace ("\n"); /* * INDEX_ENTRY * MFT_REF indexed_file; * u16 length; * u16 key_length; * INDEX_ENTRY_FLAGS flags; * u16 reserved; * * FILENAME * MFT_REF parent_directory; * s64 creation_time; * s64 last_data_change_time; * s64 last_mft_change_time; * s64 last_access_time; * s64 allocated_size; * s64 data_size; * FILE_ATTR_FLAGS file_attributes; * u32 reserved; * u8 file_name_length; * FILE_NAME_TYPE_FLAGS file_name_type; * ntfschar file_name[l]; * u8 reserved[n] * * VCN vcn; */ //ntfs_log_debug("key length = 0x%02X\n", ie->key_length); //ntfs_log_debug("new name length = %d\n", namelen); if (ie->key_length > 0) { file = &ie->key.file_name; //ntfs_log_debug("filename, length %d\n", file->file_name_length); need = ATTR_SIZE(namelen * sizeof(ntfschar) + 2) - ATTR_SIZE(file->file_name_length * sizeof(ntfschar) + 2); } else { //ntfs_log_debug("no filename\n"); need = ATTR_SIZE(sizeof(FILE_NAME_ATTR) + (namelen * sizeof(ntfschar))); wipe = TRUE; } //ntfs_log_debug("need 0x%02X bytes\n", need); if (need != 0) { if (ie->flags & INDEX_ENTRY_NODE) vcn = ntfs_ie_get_vcn(ie); ie->length += need; ie->key_length += need; //ntfs_log_debug("realloc 0x%02X\n", ie->length); ie = realloc(ie, ie->length); if (!ie) return NULL; if (ie->flags & INDEX_ENTRY_NODE) ie = ntfs_ie_set_vcn(ie, vcn); if (wipe) memset(&ie->key.file_name, 0, sizeof(FILE_NAME_ATTR)); if (need > 0) memset((u8*)ie + ie->length - need, 0, need); } memcpy(ie->key.file_name.file_name, name, namelen * sizeof(ntfschar)); ie->key.file_name.file_name_length = namelen; ie->key.file_name.file_name_type = nametype; ie->flags &= ~INDEX_ENTRY_END; //ntfs_log_debug("ie->length = 0x%02X\n", ie->length); //ntfs_log_debug("ie->key_length = 0x%02X\n", ie->key_length); return ie;}/** * ntfs_ie_remove_name - Remove the name from an index-entry * @ie: * * Description... * * Returns: */INDEX_ENTRY * ntfs_ie_remove_name(INDEX_ENTRY *ie){ VCN vcn = 0; if (!ie) return NULL; if (ie->key_length == 0) return ie; ntfs_log_trace ("\n"); if (ie->flags & INDEX_ENTRY_NODE) vcn = ntfs_ie_get_vcn(ie); ie->length -= ATTR_SIZE(ie->key_length); ie->key_length = 0; ie->flags |= INDEX_ENTRY_END; ie = realloc(ie, ie->length); if (!ie) return NULL; if (ie->flags & INDEX_ENTRY_NODE) ie = ntfs_ie_set_vcn(ie, vcn); return ie;}#endif /* NTFS_RICH *//** * ntfs_index_root_get - read the index root of an attribute * @ni: open ntfs inode in which the ntfs attribute resides * @attr: attribute for which we want its index root * * This function will read the related index root an ntfs attribute. * * On success a buffer is allocated with the content of the index root * and which needs to be freed when it's not needed anymore. * * On error NULL is returned with errno set to the error code. */INDEX_ROOT *ntfs_index_root_get(ntfs_inode *ni, ATTR_RECORD *attr){ ntfs_attr_search_ctx *ctx; ntfschar *name; INDEX_ROOT *root = NULL; name = (ntfschar *)((u8 *)attr + le16_to_cpu(attr->name_offset)); ctx = ntfs_attr_get_search_ctx(ni, NULL); if (!ctx) { ntfs_log_perror("ntfs_get_search_ctx failed"); return NULL; } if (ntfs_attr_lookup(AT_INDEX_ROOT, name, attr->name_length, 0, 0, NULL, 0, ctx)) { ntfs_log_perror("ntfs_attr_lookup failed"); goto out; } root = malloc(sizeof(INDEX_ROOT)); if (!root) { ntfs_log_perror("malloc failed"); goto out; } *root = *((INDEX_ROOT *)((u8 *)ctx->attr + le16_to_cpu(ctx->attr->value_offset)));out: ntfs_attr_put_search_ctx(ctx); return root;}#endif /* __VISOPSYS__ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -