Changeset 67184 in vbox
- Timestamp:
- May 31, 2017 8:32:04 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 115861
- Location:
- trunk/src/VBox/Main
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/Makefile.kmk
r67067 r67184 373 373 $(if $(VBOX_WITH_EHCI),VBOX_WITH_EHCI,) \ 374 374 $(if $(VBOX_WITH_NEW_USB_CODE_ON_DARWIN),VBOX_WITH_NEW_USB_CODE_ON_DARWIN,) 375 endif 376 if defined(VBOX_WITH_NEW_TAR_CREATOR) #|| "$(USERNAME)" == "bird" # temporary 377 VBoxSVC_DEFS += VBOX_WITH_NEW_TAR_CREATOR 375 378 endif 376 379 VBoxSVC_DEFS.win += VBOX_COM_OUTOFPROC_MODULE -
trunk/src/VBox/Main/include/ApplianceImpl.h
r67142 r67184 148 148 149 149 HRESULT i_findMediumFormatFromDiskImage(const ovf::DiskImage &di, ComObjPtr<MediumFormat>& mf); 150 151 RTVFSIOSTREAM i_manifestSetupDigestCalculationForGivenIoStream(RTVFSIOSTREAM hVfsIos, const char *pszManifestEntry, 152 bool fRead = true); 150 153 /** @} */ 151 154 … … 198 201 HRESULT i_preCheckImageAvailability(ImportStack &stack); 199 202 bool i_importEnsureOvaLookAhead(ImportStack &stack); 200 RTVFSIOSTREAM i_importSetupDigestCalculationForGivenIoStream(RTVFSIOSTREAM hVfsIos, const char *pszManifestEntry);201 203 RTVFSIOSTREAM i_importOpenSourceFile(ImportStack &stack, Utf8Str const &rstrSrcPath, const char *pszManifestEntry); 202 204 HRESULT i_importCreateAndWriteDestinationFile(Utf8Str const &rstrDstPath, … … 217 219 HRESULT i_writeFSOVF(TaskOVF *pTask, AutoWriteLockBase& writeLock); 218 220 HRESULT i_writeFSOVA(TaskOVF *pTask, AutoWriteLockBase& writeLock); 219 HRESULT i_writeFSImpl(TaskOVF *pTask, AutoWriteLockBase &writeLock, RTVFSFSSTREAM hVfsFss, 220 PVDINTERFACEIO pCallbacks, PSHASTORAGE pStorage); 221 #ifdef VBOX_WITH_NEW_TAR_CREATOR 222 HRESULT i_writeFSImpl(TaskOVF *pTask, AutoWriteLockBase &writeLock, RTVFSFSSTREAM hVfsFssDst); 223 HRESULT i_writeBufferToFile(RTVFSFSSTREAM hVfsFssDst, const char *pszFilename, const void *pvContent, size_t cbContent); 224 #else 225 HRESULT i_writeFSImpl(TaskOVF *pTask, AutoWriteLockBase &writeLock, PVDINTERFACEIO pCallbacks, PSHASTORAGE pStorage); 226 #endif 221 227 222 228 struct XMLStack; -
trunk/src/VBox/Main/include/ApplianceImplPrivate.h
r67142 r67184 19 19 #define ____H_APPLIANCEIMPLPRIVATE 20 20 21 #ifdef DEBUG_bird22 # define MAIN_WITH_NEW_TAR_CREATOR23 #endif24 21 25 22 class VirtualSystemDescription; … … 74 71 , hOurManifest(NIL_RTMANIFEST) 75 72 , fManifest(true) 73 #ifndef VBOX_WITH_NEW_TAR_CREATOR 76 74 , fSha256(false) 75 #endif 77 76 , fDeterminedDigestTypes(false) 78 77 , hTheirManifest(NIL_RTMANIFEST) … … 163 162 * @{ */ 164 163 bool fManifest; // Create a manifest file on export 164 #ifndef VBOX_WITH_NEW_TAR_CREATOR 165 165 bool fSha256; // true = SHA256 (OVF 2.0), false = SHA1 (OVF 1.0) 166 #endif 166 167 /** @} */ 167 168 -
trunk/src/VBox/Main/include/MediumImpl.h
r62810 r67184 207 207 MediumVariant_T aVariant, 208 208 SecretKeyStore *pKeyStore, 209 #ifdef VBOX_WITH_NEW_TAR_CREATOR 210 RTVFSIOSTREAM hVfsIosDst, 211 #else 209 212 PVDINTERFACEIO aVDImageIOIf, void *aVDImageIOUser, 213 #endif 210 214 const ComObjPtr<Progress> &aProgress); 211 215 HRESULT i_importFile(const char *aFilename, -
trunk/src/VBox/Main/src-server/ApplianceImpl.cpp
r65186 r67184 872 872 873 873 /** 874 * Setup automatic I/O stream digest calculation, adding it to hOurManifest. 875 * 876 * @returns Passthru I/O stream, of @a hVfsIos if no digest calc needed. 877 * @param hVfsIos The stream to wrap. Always consumed. 878 * @param pszManifestEntry The manifest entry. 879 * @param fRead Set if read stream, clear if write. 880 * @throws Nothing. 881 */ 882 RTVFSIOSTREAM Appliance::i_manifestSetupDigestCalculationForGivenIoStream(RTVFSIOSTREAM hVfsIos, const char *pszManifestEntry, 883 bool fRead /*= true */) 884 { 885 int vrc; 886 Assert(!RTManifestPtIosIsInstanceOf(hVfsIos)); 887 888 if (m->fDigestTypes == 0) 889 return hVfsIos; 890 891 /* Create the manifest if necessary. */ 892 if (m->hOurManifest == NIL_RTMANIFEST) 893 { 894 vrc = RTManifestCreate(0 /*fFlags*/, &m->hOurManifest); 895 AssertRCReturnStmt(vrc, RTVfsIoStrmRelease(hVfsIos), NIL_RTVFSIOSTREAM); 896 } 897 898 /* Setup the stream. */ 899 RTVFSIOSTREAM hVfsIosPt; 900 vrc = RTManifestEntryAddPassthruIoStream(m->hOurManifest, hVfsIos, pszManifestEntry, m->fDigestTypes, fRead, &hVfsIosPt); 901 902 RTVfsIoStrmRelease(hVfsIos); /* always consumed! */ 903 if (RT_SUCCESS(vrc)) 904 return hVfsIosPt; 905 906 setErrorVrc(vrc, "RTManifestEntryAddPassthruIoStream failed with rc=%Rrc", vrc); 907 return NIL_RTVFSIOSTREAM; 908 } 909 910 /** 874 911 * Returns true if the appliance is in "idle" state. This should always be the 875 912 * case unless an import or export is currently in progress. Similar to machine -
trunk/src/VBox/Main/src-server/ApplianceImplExport.cpp
r67142 r67184 21 21 #include <iprt/s3.h> 22 22 #include <iprt/manifest.h> 23 #include <iprt/tar.h>24 23 #include <iprt/stream.h> 24 #ifndef VBOX_WITH_NEW_TAR_CREATOR 25 # include <iprt/tar.h> 26 #else 27 # include <iprt/zip.h> 28 #endif 25 29 26 30 #include <VBox/version.h> … … 675 679 tr("Appliance file must have .ovf or .ova extension")); 676 680 677 m->fManifest = m->optListExport.contains(ExportOptions_CreateManifest);678 679 681 ovf::OVFVersion_T ovfF; 680 682 if (aFormat == "ovf-0.9") 681 {682 683 ovfF = ovf::OVFVersion_0_9; 683 }684 684 else if (aFormat == "ovf-1.0") 685 {686 685 ovfF = ovf::OVFVersion_1_0; 687 }688 686 else if (aFormat == "ovf-2.0") 689 {690 687 ovfF = ovf::OVFVersion_2_0; 691 }692 688 else 693 689 return setError(VBOX_E_FILE_ERROR, 694 690 tr("Invalid format \"%s\" specified"), aFormat.c_str()); 691 692 /* As of OVF 2.0 we have to use SHA-256 in the manifest. */ 693 m->fManifest = m->optListExport.contains(ExportOptions_CreateManifest); 694 if (m->fManifest) 695 m->fDigestTypes = ovfF >= ovf::OVFVersion_2_0 ? RTMANIFEST_ATTR_SHA256 : RTMANIFEST_ATTR_SHA1; 696 #ifndef VBOX_WITH_NEW_TAR_CREATOR 697 m->fSha256 = ovfF >= ovf::OVFVersion_2_0; 698 #endif 699 Assert(m->hOurManifest == NIL_RTMANIFEST); 695 700 696 701 /* Check whether all passwords are supplied or error out. */ … … 698 703 return setError(VBOX_E_INVALID_OBJECT_STATE, 699 704 tr("Appliance export failed because not all passwords were provided for all encrypted media")); 700 701 /* as of OVF 2.0 we have to use SHA256 */702 m->fSha256 = ovfF >= ovf::OVFVersion_2_0;703 705 704 706 ComObjPtr<Progress> progress; … … 1991 1993 LogFlowFuncEnter(); 1992 1994 1995 #ifdef VBOX_WITH_NEW_TAR_CREATOR 1996 HRESULT hrc = E_NOTIMPL; 1997 AssertFailed(); 1998 RT_NOREF(pTask, writeLock); 1999 2000 /** @todo need a FSS creator wrapper around a directory here. */ 2001 2002 LogFlowFuncLeave(); 2003 return hrc; 2004 2005 #else /* VBOX_WITH_NEW_TAR_CREATOR */ 1993 2006 HRESULT rc = S_OK; 1994 2007 … … 2026 2039 break; 2027 2040 } 2028 rc = i_writeFSImpl(pTask, writeLock, NIL_RTVFSFSSTREAM,pShaIo, &storage);2041 rc = i_writeFSImpl(pTask, writeLock, pShaIo, &storage); 2029 2042 } while (0); 2030 2043 … … 2037 2050 LogFlowFuncLeave(); 2038 2051 return rc; 2052 #endif 2039 2053 } 2040 2054 2041 HRESULT Appliance::i_writeFSOVA(TaskOVF *pTask, AutoWriteLockBase &writeLock)2055 HRESULT Appliance::i_writeFSOVA(TaskOVF *pTask, AutoWriteLockBase &writeLock) 2042 2056 { 2043 2057 LogFlowFuncEnter(); 2058 2059 #ifdef VBOX_WITH_NEW_TAR_CREATOR 2060 /* 2061 * Open the output file and attach a TAR creator to it. 2062 */ 2063 HRESULT hrc; 2064 RTVFSIOSTREAM hVfsIosTar; 2065 int vrc = RTVfsIoStrmOpenNormal(pTask->locInfo.strPath.c_str(), 2066 RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE, 2067 &hVfsIosTar); 2068 if (RT_SUCCESS(vrc)) 2069 { 2070 /** @todo which format does the standard dicate here actually? 2071 * GNU or USTAR/POSIX? */ 2072 RTVFSFSSTREAM hVfsFssTar; 2073 vrc = RTZipTarFsStreamToIoStream(hVfsIosTar, RTZIPTARFORMAT_GNU, 0 /*fFlags*/, &hVfsFssTar); 2074 RTVfsIoStrmRelease(hVfsIosTar); 2075 if (RT_SUCCESS(vrc)) 2076 { 2077 hrc = i_writeFSImpl(pTask, writeLock, hVfsFssTar); 2078 RTVfsFsStrmRelease(hVfsFssTar); 2079 } 2080 else 2081 hrc = setErrorVrc(vrc, tr("Failed create TAR creator for '%s' (%Rrc)"), pTask->locInfo.strPath.c_str(), vrc); 2082 2083 /* Delete the OVA on failure. */ 2084 if (FAILED(hrc)) 2085 RTFileDelete(pTask->locInfo.strPath.c_str()); 2086 } 2087 else 2088 hrc = setErrorVrc(vrc, tr("Failed to open '%s' for writing (%Rrc)"), pTask->locInfo.strPath.c_str(), vrc); 2089 2090 LogFlowFuncLeave(); 2091 return hrc; 2092 2093 #else /* VBOX_WITH_NEW_TAR_CREATOR */ 2044 2094 2045 2095 RTTAR tar; … … 2084 2134 break; 2085 2135 } 2086 rc = i_writeFSImpl(pTask, writeLock, NIL_RTVFSFSSTREAM,pShaIo, &storage);2136 rc = i_writeFSImpl(pTask, writeLock, pShaIo, &storage); 2087 2137 } while (0); 2088 2138 … … 2101 2151 LogFlowFuncLeave(); 2102 2152 return rc; 2153 #endif 2103 2154 } 2104 2155 2105 HRESULT Appliance::i_writeFSImpl(TaskOVF *pTask, AutoWriteLockBase& writeLock, RTVFSFSSTREAM hVfsFssOut, 2106 PVDINTERFACEIO pIfIo, PSHASTORAGE pStorage) 2156 #ifdef VBOX_WITH_NEW_TAR_CREATOR 2157 HRESULT Appliance::i_writeFSImpl(TaskOVF *pTask, AutoWriteLockBase &writeLock, RTVFSFSSTREAM hVfsFssDst) 2158 #else 2159 HRESULT Appliance::i_writeFSImpl(TaskOVF *pTask, AutoWriteLockBase& writeLock, PVDINTERFACEIO pIfIo, PSHASTORAGE pStorage) 2160 #endif 2107 2161 { 2108 2162 LogFlowFuncEnter(); 2109 2163 2110 2164 HRESULT rc = S_OK; 2111 2165 #ifdef VBOX_WITH_NEW_TAR_CREATOR 2166 RTMANIFEST hManifest; 2167 int vrc = RTManifestCreate(0 /*fFlags*/, &hManifest); 2168 2169 #else 2170 int vrc; 2112 2171 list<STRPAIR> fileList; 2172 #endif 2113 2173 try 2114 2174 { 2115 int vrc;2116 2175 // the XML stack contains two maps for disks and networks, which allows us to 2117 2176 // a) have a list of unique disk names (to make sure the same disk name is only added once) … … 2120 2179 // Scope this to free the memory as soon as this is finished 2121 2180 { 2122 // Create a xml document 2181 /* Construct the OVF name. */ 2182 Utf8Str strOvfFile(pTask->locInfo.strPath); 2183 strOvfFile.stripSuffix().append(".ovf"); 2184 2185 /* Render a valid ovf document into a memory buffer. */ 2123 2186 xml::Document doc; 2124 // Now fully build a valid ovf document in memory2125 2187 i_buildXML(writeLock, doc, stack, pTask->locInfo.strPath, pTask->enFormat); 2126 /* Extract the OVA file name */ 2127 Utf8Str strOvaFile = pTask->locInfo.strPath; 2128 /* Extract the path */ 2129 Utf8Str strOvfFile = strOvaFile.stripSuffix().append(".ovf"); 2130 // Create a memory buffer containing the XML. */ 2131 void *pvBuf = 0; 2132 size_t cbSize; 2188 2189 void *pvBuf = NULL; 2190 size_t cbSize = 0; 2133 2191 xml::XmlMemWriter writer; 2134 2192 writer.write(doc, &pvBuf, &cbSize); … … 2137 2195 tr("Could not create OVF file '%s'"), 2138 2196 strOvfFile.c_str()); 2139 /* Write the ovf file to disk. */ 2140 if (hVfsFssOut != NIL_RTVFSFSSTREAM) 2141 vrc = writeBufferToFile(strOvfFile.c_str(), pvBuf, cbSize, hVfsFssOut); 2142 else 2143 vrc = writeBufferToFile(strOvfFile.c_str(), pvBuf, cbSize, pIfIo, pStorage); 2197 2198 /* Write the ovf file to "disk". */ 2199 #ifdef VBOX_WITH_NEW_TAR_CREATOR 2200 rc = i_writeBufferToFile(hVfsFssDst, strOvfFile.c_str(), pvBuf, cbSize); 2201 if (FAILED(rc)) 2202 throw rc; 2203 #else 2204 vrc = writeBufferToFile(strOvfFile.c_str(), pvBuf, cbSize, pIfIo, pStorage); 2144 2205 if (RT_FAILURE(vrc)) 2145 2146 throw setError(VBOX_E_FILE_ERROR, 2147 tr("Could not create OVF file '%s' (%Rrc)"), 2148 strOvfFile.c_str(), vrc); 2206 throw setErrorVrc(vrc, tr("Could not create OVF file '%s' (%Rrc)"), strOvfFile.c_str(), vrc); 2207 #endif 2208 2209 #ifndef VBOX_WITH_NEW_TAR_CREATOR 2149 2210 fileList.push_back(STRPAIR(strOvfFile, pStorage->strDigest)); 2211 #endif 2150 2212 } 2151 2213 … … 2249 2311 if (FAILED(rc)) throw rc; 2250 2312 2251 if (hVfsFssOut != NIL_RTVFSFSSTREAM) 2252 rc = E_NOTIMPL; /** @todo Continue here later. Need to (1) wrap the FSS thing (in the caller?) 2253 * and (2) provide a push API for adding streams. (RTVfsFsStrmAdd is a pull API, 2254 * in that it pulls in the data bytes itself.) */ 2255 else 2313 #ifdef VBOX_WITH_NEW_TAR_CREATOR 2314 /* For compressed VMDK fun, we let i_exportFile produce the image bytes. */ 2315 if (true) 2256 2316 { 2317 RTVFSIOSTREAM hVfsIosDst; 2318 vrc = RTVfsFsStrmPushFile(hVfsFssDst, strTargetFilePath.c_str(), UINT64_MAX, 2319 NULL /*paObjInfo*/, 0 /*cObjInfo*/, RTVFSFSSTRM_PUSH_F_STREAM, &hVfsIosDst); 2320 if (RT_FAILURE(vrc)) 2321 throw setErrorVrc(vrc, tr("RTVfsFsStrmPushFile failed for '%s' (%Rrc)"), strTargetFilePath.c_str(), vrc); 2322 hVfsIosDst = i_manifestSetupDigestCalculationForGivenIoStream(hVfsIosDst, strTargetFilePath.c_str(), 2323 false /*fRead*/); 2324 if (hVfsIosDst == NIL_RTVFSIOSTREAM) 2325 throw setError(E_FAIL, "i_manifestSetupDigestCalculationForGivenIoStream(%s)", strTargetFilePath.c_str()); 2326 2257 2327 rc = pSourceDisk->i_exportFile(strTargetFilePath.c_str(), 2258 2328 format, 2259 2329 MediumVariant_VmdkStreamOptimized, 2260 2330 m->m_pSecretKeyStore, 2261 pIfIo, 2262 pStorage, 2331 hVfsIosDst, 2263 2332 pProgress2); 2333 RTVfsIoStrmRelease(hVfsIosDst); 2334 if (FAILED(rc)) throw rc; 2264 2335 } 2336 /* When creating sparse raw images, the tar creator stream pulls the data 2337 out of the disk image. It will scan for empty space first, then copy 2338 the non-empty segments into the tar stream. */ 2339 else 2340 { 2341 throw E_NOTIMPL; 2342 } 2343 #else 2344 rc = pSourceDisk->i_exportFile(strTargetFilePath.c_str(), 2345 format, 2346 MediumVariant_VmdkStreamOptimized, 2347 m->m_pSecretKeyStore, 2348 pIfIo, 2349 pStorage, 2350 pProgress2); 2265 2351 if (FAILED(rc)) throw rc; 2352 #endif 2266 2353 2267 2354 ComPtr<IProgress> pProgress3(pProgress2); … … 2276 2363 Assert(pDiskEntry->type == VirtualSystemDescriptionType_CDROM); 2277 2364 2278 if (hVfsFssOut != NIL_RTVFSFSSTREAM) 2365 #ifdef VBOX_WITH_NEW_TAR_CREATOR 2366 /* Open the source image and cast it to a VFS base object. */ 2367 RTVFSFILE hVfsSrcFile; 2368 vrc = RTVfsFileOpenNormal(strSrcFilePath.c_str(), 2369 RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE, 2370 &hVfsSrcFile); 2371 if (RT_FAILURE(vrc)) 2372 throw setErrorBoth(VBOX_E_FILE_ERROR, vrc, 2373 tr("Could not create or open file '%s' (%Rrc)"), strSrcFilePath.c_str(), vrc); 2374 2375 RTVFSOBJ hVfsSrc = RTVfsObjFromFile(hVfsSrcFile); 2376 RTVfsFileRelease(hVfsSrcFile); 2377 AssertStmt(hVfsSrc != NIL_RTVFSOBJ, throw VERR_INTERNAL_ERROR); 2378 2379 /* Add it to the output stream. This will pull in all the data from the object. */ 2380 vrc = RTVfsFsStrmAdd(hVfsFssDst, strTargetFilePath.c_str(), hVfsSrc, 0 /*fFlags*/); 2381 RTVfsObjRelease(hVfsSrc); 2382 if (RT_FAILURE(vrc)) 2383 throw setErrorBoth(VBOX_E_FILE_ERROR, vrc, tr("Error during copy CD/DVD image '%s' (%Rrc)"), 2384 strSrcFilePath.c_str(), vrc); 2385 #else 2386 /* Read the ISO file and add one to OVA/OVF package */ 2387 void *pvStorage; 2388 RTFILE pFile = NULL; 2389 void *pvUser = pStorage; 2390 2391 vrc = pIfIo->pfnOpen(pvUser, strTargetFilePath.c_str(), 2392 RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE, 2393 0, 2394 &pvStorage); 2395 if (RT_FAILURE(vrc)) 2396 throw setError(VBOX_E_FILE_ERROR, 2397 tr("Could not create or open file '%s' (%Rrc)"), 2398 strTargetFilePath.c_str(), vrc); 2399 2400 vrc = RTFileOpen(&pFile, 2401 strSrcFilePath.c_str(), 2402 RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE); 2403 2404 if (RT_FAILURE(vrc) || pFile == NULL) 2279 2405 { 2280 /* Open the source image and cast it to a VFS base object. */ 2281 RTVFSFILE hVfsSrcFile; 2282 vrc = RTVfsFileOpenNormal(strSrcFilePath.c_str(), 2283 RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE, 2284 &hVfsSrcFile); 2285 if (RT_FAILURE(vrc)) 2286 throw setErrorBoth(VBOX_E_FILE_ERROR, vrc, 2287 tr("Could not create or open file '%s' (%Rrc)"), strSrcFilePath.c_str(), vrc); 2288 2289 RTVFSOBJ hVfsSrc = RTVfsObjFromFile(hVfsSrcFile); 2290 RTVfsFileRelease(hVfsSrcFile); 2291 AssertStmt(hVfsSrc != NIL_RTVFSOBJ, throw VERR_INTERNAL_ERROR); 2292 2293 /* Add it to the output stream. This will pull in all the data from the object. */ 2294 vrc = RTVfsFsStrmAdd(hVfsFssOut, strTargetFilePath.c_str(), hVfsSrc, 0 /*fFlags*/); 2295 RTVfsObjRelease(hVfsSrc); 2296 if (RT_FAILURE(vrc)) 2297 throw setErrorBoth(VBOX_E_FILE_ERROR, vrc, tr("Error during copy CD/DVD image '%s' (%Rrc)"), 2298 strSrcFilePath.c_str(), vrc); 2406 pIfIo->pfnClose(pvUser, pvStorage); 2407 throw setError(VBOX_E_FILE_ERROR, 2408 tr("Could not create or open file '%s' (%Rrc)"), 2409 strSrcFilePath.c_str(), vrc); 2299 2410 } 2300 else 2411 2412 uint64_t cbFile = 0; 2413 vrc = RTFileGetSize(pFile, &cbFile); 2414 if (RT_SUCCESS(vrc)) 2301 2415 { 2302 /* Read the ISO file and add one to OVA/OVF package */ 2303 void *pvStorage; 2304 RTFILE pFile = NULL; 2305 void *pvUser = pStorage; 2306 2307 vrc = pIfIo->pfnOpen(pvUser, strTargetFilePath.c_str(), 2308 RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE, 2309 0, 2310 &pvStorage); 2311 if (RT_FAILURE(vrc)) 2416 size_t const cbTmpSize = _1M; 2417 void *pvTmpBuf = RTMemAlloc(cbTmpSize); 2418 if (pvTmpBuf) 2419 { 2420 /* The copy loop. */ 2421 uint64_t offDstFile = 0; 2422 for (;;) 2423 { 2424 size_t cbChunk = 0; 2425 vrc = RTFileRead(pFile, pvTmpBuf, cbTmpSize, &cbChunk); 2426 if (RT_FAILURE(vrc) || cbChunk == 0) 2427 break; 2428 2429 size_t cbWritten = 0; 2430 vrc = pIfIo->pfnWriteSync(pvUser, 2431 pvStorage, 2432 offDstFile, 2433 pvTmpBuf, 2434 cbChunk, 2435 &cbWritten); 2436 if (RT_FAILURE(vrc)) 2437 break; 2438 Assert(cbWritten == cbChunk); 2439 2440 offDstFile += cbWritten; 2441 } 2442 2443 RTMemFree(pvTmpBuf); 2444 } 2445 else 2446 vrc = VERR_NO_MEMORY; 2447 } 2448 2449 pIfIo->pfnClose(pvUser, pvStorage); 2450 RTFileClose(pFile); 2451 2452 if (RT_FAILURE(vrc)) 2453 { 2454 if (vrc == VERR_EOF) 2455 vrc = VINF_SUCCESS; 2456 else 2312 2457 throw setError(VBOX_E_FILE_ERROR, 2313 tr("Could not create or open file '%s' (%Rrc)"), 2314 strTargetFilePath.c_str(), vrc); 2315 2316 vrc = RTFileOpen(&pFile, 2317 strSrcFilePath.c_str(), 2318 RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE); 2319 2320 if (RT_FAILURE(vrc) || pFile == NULL) 2321 { 2322 pIfIo->pfnClose(pvUser, pvStorage); 2323 throw setError(VBOX_E_FILE_ERROR, 2324 tr("Could not create or open file '%s' (%Rrc)"), 2458 tr("Error during copy CD/DVD image '%s' (%Rrc)"), 2325 2459 strSrcFilePath.c_str(), vrc); 2326 }2327 2328 uint64_t cbFile = 0;2329 vrc = RTFileGetSize(pFile, &cbFile);2330 if (RT_SUCCESS(vrc))2331 {2332 size_t const cbTmpSize = _1M;2333 void *pvTmpBuf = RTMemAlloc(cbTmpSize);2334 if (pvTmpBuf)2335 {2336 /* The copy loop. */2337 uint64_t offDstFile = 0;2338 for (;;)2339 {2340 size_t cbChunk = 0;2341 vrc = RTFileRead(pFile, pvTmpBuf, cbTmpSize, &cbChunk);2342 if (RT_FAILURE(vrc) || cbChunk == 0)2343 break;2344 2345 size_t cbWritten = 0;2346 vrc = pIfIo->pfnWriteSync(pvUser,2347 pvStorage,2348 offDstFile,2349 pvTmpBuf,2350 cbChunk,2351 &cbWritten);2352 if (RT_FAILURE(vrc))2353 break;2354 Assert(cbWritten == cbChunk);2355 2356 offDstFile += cbWritten;2357 }2358 2359 RTMemFree(pvTmpBuf);2360 }2361 else2362 vrc = VERR_NO_MEMORY;2363 }2364 2365 pIfIo->pfnClose(pvUser, pvStorage);2366 RTFileClose(pFile);2367 2368 if (RT_FAILURE(vrc))2369 {2370 if (vrc == VERR_EOF)2371 vrc = VINF_SUCCESS;2372 else2373 throw setError(VBOX_E_FILE_ERROR,2374 tr("Error during copy CD/DVD image '%s' (%Rrc)"),2375 strSrcFilePath.c_str(), vrc);2376 }2377 2460 } 2461 #endif 2378 2462 } 2379 2463 } … … 2387 2471 // in the meantime) 2388 2472 writeLock.acquire(); 2473 #ifndef VBOX_WITH_NEW_TAR_CREATOR 2389 2474 fileList.push_back(STRPAIR(strTargetFilePath, pStorage->strDigest)); 2475 #endif 2390 2476 } 2391 2477 … … 2398 2484 m->ulWeightForManifestOperation); // operation's weight, as set up 2399 2485 // with the IProgress originally); 2486 #ifdef VBOX_WITH_NEW_TAR_CREATOR 2487 /* Create a memory I/O stream and write the manifest to it. */ 2488 RTVFSIOSTREAM hVfsIosManifest; 2489 vrc = RTVfsMemIoStrmCreate(NIL_RTVFSIOSTREAM, _1K, &hVfsIosManifest); 2490 if (RT_FAILURE(vrc)) 2491 throw setErrorVrc(vrc, tr("RTVfsMemIoStrmCreate failed (%Rrc)"), vrc); 2492 if (m->hOurManifest != NIL_RTMANIFEST) /* In case it's empty. */ 2493 vrc = RTManifestWriteStandard(m->hOurManifest, hVfsIosManifest); 2494 if (RT_SUCCESS(vrc)) 2495 { 2496 /* Rewind the stream and add it to the output. */ 2497 size_t cbIgnored; 2498 vrc = RTVfsIoStrmReadAt(hVfsIosManifest, 0 /*offset*/, &cbIgnored, 0, true /*fBlocking*/, &cbIgnored); 2499 if (RT_SUCCESS(vrc)) 2500 { 2501 RTVFSOBJ hVfsObjManifest = RTVfsObjFromIoStream(hVfsIosManifest); 2502 vrc = RTVfsFsStrmAdd(hVfsFssDst, strMfFilePath.c_str(), hVfsObjManifest, 0 /*fFlags*/); 2503 if (RT_SUCCESS(vrc)) 2504 rc = S_OK; 2505 else 2506 rc = setErrorVrc(vrc, tr("RTVfsFsStrmAdd failed for the manifest (%Rrc)"), vrc); 2507 } 2508 else 2509 rc = setErrorVrc(vrc, tr("RTManifestWriteStandard failed (%Rrc)"), vrc); 2510 } 2511 else 2512 rc = setErrorVrc(vrc, tr("RTManifestWriteStandard failed (%Rrc)"), vrc); 2513 RTVfsIoStrmRelease(hVfsIosManifest); 2514 if (FAILED(rc)) 2515 throw rc; 2516 #else 2400 2517 PRTMANIFESTTEST paManifestFiles = (PRTMANIFESTTEST)RTMemAlloc(sizeof(RTMANIFESTTEST) * fileList.size()); 2401 2518 size_t i = 0; … … 2420 2537 pStorage->fCreateDigest = false; 2421 2538 /* Write the manifest file to disk. */ 2422 if (hVfsFssOut != NIL_RTVFSFSSTREAM) 2423 vrc = writeBufferToFile(strMfFilePath.c_str(), pvBuf, cbSize, hVfsFssOut); 2424 else 2425 vrc = writeBufferToFile(strMfFilePath.c_str(), pvBuf, cbSize, pIfIo, pStorage); 2539 vrc = writeBufferToFile(strMfFilePath.c_str(), pvBuf, cbSize, pIfIo, pStorage); 2426 2540 RTMemFree(pvBuf); 2427 2541 if (RT_FAILURE(vrc)) … … 2429 2543 tr("Could not create manifest file '%s' (%Rrc)"), 2430 2544 strMfFilePath.c_str(), vrc); 2545 #endif 2431 2546 } 2432 2547 } … … 2441 2556 } 2442 2557 2558 #ifndef VBOX_WITH_NEW_TAR_CREATOR /* done in caller now */ 2443 2559 /* Cleanup on error */ 2444 2560 if (FAILED(rc)) … … 2450 2566 pIfIo->pfnDelete(pStorage, (*it).first.c_str()); 2451 2567 } 2568 #endif 2452 2569 2453 2570 LogFlowFunc(("rc=%Rhrc\n", rc)); … … 2457 2574 } 2458 2575 2576 2577 #ifdef VBOX_WITH_NEW_TAR_CREATOR 2578 /** 2579 * Writes a memory buffer to a file in the output file system stream. 2580 * 2581 * @returns COM status code. 2582 * @param hVfsFssDst The file system stream to add the file to. 2583 * @param pszFilename The file name (w/ path if desired). 2584 * @param pvContent Pointer to buffer containing the file content. 2585 * @param cbContent Size of the content. 2586 */ 2587 HRESULT Appliance::i_writeBufferToFile(RTVFSFSSTREAM hVfsFssDst, const char *pszFilename, const void *pvContent, size_t cbContent) 2588 { 2589 /* 2590 * Create a VFS file around the memory, converting it to a base VFS object handle. 2591 */ 2592 HRESULT hrc; 2593 RTVFSIOSTREAM hVfsIosSrc; 2594 int vrc = RTVfsIoStrmFromBuffer(RTFILE_O_READ, pvContent, cbContent, &hVfsIosSrc); 2595 if (RT_SUCCESS(vrc)) 2596 { 2597 hVfsIosSrc = i_manifestSetupDigestCalculationForGivenIoStream(hVfsIosSrc, pszFilename); 2598 AssertReturn(hVfsIosSrc != NIL_RTVFSIOSTREAM, 2599 setErrorVrc(vrc, "i_manifestSetupDigestCalculationForGivenIoStream")); 2600 2601 RTVFSOBJ hVfsObj = RTVfsObjFromIoStream(hVfsIosSrc); 2602 RTVfsIoStrmRelease(hVfsIosSrc); 2603 AssertReturn(hVfsObj != NIL_RTVFSOBJ, E_FAIL); 2604 2605 /* 2606 * Add it to the stream. 2607 */ 2608 vrc = RTVfsFsStrmAdd(hVfsFssDst, pszFilename, hVfsObj, 0); 2609 RTVfsObjRelease(hVfsObj); 2610 if (RT_SUCCESS(vrc)) 2611 hrc = S_OK; 2612 else 2613 hrc = setErrorVrc(vrc, tr("RTVfsFsStrmAdd failed for '%s' (%Rrc)"), pszFilename, vrc); 2614 } 2615 else 2616 hrc = setErrorVrc(vrc, "RTVfsIoStrmFromBuffer"); 2617 return hrc; 2618 } 2619 #endif 2620 -
trunk/src/VBox/Main/src-server/ApplianceImplIO.cpp
r67142 r67184 1230 1230 1231 1231 1232 /** 1233 * Writes a memory buffer to a file in the output file system stream. 1234 * 1235 * @returns IPRT status code. 1236 * @param pszFilename The file name (w/ path if desired). 1237 * @param pvContent Pointer to buffer containing the file content. 1238 * @param cbContent Size of the content. 1239 * @param hVfsFss The file system stream to add the file to. 1240 */ 1241 int writeBufferToFile(const char *pszFilename, const void *pvContent, size_t cbContent, RTVFSFSSTREAM hVfsFss) 1242 { 1243 /* 1244 * Create a VFS file around the memory, converting it to a base VFS object handle. 1245 */ 1246 RTVFSFILE hVfsFile; 1247 int rc = RTVfsFileFromBuffer(RTFILE_O_READ, pvContent, cbContent, &hVfsFile); 1248 if (RT_SUCCESS(rc)) 1249 { 1250 RTVFSOBJ hVfsObj = RTVfsObjFromFile(hVfsFile); 1251 RTVfsFileRelease(hVfsFile); 1252 AssertReturn(hVfsObj != NIL_RTVFSOBJ, VERR_INTERNAL_ERROR_2); 1253 1254 /* 1255 * Add it to the stream. 1256 */ 1257 rc = RTVfsFsStrmAdd(hVfsFss, pszFilename, hVfsObj, 0); 1258 RTVfsObjRelease(hVfsObj); 1259 } 1260 1261 return rc; 1262 } 1263 1232 #ifndef VBOX_WITH_NEW_TAR_CREATOR 1264 1233 int writeBufferToFile(const char *pcszFilename, void *pvBuf, size_t cbSize, PVDINTERFACEIO pIfIo, void *pvUser) 1265 1234 { … … 1293 1262 return rc; 1294 1263 } 1295 1264 #endif /* !VBOX_WITH_NEW_TAR_CREATOR */ 1265 -
trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp
r65887 r67184 856 856 857 857 /** 858 * Setup automatic I/O stream digest calculation, adding it to hOurManifest.859 *860 * @returns Passthru I/O stream, of @a hVfsIos if no digest calc needed.861 * @param hVfsIos The stream to wrap. Always consumed.862 * @param pszManifestEntry The manifest entry.863 * @throws Nothing.864 */865 RTVFSIOSTREAM Appliance::i_importSetupDigestCalculationForGivenIoStream(RTVFSIOSTREAM hVfsIos, const char *pszManifestEntry)866 {867 int vrc;868 Assert(!RTManifestPtIosIsInstanceOf(hVfsIos));869 870 if (m->fDigestTypes == 0)871 return hVfsIos;872 873 /* Create the manifest if necessary. */874 if (m->hOurManifest == NIL_RTMANIFEST)875 {876 vrc = RTManifestCreate(0 /*fFlags*/, &m->hOurManifest);877 AssertRCReturnStmt(vrc, RTVfsIoStrmRelease(hVfsIos), NIL_RTVFSIOSTREAM);878 }879 880 /* Setup the stream. */881 RTVFSIOSTREAM hVfsIosPt;882 vrc = RTManifestEntryAddPassthruIoStream(m->hOurManifest, hVfsIos, pszManifestEntry, m->fDigestTypes,883 true /*fReadOrWrite*/, &hVfsIosPt);884 885 RTVfsIoStrmRelease(hVfsIos); /* always consumed! */886 if (RT_SUCCESS(vrc))887 return hVfsIosPt;888 889 setErrorVrc(vrc, "RTManifestEntryAddPassthruIoStream failed with rc=%Rrc", vrc);890 return NIL_RTVFSIOSTREAM;891 }892 893 /**894 858 * Opens a source file (for reading obviously). 895 859 * … … 934 898 * Digest calculation filtering. 935 899 */ 936 hVfsIosSrc = i_ importSetupDigestCalculationForGivenIoStream(hVfsIosSrc, pszManifestEntry);900 hVfsIosSrc = i_manifestSetupDigestCalculationForGivenIoStream(hVfsIosSrc, pszManifestEntry); 937 901 if (hVfsIosSrc == NIL_RTVFSIOSTREAM) 938 902 throw E_FAIL; … … 1445 1409 * Set up digest calculation. 1446 1410 */ 1447 hVfsIosOvf = i_ importSetupDigestCalculationForGivenIoStream(hVfsIosOvf, pszManifestEntry);1411 hVfsIosOvf = i_manifestSetupDigestCalculationForGivenIoStream(hVfsIosOvf, pszManifestEntry); 1448 1412 if (hVfsIosOvf == NIL_RTVFSIOSTREAM) 1449 1413 return VBOX_E_FILE_ERROR; … … 1543 1507 m->fDeterminedDigestTypes = true; 1544 1508 1509 #ifndef VBOX_WITH_NEW_TAR_CREATOR 1545 1510 m->fSha256 = RT_BOOL(m->fDigestTypes & RTMANIFEST_ATTR_SHA256); /** @todo retire this member */ 1511 #endif 1546 1512 return S_OK; 1547 1513 } -
trunk/src/VBox/Main/src-server/MediumImpl.cpp
r67172 r67184 660 660 MediumVariant_T aVariant, 661 661 SecretKeyStore *pSecretKeyStore, 662 #ifdef VBOX_WITH_NEW_TAR_CREATOR 663 RTVFSIOSTREAM aVfsIosDst, 664 #else 662 665 VDINTERFACEIO *aVDImageIOIf, 663 666 void *aVDImageIOUser, 667 #endif 664 668 MediumLockList *aSourceMediumLockList, 665 669 bool fKeepSourceMediumLockList = false) … … 675 679 676 680 mVDImageIfaces = aMedium->m->vdImageIfaces; 681 682 #ifdef VBOX_WITH_NEW_TAR_CREATOR 683 int vrc = VDIfCreateFromVfsStream(aVfsIosDst, RTFILE_O_WRITE, &mpVfsIoIf); 684 AssertRCReturnVoidStmt(vrc, mRC = E_FAIL); 685 686 vrc = VDInterfaceAdd(&mpVfsIoIf->Core, "Medium::ExportTaskVfsIos", 687 VDINTERFACETYPE_IO, mpVfsIoIf, 688 sizeof(VDINTERFACEIO), &mVDImageIfaces); 689 AssertRCReturnVoidStmt(vrc, mRC = E_FAIL); 690 #else 691 677 692 if (aVDImageIOIf) 678 693 { … … 682 697 AssertRCReturnVoidStmt(vrc, mRC = E_FAIL); 683 698 } 699 #endif 684 700 m_strTaskName = "createExport"; 685 701 } … … 689 705 if (!mfKeepSourceMediumLockList && mpSourceMediumLockList) 690 706 delete mpSourceMediumLockList; 707 #ifdef VBOX_WITH_NEW_TAR_CREATOR 708 if (mpVfsIoIf) 709 { 710 VDIfDestroyFromVfsStream(mpVfsIoIf); 711 mpVfsIoIf = NULL; 712 } 713 #endif 691 714 } 692 715 … … 696 719 MediumVariant_T mVariant; 697 720 PVDINTERFACE mVDImageIfaces; 721 PVDINTERFACEIO mpVfsIoIf; /**< Pointer to the VFS I/O stream to VD I/O interface wrapper. */ 698 722 SecretKeyStore *m_pSecretKeyStore; 699 723 … … 6096 6120 MediumVariant_T aVariant, 6097 6121 SecretKeyStore *pKeyStore, 6122 #ifdef VBOX_WITH_NEW_TAR_CREATOR 6123 RTVFSIOSTREAM hVfsIosDst, 6124 #else 6098 6125 PVDINTERFACEIO aVDImageIOIf, void *aVDImageIOUser, 6126 #endif 6099 6127 const ComObjPtr<Progress> &aProgress) 6100 6128 { … … 6136 6164 6137 6165 /* setup task object to carry out the operation asynchronously */ 6138 pTask = new Medium::ExportTask(this, aProgress, aFilename, aFormat, 6139 aVariant, pKeyStore, aVDImageIOIf, 6140 aVDImageIOUser, pSourceMediumLockList); 6166 pTask = new Medium::ExportTask(this, aProgress, aFilename, aFormat, aVariant, 6167 #ifdef VBOX_WITH_NEW_TAR_CREATOR 6168 pKeyStore, hVfsIosDst, pSourceMediumLockList); 6169 #else 6170 pKeyStore, aVDImageIOIf, aVDImageIOUser, pSourceMediumLockList); 6171 #endif 6141 6172 rc = pTask->rc(); 6142 6173 AssertComRC(rc);
Note:
See TracChangeset
for help on using the changeset viewer.