Changeset 47500 in vbox
- Timestamp:
- Aug 1, 2013 6:01:14 AM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 87679
- Location:
- trunk
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/mangling.h
r47359 r47500 1861 1861 # define RTZipDecompDestroy RT_MANGLER(RTZipDecompDestroy) 1862 1862 # define RTZipDecompress RT_MANGLER(RTZipDecompress) 1863 # define RTZipGzipFileBufferDecompress RT_MANGLER(RTZipGzipFileBufferDecompress) 1863 1864 # define RTZipGzipCompressIoStream RT_MANGLER(RTZipGzipCompressIoStream) 1864 1865 # define RTZipGzipDecompressIoStream RT_MANGLER(RTZipGzipDecompressIoStream) 1865 1866 # define RTZipTarCmd RT_MANGLER(RTZipTarCmd) 1866 1867 # define RTZipTarFsStreamFromIoStream RT_MANGLER(RTZipTarFsStreamFromIoStream) 1868 1867 1869 /* 1868 1870 * Stable variables (alphabetical order): -
trunk/include/iprt/zip.h
r47359 r47500 170 170 171 171 /** 172 * Decompresses a chunk of Gzip file. 173 * 174 * @returns iprt status code. 175 * @param pZip The stream decompressor instance. 176 * @param pvBufIn Where to read the compressed data from. 177 * @param cbBufIn Number of bytes to read. 178 * @param pcbRead Number of bytes actually read from the 179 * buffer 180 * @param pvBufOut Where to store the decompressed data. 181 * @param cbBufOut Number of bytes to produce. 182 * @param pcbWritten Number of bytes actually written to the 183 * buffer. 184 */ 185 RTDECL(int) RTZipGzipFileBufferDecompress(PRTZIPDECOMP pZip, 186 void *pvBufIn, 187 size_t cbBufIn, 188 size_t *pcbRead, 189 void *pvBufOut, 190 size_t cbBufOut, 191 size_t *pcbWritten); 192 193 /** 172 194 * Destroys the stream decompressor instance. 173 195 * -
trunk/src/VBox/Main/include/ApplianceImplPrivate.h
r47340 r47500 241 241 PVDINTERFACEIO FileCreateInterface(); 242 242 PVDINTERFACEIO TarCreateInterface(); 243 int copyFileAndCalcShaDigest(const char *pcszSourceFilename, const char *pcszTargetFilename, PVDINTERFACEIO pIfIo, void *pvUser); 243 244 int ShaReadBuf(const char *pcszFilename, void **ppvBuf, size_t *pcbSize, PVDINTERFACEIO pIfIo, void *pvUser); 244 245 int ShaWriteBuf(const char *pcszFilename, void *pvBuf, size_t cbSize, PVDINTERFACEIO pIfIo, void *pvUser); 245 246 int decompressImageAndSave(const char *pcszFullFilenameIn, const char *pcszFullFilenameOut, PVDINTERFACEIO pIfIo, void *pvUser); 247 246 248 #endif // !____H_APPLIANCEIMPLPRIVATE 247 249 -
trunk/src/VBox/Main/src-server/ApplianceImplIO.cpp
r47357 r47500 34 34 #include <iprt/vfs.h> 35 35 #include <VBox/vd.h> 36 #include <zlib.h>37 //#define VBOX_MAIN_USE_VFS /** @todo Replace as much as possible with IPRT VFS. */38 36 39 37 /****************************************************************************** … … 96 94 } SHASTORAGEINTERNAL, *PSHASTORAGEINTERNAL; 97 95 96 98 97 /****************************************************************************** 99 98 * Defined Constants And Macros * … … 117 116 * Internal Functions * 118 117 ******************************************************************************/ 119 118 /** 119 * dummy function is needed only for initialization PRTZIPDECOMP pZipDecomp. 120 * see the call/description of RTZipDecompCreate 121 */ 122 static DECLCALLBACK(int) FillBufferWithGzipData(void *pvUser, void *pvBuf, size_t cbBuf, size_t *pcbBuf) 123 { 124 return VINF_SUCCESS; 125 } 120 126 121 127 /****************************************************************************** … … 1241 1247 } 1242 1248 1249 1250 int copyFileAndCalcShaDigest(const char *pcszSourceFilename, const char *pcszTargetFilename, PVDINTERFACEIO pIfIo, void *pvUser) 1251 { 1252 /* Validate input. */ 1253 AssertPtrReturn(pIfIo, VERR_INVALID_POINTER); 1254 1255 void *pvStorage; 1256 RTFILE pFile = NULL; 1257 1258 int rc = pIfIo->pfnOpen(pvUser, pcszSourceFilename, 1259 RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE, 0, 1260 &pvStorage); 1261 if (RT_FAILURE(rc)) 1262 return rc; 1263 1264 try 1265 { 1266 if (RTFileExists(pcszTargetFilename) == false) 1267 { 1268 /* ensure the directory exists */ 1269 rc = VirtualBox::ensureFilePathExists(pcszTargetFilename, true); 1270 if (FAILED(rc)) 1271 throw rc; 1272 1273 // create a new file and copy raw data into one from buffer pvTmpBuf 1274 rc = RTFileOpen(&pFile, 1275 pcszTargetFilename, 1276 RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 1277 1278 if (RT_FAILURE(rc) || pFile == NULL) 1279 { 1280 throw rc; 1281 } 1282 } 1283 else 1284 { 1285 rc = RTFileOpen(&pFile, 1286 pcszTargetFilename, 1287 RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 1288 if (RT_FAILURE(rc) || pFile == NULL) 1289 { 1290 throw rc; 1291 } 1292 } 1293 } 1294 catch(...) 1295 { 1296 pIfIo->pfnClose(pvUser, pvStorage); 1297 return rc; 1298 } 1299 1300 void *pvTmpBuf = 0; 1301 uint64_t cbTmpSize = _1M; 1302 size_t cbAllRead = 0; 1303 do 1304 { 1305 pvTmpBuf = RTMemAlloc(cbTmpSize); 1306 if (!pvTmpBuf) 1307 { 1308 rc = VERR_NO_MEMORY; 1309 break; 1310 } 1311 1312 for (;;) 1313 { 1314 size_t cbRead = 0; 1315 rc = pIfIo->pfnReadSync(pvUser, pvStorage, cbAllRead, pvTmpBuf, cbTmpSize, &cbRead); 1316 if ( RT_FAILURE(rc) 1317 || cbRead == 0) 1318 break; 1319 1320 size_t cbWritten = 0; 1321 1322 rc = RTFileWrite(pFile, pvTmpBuf, cbRead, &cbWritten); 1323 1324 if (RT_FAILURE(rc)) 1325 { 1326 break; 1327 } 1328 1329 cbAllRead += cbRead; 1330 } 1331 } while (0); 1332 1333 pIfIo->pfnClose(pvUser, pvStorage); 1334 RTFileClose(pFile); 1335 1336 if (rc == VERR_EOF) 1337 rc = VINF_SUCCESS; 1338 1339 if (pvTmpBuf) 1340 RTMemFree(pvTmpBuf); 1341 1342 return rc; 1343 } 1344 1243 1345 int ShaReadBuf(const char *pcszFilename, void **ppvBuf, size_t *pcbSize, PVDINTERFACEIO pIfIo, void *pvUser) 1244 1346 { … … 1336 1438 1337 1439 rc = pIfIo->pfnClose(pvUser, pvStorage); 1338 1339 return rc;1340 }1341 1342 static int zipDecompressBuffer(z_stream streamIn,1343 uint32_t *cbDecompressed,1344 bool *finished)1345 {1346 int rc;1347 int sh = streamIn.avail_out;1348 1349 *cbDecompressed = 0;1350 1351 do1352 {1353 rc = inflate(&streamIn, Z_NO_FLUSH);1354 1355 if (rc < 0)1356 {1357 switch (rc)1358 {1359 case Z_STREAM_ERROR:1360 rc = VERR_ZIP_CORRUPTED;1361 break;1362 case Z_DATA_ERROR:1363 rc = VERR_ZIP_CORRUPTED;1364 break;1365 case Z_MEM_ERROR:1366 rc = VERR_ZIP_NO_MEMORY;1367 break;1368 case Z_BUF_ERROR:1369 rc = VERR_ZIP_ERROR;1370 break;1371 case Z_VERSION_ERROR:1372 rc = VERR_ZIP_UNSUPPORTED_VERSION;1373 break;1374 case Z_ERRNO: /* We shouldn't see this status! */1375 default:1376 AssertMsgFailed(("%d\n", rc));1377 if (rc >= 0)1378 rc = VINF_SUCCESS;1379 rc = VERR_ZIP_ERROR;1380 }1381 1382 break;1383 }1384 1385 *cbDecompressed += (sh - streamIn.avail_out);1386 sh = streamIn.avail_out;1387 }1388 while (streamIn.avail_out > 0 && streamIn.avail_in > 0 );1389 1390 if (RT_SUCCESS(rc))1391 {1392 if (streamIn.avail_in == 0)1393 *finished = true;1394 else1395 {1396 if (streamIn.avail_out == 0)1397 *finished = false;1398 }1399 }1400 1440 1401 1441 return rc; … … 1416 1456 if (RT_FAILURE(rc)) 1417 1457 return rc; 1418 #ifdef VBOX_MAIN_USE_VFS 1419 1420 /* Turn the source file handle/whatever into a VFS stream. */ 1421 RTVFSIOSTREAM hVfsIosCompressedSrc; 1422 rc = VDIfCreateVfsStream(pIfIo, pvStorage, RTFILE_O_READ, &hVfsIosCompressedSrc); 1423 if (RT_SUCCESS(rc)) 1424 { 1425 /* Pass the source thru gunzip. */ 1426 RTVFSIOSTREAM hVfsIosSrc; 1427 rc = RTZipGzipDecompressIoStream(hVfsIosCompressedSrc, 0, &hVfsIosSrc); 1428 if (RT_SUCCESS(rc)) 1429 { 1430 /* 1431 * Create the output file, including necessary paths. 1432 * Any existing file will be overwritten. 1433 */ 1434 rc = VirtualBox::ensureFilePathExists(Utf8Str(pcszFullFilenameOut), true /*fCreate*/); 1435 if (RT_SUCCESS(rc)) 1436 { 1437 RTVFSIOSTREAM hVfsIosDst; 1438 rc = RTVfsIoStrmOpenNormal(pcszFullFilenameOut, 1439 RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_ALL, 1440 &hVfsIosDst); 1441 if (RT_SUCCESS(rc)) 1442 { 1443 /* 1444 * Pump the bytes thru. If we fail, delete the output file. 1445 */ 1446 rc = RTVfsUtilPumpIoStreams(hVfsIosSrc, hVfsIosDst, 0); 1447 1448 RTVfsIoStrmRelease(hVfsIosDst); 1449 RTFileDelete(pcszFullFilenameOut); 1450 } 1451 } 1452 1453 RTVfsIoStrmRelease(hVfsIosSrc); 1454 } 1455 RTVfsIoStrmRelease(hVfsIosCompressedSrc); 1456 } 1457 pIfIo->pfnClose(pvUser, pvStorage); 1458 1459 #else 1460 1461 Bytef *decompressedBuffer = 0; 1462 Bytef *compressedBuffer = 0; 1458 1459 uint8_t *compressedBuffer = 0; 1460 uint8_t *decompressedBuffer = 0; 1463 1461 uint64_t cbTmpSize = _1M; 1464 1462 size_t cbAllRead = 0; 1465 1463 size_t cbAllWritten = 0; 1466 1464 RTFILE pFile = NULL; 1467 z_stream gzipStream;1465 PRTZIPDECOMP pZipDecomp; 1468 1466 1469 1467 Utf8Str pathOut(pcszFullFilenameOut); … … 1498 1496 } 1499 1497 1500 compressedBuffer = ( Bytef*)RTMemAlloc(cbTmpSize);1498 compressedBuffer = (uint8_t *)RTMemAlloc(cbTmpSize); 1501 1499 1502 1500 if (!compressedBuffer) … … 1506 1504 } 1507 1505 1508 1509 decompressedBuffer = (Bytef *)RTMemAlloc(cbTmpSize*10); 1506 decompressedBuffer = (uint8_t *)RTMemAlloc(cbTmpSize); 1510 1507 1511 1508 if (!decompressedBuffer) … … 1515 1512 } 1516 1513 1517 gzipStream.zalloc = Z_NULL; 1518 gzipStream.zfree = Z_NULL; 1519 gzipStream.opaque = Z_NULL; 1520 gzipStream.next_in = compressedBuffer; 1521 gzipStream.avail_in = 0; 1522 gzipStream.next_out = decompressedBuffer; 1523 gzipStream.avail_out = cbTmpSize*10; 1524 1525 rc = inflateInit2(&gzipStream, MAX_WBITS + 16 /* autodetect gzip header */); 1514 rc = RTZipDecompCreate(&pZipDecomp, NULL, FillBufferWithGzipData); 1526 1515 1527 1516 if (rc < 0) … … 1530 1519 } 1531 1520 1532 size_t cbRead = 0 ;1521 size_t cbRead = 0, cbActuallyRead = 0; 1533 1522 size_t cbDecompressed = 0; 1534 bool fFinished = true; 1523 bool fData = false; 1524 uint8_t *currentInput = compressedBuffer; 1535 1525 1536 1526 for (;;) 1537 1527 { 1538 if (fFinished == true) 1528 /* 1529 * skip reading a new chunk of compressed data in case if we decompressed not at all data from the buffer 1530 * 1531 */ 1532 if (fData == false) 1539 1533 { 1540 1534 rc = pIfIo->pfnReadSync(pvUser, pvStorage, cbAllRead, compressedBuffer, cbTmpSize, &cbRead); 1541 if ( RT_FAILURE(rc) 1542 || cbRead == 0) 1535 if (RT_FAILURE(rc) || cbRead == 0) 1543 1536 break; 1544 1537 1545 gzipStream.avail_in = cbRead; 1546 gzipStream.avail_out = cbTmpSize*10; 1538 currentInput = compressedBuffer; 1547 1539 } 1548 1540 1549 /* decompress the buffer */ 1550 rc = zipDecompressBuffer(gzipStream, 1551 (uint32_t *)(&cbDecompressed), 1552 &fFinished); 1541 rc = RTZipGzipFileBufferDecompress(pZipDecomp, 1542 currentInput, 1543 cbRead, 1544 &cbActuallyRead, 1545 decompressedBuffer, 1546 cbTmpSize, 1547 &cbDecompressed); 1553 1548 1554 1549 if (RT_FAILURE(rc)) 1555 1550 break; 1556 1551 1552 cbAllRead += cbActuallyRead; 1553 1554 if (cbRead == cbActuallyRead) 1555 { 1556 /* it means the input buffer is empty */ 1557 fData = false; 1558 } 1559 else 1560 { 1561 /* some data still leaves in the input buffer */ 1562 fData = true; 1563 cbRead = cbRead - cbActuallyRead; 1564 currentInput = ¤tInput[cbActuallyRead]; 1565 } 1566 1567 /* write decompressed data to the output file */ 1557 1568 rc = RTFileWrite(pFile, decompressedBuffer, cbDecompressed, &cbDecompressed); 1558 1569 … … 1561 1572 1562 1573 cbAllWritten += cbDecompressed; 1563 cbAllRead += cbRead;1564 1574 } 1565 1575 } while (0); … … 1570 1580 rc = VINF_SUCCESS; 1571 1581 1572 rc = inflateEnd(&gzipStream); 1573 1574 rc = RTFileClose(pFile); 1575 1582 RTZipDecompDestroy(pZipDecomp); 1583 1584 RTFileClose(pFile); 1585 1586 if (compressedBuffer) 1587 RTMemFree(compressedBuffer); 1576 1588 if (decompressedBuffer) 1577 1589 RTMemFree(decompressedBuffer); 1578 if (compressedBuffer)1579 RTMemFree(compressedBuffer);1580 #endif /* !VBOX_MAIN_USE_VFS */1581 1590 1582 1591 return rc; 1583 1592 } 1584 1593 1585 -
trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp
r47401 r47500 977 977 uint64_t maxFileSize = _1M; 978 978 size_t cbRead = 0; 979 void *pBuf; /** @todo r=bird: You leak this buffer! throwing stuff is evil. */979 void *pBuf; 980 980 981 981 vrc = RTFileGetSize(pFile, &cbFile); … … 1008 1008 vrc = RTManifestVerifyDigestType(pBuf, cbRead, &digestType); 1009 1009 1010 /* pBuf isn't needed more. Here we free the memory allocated by the pBuf */ 1011 if (pBuf) 1012 RTMemFree(pBuf); 1013 1010 1014 if (RT_FAILURE(vrc)) 1011 1015 { 1012 if (pBuf)1013 RTMemFree(pBuf);1014 1016 throw setError(VBOX_E_FILE_ERROR, 1015 1017 tr("Could not verify supported digest types in the manifest file '%s' (%Rrc)"), … … 1559 1561 1560 1562 size_t cbCertSize = 0; 1561 Utf8Str manifestShaDigest; 1563 /* Save the SHA digest of the manifest file for the next validation */ 1564 Utf8Str manifestShaDigest = storage.strDigest; 1562 1565 Utf8Str strCertFile = Utf8Str(pTask->locInfo.strPath).stripExt().append(".cert"); 1563 1566 if (RTFileExists(strCertFile.c_str())) … … 1565 1568 rc = readFileToBuf(strCertFile, &pvCertBuf, &cbCertSize, false, pShaIo, &storage); 1566 1569 if (FAILED(rc)) throw rc; 1567 1568 /* Save the SHA digest of the manifest file for the next validation */1569 manifestShaDigest = storage.strDigest;1570 1570 1571 1571 /* verify Certificate */ … … 2259 2259 { 2260 2260 /* check read file to GZIP compression */ 2261 bool fGzipUsed = !(di.strCompression.compare("gzip",Utf8Str::CaseInsensitive)); 2261 2262 try 2262 2263 { 2263 if (di.strCompression.compare("gzip",Utf8Str::CaseInsensitive) == 0) 2264 { 2265 /* 2266 * 1. extract a file to the local/temporary folder 2267 * 2. apply GZIP decompression for the file 2268 * 3. replace the value of strSrcFilePath with a new path to the file 2269 * 4. replace SHA-TAR I/O interface with File I/O interface 2270 * 5. save calculated SHA digest of GZIPed file for later validation 2271 */ 2272 2264 if (fGzipUsed == true) 2265 { 2273 2266 /* Decompress the GZIP file and save a new file in the target path */ 2274 2267 strTargetDir = strTargetDir.stripFilename(); … … 2289 2282 RTPathFilename(strSrcFilePath.c_str()), vrc); 2290 2283 2291 /* Create the necessary file access interfaces. */ 2284 /* 2285 * Create the necessary file access interfaces. 2286 * For the next step: 2287 * We need to replace the previously created chain of SHA-TAR or SHA-FILE interfaces 2288 * with simple FILE interface because we don't need SHA or TAR interfaces here anymore. 2289 * But we mustn't delete the chain of SHA-TAR or SHA-FILE interfaces. 2290 */ 2292 2291 pFileIo = FileCreateInterface(); 2293 2292 if (!pFileIo) … … 2303 2302 tr("Creation of the VD interface failed (%Rrc)"), vrc); 2304 2303 2304 /* Correct the source and the target with the actual values */ 2305 2305 strSrcFilePath = strTargetDir; 2306 2306 strTargetDir = strTargetDir.stripFilename(); … … 2315 2315 ULONG lCabs = 0; 2316 2316 2317 char *pszExt = NULL; 2318 2317 2319 if (RTPathHaveExt(strTargetPath->c_str())) 2318 2320 { 2319 char *pszExt = RTPathExt(strTargetPath->c_str()); 2321 pszExt = RTPathExt(strTargetPath->c_str()); 2322 2320 2323 /* Figure out which format the user like to have. Default is VMDK. */ 2321 2324 ComObjPtr<MediumFormat> trgFormat = pSysProps->mediumFormatFromExtension(&pszExt[1]); … … 2347 2350 strTrgFormat = Utf8Str(bstrFormatName); 2348 2351 } 2352 else 2353 { 2354 throw setError(VBOX_E_FILE_ERROR, 2355 tr("The target disk '%s' has no extension "), 2356 strTargetPath->c_str(), VERR_INVALID_NAME); 2357 } 2349 2358 2350 2359 /* Create an IMedium object. */ … … 2355 2364 { 2356 2365 void *pvTmpBuf = 0; 2357 size_t cbSize = 0; 2366 2358 2367 try 2359 2368 { 2360 /* Read the ISO file into a memory buffer */ 2361 vrc = ShaReadBuf(strSrcFilePath.c_str(), &pvTmpBuf, &cbSize, pCallbacks, pRealUsedStorage); 2362 2363 if ( RT_FAILURE(vrc) || !pvTmpBuf) 2364 throw setError(VBOX_E_FILE_ERROR, 2365 tr("Could not read ISO file '%s' listed in the OVF file (%Rrc)"), 2366 RTPathFilename(strSourceOVF.c_str()), vrc); 2367 2368 if (RTFileExists(strTargetPath->c_str()) == false) 2369 if (fGzipUsed == true) 2369 2370 { 2370 2371 /* ensure the directory exists */ 2372 if (lCabs & MediumFormatCapabilities_File) 2373 { 2374 rc = VirtualBox::ensureFilePathExists(*strTargetPath, true); 2375 if (FAILED(rc)) 2376 throw rc; 2377 } 2378 2379 // create a new file and copy raw data into one from buffer pvTmpBuf 2380 RTFILE pFile = NULL; 2381 vrc = RTFileOpen(&pFile, 2382 strTargetPath->c_str(), 2383 RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 2384 2385 if (RT_SUCCESS(vrc) && pFile != NULL) 2386 { 2387 size_t cbWritten = 0; 2388 2389 vrc = RTFileWrite(pFile, pvTmpBuf, cbSize, &cbWritten); 2390 2391 if (RT_FAILURE(vrc)) 2392 { 2393 Utf8Str path(*strTargetPath); 2394 path = path.stripFilename(); 2395 2396 throw setError(VBOX_E_FILE_ERROR, 2397 tr("Could not write the ISO file '%s' into the folder %s (%Rrc)"), 2398 strSrcFilePath.stripPath().c_str(), 2399 path.c_str(), 2400 vrc); 2401 } 2402 } 2403 RTFileClose(pFile); 2371 /* 2372 * The source and target pathes are the same. 2373 * It means that we have the needed file already. 2374 * For example, in GZIP case, we decompress the file and save it in the target path, 2375 * but with some prefix like "temp_". See part "check read file to GZIP compression" earlier 2376 * in this function. 2377 * Just rename the file by deleting "temp_" from it's name 2378 */ 2379 vrc = RTFileRename(strSrcFilePath.c_str(), strTargetPath->c_str(), RTPATHRENAME_FLAGS_NO_REPLACE); 2380 if (RT_FAILURE(vrc)) 2381 throw setError(VBOX_E_FILE_ERROR, 2382 tr("Could not rename the file '%s' (%Rrc)"), 2383 RTPathFilename(strSourceOVF.c_str()), vrc); 2384 2385 } 2386 else 2387 { 2388 /* Calculating SHA digest for ISO file while copying one */ 2389 vrc = copyFileAndCalcShaDigest(strSrcFilePath.c_str(), 2390 strTargetPath->c_str(), 2391 pCallbacks, 2392 pRealUsedStorage); 2393 2394 if (RT_FAILURE(vrc)) 2395 throw setError(VBOX_E_FILE_ERROR, 2396 tr("Could not copy ISO file '%s' listed in the OVF file (%Rrc)"), 2397 RTPathFilename(strSourceOVF.c_str()), vrc); 2404 2398 } 2405 2399 } … … 2493 2487 ComPtr<IProgress> pp(pProgress); 2494 2488 waitForAsyncProgress(stack.pProgress, pp); 2489 2490 if (fGzipUsed == true) 2491 { 2492 /* 2493 * Just delete the temporary file 2494 */ 2495 vrc = RTFileDelete(strSrcFilePath.c_str()); 2496 if (RT_FAILURE(vrc)) 2497 setWarning(VBOX_E_FILE_ERROR, 2498 tr("Could not delete the file '%s' (%Rrc)"), 2499 RTPathFilename(strSrcFilePath.c_str()), vrc); 2500 } 2495 2501 } 2496 2502 } -
trunk/src/VBox/Runtime/common/zip/zip.cpp
r47343 r47500 616 616 } 617 617 618 /** 619 * pZip->u.Zlib.avail_in must be correctly initialized before 620 * calling this function 621 * pZip->u.Zlib.next_in must be correctly initialized before 622 * calling this function 623 * 624 * @param pZip The decompressor instance. 625 * @param pvBufOut Where to store the decompressed data. 626 * @param cbBufOut Number of bytes to produce. 627 * @param pcbWritten Number of bytes actually written to the 628 * buffer 629 * 630 * @return iprt status code. 631 */ 632 static DECLCALLBACK(int) rtZipZlibBufferDecompress(PRTZIPDECOMP pZip, void *pvBufOut, size_t cbBufOut, size_t *pcbWritten) 633 { 634 int rc = VINF_SUCCESS; 635 pZip->u.Zlib.next_out = (Bytef *)pvBufOut; 636 pZip->u.Zlib.avail_out = (uInt)cbBufOut; 637 int sh = pZip->u.Zlib.avail_out; 638 639 *pcbWritten = 0; 640 641 do 642 { 643 rc = inflate(&pZip->u.Zlib, Z_SYNC_FLUSH); 644 645 if (rc != Z_OK && rc != Z_STREAM_END) 646 { 647 rc = zipErrConvertFromZlib(rc, false /*fCompressing*/); 648 break; 649 } 650 651 *pcbWritten += (sh - pZip->u.Zlib.avail_out); 652 sh = pZip->u.Zlib.avail_out; 653 } 654 while (pZip->u.Zlib.avail_out > 0 && pZip->u.Zlib.avail_in > 0 ); 655 656 return rc; 657 } 618 658 619 659 /** … … 1637 1677 } 1638 1678 1679 /** 1680 * Lazy init of the decompressor for the Gzip file. 1681 * @return iprt status code. 1682 * @param pZip The decompressor instance. 1683 */ 1684 static int rtzipGzipFileDecompInit(PRTZIPDECOMP pZip) 1685 { 1686 int rc = 0; 1687 #ifdef RTZIP_USE_ZLIB 1688 pZip->pfnDecompress = rtZipZlibBufferDecompress; 1689 pZip->pfnDestroy = rtZipZlibDecompDestroy; 1690 1691 memset(&pZip->u.Zlib, 0, sizeof(pZip->u.Zlib)); 1692 pZip->enmType = RTZIPTYPE_ZLIB; 1693 pZip->u.Zlib.opaque = pZip; 1694 1695 rc = inflateInit2(&pZip->u.Zlib, MAX_WBITS + 16 /* autodetect gzip header */); 1696 rc >= 0 ? VINF_SUCCESS : zipErrConvertFromZlib(rc, false /*fCompressing*/); 1697 #else 1698 AssertMsgFailed(("Zlib is not include in this build!\n")); 1699 #endif 1700 1701 if (RT_FAILURE(rc)) 1702 { 1703 pZip->pfnDecompress = rtZipStubDecompress; 1704 pZip->pfnDestroy = rtZipStubDecompDestroy; 1705 } 1706 1707 return rc; 1708 } 1709 1710 /** 1711 * Decompresses a chunk of Gzip file. 1712 * 1713 * @returns iprt status code. 1714 * @param pZip The stream decompressor instance. 1715 * @param pvBufIn Where to read the compressed data from. 1716 * @param cbBufIn Number of bytes to read. 1717 * @param pcbRead Number of bytes actually read from the 1718 * buffer 1719 * @param pvBufOut Where to store the decompressed data. 1720 * @param cbBufOut Number of bytes to produce. 1721 * @param pcbWritten Number of bytes actually written to the 1722 * buffer. 1723 */ 1724 RTDECL(int) RTZipGzipFileBufferDecompress(PRTZIPDECOMP pZip, 1725 void *pvBufIn, 1726 size_t cbBufIn, 1727 size_t *pcbRead, 1728 void *pvBufOut, 1729 size_t cbBufOut, 1730 size_t *pcbWritten) 1731 { 1732 int rc; 1733 /* 1734 * Skip empty requests. 1735 */ 1736 if (!cbBufIn) 1737 return VINF_SUCCESS; 1738 1739 if (!pZip->pfnDecompress) 1740 { 1741 rc = rtzipGzipFileDecompInit(pZip); 1742 if (RT_FAILURE(rc)) 1743 return rc; 1744 } 1745 1746 pZip->u.Zlib.avail_in = (uInt)cbBufIn; 1747 pZip->u.Zlib.next_in = (Bytef *)pvBufIn; 1748 1749 /* 1750 * 'Read' the decompressed stream. 1751 */ 1752 rc = pZip->pfnDecompress(pZip, pvBufOut, cbBufOut, pcbWritten); 1753 1754 *pcbRead = cbBufIn - pZip->u.Zlib.avail_in; 1755 1756 return rc; 1757 } 1758 RT_EXPORT_SYMBOL(RTZipGzipFileBufferDecompress); 1639 1759 1640 1760 /**
Note:
See TracChangeset
for help on using the changeset viewer.