Changeset 67860 in vbox
- Timestamp:
- Jul 7, 2017 4:08:30 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 116816
- Location:
- trunk/src/VBox/Runtime/common/fs
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fs/isomaker.cpp
r67850 r67860 5343 5343 pER->cchDescription = sizeof(ISO9660_RRIP_DESC) - 1; 5344 5344 pER->cchSource = sizeof(ISO9660_RRIP_SRC) - 1; 5345 pER->bVersion = ISO9660_RRIP_VER; 5345 5346 memcpy(&pER->achPayload[0], RT_STR_TUPLE(ISO9660_RRIP_ID)); 5346 memcpy(&pER->achPayload[sizeof(ISO9660_RRIP_ID) ], RT_STR_TUPLE(ISO9660_RRIP_DESC));5347 memcpy(&pER->achPayload[sizeof(ISO9660_RRIP_ID) + sizeof(ISO9660_RRIP_DESC)], RT_STR_TUPLE(ISO9660_RRIP_SRC));5347 memcpy(&pER->achPayload[sizeof(ISO9660_RRIP_ID) - 1], RT_STR_TUPLE(ISO9660_RRIP_DESC)); 5348 memcpy(&pER->achPayload[sizeof(ISO9660_RRIP_ID) - 1 + sizeof(ISO9660_RRIP_DESC) - 1], RT_STR_TUPLE(ISO9660_RRIP_SRC)); 5348 5349 pbSys += ISO9660_RRIP_ER_LEN; 5349 5350 cbSys -= ISO9660_RRIP_ER_LEN; … … 6332 6333 uint8_t abTmpBuf[256]; 6333 6334 Assert(pName->cbDirRec <= sizeof(abTmpBuf)); 6334 uint32_t const cbOne = rtFsIsoMakerOutFile_GenerateDirRec(pName, fUnicode, pbBuf, pFinalizedDirs);6335 uint32_t const cbOne = rtFsIsoMakerOutFile_GenerateDirRec(pName, fUnicode, abTmpBuf, pFinalizedDirs); 6335 6336 Assert(cbOne == pName->cbDirRec); 6336 6337 if (cbOne == pName->cbDirRecTotal) … … 6461 6462 uint8_t cbSysUse = pDirRec->cbDirRec - offSysUse; 6462 6463 if (cbSysUse > 0) 6463 memmove(&pDirRec->achFileId[1], & pbBuf[offSysUse], cbSysUse);6464 memmove(&pDirRec->achFileId[1], &abTmpBuf[offSysUse], cbSysUse); 6464 6465 pDirRec->bFileIdLength = 1; 6465 6466 cbToCopy = RT_UOFFSETOF(ISO9660DIRREC, achFileId) + 1 + cbSysUse; … … 6519 6520 pDir = RTListGetFirst(&pFinalizedDirs->FinalizedDirs, RTFSISOMAKERNAMEDIR, FinalizedEntry); 6520 6521 AssertReturnStmt(pDir, *pbBuf = 0xff, 1); 6522 offInDir64 = offUnsigned - pDir->offDir; 6521 6523 } 6522 6524 /* Seek backwards: */ -
trunk/src/VBox/Runtime/common/fs/isomakercmd.cpp
r67605 r67860 33 33 #include <iprt/fsisomaker.h> 34 34 35 #include <iprt/asm.h> 35 36 #include <iprt/assert.h> 36 37 #include <iprt/buildconfig.h> … … 93 94 RTFSISOMAKERCMD_OPT_OUTPUT_BUFFER_SIZE, 94 95 RTFSISOMAKERCMD_OPT_RANDOM_OUTPUT_BUFFER_SIZE, 96 RTFSISOMAKERCMD_OPT_RANDOM_ORDER_VERIFICATION, 95 97 RTFSISOMAKERCMD_OPT_NAME_SETUP, 96 98 RTFSISOMAKERCMD_OPT_NO_JOLIET, … … 312 314 * when this is enabled. */ 313 315 bool fRandomOutputReadBufferSize; 316 /** Do output verification, but do it in random order if non-zero. The 317 * values gives the block size to use. */ 318 uint32_t cbRandomOrderVerifciationBlock; 314 319 315 320 /** @name Processing of inputs … … 414 419 { "--output-buffer-size", RTFSISOMAKERCMD_OPT_OUTPUT_BUFFER_SIZE, RTGETOPT_REQ_UINT32 }, 415 420 { "--random-output-buffer-size", RTFSISOMAKERCMD_OPT_RANDOM_OUTPUT_BUFFER_SIZE, RTGETOPT_REQ_NOTHING }, 421 { "--random-order-verficiation", RTFSISOMAKERCMD_OPT_RANDOM_ORDER_VERIFICATION, RTGETOPT_REQ_UINT32 }, 416 422 { "--name-setup", RTFSISOMAKERCMD_OPT_NAME_SETUP, RTGETOPT_REQ_STRING }, 417 423 { "--no-joliet", RTFSISOMAKERCMD_OPT_NO_JOLIET, RTGETOPT_REQ_NOTHING }, … … 731 737 } 732 738 739 static int rtFsIsoMakerCmdVerifyImageInRandomOrder(PRTFSISOMAKERCMDOPTS pOpts, RTVFSFILE hVfsSrcFile, RTVFSFILE hVfsDstFile, uint64_t cbImage) 740 { 741 /* 742 * Figure the buffer (block) size and allocate a bitmap for noting down blocks we've covered. 743 */ 744 int rc; 745 size_t cbBuf = RT_MAX(pOpts->cbRandomOrderVerifciationBlock, 1); 746 uint64_t cBlocks64 = (cbImage + cbBuf - 1) / cbBuf; 747 if (cBlocks64 > _512M) 748 return rtFsIsoMakerCmdErrorRc(pOpts, VERR_OUT_OF_RANGE, 749 "verification block count too high: cBlocks=%#RX64 (cbBuf=%#zx), max 512M", cBlocks64, cbBuf); 750 uint32_t cBlocks = (uint32_t)cBlocks64; 751 uint32_t cbBitmap = (cBlocks + 63) / 8; 752 if (cbBitmap > _64M) 753 return rtFsIsoMakerCmdErrorRc(pOpts, VERR_OUT_OF_RANGE, 754 "verification bitmap too big: cbBitmap=%#RX32 (cbBuf=%#zx), max 64MB", cbBitmap, cbBuf); 755 void *pvSrcBuf = RTMemTmpAlloc(cbBuf); 756 void *pvDstBuf = RTMemTmpAlloc(cbBuf); 757 void *pvBitmap = RTMemTmpAllocZ(cbBitmap); 758 if (pvSrcBuf && pvDstBuf && pvBitmap) 759 { 760 /* Must set the unused bits in the top qword. */ 761 for (uint32_t i = RT_ALIGN_32(cBlocks, 64) - 1; i >= cBlocks; i--) 762 ASMBitSet(pvBitmap, i); 763 764 /* 765 * Do the verification. 766 */ 767 rtFsIsoMakerPrintf(pOpts, "Verifying image in random order using %zu (%#zx) byte blocks: %#zx in blocks\n", 768 cbBuf, cbBuf, cBlocks); 769 770 rc = VINF_SUCCESS; 771 uint64_t cLeft = cBlocks; 772 while (cLeft-- > 0) 773 { 774 /* 775 * Figure out which block to check next. 776 */ 777 uint32_t iBlock = RTRandU32Ex(0, cBlocks - 1); 778 if (!ASMBitTestAndSet(pvBitmap, iBlock)) 779 Assert(iBlock < (int32_t)cBlocks); 780 else 781 { 782 /* try 32 other random numbers. */ 783 bool fBitSet; 784 unsigned cTries = 0; 785 do 786 { 787 iBlock = RTRandU32Ex(0, cBlocks - 1); 788 fBitSet = ASMBitTestAndSet(pvBitmap, iBlock); 789 } while (fBitSet && ++cTries < 32); 790 if (fBitSet) 791 { 792 /* Look for the next clear bit after it (with wrap around). */ 793 int iHit = ASMBitNextClear(pvBitmap, cBlocks, iBlock); 794 Assert(iHit < (int32_t)cBlocks); 795 if (iHit < 0) 796 { 797 iHit = ASMBitNextClear(pvBitmap, iBlock, 0); 798 Assert(iHit < (int32_t)cBlocks); 799 } 800 if (iHit >= 0) 801 { 802 fBitSet = ASMBitTestAndSet(pvBitmap, iHit); 803 if (!fBitSet) 804 iBlock = iHit; 805 else 806 { 807 rc = rtFsIsoMakerCmdErrorRc(pOpts, VERR_INTERNAL_ERROR_3, 808 "Bitmap weirdness: iHit=%#x iBlock=%#x cBlocks=%#x", 809 iHit, iBlock, cBlocks); 810 break; 811 } 812 } 813 else 814 { 815 rc = rtFsIsoMakerCmdErrorRc(pOpts, VERR_INTERNAL_ERROR_2, "Bitmap weirdness: iBlock=%#x cBlocks=%#x", 816 iBlock, cBlocks); 817 break; 818 } 819 } 820 } 821 Assert(ASMBitTest(pvBitmap, iBlock)); 822 823 /* 824 * Figure out how much and where to read (last block fun). 825 */ 826 uint64_t offBlock = iBlock * (uint64_t)cbBuf; 827 size_t cbToRead = cbBuf; 828 if (iBlock + 1 < cBlocks) 829 { /* likely */ } 830 else if (cbToRead > cbImage - offBlock) 831 cbToRead = (size_t)(cbImage - offBlock); 832 Assert(offBlock + cbToRead <= cbImage); 833 834 /* 835 * Read the blocks. 836 */ 837 //RTPrintf("Reading block #%#x at %#RX64\n", iBlock, offBlock); 838 rc = RTVfsFileReadAt(hVfsDstFile, offBlock, pvDstBuf, cbToRead, NULL); 839 if (RT_SUCCESS(rc)) 840 { 841 memset(pvSrcBuf, 0xdd, cbBuf); 842 rc = RTVfsFileReadAt(hVfsSrcFile, offBlock, pvSrcBuf, cbToRead, NULL); 843 if (RT_SUCCESS(rc)) 844 { 845 if (memcmp(pvDstBuf, pvSrcBuf, cbToRead) == 0) 846 continue; 847 rc = rtFsIsoMakerCmdErrorRc(pOpts, VERR_MISMATCH, 848 "Block #%#x differs! offBlock=%#RX64 cbToRead=%#zu\n" 849 "Virtual ISO (source):\n%.*Rhxd\nWritten ISO (destination):\n%.*Rhxd", 850 iBlock, offBlock, cbToRead, cbToRead, pvSrcBuf, cbToRead, pvDstBuf); 851 } 852 else 853 rc = rtFsIsoMakerCmdErrorRc(pOpts, rc, 854 "Error reading %#zx bytes source (virtual ISO) block #%#x at %#RX64: %Rrc", 855 cbToRead, iBlock, offBlock, rc); 856 } 857 else 858 rc = rtFsIsoMakerCmdErrorRc(pOpts, rc, 859 "Error reading %#zx bytes destination (written ISO) block #%#x at %#RX64: %Rrc", 860 cbToRead, iBlock, offBlock, rc); 861 break; 862 } 863 864 if (RT_SUCCESS(rc)) 865 rtFsIsoMakerPrintf(pOpts, "Written image verified fine!\n"); 866 } 867 else if (!pvSrcBuf || !pvDstBuf) 868 rc = rtFsIsoMakerCmdErrorRc(pOpts, VERR_NO_TMP_MEMORY, "RTMemTmpAlloc(%#zx) failed", cbBuf); 869 else 870 rc = rtFsIsoMakerCmdErrorRc(pOpts, VERR_NO_TMP_MEMORY, "RTMemTmpAlloc(%#zx) failed", cbBuf); 871 RTMemTmpFree(pvBitmap); 872 RTMemTmpFree(pvDstBuf); 873 RTMemTmpFree(pvSrcBuf); 874 return rc; 875 } 876 877 878 /** 879 * Writes the image to file, no checking, no special buffering. 880 * 881 * @returns IPRT status code. 882 * @param pOpts The ISO maker command instance. 883 * @param hVfsSrcFile The source file from the ISO maker. 884 */ 885 static int rtFsIsoMakerCmdWriteImageRandomBufferSize(PRTFSISOMAKERCMDOPTS pOpts, RTVFSFILE hVfsSrcFile, RTVFSFILE hVfsDstFile, 886 uint64_t cbImage, void **ppvBuf) 887 { 888 /* 889 * Copy the virtual image bits to the destination file. 890 */ 891 void *pvBuf = *ppvBuf; 892 uint32_t cbMaxBuf = pOpts->cbOutputReadBuffer > 0 ? pOpts->cbOutputReadBuffer : _64K; 893 uint64_t offImage = 0; 894 while (offImage < cbImage) 895 { 896 /* Figure out how much to copy this time. */ 897 size_t cbToCopy = RTRandU32Ex(1, cbMaxBuf - 1); 898 if (offImage + cbToCopy < cbImage) 899 { /* likely */ } 900 else 901 cbToCopy = (size_t)(cbImage - offImage); 902 RTMemFree(pvBuf); 903 *ppvBuf = pvBuf = RTMemTmpAlloc(cbToCopy); 904 if (pvBuf) 905 { 906 /* Do the copying. */ 907 int rc = RTVfsFileReadAt(hVfsSrcFile, offImage, pvBuf, cbToCopy, NULL); 908 if (RT_SUCCESS(rc)) 909 { 910 rc = RTVfsFileWriteAt(hVfsDstFile, offImage, pvBuf, cbToCopy, NULL); 911 if (RT_SUCCESS(rc)) 912 offImage += cbToCopy; 913 else 914 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error %Rrc writing %#zx bytes at offset %#RX64 to '%s'", 915 rc, cbToCopy, offImage, pOpts->pszOutFile); 916 } 917 else 918 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error %Rrc read %#zx bytes at offset %#RX64", rc, cbToCopy, offImage); 919 } 920 else 921 return rtFsIsoMakerCmdErrorRc(pOpts, VERR_NO_TMP_MEMORY, "RTMemTmpAlloc(%#zx) failed", cbToCopy); 922 } 923 return VINF_SUCCESS; 924 } 925 926 927 /** 928 * Writes the image to file, no checking, no special buffering. 929 * 930 * @returns IPRT status code. 931 * @param pOpts The ISO maker command instance. 932 * @param hVfsSrcFile The source file from the ISO maker. 933 */ 934 static int rtFsIsoMakerCmdWriteImageSimple(PRTFSISOMAKERCMDOPTS pOpts, RTVFSFILE hVfsSrcFile, RTVFSFILE hVfsDstFile, 935 uint64_t cbImage, void *pvBuf, size_t cbBuf) 936 { 937 /* 938 * Copy the virtual image bits to the destination file. 939 */ 940 uint64_t offImage = 0; 941 while (offImage < cbImage) 942 { 943 /* Figure out how much to copy this time. */ 944 size_t cbToCopy = cbBuf; 945 if (offImage + cbToCopy < cbImage) 946 { /* likely */ } 947 else 948 cbToCopy = (size_t)(cbImage - offImage); 949 950 /* Do the copying. */ 951 int rc = RTVfsFileReadAt(hVfsSrcFile, offImage, pvBuf, cbToCopy, NULL); 952 if (RT_SUCCESS(rc)) 953 { 954 rc = RTVfsFileWriteAt(hVfsDstFile, offImage, pvBuf, cbToCopy, NULL); 955 if (RT_SUCCESS(rc)) 956 offImage += cbToCopy; 957 else 958 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error %Rrc writing %#zx bytes at offset %#RX64 to '%s'", 959 rc, cbToCopy, offImage, pOpts->pszOutFile); 960 } 961 else 962 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error %Rrc read %#zx bytes at offset %#RX64", rc, cbToCopy, offImage); 963 } 964 return VINF_SUCCESS; 965 } 966 733 967 734 968 /** … … 760 994 uint32_t offError; 761 995 RTERRINFOSTATIC ErrInfo; 762 rc = RTVfsChainOpenFile(pOpts->pszOutFile, RTFILE_O_ WRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_WRITE,996 rc = RTVfsChainOpenFile(pOpts->pszOutFile, RTFILE_O_READWRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_WRITE, 763 997 &hVfsDstFile, &offError, RTErrInfoInitStatic(&ErrInfo)); 764 998 if (RT_SUCCESS(rc)) 765 999 { 766 1000 /* 767 * Copy the virtual image bits to the destination file.1001 * Apply the desired writing method. 768 1002 */ 769 uint64_t offImage = 0; 770 while (offImage < cbImage) 771 { 772 /* Figure out how much to copy this time. */ 773 size_t cbToCopy = cbBuf; 774 if (pOpts->fRandomOutputReadBufferSize) 775 cbToCopy = RTRandU32Ex(1, (uint32_t)cbBuf - 1); 776 if (offImage + cbToCopy < cbImage) 777 { /* likely */ } 778 else 779 cbToCopy = (size_t)(cbImage - offImage); 780 781 /* Do the copying. */ 782 rc = RTVfsFileReadAt(hVfsSrcFile, offImage, pvBuf, cbToCopy, NULL); 783 if (RT_SUCCESS(rc)) 784 { 785 rc = RTVfsFileWriteAt(hVfsDstFile, offImage, pvBuf, cbToCopy, NULL); 786 if (RT_SUCCESS(rc)) 787 offImage += cbToCopy; 788 else 789 { 790 rc = rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error %Rrc writing %#zx bytes at offset %#RX64 to '%s'", 791 rc, cbToCopy, offImage, pOpts->pszOutFile); 792 break; 793 } 794 } 795 else 796 { 797 rc = rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error %Rrc read %#zx bytes at offset %#RX64", rc, cbToCopy, offImage); 798 break; 799 } 800 } 1003 if (!pOpts->fRandomOutputReadBufferSize) 1004 rc = rtFsIsoMakerCmdWriteImageRandomBufferSize(pOpts, hVfsSrcFile, hVfsDstFile, cbImage, &pvBuf); 1005 else 1006 rc = rtFsIsoMakerCmdWriteImageSimple(pOpts, hVfsSrcFile, hVfsDstFile, cbImage, pvBuf, cbBuf); 1007 RTMemTmpFree(pvBuf); 1008 1009 if (RT_SUCCESS(rc) && pOpts->cbRandomOrderVerifciationBlock > 0) 1010 rc = rtFsIsoMakerCmdVerifyImageInRandomOrder(pOpts, hVfsSrcFile, hVfsDstFile, cbImage); 801 1011 802 1012 /* … … 813 1023 } 814 1024 else 1025 { 1026 RTMemTmpFree(pvBuf); 815 1027 rc = rtFsIsoMakerCmdChainError(pOpts, "RTVfsChainOpenFile", pOpts->pszOutFile, rc, offError, &ErrInfo.Core); 816 817 RTMemTmpFree(pvBuf); 1028 } 818 1029 } 819 1030 else 820 rc = rtFsIsoMakerCmdErrorRc(pOpts, rc, "RTMemTmpAlloc(%zu) failed: %Rrc", pOpts->cbOutputReadBuffer, rc);1031 rc = rtFsIsoMakerCmdErrorRc(pOpts, VERR_NO_TMP_MEMORY, "RTMemTmpAlloc(%zu) failed", cbBuf); 821 1032 } 822 1033 else … … 1409 1620 1410 1621 pOpts->cItemsAdded += Results.cAddedFiles; 1622 pOpts->cItemsAdded += Results.cAddedSymlinks; 1411 1623 pOpts->cItemsAdded += Results.cAddedDirs; 1412 1624 pOpts->cItemsAdded += Results.cBootCatEntries != UINT32_MAX ? Results.cBootCatEntries : 0; … … 1418 1630 rtFsIsoMakerPrintf(pOpts, " cbAddedDataBlocks: %'14RU64 bytes\n", Results.cbAddedDataBlocks); 1419 1631 rtFsIsoMakerPrintf(pOpts, " cAddedFiles: %'14RU32\n", Results.cAddedFiles); 1632 rtFsIsoMakerPrintf(pOpts, " cAddedSymlinks: %'14RU32\n", Results.cAddedSymlinks); 1420 1633 if (Results.cBootCatEntries == UINT32_MAX) 1421 1634 rtFsIsoMakerPrintf(pOpts, " cBootCatEntries: none\n"); … … 2078 2291 break; 2079 2292 2293 case RTFSISOMAKERCMD_OPT_OUTPUT_BUFFER_SIZE: /* --output-buffer-size {cb} */ 2294 pOpts->cbOutputReadBuffer = ValueUnion.u32; 2295 break; 2296 2297 case RTFSISOMAKERCMD_OPT_RANDOM_OUTPUT_BUFFER_SIZE: /* --random-output-buffer-size */ 2298 pOpts->fRandomOutputReadBufferSize = true; 2299 break; 2300 2301 case RTFSISOMAKERCMD_OPT_RANDOM_ORDER_VERIFICATION: /* --random-order-verficiation {cb} */ 2302 pOpts->cbRandomOrderVerifciationBlock = ValueUnion.u32; 2303 break; 2304 2080 2305 case RTFSISOMAKERCMD_OPT_IMPORT_ISO: 2081 2306 rc = rtFsIsoMakerCmdOptImportIso(pOpts, ValueUnion.psz); -
trunk/src/VBox/Runtime/common/fs/isomakerimport.cpp
r67850 r67860 2496 2496 pResults->cbAddedDataBlocks = 0; 2497 2497 pResults->cAddedFiles = 0; 2498 pResults->cAddedSymlinks = 0; 2498 2499 pResults->cBootCatEntries = UINT32_MAX; 2499 2500 pResults->cbSysArea = 0;
Note:
See TracChangeset
for help on using the changeset viewer.