- Timestamp:
- Jun 12, 2017 11:38:33 AM (7 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
-
include/iprt/formats/iso9660.h (modified) (2 diffs)
-
src/VBox/Runtime/common/fs/isomaker.cpp (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/formats/iso9660.h
r67326 r67339 222 222 typedef struct ISO9660PATHREC 223 223 { 224 /** 0x00: Length of th is record in bytes. */224 /** 0x00: Length of the achDirId field in bytes. */ 225 225 uint8_t cbDirId; 226 226 /** 0x01: Extended attribute record length in bytes? */ … … 242 242 AssertCompileMemberOffset(ISO9660PATHREC, idParentRec, 0x06); 243 243 AssertCompileMemberOffset(ISO9660PATHREC, achDirId, 0x08); 244 /** Pointer to an ISO 9660 path table record. */ 245 typedef ISO9660PATHREC *PISO9660PATHREC; 246 /** Pointer to a const ISO 9660 path table record. */ 247 typedef ISO9660PATHREC const *PCISO9660PATHREC; 244 248 245 249 -
trunk/src/VBox/Runtime/common/fs/isomaker.cpp
r67332 r67339 87 87 88 88 89 /** Calculates the path table record size given the name length. */ 90 #define RTFSISOMAKER_CALC_PATHREC_SIZE(a_cbNameInDirRec) \ 91 ( RT_UOFFSETOF(ISO9660PATHREC, achDirId[(a_cbNameInDirRec)]) + ((a_cbNameInDirRec) & 1) ) 92 89 93 90 94 /********************************************************************************************************************************* … … 93 97 /** Pointer to an ISO maker object name space node. */ 94 98 typedef struct RTFSISOMAKERNAME *PRTFSISOMAKERNAME; 99 /** Pointer to a const ISO maker object name space node. */ 100 typedef struct RTFSISOMAKERNAME const *PCRTFSISOMAKERNAME; 95 101 /** Pointer to an ISO maker object name space node pointer. */ 96 102 typedef PRTFSISOMAKERNAME *PPRTFSISOMAKERNAME; 103 97 104 /** Pointer to a common ISO image maker file system object. */ 98 105 typedef struct RTFSISOMAKEROBJ *PRTFSISOMAKEROBJ; 106 /** Pointer to a const common ISO image maker file system object. */ 107 typedef struct RTFSISOMAKEROBJ const *PCRTFSISOMAKEROBJ; 108 99 109 /** Pointer to a ISO maker file object. */ 100 110 typedef struct RTFSISOMAKERFILE *PRTFSISOMAKERFILE; 111 /** Pointer to a const ISO maker file object. */ 112 typedef struct RTFSISOMAKERFILE const *PCRTFSISOMAKERFILE; 101 113 102 114 … … 147 159 * This is set when finalizing the image. */ 148 160 uint16_t idPathTable; 161 /** The size of the first directory record (0x00 - '.'). */ 162 uint8_t cbDirRec00; 163 /** The size of the second directory record (0x01 - '..'). */ 164 uint8_t cbDirRec01; 149 165 /** Pointer to back to the namespace node this belongs to (for the finalized 150 166 * entry list). */ … … 153 169 RTLISTNODE FinalizedEntry; 154 170 } RTFSISOMAKERNAMEDIR; 155 /** Pointer to directory specfic name space node info. */171 /** Pointer to directory specfic namespace node info. */ 156 172 typedef RTFSISOMAKERNAMEDIR *PRTFSISOMAKERNAMEDIR; 173 /** Pointer to const directory specfic namespace node info. */ 174 typedef const RTFSISOMAKERNAMEDIR *PCRTFSISOMAKERNAMEDIR; 157 175 158 176 … … 1791 1809 pDir->offPathTable = UINT32_MAX; 1792 1810 pDir->idPathTable = UINT16_MAX; 1811 pDir->cbDirRec00 = 0; 1812 pDir->cbDirRec01 = 0; 1793 1813 RTListInit(&pDir->FinalizedEntry); 1794 1814 pName->pDir = pDir; … … 2906 2926 with a 1 byte name (00 or 01). */ 2907 2927 Assert(pCurName->cbDirRec != 0); 2908 uint32_t offInDir = pCurName->cbDirRec - pCurName->cbNameInDirRec + 1; 2909 offInDir += pParentName->cbDirRec - pParentName->cbNameInDirRec + 1; 2928 Assert(pParentName->cbDirRec != 0); 2929 pCurDir->cbDirRec00 = pCurName->cbDirRec - pCurName->cbNameInDirRec - !(pCurName->cbNameInDirRec & 1) + 1; 2930 pCurDir->cbDirRec01 = pParentName->cbDirRec - pParentName->cbNameInDirRec - !(pParentName->cbNameInDirRec & 1) + 1; 2931 2932 uint32_t offInDir = (uint32_t)pCurDir->cbDirRec00 + pCurDir->cbDirRec01; 2910 2933 2911 2934 /* Finalize the directory entries. */ … … 2940 2963 pCurDir->offPathTable = cbPathTable; 2941 2964 pCurDir->idPathTable = idPathTable++; 2942 cbPathTable += RT _OFFSETOF(ISO9660PATHREC, achDirId[pCurName->cbNameInDirRec]) + (pCurName->cbNameInDirRec & 1);2965 cbPathTable += RTFSISOMAKER_CALC_PATHREC_SIZE(pCurName->cbNameInDirRec); 2943 2966 } 2944 2967 } … … 3718 3741 3719 3742 3720 static size_t rtFsIsoMakerOutFile_ReadPathTable(PRTFSISOMAKEROUTPUTFILE pThis, PRTFSISOMAKERNAMESPACE pNamespace, 3721 PRTFSISOMAKERFINALIZEDDIRS pFinalizedDirs, bool fLittleEndian, 3722 uint32_t offInTable, uint8_t *pbBuf, size_t cbBuf) 3723 { 3724 RT_NOREF(pThis, pNamespace, pFinalizedDirs, fLittleEndian, offInTable, pbBuf, cbBuf); 3725 return 0; 3726 } 3727 3728 3729 static uint32_t rtFsIsoMakerOutFile_GenerateDirRec(PRTFSISOMAKERNAME pName, uint8_t *pbBuf) 3730 { 3731 memset(pbBuf, pName->szName[0], sizeof(ISO9660DIRREC)); 3743 /** 3744 * Generates ISO-9660 path table record into the specified buffer. 3745 * 3746 * @returns Number of bytes copied into the buffer. 3747 * @param pName The directory namespace node. 3748 * @param fUnicode Set if the name should be translated to big endian 3749 * UTF-16 / UCS-2, i.e. we're in the joliet namespace. 3750 * @param pbBuf The buffer. This is large enough to hold the path 3751 * record (use RTFSISOMAKER_CALC_PATHREC_SIZE) and a zero 3752 * RTUTF16 terminator if @a fUnicode is true. 3753 */ 3754 static uint32_t rtFsIsoMakerOutFile_GeneratePathRec(PRTFSISOMAKERNAME pName, bool fUnicode, bool fLittleEndian, uint8_t *pbBuf) 3755 { 3756 PISO9660PATHREC pPathRec = (PISO9660PATHREC)pbBuf; 3757 pPathRec->cbDirId = pName->cbNameInDirRec; 3758 pPathRec->cbExtAttr = 0; 3759 if (fLittleEndian) 3760 { 3761 pPathRec->offExtent = RT_H2LE_U32(pName->pDir->offDir / RTFSISOMAKER_SECTOR_SIZE); 3762 pPathRec->idParentRec = RT_H2LE_U16(pName->pParent ? pName->pParent->pDir->idPathTable : 0); 3763 } 3764 else 3765 { 3766 pPathRec->offExtent = RT_H2BE_U32(pName->pDir->offDir / RTFSISOMAKER_SECTOR_SIZE); 3767 pPathRec->idParentRec = RT_H2BE_U16(pName->pParent ? pName->pParent->pDir->idPathTable : 0); 3768 } 3769 if (!fUnicode) 3770 { 3771 memcpy(&pPathRec->achDirId[0], pName->szName, pName->cbNameInDirRec); 3772 if (pName->cbNameInDirRec & 1) 3773 pPathRec->achDirId[pName->cbNameInDirRec] = '\0'; 3774 } 3775 else 3776 { 3777 /* Caller made sure there is space for a zero terminator character. */ 3778 PRTUTF16 pwszTmp = (PRTUTF16)&pPathRec->achDirId[0]; 3779 size_t cwcResult = 0; 3780 int rc = RTStrToUtf16BigEx(pName->szName, RTSTR_MAX, &pwszTmp, pName->cbNameInDirRec / sizeof(RTUTF16) + 1, &cwcResult); 3781 AssertRC(rc); 3782 Assert(cwcResult * sizeof(RTUTF16) == pName->cbNameInDirRec); 3783 } 3784 return RTFSISOMAKER_CALC_PATHREC_SIZE(pName->cbNameInDirRec); 3785 } 3786 3787 3788 /** 3789 * Deals with situations where the destination buffer doesn't cover the whole 3790 * path table record. 3791 * 3792 * @returns Number of bytes copied into the buffer. 3793 * @param pName The directory namespace node. 3794 * @param fUnicode Set if the name should be translated to big endian 3795 * UTF-16 / UCS-2, i.e. we're in the joliet namespace. 3796 * @param offInRec The offset into the path table record. 3797 * @param pbBuf The buffer. 3798 * @param cbBuf The buffer size. 3799 */ 3800 static uint32_t rtFsIsoMakerOutFile_GeneratePathRecPartial(PRTFSISOMAKERNAME pName, bool fUnicode, bool fLittleEndian, 3801 uint32_t offInRec, uint8_t *pbBuf, size_t cbBuf) 3802 { 3803 uint8_t abTmpRec[256]; 3804 size_t cbToCopy = rtFsIsoMakerOutFile_GeneratePathRec(pName, fUnicode, fLittleEndian, abTmpRec); 3805 cbToCopy = RT_MIN(cbBuf, cbToCopy - offInRec); 3806 memcpy(pbBuf, &abTmpRec[offInRec], cbToCopy); 3807 return (uint32_t)cbToCopy; 3808 } 3809 3810 3811 /** 3812 * Generate path table records. 3813 * 3814 * This will generate record up to the end of the table. However, it will not 3815 * supply the zero padding in the last sector, the caller is expected to take 3816 * care of that. 3817 * 3818 * @returns Number of bytes written to the buffer. 3819 * @param pThis The instance data for the VFS file. We use this to 3820 * keep hints about where we are and we which source 3821 * file we've opened/created. 3822 * @param pFinalizedDirs The finalized directory data for the namespace. 3823 * @param fUnicode Set if the name should be translated to big endian 3824 * UTF-16 / UCS-2, i.e. we're in the joliet namespace. 3825 * @param fLittleEndian Set if we're generating little endian records, clear 3826 * if big endian records. 3827 * @param offInTable Offset into the path table. 3828 * @param pbBuf The output buffer. 3829 * @param cbBuf The buffer size. 3830 */ 3831 static size_t rtFsIsoMakerOutFile_ReadPathTable(PRTFSISOMAKEROUTPUTFILE pThis, PRTFSISOMAKERFINALIZEDDIRS pFinalizedDirs, 3832 bool fUnicode, bool fLittleEndian, uint32_t offInTable, 3833 uint8_t *pbBuf, size_t cbBuf) 3834 { 3835 /* 3836 * Figure out which directory to start with. We keep a hint in the instance. 3837 */ 3838 PRTFSISOMAKERNAMEDIR pDir = pThis->pDirHint; 3839 if (!pDir) 3840 { 3841 pDir = RTListGetFirst(&pFinalizedDirs->FinalizedDirs, RTFSISOMAKERNAMEDIR, FinalizedEntry); 3842 AssertReturnStmt(pDir, *pbBuf = 0xff, 1); 3843 } 3844 if (offInTable - pDir->offPathTable < RTFSISOMAKER_CALC_PATHREC_SIZE(pDir->pName->cbNameInDirRec)) 3845 { /* hit */ } 3846 /* Seek forwards: */ 3847 else if (offInTable > pDir->offPathTable) 3848 do 3849 { 3850 pDir = RTListGetNext(&pFinalizedDirs->FinalizedDirs, pDir, RTFSISOMAKERNAMEDIR, FinalizedEntry); 3851 AssertReturnStmt(pDir, *pbBuf = 0xff, 1); 3852 } while (offInTable - pDir->offPathTable < RTFSISOMAKER_CALC_PATHREC_SIZE(pDir->pName->cbNameInDirRec)); 3853 /* Back to the start: */ 3854 else if (offInTable == 0) 3855 { 3856 pDir = RTListGetFirst(&pFinalizedDirs->FinalizedDirs, RTFSISOMAKERNAMEDIR, FinalizedEntry); 3857 AssertReturnStmt(pDir, *pbBuf = 0xff, 1); 3858 } 3859 /* Seek backwards: */ 3860 else 3861 do 3862 { 3863 pDir = RTListGetPrev(&pFinalizedDirs->FinalizedDirs, pDir, RTFSISOMAKERNAMEDIR, FinalizedEntry); 3864 AssertReturnStmt(pDir, *pbBuf = 0xff, 1); 3865 } while (offInTable - pDir->offPathTable < RTFSISOMAKER_CALC_PATHREC_SIZE(pDir->pName->cbNameInDirRec)); 3866 3867 /* 3868 * Generate content. 3869 */ 3870 size_t cbDone = 0; 3871 while ( cbBuf > 0 3872 && pDir) 3873 { 3874 PRTFSISOMAKERNAME pName = pDir->pName; 3875 uint8_t cbRec = RTFSISOMAKER_CALC_PATHREC_SIZE(pName->cbNameInDirRec); 3876 uint32_t cbCopied; 3877 if ( offInTable == pDir->offPathTable 3878 && cbBuf >= cbRec + fUnicode * 2U) 3879 cbCopied = rtFsIsoMakerOutFile_GeneratePathRec(pName, fUnicode, fLittleEndian, pbBuf); 3880 else 3881 cbCopied = rtFsIsoMakerOutFile_GeneratePathRecPartial(pName, fUnicode, fLittleEndian, 3882 offInTable - pDir->offPathTable, pbBuf, cbBuf); 3883 cbDone += cbCopied; 3884 offInTable += cbCopied; 3885 pbBuf += cbCopied; 3886 cbBuf -= cbCopied; 3887 pDir = RTListGetNext(&pFinalizedDirs->FinalizedDirs, pDir, RTFSISOMAKERNAMEDIR, FinalizedEntry); 3888 } 3889 3890 /* 3891 * Update the hint. 3892 */ 3893 pThis->pDirHint = pDir; 3894 3895 return cbDone; 3896 } 3897 3898 3899 /** 3900 * Generates ISO-9660 directory record into the specified buffer. 3901 * 3902 * @returns Number of bytes copied into the buffer. 3903 * @param pName The namespace node. 3904 * @param fUnicode Set if the name should be translated to big endian 3905 * UTF-16 / UCS-2, i.e. we're in the joliet namespace. 3906 * @param pbBuf The buffer. This is at least pName->cbDirRec bytes big. 3907 */ 3908 static uint32_t rtFsIsoMakerOutFile_GenerateDirRec(PRTFSISOMAKERNAME pName, bool fUnicode, uint8_t *pbBuf) 3909 { 3910 /* 3911 * Emit a standard ISO-9660 directory record. 3912 */ 3913 PISO9660DIRREC pDirRec = (PISO9660DIRREC)pbBuf; 3914 PCRTFSISOMAKEROBJ pObj = pName->pObj; 3915 PCRTFSISOMAKERNAMEDIR pDir = pName->pDir; 3916 if (pDir) 3917 { 3918 pDirRec->offExtent.be = RT_H2BE_U32(pDir->offDir / RTFSISOMAKER_SECTOR_SIZE); 3919 pDirRec->offExtent.le = RT_H2LE_U32(pDir->offDir / RTFSISOMAKER_SECTOR_SIZE); 3920 pDirRec->cbData.be = RT_H2BE_U32(pDir->cbDir); 3921 pDirRec->cbData.le = RT_H2LE_U32(pDir->cbDir); 3922 pDirRec->fFileFlags = ISO9660_FILE_FLAGS_DIRECTORY; 3923 } 3924 else if (pObj->enmType == RTFSISOMAKEROBJTYPE_FILE) 3925 { 3926 PRTFSISOMAKERFILE pFile = (PRTFSISOMAKERFILE)pObj; 3927 pDirRec->offExtent.be = RT_H2BE_U32(pFile->offData / RTFSISOMAKER_SECTOR_SIZE); 3928 pDirRec->offExtent.le = RT_H2LE_U32(pFile->offData / RTFSISOMAKER_SECTOR_SIZE); 3929 pDirRec->cbData.be = RT_H2BE_U32(pFile->cbData); 3930 pDirRec->cbData.le = RT_H2LE_U32(pFile->cbData); 3931 pDirRec->fFileFlags = 0; 3932 } 3933 else 3934 { 3935 pDirRec->offExtent.be = 0; 3936 pDirRec->offExtent.le = 0; 3937 pDirRec->cbData.be = 0; 3938 pDirRec->cbData.le = 0; 3939 pDirRec->fFileFlags = 0; 3940 } 3941 rtFsIsoMakerTimespecToIso9660RecTimestamp(&pObj->BirthTime, &pDirRec->RecTime); 3942 3943 pDirRec->cbDirRec = pName->cbDirRec; 3944 pDirRec->cExtAttrBlocks = 0; 3945 pDirRec->bFileUnitSize = 0; 3946 pDirRec->bInterleaveGapSize = 0; 3947 pDirRec->VolumeSeqNo.be = RT_H2BE_U16_C(1); 3948 pDirRec->VolumeSeqNo.le = RT_H2BE_U16_C(1); 3949 pDirRec->bFileIdLength = pName->cbNameInDirRec; 3950 3951 if (!fUnicode) 3952 { 3953 memcpy(&pDirRec->achFileId[0], pName->szName, pName->cbNameInDirRec); 3954 if (!(pName->cbNameInDirRec & 1)) 3955 pDirRec->achFileId[pName->cbNameInDirRec] = '\0'; 3956 } 3957 else 3958 { 3959 /* Convert to big endian UTF-16. We're using a separate buffer here 3960 because of zero terminator (none in pDirRec) and misalignment. */ 3961 RTUTF16 wszTmp[128]; 3962 PRTUTF16 pwszTmp = &wszTmp[0]; 3963 size_t cwcResult = 0; 3964 int rc = RTStrToUtf16BigEx(pName->szName, RTSTR_MAX, &pwszTmp, RT_ELEMENTS(wszTmp), &cwcResult); 3965 AssertRC(rc); 3966 Assert(cwcResult * sizeof(RTUTF16) == pName->cbNameInDirRec); 3967 memcpy(&pDirRec->achFileId[0], pwszTmp, pName->cbNameInDirRec); 3968 pDirRec->achFileId[pName->cbNameInDirRec] = '\0'; 3969 } 3970 3971 /* 3972 * Rock ridge fields if enabled. 3973 */ 3974 /** @todo rock ridge. */ 3975 3732 3976 return pName->cbDirRec; 3733 3977 } 3734 3978 3735 3979 3736 static uint32_t rtFsIsoMakerOutFile_GenerateDirRecPartial(PRTFSISOMAKERNAME pName, uint32_t off, uint8_t *pbBuf, size_t cbBuf) 3980 /** 3981 * Deals with situations where the destination buffer doesn't cover the whole 3982 * directory record. 3983 * 3984 * @returns Number of bytes copied into the buffer. 3985 * @param pName The namespace node. 3986 * @param fUnicode Set if the name should be translated to big endian 3987 * UTF-16 / UCS-2, i.e. we're in the joliet namespace. 3988 * @param off The offset into the directory record. 3989 * @param pbBuf The buffer. 3990 * @param cbBuf The buffer size. 3991 */ 3992 static uint32_t rtFsIsoMakerOutFile_GenerateDirRecPartial(PRTFSISOMAKERNAME pName, bool fUnicode, 3993 uint32_t off, uint8_t *pbBuf, size_t cbBuf) 3737 3994 { 3738 3995 Assert(off < pName->cbDirRec); 3739 3996 3740 3997 uint8_t abTmpBuf[256]; 3741 size_t cbToCopy = rtFsIsoMakerOutFile_GenerateDirRec(pName, pbBuf);3998 size_t cbToCopy = rtFsIsoMakerOutFile_GenerateDirRec(pName, fUnicode, pbBuf); 3742 3999 cbToCopy = RT_MIN(cbBuf, cbToCopy - off); 3743 4000 memcpy(pbBuf, &abTmpBuf[off], cbToCopy); … … 3746 4003 3747 4004 4005 /** 4006 * Generate a '.' or '..' directory record. 4007 * 4008 * This is the same as rtFsIsoMakerOutFile_GenerateDirRec, but with the filename 4009 * reduced to 1 byte. 4010 * 4011 * @returns Number of bytes copied into the buffer. 4012 * @param pName The directory namespace node. 4013 * @param fUnicode Set if the name should be translated to big endian 4014 * UTF-16 / UCS-2, i.e. we're in the joliet namespace. 4015 * @param bDirId The directory ID (0x00 or 0x01). 4016 * @param off The offset into the directory record. 4017 * @param pbBuf The buffer. 4018 * @param cbBuf The buffer size. 4019 */ 4020 static uint32_t rtFsIsoMakerOutFile_GenerateSpecialDirRec(PRTFSISOMAKERNAME pName, bool fUnicode, uint8_t bDirId, 4021 uint32_t off, uint8_t *pbBuf, size_t cbBuf) 4022 { 4023 Assert(off < pName->cbDirRec); 4024 Assert(pName->pDir); 4025 4026 /* Generate a regular directory record. */ 4027 uint8_t abTmpBuf[256]; 4028 size_t cbToCopy = rtFsIsoMakerOutFile_GenerateDirRec(pName, fUnicode, pbBuf); 4029 4030 /* Replace the filename part. */ 4031 PISO9660DIRREC pDirRec = (PISO9660DIRREC)abTmpBuf; 4032 if (pDirRec->bFileIdLength != 1) 4033 { 4034 uint8_t offSysUse = pDirRec->bFileIdLength + !(pDirRec->bFileIdLength & 1) + RT_OFFSETOF(ISO9660DIRREC, achFileId); 4035 uint8_t cbSysUse = pDirRec->cbDirRec - offSysUse; 4036 if (cbSysUse > 0) 4037 memmove(&pDirRec->achFileId[1], &pbBuf[offSysUse], cbSysUse); 4038 pDirRec->bFileIdLength = 1; 4039 cbToCopy = RT_OFFSETOF(ISO9660DIRREC, achFileId) + 1 + cbSysUse; 4040 pDirRec->cbDirRec = (uint8_t)cbToCopy; 4041 } 4042 pDirRec->achFileId[0] = bDirId; 4043 4044 /* Do the copying. */ 4045 cbToCopy = RT_MIN(cbBuf, cbToCopy - off); 4046 memcpy(pbBuf, &abTmpBuf[off], cbToCopy); 4047 return (uint32_t)cbToCopy; 4048 } 4049 4050 4051 /** 4052 * Read directory records. 4053 * 4054 * This locates the directory at @a offUnsigned and generates directory records 4055 * for it. Caller must repeat the call to get directory entries for the next 4056 * directory should there be desire for that. 4057 * 4058 * @returns Number of bytes copied into @a pbBuf. 4059 * @param pThis The instance data for the VFS file. We use this to 4060 * keep hints about where we are and we which source 4061 * file we've opened/created. 4062 * @param pIsoMaker The ISO maker instance. 4063 * @param pFinalizedDirs The finalized directory data for the namespace. 4064 * @param fUnicode Set if the name should be translated to big endian 4065 * UTF-16 / UCS-2, i.e. we're in the joliet namespace. 4066 * @param offUnsigned The ISO image byte offset of the requested data. 4067 * @param pbBuf The output buffer. 4068 * @param cbBuf How much to read. 4069 */ 3748 4070 static size_t rtFsIsoMakerOutFile_ReadDirRecords(PRTFSISOMAKEROUTPUTFILE pThis, PRTFSISOMAKERFINALIZEDDIRS pFinalizedDirs, 3749 uint64_t offUnsigned, uint8_t *pbBuf, size_t cbBuf) 3750 { 3751 4071 bool fUnicode, uint64_t offUnsigned, uint8_t *pbBuf, size_t cbBuf) 4072 { 3752 4073 /* 3753 4074 * Figure out which directory. We keep a hint in the instance. … … 3758 4079 { 3759 4080 pDir = RTListGetFirst(&pFinalizedDirs->FinalizedDirs, RTFSISOMAKERNAMEDIR, FinalizedEntry); 3760 AssertReturn (pDir, 0);4081 AssertReturnStmt(pDir, *pbBuf = 0xff, 1); 3761 4082 } 3762 4083 if ((offInDir64 = offUnsigned - pDir->offDir) < RT_ALIGN_32(pDir->cbDir, RTFSISOMAKER_SECTOR_SIZE)) … … 3767 4088 { 3768 4089 pDir = RTListGetNext(&pFinalizedDirs->FinalizedDirs, pDir, RTFSISOMAKERNAMEDIR, FinalizedEntry); 3769 AssertReturn (pDir, 0);4090 AssertReturnStmt(pDir, *pbBuf = 0xff, 1); 3770 4091 } while ((offInDir64 = offUnsigned - pDir->offDir) < RT_ALIGN_32(pDir->cbDir, RTFSISOMAKER_SECTOR_SIZE)); 3771 4092 /* Back to the start: */ … … 3773 4094 { 3774 4095 pDir = RTListGetFirst(&pFinalizedDirs->FinalizedDirs, RTFSISOMAKERNAMEDIR, FinalizedEntry); 3775 AssertReturn (pDir, 0);4096 AssertReturnStmt(pDir, *pbBuf = 0xff, 1); 3776 4097 } 3777 4098 /* Seek backwards: */ … … 3780 4101 { 3781 4102 pDir = RTListGetPrev(&pFinalizedDirs->FinalizedDirs, pDir, RTFSISOMAKERNAMEDIR, FinalizedEntry); 3782 AssertReturn (pDir, 0);4103 AssertReturnStmt(pDir, *pbBuf = 0xff, 1); 3783 4104 } while ((offInDir64 = offUnsigned - pDir->offDir) < RT_ALIGN_32(pDir->cbDir, RTFSISOMAKER_SECTOR_SIZE)); 3784 4105 … … 3797 4118 PRTFSISOMAKERNAME pDirName = pDir->pName; 3798 4119 PRTFSISOMAKERNAME pParentName = pDirName->pParent ? pDirName->pParent : pDirName; 3799 uint32_t cbSpecialRecs = pDirName->cbDirRec + pParentName->cbDirRec;4120 uint32_t cbSpecialRecs = (uint32_t)pDir->cbDirRec00 + pDir->cbDirRec01; 3800 4121 3801 4122 /* … … 3806 4127 { 3807 4128 /* do '.' */ 3808 if (offInDir < pDir Name->cbDirRec)4129 if (offInDir < pDir->cbDirRec00) 3809 4130 { 3810 uint32_t cbCopied = rtFsIsoMakerOutFile_Generate DirRecPartial(pDirName, offInDir, pbBuf, cbBuf);4131 uint32_t cbCopied = rtFsIsoMakerOutFile_GenerateSpecialDirRec(pDirName, fUnicode, 0, offInDir, pbBuf, cbBuf); 3811 4132 cbDone += cbCopied; 3812 4133 offInDir += cbCopied; 4134 pbBuf += cbCopied; 3813 4135 cbBuf -= cbCopied; 3814 4136 } … … 3817 4139 if (cbBuf > 0) 3818 4140 { 3819 uint32_t cbCopied = rtFsIsoMakerOutFile_Generate DirRecPartial(pParentName, offInDir - pDirName->cbDirRec,3820 pbBuf, cbBuf);4141 uint32_t cbCopied = rtFsIsoMakerOutFile_GenerateSpecialDirRec(pParentName, fUnicode, 1, 4142 offInDir - pDir->cbDirRec00, pbBuf, cbBuf); 3821 4143 cbDone += cbCopied; 3822 4144 offInDir += cbCopied; 4145 pbBuf += cbCopied; 3823 4146 cbBuf -= cbCopied; 3824 4147 } … … 3841 4164 iChild++; 3842 4165 } 3843 AssertReturn (iChild < pDir->cChildren, 0);4166 AssertReturnStmt(iChild < pDir->cChildren, *pbBuf = 0xff, 1); 3844 4167 } 3845 4168 … … 3854 4177 if ( offInDir == pChild->offDirRec 3855 4178 && cbBuf >= pChild->cbDirRec) 3856 cbCopied = rtFsIsoMakerOutFile_GenerateDirRec(pChild, pbBuf);4179 cbCopied = rtFsIsoMakerOutFile_GenerateDirRec(pChild, fUnicode, pbBuf); 3857 4180 else 3858 cbCopied = rtFsIsoMakerOutFile_GenerateDirRecPartial(pChild, offInDir - pChild->offDirRec, pbBuf, cbBuf);4181 cbCopied = rtFsIsoMakerOutFile_GenerateDirRecPartial(pChild, fUnicode, offInDir - pChild->offDirRec, pbBuf, cbBuf); 3859 4182 cbDone += cbCopied; 3860 4183 offInDir += cbCopied; 4184 pbBuf += cbCopied; 3861 4185 cbBuf -= cbCopied; 4186 iChild++; 3862 4187 } 3863 4188 … … 3883 4208 3884 4209 4210 /** 4211 * Read directory records or path table records. 4212 * 4213 * Will not necessarily fill the entire buffer. Caller must call again to get 4214 * more. 4215 * 4216 * @returns Number of bytes copied into @a pbBuf. 4217 * @param pThis The instance data for the VFS file. We use this to 4218 * keep hints about where we are and we which source 4219 * file we've opened/created. 4220 * @param pIsoMaker The ISO maker instance. 4221 * @param pNamespace The namespace. 4222 * @param pFinalizedDirs The finalized directory data for the namespace. 4223 * @param offUnsigned The ISO image byte offset of the requested data. 4224 * @param pbBuf The output buffer. 4225 * @param cbBuf How much to read. 4226 */ 3885 4227 static size_t rtFsIsoMakerOutFile_ReadDirStructures(PRTFSISOMAKEROUTPUTFILE pThis, PRTFSISOMAKERNAMESPACE pNamespace, 3886 4228 PRTFSISOMAKERFINALIZEDDIRS pFinalizedDirs, 3887 uint64_t off, uint8_t *pbBuf, size_t cbBuf) 3888 { 3889 if (off < pFinalizedDirs->offPathTableL) 3890 return rtFsIsoMakerOutFile_ReadDirRecords(pThis, pFinalizedDirs, off, pbBuf, cbBuf); 3891 if (off < pFinalizedDirs->offPathTableM) 3892 return rtFsIsoMakerOutFile_ReadPathTable(pThis, pNamespace, pFinalizedDirs, true /*fLittleEndian*/, 3893 (uint32_t)(off - pFinalizedDirs->offPathTableL), pbBuf, cbBuf); 3894 return rtFsIsoMakerOutFile_ReadPathTable(pThis, pNamespace, pFinalizedDirs, false /*fLittleEndian*/, 3895 (uint32_t)(off - pFinalizedDirs->offPathTableM), pbBuf, cbBuf); 4229 uint64_t offUnsigned, uint8_t *pbBuf, size_t cbBuf) 4230 { 4231 if (offUnsigned < pFinalizedDirs->offPathTableL) 4232 return rtFsIsoMakerOutFile_ReadDirRecords(pThis, pFinalizedDirs, pNamespace->fNamespace == RTFSISOMAKER_NAMESPACE_JOLIET, 4233 offUnsigned, pbBuf, cbBuf); 4234 4235 uint64_t offInTable; 4236 if ((offInTable = offUnsigned - pFinalizedDirs->offPathTableL) < pFinalizedDirs->cbPathTable) 4237 return rtFsIsoMakerOutFile_ReadPathTable(pThis, pFinalizedDirs, pNamespace->fNamespace == RTFSISOMAKER_NAMESPACE_JOLIET, 4238 true /*fLittleEndian*/, (uint32_t)offInTable, pbBuf, cbBuf); 4239 4240 if ((offInTable = offUnsigned - pFinalizedDirs->offPathTableM) < pFinalizedDirs->cbPathTable) 4241 return rtFsIsoMakerOutFile_ReadPathTable(pThis, pFinalizedDirs, pNamespace->fNamespace == RTFSISOMAKER_NAMESPACE_JOLIET, 4242 false /*fLittleEndian*/, (uint32_t)offInTable, pbBuf, cbBuf); 4243 4244 /* ASSUME we're in the zero padding at the end of a path table. */ 4245 Assert( offUnsigned - pFinalizedDirs->offPathTableL < RT_ALIGN_32(pFinalizedDirs->cbPathTable, RTFSISOMAKER_SECTOR_SIZE) 4246 || offUnsigned - pFinalizedDirs->offPathTableM < RT_ALIGN_32(pFinalizedDirs->cbPathTable, RTFSISOMAKER_SECTOR_SIZE)); 4247 size_t cbZeros = RT_MIN(cbBuf, RTFSISOMAKER_SECTOR_SIZE - ((size_t)offUnsigned & RTFSISOMAKER_SECTOR_OFFSET_MASK)); 4248 memset(pbBuf, 0, cbZeros); 4249 return cbZeros; 3896 4250 } 3897 4251
Note:
See TracChangeset
for help on using the changeset viewer.

