Changeset 67595 in vbox for trunk/src/VBox/Runtime/common
- Timestamp:
- Jun 24, 2017 11:28:35 AM (7 years ago)
- Location:
- trunk/src/VBox/Runtime/common/fs
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fs/iso9660vfs.cpp
r67570 r67595 650 650 else 651 651 { 652 653 652 return VERR_NOT_IMPLEMENTED; /** @todo multi-extent stuff . */ 654 653 } -
trunk/src/VBox/Runtime/common/fs/isomaker.cpp
r67549 r67595 64 64 65 65 /** The sector size. */ 66 #define RTFSISOMAKER_SECTOR_SIZE _2K66 #define RTFSISOMAKER_SECTOR_SIZE _2K 67 67 /** The sector offset mask. */ 68 #define RTFSISOMAKER_SECTOR_OFFSET_MASK (_2K - 1)68 #define RTFSISOMAKER_SECTOR_OFFSET_MASK (_2K - 1) 69 69 /** Maximum number of objects. */ 70 #define RTFSISOMAKER_MAX_OBJECTS _16M70 #define RTFSISOMAKER_MAX_OBJECTS _16M 71 71 /** Maximum number of objects per directory. */ 72 #define RTFSISOMAKER_MAX_OBJECTS_PER_DIR _256K /**< @todo check limit */ 72 #define RTFSISOMAKER_MAX_OBJECTS_PER_DIR _256K /**< @todo check limit */ 73 74 /** Number of bytes to store per dir record when using multiple extents. */ 75 #define RTFSISOMAKER_MAX_ISO9660_EXTENT_SIZE UINT32_C(0xfffff800) 73 76 74 77 /** UTF-8 name buffer. */ 75 #define RTFSISOMAKER_MAX_NAME_BUF 76878 #define RTFSISOMAKER_MAX_NAME_BUF 768 76 79 77 80 /** TRANS.TBL left padding length. 78 81 * We keep the amount of padding low to avoid wasing memory when generating 79 82 * these long obsolete files. */ 80 #define RTFSISOMAKER_TRANS_TBL_LEFT_PAD 1283 #define RTFSISOMAKER_TRANS_TBL_LEFT_PAD 12 81 84 82 85 /** Tests if @a a_ch is in the set of d-characters. */ … … 227 230 * This is set when the image is being finalized. */ 228 231 uint16_t cbDirRec; 229 /** Same as cbDirRec but with end of sector zero padding added. */ 230 uint16_t cbDirRecWithZeroPad; 232 /** Number of directory records needed to cover the entire file size. */ 233 uint16_t cDirRecs; 234 /** The total directory record size (cbDirRec * cDirRecs), including end of 235 * sector zero padding. */ 236 uint16_t cbDirRecTotal; 231 237 232 238 /** The number of bytes the name requires in the directory record. */ … … 1911 1917 1912 1918 /* 1919 * If this is a file, check the size against the ISO level. 1920 * This ASSUMES that only files which size we already know will be 4GB+ sized. 1921 */ 1922 if ( (pNamespace->fNamespace & RTFSISOMAKER_NAMESPACE_ISO_9660) 1923 && pNamespace->uLevel < 3 1924 && pObj->enmType == RTFSISOMAKEROBJTYPE_FILE) 1925 { 1926 PRTFSISOMAKERFILE pFile = (PRTFSISOMAKERFILE)pObj; 1927 if (pFile->cbData >= _4G) 1928 return VERR_ISOMK_FILE_TOO_BIG_REQ_ISO_LEVEL_3; 1929 } 1930 1931 /* 1913 1932 * If the object is already named, unset that name before continuing. 1914 1933 */ … … 1988 2007 pName->offDirRec = UINT32_MAX; 1989 2008 pName->cbDirRec = 0; 1990 pName->cbDirRecWithZeroPad = 0; 2009 pName->cDirRecs = 1; 2010 pName->cbDirRecTotal = 0; 1991 2011 1992 2012 memcpy(pName->szName, szName, cchName); … … 3861 3881 size_t cbDirRec = RT_UOFFSETOF(ISO9660DIRREC, achFileId) + pName->cbNameInDirRec + !(pName->cbNameInDirRec & 1); 3862 3882 AssertReturn(cbDirRec <= UINT8_MAX, VERR_FILENAME_TOO_LONG); 3863 pName->cbDirRecWithZeroPad = pName->cbDirRec = (uint8_t)cbDirRec; 3883 3884 pName->cbDirRec = (uint8_t)cbDirRec; 3885 pName->cDirRecs = 1; 3886 if (pName->pObj->enmType == RTFSISOMAKEROBJTYPE_FILE) 3887 { 3888 PRTFSISOMAKERFILE pFile = (PRTFSISOMAKERFILE)pName->pObj; 3889 if (pFile->cbData > UINT32_MAX) 3890 pName->cDirRecs = (pFile->cbData + RTFSISOMAKER_MAX_ISO9660_EXTENT_SIZE - 1) / RTFSISOMAKER_MAX_ISO9660_EXTENT_SIZE; 3891 } 3864 3892 3865 3893 /* … … 3873 3901 } 3874 3902 3903 pName->cbDirRecTotal = pName->cbDirRec * pName->cDirRecs; 3875 3904 return VINF_SUCCESS; 3876 3905 } … … 3949 3978 AssertRCReturn(rc, rc); 3950 3979 3951 if ((RTFSISOMAKER_SECTOR_SIZE - (offInDir & RTFSISOMAKER_SECTOR_OFFSET_MASK)) < pChild->cbDirRec )3980 if ((RTFSISOMAKER_SECTOR_SIZE - (offInDir & RTFSISOMAKER_SECTOR_OFFSET_MASK)) < pChild->cbDirRecTotal) 3952 3981 { 3953 3982 Assert(ppChild[-1] == pChild && &ppChild[-1] != pCurDir->papChildren); 3954 ppChild[-2]->cbDirRecWithZeroPad += RTFSISOMAKER_SECTOR_SIZE - (offInDir & RTFSISOMAKER_SECTOR_OFFSET_MASK); 3955 offInDir = (offInDir | RTFSISOMAKER_SECTOR_OFFSET_MASK) + 1; /* doesn't fit, skip to next sector. */ 3956 Log4(("rtFsIsoMakerFinalizeDirectoriesInIsoNamespace: zero padding dir rec @%#x: %#x -> %#x; offset %#x -> %#x\n", 3957 ppChild[-2]->offDirRec, ppChild[-2]->cbDirRec, ppChild[-2]->cbDirRecWithZeroPad, pChild->offDirRec, offInDir)); 3958 pChild->offDirRec = offInDir; 3983 if ( pChild->cDirRecs == 1 3984 || pChild->cDirRecs <= RTFSISOMAKER_SECTOR_SIZE / pChild->cbDirRec) 3985 { 3986 ppChild[-2]->cbDirRecTotal += RTFSISOMAKER_SECTOR_SIZE - (offInDir & RTFSISOMAKER_SECTOR_OFFSET_MASK); 3987 offInDir = (offInDir | RTFSISOMAKER_SECTOR_OFFSET_MASK) + 1; /* doesn't fit, skip to next sector. */ 3988 Log4(("rtFsIsoMakerFinalizeDirectoriesInIsoNamespace: zero padding dir rec @%#x: %#x -> %#x; offset %#x -> %#x\n", 3989 ppChild[-2]->offDirRec, ppChild[-2]->cbDirRec, ppChild[-2]->cbDirRecTotal, pChild->offDirRec, offInDir)); 3990 pChild->offDirRec = offInDir; 3991 } 3992 /* else: too complicated and ulikely, so whatever. */ 3959 3993 } 3960 3994 3961 offInDir += pChild->cbDirRec ;3995 offInDir += pChild->cbDirRecTotal; 3962 3996 if (pChild->cchTransNm) 3963 3997 cbTransTbl += 2 /* type & space*/ … … 5047 5081 * Generates ISO-9660 directory record into the specified buffer. 5048 5082 * 5049 * @returns Number of bytes copied into the buffer. 5083 * The caller must deal with multi-extent copying and end of sector zero 5084 * padding. 5085 * 5086 * @returns Number of bytes copied into the buffer (pName->cbDirRec). 5050 5087 * @param pName The namespace node. 5051 5088 * @param fUnicode Set if the name should be translated to big endian 5052 5089 * UTF-16BE / UCS-2BE, i.e. we're in the joliet namespace. 5053 * @param pbBuf The buffer. This is at least pName->cbDirRec bytes big. 5090 * @param pbBuf The buffer. This is at least pName->cbDirRec bytes big 5091 * (i.e. at most 256 bytes). 5054 5092 */ 5055 5093 static uint32_t rtFsIsoMakerOutFile_GenerateDirRec(PRTFSISOMAKERNAME pName, bool fUnicode, uint8_t *pbBuf) … … 5122 5160 /** @todo rock ridge. */ 5123 5161 5124 /* 5125 * Do end-of-sector zero padding. 5126 */ 5127 if (pName->cbDirRecWithZeroPad == pName->cbDirRec) 5128 { /* likely */ } 5129 else 5130 { 5131 Assert(pName->cbDirRecWithZeroPad >= pName->cbDirRec); 5132 memset((uint8_t *)pDirRec + pName->cbDirRec, 0, pName->cbDirRecWithZeroPad - pName->cbDirRec); 5133 } 5134 5135 return pName->cbDirRecWithZeroPad; 5162 return pName->cbDirRec; 5163 } 5164 5165 5166 /** 5167 * Generates ISO-9660 directory records into the specified buffer. 5168 * 5169 * @returns Number of bytes copied into the buffer. 5170 * @param pName The namespace node. 5171 * @param fUnicode Set if the name should be translated to big endian 5172 * UTF-16BE / UCS-2BE, i.e. we're in the joliet namespace. 5173 * @param pbBuf The buffer. This is at least pName->cbDirRecTotal bytes 5174 * big. 5175 */ 5176 static uint32_t rtFsIsoMakerOutFile_GenerateDirRecDirect(PRTFSISOMAKERNAME pName, bool fUnicode, uint8_t *pbBuf) 5177 { 5178 /* 5179 * Normally there is just a single record without any zero padding. 5180 */ 5181 uint32_t cbReturn = rtFsIsoMakerOutFile_GenerateDirRec(pName, fUnicode, pbBuf); 5182 if (RT_LIKELY(pName->cbDirRecTotal == cbReturn)) 5183 return cbReturn; 5184 Assert(cbReturn < pName->cbDirRecTotal); 5185 5186 /* 5187 * Deal with multiple records. 5188 */ 5189 if (pName->cDirRecs > 1) 5190 { 5191 Assert(pName->pObj->enmType == RTFSISOMAKEROBJTYPE_FILE); 5192 PRTFSISOMAKERFILE pFile = (PRTFSISOMAKERFILE)pName->pObj; 5193 5194 /* Set max size and duplicate the first directory record cDirRecs - 1 times. */ 5195 uint32_t const cbOne = cbReturn; 5196 PISO9660DIRREC pDirRec = (PISO9660DIRREC)pbBuf; 5197 pDirRec->cbData.be = RT_H2BE_U32_C(RTFSISOMAKER_MAX_ISO9660_EXTENT_SIZE); 5198 pDirRec->cbData.le = RT_H2LE_U32_C(RTFSISOMAKER_MAX_ISO9660_EXTENT_SIZE); 5199 pDirRec->fFileFlags |= ISO9660_FILE_FLAGS_MULTI_EXTENT; 5200 5201 PISO9660DIRREC pCurDirRec = pDirRec; 5202 uint32_t offExtent = (uint32_t)(pFile->offData / RTFSISOMAKER_SECTOR_SIZE); 5203 Assert(offExtent == ISO9660_GET_ENDIAN(&pDirRec->offExtent)); 5204 for (uint32_t iDirRec = 1; iDirRec < pName->cDirRecs; iDirRec++) 5205 { 5206 pCurDirRec = (PISO9660DIRREC)memcpy(&pbBuf[cbReturn], pDirRec, cbOne); 5207 5208 offExtent += RTFSISOMAKER_MAX_ISO9660_EXTENT_SIZE / RTFSISOMAKER_SECTOR_SIZE; 5209 pCurDirRec->offExtent.le = RT_H2LE_U32(offExtent); 5210 5211 cbReturn += cbOne; 5212 iDirRec++; 5213 } 5214 Assert(cbReturn <= pName->cbDirRecTotal); 5215 5216 /* Adjust the size in the final record. */ 5217 uint32_t cbDataLast = (uint32_t)(pFile->cbData % RTFSISOMAKER_MAX_ISO9660_EXTENT_SIZE); 5218 pCurDirRec->cbData.be = RT_H2BE_U32(cbDataLast); 5219 pCurDirRec->cbData.le = RT_H2LE_U32(cbDataLast); 5220 pCurDirRec->fFileFlags &= ~ISO9660_FILE_FLAGS_MULTI_EXTENT; 5221 } 5222 5223 /* 5224 * Do end of sector zero padding. 5225 */ 5226 if (cbReturn < pName->cbDirRecTotal) 5227 memset(&pbBuf[cbReturn], 0, (uint32_t)pName->cbDirRecTotal - cbReturn); 5228 5229 return pName->cbDirRecTotal; 5136 5230 } 5137 5231 … … 5152 5246 uint32_t off, uint8_t *pbBuf, size_t cbBuf) 5153 5247 { 5154 uint8_t abTmpBuf[256 * 2]; 5155 Assert(off < pName->cbDirRecWithZeroPad); 5156 Assert(pName->cbDirRecWithZeroPad <= sizeof(abTmpBuf)); 5157 5158 size_t cbToCopy = rtFsIsoMakerOutFile_GenerateDirRec(pName, fUnicode, pbBuf); 5159 cbToCopy = RT_MIN(cbBuf, cbToCopy - off); 5160 memcpy(pbBuf, &abTmpBuf[off], cbToCopy); 5161 return (uint32_t)cbToCopy; 5248 Assert(off < pName->cbDirRecTotal); 5249 5250 /* 5251 * This is reasonably simple when there is only one directory record and 5252 * without any padding. 5253 */ 5254 uint8_t abTmpBuf[256]; 5255 Assert(pName->cbDirRec <= sizeof(abTmpBuf)); 5256 uint32_t const cbOne = rtFsIsoMakerOutFile_GenerateDirRec(pName, fUnicode, pbBuf); 5257 Assert(cbOne == pName->cbDirRec); 5258 if (cbOne == pName->cbDirRecTotal) 5259 { 5260 uint32_t cbToCopy = RT_MIN((uint32_t)cbBuf, cbOne - off); 5261 memcpy(pbBuf, &abTmpBuf[off], cbToCopy); 5262 return cbToCopy; 5263 } 5264 Assert(cbOne < pName->cbDirRecTotal); 5265 5266 /* 5267 * Single record and zero padding? 5268 */ 5269 uint32_t cbCopied = 0; 5270 if (pName->cDirRecs == 1) 5271 { 5272 /* Anything from the record to copy? */ 5273 if (off < cbOne) 5274 { 5275 cbCopied = RT_MIN((uint32_t)cbBuf, cbOne - off); 5276 memcpy(pbBuf, &abTmpBuf[off], cbCopied); 5277 pbBuf += cbCopied; 5278 cbBuf -= cbCopied; 5279 off += cbCopied; 5280 } 5281 5282 /* Anything from the zero padding? */ 5283 if (off >= cbOne && cbBuf > 0) 5284 { 5285 uint32_t cbToZero = RT_MIN((uint32_t)cbBuf, (uint32_t)pName->cbDirRecTotal - off); 5286 memset(pbBuf, 0, cbToZero); 5287 cbCopied += cbToZero; 5288 } 5289 } 5290 /* 5291 * Multi-extent stuff. Need to modify the cbData member as we copy. 5292 */ 5293 else 5294 { 5295 Assert(pName->pObj->enmType == RTFSISOMAKEROBJTYPE_FILE); 5296 PRTFSISOMAKERFILE pFile = (PRTFSISOMAKERFILE)pName->pObj; 5297 5298 /* Max out the size. */ 5299 PISO9660DIRREC pDirRec = (PISO9660DIRREC)abTmpBuf; 5300 pDirRec->cbData.be = RT_H2BE_U32_C(RTFSISOMAKER_MAX_ISO9660_EXTENT_SIZE); 5301 pDirRec->cbData.le = RT_H2LE_U32_C(RTFSISOMAKER_MAX_ISO9660_EXTENT_SIZE); 5302 pDirRec->fFileFlags |= ISO9660_FILE_FLAGS_MULTI_EXTENT; 5303 5304 /* Copy directory records. */ 5305 uint32_t offDirRec = pName->offDirRec; 5306 uint32_t offExtent = pFile->offData / RTFSISOMAKER_SECTOR_SIZE; 5307 for (uint32_t i = 0; i < pName->cDirRecs && cbBuf > 0; i++) 5308 { 5309 uint32_t const offInRec = off - offDirRec; 5310 if (offInRec < cbOne) 5311 { 5312 /* Update the record. */ 5313 pDirRec->offExtent.be = RT_H2BE_U32(offExtent); 5314 pDirRec->offExtent.le = RT_H2LE_U32(offExtent); 5315 if (i + 1 == pName->cDirRecs) 5316 { 5317 uint32_t cbDataLast = pFile->cbData % RTFSISOMAKER_MAX_ISO9660_EXTENT_SIZE; 5318 pDirRec->cbData.be = RT_H2BE_U32(cbDataLast); 5319 pDirRec->cbData.le = RT_H2LE_U32(cbDataLast); 5320 pDirRec->fFileFlags &= ~ISO9660_FILE_FLAGS_MULTI_EXTENT; 5321 } 5322 5323 /* Copy chunk. */ 5324 uint32_t cbToCopy = RT_MIN((uint32_t)cbBuf, cbOne - offInRec); 5325 memcpy(pbBuf, &abTmpBuf[offInRec], cbToCopy); 5326 cbCopied += cbToCopy; 5327 pbBuf += cbToCopy; 5328 cbBuf -= cbToCopy; 5329 off += cbToCopy; 5330 } 5331 5332 offDirRec += cbOne; 5333 offExtent += RTFSISOMAKER_MAX_ISO9660_EXTENT_SIZE / RTFSISOMAKER_SECTOR_SIZE; 5334 } 5335 5336 /* Anything from the zero padding? */ 5337 if (off >= offDirRec && cbBuf > 0) 5338 { 5339 uint32_t cbToZero = RT_MIN((uint32_t)cbBuf, (uint32_t)pName->cbDirRecTotal - offDirRec); 5340 memset(pbBuf, 0, cbToZero); 5341 cbCopied += cbToZero; 5342 } 5343 } 5344 5345 return cbCopied; 5162 5346 } 5163 5347 … … 5185 5369 5186 5370 /* Generate a regular directory record. */ 5187 uint8_t abTmpBuf[256 * 2];5188 Assert(off < pName->cbDirRec WithZeroPad);5371 uint8_t abTmpBuf[256]; 5372 Assert(off < pName->cbDirRec); 5189 5373 size_t cbToCopy = rtFsIsoMakerOutFile_GenerateDirRec(pName, fUnicode, abTmpBuf); 5190 Assert(cbToCopy == pName->cbDirRecWithZeroPad); 5191 cbToCopy = pName->cbDirRec; 5374 Assert(cbToCopy == pName->cbDirRec); 5192 5375 5193 5376 /* Replace the filename part. */ … … 5321 5504 { 5322 5505 PRTFSISOMAKERNAME pChild = pDir->papChildren[iChild]; 5323 if ((offInDir - pChild->offDirRec) < pChild->cbDirRec WithZeroPad)5506 if ((offInDir - pChild->offDirRec) < pChild->cbDirRecTotal) 5324 5507 break; 5325 5508 iChild++; … … 5337 5520 uint32_t cbCopied; 5338 5521 if ( offInDir == pChild->offDirRec 5339 && cbBuf >= pChild->cbDirRec WithZeroPad)5340 cbCopied = rtFsIsoMakerOutFile_GenerateDirRec (pChild, fUnicode, pbBuf);5522 && cbBuf >= pChild->cbDirRecTotal) 5523 cbCopied = rtFsIsoMakerOutFile_GenerateDirRecDirect(pChild, fUnicode, pbBuf); 5341 5524 else 5342 5525 cbCopied = rtFsIsoMakerOutFile_GenerateDirRecPartial(pChild, fUnicode, offInDir - pChild->offDirRec, pbBuf, cbBuf); -
trunk/src/VBox/Runtime/common/fs/isomakercmd.cpp
r67549 r67595 446 446 { "--application-id", 'A', RTGETOPT_REQ_STRING }, 447 447 DD("-biblio", RTFSISOMAKERCMD_OPT_BIBLIOGRAPHIC_FILE_ID, RTGETOPT_REQ_STRING ), 448 DD("-copyright", RTFSISOMAKERCMD_OPT_COPYRIGHT_FILE_ID,RTGETOPT_REQ_STRING ),448 DD("-copyright", RTFSISOMAKERCMD_OPT_COPYRIGHT_FILE_ID, RTGETOPT_REQ_STRING ), 449 449 DD("-publisher", 'P', RTGETOPT_REQ_STRING ), 450 450 { "--preparer", 'p', RTGETOPT_REQ_STRING }, … … 1404 1404 pOpts->cItemsAdded += Results.cAddedFiles; 1405 1405 pOpts->cItemsAdded += Results.cAddedDirs; 1406 pOpts->cItemsAdded += Results.cBootCatEntries ;1406 pOpts->cItemsAdded += Results.cBootCatEntries != UINT32_MAX ? Results.cBootCatEntries : 0; 1407 1407 pOpts->cItemsAdded += Results.cbSysArea != 0 ? 1 : 0; 1408 1408
Note:
See TracChangeset
for help on using the changeset viewer.