Changeset 77830 in vbox for trunk/src/VBox
- Timestamp:
- Mar 21, 2019 6:07:40 PM (6 years ago)
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 1 added
- 2 edited
- 2 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/Makefile.kmk
r77825 r77830 666 666 generic/RTEnvDupEx-generic.cpp \ 667 667 generic/RTFileCopy-generic.cpp \ 668 generic/RTFileCopyAttributes-generic.cpp \ 668 669 generic/RTFileCopyEx-generic.cpp \ 669 670 generic/RTFileCopyByHandlesEx-generic.cpp \ 670 generic/RTFileCopy Range-generic.cpp \671 generic/RTFileCopy RangeEx-generic.cpp \671 generic/RTFileCopyPart-generic.cpp \ 672 generic/RTFileCopyPartEx-generic.cpp \ 672 673 generic/RTFileQuerySize-generic.cpp \ 673 674 generic/RTFileReadAll-generic.cpp \ … … 1790 1791 generic/RTEnvDupEx-generic.cpp \ 1791 1792 generic/RTFileCopy-generic.cpp \ 1793 generic/RTFileCopyAttributes-generic.cpp \ 1792 1794 generic/RTFileCopyEx-generic.cpp \ 1793 1795 generic/RTFileCopyByHandlesEx-generic.cpp \ 1796 generic/RTFileCopyPartEx-generic.cpp \ 1794 1797 generic/RTFileQuerySize-generic.cpp \ 1795 1798 generic/RTFileReadAll-generic.cpp \ -
trunk/src/VBox/Runtime/generic/RTFileCopyByHandlesEx-generic.cpp
r77825 r77830 38 38 39 39 40 RTDECL(int) RTFileCopyByHandlesEx(RTFILE FileSrc, RTFILEFileDst, PFNRTPROGRESS pfnProgress, void *pvUser)40 RTDECL(int) RTFileCopyByHandlesEx(RTFILE hFileSrc, RTFILE hFileDst, PFNRTPROGRESS pfnProgress, void *pvUser) 41 41 { 42 42 /* 43 43 * Validate input. 44 44 */ 45 AssertMsgReturn(RTFileIsValid( FileSrc), ("FileSrc=%RTfile\n",FileSrc), VERR_INVALID_PARAMETER);46 AssertMsgReturn(RTFileIsValid( FileDst), ("FileDst=%RTfile\n",FileDst), VERR_INVALID_PARAMETER);45 AssertMsgReturn(RTFileIsValid(hFileSrc), ("hFileSrc=%RTfile\n", hFileSrc), VERR_INVALID_PARAMETER); 46 AssertMsgReturn(RTFileIsValid(hFileDst), ("hFileDst=%RTfile\n", hFileDst), VERR_INVALID_PARAMETER); 47 47 AssertMsgReturn(!pfnProgress || VALID_PTR(pfnProgress), ("pfnProgress=%p\n", pfnProgress), VERR_INVALID_PARAMETER); 48 48 … … 50 50 * Save file offset. 51 51 */ 52 RTFOFFoffSrcSaved;53 int rc = RTFileSeek( FileSrc, 0, RTFILE_SEEK_CURRENT, (uint64_t *)&offSrcSaved);52 uint64_t offSrcSaved; 53 int rc = RTFileSeek(hFileSrc, 0, RTFILE_SEEK_CURRENT, &offSrcSaved); 54 54 if (RT_FAILURE(rc)) 55 55 return rc; 56 56 57 57 /* 58 * Get the file size .58 * Get the file size and figure out how much we'll copy at a time. 59 59 */ 60 RTFOFFcbSrc;61 rc = RTFile Seek(FileSrc, 0, RTFILE_SEEK_END, (uint64_t *)&cbSrc);60 uint64_t cbSrc; 61 rc = RTFileGetSize(hFileSrc, &cbSrc); 62 62 if (RT_FAILURE(rc)) 63 63 return rc; 64 64 65 uint64_t cbChunk = cbSrc; 66 if (pfnProgress && cbSrc > _1M) 67 { 68 cbChunk /= 100; 69 if (cbChunk > _64M) 70 cbChunk = RT_ALIGN_64(cbChunk, _2M); 71 else 72 cbChunk = RT_ALIGN_64(cbChunk, _128K); 73 } 74 65 75 /* 66 * Allocate buffer.76 * Prepare buffers. 67 77 */ 68 size_t cbBuf; 69 uint8_t *pbBufFree = NULL; 70 uint8_t *pbBuf; 71 if (cbSrc < _512K) 72 { 73 cbBuf = 8*_1K; 74 pbBuf = (uint8_t *)alloca(cbBuf); 75 } 76 else 77 { 78 cbBuf = _128K; 79 pbBuf = pbBufFree = (uint8_t *)RTMemTmpAlloc(cbBuf); 80 } 81 if (pbBuf) 78 RTFILECOPYPARTBUFSTATE BufState; 79 rc = RTFileCopyPartPrep(&BufState, cbChunk); 80 if (RT_SUCCESS(rc)) 82 81 { 83 82 /* 84 * Seek to the start of each file 85 * and set the size of the destination file. 83 * Prepare the destination file. 86 84 */ 87 rc = RTFileSeek(FileSrc, 0, RTFILE_SEEK_BEGIN, NULL); 85 uint64_t cbDst; 86 rc = RTFileGetSize(hFileDst, &cbDst); 87 if (RT_SUCCESS(rc) && cbDst > cbSrc) 88 rc = RTFileSetSize(hFileDst, cbSrc); 89 if (RT_SUCCESS(rc) && cbDst < cbSrc) 90 { 91 rc = RTFileSetAllocationSize(hFileDst, cbSrc, RTFILE_ALLOC_SIZE_F_DEFAULT); 92 if (rc == VERR_NOT_SUPPORTED) 93 rc = RTFileSetSize(hFileDst, cbSrc); 94 } 88 95 if (RT_SUCCESS(rc)) 89 96 { 90 rc = RTFileSeek(FileDst, 0, RTFILE_SEEK_BEGIN, NULL); 91 if (RT_SUCCESS(rc)) 92 rc = RTFileSetSize(FileDst, cbSrc); 93 if (RT_SUCCESS(rc) && pfnProgress) 94 rc = pfnProgress(0, pvUser); 95 if (RT_SUCCESS(rc)) 97 /* 98 * Copy loop that works till we reach EOF. 99 */ 100 RTFOFF off = 0; 101 RTFOFF cbPercent = cbSrc / 100; 102 RTFOFF offNextPercent = pfnProgress ? cbPercent : RTFOFF_MAX; 103 unsigned uPercentage = pfnProgress ? 0 : 100; 104 for (;;) 96 105 { 97 106 /* 98 * Copy loop.107 * Copy a block. 99 108 */ 100 u nsigned uPercentage= 0;101 RTFOFF off = 0;102 RTFOFF cbPercent = cbSrc / 100;103 RTFOFF offNextPercent = cbPercent;104 while (off < cbSrc)109 uint64_t cbCopied = 0; 110 rc = RTFileCopyPartEx(hFileSrc, off, hFileDst, off, cbChunk, 0 /*fFlags*/, &BufState, &cbCopied); 111 if (RT_FAILURE(rc)) 112 break; 113 if (cbCopied == 0) 105 114 { 106 /* copy block */ 107 RTFOFF cbLeft = cbSrc - off; 108 size_t cbBlock = cbLeft >= (RTFOFF)cbBuf ? cbBuf : (size_t)cbLeft; 109 rc = RTFileRead(FileSrc, pbBuf, cbBlock, NULL); 115 /* 116 * We reached the EOF. Complete the copy operation. 117 */ 118 rc = RTFileSetSize(hFileDst, off); 119 if (RT_SUCCESS(rc)) 120 rc = RTFileCopyAttributes(hFileSrc, hFileDst, 0); 121 break; 122 } 123 124 /* 125 * Advance and work the progress callback. 126 */ 127 off += cbCopied; 128 if ( off >= offNextPercent 129 && pfnProgress 130 && uPercentage < 99) 131 { 132 do 133 { 134 uPercentage++; 135 offNextPercent += cbPercent; 136 } while ( offNextPercent <= off 137 && uPercentage < 99); 138 rc = pfnProgress(uPercentage, pvUser); 110 139 if (RT_FAILURE(rc)) 111 140 break; 112 rc = RTFileWrite(FileDst, pbBuf, cbBlock, NULL);113 if (RT_FAILURE(rc))114 break;115 116 /* advance */117 off += cbBlock;118 if (pfnProgress && offNextPercent < off && uPercentage < 100)119 {120 do121 {122 uPercentage++;123 offNextPercent += cbPercent;124 } while (offNextPercent < off && uPercentage < 100);125 rc = pfnProgress(uPercentage, pvUser);126 if (RT_FAILURE(rc))127 break;128 }129 141 } 130 131 #if 0132 /*133 * Copy OS specific data (EAs and stuff).134 */135 rtFileCopyOSStuff(FileSrc, FileDst);136 #endif137 138 /* 100% */139 if (pfnProgress && uPercentage < 100 && RT_SUCCESS(rc))140 rc = pfnProgress(100, pvUser);141 142 } 142 143 } 143 RTMemTmpFree(pbBufFree); 144 145 RTFileCopyPartCleanup(&BufState); 146 147 /* 148 * 100%. 149 */ 150 if ( pfnProgress 151 && RT_SUCCESS(rc)) 152 rc = pfnProgress(100, pvUser); 144 153 } 145 else146 rc = VERR_NO_MEMORY;147 154 148 155 /* 149 156 * Restore source position. 150 157 */ 151 RTFileSeek(FileSrc, offSrcSaved, RTFILE_SEEK_BEGIN, NULL); 152 158 RTFileSeek(hFileSrc, offSrcSaved, RTFILE_SEEK_BEGIN, NULL); 153 159 return rc; 154 160 }
Note:
See TracChangeset
for help on using the changeset viewer.