Changeset 77825 in vbox for trunk/src/VBox/Runtime/r3/fileio.cpp
- Timestamp:
- Mar 21, 2019 12:33:42 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 129505
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/fileio.cpp
r77209 r77825 240 240 { 241 241 return RTFileCopyByHandlesEx(FileSrc, FileDst, NULL, NULL); 242 }243 244 245 RTDECL(int) RTFileCopyEx(const char *pszSrc, const char *pszDst, uint32_t fFlags, PFNRTPROGRESS pfnProgress, void *pvUser)246 {247 /*248 * Validate input.249 */250 AssertMsgReturn(VALID_PTR(pszSrc), ("pszSrc=%p\n", pszSrc), VERR_INVALID_PARAMETER);251 AssertMsgReturn(*pszSrc, ("pszSrc=%p\n", pszSrc), VERR_INVALID_PARAMETER);252 AssertMsgReturn(VALID_PTR(pszDst), ("pszDst=%p\n", pszDst), VERR_INVALID_PARAMETER);253 AssertMsgReturn(*pszDst, ("pszDst=%p\n", pszDst), VERR_INVALID_PARAMETER);254 AssertMsgReturn(!pfnProgress || VALID_PTR(pfnProgress), ("pfnProgress=%p\n", pfnProgress), VERR_INVALID_PARAMETER);255 AssertMsgReturn(!(fFlags & ~RTFILECOPY_FLAGS_MASK), ("%#x\n", fFlags), VERR_INVALID_PARAMETER);256 257 /*258 * Open the files.259 */260 RTFILE FileSrc;261 int rc = RTFileOpen(&FileSrc, pszSrc,262 RTFILE_O_READ | RTFILE_O_OPEN263 | (fFlags & RTFILECOPY_FLAGS_NO_SRC_DENY_WRITE ? RTFILE_O_DENY_NONE : RTFILE_O_DENY_WRITE));264 if (RT_SUCCESS(rc))265 {266 RTFILE FileDst;267 rc = RTFileOpen(&FileDst, pszDst,268 RTFILE_O_WRITE | RTFILE_O_CREATE269 | (fFlags & RTFILECOPY_FLAGS_NO_DST_DENY_WRITE ? RTFILE_O_DENY_NONE : RTFILE_O_DENY_WRITE));270 if (RT_SUCCESS(rc))271 {272 /*273 * Call the ByHandles version and let it do the job.274 */275 rc = RTFileCopyByHandlesEx(FileSrc, FileDst, pfnProgress, pvUser);276 277 /*278 * Close the files regardless of the result.279 * Don't bother cleaning up or anything like that.280 */281 int rc2 = RTFileClose(FileDst);282 AssertRC(rc2);283 if (RT_FAILURE(rc2) && RT_SUCCESS(rc))284 rc = rc2;285 }286 287 int rc2 = RTFileClose(FileSrc);288 AssertRC(rc2);289 if (RT_FAILURE(rc2) && RT_SUCCESS(rc))290 rc = rc2;291 }292 return rc;293 }294 295 296 RTDECL(int) RTFileCopyByHandlesEx(RTFILE FileSrc, RTFILE FileDst, PFNRTPROGRESS pfnProgress, void *pvUser)297 {298 /*299 * Validate input.300 */301 AssertMsgReturn(RTFileIsValid(FileSrc), ("FileSrc=%RTfile\n", FileSrc), VERR_INVALID_PARAMETER);302 AssertMsgReturn(RTFileIsValid(FileDst), ("FileDst=%RTfile\n", FileDst), VERR_INVALID_PARAMETER);303 AssertMsgReturn(!pfnProgress || VALID_PTR(pfnProgress), ("pfnProgress=%p\n", pfnProgress), VERR_INVALID_PARAMETER);304 305 /*306 * Save file offset.307 */308 RTFOFF offSrcSaved;309 int rc = RTFileSeek(FileSrc, 0, RTFILE_SEEK_CURRENT, (uint64_t *)&offSrcSaved);310 if (RT_FAILURE(rc))311 return rc;312 313 /*314 * Get the file size.315 */316 RTFOFF cbSrc;317 rc = RTFileSeek(FileSrc, 0, RTFILE_SEEK_END, (uint64_t *)&cbSrc);318 if (RT_FAILURE(rc))319 return rc;320 321 /*322 * Allocate buffer.323 */324 size_t cbBuf;325 uint8_t *pbBufFree = NULL;326 uint8_t *pbBuf;327 if (cbSrc < _512K)328 {329 cbBuf = 8*_1K;330 pbBuf = (uint8_t *)alloca(cbBuf);331 }332 else333 {334 cbBuf = _128K;335 pbBuf = pbBufFree = (uint8_t *)RTMemTmpAlloc(cbBuf);336 }337 if (pbBuf)338 {339 /*340 * Seek to the start of each file341 * and set the size of the destination file.342 */343 rc = RTFileSeek(FileSrc, 0, RTFILE_SEEK_BEGIN, NULL);344 if (RT_SUCCESS(rc))345 {346 rc = RTFileSeek(FileDst, 0, RTFILE_SEEK_BEGIN, NULL);347 if (RT_SUCCESS(rc))348 rc = RTFileSetSize(FileDst, cbSrc);349 if (RT_SUCCESS(rc) && pfnProgress)350 rc = pfnProgress(0, pvUser);351 if (RT_SUCCESS(rc))352 {353 /*354 * Copy loop.355 */356 unsigned uPercentage = 0;357 RTFOFF off = 0;358 RTFOFF cbPercent = cbSrc / 100;359 RTFOFF offNextPercent = cbPercent;360 while (off < cbSrc)361 {362 /* copy block */363 RTFOFF cbLeft = cbSrc - off;364 size_t cbBlock = cbLeft >= (RTFOFF)cbBuf ? cbBuf : (size_t)cbLeft;365 rc = RTFileRead(FileSrc, pbBuf, cbBlock, NULL);366 if (RT_FAILURE(rc))367 break;368 rc = RTFileWrite(FileDst, pbBuf, cbBlock, NULL);369 if (RT_FAILURE(rc))370 break;371 372 /* advance */373 off += cbBlock;374 if (pfnProgress && offNextPercent < off && uPercentage < 100)375 {376 do377 {378 uPercentage++;379 offNextPercent += cbPercent;380 } while (offNextPercent < off && uPercentage < 100);381 rc = pfnProgress(uPercentage, pvUser);382 if (RT_FAILURE(rc))383 break;384 }385 }386 387 #if 0388 /*389 * Copy OS specific data (EAs and stuff).390 */391 rtFileCopyOSStuff(FileSrc, FileDst);392 #endif393 394 /* 100% */395 if (pfnProgress && uPercentage < 100 && RT_SUCCESS(rc))396 rc = pfnProgress(100, pvUser);397 }398 }399 RTMemTmpFree(pbBufFree);400 }401 else402 rc = VERR_NO_MEMORY;403 404 /*405 * Restore source position.406 */407 RTFileSeek(FileSrc, offSrcSaved, RTFILE_SEEK_BEGIN, NULL);408 409 return rc;410 242 } 411 243
Note:
See TracChangeset
for help on using the changeset viewer.