diff --git a/include/ntfs/layout.h b/include/ntfs/layout.h index cce72fc2..4557d849 100644 --- a/include/ntfs/layout.h +++ b/include/ntfs/layout.h @@ -247,15 +247,22 @@ typedef enum { * * These are the so far known MFT_RECORD_* flags (16-bit) which contain * information about the mft record in which they are present. - * _4 and _8 are needed by $Extend sub-files (don't know what to - * call them yet...) + * + * MFT_RECORD_IS_4 exists on all $Extend sub-files. + * It seems that it marks it is a metadata file with MFT record >24, however, + * it is unknown if it is limited to metadata files only. + * + * MFT_RECORD_IS_VIEW_INDEX exists on every metafile with a non directory + * index, that means an INDEX_ROOT and an INDEX_ALLOCATION with a name other + * than "$I30". It is unknown if it is limited to metadata files only. */ typedef enum { - MFT_RECORD_IN_USE = const_cpu_to_le16(0x0001), - MFT_RECORD_IS_DIRECTORY = const_cpu_to_le16(0x0002), - MFT_RECORD_IS_4 = const_cpu_to_le16(0x0004), - MFT_RECORD_IS_8 = const_cpu_to_le16(0x0008), - MFT_REC_SPACE_FILLER = 0xffff /* Just to make flags 16-bit. */ + MFT_RECORD_IN_USE = const_cpu_to_le16(0x0001), + MFT_RECORD_IS_DIRECTORY = const_cpu_to_le16(0x0002), + MFT_RECORD_IS_4 = const_cpu_to_le16(0x0004), + MFT_RECORD_IS_VIEW_INDEX = const_cpu_to_le16(0x0008), + MFT_REC_SPACE_FILLER = 0xffff, /* Just to make flags + 16-bit. */ } __attribute__((__packed__)) MFT_RECORD_FLAGS; /* @@ -857,19 +864,30 @@ typedef enum { and preserves the rest. This mask is used to to obtain all flags that are valid for setting. */ - /* - * FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT is only present in the - * FILE_NAME attribute (in the field file_attributes). + /** + * FILE_ATTR_I30_INDEX_PRESENT - Is it a directory? + * + * This is a copy of the MFT_RECORD_IS_DIRECTORY bit from the mft + * record, telling us whether this is a directory or not, i.e. whether + * it has an index root attribute named "$I30" or not. + * + * This flag is only present in the FILE_NAME attribute (in the + * file_attributes field). */ - FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT = const_cpu_to_le32(0x10000000), - /* This is a copy of the corresponding bit from the mft record, telling - us whether this is a directory or not, i.e. whether it has an - index root attribute or not. */ - FILE_ATTR_DUP_VIEW_INDEX_PRESENT = const_cpu_to_le32(0x20000000), - /* This is a copy of the corresponding bit from the mft record, telling - us whether this file has a view index present (eg. object id index, - quota index, one of the security indexes or the encrypting file - system related indexes). */ + FILE_ATTR_I30_INDEX_PRESENT = const_cpu_to_le32(0x10000000), + + /** + * FILE_ATTR_VIEW_INDEX_PRESENT - Does have a non-directory index? + * + * This is a copy of the MFT_RECORD_IS_VIEW_INDEX bit from the mft + * record, telling us whether this file has a view index present (eg. + * object id index, quota index, one of the security indexes and the + * reparse points index). + * + * This flag is only present in the $STANDARD_INFORMATION and + * $FILE_NAME attributes. + */ + FILE_ATTR_VIEW_INDEX_PRESENT = const_cpu_to_le32(0x20000000), } __attribute__((__packed__)) FILE_ATTR_FLAGS; /* diff --git a/libntfs/dir.c b/libntfs/dir.c index 8696bde5..37b1fcff 100644 --- a/libntfs/dir.c +++ b/libntfs/dir.c @@ -643,8 +643,7 @@ static inline int ntfs_filldir(ntfs_inode *dir_ni, s64 *pos, u8 ivcn_bits, /* Skip root directory self reference entry. */ if (MREF_LE(ie->indexed_file) == FILE_root) return 0; - if (ie->key.file_name.file_attributes & - FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT) + if (ie->key.file_name.file_attributes & FILE_ATTR_I30_INDEX_PRESENT) dt_type = NTFS_DT_DIR; else dt_type = NTFS_DT_REG; @@ -1254,7 +1253,7 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, fn->file_name_length = name_len; fn->file_name_type = FILE_NAME_POSIX; if (S_ISDIR(type)) - fn->file_attributes = FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT; + fn->file_attributes = FILE_ATTR_I30_INDEX_PRESENT; if (!S_ISREG(type) && !S_ISDIR(type)) fn->file_attributes = FILE_ATTR_SYSTEM; fn->creation_time = utc2ntfs(ni->creation_time); @@ -1576,7 +1575,7 @@ int ntfs_link(ntfs_inode *ni, ntfs_inode *dir_ni, ntfschar *name, u8 name_len) fn->file_name_type = FILE_NAME_POSIX; fn->file_attributes = ni->flags; if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) - fn->file_attributes |= FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT; + fn->file_attributes |= FILE_ATTR_I30_INDEX_PRESENT; fn->allocated_size = cpu_to_sle64(ni->allocated_size); fn->data_size = cpu_to_sle64(ni->data_size); fn->creation_time = utc2ntfs(ni->creation_time); diff --git a/ntfsprogs/mkntfs.c b/ntfsprogs/mkntfs.c index 5e9cec49..0829fc8b 100644 --- a/ntfsprogs/mkntfs.c +++ b/ntfsprogs/mkntfs.c @@ -4358,7 +4358,7 @@ static void mkntfs_create_root_structures(void) add_attr_std_info(m, file_attrs, cpu_to_le32(0x0100)); } else if (i == 9) { - file_attrs |= FILE_ATTR_DUP_VIEW_INDEX_PRESENT; + file_attrs |= FILE_ATTR_VIEW_INDEX_PRESENT; add_attr_std_info(m, file_attrs, cpu_to_le32(0x0101)); } else if (i == 11) { @@ -4366,7 +4366,7 @@ static void mkntfs_create_root_structures(void) cpu_to_le32(0x0101)); } else if (i == 24 || i == 25 || i == 26) { file_attrs |= FILE_ATTR_ARCHIVE; - file_attrs |= FILE_ATTR_DUP_VIEW_INDEX_PRESENT; + file_attrs |= FILE_ATTR_VIEW_INDEX_PRESENT; add_attr_std_info(m, file_attrs, cpu_to_le32(0x0101)); } else { @@ -4384,8 +4384,8 @@ static void mkntfs_create_root_structures(void) m->link_count = cpu_to_le16(le16_to_cpu(m->link_count) + 1); err = add_attr_file_name(m, root_ref, 0LL, 0LL, FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM | - FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT, 0, 0, - ".", FILE_NAME_WIN32_AND_DOS); + FILE_ATTR_I30_INDEX_PRESENT, 0, 0, ".", + FILE_NAME_WIN32_AND_DOS); if (!err) { if (g_vol->major_ver == 1) { init_system_file_sd(FILE_root, &sd, &i); @@ -4690,14 +4690,13 @@ static void mkntfs_create_root_structures(void) } else { ntfs_log_verbose("Creating $Secure (mft record 9)\n"); m = (MFT_RECORD*)(g_buf + 9 * g_vol->mft_record_size); - m->flags |= MFT_RECORD_IS_8; + m->flags |= MFT_RECORD_IS_VIEW_INDEX; if (!err) err = create_hardlink(g_index_block, root_ref, m, MK_LE_MREF(9, 9), 0LL, 0LL, FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM | - FILE_ATTR_DUP_VIEW_INDEX_PRESENT - , 0, 0, "$Secure", - FILE_NAME_WIN32_AND_DOS); + FILE_ATTR_VIEW_INDEX_PRESENT, 0, 0, + "$Secure", FILE_NAME_WIN32_AND_DOS); if (!err) { if (g_vol->minor_ver == 0) { g_buf_sds_first_size = 0x1E0; @@ -4782,9 +4781,8 @@ static void mkntfs_create_root_structures(void) err = create_hardlink(g_index_block, root_ref, m, MK_LE_MREF(11, 11), 0LL, 0LL, FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM | - FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT, - 0, 0, "$Extend", - FILE_NAME_WIN32_AND_DOS); + FILE_ATTR_I30_INDEX_PRESENT, 0, 0, + "$Extend", FILE_NAME_WIN32_AND_DOS); /* FIXME: This should be IGNORE_CASE */ if (!err) err = add_attr_index_root(m, "$I30", 4, 0, AT_FILE_NAME, @@ -4811,11 +4809,11 @@ static void mkntfs_create_root_structures(void) /* starting vith file 24 (ignoring file 16-23) */ if (g_vol->major_ver >= 3) { extend_flags = FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM | - FILE_ATTR_ARCHIVE | FILE_ATTR_DUP_VIEW_INDEX_PRESENT; + FILE_ATTR_ARCHIVE | FILE_ATTR_VIEW_INDEX_PRESENT; ntfs_log_verbose("Creating $Quota (mft record 24)\n"); m = (MFT_RECORD*)(g_buf + 24 * g_vol->mft_record_size); m->flags |= MFT_RECORD_IS_4; - m->flags |= MFT_RECORD_IS_8; + m->flags |= MFT_RECORD_IS_VIEW_INDEX; if (!err) err = create_hardlink_res((MFT_RECORD*)(g_buf + 11 * g_vol->mft_record_size), extend_ref, m, @@ -4836,7 +4834,7 @@ static void mkntfs_create_root_structures(void) ntfs_log_verbose("Creating $ObjId (mft record 25)\n"); m = (MFT_RECORD*)(g_buf + 25 * g_vol->mft_record_size); m->flags |= MFT_RECORD_IS_4; - m->flags |= MFT_RECORD_IS_8; + m->flags |= MFT_RECORD_IS_VIEW_INDEX; if (!err) err = create_hardlink_res((MFT_RECORD*)(g_buf + 11 * g_vol->mft_record_size), extend_ref, @@ -4853,7 +4851,7 @@ static void mkntfs_create_root_structures(void) ntfs_log_verbose("Creating $Reparse (mft record 26)\n"); m = (MFT_RECORD*)(g_buf + 26 * g_vol->mft_record_size); m->flags |= MFT_RECORD_IS_4; - m->flags |= MFT_RECORD_IS_8; + m->flags |= MFT_RECORD_IS_VIEW_INDEX; if (!err) err = create_hardlink_res((MFT_RECORD*)(g_buf + 11 * g_vol->mft_record_size), diff --git a/ntfsprogs/ntfsinfo.c b/ntfsprogs/ntfsinfo.c index c2c32190..bdb5e6b5 100644 --- a/ntfsprogs/ntfsinfo.c +++ b/ntfsprogs/ntfsinfo.c @@ -484,15 +484,17 @@ static void ntfs_dump_flags(ATTR_TYPES type, u32 flags) printf(" ENCRYPTED"); flags &= ~FILE_ATTR_ENCRYPTED; } + /* We know that FILE_ATTR_I30_INDEX_PRESENT only exists on $FILE_NAME, + and in case we are wrong, let it appear as UNKNOWN */ if (type == AT_FILE_NAME) { - if (flags & FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT) { - printf(" FILE_NAME_INDEX"); - flags &= ~FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT; + if (flags & FILE_ATTR_I30_INDEX_PRESENT) { + printf(" I30_INDEX"); + flags &= ~FILE_ATTR_I30_INDEX_PRESENT; } } - if (flags & FILE_ATTR_DUP_VIEW_INDEX_PRESENT) { + if (flags & FILE_ATTR_VIEW_INDEX_PRESENT) { printf(" VIEW_INDEX"); - flags &= ~FILE_ATTR_DUP_VIEW_INDEX_PRESENT; + flags &= ~FILE_ATTR_VIEW_INDEX_PRESENT; } if (flags) printf(" UNKNOWN: 0x%x", (unsigned int)le32_to_cpu(flags)); diff --git a/ntfsprogs/ntfsrm.c b/ntfsprogs/ntfsrm.c index 09ad67ec..db5f93a3 100644 --- a/ntfsprogs/ntfsrm.c +++ b/ntfsprogs/ntfsrm.c @@ -381,7 +381,7 @@ static BOOL utils_pathname_to_inode2(ntfs_volume *vol, struct ntfs_dir *parent, ntfs_log_debug("dt = %p, data_len = %d, parent = %p\n", dt, dt->data_len, dt->parent); //printf("dt's flags = 0x%08x\n", dt->children[dt_num]->key.file_name.file_attributes); - if (dt->children[dt_num]->key.file_name.file_attributes == FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT) { + if (dt->children[dt_num]->key.file_name.file_attributes == FILE_ATTR_I30_INDEX_PRESENT) { //printf("DIR\n"); child = ntfs_dir_create(dir->vol, dt->children[dt_num]->indexed_file); //printf("child = %p (%lld)\n", child, MREF(dt->children[dt_num]->indexed_file));