VirtualBox

Changeset 69925 in vbox for trunk/src


Ignore:
Timestamp:
Dec 5, 2017 12:06:59 AM (7 years ago)
Author:
vboxsync
Message:

iprt/ntfsvfs.cpp: Made opening and traversing directories work.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/fs/ntfsvfs.cpp

    r69924 r69925  
    3535#include <iprt/avl.h>
    3636#include <iprt/assert.h>
     37#include <iprt/ctype.h>
    3738#include <iprt/file.h>
    3839#include <iprt/log.h>
     
    4344#include <iprt/utf16.h>
    4445#include <iprt/formats/ntfs.h>
     46
     47#include <internal/fs.h> /* For RTFSMODE_SYMLINK_REPARSE_TAG. */
    4548
    4649
     
    18141817
    18151818
     1819/**
     1820 * Worker for various QueryInfo methods.
     1821 *
     1822 * @returns IPRT status code.
     1823 * @param   pThis               The core object structure to return info for.
     1824 * @param   pAttr               The attribute that's being presented.  Take the
     1825 *                              allocation and timestamp info from it, if
     1826 *                              non-resident.
     1827 * @param   pObjInfo            Where to return object info.
     1828 * @param   enmAddAttr          What additional info to return.
     1829 */
     1830static int rtFsNtfsCore_QueryInfo(PRTFSNTFSCORE pThis, PRTFSNTFSATTR pAttr, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
     1831{
     1832    /*
     1833     * Wipe the structure and fill in common dummy value.
     1834     */
     1835    RT_ZERO(*pObjInfo);
     1836    switch (enmAddAttr)
     1837    {
     1838        case RTFSOBJATTRADD_UNIX:
     1839            pObjInfo->Attr.u.Unix.uid           = NIL_RTUID;
     1840            pObjInfo->Attr.u.Unix.gid           = NIL_RTGID;
     1841            pObjInfo->Attr.u.Unix.cHardlinks    = 1;
     1842            //pObjInfo->Attr.u.Unix.INodeIdDevice = 0;
     1843            pObjInfo->Attr.u.Unix.INodeId       = pThis->pMftRec->TreeNode.Key;
     1844            //pObjInfo->Attr.u.Unix.fFlags        = 0;
     1845            //pObjInfo->Attr.u.Unix.GenerationId  = 0;
     1846            //pObjInfo->Attr.u.Unix.Device        = 0;
     1847            break;
     1848
     1849        case RTFSOBJATTRADD_UNIX_OWNER:
     1850            pObjInfo->Attr.u.UnixOwner.uid = NIL_RTUID;
     1851            break;
     1852
     1853        case RTFSOBJATTRADD_UNIX_GROUP:
     1854            pObjInfo->Attr.u.UnixGroup.gid = NIL_RTGID;
     1855            break;
     1856
     1857        default:
     1858            break;
     1859    }
     1860
     1861    /*
     1862     * Look for the standard information attribute and use that as basis.
     1863     */
     1864    uint32_t      fFileAttrs;
     1865    PRTFSNTFSATTR pStdInfoAttr = rtFsNtfsCore_FindUnnamedAttribute(pThis, NTFS_AT_STANDARD_INFORMATION);
     1866    if (   pStdInfoAttr
     1867        && pStdInfoAttr->cbResident >= sizeof(NTFSATSTDINFO) )
     1868    {
     1869        Assert(!pStdInfoAttr->pAttrHdr->fNonResident);
     1870        PCNTFSATSTDINFO pStdInfo = (PCNTFSATSTDINFO)NTFSATTRIBHDR_GET_RES_VALUE_PTR(pStdInfoAttr->pAttrHdr);
     1871        RTTimeSpecSetNtTime(&pObjInfo->BirthTime,        RT_LE2H_U64(pStdInfo->iCreationTime));
     1872        RTTimeSpecSetNtTime(&pObjInfo->ModificationTime, RT_LE2H_U64(pStdInfo->iLastDataModTime));
     1873        RTTimeSpecSetNtTime(&pObjInfo->ChangeTime,       RT_LE2H_U64(pStdInfo->iLastMftModTime));
     1874        RTTimeSpecSetNtTime(&pObjInfo->AccessTime,       RT_LE2H_U64(pStdInfo->iLastAccessTime));
     1875        if (enmAddAttr == RTFSOBJATTRADD_UNIX)
     1876        {
     1877            pObjInfo->Attr.u.Unix.uid          = pStdInfo->idOwner;
     1878            pObjInfo->Attr.u.Unix.GenerationId = pStdInfo->uFileVersion;
     1879        }
     1880        else if (enmAddAttr == RTFSOBJATTRADD_UNIX_OWNER)
     1881            pObjInfo->Attr.u.UnixOwner.uid = pStdInfo->idOwner;
     1882        fFileAttrs = pStdInfo->fFileAttribs;
     1883    }
     1884    else
     1885    {
     1886        /** @todo check out the filename record?   */
     1887        switch (pAttr->pAttrHdr->uAttrType)
     1888        {
     1889            default:
     1890                AssertFailed();
     1891            case NTFS_AT_DATA:
     1892                fFileAttrs = NTFS_FA_NORMAL;
     1893                break;
     1894
     1895            case NTFS_AT_INDEX_ROOT:
     1896            case NTFS_AT_INDEX_ALLOCATION:
     1897                fFileAttrs = NTFS_FA_DIRECTORY;
     1898                break;
     1899        }
     1900    }
     1901
     1902    /*
     1903     * Take the allocation info from the destilled attribute data.
     1904     */
     1905    pObjInfo->cbObject    = pAttr->cbValue;
     1906    pObjInfo->cbAllocated = pAttr->Extents.cbData;
     1907    if (   pAttr->pAttrHdr->fNonResident
     1908        && (int64_t)pObjInfo->cbAllocated < (int64_t)RT_LE2H_U64(pAttr->pAttrHdr->u.NonRes.cbAllocated))
     1909        pObjInfo->cbAllocated = RT_LE2H_U64(pAttr->pAttrHdr->u.NonRes.cbAllocated);
     1910
     1911
     1912    /*
     1913     * See if we can find a filename record before we try convert the file attributes to mode.
     1914     */
     1915    PCNTFSATFILENAME pFilename     = NULL;
     1916    PRTFSNTFSATTR    pFilenameAttr = rtFsNtfsCore_FindUnnamedAttribute(pThis, NTFS_AT_FILENAME);
     1917    if (   pFilenameAttr
     1918        && pFilenameAttr->cbResident >= RT_UOFFSETOF(NTFSATFILENAME, wszFilename) )
     1919    {
     1920        Assert(!pFilenameAttr->pAttrHdr->fNonResident);
     1921        pFilename = (PCNTFSATFILENAME)NTFSATTRIBHDR_GET_RES_VALUE_PTR(pFilenameAttr->pAttrHdr);
     1922        if (pStdInfoAttr)
     1923            fFileAttrs |= pFilename->fFileAttribs;
     1924        else
     1925            fFileAttrs = pFilename->fFileAttribs;
     1926    }
     1927
     1928    /*
     1929     * This attribute conversion code is a slightly modified version of rtFsModeFromDos.
     1930     */
     1931    pObjInfo->Attr.fMode = (fFileAttrs << RTFS_DOS_SHIFT) & RTFS_DOS_MASK_NT;
     1932    if (fFileAttrs & NTFS_FA_DUP_FILE_NAME_INDEX_PRESENT)
     1933        pObjInfo->Attr.fMode |= RTFS_DOS_DIRECTORY;
     1934
     1935    /* everything is readable. */
     1936    pObjInfo->Attr.fMode |= RTFS_UNIX_IRUSR | RTFS_UNIX_IRGRP | RTFS_UNIX_IROTH;
     1937    if (pObjInfo->Attr.fMode & RTFS_DOS_DIRECTORY)
     1938        /* directories are executable. */
     1939        pObjInfo->Attr.fMode |= RTFS_TYPE_DIRECTORY | RTFS_UNIX_IXUSR | RTFS_UNIX_IXGRP | RTFS_UNIX_IXOTH;
     1940    else
     1941    {
     1942        pObjInfo->Attr.fMode |= RTFS_TYPE_FILE;
     1943        if (   pFilename
     1944            && pFilename->cwcFilename >= 4
     1945            && RT_UOFFSETOF(NTFSATFILENAME, wszFilename[pFilename->cwcFilename]) <= pFilenameAttr->cbResident)
     1946        {
     1947            PCRTUTF16 pwcExt = &pFilename->wszFilename[pFilename->cwcFilename - 4];
     1948            if ( *pwcExt++ == '.')
     1949            {
     1950                /* check for executable extension. */
     1951                if (   (unsigned)pwcExt[0] < 0x7fU
     1952                    && (unsigned)pwcExt[1] < 0x7fU
     1953                    && (unsigned)pwcExt[2] < 0x7fU)
     1954                {
     1955                    char szExt[4];
     1956                    szExt[0] = RT_C_TO_LOWER(pwcExt[0]);
     1957                    szExt[1] = RT_C_TO_LOWER(pwcExt[1]);
     1958                    szExt[2] = RT_C_TO_LOWER(pwcExt[2]);
     1959                    szExt[3] = '\0';
     1960                    if (    !memcmp(szExt, "exe", 4)
     1961                        ||  !memcmp(szExt, "bat", 4)
     1962                        ||  !memcmp(szExt, "com", 4)
     1963                        ||  !memcmp(szExt, "cmd", 4)
     1964                        ||  !memcmp(szExt, "btm", 4)
     1965                       )
     1966                        pObjInfo->Attr.fMode |= RTFS_UNIX_IXUSR | RTFS_UNIX_IXGRP | RTFS_UNIX_IXOTH;
     1967                }
     1968            }
     1969        }
     1970    }
     1971
     1972    /* Is it really a symbolic link? */
     1973    if (   (pObjInfo->Attr.fMode & RTFS_DOS_NT_REPARSE_POINT)
     1974        && pFilename
     1975        && pFilename->u.uReparseTag == RTFSMODE_SYMLINK_REPARSE_TAG)
     1976        pObjInfo->Attr.fMode = (pObjInfo->Attr.fMode & ~RTFS_TYPE_MASK) | RTFS_TYPE_SYMLINK;
     1977
     1978    /* writable? */
     1979    if (!(pObjInfo->Attr.fMode & RTFS_DOS_READONLY))
     1980        pObjInfo->Attr.fMode |= RTFS_UNIX_IWUSR | RTFS_UNIX_IWGRP | RTFS_UNIX_IWOTH;
     1981
     1982    return VINF_SUCCESS;
     1983}
     1984
    18161985
    18171986/*
     
    24962665        RTUTF16 uc1 = *pwszUpper1++;
    24972666        RTUTF16 uc2 = *pawcFilename2++;
    2498         if (   uc1 != uc2
    2499             && uc1 != pawcUpcase[uc2])
    2500             return uc1 < uc2 ? -1 : 1;
     2667        if (uc1 != uc2)
     2668        {
     2669            uc2 = pawcUpcase[uc2];
     2670            if (uc1 != uc2)
     2671                return uc1 < uc2 ? -1 : 1;
     2672        }
    25012673
    25022674        /* Decrement the lengths and loop. */
     
    26152787                    }
    26162788                    else
    2617                     {
    2618                         rtFsNtfsIdxNode_Release(pNode);
    2619                         LogFlow(("rtFsNtfsDirShrd_Lookup(%s): Not found!\n", pszEntry));
    2620                         return VERR_FILE_NOT_FOUND;
    2621                     }
     2789                        break;
    26222790                }
    26232791            }
     
    28122980static DECLCALLBACK(int) rtFsNtfsDir_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
    28132981{
     2982    PRTFSNTFSDIR pThis = (PRTFSNTFSDIR)pvThis;
    28142983    Log(("rtFsNtfsDir_QueryInfo\n"));
    2815     //PRTFSNTFSDIR pThis = (PRTFSNTFSDIR)pvThis;
    2816     //return rtFsNtfsCore_QueryInfo(&pThis->pShared->Core, pObjInfo, enmAddAttr);
    2817     NOREF(pvThis); NOREF(pObjInfo); NOREF(enmAddAttr);
    2818     return VERR_NOT_IMPLEMENTED;
     2984    return rtFsNtfsCore_QueryInfo(pThis->pShared->RootInfo.pRootAttr->pCore,
     2985                                  pThis->pShared->RootInfo.pAlloc ? pThis->pShared->RootInfo.pAlloc
     2986                                  : pThis->pShared->RootInfo.pRootAttr,
     2987                                  pObjInfo, enmAddAttr);
    28192988}
    28202989
     
    29393108    {
    29403109        uint32_t fFileAttribs = RT_LE2H_U32(pFilename->fFileAttribs);
    2941         switch (fFileAttribs & (NTFS_FA_DIRECTORY | NTFS_FA_REPARSE_POINT))
     3110        switch (fFileAttribs & (NTFS_FA_DIRECTORY | NTFS_FA_REPARSE_POINT | NTFS_FA_DUP_FILE_NAME_INDEX_PRESENT))
    29423111        {
    29433112            /*
     
    29653134             * Directory
    29663135             */
     3136            case NTFS_FA_DUP_FILE_NAME_INDEX_PRESENT:
     3137            case NTFS_FA_DIRECTORY | NTFS_FA_DUP_FILE_NAME_INDEX_PRESENT:
    29673138            case NTFS_FA_DIRECTORY:
    29683139                if (fFlags & RTVFSOBJ_F_OPEN_DIRECTORY)
     
    29923163             */
    29933164            case NTFS_FA_REPARSE_POINT:
    2994             case NTFS_FA_DIRECTORY | NTFS_FA_REPARSE_POINT:
     3165            case NTFS_FA_REPARSE_POINT | NTFS_FA_DIRECTORY:
     3166            case NTFS_FA_REPARSE_POINT | NTFS_FA_DUP_FILE_NAME_INDEX_PRESENT:
     3167            case NTFS_FA_REPARSE_POINT | NTFS_FA_DIRECTORY | NTFS_FA_DUP_FILE_NAME_INDEX_PRESENT:
    29953168                rc = VERR_NOT_IMPLEMENTED;
    29963169                break;
    29973170
    29983171            default:
    2999                 rc = VERR_IPE_NOT_REACHED_DEFAULT_CASE;
     3172                AssertFailed();
     3173                rc = VERR_FILE_NOT_FOUND;
    30003174                break;
    30013175        }
Note: See TracChangeset for help on using the changeset viewer.

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