VirtualBox

Changeset 69910 in vbox for trunk/include/iprt/formats


Ignore:
Timestamp:
Dec 3, 2017 5:06:56 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
119388
Message:

IPRT/ntfsvfs.cpp: More on the subject of directories (indexes).

Location:
trunk/include/iprt/formats
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/formats/fat.h

    r69849 r69910  
    468468    /** 0x41 / 0x36: Reserved. */
    469469    uint8_t         abReserved3[3];
    470     /** 0x44 / 0x39: Logical clusters pre index block.
     470    /** 0x44 / 0x39: The default logical clusters count per index node.
    471471     * This is a shift count if negative.  */
    472     int8_t          cClusterPerIndexBlock;
     472    int8_t          cClustersPerIndexNode;
    473473    /** 0x45 / 0x3a: Reserved. */
    474474    uint8_t         abReserved4[3];
  • trunk/include/iprt/formats/ntfs.h

    r69902 r69910  
    139139/** Pointer to a const NTFS record header. */
    140140typedef NTFSRECHDR const *PCNTFSRECHDR;
     141
     142/** The multi-sector update sequence stride.
     143 * @see https://msdn.microsoft.com/en-us/library/bb470212%28v=vs.85%29.aspx
     144 * @see NTFSRECHDR::offUpdateSeqArray, NTFSRECHDR::cUpdateSeqEntries
     145 */
     146#define NTFS_MULTI_SECTOR_STRIDE        512
    141147
    142148
     
    332338#define NTFSATTRIBHDR_GET_NAME(a_pAttrHdr)          ( (PRTUTF16)((uintptr_t)(a_pAttrHdr) + (a_pAttrHdr)->offName) )
    333339
     340/** Get the pointer to resident value.
     341 * @note  ASSUMES the caller checks that it's resident and valid. */
     342#define NTFSATTRIBHDR_GET_RES_VALUE_PTR(a_pAttrHdr) ( (uint8_t *)(a_pAttrHdr) + (a_pAttrHdr)->u.Res.offValue )
     343
    334344
    335345/** @name NTFS_RES_AF_XXX
     
    549559 * NTFS index header.
    550560 *
    551  * This is used by NTFSATINDEXROOT and NTFSATINDEXALLOC.
    552  */
    553 typedef struct NTFSINDEXHEADER
     561 * This is used by NTFSATINDEXROOT and NTFSATINDEXALLOC as a prelude to the
     562 * sequence of entries in a node.
     563 */
     564typedef struct NTFSINDEXHDR
    554565{
    555566    /** 0x00: Offset of the first entry relative to this header. */
    556567    uint32_t        offFirstEntry;
    557     /** 0x04: Size of the index in bytes, including this header.  */
    558     uint32_t        cbIndex;
     568    /** 0x04: Current index size in bytes, including this header.  */
     569    uint32_t        cbUsed;
    559570    /** 0x08: Number of bytes allocated for the index (including this header). */
    560571    uint32_t        cbAllocated;
    561     /** 0x0c: Flags (NTFSINDEXHEADER_F_XXX).   */
     572    /** 0x0c: Flags (NTFSINDEXHDR_F_XXX).   */
    562573    uint8_t         fFlags;
    563574    /** 0x0d: Reserved bytes. */
    564575    uint8_t         abReserved[3];
    565 } NTFSINDEXHEADER;
    566 AssertCompileSize(NTFSINDEXHEADER, 16);
     576    /* NTFSIDXENTRYHDR sequence typically follows here */
     577} NTFSINDEXHDR;
     578AssertCompileSize(NTFSINDEXHDR, 16);
    567579/** Pointer to a NTFS index header. */
    568 typedef NTFSINDEXHEADER *PNTFSINDEXHEADER;
     580typedef NTFSINDEXHDR *PNTFSINDEXHDR;
    569581/** Pointer to a const NTFS index header. */
    570 typedef NTFSINDEXHEADER const *PCNTFSINDEXHEADER;
    571 
    572 /** Index root only: Small enough to fit inside the index root attrib.  */
    573 #define NTFSINDEXHEADER_F_ROOT_SMALL        UINT8_C(0x00)
    574 /** Index root only: Too large to fit inside the index root attrib and/or an
    575  *  index allocation attribute is present. */
    576 #define NTFSINDEXHEADER_F_ROOT_LARGE        UINT8_C(0x01)
    577 
    578 
    579 /**
    580  * NTFS index root (NTFS_AT_INDEX_ROOT).
     582typedef NTFSINDEXHDR const *PCNTFSINDEXHDR;
     583
     584/** @name NTFSINDEXHDR_F_XXX
     585 * @{ */
     586/** An internal node (as opposed to a leaf node if clear).
     587 * This means that the entries will have trailing node references (VCN). */
     588#define NTFSINDEXHDR_F_INTERNAL        UINT8_C(0x01)
     589/** @} */
     590
     591
     592/**
     593 * NTFS index root node (NTFS_AT_INDEX_ROOT).
    581594 *
    582595 * This is a generic index structure, but is most prominently used for
    583  * implementating directories.
     596 * implementating directories.  The index is structured like B-tree, meaning
     597 * each node contains multiple entries, and each entry contains data regardless
     598 * of whether it's a leaf node or not.
     599 *
     600 * The index is sorted in ascending order according to the collation rules
     601 * defined by the root node (NTFSATINDEXROOT::uCollationRules, see also (see
     602 * NTFS_COLLATION_XXX).
     603 *
     604 * @note    The root directory contains a '.' entry, others don't.
    584605 */
    585606typedef struct NTFSATINDEXROOT
     
    589610    /** 0x04: The sorting rules to use (NTFS_COLLATION_XXX). */
    590611    uint32_t        uCollationRules;
    591     /** 0x08: Index buffer size (in bytes). */
    592     uint32_t        cbIndexBuffer;
    593     /** 0x0c: Number of clusters allocated for each index buffer if
    594      * cbIndexBuffer is larger than a cluster, otherwise log2(cbIndexBuffer)?  */
    595     uint8_t         cClustersPerBuffer;
     612    /** 0x08: Number of bytes in
     613     *  Index node size (in bytes). */
     614    uint32_t        cbIndexNode;
     615    /** 0x0c: Number of node addresses per node.
     616     * This sounds weird right?  A subnode is generally addressed as a virtual
     617     * cluster when cbIndexNode >= cbCluster, but when clusters are large NTFS uses
     618     * 512 bytes chunks.
     619     *
     620     * (You would've thought it would be simpler to just use cbIndexNode as the
     621     * addressing unit, maybe storing the log2 here to avoid a ffs call.) */
     622    uint8_t         cAddressesPerIndexNode;
    596623    /** 0x0d: Reserved padding or something. */
    597624    uint8_t         abReserved[3];
    598625    /** 0x10: Index header detailing the entries that follows. */
    599     NTFSINDEXHEADER Hdr;
    600     /* NTFSINDEXENTRYHDR array typically follows */
     626    NTFSINDEXHDR    Hdr;
     627    /*  0x20: NTFSIDXENTRYHDR sequence typically follows here */
    601628} NTFSATINDEXROOT;
    602629AssertCompileSize(NTFSATINDEXROOT, 32);
     
    611638#define NTFSATINDEXROOT_TYPE_VIEW           RT_H2LE_U32_C(UINT32_C(0x00000000))
    612639/** Directory index, NTFSATFILENAME follows NTFSINDEXENTRY. */
    613 #define NTFSATINDEXROOT_TYPE_DIRECTORY      RT_H2LE_U32_C(UINT32_C(0x00000030))
     640#define NTFSATINDEXROOT_TYPE_DIR            RT_H2LE_U32_C(UINT32_C(0x00000030))
    614641/** @} */
    615642
     
    631658/** Sequence of little endian 32-bit unsigned integer values used as sorting key. */
    632659#define NTFS_COLLATION_UINT32_SEQ           RT_H2LE_U32_C(UINT32_C(0x00000013))
    633 
    634 /** @} */
     660/** @} */
     661
     662
     663/**
     664 * NTFS index non-root node.
     665 */
     666typedef struct NTFSATINDEXALLOC
     667{
     668    /** 0x00: Header with NTFSREC_MAGIC_INDEX_ALLOC. */
     669    NTFSRECHDR      RecHdr;
     670    /** 0x08: Log file sequence number. */
     671    uint64_t        uLsn;
     672    /** 0x10: The node address of this node (for consistency checking and
     673     * perhaps data reconstruction).
     674     * @see NTFSATINDEXROOT::cAddressesPerIndexNode for node addressing. */
     675    int64_t         iSelfAddress;
     676    /** 0x18: Index header detailing the entries that follows. */
     677    NTFSINDEXHDR    Hdr;
     678    /*  0x28: NTFSIDXENTRYHDR sequence typically follows here */
     679} NTFSATINDEXALLOC;
     680AssertCompileSize(NTFSATINDEXALLOC, 40);
     681/** Pointer to a NTFS index non-root node. */
     682typedef NTFSATINDEXALLOC *PNTFSATINDEXALLOC;
     683/** Pointer to a const NTFS index non-root node. */
     684typedef NTFSATINDEXALLOC const *PCNTFSATINDEXALLOC;
     685
     686/** NTFS 'INDX' attribute magic value (NTFSATINDEXALLOC).
     687 * @todo sort out the record / attribute name clash here.  */
     688#define NTFSREC_MAGIC_INDEX_ALLOC           RT_H2LE_U32_C(UINT32_C(0x58444e49))
    635689
    636690
    637691/**
    638692 * NTFS index entry header.
    639  */
    640 typedef struct NTFSINDEXENTRYHDR
     693 *
     694 * Each entry in a node starts with this header.  It is immediately followed by
     695 * the key data (NTFSIDXENTRYHDR::cbKey).  When
     696 *
     697 */
     698typedef struct NTFSIDXENTRYHDR
    641699{
    642700    union
    643701    {
    644         /** 0x00: Non-View: Reference to the MFT record being indexed here.
    645          * This is invalid if NTFSINDEX_EF_LAST is set. */
     702        /** 0x00: NTFSATINDEXROOT_TYPE_DIR: Reference to the MFT record being indexed here.
     703         * @note This is invalid if NTFSIDXENTRYHDR_F_END is set (no key data). */
    646704        NTFSMFTREF      FileMftRec;
    647         /** 0x00: View  */
     705        /** 0x00: NTFSATINDEXROOT_TYPE_VIEW: Go figure later if necessary. */
    648706        struct
    649707        {
    650             /** 0x00: Offset to the data relative to this header. */
     708            /** 0x00: Offset to the data relative to this header.
     709             * @note This is invalid if NTFSIDXENTRYHDR_F_END is set (no key data). */
    651710            uint16_t    offData;
    652             /** 0x02: Size of data at offData. */
     711            /** 0x02: Size of data at offData.
     712             * @note This is invalid if NTFSIDXENTRYHDR_F_END is set (no key data). */
    653713            uint16_t    cbData;
    654714            /** 0x04: Reserved.   */
     
    661721    /** 0x0a: Key length (unaligned). */
    662722    uint16_t        cbKey;
    663     /** 0x0c: Entry flags, NTFSINDEX_EF_XXX. */
     723    /** 0x0c: Entry flags, NTFSIDXENTRYHDR_F_XXX. */
    664724    uint16_t        fFlags;
    665     /** 0x0d: Entry flags, NTFSINDEX_EF_XXX. */
     725    /** 0x0e: Reserved. */
    666726    uint16_t        uReserved;
    667 } NTFSINDEXENTRYHDR;
    668 AssertCompileSize(NTFSINDEXENTRYHDR, 16);
     727} NTFSIDXENTRYHDR;
     728AssertCompileSize(NTFSIDXENTRYHDR, 16);
    669729/** Pointer to a NTFS index entry header. */
    670 typedef NTFSINDEXENTRYHDR *PNTFSINDEXENTRYHDR;
     730typedef NTFSIDXENTRYHDR *PNTFSIDXENTRYHDR;
    671731/** Pointer to a const NTFS index entry header. */
    672 typedef NTFSINDEXENTRYHDR const *PCNTFSINDEXENTRYHDR;
    673 
    674 /** @name  NTFSINDEX_EF_XXX - NTFSINDEXENTRYHDR::fFlags
    675  * @{ */
    676 /** Indicates an internal node, as opposed to a leaf node. */
    677 #define NTFSINDEX_EF_NODE           RT_H2LE_U16_C(UINT16_C(0x0001))
    678 /** Last entry in a block, may point to the next node. */
    679 #define NTFSINDEX_EF_LAST           RT_H2LE_U16_C(UINT16_C(0x0002))
     732typedef NTFSIDXENTRYHDR const *PCNTFSIDXENTRYHDR;
     733
     734/** @name  NTFSIDXENTRYHDR_F_XXX - NTFSIDXENTRYHDR::fFlags
     735 * @{ */
     736/** Indicates an internal node (as opposed to a leaf node).
     737 * This indicates that there is a 64-bit integer value at the very end of the
     738 * entry (NTFSIDXENTRYHDR::cbEntry - 8) giving the virtual cluster number of the
     739 * subnode.  The subnode and all its decendants contain keys that are lower than
     740 * the key in this entry.
     741 */
     742#define NTFSIDXENTRYHDR_F_INTERNAL          RT_H2LE_U16_C(UINT16_C(0x0001))
     743/** Set if special end entry in a node.
     744 * This does not have any key data, but can point to a subnode with
     745 * higher keys.  */
     746#define NTFSIDXENTRYHDR_F_END               RT_H2LE_U16_C(UINT16_C(0x0002))
    680747/** @}  */
    681748
     749/** Gets the pointer to the next index entry header. */
     750#define NTFSIDXENTRYHDR_GET_NEXT(a_pEntryHdr) \
     751    ( (PNTFSIDXENTRYHDR)((uintptr_t)(a_pEntryHdr) + RT_LE2H_U16((a_pEntryHdr)->cbEntry)) )
     752/** Gets the subnode address from an index entry.
     753 * @see NTFSATINDEXROOT::cAddressesPerIndexNode for node addressing.
     754 * @note Only invoke when NTFSIDXENTRYHDR_F_INTERNAL is set! */
     755#define NTFSIDXENTRYHDR_GET_SUBNODE(a_pEntryHdr) \
     756    ( *(int64_t *)((uintptr_t)(a_pEntryHdr) + RT_LE2H_U16((a_pEntryHdr)->cbEntry) - sizeof(int64_t)) )
     757
    682758/** @} */
    683759
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette