儲存庫 vbox 的更動 67332
- 時間撮記:
- 2017-6-11 下午02:35:05 (7 年 以前)
- 檔案:
-
- 修改 1 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/VBox/Runtime/common/fs/isomaker.cpp
r67331 r67332 65 65 /** The sector size. */ 66 66 #define RTFSISOMAKER_SECTOR_SIZE _2K 67 /** The sector offset mask. */ 68 #define RTFSISOMAKER_SECTOR_OFFSET_MASK (_2K - 1) 67 69 /** Maximum number of objects. */ 68 70 #define RTFSISOMAKER_MAX_OBJECTS _16M … … 72 74 /** UTF-8 name buffer. */ 73 75 #define RTFSISOMAKER_MAX_NAME_BUF 768 76 77 /** TRANS.TBL left padding length. 78 * We keep the amount of padding low to avoid wasing memory when generating 79 * these long obsolete files. */ 80 #define RTFSISOMAKER_TRANS_TBL_LEFT_PAD 12 74 81 75 82 /** Tests if @a a_ch is in the set of d-characters. */ … … 207 214 uint32_t cHardlinks; 208 215 209 /** The offset of the translate table file entry. */210 uint32_t offTransTbl;211 216 /** The offset of the directory entry in the parent directory. */ 212 217 uint32_t offDirRec; … … 515 520 * RTFSISOMAKERSRCTYPE_TRANS_TBL file. */ 516 521 RTVFSFILE hVfsSrcFile; 522 /** Current directory hint. */ 523 PRTFSISOMAKERNAMEDIR pDirHint; 517 524 } RTFSISOMAKEROUTPUTFILE; 518 525 /** Pointer to the instance data of an ISO maker output file. */ … … 1649 1656 * Add it to the directory. 1650 1657 */ 1658 PRTFSISOMAKERNAME pTransTblNm; 1651 1659 rc = rtFsIsoMakerObjSetName(pThis, pNamespace, &pFile->Core, pDirName, 1652 pNamespace->pszTransTbl, strlen(pNamespace->pszTransTbl), NULL /*ppNewName*/);1660 pNamespace->pszTransTbl, strlen(pNamespace->pszTransTbl), &pTransTblNm); 1653 1661 if (RT_SUCCESS(rc)) 1662 { 1663 pTransTblNm->cchTransNm = 0; 1654 1664 return VINF_SUCCESS; 1665 } 1655 1666 1656 1667 /* … … 1747 1758 pName->pszTransNm = pszDst; 1748 1759 pName->cchSpecNm = (uint16_t)cchSpec; 1749 pName->cchRockRidgeNm = 0;1750 pName->cchTransNm = 0;1760 pName->cchRockRidgeNm = (uint16_t)cchSpec; 1761 pName->cchTransNm = (uint16_t)cchSpec; 1751 1762 pName->uDepth = pParent->uDepth + 1; 1752 1763 pName->fRockRidgeNmAlloced = false; … … 1759 1770 pName->INode = pObj->idxObj; 1760 1771 pName->cHardlinks = 1; 1761 pName->offTransTbl = UINT32_MAX;1762 1772 pName->offDirRec = UINT32_MAX; 1763 1773 pName->cbDirRec = 0; … … 2815 2825 */ 2816 2826 static int rtFsIsoMakerFinalizeIsoDirectoryEntry(PRTFSISOMAKERFINALIZEDDIRS pFinalizedDirs, PRTFSISOMAKERNAME pName, 2817 uint32_t offInDir, uint 32_t offInTransTbl, uint8_t uRootRockRidge)2827 uint32_t offInDir, uint8_t uRootRockRidge) 2818 2828 { 2819 2829 /* Set directory and translation table offsets. (These are for 2820 2830 helping generating data blocks later.) */ 2821 2831 pName->offDirRec = offInDir; 2822 pName->offTransTbl = offInTransTbl;2823 2832 2824 2833 /* Calculate the minimal directory record size. */ … … 2881 2890 * Precalc the directory record size for the root directory. 2882 2891 */ 2883 rc = rtFsIsoMakerFinalizeIsoDirectoryEntry(pFinalizedDirs, pNamespace->pRoot, 0 /*offInDir*/, 0 /*offInTransTbl*/, 2884 pNamespace->uRockRidgeLevel); 2892 rc = rtFsIsoMakerFinalizeIsoDirectoryEntry(pFinalizedDirs, pNamespace->pRoot, 0 /*offInDir*/, pNamespace->uRockRidgeLevel); 2885 2893 AssertRCReturn(rc, rc); 2886 2894 … … 2902 2910 2903 2911 /* Finalize the directory entries. */ 2904 uint32_t offInTransTbl= 0;2905 uint32_t cLeft 2906 PPRTFSISOMAKERNAME ppChild 2912 uint32_t cbTransTbl = 0; 2913 uint32_t cLeft = pCurDir->cChildren; 2914 PPRTFSISOMAKERNAME ppChild = pCurDir->papChildren; 2907 2915 while (cLeft-- > 0) 2908 2916 { 2909 2917 PRTFSISOMAKERNAME pChild = *ppChild++; 2910 rc = rtFsIsoMakerFinalizeIsoDirectoryEntry(pFinalizedDirs, pChild, offInDir, offInTransTbl,0 /*uRootRockRidge*/);2918 rc = rtFsIsoMakerFinalizeIsoDirectoryEntry(pFinalizedDirs, pChild, offInDir, 0 /*uRootRockRidge*/); 2911 2919 AssertRCReturn(rc, rc); 2912 2920 2913 2921 offInDir += pChild->cbDirRec; 2914 2922 if (pChild->cchTransNm) 2915 offInTransTbl += 2 /* type & space*/2916 + RT_MAX(pChild->cchName, 39)2917 2918 2919 2923 cbTransTbl += 2 /* type & space*/ 2924 + RT_MAX(pChild->cchName, RTFSISOMAKER_TRANS_TBL_LEFT_PAD) 2925 + 1 /* tab */ 2926 + pChild->cchTransNm 2927 + 1 /* newline */; 2920 2928 } 2921 2929 … … 2927 2935 /* Set the translation table file size. */ 2928 2936 if (pCurDir->pTransTblFile) 2929 pCurDir->pTransTblFile->cbData = offInTransTbl;2937 pCurDir->pTransTblFile->cbData = cbTransTbl; 2930 2938 2931 2939 /* Add to the path table size calculation. */ … … 3552 3560 if (pChild->pszTransNm) 3553 3561 { 3554 /** @todo TRANS.TBL codeset, currently using UTF-8 which is probably not it. */ 3562 /** @todo TRANS.TBL codeset, currently using UTF-8 which is probably not it. 3563 * However, nobody uses this stuff any more, so who cares. */ 3555 3564 char szEntry[RTFSISOMAKER_MAX_NAME_BUF * 2 + 128]; 3556 size_t cchEntry = RTStrPrintf(szEntry, sizeof(szEntry), 3557 "%c %-38s\t%s\n", pChild->pDir ? 'D' : 'F', pChild->szName, pChild->pszTransNm);3565 size_t cchEntry = RTStrPrintf(szEntry, sizeof(szEntry), "%c %-*s\t%s\n", pChild->pDir ? 'D' : 'F', 3566 RTFSISOMAKER_TRANS_TBL_LEFT_PAD, pChild->szName, pChild->pszTransNm); 3558 3567 rc = RTVfsFileWrite(hVfsFile, szEntry, cchEntry, NULL); 3559 3568 if (RT_FAILURE(rc)) … … 3583 3592 3584 3593 3594 /** 3595 * Reads file data. 3596 * 3597 * @returns IPRT status code 3598 * @param pThis The instance data for the VFS file. We use this to 3599 * keep hints about where we are and we which source 3600 * file we've opened/created. 3601 * @param pIsoMaker The ISO maker instance. 3602 * @param offUnsigned The ISO image byte offset of the requested data. 3603 * @param pbBuf The output buffer. 3604 * @param cbBuf How much to read. 3605 * @param pcbDone Where to return how much was read. 3606 */ 3585 3607 static int rtFsIsoMakerOutFile_ReadFileData(PRTFSISOMAKEROUTPUTFILE pThis, PRTFSISOMAKERINT pIsoMaker, uint64_t offUnsigned, 3586 3608 uint8_t *pbBuf, size_t cbBuf, size_t *pcbDone) … … 3672 3694 return rc; 3673 3695 *pcbDone = cbToRead; 3696 3697 /* 3698 * Check if we're into the zero padding at the end of the file now. 3699 */ 3700 if ( cbToRead < cbBuf 3701 && offInFile + cbToRead == pFile->cbData) 3702 { 3703 cbBuf -= cbToRead; 3704 pbBuf += cbToRead; 3705 size_t cbZeros = RT_MIN(cbBuf, RTFSISOMAKER_SECTOR_SIZE - (pFile->cbData & RTFSISOMAKER_SECTOR_OFFSET_MASK)); 3706 memset(pbBuf, 0, cbZeros); 3707 *pcbDone += cbZeros; 3708 } 3674 3709 } 3675 3710 else … … 3692 3727 3693 3728 3694 static size_t rtFsIsoMakerOutFile_ReadDirRecords(PRTFSISOMAKEROUTPUTFILE pThis, PRTFSISOMAKERNAMESPACE pNamespace, 3695 PRTFSISOMAKERFINALIZEDDIRS pFinalizedDirs, 3696 uint64_t off, uint8_t *pbBuf, size_t cbBuf) 3697 { 3698 RT_NOREF(pThis, pNamespace, pFinalizedDirs, off, pbBuf, cbBuf); 3699 return 0; 3729 static uint32_t rtFsIsoMakerOutFile_GenerateDirRec(PRTFSISOMAKERNAME pName, uint8_t *pbBuf) 3730 { 3731 memset(pbBuf, pName->szName[0], sizeof(ISO9660DIRREC)); 3732 return pName->cbDirRec; 3733 } 3734 3735 3736 static uint32_t rtFsIsoMakerOutFile_GenerateDirRecPartial(PRTFSISOMAKERNAME pName, uint32_t off, uint8_t *pbBuf, size_t cbBuf) 3737 { 3738 Assert(off < pName->cbDirRec); 3739 3740 uint8_t abTmpBuf[256]; 3741 size_t cbToCopy = rtFsIsoMakerOutFile_GenerateDirRec(pName, pbBuf); 3742 cbToCopy = RT_MIN(cbBuf, cbToCopy - off); 3743 memcpy(pbBuf, &abTmpBuf[off], cbToCopy); 3744 return (uint32_t)cbToCopy; 3745 } 3746 3747 3748 static size_t rtFsIsoMakerOutFile_ReadDirRecords(PRTFSISOMAKEROUTPUTFILE pThis, PRTFSISOMAKERFINALIZEDDIRS pFinalizedDirs, 3749 uint64_t offUnsigned, uint8_t *pbBuf, size_t cbBuf) 3750 { 3751 3752 /* 3753 * Figure out which directory. We keep a hint in the instance. 3754 */ 3755 uint64_t offInDir64; 3756 PRTFSISOMAKERNAMEDIR pDir = pThis->pDirHint; 3757 if (!pDir) 3758 { 3759 pDir = RTListGetFirst(&pFinalizedDirs->FinalizedDirs, RTFSISOMAKERNAMEDIR, FinalizedEntry); 3760 AssertReturn(pDir, 0); 3761 } 3762 if ((offInDir64 = offUnsigned - pDir->offDir) < RT_ALIGN_32(pDir->cbDir, RTFSISOMAKER_SECTOR_SIZE)) 3763 { /* hit */ } 3764 /* Seek forwards: */ 3765 else if (offUnsigned > pDir->offDir) 3766 do 3767 { 3768 pDir = RTListGetNext(&pFinalizedDirs->FinalizedDirs, pDir, RTFSISOMAKERNAMEDIR, FinalizedEntry); 3769 AssertReturn(pDir, 0); 3770 } while ((offInDir64 = offUnsigned - pDir->offDir) < RT_ALIGN_32(pDir->cbDir, RTFSISOMAKER_SECTOR_SIZE)); 3771 /* Back to the start: */ 3772 else if (pFinalizedDirs->offDirs / RTFSISOMAKER_SECTOR_SIZE == offUnsigned / RTFSISOMAKER_SECTOR_SIZE) 3773 { 3774 pDir = RTListGetFirst(&pFinalizedDirs->FinalizedDirs, RTFSISOMAKERNAMEDIR, FinalizedEntry); 3775 AssertReturn(pDir, 0); 3776 } 3777 /* Seek backwards: */ 3778 else 3779 do 3780 { 3781 pDir = RTListGetPrev(&pFinalizedDirs->FinalizedDirs, pDir, RTFSISOMAKERNAMEDIR, FinalizedEntry); 3782 AssertReturn(pDir, 0); 3783 } while ((offInDir64 = offUnsigned - pDir->offDir) < RT_ALIGN_32(pDir->cbDir, RTFSISOMAKER_SECTOR_SIZE)); 3784 3785 /* 3786 * Update the hint. 3787 */ 3788 pThis->pDirHint = pDir; 3789 3790 /* 3791 * Generate content. 3792 */ 3793 size_t cbDone = 0; 3794 uint32_t offInDir = (uint32_t)offInDir64; 3795 if (offInDir < pDir->cbDir) 3796 { 3797 PRTFSISOMAKERNAME pDirName = pDir->pName; 3798 PRTFSISOMAKERNAME pParentName = pDirName->pParent ? pDirName->pParent : pDirName; 3799 uint32_t cbSpecialRecs = pDirName->cbDirRec + pParentName->cbDirRec; 3800 3801 /* 3802 * Special '.' and/or '..' entries requested. 3803 */ 3804 uint32_t iChild; 3805 if (offInDir < cbSpecialRecs) 3806 { 3807 /* do '.' */ 3808 if (offInDir < pDirName->cbDirRec) 3809 { 3810 uint32_t cbCopied = rtFsIsoMakerOutFile_GenerateDirRecPartial(pDirName, offInDir, pbBuf, cbBuf); 3811 cbDone += cbCopied; 3812 offInDir += cbCopied; 3813 cbBuf -= cbCopied; 3814 } 3815 3816 /* do '..' */ 3817 if (cbBuf > 0) 3818 { 3819 uint32_t cbCopied = rtFsIsoMakerOutFile_GenerateDirRecPartial(pParentName, offInDir - pDirName->cbDirRec, 3820 pbBuf, cbBuf); 3821 cbDone += cbCopied; 3822 offInDir += cbCopied; 3823 cbBuf -= cbCopied; 3824 } 3825 3826 iChild = 0; 3827 } 3828 /* 3829 * Locate the directory entry we should start with. We can do this 3830 * using binary searching on offInDir. 3831 */ 3832 else 3833 { 3834 /** @todo binary search */ 3835 iChild = 0; 3836 while (iChild < pDir->cChildren) 3837 { 3838 PRTFSISOMAKERNAME pChild = pDir->papChildren[iChild]; 3839 if ((offInDir - pChild->offDirRec) < pChild->cbDirRec) 3840 break; 3841 iChild++; 3842 } 3843 AssertReturn(iChild < pDir->cChildren, 0); 3844 } 3845 3846 /* 3847 * Normal directory entries. 3848 */ 3849 while ( cbBuf > 0 3850 && iChild < pDir->cChildren) 3851 { 3852 PRTFSISOMAKERNAME pChild = pDir->papChildren[iChild]; 3853 uint32_t cbCopied; 3854 if ( offInDir == pChild->offDirRec 3855 && cbBuf >= pChild->cbDirRec) 3856 cbCopied = rtFsIsoMakerOutFile_GenerateDirRec(pChild, pbBuf); 3857 else 3858 cbCopied = rtFsIsoMakerOutFile_GenerateDirRecPartial(pChild, offInDir - pChild->offDirRec, pbBuf, cbBuf); 3859 cbDone += cbCopied; 3860 offInDir += cbCopied; 3861 cbBuf -= cbCopied; 3862 } 3863 3864 /* 3865 * Check if we're into the zero padding at the end of the directory now. 3866 */ 3867 if ( cbBuf > 0 3868 && iChild >= pDir->cChildren) 3869 { 3870 size_t cbZeros = RT_MIN(cbBuf, RTFSISOMAKER_SECTOR_SIZE - (pDir->cbDir & RTFSISOMAKER_SECTOR_OFFSET_MASK)); 3871 memset(pbBuf, 0, cbZeros); 3872 cbDone += cbZeros; 3873 } 3874 } 3875 else 3876 { 3877 cbDone = RT_MIN(cbBuf, RT_ALIGN_32(pDir->cbDir, RTFSISOMAKER_SECTOR_SIZE) - offInDir); 3878 memset(pbBuf, 0, cbDone); 3879 } 3880 3881 return cbDone; 3700 3882 } 3701 3883 … … 3706 3888 { 3707 3889 if (off < pFinalizedDirs->offPathTableL) 3708 return rtFsIsoMakerOutFile_ReadDirRecords(pThis, p Namespace, pFinalizedDirs, off, pbBuf, cbBuf);3890 return rtFsIsoMakerOutFile_ReadDirRecords(pThis, pFinalizedDirs, off, pbBuf, cbBuf); 3709 3891 if (off < pFinalizedDirs->offPathTableM) 3710 3892 return rtFsIsoMakerOutFile_ReadPathTable(pThis, pNamespace, pFinalizedDirs, true /*fLittleEndian*/, … … 4051 4233 pFileData->pFileHint = NULL; 4052 4234 pFileData->hVfsSrcFile = NIL_RTVFSFILE; 4235 pFileData->pDirHint = NULL; 4053 4236 return VINF_SUCCESS; 4054 4237 }
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器