Changeset 59621 in vbox for trunk/src/VBox/Main/src-server/ApplianceImplIO.cpp
- Timestamp:
- Feb 10, 2016 12:51:35 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/ApplianceImplIO.cpp
r59555 r59621 162 162 } 163 163 164 #if 0 164 165 /** @interface_method_impl{VDINTERFACEIO,pfnSetSize} */ 165 166 static DECLCALLBACK(int) notImpl_SetSize(void *pvUser, void *pvStorage, uint64_t cb) … … 178 179 return VERR_NOT_IMPLEMENTED; 179 180 } 181 #endif 180 182 181 183 /** @interface_method_impl{VDINTERFACEIO,pfnFlushSync} */ … … 469 471 return pCallbacks; 470 472 } 471 472 /** @} */473 474 475 /** @name VDINTERFACEIO implementation on top of an IPRT file system stream.476 * @{ */477 478 /**479 * Internal data for read only I/O stream (related to FSSRDONLYINTERFACEIO).480 */481 typedef struct IOSRDONLYINTERNAL482 {483 /** The I/O stream. */484 RTVFSIOSTREAM hVfsIos;485 /** Completion callback. */486 PFNVDCOMPLETED pfnCompleted;487 } IOSRDONLYINTERNAL, *PIOSRDONLYINTERNAL;488 489 /**490 * Extended VD I/O interface structure that fssRdOnly uses.491 *492 * It's passed as pvUser to each call.493 */494 typedef struct FSSRDONLYINTERFACEIO495 {496 VDINTERFACEIO CoreIo;497 498 /** The file system stream object. */499 RTVFSFSSTREAM hVfsFss;500 /** Set if we've seen VERR_EOF on the file system stream already. */501 bool fEndOfFss;502 503 /** The current object in the stream. */504 RTVFSOBJ hVfsCurObj;505 /** The name of the current object. */506 char *pszCurName;507 /** The type of the current object. */508 RTVFSOBJTYPE enmCurType;509 510 } FSSRDONLYINTERFACEIO;511 512 513 /** @interface_method_impl{VDINTERFACEIO,pfnOpen} */514 static DECLCALLBACK(int) fssRdOnly_Open(void *pvUser, const char *pszLocation, uint32_t fOpen,515 PFNVDCOMPLETED pfnCompleted, void **ppInt)516 {517 PFSSRDONLYINTERFACEIO pThis = (PFSSRDONLYINTERFACEIO)pvUser;518 519 /*520 * Validate input.521 */522 AssertPtrReturn(ppInt, VERR_INVALID_POINTER);523 AssertPtrNullReturn(pfnCompleted, VERR_INVALID_PARAMETER);524 AssertReturn((fOpen & RTFILE_O_ACCESS_MASK) == RTFILE_O_READ, VERR_INVALID_PARAMETER);525 526 DEBUG_PRINT_FLOW();527 528 /*529 * Scan the stream until a matching file is found.530 */531 for (;;)532 {533 if (pThis->hVfsCurObj != NIL_RTVFSOBJ)534 {535 if (RTStrICmp(pThis->pszCurName, pszLocation) == 0)536 {537 switch (pThis->enmCurType)538 {539 case RTVFSOBJTYPE_IO_STREAM:540 case RTVFSOBJTYPE_FILE:541 {542 PIOSRDONLYINTERNAL pFile = (PIOSRDONLYINTERNAL)RTMemAlloc(sizeof(*pFile));543 if (!pFile)544 return VERR_NO_MEMORY;545 pFile->hVfsIos = RTVfsObjToIoStream(pThis->hVfsCurObj);546 pFile->pfnCompleted = pfnCompleted;547 *ppInt = pFile;548 549 /* Force stream to be advanced on next open call. */550 RTVfsObjRelease(pThis->hVfsCurObj);551 pThis->hVfsCurObj = NIL_RTVFSOBJ;552 RTStrFree(pThis->pszCurName);553 pThis->pszCurName = NULL;554 555 return VINF_SUCCESS;556 }557 558 case RTVFSOBJTYPE_DIR:559 return VERR_IS_A_DIRECTORY;560 default:561 return VERR_UNEXPECTED_FS_OBJ_TYPE;562 }563 }564 565 /*566 * Drop the current stream object.567 */568 RTVfsObjRelease(pThis->hVfsCurObj);569 pThis->hVfsCurObj = NIL_RTVFSOBJ;570 RTStrFree(pThis->pszCurName);571 pThis->pszCurName = NULL;572 }573 574 /*575 * Fetch the next object in the stream.576 */577 if (pThis->fEndOfFss)578 return VERR_FILE_NOT_FOUND;579 int rc = RTVfsFsStrmNext(pThis->hVfsFss, &pThis->pszCurName, &pThis->enmCurType, &pThis->hVfsCurObj);580 if (RT_FAILURE(rc))581 {582 pThis->fEndOfFss = rc == VERR_EOF;583 return rc == VERR_EOF ? VERR_FILE_NOT_FOUND : rc;584 }585 }586 }587 588 /** @interface_method_impl{VDINTERFACEIO,pfnClose} */589 static DECLCALLBACK(int) fssRdOnly_Close(void *pvUser, void *pvStorage)590 {591 PIOSRDONLYINTERNAL pFile = (PIOSRDONLYINTERNAL)pvStorage;592 AssertPtrReturn(pvUser, VERR_INVALID_POINTER);593 AssertPtrReturn(pFile, VERR_INVALID_POINTER);594 DEBUG_PRINT_FLOW();595 596 uint32_t cRefs = RTVfsIoStrmRelease(pFile->hVfsIos);597 pFile->hVfsIos = NIL_RTVFSIOSTREAM;598 RTMemFree(pFile);599 600 return cRefs != UINT32_MAX ? VINF_SUCCESS : VERR_INTERNAL_ERROR_3;601 }602 603 604 /** @interface_method_impl{VDINTERFACEIO,pfnGetSize} */605 static DECLCALLBACK(int) fssRdOnly_GetSize(void *pvUser, void *pvStorage, uint64_t *pcb)606 {607 PIOSRDONLYINTERNAL pFile = (PIOSRDONLYINTERNAL)pvStorage;608 AssertPtrReturn(pvUser, VERR_INVALID_POINTER);609 AssertPtrReturn(pFile, VERR_INVALID_POINTER);610 AssertPtrReturn(pcb, VERR_INVALID_POINTER);611 DEBUG_PRINT_FLOW();612 613 RTFSOBJINFO ObjInfo;614 int rc = RTVfsIoStrmQueryInfo(pFile->hVfsIos, &ObjInfo, RTFSOBJATTRADD_NOTHING);615 if (RT_SUCCESS(rc))616 *pcb = ObjInfo.cbObject;617 return rc;618 }619 620 /** @interface_method_impl{VDINTERFACEIO,pfnReadSync} */621 static DECLCALLBACK(int) fssRdOnly_ReadSync(void *pvUser, void *pvStorage, uint64_t off, void *pvBuf,622 size_t cbToRead, size_t *pcbRead)623 {624 PIOSRDONLYINTERNAL pFile = (PIOSRDONLYINTERNAL)pvStorage;625 AssertPtrReturn(pvUser, VERR_INVALID_POINTER);626 AssertPtrReturn(pFile, VERR_INVALID_POINTER);627 AssertPtrNullReturn(pcbRead, VERR_INVALID_POINTER);628 DEBUG_PRINT_FLOW();629 630 return RTVfsIoStrmReadAt(pFile->hVfsIos, off, pvBuf, cbToRead, true /*fBlocking*/, pcbRead);631 }632 633 634 /**635 * Opens the specified tar file for stream-like reading, returning a VD I/O636 * interface to it.637 *638 * @returns VBox status code.639 * @param pszFilename The path to the TAR file.640 * @param ppTarIo Where to return the VD I/O interface. This641 * shall be passed as pvUser when using the642 * interface.643 *644 * Pass to fssRdOnlyDestroyInterface for cleaning645 * up!646 */647 int fssRdOnlyCreateInterfaceForTarFile(const char *pszFilename, PFSSRDONLYINTERFACEIO *ppTarIo)648 {649 /*650 * Open the tar file first.651 */652 RTVFSFILE hVfsFile;653 int rc = RTVfsFileOpenNormal(pszFilename, RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN, &hVfsFile);654 if (RT_SUCCESS(rc))655 {656 RTVFSIOSTREAM hVfsIos = RTVfsFileToIoStream(hVfsFile);657 RTVFSFSSTREAM hVfsFss;658 rc = RTZipTarFsStreamFromIoStream(hVfsIos, 0 /*fFlags*/, &hVfsFss);659 if (RT_SUCCESS(rc))660 {661 /*662 * Allocate and init a callback + instance data structure.663 */664 PFSSRDONLYINTERFACEIO pThis = (PFSSRDONLYINTERFACEIO)RTMemAllocZ(sizeof(*pThis));665 if (pThis)666 {667 RTVfsIoStrmRelease(hVfsIos);668 RTVfsFileRelease(hVfsFile);669 670 pThis->CoreIo.pfnOpen = fssRdOnly_Open;671 pThis->CoreIo.pfnClose = fssRdOnly_Close;672 pThis->CoreIo.pfnDelete = notImpl_Delete;673 pThis->CoreIo.pfnMove = notImpl_Move;674 pThis->CoreIo.pfnGetFreeSpace = notImpl_GetFreeSpace;675 pThis->CoreIo.pfnGetModificationTime = notImpl_GetModificationTime;676 pThis->CoreIo.pfnGetSize = fssRdOnly_GetSize;677 pThis->CoreIo.pfnSetSize = notImpl_SetSize;678 pThis->CoreIo.pfnReadSync = fssRdOnly_ReadSync;679 pThis->CoreIo.pfnWriteSync = notImpl_WriteSync;680 pThis->CoreIo.pfnFlushSync = notImpl_FlushSync;681 682 pThis->hVfsFss = hVfsFss;683 pThis->fEndOfFss = false;684 pThis->hVfsCurObj = NIL_RTVFSOBJ;685 pThis->pszCurName = NULL;686 pThis->enmCurType = RTVFSOBJTYPE_INVALID;687 688 *ppTarIo = pThis;689 return VINF_SUCCESS;690 }691 RTVfsFsStrmRelease(hVfsFss);692 }693 RTVfsIoStrmRelease(hVfsIos);694 RTVfsFileRelease(hVfsFile);695 }696 697 *ppTarIo = NULL;698 return rc;699 }700 701 /**702 * Destroys a read-only FSS interface.703 *704 * @param pFssIo What TarFssCreateReadOnlyInterfaceForFile705 * returned.706 */707 void fssRdOnlyDestroyInterface(PFSSRDONLYINTERFACEIO pFssIo)708 {709 AssertPtr(pFssIo); AssertPtr(pFssIo->hVfsFss);710 711 RTVfsFsStrmRelease(pFssIo->hVfsFss);712 pFssIo->hVfsFss = NIL_RTVFSFSSTREAM;713 714 RTVfsObjRelease(pFssIo->hVfsCurObj);715 pFssIo->hVfsCurObj = NIL_RTVFSOBJ;716 717 RTStrFree(pFssIo->pszCurName);718 pFssIo->pszCurName = NULL;719 720 RTMemFree(pFssIo);721 }722 723 724 /**725 * Returns the read-only name of the current stream object.726 *727 * @returns VBox status code.728 * @param pFssIo What TarFssCreateReadOnlyInterfaceForFile729 * returned.730 * @param ppszName Where to return the filename. DO NOT FREE!731 */732 int fssRdOnlyGetCurrentName(PFSSRDONLYINTERFACEIO pFssIo, const char **ppszName)733 {734 AssertPtr(pFssIo); AssertPtr(pFssIo->hVfsFss);735 736 if (pFssIo->hVfsCurObj == NIL_RTVFSOBJ)737 {738 if (pFssIo->fEndOfFss)739 return VERR_EOF;740 int rc = RTVfsFsStrmNext(pFssIo->hVfsFss, &pFssIo->pszCurName, &pFssIo->enmCurType, &pFssIo->hVfsCurObj);741 if (RT_FAILURE(rc))742 {743 pFssIo->fEndOfFss = rc == VERR_EOF;744 *ppszName = NULL;745 return rc;746 }747 }748 749 *ppszName = pFssIo->pszCurName;750 return VINF_SUCCESS;751 }752 753 /**754 * Checks if the current file w/o path is equal to the given one.755 *756 * @returns true / false.757 * @param pFssIo What TarFssCreateReadOnlyInterfaceForFile758 * returned.759 * @param rstrFilename The filename to compare with.760 */761 bool fssRdOnlyEqualsCurrentFilename(PFSSRDONLYINTERFACEIO pFssIo, com::Utf8Str const &rstrFilename)762 {763 const char *pszName;764 int rc = fssRdOnlyGetCurrentName(pFssIo, &pszName);765 if (RT_SUCCESS(rc))766 {767 pszName = RTPathFilenameEx(pszName, RTPATH_STR_F_STYLE_DOS);768 return strcmp(pszName, rstrFilename.c_str()) == 0;769 }770 return false;771 }772 773 774 /**775 * Calls RTVfsMemorizeIoStreamAsFile on the current VFS object (ensuring there776 * is one first).777 *778 * @returns VBox status code.779 * @param pFssIo What TarFssCreateReadOnlyInterfaceForFile780 * returned.781 * @param phVfsFile Where to return the VFS file object.782 */783 int fssRdOnlyMemorizeCurrentAsFile(PFSSRDONLYINTERFACEIO pFssIo, PRTVFSFILE phVfsFile)784 {785 AssertPtr(pFssIo); AssertPtr(pFssIo->hVfsFss);786 787 if (pFssIo->hVfsCurObj == NIL_RTVFSOBJ)788 {789 if (pFssIo->fEndOfFss)790 return VERR_EOF;791 int rc = RTVfsFsStrmNext(pFssIo->hVfsFss, &pFssIo->pszCurName, &pFssIo->enmCurType, &pFssIo->hVfsCurObj);792 if (RT_FAILURE(rc))793 {794 pFssIo->fEndOfFss = rc == VERR_EOF;795 *phVfsFile = NIL_RTVFSFILE;796 return rc;797 }798 }799 800 RTVFSIOSTREAM hVfsIoStrm = RTVfsObjToIoStream(pFssIo->hVfsCurObj);801 int rc = RTVfsMemorizeIoStreamAsFile(hVfsIoStrm, RTFILE_O_READ, phVfsFile);802 RTVfsIoStrmRelease(hVfsIoStrm);803 804 if (RT_SUCCESS(rc))805 rc = fssRdOnlySkipCurrent(pFssIo);806 return rc;807 }808 809 810 /**811 * Skips the current object.812 *813 * @returns VBox status code.814 * @param pFssIo What TarFssCreateReadOnlyInterfaceForFile815 * returned.816 */817 int fssRdOnlySkipCurrent(PFSSRDONLYINTERFACEIO pFssIo)818 {819 AssertPtr(pFssIo); AssertPtr(pFssIo->hVfsFss);820 821 if (pFssIo->hVfsCurObj == NIL_RTVFSOBJ)822 {823 if (pFssIo->fEndOfFss)824 return VERR_EOF;825 int rc = RTVfsFsStrmNext(pFssIo->hVfsFss, &pFssIo->pszCurName, &pFssIo->enmCurType, &pFssIo->hVfsCurObj);826 if (RT_FAILURE(rc))827 {828 pFssIo->fEndOfFss = rc == VERR_EOF;829 return rc;830 }831 }832 833 /* Force a RTVfsFsStrmNext call the next time around. */834 RTVfsObjRelease(pFssIo->hVfsCurObj);835 pFssIo->hVfsCurObj = NIL_RTVFSOBJ;836 837 RTStrFree(pFssIo->pszCurName);838 pFssIo->pszCurName = NULL;839 840 return VINF_SUCCESS;841 }842 843 844 /**845 * Checks if the current file is a directory.846 *847 * @returns true if directory, false if not (or error).848 * @param pFssIo What TarFssCreateReadOnlyInterfaceForFile849 * returned.850 */851 bool fssRdOnlyIsCurrentDirectory(PFSSRDONLYINTERFACEIO pFssIo)852 {853 AssertPtr(pFssIo); AssertPtr(pFssIo->hVfsFss);854 855 if (pFssIo->hVfsCurObj == NIL_RTVFSOBJ)856 {857 if (pFssIo->fEndOfFss)858 return false;859 int rc = RTVfsFsStrmNext(pFssIo->hVfsFss, &pFssIo->pszCurName, &pFssIo->enmCurType, &pFssIo->hVfsCurObj);860 if (RT_FAILURE(rc))861 {862 pFssIo->fEndOfFss = rc == VERR_EOF;863 return false;864 }865 }866 867 return pFssIo->enmCurType == RTVFSOBJTYPE_DIR;868 }869 870 871 473 872 474 /** @} */ … … 1627 1229 } 1628 1230 1629 int readFileIntoBuffer(const char *pcszFilename, void **ppvBuf, size_t *pcbSize, PVDINTERFACEIO pIfIo, void *pvUser)1630 {1631 /* Validate input. */1632 AssertPtrReturn(ppvBuf, VERR_INVALID_POINTER);1633 AssertPtrReturn(pcbSize, VERR_INVALID_POINTER);1634 AssertPtrReturn(pIfIo, VERR_INVALID_POINTER);1635 1636 void *pvStorage;1637 int rc = pIfIo->pfnOpen(pvUser, pcszFilename,1638 RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE, 0,1639 &pvStorage);1640 if (RT_FAILURE(rc))1641 return rc;1642 1643 void *pvTmpBuf = 0;1644 void *pvBuf = 0;1645 uint64_t cbTmpSize = _1M;1646 size_t cbAllRead = 0;1647 do1648 {1649 pvTmpBuf = RTMemAlloc(cbTmpSize);1650 if (!pvTmpBuf)1651 {1652 rc = VERR_NO_MEMORY;1653 break;1654 }1655 1656 for (;;)1657 {1658 size_t cbRead = 0;1659 rc = pIfIo->pfnReadSync(pvUser, pvStorage, cbAllRead, pvTmpBuf, cbTmpSize, &cbRead);1660 if ( RT_FAILURE(rc)1661 || cbRead == 0)1662 break;1663 pvBuf = RTMemRealloc(pvBuf, cbAllRead + cbRead);1664 if (!pvBuf)1665 {1666 rc = VERR_NO_MEMORY;1667 break;1668 }1669 memcpy(&((char*)pvBuf)[cbAllRead], pvTmpBuf, cbRead);1670 cbAllRead += cbRead;1671 }1672 } while (0);1673 1674 pIfIo->pfnClose(pvUser, pvStorage);1675 1676 if (rc == VERR_EOF)1677 rc = VINF_SUCCESS;1678 1679 if (pvTmpBuf)1680 RTMemFree(pvTmpBuf);1681 1682 if (RT_SUCCESS(rc))1683 {1684 *ppvBuf = pvBuf;1685 *pcbSize = cbAllRead;1686 }1687 else1688 {1689 if (pvBuf)1690 RTMemFree(pvBuf);1691 }1692 1693 return rc;1694 }1695 1696 1231 int writeBufferToFile(const char *pcszFilename, void *pvBuf, size_t cbSize, PVDINTERFACEIO pIfIo, void *pvUser) 1697 1232 { … … 1726 1261 } 1727 1262 1728 int decompressImageAndSave(const char *pcszFullFilenameIn, const char *pcszFullFilenameOut, PVDINTERFACEIO pIfIo, void *pvUser)1729 {1730 /* Validate input. */1731 AssertPtrReturn(pIfIo, VERR_INVALID_POINTER);1732 1733 PSHASTORAGE pShaStorage = (PSHASTORAGE)pvUser;1734 /*1735 * Open the source file.1736 */1737 void *pvStorage;1738 int rc = pIfIo->pfnOpen(pvUser, pcszFullFilenameIn,1739 RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE, 0,1740 &pvStorage);1741 if (RT_FAILURE(rc))1742 return rc;1743 1744 /* Turn the source file handle/whatever into a VFS stream. */1745 RTVFSIOSTREAM hVfsIosCompressedSrc;1746 1747 rc = VDIfCreateVfsStream(pIfIo, pvStorage, RTFILE_O_READ, &hVfsIosCompressedSrc);1748 if (RT_SUCCESS(rc))1749 {1750 /* Pass the source thru gunzip. */1751 RTVFSIOSTREAM hVfsIosSrc;1752 rc = RTZipGzipDecompressIoStream(hVfsIosCompressedSrc, 0, &hVfsIosSrc);1753 if (RT_SUCCESS(rc))1754 {1755 /*1756 * Create the output file, including necessary paths.1757 * Any existing file will be overwritten.1758 */1759 rc = VirtualBox::i_ensureFilePathExists(Utf8Str(pcszFullFilenameOut), true /*fCreate*/);1760 if (RT_SUCCESS(rc))1761 {1762 RTVFSIOSTREAM hVfsIosDst;1763 rc = RTVfsIoStrmOpenNormal(pcszFullFilenameOut,1764 RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_ALL,1765 &hVfsIosDst);1766 if (RT_SUCCESS(rc))1767 {1768 /*1769 * Pump the bytes thru. If we fail, delete the output file.1770 */1771 RTMANIFEST hFileManifest = NIL_RTMANIFEST;1772 rc = RTManifestCreate(0 /*fFlags*/, &hFileManifest);1773 if (RT_SUCCESS(rc))1774 {1775 RTVFSIOSTREAM hVfsIosMfst;1776 1777 uint32_t digestType = (pShaStorage->fSha256 == true) ? RTMANIFEST_ATTR_SHA256: RTMANIFEST_ATTR_SHA1;1778 1779 rc = RTManifestEntryAddPassthruIoStream(hFileManifest,1780 hVfsIosSrc,1781 "ovf import",1782 digestType,1783 true /*read*/, &hVfsIosMfst);1784 if (RT_SUCCESS(rc))1785 {1786 rc = RTVfsUtilPumpIoStreams(hVfsIosMfst, hVfsIosDst, 0);1787 }1788 1789 RTVfsIoStrmRelease(hVfsIosMfst);1790 }1791 1792 RTVfsIoStrmRelease(hVfsIosDst);1793 }1794 }1795 1796 RTVfsIoStrmRelease(hVfsIosSrc);1797 }1798 }1799 pIfIo->pfnClose(pvUser, pvStorage);1800 1801 return rc;1802 }1803 1804 int copyFileAndCalcShaDigest(const char *pcszSourceFilename, const char *pcszTargetFilename, PVDINTERFACEIO pIfIo, void *pvUser)1805 {1806 /* Validate input. */1807 AssertPtrReturn(pIfIo, VERR_INVALID_POINTER);1808 1809 PSHASTORAGE pShaStorage = (PSHASTORAGE)pvUser;1810 void *pvStorage;1811 1812 int rc = pIfIo->pfnOpen(pvUser, pcszSourceFilename,1813 RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE, 0,1814 &pvStorage);1815 if (RT_FAILURE(rc))1816 return rc;1817 1818 /* Turn the source file handle/whatever into a VFS stream. */1819 RTVFSIOSTREAM hVfsIosSrc;1820 1821 rc = VDIfCreateVfsStream(pIfIo, pvStorage, RTFILE_O_READ, &hVfsIosSrc);1822 if (RT_SUCCESS(rc))1823 {1824 /*1825 * Create the output file, including necessary paths.1826 * Any existing file will be overwritten.1827 */1828 rc = VirtualBox::i_ensureFilePathExists(Utf8Str(pcszTargetFilename), true /*fCreate*/);1829 if (RT_SUCCESS(rc))1830 {1831 RTVFSIOSTREAM hVfsIosDst;1832 rc = RTVfsIoStrmOpenNormal(pcszTargetFilename,1833 RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_ALL,1834 &hVfsIosDst);1835 if (RT_SUCCESS(rc))1836 {1837 /*1838 * Pump the bytes thru. If we fail, delete the output file.1839 */1840 RTMANIFEST hFileManifest = NIL_RTMANIFEST;1841 rc = RTManifestCreate(0 /*fFlags*/, &hFileManifest);1842 if (RT_SUCCESS(rc))1843 {1844 RTVFSIOSTREAM hVfsIosMfst;1845 1846 uint32_t digestType = (pShaStorage->fSha256 == true) ? RTMANIFEST_ATTR_SHA256: RTMANIFEST_ATTR_SHA1;1847 1848 rc = RTManifestEntryAddPassthruIoStream(hFileManifest,1849 hVfsIosSrc,1850 "ovf import",1851 digestType,1852 true /*read*/, &hVfsIosMfst);1853 if (RT_SUCCESS(rc))1854 {1855 rc = RTVfsUtilPumpIoStreams(hVfsIosMfst, hVfsIosDst, 0);1856 }1857 1858 RTVfsIoStrmRelease(hVfsIosMfst);1859 }1860 1861 RTVfsIoStrmRelease(hVfsIosDst);1862 }1863 }1864 1865 RTVfsIoStrmRelease(hVfsIosSrc);1866 1867 }1868 1869 pIfIo->pfnClose(pvUser, pvStorage);1870 return rc;1871 }
Note:
See TracChangeset
for help on using the changeset viewer.