Changeset 67303 in vbox for trunk/src/VBox/Runtime/common/fs
- Timestamp:
- Jun 8, 2017 2:54:31 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 116007
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fs/isomaker.cpp
r67281 r67303 172 172 bool fTransNmAlloced : 1; 173 173 174 /** @todo more rock ridge info here. */ 174 /** The mode mask. 175 * Starts out as a copy of RTFSISOMAKEROBJ::fMode. */ 176 RTFMODE fMode; 177 /** The owner ID. 178 * Starts out as a copy of RTFSISOMAKEROBJ::uid. */ 179 RTUID uid; 180 /** The group ID. 181 * Starts out as a copy of RTFSISOMAKEROBJ::gid. */ 182 RTGID gid; 183 /** The device number if a character or block device. 184 * This is for Rock Ridge. */ 185 RTDEV Device; 186 /** The number of hardlinks to report in the file stats. 187 * This is for Rock Ridge. */ 188 uint32_t cHardlinks; 189 /** The inode/serial number. 190 * This is for Rock Ridge. */ 191 uint64_t INode; 175 192 176 193 /** The name length. */ … … 186 203 { 187 204 /** The namespace root. */ 188 RTFSISOMAKERNAMEpRoot;205 PRTFSISOMAKERNAME pRoot; 189 206 /** Total number of name nodes in the namespace. */ 190 207 uint32_t cNames; … … 193 210 /** The namespace selector (RTFSISOMAKER_NAMESPACE_XXX). */ 194 211 uint32_t fNamespace; 212 /** Offset into RTFSISOMAKERNAMESPACE of the name member. */ 213 uint32_t offName; 195 214 /** The configuration level for this name space. 196 215 * - For UDF and HFS namespaces this is either @c true or @c false. … … 202 221 uint8_t uRockRidgeLevel; 203 222 /** Set if TRANS.TBL files are to be generated for this namespace. */ 223 bool fTransTbl; 204 224 } RTFSISOMAKERNAMESPACE; 205 225 /** Pointer to a namespace. */ 206 226 typedef RTFSISOMAKERNAMESPACE *PRTFSISOMAKERNAMESPACE; 227 /** Pointer to a const namespace. */ 228 typedef RTFSISOMAKERNAMESPACE const *PCRTFSISOMAKERNAMESPACE; 207 229 208 230 209 231 /** 210 232 * Common base structure for the file system objects. 233 * 234 * The times are shared across all namespaces, while the uid, gid and mode are 235 * duplicates in each namespace. 211 236 */ 212 237 typedef struct RTFSISOMAKEROBJ … … 228 253 PRTFSISOMAKERNAME pHfsName; 229 254 255 /** Birth (creation) time. */ 256 RTTIMESPEC BirthTime; 257 /** Attribute change time. */ 258 RTTIMESPEC ChangeTime; 259 /** Modification time. */ 260 RTTIMESPEC ModificationTime; 261 /** Accessed time. */ 262 RTTIMESPEC AccessedTime; 263 264 /** Owner ID. */ 265 RTUID uid; 266 /** Group ID. */ 267 RTGID gid; 268 /** Attributes (unix permissions bits mainly). */ 269 RTFMODE fMode; 270 230 271 } RTFSISOMAKEROBJ; 231 272 … … 238 279 RTFSISOMAKERSRCTYPE_INVALID = 0, 239 280 RTFSISOMAKERSRCTYPE_PATH, 240 RTFSISOMAKERSRCTYPE_VFS_ IO_STREAM,281 RTFSISOMAKERSRCTYPE_VFS_FILE, 241 282 RTFSISOMAKERSRCTYPE_END 242 283 } RTFSISOMAKERSRCTYPE; … … 259 300 union 260 301 { 261 /** Path to the source file. */ 302 /** Path to the source file. 303 * Allocated together with this structure. */ 262 304 const char *pszSrcPath; 263 /** Source I/O stream (or file). */264 RTVFS IOSTREAM hVfsIoStr;305 /** Source VFS file. */ 306 RTVFSFILE hVfsFile; 265 307 } u; 266 308 } RTFSISOMAKERFILE; … … 293 335 uint32_t volatile cRefs; 294 336 295 /** @name Name space configuration.296 * @{ */297 337 /** Set after we've been fed the first bit of content. 298 338 * This means that the namespace configuration has been finalized and can no … … 300 340 * after having started to add files. */ 301 341 bool fSeenContent; 302 /** The ISO level (1-3), default is 3.303 * @todo support mkisofs level 4 (ISO-9660:1990, version 2). */304 uint8_t uIsoLevel;305 /** The joliet UCS level (1, 2, or 3), 0 if joliet is not enabled. */306 uint8_t uJolietLevel;307 /** Enables UDF.308 * @remarks not yet implemented. */309 bool fUdf;310 /** Enables HFS311 * @remarks not yet implemented. */312 bool fHfs;313 /** @} */314 342 315 343 /** The primary ISO-9660 namespace. */ … … 334 362 uint64_t cbTotal; 335 363 364 /** The 'now' timestamp we use for the whole image. 365 * This way we'll save lots of RTTimeNow calls and have similar timestamps 366 * over the whole image. */ 367 RTTIMESPEC ImageCreationTime; 368 /** The default owner ID. */ 369 RTUID uidDefault; 370 /** The default group ID. */ 371 RTGID gidDefault; 372 /** The default file mode mask. */ 373 RTFMODE fDefaultFileMode; 374 /** The default file mode mask. */ 375 RTFMODE fDefaultDirMode; 376 336 377 } RTFSISOMAKERINT; 337 378 /** Pointer to an ISO maker instance. */ … … 349 390 /** The RTFSISOMAKERNAMESPACE_XXX indicator. */ 350 391 uint32_t fNamespace; 351 /** Offset into RTFSISOMAKERINT of the rootmember. */352 uintptr_t off Root;392 /** Offset into RTFSISOMAKERINT of the namespace member. */ 393 uintptr_t offNamespace; 353 394 /** Offset into RTFSISOMAKERNAMESPACE of the name member. */ 354 395 uintptr_t offName; … … 357 398 } g_aRTFsIsoNamespaces[] = 358 399 { 359 { RTFSISOMAKERNAMESPACE_ISO_9660, RT_OFFSETOF(RTFSISOMAKERINT, pPrimaryIsoRoot), RT_OFFSETOF(RTFSISOMAKEROBJ, pPrimaryName), "iso-9660" },360 { RTFSISOMAKERNAMESPACE_JOLIET, RT_OFFSETOF(RTFSISOMAKERINT, pJolietRoot), RT_OFFSETOF(RTFSISOMAKEROBJ, pJolietName), "joliet" },361 { RTFSISOMAKERNAMESPACE_UDF, RT_OFFSETOF(RTFSISOMAKERINT, pUdfRoot), RT_OFFSETOF(RTFSISOMAKEROBJ, pUdfName), "udf" },362 { RTFSISOMAKERNAMESPACE_HFS, RT_OFFSETOF(RTFSISOMAKERINT, pHfsRoot), RT_OFFSETOF(RTFSISOMAKEROBJ, pHfsName), "hfs" },400 { RTFSISOMAKERNAMESPACE_ISO_9660, RT_OFFSETOF(RTFSISOMAKERINT, PrimaryIso), RT_OFFSETOF(RTFSISOMAKEROBJ, pPrimaryName), "iso-9660" }, 401 { RTFSISOMAKERNAMESPACE_JOLIET, RT_OFFSETOF(RTFSISOMAKERINT, Joliet), RT_OFFSETOF(RTFSISOMAKEROBJ, pJolietName), "joliet" }, 402 { RTFSISOMAKERNAMESPACE_UDF, RT_OFFSETOF(RTFSISOMAKERINT, Udf), RT_OFFSETOF(RTFSISOMAKEROBJ, pUdfName), "udf" }, 403 { RTFSISOMAKERNAMESPACE_HFS, RT_OFFSETOF(RTFSISOMAKERINT, Hfs), RT_OFFSETOF(RTFSISOMAKEROBJ, pHfsName), "hfs" }, 363 404 }; 364 405 … … 443 484 444 485 pThis->PrimaryIso.fNamespace = RTFSISOMAKERNAMESPACE_ISO_9660; 486 pThis->PrimaryIso.offName = RT_OFFSETOF(RTFSISOMAKEROBJ, pPrimaryName); 445 487 pThis->PrimaryIso.uLevel = 3; /* 30 char names, large files */ 446 488 pThis->PrimaryIso.uRockRidgeLevel = 1; 489 pThis->PrimaryIso.fTransTbl = true; 447 490 pThis->Joliet.fNamespace = RTFSISOMAKERNAMESPACE_JOLIET; 491 pThis->Joliet.offName = RT_OFFSETOF(RTFSISOMAKEROBJ, pJolietName); 448 492 pThis->Joliet.uLevel = 3; 449 493 //pThis->Joliet.uRockRidgeLevel = 0; 494 //pThis->Joliet.fTransTbl = false; 450 495 pThis->Udf.fNamespace = RTFSISOMAKERNAMESPACE_UDF; 496 pThis->Udf.offName = RT_OFFSETOF(RTFSISOMAKEROBJ, pUdfName); 451 497 //pThis->Udf.uLevel = 0; 452 498 //pThis->Udf.uRockRidgeLevel = 0; 499 //pThis->Udf.fTransTbl = false; 453 500 pThis->Hfs.fNamespace = RTFSISOMAKERNAMESPACE_HFS; 501 pThis->Hfs.offName = RT_OFFSETOF(RTFSISOMAKEROBJ, pHfsName); 454 502 //pThis->Hfs.uLevel = 0; 455 503 //pThis->Hfs.uRockRidgeLevel = 0; 504 //pThis->Hfs.fTransTbl = false; 456 505 457 506 RTListInit(&pThis->ObjectHead); 458 507 //pThis->cObjects = 0; 459 //pThis->cNames = 0;460 508 //pThis->cbData = 0; 509 461 510 pThis->cbTotal = _32K /* The system area size. */ 462 511 + RTFSISOMAKER_SECTOR_SIZE /* Primary volume descriptor. */ 463 512 + RTFSISOMAKER_SECTOR_SIZE /* Secondary volume descriptor for joliet. */ 464 513 + RTFSISOMAKER_SECTOR_SIZE /* Terminator descriptor. */; 514 515 //pThis->uidDefault = 0; 516 //pThis->gidDefault = 0; 517 pThis->fDefaultFileMode = 0444 | RTFS_TYPE_FILE | RTFS_DOS_ARCHIVED | RTFS_DOS_READONLY; 518 pThis->fDefaultDirMode = 0555 | RTFS_TYPE_DIRECTORY | RTFS_DOS_DIRECTORY | RTFS_DOS_READONLY; 519 520 RTTimeNow(&pThis->ImageCreationTime); 521 465 522 *phIsoMaker = pThis; 466 523 return VINF_SUCCESS; 467 524 } 468 525 return VERR_NO_MEMORY; 526 } 527 528 529 /** 530 * Frees an object. 531 * 532 * This is a worker for rtFsIsoMakerDestroy and RTFsIsoMakerObjRemove. 533 * 534 * @param pObj The object to free. 535 */ 536 DECLINLINE(void) rtFsIsoMakerObjDestroy(PRTFSISOMAKEROBJ pObj) 537 { 538 if (pObj->enmType == RTFSISOMAKEROBJTYPE_FILE) 539 { 540 PRTFSISOMAKERFILE pFile = (PRTFSISOMAKERFILE)pObj; 541 switch (pFile->enmSrcType) 542 { 543 case RTFSISOMAKERSRCTYPE_PATH: 544 /* do nothing. */ 545 break; 546 547 case RTFSISOMAKERSRCTYPE_VFS_FILE: 548 RTVfsFileRelease(pFile->u.hVfsFile); 549 pFile->u.hVfsFile = NIL_RTVFSFILE; 550 break; 551 552 case RTFSISOMAKERSRCTYPE_INVALID: 553 case RTFSISOMAKERSRCTYPE_END: 554 AssertFailed(); 555 break; 556 557 /* no default, want warnings */ 558 } 559 } 560 561 RTMemFree(pObj); 562 } 563 564 565 /** 566 * Frees a namespace node. 567 * 568 * This is a worker for rtFsIsoMakerDestroyTree and rtFsIsoMakerObjUnsetName. 569 * 570 * @param pName The node to free. 571 */ 572 DECLINLINE(void) rtFsIsoMakerDestroyName(PRTFSISOMAKERNAME pName) 573 { 574 if (pName->fRockRidgeNmAlloced) 575 { 576 RTMemFree(pName->pszRockRidgeNm); 577 pName->pszRockRidgeNm = NULL; 578 } 579 if (pName->fTransNmAlloced) 580 { 581 RTMemFree(pName->pszTransNm); 582 pName->pszTransNm = NULL; 583 } 584 RTMemFree(pName); 469 585 } 470 586 … … 486 602 else 487 603 { 488 RTMemFree(pCur->pszRockRidgeNm);489 pCur->pszRockRidgeNm = NULL;490 RTMemFree(pCur->pszTransNm);491 pCur->pszTransNm = NULL;492 604 PRTFSISOMAKERNAME pNext = pCur->pParent; 493 RTMemFree(pCur);605 rtFsIsoMakerDestroyName(pCur); 494 606 495 607 /* Unlink from parent, we're the last entry. */ … … 519 631 static void rtFsIsoMakerDestroy(PRTFSISOMAKERINT pThis) 520 632 { 521 rtFsIsoMakerDestroyTree(pThis-> pPrimaryIsoRoot);522 rtFsIsoMakerDestroyTree(pThis-> pJolietRoot);523 rtFsIsoMakerDestroyTree(pThis-> pUdfRoot);524 rtFsIsoMakerDestroyTree(pThis-> pHfsRoot);633 rtFsIsoMakerDestroyTree(pThis->PrimaryIso.pRoot); 634 rtFsIsoMakerDestroyTree(pThis->Joliet.pRoot); 635 rtFsIsoMakerDestroyTree(pThis->Udf.pRoot); 636 rtFsIsoMakerDestroyTree(pThis->Hfs.pRoot); 525 637 526 638 PRTFSISOMAKEROBJ pCur; … … 529 641 { 530 642 RTListNodeRemove(&pCur->Entry); 531 RTMemFree(pCur);643 rtFsIsoMakerObjDestroy(pCur); 532 644 } 533 645 } … … 592 704 AssertReturn(!pThis->fSeenContent, VERR_WRONG_ORDER); 593 705 594 pThis-> uIsoLevel = uIsoLevel;706 pThis->PrimaryIso.uLevel = uIsoLevel; 595 707 return VINF_SUCCESS; 596 708 } … … 612 724 AssertReturn(!pThis->fSeenContent, VERR_WRONG_ORDER); 613 725 614 if (pThis-> uJolietLevel != uJolietLevel)726 if (pThis->Joliet.uLevel != uJolietLevel) 615 727 { 616 728 if (uJolietLevel == 0) 617 729 pThis->cbTotal -= RTFSISOMAKER_SECTOR_SIZE; 618 else if (pThis-> uJolietLevel == 0)730 else if (pThis->Joliet.uLevel == 0) 619 731 pThis->cbTotal += RTFSISOMAKER_SECTOR_SIZE; 620 pThis-> uJolietLevel = uJolietLevel;732 pThis->Joliet.uLevel = uJolietLevel; 621 733 } 622 734 return VINF_SUCCESS; … … 639 751 AssertReturn(uLevel <= 2, VERR_INVALID_PARAMETER); 640 752 641 pThis-> uRockRidgeLevel = uLevel;753 pThis->PrimaryIso.uRockRidgeLevel = uLevel; 642 754 return VINF_SUCCESS; 643 755 } … … 659 771 AssertReturn(uLevel <= 2, VERR_INVALID_PARAMETER); 660 772 661 pThis-> uJolietRockRidgeLevel = uLevel;773 pThis->Joliet.uRockRidgeLevel = uLevel; 662 774 return VINF_SUCCESS; 663 775 } … … 673 785 */ 674 786 675 787 #if 0 676 788 /** 677 789 * Gets the pointer to the root member for the given namespace. … … 688 800 return (PPRTFSISOMAKERNAME)((uintptr_t)pThis + g_aRTFsIsoNamespaces[g_aidxRTFsIsoNamespaceFlagToIdx[fNamespace]].offRoot); 689 801 } 802 #endif 690 803 691 804 … … 695 808 * @returns Pointer to name member. 696 809 * @param pObj The object to find a name member in. 697 * @param fNamespace The namespace which name to find. 698 */ 699 static PPRTFSISOMAKERNAME rtFsIsoMakerObjGetNameForNamespace(PRTFSISOMAKEROBJ pObj, uint32_t fNamespace) 700 { 701 Assert(RT_IS_POWER_OF_TWO(fNamespace)); 702 Assert(fNamespace); 703 Assert(fNamespace <= RTFSISOMAKERNAMESPACE_HFS); 704 return (PPRTFSISOMAKERNAME)((uintptr_t)pObj + g_aRTFsIsoNamespaces[g_aidxRTFsIsoNamespaceFlagToIdx[fNamespace]].offName); 810 * @param pNamespace The namespace which name to calculate. 811 */ 812 DECLINLINE(PPRTFSISOMAKERNAME) rtFsIsoMakerObjGetNameForNamespace(PRTFSISOMAKEROBJ pObj, PCRTFSISOMAKERNAMESPACE pNamespace) 813 { 814 return (PPRTFSISOMAKERNAME)((uintptr_t)pObj + pNamespace->offName); 705 815 } 706 816 … … 875 985 * Produce a first name. 876 986 */ 987 uint8_t const uIsoLevel = pThis->PrimaryIso.uLevel; 877 988 size_t cchDst; 878 989 size_t offDstDot; 879 990 if (fIsDir) 880 offDstDot = cchDst = rtFsIsoMakerCopyIso9660Name(pszDst, pThis->uIsoLevel >= 2 ? ISO9660_MAX_NAME_LEN : 8,991 offDstDot = cchDst = rtFsIsoMakerCopyIso9660Name(pszDst, uIsoLevel >= 2 ? ISO9660_MAX_NAME_LEN : 8, 881 992 pchSrc, cchSrc); 882 993 else … … 889 1000 890 1001 if (offLastDot == cchSrc) 891 offDstDot = cchDst = rtFsIsoMakerCopyIso9660Name(pszDst, pThis->uIsoLevel >= 2 ? ISO9660_MAX_NAME_LEN : 8,1002 offDstDot = cchDst = rtFsIsoMakerCopyIso9660Name(pszDst, uIsoLevel >= 2 ? ISO9660_MAX_NAME_LEN : 8, 892 1003 pchSrc, cchSrc); 893 1004 else … … 895 1006 const char * const pchSrcExt = &pchSrc[offLastDot + 1]; 896 1007 size_t const cchSrcExt = cchSrc - offLastDot - 1; 897 if ( pThis->uIsoLevel < 2)1008 if (uIsoLevel < 2) 898 1009 { 899 1010 cchDst = rtFsIsoMakerCopyIso9660Name(pszDst, 8, pchSrc, cchSrc); … … 936 1047 * Mangle the name till we've got a unique one. 937 1048 */ 938 size_t const cchMaxBasename = ( pThis->uIsoLevel >= 2 ? ISO9660_MAX_NAME_LEN : 8) - (cchDst - offDstDot);1049 size_t const cchMaxBasename = (uIsoLevel >= 2 ? ISO9660_MAX_NAME_LEN : 8) - (cchDst - offDstDot); 939 1050 size_t cchInserted = 0; 940 1051 for (uint32_t i = 0; i < _32K; i++) … … 975 1086 * @returns IPRT status code. 976 1087 * @param pThis The ISO maker instance. 1088 * @param pNamespace The namespace which rules to normalize it according to. 977 1089 * @param pParent The parent directory. NULL if root. 978 1090 * @param pchSrc The specified name to normalize (not necessarily zero 979 1091 * terminated). 980 1092 * @param cchSrc The length of the specified name. 981 * @param fNamespace The namespace rules to normalize it according to.982 1093 * @param fIsDir Indicates whether it's a directory or file (like). 983 1094 * @param pszDst The output buffer. Must be at least 32 bytes. … … 986 1097 * not counting the terminator). 987 1098 */ 988 static int rtFsIsoMakerNormalizeNameForNamespace(PRTFSISOMAKERINT pThis, PRTFSISOMAKERNAME pParent,989 const char *pchSrc, size_t cchSrc, uint32_t fNamespace, bool fIsDir,1099 static int rtFsIsoMakerNormalizeNameForNamespace(PRTFSISOMAKERINT pThis, PRTFSISOMAKERNAMESPACE pNamespace, 1100 PRTFSISOMAKERNAME pParent, const char *pchSrc, size_t cchSrc, bool fIsDir, 990 1101 char *pszDst, size_t cbDst, size_t *pcchDst) 991 1102 { … … 996 1107 */ 997 1108 AssertReturn(!rtFsIsoMakerFindEntryInDirBySpec(pParent, pchSrc, cchSrc), VERR_ALREADY_EXISTS); 998 switch ( fNamespace)1109 switch (pNamespace->fNamespace) 999 1110 { 1000 1111 /* … … 1009 1120 case RTFSISOMAKERNAMESPACE_JOLIET: 1010 1121 { 1011 /** @todo Joliet name limit . */1122 /** @todo Joliet name limit and check for duplicates. */ 1012 1123 AssertReturn(cbDst > cchSrc, VERR_BUFFER_OVERFLOW); 1013 1124 memcpy(pszDst, pchSrc, cchSrc); … … 1047 1158 * @param pNamespace The namespace. 1048 1159 * @param pObj The object to name. 1049 * @param ppName The pointer to the object's namespace member.1050 1160 * @param pParent The parent namespace entry 1051 1161 * @param pchSpec The specified name (not necessarily terminated). … … 1054 1164 */ 1055 1165 static int rtFsIsoMakerObjSetName(PRTFSISOMAKERINT pThis, PRTFSISOMAKERNAMESPACE pNamespace, PRTFSISOMAKEROBJ pObj, 1056 PPRTFSISOMAKERNAME ppName, PRTFSISOMAKERNAME pParent, const char *pchSpec, size_t cchSpec, 1057 PPRTFSISOMAKERNAME ppNewName) 1166 PRTFSISOMAKERNAME pParent, const char *pchSpec, size_t cchSpec, PPRTFSISOMAKERNAME ppNewName) 1058 1167 { 1059 1168 Assert(cchSpec < _32K); … … 1063 1172 * large enough. If root object, make sure we haven't got a root already. 1064 1173 */ 1065 PPRTFSISOMAKERNAME ppRoot;1066 1174 if (pParent) 1067 1175 { … … 1077 1185 pParent->pDir->papChildren = (PPRTFSISOMAKERNAME)pvNew; 1078 1186 } 1079 ppRoot = NULL;1080 1187 } 1081 1188 else 1082 { 1083 ppRoot = rtFsIsoMakerGetRootForNamespace(pThis, fNamespace); 1084 AssertReturn(*ppRoot, VERR_INTERNAL_ERROR_5); 1085 } 1189 AssertReturn(pNamespace->pRoot == NULL, VERR_INTERNAL_ERROR_5); 1086 1190 1087 1191 /* … … 1090 1194 size_t cchName; 1091 1195 char szName[RTFSISOMAKER_MAX_NAME_BUF]; 1092 int rc = rtFsIsoMakerNormalizeNameForNamespace(pThis, p Parent, pchSpec, cchSpec, fNamespace,1196 int rc = rtFsIsoMakerNormalizeNameForNamespace(pThis, pNamespace, pParent, pchSpec, cchSpec, 1093 1197 pObj->enmType == RTFSISOMAKEROBJTYPE_DIR, 1094 1198 szName, sizeof(szName), &cchName); … … 1119 1223 pName->fRockRidgeNmAlloced = false; 1120 1224 pName->fTransNmAlloced = false; 1225 1226 pName->fMode = pObj->fMode; 1227 pName->uid = pObj->uid; 1228 pName->gid = pObj->gid; 1229 pName->Device = 0; 1230 pName->cHardlinks = 1; 1231 pName->INode = pObj->idxObj; 1121 1232 1122 1233 memcpy(pName->szName, szName, cchName); … … 1146 1257 pParent->pDir->papChildren[pParent->pDir->cChildren++] = pName; 1147 1258 else 1148 *ppRoot = pName;1149 * ppName= pName;1150 p This->cNames++;1259 pNamespace->pRoot = pName; 1260 *rtFsIsoMakerObjGetNameForNamespace(pObj, pNamespace) = pName; 1261 pNamespace->cNames++; 1151 1262 1152 1263 /* … … 1162 1273 1163 1274 1164 static int rtFsIsoMakerPathToParent(PRTFSISOMAKERINT pThis, P PRTFSISOMAKERNAME ppRoot, uint32_t fNamespace, const char *pszPath,1275 static int rtFsIsoMakerPathToParent(PRTFSISOMAKERINT pThis, PRTFSISOMAKERNAMESPACE pNamespace, const char *pszPath, 1165 1276 PPRTFSISOMAKERNAME ppParent, const char **ppszEntry, size_t *pcchEntry) 1166 1277 { … … 1175 1286 AssertReturn(*pszPath, VERR_INTERNAL_ERROR_4); 1176 1287 1177 PRTFSISOMAKERNAME pParent = *ppRoot;1288 PRTFSISOMAKERNAME pParent = pNamespace->pRoot; 1178 1289 if (!pParent) 1179 1290 { … … 1191 1302 Assert(pDir->Core.idxObj == 0); 1192 1303 Assert(pDir->Core.enmType == RTFSISOMAKEROBJTYPE_DIR); 1193 Assert(*rtFsIsoMakerObjGetNameForNamespace(&pDir->Core, fNamespace) == NULL);1304 Assert(*rtFsIsoMakerObjGetNameForNamespace(&pDir->Core, pNamespace) == NULL); 1194 1305 #endif 1195 1306 } 1196 1307 1197 rc = rtFsIsoMakerObjSetName(pThis, pNamespace, &pDir->Core, rtFsIsoMakerObjGetNameForNamespace(&pDir->Core, fNamespace), 1198 NULL /*pParent*/, "", 0, &pParent); 1308 rc = rtFsIsoMakerObjSetName(pThis, pNamespace, &pDir->Core, NULL /*pParent*/, "", 0, &pParent); 1199 1309 AssertRCReturn(rc, rc); 1200 AssertReturn(*ppRoot, VERR_INTERNAL_ERROR_4);1201 pParent = *ppRoot;1310 pParent = pNamespace->pRoot; 1311 AssertReturn(pParent, VERR_INTERNAL_ERROR_4); 1202 1312 } 1203 1313 … … 1260 1370 (We don't want to waste heap by creating a directory instance per namespace.) */ 1261 1371 PRTFSISOMAKERDIR pChildObj = rtFsIsoMakerFindSubdirBySpec((PRTFSISOMAKERDIR)pParent->pObj, 1262 pszPath, cchComponent, fNamespace);1372 pszPath, cchComponent, pNamespace->fNamespace); 1263 1373 if (pChildObj) 1264 1374 { 1265 PPRTFSISOMAKERNAME ppChildName = rtFsIsoMakerObjGetNameForNamespace(&pChildObj->Core, fNamespace);1375 PPRTFSISOMAKERNAME ppChildName = rtFsIsoMakerObjGetNameForNamespace(&pChildObj->Core, pNamespace); 1266 1376 if (!*ppChildName) 1267 1377 { 1268 rc = rtFsIsoMakerObjSetName(pThis, pNamespace, &pChildObj->Core, ppChildName, pParent, 1269 pszPath, cchComponent, &pChild); 1378 rc = rtFsIsoMakerObjSetName(pThis, pNamespace, &pChildObj->Core, pParent, pszPath, cchComponent, &pChild); 1270 1379 if (RT_FAILURE(rc)) 1271 1380 return rc; … … 1278 1387 rc = rtFsIsoMakerAddUnnamedDirWorker(pThis, &pChildObj); 1279 1388 if (RT_SUCCESS(rc)) 1280 rc = rtFsIsoMakerObjSetName(pThis, pNamespace, &pChildObj->Core, 1281 rtFsIsoMakerObjGetNameForNamespace(&pChildObj->Core, fNamespace), 1282 pParent, pszPath, cchComponent, &pChild); 1389 rc = rtFsIsoMakerObjSetName(pThis, pNamespace, &pChildObj->Core, pParent, pszPath, cchComponent, &pChild); 1283 1390 if (RT_FAILURE(rc)) 1284 1391 return rc; … … 1301 1408 * @returns IPRT status code. 1302 1409 * @param pThis The ISO maker instance. 1410 * @param pNamespace The namespace to name it in. 1303 1411 * @param pObj The filesystem object to name. 1304 * @param fNamespace The namespace to name it in.1305 1412 * @param pszPath The path to the entry in the namespace. 1306 * @param ppRoot The namespace root. 1307 * @param ppName The namespace name member in @a paEntry. 1308 */ 1309 static int rtFsIsoMakerObjSetPathInOne(PRTFSISOMAKERINT pThis, PRTFSISOMAKEROBJ pObj, uint32_t fNamespace, const char *pszPath, 1310 PPRTFSISOMAKERNAME ppRoot, PPRTFSISOMAKERNAME ppName) 1311 { 1312 AssertReturn(!*ppName, VERR_WRONG_ORDER); 1413 */ 1414 static int rtFsIsoMakerObjSetPathInOne(PRTFSISOMAKERINT pThis, PRTFSISOMAKERNAMESPACE pNamespace, 1415 PRTFSISOMAKEROBJ pObj, const char *pszPath) 1416 { 1417 AssertReturn(*rtFsIsoMakerObjGetNameForNamespace(pObj, pNamespace) == NULL, VERR_WRONG_ORDER); 1313 1418 AssertReturn(RTPATH_IS_SLASH(*pszPath), VERR_INTERNAL_ERROR_5); 1314 1419 … … 1322 1427 int rc; 1323 1428 if (pszPath[1] != '\0') 1324 rc = rtFsIsoMakerPathToParent(pThis, p pRoot, fNamespace, pszPath, &pParent, &pszEntry, &cchEntry);1429 rc = rtFsIsoMakerPathToParent(pThis, pNamespace, pszPath, &pParent, &pszEntry, &cchEntry); 1325 1430 else 1326 1431 { … … 1329 1434 */ 1330 1435 Assert(pObj->enmType == RTFSISOMAKEROBJTYPE_DIR); 1331 AssertReturn( !*ppRoot, VERR_WRONG_ORDER);1436 AssertReturn(pNamespace->pRoot == NULL, VERR_WRONG_ORDER); 1332 1437 pszEntry = "/"; 1333 1438 cchEntry = 0; … … 1343 1448 AssertReturn(!RTPATH_IS_SLASH(pszEntry[cchEntry]) || pObj->enmType == RTFSISOMAKEROBJTYPE_DIR, 1344 1449 VERR_NOT_A_DIRECTORY); 1345 rc = rtFsIsoMakerObjSetName(pThis, pNamespace, pObj, p pName, pParent, pszEntry, cchEntry, NULL);1450 rc = rtFsIsoMakerObjSetName(pThis, pNamespace, pObj, pParent, pszEntry, cchEntry, NULL); 1346 1451 } 1347 1452 return rc; 1453 } 1454 1455 1456 /** 1457 * Removes an object from the given namespace. 1458 * 1459 * @returns IPRT status code. 1460 * @param pThis The ISO maker instance. 1461 * @param pNamespace The namespace. 1462 * @param pObj The object to name. 1463 */ 1464 static int rtFsIsoMakerObjUnsetName(PRTFSISOMAKERINT pThis, PRTFSISOMAKERNAMESPACE pNamespace, PRTFSISOMAKEROBJ pObj) 1465 { 1466 /* 1467 * First check if there is anything to do here at all. 1468 */ 1469 PPRTFSISOMAKERNAME ppName = rtFsIsoMakerObjGetNameForNamespace(pObj, pNamespace); 1470 PRTFSISOMAKERNAME pName = *ppName; 1471 if (!pName) 1472 return VINF_SUCCESS; 1473 1474 /* 1475 * We don't support this on the root. 1476 */ 1477 AssertReturn(pName->pParent, VERR_ACCESS_DENIED); 1478 1479 /* 1480 * If this is a directory, we're in for some real fun here as we need to 1481 * unset the names of all the children too. 1482 */ 1483 PRTFSISOMAKERNAMEDIR pDir = pName->pDir; 1484 if (pDir) 1485 { 1486 uint32_t iChild = pDir->cChildren; 1487 while (iChild-- > 0) 1488 { 1489 int rc = rtFsIsoMakerObjUnsetName(pThis, pNamespace, pDir->papChildren[iChild]->pObj); 1490 if (RT_FAILURE(rc)) 1491 return rc; 1492 } 1493 AssertReturn(pDir->cChildren == 0, VERR_DIR_NOT_EMPTY); 1494 } 1495 1496 /* 1497 * Unlink the pName from the parent. 1498 */ 1499 pDir = pName->pParent->pDir; 1500 uint32_t iChild = pDir->cChildren; 1501 while (iChild-- > 0) 1502 if (pDir->papChildren[iChild] == pName) 1503 { 1504 uint32_t cToMove = pDir->cChildren - iChild - 1; 1505 if (cToMove > 0) 1506 memmove(&pDir->papChildren[iChild], &pDir->papChildren[iChild + 1], cToMove * sizeof(pDir->papChildren[0])); 1507 pDir->cChildren--; 1508 pNamespace->cNames--; 1509 1510 /* 1511 * NULL the name member in the object and free the structure. 1512 */ 1513 *ppName = NULL; 1514 RTMemFree(pName); 1515 1516 return VINF_SUCCESS; 1517 } 1518 1519 /* Not found. This can't happen. */ 1520 AssertFailed(); 1521 return VERR_INTERNAL_ERROR_2; 1348 1522 } 1349 1523 … … 1391 1565 return pObj; 1392 1566 return rtFsIsoMakerIndexToObjSlow(pThis, idxObj); 1567 } 1568 1569 1570 /** 1571 * Removes the specified object from the image. 1572 * 1573 * @returns IPRT status code. 1574 * @param hIsoMaker The ISO maker instance. 1575 * @param idxObj The index of the object to remove. 1576 */ 1577 RTDECL(int) RTFsIsoMakerObjRemove(RTFSISOMAKER hIsoMaker, uint32_t idxObj) 1578 { 1579 /* 1580 * Validate and translate input. 1581 */ 1582 PRTFSISOMAKERINT pThis = hIsoMaker; 1583 RTFSISOMAKER_ASSER_VALID_HANDLE_RET(pThis); 1584 PRTFSISOMAKEROBJ pObj = rtFsIsoMakerIndexToObj(pThis, idxObj); 1585 AssertReturn(pObj, VERR_OUT_OF_RANGE); 1586 1587 /* 1588 * Remove the object from all name spaces. 1589 */ 1590 int rc = VINF_SUCCESS; 1591 for (uint32_t i = 0; i < RT_ELEMENTS(g_aRTFsIsoNamespaces); i++) 1592 { 1593 PRTFSISOMAKERNAMESPACE pNamespace = (PRTFSISOMAKERNAMESPACE)((uintptr_t)pThis + g_aRTFsIsoNamespaces[i].offNamespace); 1594 int rc2 = rtFsIsoMakerObjUnsetName(pThis, pNamespace, pObj); 1595 if (RT_SUCCESS(rc2) || RT_FAILURE(rc)) 1596 continue; 1597 rc = rc2; 1598 } 1599 1600 /* 1601 * If that succeeded, remove the object itself. 1602 */ 1603 if (RT_SUCCESS(rc)) 1604 { 1605 RTListNodeRemove(&pObj->Entry); 1606 if (pObj->enmType == RTFSISOMAKEROBJTYPE_FILE) 1607 { 1608 uint64_t cbData = ((PRTFSISOMAKERFILE)pObj)->cbData; 1609 pThis->cbData -= RT_ALIGN_64(cbData, RTFSISOMAKER_SECTOR_SIZE); 1610 } 1611 pThis->cObjects--; 1612 rtFsIsoMakerObjDestroy(pObj); 1613 } 1614 1615 return rc; 1393 1616 } 1394 1617 … … 1407 1630 * @param fNamespaces The namespaces to apply the path to 1408 1631 * (RTFSISOMAKERNAMESPACE_XXX). 1409 * @param pszPath The ISO-9660path.1632 * @param pszPath The path. 1410 1633 */ 1411 1634 RTDECL(int) RTFsIsoMakerObjSetPath(RTFSISOMAKER hIsoMaker, uint32_t idxObj, uint32_t fNamespaces, const char *pszPath) … … 1429 1652 if (fNamespaces & g_aRTFsIsoNamespaces[i].fNamespace) 1430 1653 { 1431 int rc2 = rtFsIsoMakerObjSetPathInOne(pThis, pObj, g_aRTFsIsoNamespaces[i].fNamespace, pszPath, 1432 (PPRTFSISOMAKERNAME)((uintptr_t)pThis + g_aRTFsIsoNamespaces[i].offRoot), 1433 (PPRTFSISOMAKERNAME)((uintptr_t)pObj + g_aRTFsIsoNamespaces[i].offName)); 1434 if (RT_SUCCESS(rc2) || RT_FAILURE(rc)) 1435 continue; 1436 rc = rc2; 1654 PRTFSISOMAKERNAMESPACE pNamespace = (PRTFSISOMAKERNAMESPACE)((uintptr_t)pThis + g_aRTFsIsoNamespaces[i].offNamespace); 1655 if (pNamespace->uLevel > 0) 1656 { 1657 int rc2 = rtFsIsoMakerObjSetPathInOne(pThis, pNamespace, pObj, pszPath); 1658 if (RT_SUCCESS(rc2) || RT_FAILURE(rc)) 1659 continue; 1660 rc = rc2; 1661 } 1662 } 1663 return rc; 1664 } 1665 1666 1667 /** 1668 * Sets the name of an object in the selected namespaces, placing it under the 1669 * given directory. 1670 * 1671 * The name will be transformed as necessary. 1672 * 1673 * The initial implementation does not allow this function to be called more 1674 * than once on an object. 1675 * 1676 * @returns IPRT status code. 1677 * @param hIsoMaker The ISO maker handle. 1678 * @param idxObj The configuration index of to name. 1679 * @param idxParentObj The parent directory object. 1680 * @param fNamespaces The namespaces to apply the path to 1681 * (RTFSISOMAKERNAMESPACE_XXX). 1682 * @param pszName The name. 1683 */ 1684 RTDECL(int) RTFsIsoMakerObjSetNameAndParent(RTFSISOMAKER hIsoMaker, uint32_t idxObj, uint32_t idxParentObj, 1685 uint32_t fNamespaces, const char *pszName) 1686 { 1687 /* 1688 * Validate and translate input. 1689 */ 1690 PRTFSISOMAKERINT pThis = hIsoMaker; 1691 RTFSISOMAKER_ASSER_VALID_HANDLE_RET(pThis); 1692 AssertReturn(!(fNamespaces & ~RTFSISOMAKERNAMESPACE_VALID_MASK), VERR_INVALID_FLAGS); 1693 AssertPtrReturn(pszName, VERR_INVALID_POINTER); 1694 size_t cchName = strlen(pszName); 1695 AssertReturn(cchName > 0, VERR_INVALID_NAME); 1696 AssertReturn(memchr(pszName, '/', cchName) == NULL, VERR_INVALID_NAME); 1697 PRTFSISOMAKEROBJ pObj = rtFsIsoMakerIndexToObj(pThis, idxObj); 1698 AssertReturn(pObj, VERR_OUT_OF_RANGE); 1699 PRTFSISOMAKEROBJ pParentObj = rtFsIsoMakerIndexToObj(pThis, idxParentObj); 1700 AssertReturn(pParentObj, VERR_OUT_OF_RANGE); 1701 1702 /* 1703 * Execute requested actions. 1704 */ 1705 int rc = VINF_SUCCESS; 1706 for (uint32_t i = 0; i < RT_ELEMENTS(g_aRTFsIsoNamespaces); i++) 1707 if (fNamespaces & g_aRTFsIsoNamespaces[i].fNamespace) 1708 { 1709 PRTFSISOMAKERNAMESPACE pNamespace = (PRTFSISOMAKERNAMESPACE)((uintptr_t)pThis + g_aRTFsIsoNamespaces[i].offNamespace); 1710 if (pNamespace->uLevel > 0) 1711 { 1712 PRTFSISOMAKERNAME pParentName = *rtFsIsoMakerObjGetNameForNamespace(pParentObj, pNamespace); 1713 if (pParentName) 1714 { 1715 int rc2 = rtFsIsoMakerObjSetName(pThis, pNamespace, pObj, pParentName, pszName, cchName, NULL /*ppNewName*/); 1716 if (RT_SUCCESS(rc2) || RT_FAILURE(rc)) 1717 continue; 1718 rc = rc2; 1719 } 1720 } 1437 1721 } 1438 1722 return rc; … … 1448 1732 * @param pObj The common object. 1449 1733 * @param enmType The object type. 1450 */ 1451 static int rtFsIsoMakerInitCommonObj(PRTFSISOMAKERINT pThis, PRTFSISOMAKEROBJ pObj, RTFSISOMAKEROBJTYPE enmType) 1734 * @param pObjInfo The object information (typically source). 1735 * Optional. 1736 */ 1737 static int rtFsIsoMakerInitCommonObj(PRTFSISOMAKERINT pThis, PRTFSISOMAKEROBJ pObj, 1738 RTFSISOMAKEROBJTYPE enmType, PCRTFSOBJINFO pObjInfo) 1452 1739 { 1453 1740 AssertReturn(pThis->cObjects < RTFSISOMAKER_MAX_OBJECTS, VERR_OUT_OF_RANGE); … … 1458 1745 pObj->pHfsName = NULL; 1459 1746 pObj->idxObj = pThis->cObjects++; 1747 if (pObjInfo) 1748 { 1749 pObj->BirthTime = pObjInfo->BirthTime; 1750 pObj->ChangeTime = pObjInfo->ChangeTime; 1751 pObj->ModificationTime = pObjInfo->ModificationTime; 1752 pObj->AccessedTime = pObjInfo->AccessTime; 1753 pObj->fMode = pObjInfo->Attr.fMode; 1754 pObj->uid = pObjInfo->Attr.u.Unix.uid != NIL_RTUID ? pObjInfo->Attr.u.Unix.uid : pThis->uidDefault; 1755 pObj->gid = pObjInfo->Attr.u.Unix.gid != NIL_RTGID ? pObjInfo->Attr.u.Unix.gid : pThis->gidDefault; 1756 } 1757 else 1758 { 1759 pObj->BirthTime = pThis->ImageCreationTime; 1760 pObj->ChangeTime = pThis->ImageCreationTime; 1761 pObj->ModificationTime = pThis->ImageCreationTime; 1762 pObj->AccessedTime = pThis->ImageCreationTime; 1763 pObj->fMode = enmType == RTFSISOMAKEROBJTYPE_DIR ? pThis->fDefaultDirMode : pThis->fDefaultFileMode; 1764 pObj->uid = pThis->uidDefault; 1765 pObj->gid = pThis->gidDefault; 1766 } 1767 1460 1768 RTListAppend(&pThis->ObjectHead, &pObj->Entry); 1461 1769 return VINF_SUCCESS; … … 1474 1782 PRTFSISOMAKERDIR pDir = (PRTFSISOMAKERDIR)RTMemAllocZ(sizeof(*pDir)); 1475 1783 AssertReturn(pDir, VERR_NO_MEMORY); 1476 int rc = rtFsIsoMakerInitCommonObj(pThis, &pDir->Core, RTFSISOMAKEROBJTYPE_DIR );1784 int rc = rtFsIsoMakerInitCommonObj(pThis, &pDir->Core, RTFSISOMAKEROBJTYPE_DIR, NULL); 1477 1785 if (RT_SUCCESS(rc)) 1478 1786 { … … 1538 1846 *pidxObj = idxObj; 1539 1847 } 1540 /** @todo else: back out later? */ 1848 else 1849 RTFsIsoMakerObjRemove(hIsoMaker, idxObj); 1541 1850 } 1542 1851 return rc; 1543 1852 } 1544 1853 1854 1855 /** 1856 * Internal function for adding an unnamed file. 1857 * 1858 * @returns IPRT status code. 1859 * @param pThis The ISO make instance. 1860 * @param cbExtra Extra space for additional data (e.g. source 1861 * path string copy). 1862 * @param ppFile Where to return the file. 1863 */ 1864 static int rtFsIsoMakerAddUnnamedFileWorker(PRTFSISOMAKERINT pThis, PCRTFSOBJINFO pObjInfo, size_t cbExtra, 1865 PRTFSISOMAKERFILE *ppFile) 1866 { 1867 PRTFSISOMAKERFILE pFile = (PRTFSISOMAKERFILE)RTMemAllocZ(sizeof(*pFile) + cbExtra); 1868 AssertReturn(pFile, VERR_NO_MEMORY); 1869 int rc = rtFsIsoMakerInitCommonObj(pThis, &pFile->Core, RTFSISOMAKEROBJTYPE_FILE, pObjInfo); 1870 if (RT_SUCCESS(rc)) 1871 { 1872 pFile->cbData = pObjInfo->cbObject; 1873 pThis->cbData += RT_ALIGN_64(pFile->cbData, RTFSISOMAKER_SECTOR_SIZE); 1874 pFile->offData = UINT64_MAX; 1875 pFile->enmSrcType = RTFSISOMAKERSRCTYPE_INVALID; 1876 pFile->u.pszSrcPath = NULL; 1877 1878 *ppFile = pFile; 1879 return VINF_SUCCESS; 1880 } 1881 RTMemFree(pFile); 1882 return rc; 1883 1884 } 1885 1886 1887 /** 1888 * Adds an unnamed file to the image that's backed by a host file. 1889 * 1890 * The file must explictly be entered into the desired namespaces. 1891 * 1892 * @returns IPRT status code 1893 * @param hIsoMaker The ISO maker handle. 1894 * @param pszSrcFile The source file path. VFS chain spec allowed. 1895 * @param pidxObj Where to return the configuration index of the 1896 * directory. 1897 * @sa RTFsIsoMakerAddFile, RTFsIsoMakerObjSetPath 1898 */ 1899 RTDECL(int) RTFsIsoMakerAddUnnamedFileWithSrcPath(RTFSISOMAKER hIsoMaker, const char *pszSrcFile, uint32_t *pidxObj) 1900 { 1901 PRTFSISOMAKERINT pThis = hIsoMaker; 1902 RTFSISOMAKER_ASSER_VALID_HANDLE_RET(pThis); 1903 AssertPtrReturn(pidxObj, VERR_INVALID_POINTER); 1904 *pidxObj = UINT32_MAX; 1905 1906 /* 1907 * Check that the source file exists and is a file. 1908 */ 1909 uint32_t offError = 0; 1910 RTFSOBJINFO ObjInfo; 1911 int rc = RTVfsChainQueryInfo(pszSrcFile, &ObjInfo, RTFSOBJATTRADD_UNIX, RTPATH_F_FOLLOW_LINK, &offError, NULL); 1912 AssertMsgRCReturn(rc, ("%s -> %Rrc offError=%u\n", pszSrcFile, rc, offError), rc); 1913 AssertMsgReturn(RTFS_IS_FILE(ObjInfo.Attr.fMode), ("%#x - %s\n", ObjInfo.Attr.fMode, pszSrcFile), VERR_NOT_A_FILE); 1914 1915 /* 1916 * Create a file object for it. 1917 */ 1918 size_t const cbSrcFile = strlen(pszSrcFile) + 1; 1919 PRTFSISOMAKERFILE pFile; 1920 rc = rtFsIsoMakerAddUnnamedFileWorker(pThis, &ObjInfo, cbSrcFile, &pFile); 1921 if (RT_SUCCESS(rc)) 1922 { 1923 pFile->enmSrcType = RTFSISOMAKERSRCTYPE_PATH; 1924 pFile->u.pszSrcPath = (char *)memcpy(pFile + 1, pszSrcFile, cbSrcFile); 1925 1926 *pidxObj = pFile->Core.idxObj; 1927 } 1928 return rc; 1929 } 1930 1931 1932 /** 1933 * Adds an unnamed file to the image that's backed by a VFS file. 1934 * 1935 * The file must explictly be entered into the desired namespaces. 1936 * 1937 * @returns IPRT status code 1938 * @param hIsoMaker The ISO maker handle. 1939 * @param hVfsFileSrc The source file handle. 1940 * @param pidxObj Where to return the configuration index of the 1941 * directory. 1942 * @sa RTFsIsoMakerAddUnnamedFileWithSrcPath, RTFsIsoMakerObjSetPath 1943 */ 1944 RTDECL(int) RTFsIsoMakerAddUnnamedFileWithVfsFile(RTFSISOMAKER hIsoMaker, RTVFSFILE hVfsFileSrc, uint32_t *pidxObj) 1945 { 1946 PRTFSISOMAKERINT pThis = hIsoMaker; 1947 RTFSISOMAKER_ASSER_VALID_HANDLE_RET(pThis); 1948 AssertPtrReturn(pidxObj, VERR_INVALID_POINTER); 1949 *pidxObj = UINT32_MAX; 1950 1951 /* 1952 * Get the VFS file info. This implicitly validates the handle. 1953 */ 1954 RTFSOBJINFO ObjInfo; 1955 int rc = RTVfsFileQueryInfo(hVfsFileSrc, &ObjInfo, RTFSOBJATTRADD_UNIX); 1956 AssertMsgRCReturn(rc, ("RTVfsFileQueryInfo(%p) -> %Rrc\n", hVfsFileSrc, rc), rc); 1957 1958 /* 1959 * Retain a reference to the file. 1960 */ 1961 uint32_t cRefs = RTVfsFileRetain(hVfsFileSrc); 1962 AssertReturn(cRefs != UINT32_MAX, VERR_INVALID_HANDLE); 1963 1964 /* 1965 * Create a file object for it. 1966 */ 1967 PRTFSISOMAKERFILE pFile; 1968 rc = rtFsIsoMakerAddUnnamedFileWorker(pThis, &ObjInfo, 0, &pFile); 1969 if (RT_SUCCESS(rc)) 1970 { 1971 pFile->enmSrcType = RTFSISOMAKERSRCTYPE_VFS_FILE; 1972 pFile->u.hVfsFile = hVfsFileSrc; 1973 1974 *pidxObj = pFile->Core.idxObj; 1975 } 1976 else 1977 RTVfsFileRelease(hVfsFileSrc); 1978 return rc; 1979 } 1980 1981 1982 /** 1983 * Adds a file that's backed by a host file to the image in all namespaces and 1984 * with attributes taken from the source file. 1985 * 1986 * @returns IPRT status code 1987 * @param hIsoMaker The ISO maker handle. 1988 * @param pszFile The path to the file in the image. 1989 * @param pszSrcFile The source file path. VFS chain spec allowed. 1990 * @param pidxObj Where to return the configuration index of the file. 1991 * Optional 1992 * @sa RTFsIsoMakerAddFileWithVfsFile, 1993 * RTFsIsoMakerAddUnnamedFileWithSrcPath 1994 */ 1995 RTDECL(int) RTFsIsoMakerAddFileWithSrcPath(RTFSISOMAKER hIsoMaker, const char *pszFile, const char *pszSrcFile, uint32_t *pidxObj) 1996 { 1997 PRTFSISOMAKERINT pThis = hIsoMaker; 1998 RTFSISOMAKER_ASSER_VALID_HANDLE_RET(pThis); 1999 AssertPtrReturn(pszFile, VERR_INVALID_POINTER); 2000 AssertReturn(RTPATH_IS_SLASH(*pszFile), VERR_INVALID_NAME); 2001 2002 uint32_t idxObj; 2003 int rc = RTFsIsoMakerAddUnnamedFileWithSrcPath(hIsoMaker, pszSrcFile, &idxObj); 2004 if (RT_SUCCESS(rc)) 2005 { 2006 rc = RTFsIsoMakerObjSetPath(hIsoMaker, idxObj, RTFSISOMAKERNAMESPACE_ALL, pszFile); 2007 if (RT_SUCCESS(rc)) 2008 { 2009 if (pidxObj) 2010 *pidxObj = idxObj; 2011 } 2012 else 2013 RTFsIsoMakerObjRemove(hIsoMaker, idxObj); 2014 } 2015 return rc; 2016 } 2017 2018 2019 /** 2020 * Adds a file that's backed by a VFS file to the image in all namespaces and 2021 * with attributes taken from the source file. 2022 * 2023 * @returns IPRT status code 2024 * @param hIsoMaker The ISO maker handle. 2025 * @param pszFile The path to the file in the image. 2026 * @param hVfsFileSrc The source file handle. 2027 * @param pidxObj Where to return the configuration index of the file. 2028 * Optional. 2029 * @sa RTFsIsoMakerAddUnnamedFileWithVfsFile, 2030 * RTFsIsoMakerAddFileWithSrcPath 2031 */ 2032 RTDECL(int) RTFsIsoMakerAddFileWithVfsFile(RTFSISOMAKER hIsoMaker, const char *pszFile, RTVFSFILE hVfsFileSrc, uint32_t *pidxObj) 2033 { 2034 PRTFSISOMAKERINT pThis = hIsoMaker; 2035 RTFSISOMAKER_ASSER_VALID_HANDLE_RET(pThis); 2036 AssertPtrReturn(pszFile, VERR_INVALID_POINTER); 2037 AssertReturn(RTPATH_IS_SLASH(*pszFile), VERR_INVALID_NAME); 2038 2039 uint32_t idxObj; 2040 int rc = RTFsIsoMakerAddUnnamedFileWithVfsFile(hIsoMaker, hVfsFileSrc, &idxObj); 2041 if (RT_SUCCESS(rc)) 2042 { 2043 rc = RTFsIsoMakerObjSetPath(hIsoMaker, idxObj, RTFSISOMAKERNAMESPACE_ALL, pszFile); 2044 if (RT_SUCCESS(rc)) 2045 { 2046 if (pidxObj) 2047 *pidxObj = idxObj; 2048 } 2049 else 2050 RTFsIsoMakerObjRemove(hIsoMaker, idxObj); 2051 } 2052 return rc; 2053 } 2054
Note:
See TracChangeset
for help on using the changeset viewer.