VirtualBox

Changeset 72273 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
May 21, 2018 12:51:27 PM (7 years ago)
Author:
vboxsync
Message:

IPRT: Tweaked ntfsvfs.cpp and RTCp.cpp so it's patch files, provided the size doesn't change and they're large enough to not live in the MFT. This is very crude, but it's enormously helpful for tweaking the kernel.

Location:
trunk/src/VBox/Runtime
Files:
2 edited

Legend:

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

    r70324 r72273  
    15621562/**
    15631563 *
     1564 * @note    Only modifying non-resident data is currently supported.  No
     1565 *          shrinking or growing.  Metadata is not modified.
     1566 */
     1567static int rtFsNtfsAttr_Write(PRTFSNTFSATTR pAttr, uint64_t off, void const *pvBuf, size_t cbToWrite)
     1568{
     1569    PRTFSNTFSVOL pVol = pAttr->pCore->pVol;
     1570    int          rc;
     1571    if (!pAttr->pAttrHdr->fNonResident)
     1572    {
     1573        /*
     1574         * The attribute is resident.  Currently not supported.
     1575         */
     1576#if 0
     1577        uint32_t cbAttrib = RT_LE2H_U32(pAttr->pAttrHdr->cbAttrib);
     1578        uint32_t cbValue  = RT_LE2H_U32(pAttr->pAttrHdr->u.Res.cbValue);
     1579        uint16_t offValue = RT_LE2H_U16(pAttr->pAttrHdr->u.Res.offValue);
     1580        if (   off             <  cbValue
     1581            && cbToWrite       <= cbValue
     1582            && off + cbToWrite <= cbValue)
     1583        {
     1584            if (offValue <= cbAttrib)
     1585            {
     1586                cbAttrib -= offValue;
     1587                if (off < cbAttrib)
     1588                {
     1589                    /** @todo check if its possible to have cbValue larger than the attribute and
     1590                     *        reading those extra bytes as zero. */
     1591                    if (   pAttr->offAttrHdrInMftRec + offValue + cbAttrib <= pVol->cbMftRecord
     1592                        && cbAttrib <= pVol->cbMftRecord)
     1593                    {
     1594                        size_t cbToCopy = cbAttrib - off;
     1595                        if (cbToCopy > cbToWrite)
     1596                            cbToCopy = cbToWrite;
     1597                        memcpy(pvBuf, (uint8_t *)pAttr->pAttrHdr + offValue, cbToCopy);
     1598                        pvBuf      = (uint8_t *)pvBuf + cbToCopy;
     1599                        cbToWrite -= cbToCopy;
     1600                        rc = VINF_SUCCESS;
     1601                    }
     1602                    else
     1603                    {
     1604                        rc = VERR_VFS_BOGUS_OFFSET;
     1605                        Log(("rtFsNtfsAttr_Write: bad resident attribute!\n"));
     1606                    }
     1607                }
     1608                else
     1609                    rc = VINF_SUCCESS;
     1610            }
     1611            else
     1612                rc = VERR_VFS_BOGUS_FORMAT;
     1613        }
     1614        else
     1615            rc = VERR_EOF;
     1616#else
     1617        LogRel(("rtFsNtfsAttr_Write: file too small to write to.\n"));
     1618        rc = VERR_INTERNAL_ERROR_3;
     1619#endif
     1620    }
     1621    else if (pAttr->pAttrHdr->u.NonRes.uCompressionUnit == 0)
     1622    {
     1623        /*
     1624         * Uncompressed non-resident attribute.
     1625         * Note! We currently
     1626         */
     1627        uint64_t const cbAllocated   = RT_LE2H_U64(pAttr->pAttrHdr->u.NonRes.cbAllocated);
     1628        if (   off >= cbAllocated
     1629            || cbToWrite > cbAllocated
     1630            || off + cbToWrite > cbAllocated)
     1631            rc = VERR_EOF;
     1632        else
     1633        {
     1634            rc = VINF_SUCCESS;
     1635
     1636            uint64_t const cbInitialized = RT_LE2H_U64(pAttr->pAttrHdr->u.NonRes.cbInitialized);
     1637            if (   off < cbInitialized
     1638                && cbToWrite > 0)
     1639            {
     1640                /*
     1641                 * Locate the first extent.  This is a tad complicated.
     1642                 *
     1643                 * We move off along as we traverse the extent tables, so that it is relative
     1644                 * to the start of the current extent.
     1645                 */
     1646                PRTFSNTFSEXTENTS    pTable   = &pAttr->Extents;
     1647                uint32_t            iExtent  = 0;
     1648                PRTFSNTFSATTRSUBREC pCurSub  = NULL;
     1649                for (;;)
     1650                {
     1651                    if (off < pTable->cbData)
     1652                    {
     1653                        while (   iExtent < pTable->cExtents
     1654                               && off >= pTable->paExtents[iExtent].cbExtent)
     1655                        {
     1656                            off -= pTable->paExtents[iExtent].cbExtent;
     1657                            iExtent++;
     1658                        }
     1659                        AssertReturn(iExtent < pTable->cExtents, VERR_INTERNAL_ERROR_2);
     1660                        break;
     1661                    }
     1662
     1663                    /* Next table. */
     1664                    off -= pTable->cbData;
     1665                    if (!pCurSub)
     1666                        pCurSub = pAttr->pSubRecHead;
     1667                    else
     1668                        pCurSub = pCurSub->pNext;
     1669                    if (!pCurSub)
     1670                    {
     1671                        iExtent = UINT32_MAX;
     1672                        break;
     1673                    }
     1674                    pTable  = &pCurSub->Extents;
     1675                    iExtent = 0;
     1676                }
     1677
     1678                /*
     1679                 * The write loop.
     1680                 */
     1681                while (iExtent != UINT32_MAX)
     1682                {
     1683                    uint64_t cbMaxWrite = pTable->paExtents[iExtent].cbExtent;
     1684                    Assert(off < cbMaxWrite);
     1685                    cbMaxWrite -= off;
     1686                    size_t const cbThisWrite = cbMaxWrite >= cbToWrite ? cbToWrite : (size_t)cbMaxWrite;
     1687                    if (pTable->paExtents[iExtent].off == UINT64_MAX)
     1688                    {
     1689                        if (!ASMMemIsZero(pvBuf, cbThisWrite))
     1690                        {
     1691                            LogRel(("rtFsNtfsAttr_Write: Unable to modify sparse section of file!\n"));
     1692                            rc = VERR_INTERNAL_ERROR_2;
     1693                            break;
     1694                        }
     1695                    }
     1696                    else
     1697                    {
     1698                        rc = RTVfsFileWriteAt(pVol->hVfsBacking, pTable->paExtents[iExtent].off + off, pvBuf, cbThisWrite, NULL);
     1699                        Log4(("NTFS: Volume write: @%#RX64 LB %#zx -> %Rrc\n", pTable->paExtents[iExtent].off + off, cbThisWrite, rc));
     1700                        if (RT_FAILURE(rc))
     1701                            break;
     1702                    }
     1703                    pvBuf      = (uint8_t const *)pvBuf + cbThisWrite;
     1704                    cbToWrite -= cbThisWrite;
     1705                    if (!cbToWrite)
     1706                        break;
     1707                    off = 0;
     1708
     1709                    /*
     1710                     * Advance to the next extent.
     1711                     */
     1712                    iExtent++;
     1713                    if (iExtent >= pTable->cExtents)
     1714                    {
     1715                        pCurSub = pCurSub ? pCurSub->pNext : pAttr->pSubRecHead;
     1716                        if (!pCurSub)
     1717                            break;
     1718                        pTable  = &pCurSub->Extents;
     1719                        iExtent = 0;
     1720                    }
     1721                }
     1722            }
     1723        }
     1724    }
     1725    else
     1726    {
     1727        LogRel(("rtFsNtfsAttr_Write: Compressed files are not supported\n"));
     1728        rc = VERR_NOT_SUPPORTED;
     1729    }
     1730
     1731    /*
     1732     * Anything else beyond the end of what's stored/initialized?
     1733     */
     1734    if (   cbToWrite > 0
     1735        && RT_SUCCESS(rc))
     1736    {
     1737        LogRel(("rtFsNtfsAttr_Write: Unable to modify sparse section (tail) of file!\n"));
     1738        rc = VERR_INTERNAL_ERROR_2;
     1739    }
     1740
     1741    return rc;
     1742}
     1743
     1744
     1745/**
     1746 *
    15641747 * @returns
    15651748 * @param   pRecHdr             .
     
    22372420static DECLCALLBACK(int) rtFsNtfsFile_Write(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten)
    22382421{
    2239     RT_NOREF(pvThis, off, pSgBuf, fBlocking, pcbWritten);
    2240     return VERR_WRITE_PROTECT;
     2422    PRTFSNTFSFILE pThis = (PRTFSNTFSFILE)pvThis;
     2423    AssertReturn(pSgBuf->cSegs == 1, VERR_INTERNAL_ERROR_3);
     2424    RT_NOREF(fBlocking);
     2425
     2426    if (off == -1)
     2427        off = pThis->offFile;
     2428    else
     2429        AssertReturn(off >= 0, VERR_INTERNAL_ERROR_3);
     2430
     2431    int           rc;
     2432    PRTFSNTFSATTR pDataAttr = pThis->pShared->pData;
     2433    size_t        cbToWrite = pSgBuf->paSegs[0].cbSeg;
     2434    if ((uint64_t)off + cbToWrite <= pDataAttr->cbValue)
     2435    {
     2436        rc = rtFsNtfsAttr_Write(pThis->pShared->pData, off, pSgBuf->paSegs[0].pvSeg, cbToWrite);
     2437        Log6(("rtFsNtfsFile_Write: off=%#RX64 cbToWrite=%#zx -> %Rrc\n", off, cbToWrite, rc));
     2438        if (RT_SUCCESS(rc))
     2439            pThis->offFile = off + cbToWrite;
     2440        if (pcbWritten)
     2441            *pcbWritten = RT_SUCCESS(rc) ? cbToWrite : 0;
     2442    }
     2443    else if ((uint64_t)off < pDataAttr->cbValue)
     2444    {
     2445        size_t cbWritten = pDataAttr->cbValue - off;
     2446        rc = rtFsNtfsAttr_Write(pThis->pShared->pData, off, pSgBuf->paSegs[0].pvSeg, cbWritten);
     2447        if (RT_SUCCESS(rc))
     2448        {
     2449            Log6(("rtFsNtfsFile_Write: off=%#RX64 cbToWrite=%#zx -> VERR_EOF [EOF: %#RX64, Written: %#zx]\n",
     2450                  off, cbToWrite, pDataAttr->cbValue, cbWritten));
     2451            pThis->offFile = off + cbWritten;
     2452            if (pcbWritten)
     2453                *pcbWritten = cbWritten;
     2454            rc = VERR_EOF;
     2455        }
     2456        else
     2457        {
     2458            Log6(("rtFsNtfsFile_Write: off=%#RX64 cbToWrite=%#zx -> %Rrc [EOF: %#RX64]\n", off, cbToWrite, rc, pDataAttr->cbValue));
     2459            if (pcbWritten)
     2460                *pcbWritten = 0;
     2461        }
     2462    }
     2463    else
     2464    {
     2465        Log6(("rtFsNtfsFile_Write: off=%#RX64 cbToWrite=%#zx -> VERR_EOF [EOF: %#RX64]\n", off, cbToWrite, pDataAttr->cbValue));
     2466        rc = VERR_EOF;
     2467        if (pcbWritten)
     2468            *pcbWritten = 0;
     2469    }
     2470
     2471    return rc;
    22412472}
    22422473
  • trunk/src/VBox/Runtime/tools/RTCp.cpp

    r70442 r72273  
    6161    /** -x, --one-filesystem. */
    6262    bool            fOneFileSystem;
     63
     64    /** Special --no-replace-nor-trucate hack for basic NTFS write support. */
     65    bool            fNoReplaceNorTruncate;
    6366
    6467    /** Number of sources. */
     
    143146                {
    144147                    RTVFSFILE hVfsDst;
    145                     rc = RTVfsChainOpenFile(pszDst, RTFILE_O_READWRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_WRITE,
    146                                             &hVfsDst, &offError, RTErrInfoInitStatic(&ErrInfo));
     148                    uint64_t fDstFlags = (pOpts->fNoReplaceNorTruncate ? RTFILE_O_OPEN_CREATE : RTFILE_O_CREATE_REPLACE)
     149                                       | RTFILE_O_READWRITE | RTFILE_O_DENY_WRITE | (0666 << RTFILE_O_CREATE_MODE_SHIFT);
     150                    rc = RTVfsChainOpenFile(pszDst, fDstFlags, &hVfsDst, &offError, RTErrInfoInitStatic(&ErrInfo));
    147151                    if (RT_SUCCESS(rc))
    148152                    {
     
    240244        { "--verbose",                          'v', RTGETOPT_REQ_NOTHING },
    241245        { "--one-file-system",                  'x', RTGETOPT_REQ_NOTHING },
     246        { "--no-replace-nor-trucate",          1032, RTGETOPT_REQ_NOTHING },
    242247    };
    243248
     
    247252    Opts.fRecursive                 = false;
    248253    Opts.fOneFileSystem             = false;
     254    Opts.fNoReplaceNorTruncate      = false;
    249255    Opts.pszDestination             = NULL;
    250256    Opts.cSources                   = 0;
     
    303309                    break;
    304310
     311                case 1032:
     312                    Opts.fNoReplaceNorTruncate = true;
     313                    break;
     314
    305315                case 'h':
    306316                    RTPrintf("Usage: to be written\nOption dump:\n");
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