Changeset 72273 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- May 21, 2018 12:51:27 PM (7 years ago)
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fs/ntfsvfs.cpp
r70324 r72273 1562 1562 /** 1563 1563 * 1564 * @note Only modifying non-resident data is currently supported. No 1565 * shrinking or growing. Metadata is not modified. 1566 */ 1567 static 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 * 1564 1747 * @returns 1565 1748 * @param pRecHdr . … … 2237 2420 static DECLCALLBACK(int) rtFsNtfsFile_Write(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten) 2238 2421 { 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; 2241 2472 } 2242 2473 -
trunk/src/VBox/Runtime/tools/RTCp.cpp
r70442 r72273 61 61 /** -x, --one-filesystem. */ 62 62 bool fOneFileSystem; 63 64 /** Special --no-replace-nor-trucate hack for basic NTFS write support. */ 65 bool fNoReplaceNorTruncate; 63 66 64 67 /** Number of sources. */ … … 143 146 { 144 147 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)); 147 151 if (RT_SUCCESS(rc)) 148 152 { … … 240 244 { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, 241 245 { "--one-file-system", 'x', RTGETOPT_REQ_NOTHING }, 246 { "--no-replace-nor-trucate", 1032, RTGETOPT_REQ_NOTHING }, 242 247 }; 243 248 … … 247 252 Opts.fRecursive = false; 248 253 Opts.fOneFileSystem = false; 254 Opts.fNoReplaceNorTruncate = false; 249 255 Opts.pszDestination = NULL; 250 256 Opts.cSources = 0; … … 303 309 break; 304 310 311 case 1032: 312 Opts.fNoReplaceNorTruncate = true; 313 break; 314 305 315 case 'h': 306 316 RTPrintf("Usage: to be written\nOption dump:\n");
Note:
See TracChangeset
for help on using the changeset viewer.