Changeset 47963 in vbox for trunk/src/VBox
- Timestamp:
- Aug 21, 2013 10:59:34 AM (11 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/ApplianceImplPrivate.h
r47516 r47963 244 244 int ShaWriteBuf(const char *pcszFilename, void *pvBuf, size_t cbSize, PVDINTERFACEIO pIfIo, void *pvUser); 245 245 int decompressImageAndSave(const char *pcszFullFilenameIn, const char *pcszFullFilenameOut, PVDINTERFACEIO pIfIo, void *pvUser); 246 int copyFileAndCalcShaDigest(const char *pcszSourceFilename, const char *pcszTargetFilename, PVDINTERFACEIO pIfIo, void *pvUser); 246 247 #endif // !____H_APPLIANCEIMPLPRIVATE 247 248 -
trunk/src/VBox/Main/src-server/ApplianceImplIO.cpp
r47716 r47963 1098 1098 1099 1099 size_t cbAllRead = 0; 1100 size_t cbAvail = 0; 1100 1101 for (;;) 1101 1102 { … … 1103 1104 if (cbAllRead == cbRead) 1104 1105 break; 1105 size_t cbAvail = RTCircBufUsed(pInt->pCircBuf); 1106 1107 cbAvail = RTCircBufUsed(pInt->pCircBuf); 1108 1106 1109 if ( cbAvail == 0 1107 1110 && pInt->fEOF 1108 1111 && !RTCircBufIsWriting(pInt->pCircBuf)) 1109 1112 { 1113 rc = VINF_EOF; 1110 1114 break; 1111 1115 } 1116 1112 1117 /* If there isn't enough data make sure the worker thread is fetching 1113 1118 * more. */ … … 1150 1155 /* Signal the thread to read more data in the mean time. */ 1151 1156 if ( RT_SUCCESS(rc) 1157 && rc != VINF_EOF 1152 1158 && RTCircBufFree(pInt->pCircBuf) >= (RTCircBufSize(pInt->pCircBuf) / 2)) 1153 1159 rc = shaSignalManifestThread(pInt, STATUS_READ); … … 1416 1422 } 1417 1423 1418 1424 int 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 1008 1008 vrc = RTManifestVerifyDigestType(pBuf, cbRead, &digestType); 1009 1009 1010 if (pBuf) 1011 RTMemFree(pBuf); 1012 1010 1013 if (RT_FAILURE(vrc)) 1011 1014 { 1012 if (pBuf)1013 RTMemFree(pBuf);1014 1015 throw setError(VBOX_E_FILE_ERROR, 1015 1016 tr("Could not verify supported digest types in the manifest file '%s' (%Rrc)"), … … 1568 1569 1569 1570 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 1571 1575 Utf8Str strCertFile = Utf8Str(pTask->locInfo.strPath).stripExt().append(".cert"); 1572 1576 if (RTFileExists(strCertFile.c_str())) … … 1574 1578 rc = readFileToBuf(strCertFile, &pvCertBuf, &cbCertSize, false, pShaIo, &storage); 1575 1579 if (FAILED(rc)) throw rc; 1576 1577 /* Save the SHA digest of the manifest file for the next validation */1578 manifestShaDigest = storage.strDigest;1579 1580 1580 1581 /* verify Certificate */ … … 2276 2277 else 2277 2278 { 2279 bool fGzipUsed = !(di.strCompression.compare("gzip",Utf8Str::CaseInsensitive)); 2278 2280 /* check read file to GZIP compression */ 2279 2281 try 2280 2282 { 2281 if ( di.strCompression.compare("gzip",Utf8Str::CaseInsensitive) == 0)2283 if (fGzipUsed == true) 2282 2284 { 2283 2285 /* 2284 * 1. extract a file to the local/temporary folder2285 * 2. apply GZIP decompression for the file2286 * 3. replace the value of strSrcFilePath with a new path to the file2287 * 4. replace SHA-TAR I/O interface with File I/O interface2288 * 5. save calculated SHA digest of GZIPed file for later validation2289 */ 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 */ 2290 2292 2291 2293 /* Decompress the GZIP file and save a new file in the target path */ … … 2308 2310 2309 2311 /* Create the necessary file access interfaces. */ 2310 2311 2312 pFileIo = FileCreateInterface(); 2312 2313 if (!pFileIo) … … 2322 2323 tr("Creation of the VD interface failed (%Rrc)"), vrc); 2323 2324 2325 /* Correct the source and the target with the actual values */ 2324 2326 strSrcFilePath = strTargetDir; 2325 2327 strTargetDir = strTargetDir.stripFilename(); … … 2333 2335 Utf8Str strTrgFormat = "VMDK"; 2334 2336 ULONG lCabs = 0; 2337 char *pszExt = NULL; 2335 2338 2336 2339 if (RTPathHaveExt(strTargetPath->c_str())) 2337 2340 { 2338 char *pszExt = RTPathExt(strTargetPath->c_str());2341 pszExt = RTPathExt(strTargetPath->c_str()); 2339 2342 /* Figure out which format the user like to have. Default is VMDK. */ 2340 2343 ComObjPtr<MediumFormat> trgFormat = pSysProps->mediumFormatFromExtension(&pszExt[1]); … … 2366 2369 strTrgFormat = Utf8Str(bstrFormatName); 2367 2370 } 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 } 2368 2377 2369 2378 /* Create an IMedium object. */ … … 2377 2386 try 2378 2387 { 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) 2388 2389 { 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); 2423 2403 } 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 } 2424 2417 } 2425 2418 catch (HRESULT arc) … … 2501 2494 if (FAILED(rc)) throw rc; 2502 2495 2496 2497 2503 2498 /* Advance to the next operation. */ 2504 2499 /* operation's weight, as set up with the IProgress originally */ … … 2512 2507 ComPtr<IProgress> pp(pProgress); 2513 2508 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 } 2514 2521 } 2515 2522 }
Note:
See TracChangeset
for help on using the changeset viewer.