VirtualBox

Changeset 47963 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Aug 21, 2013 10:59:34 AM (11 years ago)
Author:
vboxsync
Message:

pr6022. Additional checks during OVA/OVF import. Deleting temporary files. Using small memory buffer for copying ISO images with simultaneously calculating SHA digest.

Location:
trunk/src/VBox/Main
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/ApplianceImplPrivate.h

    r47516 r47963  
    244244int ShaWriteBuf(const char *pcszFilename, void *pvBuf, size_t cbSize, PVDINTERFACEIO pIfIo, void *pvUser);
    245245int decompressImageAndSave(const char *pcszFullFilenameIn, const char *pcszFullFilenameOut, PVDINTERFACEIO pIfIo, void *pvUser);
     246int copyFileAndCalcShaDigest(const char *pcszSourceFilename, const char *pcszTargetFilename, PVDINTERFACEIO pIfIo, void *pvUser);
    246247#endif // !____H_APPLIANCEIMPLPRIVATE
    247248
  • trunk/src/VBox/Main/src-server/ApplianceImplIO.cpp

    r47716 r47963  
    10981098
    10991099    size_t cbAllRead = 0;
     1100    size_t cbAvail = 0;
    11001101    for (;;)
    11011102    {
     
    11031104        if (cbAllRead == cbRead)
    11041105            break;
    1105         size_t cbAvail = RTCircBufUsed(pInt->pCircBuf);
     1106
     1107        cbAvail = RTCircBufUsed(pInt->pCircBuf);
     1108
    11061109        if (    cbAvail == 0
    11071110            &&  pInt->fEOF
    11081111            && !RTCircBufIsWriting(pInt->pCircBuf))
    11091112        {
     1113            rc = VINF_EOF;
    11101114            break;
    11111115        }
     1116
    11121117        /* If there isn't enough data make sure the worker thread is fetching
    11131118         * more. */
     
    11501155    /* Signal the thread to read more data in the mean time. */
    11511156    if (   RT_SUCCESS(rc)
     1157        && rc != VINF_EOF
    11521158        && RTCircBufFree(pInt->pCircBuf) >= (RTCircBufSize(pInt->pCircBuf) / 2))
    11531159        rc = shaSignalManifestThread(pInt, STATUS_READ);
     
    14161422}
    14171423
    1418 
     1424int copyFileAndCalcShaDigest(const char *pcszSourceFilename, const char *pcszTargetFilename, PVDINTERFACEIO pIfIo, void *pvUser)
     1425{
     1426    /* Validate input. */
     1427    AssertPtrReturn(pIfIo, VERR_INVALID_POINTER);
     1428 
     1429    PSHASTORAGE pShaStorage = (PSHASTORAGE)pvUser;
     1430    void *pvStorage;
     1431
     1432    int rc = pIfIo->pfnOpen(pvUser, pcszSourceFilename,
     1433                            RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE, 0,
     1434                            &pvStorage);
     1435    if (RT_FAILURE(rc))
     1436        return rc;
     1437
     1438    /* Turn the source file handle/whatever into a VFS stream. */
     1439    RTVFSIOSTREAM hVfsIosSrc;
     1440
     1441    rc = VDIfCreateVfsStream(pIfIo, pvStorage, RTFILE_O_READ, &hVfsIosSrc);
     1442    if (RT_SUCCESS(rc))
     1443    {
     1444        /*
     1445         * Create the output file, including necessary paths.
     1446         * Any existing file will be overwritten.
     1447         */
     1448        rc = VirtualBox::ensureFilePathExists(Utf8Str(pcszTargetFilename), true /*fCreate*/);
     1449        if (RT_SUCCESS(rc))
     1450        {
     1451            RTVFSIOSTREAM hVfsIosDst;
     1452            rc = RTVfsIoStrmOpenNormal(pcszTargetFilename,
     1453                                       RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_ALL,
     1454                                       &hVfsIosDst);
     1455            if (RT_SUCCESS(rc))
     1456            {
     1457                /*
     1458                 * Pump the bytes thru. If we fail, delete the output file.
     1459                 */
     1460                RTMANIFEST hFileManifest = NIL_RTMANIFEST;
     1461                rc = RTManifestCreate(0 /*fFlags*/, &hFileManifest);
     1462                if (RT_SUCCESS(rc))
     1463                {
     1464                    RTVFSIOSTREAM hVfsIosMfst;
     1465
     1466                    uint32_t digestType = (pShaStorage->fSha256 == true) ? RTMANIFEST_ATTR_SHA256: RTMANIFEST_ATTR_SHA1;
     1467
     1468                    rc = RTManifestEntryAddPassthruIoStream(hFileManifest,
     1469                                                            hVfsIosSrc,
     1470                                                            "ovf import",
     1471                                                            digestType,
     1472                                                            true /*read*/, &hVfsIosMfst);
     1473                    if (RT_SUCCESS(rc))
     1474                    {
     1475                        rc = RTVfsUtilPumpIoStreams(hVfsIosMfst, hVfsIosDst, 0);
     1476                    }
     1477
     1478                    RTVfsIoStrmRelease(hVfsIosMfst);
     1479                }
     1480
     1481                RTVfsIoStrmRelease(hVfsIosDst);
     1482            }
     1483        }
     1484
     1485        RTVfsIoStrmRelease(hVfsIosSrc);
     1486
     1487    }
     1488
     1489    pIfIo->pfnClose(pvUser, pvStorage);
     1490    return rc;
     1491}
  • trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp

    r47716 r47963  
    10081008                    vrc = RTManifestVerifyDigestType(pBuf, cbRead, &digestType);
    10091009
     1010                    if (pBuf)
     1011                        RTMemFree(pBuf);
     1012
    10101013                    if (RT_FAILURE(vrc))
    10111014                    {
    1012                         if (pBuf)
    1013                             RTMemFree(pBuf);
    10141015                        throw setError(VBOX_E_FILE_ERROR,
    10151016                               tr("Could not verify supported digest types in the manifest file '%s' (%Rrc)"),
     
    15681569
    15691570            size_t cbCertSize = 0;
    1570             Utf8Str manifestShaDigest;
     1571
     1572            /* Save the SHA digest of the manifest file for the next validation */
     1573            Utf8Str manifestShaDigest = storage.strDigest;
     1574
    15711575            Utf8Str strCertFile = Utf8Str(pTask->locInfo.strPath).stripExt().append(".cert");
    15721576            if (RTFileExists(strCertFile.c_str()))
     
    15741578                rc = readFileToBuf(strCertFile, &pvCertBuf, &cbCertSize, false, pShaIo, &storage);
    15751579                if (FAILED(rc)) throw rc;
    1576 
    1577                 /* Save the SHA digest of the manifest file for the next validation */
    1578                 manifestShaDigest = storage.strDigest;
    15791580
    15801581                /* verify Certificate */
     
    22762277    else
    22772278    {
     2279        bool fGzipUsed = !(di.strCompression.compare("gzip",Utf8Str::CaseInsensitive));
    22782280        /* check read file to GZIP compression */
    22792281        try
    22802282        {
    2281             if (di.strCompression.compare("gzip",Utf8Str::CaseInsensitive) == 0)
     2283            if (fGzipUsed == true)
    22822284            {
    22832285                /*
    2284                  * 1. extract a file to the local/temporary folder
    2285                  * 2. apply GZIP decompression for the file
    2286                  * 3. replace the value of strSrcFilePath with a new path to the file
    2287                  * 4. replace SHA-TAR I/O interface with File I/O interface
    2288                  * 5. save calculated SHA digest of GZIPed file for later validation
    2289                  */
     2286                 * Create the necessary file access interfaces.
     2287                 * For the next step:
     2288                 * We need to replace the previously created chain of SHA-TAR or SHA-FILE interfaces
     2289                 * with simple FILE interface because we don't need SHA or TAR interfaces here anymore.
     2290                 * But we mustn't delete the chain of SHA-TAR or SHA-FILE interfaces.
     2291                 */ 
    22902292
    22912293                /* Decompress the GZIP file and save a new file in the target path */
     
    23082310
    23092311                /* Create the necessary file access interfaces. */
    2310 
    23112312                pFileIo = FileCreateInterface();
    23122313                if (!pFileIo)
     
    23222323                                   tr("Creation of the VD interface failed (%Rrc)"), vrc);
    23232324
     2325                /* Correct the source and the target with the actual values */
    23242326                strSrcFilePath = strTargetDir;
    23252327                strTargetDir = strTargetDir.stripFilename();
     
    23332335            Utf8Str strTrgFormat = "VMDK";
    23342336            ULONG lCabs = 0;
     2337            char *pszExt = NULL;
    23352338
    23362339            if (RTPathHaveExt(strTargetPath->c_str()))
    23372340            {
    2338                 char *pszExt = RTPathExt(strTargetPath->c_str());
     2341                pszExt = RTPathExt(strTargetPath->c_str());
    23392342                /* Figure out which format the user like to have. Default is VMDK. */
    23402343                ComObjPtr<MediumFormat> trgFormat = pSysProps->mediumFormatFromExtension(&pszExt[1]);
     
    23662369                strTrgFormat = Utf8Str(bstrFormatName);
    23672370            }
     2371            else
     2372            {
     2373                throw setError(VBOX_E_FILE_ERROR,
     2374                               tr("The target disk '%s' has no extension "),
     2375                               strTargetPath->c_str(), VERR_INVALID_NAME);
     2376            }
    23682377
    23692378            /* Create an IMedium object. */
     
    23772386                try
    23782387                {
    2379                     /* Read the ISO file into a memory buffer */
    2380                     vrc = ShaReadBuf(strSrcFilePath.c_str(), &pvTmpBuf, &cbSize, pCallbacks, pRealUsedStorage);
    2381 
    2382                     if ( RT_FAILURE(vrc) || !pvTmpBuf)
    2383                         throw setError(VBOX_E_FILE_ERROR,
    2384                                        tr("Could not read ISO file '%s' listed in the OVF file (%Rrc)"),
    2385                                        RTPathFilename(strSourceOVF.c_str()), vrc);
    2386 
    2387                     if (RTFileExists(strTargetPath->c_str()) == false)
     2388                    if (fGzipUsed == true)
    23882389                    {
    2389 
    2390                         /* ensure the directory exists */
    2391                         if (lCabs & MediumFormatCapabilities_File)
    2392                         {
    2393                             rc = VirtualBox::ensureFilePathExists(*strTargetPath, true);
    2394                             if (FAILED(rc))
    2395                                 throw rc;
    2396                         }
    2397 
    2398                         // create a new file and copy raw data into one from buffer pvTmpBuf
    2399                         RTFILE pFile = NULL;
    2400                         vrc = RTFileOpen(&pFile,
    2401                                          strTargetPath->c_str(),
    2402                                          RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
    2403 
    2404                         if (RT_SUCCESS(vrc) && pFile != NULL)
    2405                         {
    2406                             size_t cbWritten = 0;
    2407 
    2408                             vrc = RTFileWrite(pFile, pvTmpBuf, cbSize, &cbWritten);
    2409 
    2410                             if (RT_FAILURE(vrc))
    2411                             {
    2412                                 Utf8Str path(*strTargetPath);
    2413                                 path = path.stripFilename();
    2414 
    2415                                 throw setError(VBOX_E_FILE_ERROR,
    2416                                                tr("Could not write the ISO file '%s' into the folder %s (%Rrc)"),
    2417                                                strSrcFilePath.stripPath().c_str(),
    2418                                                path.c_str(),
    2419                                                vrc);
    2420                             }
    2421                         }
    2422                         RTFileClose(pFile);
     2390                        /* 
     2391                         * The source and target pathes are the same. 
     2392                         * It means that we have the needed file already.
     2393                         * For example, in GZIP case, we decompress the file and save it in the target path, 
     2394                         * but with some prefix like "temp_". See part "check read file to GZIP compression" earlier 
     2395                         * in this function.
     2396                         * Just rename the file by deleting "temp_" from it's name 
     2397                         */
     2398                        vrc = RTFileRename(strSrcFilePath.c_str(), strTargetPath->c_str(), RTPATHRENAME_FLAGS_NO_REPLACE);
     2399                        if (RT_FAILURE(vrc))
     2400                            throw setError(VBOX_E_FILE_ERROR,
     2401                                           tr("Could not rename the file '%s' (%Rrc)"),
     2402                                           RTPathFilename(strSourceOVF.c_str()), vrc);
    24232403                    }
     2404                    else
     2405                    {
     2406                        /* Calculating SHA digest for ISO file while copying one */
     2407                        vrc = copyFileAndCalcShaDigest(strSrcFilePath.c_str(), 
     2408                                                        strTargetPath->c_str(), 
     2409                                                       pCallbacks, 
     2410                                                       pRealUsedStorage);
     2411
     2412                        if (RT_FAILURE(vrc))
     2413                            throw setError(VBOX_E_FILE_ERROR,
     2414                                           tr("Could not copy ISO file '%s' listed in the OVF file (%Rrc)"),
     2415                                           RTPathFilename(strSourceOVF.c_str()), vrc);
     2416                    }
    24242417                }
    24252418                catch (HRESULT arc)
     
    25012494                    if (FAILED(rc)) throw rc;
    25022495
     2496
     2497
    25032498                    /* Advance to the next operation. */
    25042499                    /* operation's weight, as set up with the IProgress originally */
     
    25122507                ComPtr<IProgress> pp(pProgress);
    25132508                waitForAsyncProgress(stack.pProgress, pp);
     2509
     2510                if (fGzipUsed == true)
     2511                {
     2512                    /* 
     2513                     * Just delete the temporary file
     2514                     */
     2515                    vrc = RTFileDelete(strSrcFilePath.c_str());
     2516                    if (RT_FAILURE(vrc))
     2517                        setWarning(VBOX_E_FILE_ERROR,
     2518                                   tr("Could not delete the file '%s' (%Rrc)"),
     2519                                   RTPathFilename(strSrcFilePath.c_str()), vrc);
     2520                }
    25142521            }
    25152522        }
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