Changeset 67381 in vbox for trunk/src/VBox/Runtime/common
- Timestamp:
- Jun 13, 2017 7:10:51 PM (8 years ago)
- Location:
- trunk/src/VBox/Runtime/common/fs
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fs/isomaker.cpp
r67370 r67381 57 57 #define RTFSISOMAKER_ASSER_VALID_HANDLE_RET_EX(a_pThis, a_rcRet) \ 58 58 do { AssertPtrReturn(a_pThis, a_rcRet); \ 59 Assert PtrReturn((a_pThis)->uMagic == RTFSISOMAKERINT_MAGIC, a_rcRet); \59 AssertReturn((a_pThis)->uMagic == RTFSISOMAKERINT_MAGIC, a_rcRet); \ 60 60 } while (0) 61 61 … … 525 525 * RTFSISOMAKERSRCTYPE_TRANS_TBL file. */ 526 526 RTVFSFILE hVfsSrcFile; 527 /** Current directory hint. */ 528 PRTFSISOMAKERNAMEDIR pDirHint; 527 /** Current directory hint for the primary ISO namespace. */ 528 PRTFSISOMAKERNAMEDIR pDirHintPrimaryIso; 529 /** Current directory hint for the joliet namespace. */ 530 PRTFSISOMAKERNAMEDIR pDirHintJoliet; 529 531 } RTFSISOMAKEROUTPUTFILE; 530 532 /** Pointer to the instance data of an ISO maker output file. */ … … 634 636 * Create the instance with defaults. 635 637 */ 638 int rc; 636 639 PRTFSISOMAKERINT pThis = (PRTFSISOMAKERINT)RTMemAllocZ(sizeof(*pThis)); 637 640 if (pThis) … … 741 744 742 745 RTTimeNow(&pThis->ImageCreationTime); 743 *phIsoMaker = pThis; 744 return VINF_SUCCESS; 745 } 746 return VERR_NO_MEMORY; 746 747 /* 748 * Add the root directory node with idObj == 0. 749 */ 750 PRTFSISOMAKERDIR pDirRoot; 751 rc = rtFsIsoMakerAddUnnamedDirWorker(pThis, &pDirRoot); 752 if (RT_SUCCESS(rc)) 753 { 754 *phIsoMaker = pThis; 755 return VINF_SUCCESS; 756 } 757 758 RTMemFree(pThis); 759 } 760 else 761 rc = VERR_NO_MEMORY; 762 return rc; 747 763 } 748 764 … … 1591 1607 pszDst[cchSrc] = '\0'; 1592 1608 *pcchDst = cchSrc; 1593 *pcbInDirRec = RTStrCalcUtf16Len(pszDst) ;1609 *pcbInDirRec = RTStrCalcUtf16Len(pszDst) * sizeof(RTUTF16); 1594 1610 return VINF_SUCCESS; 1595 1611 } … … 1611 1627 *pcchDst = 0; 1612 1628 *pcbInDirRec = 0; 1613 AssertReturn( pParent, VERR_INTERNAL_ERROR_3);1629 AssertReturn(!pParent, VERR_INTERNAL_ERROR_3); 1614 1630 return VINF_SUCCESS; 1615 1631 } … … 1749 1765 pName->cchRockRidgeNm = (uint16_t)cchSpec; 1750 1766 pName->cchTransNm = (uint16_t)cchSpec; 1751 pName->uDepth = pParent ->uDepth + 1;1767 pName->uDepth = pParent ? pParent->uDepth + 1 : 0; 1752 1768 pName->fRockRidgeNmAlloced = false; 1753 1769 pName->fTransNmAlloced = false; … … 1857 1873 if (!pParent) 1858 1874 { 1859 PRTFSISOMAKERDIR pDir; 1860 if (pThis->cObjects == 0) 1861 { 1862 rc = rtFsIsoMakerAddUnnamedDirWorker(pThis, &pDir); 1863 AssertRCReturn(rc, rc); 1864 } 1865 else 1866 { 1867 pDir = RTListGetFirst(&pThis->ObjectHead, RTFSISOMAKERDIR, Core.Entry); 1875 PRTFSISOMAKERDIR pDir = RTListGetFirst(&pThis->ObjectHead, RTFSISOMAKERDIR, Core.Entry); 1868 1876 #ifdef RT_STRICT 1869 1870 1871 1872 1877 Assert(pDir); 1878 Assert(pDir->Core.idxObj == 0); 1879 Assert(pDir->Core.enmType == RTFSISOMAKEROBJTYPE_DIR); 1880 Assert(*rtFsIsoMakerObjGetNameForNamespace(&pDir->Core, pNamespace) == NULL); 1873 1881 #endif 1874 }1875 1882 1876 1883 rc = rtFsIsoMakerObjSetName(pThis, pNamespace, &pDir->Core, NULL /*pParent*/, "", 0, &pParent); … … 1890 1897 char ch; 1891 1898 size_t cchComponent = 0; 1892 while ((ch = pszPath[cchComponent]) != '\0' && RTPATH_IS_SLASH(ch))1899 while ((ch = pszPath[cchComponent]) != '\0' && !RTPATH_IS_SLASH(ch)) 1893 1900 cchComponent++; 1894 1901 AssertReturn(cchComponent > 0, VERR_INTERNAL_ERROR_4); … … 2510 2517 if (RT_SUCCESS(rc)) 2511 2518 { 2512 pFile->cbData = pObjInfo ->cbObject;2519 pFile->cbData = pObjInfo ? pObjInfo->cbObject : 0; 2513 2520 pThis->cbData += RT_ALIGN_64(pFile->cbData, RTFSISOMAKER_SECTOR_SIZE); 2514 2521 pFile->offData = UINT64_MAX; … … 2888 2895 */ 2889 2896 PRTFSISOMAKERNAMEDIR pCurDir; 2890 RTListForEach(&p This->PrimaryIsoDirs.FinalizedDirs, pCurDir, RTFSISOMAKERNAMEDIR, FinalizedEntry)2897 RTListForEach(&pFinalizedDirs->FinalizedDirs, pCurDir, RTFSISOMAKERNAMEDIR, FinalizedEntry) 2891 2898 { 2892 2899 PRTFSISOMAKERNAME pCurName = pCurDir->pName; … … 3010 3017 static int rtFsIsoMakerFinalizeData(PRTFSISOMAKERINT pThis, uint64_t *poffData) 3011 3018 { 3019 pThis->offFirstFile = *poffData; 3020 3012 3021 /* 3013 3022 * We currently does not have any ordering prioritizing implemented, so we … … 3350 3359 pPrimary->RootDir.DirRec.bInterleaveGapSize = 0; 3351 3360 pPrimary->RootDir.DirRec.VolumeSeqNo.be = RT_H2BE_U16_C(1); 3352 pPrimary->RootDir.DirRec.VolumeSeqNo.le = RT_H2 BE_U16_C(1);3361 pPrimary->RootDir.DirRec.VolumeSeqNo.le = RT_H2LE_U16_C(1); 3353 3362 pPrimary->RootDir.DirRec.bFileIdLength = 1; 3354 3363 pPrimary->RootDir.DirRec.achFileId[1] = 0x00; … … 3376 3385 pJoliet->RootDir.DirRec.bInterleaveGapSize = 0; 3377 3386 pJoliet->RootDir.DirRec.VolumeSeqNo.be = RT_H2BE_U16_C(1); 3378 pJoliet->RootDir.DirRec.VolumeSeqNo.le = RT_H2 BE_U16_C(1);3387 pJoliet->RootDir.DirRec.VolumeSeqNo.le = RT_H2LE_U16_C(1); 3379 3388 pJoliet->RootDir.DirRec.bFileIdLength = 1; 3380 3389 pJoliet->RootDir.DirRec.achFileId[1] = 0x00; … … 3403 3412 if (RT_FAILURE(rc)) 3404 3413 return rc; 3414 AssertReturn(pThis->cObjects > 0, VERR_NO_DATA); 3415 AssertReturn(pThis->PrimaryIso.pRoot || pThis->PrimaryIso.uLevel == 0, VERR_NO_DATA); 3416 AssertReturn(pThis->Joliet.pRoot || pThis->Joliet.uLevel == 0, VERR_NO_DATA); 3417 3405 3418 rc = rtFsIsoMakerFinalizePrepVolumeDescriptors(pThis); 3406 3419 if (RT_FAILURE(rc)) … … 3788 3801 * 3789 3802 * @returns Number of bytes written to the buffer. 3790 * @param pThis The instance data for the VFS file. We use this to 3791 * keep hints about where we are and we which source 3792 * file we've opened/created. 3803 * @param ppDirHint Pointer to the directory hint for the namespace. 3793 3804 * @param pFinalizedDirs The finalized directory data for the namespace. 3794 3805 * @param fUnicode Set if the name should be translated to big endian … … 3800 3811 * @param cbBuf The buffer size. 3801 3812 */ 3802 static size_t rtFsIsoMakerOutFile_ReadPathTable(PRTFSISOMAKER OUTPUTFILE pThis, PRTFSISOMAKERFINALIZEDDIRS pFinalizedDirs,3813 static size_t rtFsIsoMakerOutFile_ReadPathTable(PRTFSISOMAKERNAMEDIR *ppDirHint, PRTFSISOMAKERFINALIZEDDIRS pFinalizedDirs, 3803 3814 bool fUnicode, bool fLittleEndian, uint32_t offInTable, 3804 3815 uint8_t *pbBuf, size_t cbBuf) … … 3807 3818 * Figure out which directory to start with. We keep a hint in the instance. 3808 3819 */ 3809 PRTFSISOMAKERNAMEDIR pDir = pThis->pDirHint;3820 PRTFSISOMAKERNAMEDIR pDir = *ppDirHint; 3810 3821 if (!pDir) 3811 3822 { … … 3862 3873 * Update the hint. 3863 3874 */ 3864 pThis->pDirHint = pDir;3875 *ppDirHint = pDir; 3865 3876 3866 3877 return cbDone; … … 3917 3928 pDirRec->bInterleaveGapSize = 0; 3918 3929 pDirRec->VolumeSeqNo.be = RT_H2BE_U16_C(1); 3919 pDirRec->VolumeSeqNo.le = RT_H2 BE_U16_C(1);3930 pDirRec->VolumeSeqNo.le = RT_H2LE_U16_C(1); 3920 3931 pDirRec->bFileIdLength = pName->cbNameInDirRec; 3921 3932 … … 3997 4008 /* Generate a regular directory record. */ 3998 4009 uint8_t abTmpBuf[256]; 3999 size_t cbToCopy = rtFsIsoMakerOutFile_GenerateDirRec(pName, fUnicode, pbBuf);4010 size_t cbToCopy = rtFsIsoMakerOutFile_GenerateDirRec(pName, fUnicode, abTmpBuf); 4000 4011 4001 4012 /* Replace the filename part. */ … … 4028 4039 * 4029 4040 * @returns Number of bytes copied into @a pbBuf. 4030 * @param pThis The instance data for the VFS file. We use this to 4031 * keep hints about where we are and we which source 4032 * file we've opened/created. 4041 * @param ppDirHint Pointer to the directory hint for the namespace. 4033 4042 * @param pIsoMaker The ISO maker instance. 4034 4043 * @param pFinalizedDirs The finalized directory data for the namespace. … … 4039 4048 * @param cbBuf How much to read. 4040 4049 */ 4041 static size_t rtFsIsoMakerOutFile_ReadDirRecords(PRTFSISOMAKER OUTPUTFILE pThis, PRTFSISOMAKERFINALIZEDDIRS pFinalizedDirs,4050 static size_t rtFsIsoMakerOutFile_ReadDirRecords(PRTFSISOMAKERNAMEDIR *ppDirHint, PRTFSISOMAKERFINALIZEDDIRS pFinalizedDirs, 4042 4051 bool fUnicode, uint64_t offUnsigned, uint8_t *pbBuf, size_t cbBuf) 4043 4052 { … … 4046 4055 */ 4047 4056 uint64_t offInDir64; 4048 PRTFSISOMAKERNAMEDIR pDir = pThis->pDirHint;4057 PRTFSISOMAKERNAMEDIR pDir = *ppDirHint; 4049 4058 if (!pDir) 4050 4059 { … … 4078 4087 * Update the hint. 4079 4088 */ 4080 pThis->pDirHint = pDir;4089 *ppDirHint = pDir; 4081 4090 4082 4091 /* … … 4186 4195 * 4187 4196 * @returns Number of bytes copied into @a pbBuf. 4188 * @param pThis The instance data for the VFS file. We use this to 4189 * keep hints about where we are and we which source 4190 * file we've opened/created. 4197 * @param ppDirHint Pointer to the directory hint for the namespace. 4191 4198 * @param pIsoMaker The ISO maker instance. 4192 4199 * @param pNamespace The namespace. … … 4196 4203 * @param cbBuf How much to read. 4197 4204 */ 4198 static size_t rtFsIsoMakerOutFile_ReadDirStructures(PRTFSISOMAKER OUTPUTFILE pThis, PRTFSISOMAKERNAMESPACE pNamespace,4205 static size_t rtFsIsoMakerOutFile_ReadDirStructures(PRTFSISOMAKERNAMEDIR *ppDirHint, PRTFSISOMAKERNAMESPACE pNamespace, 4199 4206 PRTFSISOMAKERFINALIZEDDIRS pFinalizedDirs, 4200 4207 uint64_t offUnsigned, uint8_t *pbBuf, size_t cbBuf) 4201 4208 { 4202 4209 if (offUnsigned < pFinalizedDirs->offPathTableL) 4203 return rtFsIsoMakerOutFile_ReadDirRecords(pThis, pFinalizedDirs, pNamespace->fNamespace == RTFSISOMAKER_NAMESPACE_JOLIET, 4210 return rtFsIsoMakerOutFile_ReadDirRecords(ppDirHint, pFinalizedDirs, 4211 pNamespace->fNamespace == RTFSISOMAKER_NAMESPACE_JOLIET, 4204 4212 offUnsigned, pbBuf, cbBuf); 4205 4213 4206 4214 uint64_t offInTable; 4207 4215 if ((offInTable = offUnsigned - pFinalizedDirs->offPathTableL) < pFinalizedDirs->cbPathTable) 4208 return rtFsIsoMakerOutFile_ReadPathTable(pThis, pFinalizedDirs, pNamespace->fNamespace == RTFSISOMAKER_NAMESPACE_JOLIET, 4216 return rtFsIsoMakerOutFile_ReadPathTable(ppDirHint, pFinalizedDirs, 4217 pNamespace->fNamespace == RTFSISOMAKER_NAMESPACE_JOLIET, 4209 4218 true /*fLittleEndian*/, (uint32_t)offInTable, pbBuf, cbBuf); 4210 4219 4211 4220 if ((offInTable = offUnsigned - pFinalizedDirs->offPathTableM) < pFinalizedDirs->cbPathTable) 4212 return rtFsIsoMakerOutFile_ReadPathTable(pThis, pFinalizedDirs, pNamespace->fNamespace == RTFSISOMAKER_NAMESPACE_JOLIET, 4221 return rtFsIsoMakerOutFile_ReadPathTable(ppDirHint, pFinalizedDirs, 4222 pNamespace->fNamespace == RTFSISOMAKER_NAMESPACE_JOLIET, 4213 4223 false /*fLittleEndian*/, (uint32_t)offInTable, pbBuf, cbBuf); 4214 4224 … … 4287 4297 else if ( offUnsigned >= pIsoMaker->JolietDirs.offDirs 4288 4298 && pIsoMaker->JolietDirs.offDirs < pIsoMaker->JolietDirs.offPathTableL) 4289 cbDone = rtFsIsoMakerOutFile_ReadDirStructures( pThis, &pIsoMaker->Joliet, &pIsoMaker->JolietDirs,4299 cbDone = rtFsIsoMakerOutFile_ReadDirStructures(&pThis->pDirHintJoliet, &pIsoMaker->Joliet, &pIsoMaker->JolietDirs, 4290 4300 offUnsigned, pbBuf, cbBuf); 4291 4301 /* … … 4293 4303 */ 4294 4304 else if (offUnsigned >= pIsoMaker->PrimaryIsoDirs.offDirs) 4295 cbDone = rtFsIsoMakerOutFile_ReadDirStructures( pThis, &pIsoMaker->PrimaryIso, &pIsoMaker->PrimaryIsoDirs,4296 offUnsigned, pbBuf, cbBuf);4305 cbDone = rtFsIsoMakerOutFile_ReadDirStructures(&pThis->pDirHintPrimaryIso, &pIsoMaker->PrimaryIso, 4306 &pIsoMaker->PrimaryIsoDirs, offUnsigned, pbBuf, cbBuf); 4297 4307 /** @todo Insert El Torito stuff here? Probably okay to let it be in the file 4298 4308 * area, right? */ … … 4554 4564 if (RT_SUCCESS(rc)) 4555 4565 { 4556 pFileData->pIsoMaker = pThis; 4557 pFileData->offCurPos = 0; 4558 pFileData->pFileHint = NULL; 4559 pFileData->hVfsSrcFile = NIL_RTVFSFILE; 4560 pFileData->pDirHint = NULL; 4566 pFileData->pIsoMaker = pThis; 4567 pFileData->offCurPos = 0; 4568 pFileData->pFileHint = NULL; 4569 pFileData->hVfsSrcFile = NIL_RTVFSFILE; 4570 pFileData->pDirHintPrimaryIso = NULL; 4571 pFileData->pDirHintJoliet = NULL; 4572 *phVfsFile = hVfsFile; 4561 4573 return VINF_SUCCESS; 4562 4574 } -
trunk/src/VBox/Runtime/common/fs/isomakercmd.cpp
r67370 r67381 57 57 /** @name Name specifiers 58 58 * @{ */ 59 #define RTFSISOMAKERCMDNAME_PRIMARY_ISO RT_BIT_32(0) 60 #define RTFSISOMAKERCMDNAME_PRIMARY_ISO_ROCK_RIDGE RT_BIT_32(1) 61 #define RTFSISOMAKERCMDNAME_PRIMARY_ISO_TRANS_TBL RT_BIT_32(2) 62 #define RTFSISOMAKERCMDNAME_JOLIET RT_BIT_32(3) 63 #define RTFSISOMAKERCMDNAME_JOLIET_ROCK_RIDGE RT_BIT_32(4) 64 #define RTFSISOMAKERCMDNAME_JOLIET_TRANS_TBL RT_BIT_32(5) 65 #define RTFSISOMAKERCMDNAME_UDF RT_BIT_32(6) 66 #define RTFSISOMAKERCMDNAME_UDF_TRANS_TBL RT_BIT_32(7) 67 #define RTFSISOMAKERCMDNAME_HFS RT_BIT_32(8) 68 #define RTFSISOMAKERCMDNAME_HFS_TRANS_TBL RT_BIT_32(9) 59 #define RTFSISOMAKERCMDNAME_PRIMARY_ISO RTFSISOMAKER_NAMESPACE_ISO_9660 60 #define RTFSISOMAKERCMDNAME_JOLIET RTFSISOMAKER_NAMESPACE_JOLIET 61 #define RTFSISOMAKERCMDNAME_UDF RTFSISOMAKER_NAMESPACE_UDF 62 #define RTFSISOMAKERCMDNAME_HFS RTFSISOMAKER_NAMESPACE_HFS 63 64 #define RTFSISOMAKERCMDNAME_PRIMARY_ISO_ROCK_RIDGE RT_BIT_32(16) 65 #define RTFSISOMAKERCMDNAME_JOLIET_ROCK_RIDGE RT_BIT_32(17) 66 67 #define RTFSISOMAKERCMDNAME_JOLIET_TRANS_TBL RT_BIT_32(20) 68 #define RTFSISOMAKERCMDNAME_PRIMARY_ISO_TRANS_TBL RT_BIT_32(21) 69 #define RTFSISOMAKERCMDNAME_UDF_TRANS_TBL RT_BIT_32(22) 70 #define RTFSISOMAKERCMDNAME_HFS_TRANS_TBL RT_BIT_32(23) 69 71 70 72 #define RTFSISOMAKERCMDNAME_MAJOR_MASK \ 71 73 (RTFSISOMAKERCMDNAME_PRIMARY_ISO | RTFSISOMAKERCMDNAME_JOLIET | RTFSISOMAKERCMDNAME_UDF | RTFSISOMAKERCMDNAME_HFS) 74 72 75 #define RTFSISOMAKERCMDNAME_MINOR_MASK \ 73 76 ( RTFSISOMAKERCMDNAME_PRIMARY_ISO_ROCK_RIDGE | RTFSISOMAKERCMDNAME_PRIMARY_ISO_TRANS_TBL \ … … 75 78 | RTFSISOMAKERCMDNAME_UDF_TRANS_TBL \ 76 79 | RTFSISOMAKERCMDNAME_HFS_TRANS_TBL) 80 AssertCompile((RTFSISOMAKERCMDNAME_MAJOR_MASK & RTFSISOMAKERCMDNAME_MINOR_MASK) == 0); 77 81 /** @} */ 82 78 83 79 84 /********************************************************************************************************************************* … … 285 290 /** Pointer to a parsed name. */ 286 291 typedef RTFSISOMAKERCMDPARSEDNAME *PRTFSISOMAKERCMDPARSEDNAME; 292 /** Pointer to a const parsed name. */ 293 typedef RTFSISOMAKERCMDPARSEDNAME const *PCRTFSISOMAKERCMDPARSEDNAME; 287 294 288 295 … … 900 907 901 908 /** 909 * Adds a file. 910 * 911 * @returns IPRT status code. 912 * @param pOpts The ISO maker command instance. 913 * @param pszSrc The path to the source file. 914 * @param paParsedNames Array of parsed names, there are 915 * pOpts->cNameSpecifiers entries in the array. 916 */ 917 static int rtFsIsoMakerCmdAddFile(PRTFSISOMAKERCMDOPTS pOpts, const char *pszSrc, PCRTFSISOMAKERCMDPARSEDNAME paParsedNames) 918 { 919 uint32_t idxObj; 920 int rc = RTFsIsoMakerAddUnnamedFileWithSrcPath(pOpts->hIsoMaker, pszSrc, &idxObj); 921 if (RT_SUCCESS(rc)) 922 { 923 pOpts->cItemsAdded++; 924 925 for (uint32_t i = 0; i < pOpts->cNameSpecifiers; i++) 926 if (paParsedNames[i].cchPath > 0) 927 { 928 if (paParsedNames[i].fNameSpecifiers & RTFSISOMAKERCMDNAME_MAJOR_MASK) 929 { 930 rc = RTFsIsoMakerObjSetPath(pOpts->hIsoMaker, idxObj, 931 paParsedNames[i].fNameSpecifiers & RTFSISOMAKERCMDNAME_MAJOR_MASK, 932 paParsedNames[i].szPath); 933 if (RT_FAILURE(rc)) 934 { 935 rc = rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error setting name '%s' on '%s': %Rrc", 936 paParsedNames[i].szPath, pszSrc, rc); 937 break; 938 } 939 } 940 if (paParsedNames[i].fNameSpecifiers & RTFSISOMAKERCMDNAME_MINOR_MASK) 941 { 942 /** @todo add APIs for this. */ 943 } 944 } 945 } 946 else 947 rc = rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error adding '%s': %Rrc", pszSrc, rc); 948 return rc; 949 } 950 951 952 /** 902 953 * Processes a non-option argument. 903 954 * 904 * @returns 905 * @param pOpts .906 * @param pszSpec .955 * @returns IPRT status code. 956 * @param pOpts The ISO maker command instance. 957 * @param pszSpec The specification of what to add. 907 958 */ 908 959 static int rtFsIsoMakerCmdAddSomething(PRTFSISOMAKERCMDOPTS pOpts, const char *pszSpec) 909 960 { 910 961 const char * const pszSpecIn = pszSpec; 962 enum { kSpecialSrc_Normal, kSpecialSrc_Remove, kSpecialSrc_MustRemove } enmSpecialSrc = kSpecialSrc_Normal; 911 963 912 964 /* … … 917 969 for (;;) 918 970 { 919 const char *pszEqual = strchr(pszSpec, '='); 920 size_t cchName = pszEqual ? pszEqual - pszSpec : strlen(pszSpec); 921 if (cchName >= sizeof(aParsedNames[cParsedNames].szPath)) 971 const char *pszEqual = strchr(pszSpec, '='); 972 size_t cchName = pszEqual ? pszEqual - pszSpec : strlen(pszSpec); 973 bool fNeedSlash = pszEqual && !RTPATH_IS_SLASH(*pszSpec) && cchName > 0; 974 if (cchName + fNeedSlash >= sizeof(aParsedNames[cParsedNames].szPath)) 922 975 return rtFsIsoMakerCmdSyntaxError(pOpts, "name #%u (0-based) is too long: %s", cParsedNames, pszSpecIn); 923 976 if (cParsedNames >= pOpts->cNameSpecifiers + 1) 924 977 return rtFsIsoMakerCmdSyntaxError(pOpts, "too many names specified (max %u + source): %s", 925 978 pOpts->cNameSpecifiers, pszSpecIn); 926 memcpy(aParsedNames[cParsedNames].szPath, pszSpec, cchName); 979 if (!fNeedSlash) 980 memcpy(aParsedNames[cParsedNames].szPath, pszSpec, cchName); 981 else 982 { 983 memcpy(&aParsedNames[cParsedNames].szPath[1], pszSpec, cchName); 984 aParsedNames[cParsedNames].szPath[0] = RTPATH_SLASH; 985 cchName++; 986 } 927 987 aParsedNames[cParsedNames].szPath[cchName] = '\0'; 928 988 aParsedNames[cParsedNames].cchPath = (uint32_t)cchName; 929 989 cParsedNames++; 990 930 991 if (!pszEqual) 931 992 { 932 993 if (!cchName) 933 994 return rtFsIsoMakerCmdSyntaxError(pOpts, "empty source file name: %s", pszSpecIn); 995 if (cchName == 8 && strcmp(pszSpec, ":remove:") == 0) 996 enmSpecialSrc = kSpecialSrc_Remove; 997 else if (cchName == 13 && strcmp(pszSpec, ":must-remove:") == 0) 998 enmSpecialSrc = kSpecialSrc_MustRemove; 934 999 break; 935 1000 } … … 944 1009 aParsedNames[pOpts->cNameSpecifiers] = aParsedNames[cParsedNames - 1]; 945 1010 uint32_t iSrc = cParsedNames >= 2 ? cParsedNames - 2 : 0; 1011 1012 /* If the source is a input file name specifier, reduce it to something that starts with a slash. */ 1013 if (cParsedNames == 1) 1014 { 1015 if (RTVfsChainIsSpec(aParsedNames[iSrc].szPath)) 1016 { 1017 char *pszFinalPath; 1018 int rc = RTVfsChainQueryFinalPath(aParsedNames[iSrc].szPath, &pszFinalPath, NULL); 1019 if (RT_FAILURE(rc)) 1020 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "RTVfsChainQueryFinalPath failed with %Rrc on: %s", rc, pszSpecIn); 1021 aParsedNames[iSrc].cchPath = (uint32_t)strlen(pszFinalPath); 1022 if (RTPATH_IS_SLASH(*pszFinalPath)) 1023 memcpy(aParsedNames[iSrc].szPath, pszFinalPath, aParsedNames[iSrc].cchPath + 1); 1024 else 1025 { 1026 memcpy(&aParsedNames[iSrc].szPath[1], pszFinalPath, aParsedNames[iSrc].cchPath + 1); 1027 aParsedNames[iSrc].szPath[0] = RTPATH_SLASH; 1028 aParsedNames[iSrc].cchPath++; 1029 } 1030 RTStrFree(pszFinalPath); 1031 } 1032 #if RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS 1033 else if ( RTPATH_IS_VOLSEP(aParsedNames[iSrc].szPath[1]) 1034 && RT_C_IS_ALPHA(aParsedNames[iSrc].szPath[0])) 1035 { 1036 if (RTPATH_IS_SLASH(aParsedNames[iSrc].szPath[2])) 1037 { 1038 memmove(&aParsedNames[iSrc].szPath[0], &aParsedNames[iSrc].szPath[2], aParsedNames[iSrc].cchPath - 1); 1039 aParsedNames[iSrc].cchPath -= 2; 1040 } 1041 else 1042 { 1043 memmove(&aParsedNames[iSrc].szPath[1], &aParsedNames[iSrc].szPath[2], aParsedNames[iSrc].cchPath - 1); 1044 aParsedNames[iSrc].szPath[0] = RTPATH_SLASH; 1045 aParsedNames[iSrc].cchPath -= 1; 1046 } 1047 } 1048 #endif 1049 else if (!RTPATH_IS_SLASH(aParsedNames[iSrc].szPath[0])) 1050 { 1051 if (aParsedNames[iSrc].cchPath + 2 > sizeof(aParsedNames[iSrc].szPath)) 1052 return rtFsIsoMakerCmdSyntaxError(pOpts, "name too long: %s", pszSpecIn); 1053 memmove(&aParsedNames[iSrc].szPath[1], &aParsedNames[iSrc].szPath[0], aParsedNames[iSrc].cchPath + 1); 1054 aParsedNames[iSrc].szPath[0] = RTPATH_SLASH; 1055 aParsedNames[iSrc].cchPath++; 1056 } 1057 } 1058 946 1059 for (uint32_t iDst = cParsedNames; iDst < pOpts->cNameSpecifiers; iDst++) 947 1060 aParsedNames[iDst] = aParsedNames[iSrc]; … … 949 1062 } 950 1063 951 /* Copy the specifier flags. */ 1064 /* 1065 * Copy the specifier flags and check that the paths all starts with slashes. 1066 */ 952 1067 for (uint32_t i = 0; i < pOpts->cNameSpecifiers; i++) 1068 { 953 1069 aParsedNames[i].fNameSpecifiers = pOpts->afNameSpecifiers[i]; 1070 Assert( aParsedNames[i].cchPath == 0 1071 || RTPATH_IS_SLASH(aParsedNames[i].szPath[0])); 1072 } 954 1073 955 1074 /* 956 1075 * Deal with special source filenames used to remove/change stuff. 957 1076 */ 958 const char * const pszSrc = aParsedNames[cParsedNames - 1].szPath;959 if (strcmp(pszSrc, ":remove:") == 0)1077 if ( enmSpecialSrc == kSpecialSrc_Remove 1078 || enmSpecialSrc == kSpecialSrc_MustRemove) 960 1079 { 961 1080 const char *pszFirstNm = NULL; 1081 uint32_t cRemoved = 0; 1082 for (uint32_t i = 0; i < pOpts->cNameSpecifiers; i++) 1083 if ( aParsedNames[i].cchPath > 0 1084 && (aParsedNames[i].fNameSpecifiers & RTFSISOMAKERCMDNAME_MAJOR_MASK)) 1085 { 1086 pszFirstNm = aParsedNames[i].szPath; 1087 uint32_t idxObj = RTFsIsoMakerGetObjIdxForPath(pOpts->hIsoMaker, 1088 aParsedNames[i].fNameSpecifiers & RTFSISOMAKERCMDNAME_MAJOR_MASK, 1089 aParsedNames[i].szPath); 1090 if (idxObj != UINT32_MAX) 1091 { 1092 int rc = RTFsIsoMakerObjRemove(pOpts->hIsoMaker, idxObj); 1093 if (RT_FAILURE(rc)) 1094 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "Failed to remove '%s': %Rrc", pszSpecIn, rc); 1095 cRemoved++; 1096 } 1097 } 1098 if ( enmSpecialSrc == kSpecialSrc_MustRemove 1099 && cRemoved == 0) 1100 return rtFsIsoMakerCmdErrorRc(pOpts, VERR_NOT_FOUND, "Failed to locate '%s' for removal", pszSpecIn); 962 1101 } 1102 /* 1103 * Add regular source. 1104 */ 963 1105 else 964 1106 { 965 /* 966 * Regular source. 967 */ 968 1107 const char *pszSrc = aParsedNames[cParsedNames - 1].szPath; 1108 RTFSOBJINFO ObjInfo; 1109 uint32_t offError; 1110 RTERRINFOSTATIC ErrInfo; 1111 int rc = RTVfsChainQueryInfo(pszSrc, &ObjInfo, RTFSOBJATTRADD_UNIX, 1112 RTPATH_F_FOLLOW_LINK, &offError, RTErrInfoInitStatic(&ErrInfo)); 1113 if (RT_FAILURE(rc)) 1114 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error query info on '%s': %Rrc", pszSrc, rc); 1115 if (RTFS_IS_FILE(ObjInfo.Attr.fMode)) 1116 return rtFsIsoMakerCmdAddFile(pOpts, pszSrc, aParsedNames); 1117 if (RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode)) 1118 return rtFsIsoMakerCmdErrorRc(pOpts, VERR_NOT_IMPLEMENTED, "Adding directory '%s' failed: not implemented", pszSpecIn); 1119 if (RTFS_IS_SYMLINK(ObjInfo.Attr.fMode)) 1120 return rtFsIsoMakerCmdErrorRc(pOpts, VERR_NOT_IMPLEMENTED, "Adding symlink '%s' failed: not implemented", pszSpecIn); 1121 return rtFsIsoMakerCmdErrorRc(pOpts, VERR_NOT_IMPLEMENTED, "Adding special file '%s' failed: not implemented", pszSpecIn); 969 1122 } 970 1123 … … 997 1150 Opts.pErrInfo = pErrInfo; 998 1151 Opts.fVirtualImageMaker = phVfsFile != NULL; 1152 Opts.cNameSpecifiers = 1; 1153 Opts.afNameSpecifiers[0] = RTFSISOMAKERCMDNAME_MAJOR_MASK; 1154 Opts.fDstNamespaces = RTFSISOMAKERCMDNAME_MAJOR_MASK; 999 1155 if (phVfsFile) 1000 1156 *phVfsFile = NIL_RTVFSFILE;
Note:
See TracChangeset
for help on using the changeset viewer.