VirtualBox

Ignore:
Timestamp:
Feb 10, 2016 12:51:35 AM (9 years ago)
Author:
vboxsync
Message:

ApplianceImplImport.cpp,++: Pushed the IPRT VFS stuff futher down, only going to the VD I/O wrappers when start getting down into the media code during import. Reworked the OVA releated import code to skip files it doesn't care about (like message resource xml files which we don't implement) and not be picky about which order files the OVF, MF and CERT files come in (todo: make sure it isn't picky about the order of disks either). Read the manifest and certificate file during the read() method.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/ApplianceImplIO.cpp

    r59555 r59621  
    162162}
    163163
     164#if 0
    164165/** @interface_method_impl{VDINTERFACEIO,pfnSetSize}  */
    165166static DECLCALLBACK(int) notImpl_SetSize(void *pvUser, void *pvStorage, uint64_t cb)
     
    178179    return VERR_NOT_IMPLEMENTED;
    179180}
     181#endif
    180182
    181183/** @interface_method_impl{VDINTERFACEIO,pfnFlushSync}  */
     
    469471    return pCallbacks;
    470472}
    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 IOSRDONLYINTERNAL
    482 {
    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 FSSRDONLYINTERFACEIO
    495 {
    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/O
    636  * 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.  This
    641  *                              shall be passed as pvUser when using the
    642  *                              interface.
    643  *
    644  *                              Pass to fssRdOnlyDestroyInterface for cleaning
    645  *                              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 TarFssCreateReadOnlyInterfaceForFile
    705  *                              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 TarFssCreateReadOnlyInterfaceForFile
    729  *                              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 TarFssCreateReadOnlyInterfaceForFile
    758  *                              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 there
    776  * is one first).
    777  *
    778  * @returns VBox status code.
    779  * @param   pFssIo              What TarFssCreateReadOnlyInterfaceForFile
    780  *                              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 TarFssCreateReadOnlyInterfaceForFile
    815  *                              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 TarFssCreateReadOnlyInterfaceForFile
    849  *                              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 
    871473
    872474/** @} */
     
    16271229}
    16281230
    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     do
    1648     {
    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     else
    1688     {
    1689         if (pvBuf)
    1690             RTMemFree(pvBuf);
    1691     }
    1692 
    1693     return rc;
    1694 }
    1695 
    16961231int writeBufferToFile(const char *pcszFilename, void *pvBuf, size_t cbSize, PVDINTERFACEIO pIfIo, void *pvUser)
    16971232{
     
    17261261}
    17271262
    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.

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