- Timestamp:
- Jun 8, 2017 9:25:39 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fs/isomaker.cpp
r67303 r67305 52 52 * Defined Constants And Macros * 53 53 *********************************************************************************************************************************/ 54 /** Asserts valid handle, returns @a a_rcRet if not. */ 55 #define RTFSISOMAKER_ASSER_VALID_HANDLE_RET_EX(a_pThis, a_rcRet) \ 56 do { AssertPtrReturn(a_pThis, a_rcRet); \ 57 AssertPtrReturn((a_pThis)->uMagic == RTFSISOMAKERINT_MAGIC, a_rcRet); \ 58 } while (0) 59 54 60 /** Asserts valid handle, returns VERR_INVALID_HANDLE if not. */ 55 #define RTFSISOMAKER_ASSER_VALID_HANDLE_RET(a_pThis) \ 56 do { AssertPtrReturn(a_pThis, VERR_INVALID_HANDLE); \ 57 AssertPtrReturn((a_pThis)->uMagic == RTFSISOMAKERINT_MAGIC, VERR_INVALID_HANDLE); \ 58 } while (0) 61 #define RTFSISOMAKER_ASSER_VALID_HANDLE_RET(a_pThis) RTFSISOMAKER_ASSER_VALID_HANDLE_RET_EX(a_pThis, VERR_INVALID_HANDLE) 59 62 60 63 /** The sector size. */ … … 92 95 * @{ 93 96 */ 94 #define RTFSISOMAKER NAMESPACE_ISO_9660RT_BIT_32(0) /**< The primary ISO-9660 namespace. */95 #define RTFSISOMAKER NAMESPACE_JOLIETRT_BIT_32(1) /**< The joliet namespace. */96 #define RTFSISOMAKER NAMESPACE_UDFRT_BIT_32(2) /**< The UDF namespace. */97 #define RTFSISOMAKER NAMESPACE_HFSRT_BIT_32(3) /**< The HFS namespace */98 #define RTFSISOMAKER NAMESPACE_ALLUINT32_C(0x0000000f) /**< All namespaces. */99 #define RTFSISOMAKER NAMESPACE_VALID_MASKUINT32_C(0x0000000f) /**< Valid namespace bits. */97 #define RTFSISOMAKER_NAMESPACE_ISO_9660 RT_BIT_32(0) /**< The primary ISO-9660 namespace. */ 98 #define RTFSISOMAKER_NAMESPACE_JOLIET RT_BIT_32(1) /**< The joliet namespace. */ 99 #define RTFSISOMAKER_NAMESPACE_UDF RT_BIT_32(2) /**< The UDF namespace. */ 100 #define RTFSISOMAKER_NAMESPACE_HFS RT_BIT_32(3) /**< The HFS namespace */ 101 #define RTFSISOMAKER_NAMESPACE_ALL UINT32_C(0x0000000f) /**< All namespaces. */ 102 #define RTFSISOMAKER_NAMESPACE_VALID_MASK UINT32_C(0x0000000f) /**< Valid namespace bits. */ 100 103 /** @} */ 101 104 … … 220 223 * Linux behaves a little different when seeing the ER tag. */ 221 224 uint8_t uRockRidgeLevel; 222 /** Set if TRANS.TBL files are to be generated for this namespace. */ 223 bool fTransTbl; 225 /** The TRANS.TBL filename if enabled, NULL if disabled. 226 * When not NULL, this may be pointing to heap or g_szTransTbl. */ 227 char *pszTransTbl; 224 228 } RTFSISOMAKERNAMESPACE; 225 229 /** Pointer to a namespace. */ … … 269 273 RTFMODE fMode; 270 274 275 /** Used to make sure things like the boot catalog stays in the image even if 276 * it's not mapped into any of the namespaces. */ 277 bool fNotOrphan; 271 278 } RTFSISOMAKEROBJ; 272 279 … … 280 287 RTFSISOMAKERSRCTYPE_PATH, 281 288 RTFSISOMAKERSRCTYPE_VFS_FILE, 289 RTFSISOMAKERSRCTYPE_TRANS_TBL, 282 290 RTFSISOMAKERSRCTYPE_END 283 291 } RTFSISOMAKERSRCTYPE; … … 305 313 /** Source VFS file. */ 306 314 RTVFSFILE hVfsFile; 315 /** The directory the translation table belongs to. */ 316 PRTFSISOMAKERNAME pTransTblDir; 307 317 } u; 308 318 } RTFSISOMAKERFILE; … … 340 350 * after having started to add files. */ 341 351 bool fSeenContent; 352 /** Set once we've finalized the image structures. 353 * After this no more changes are allowed. */ 354 bool fFinalized; 342 355 343 356 /** The primary ISO-9660 namespace. */ … … 358 371 /** Amount of file data. */ 359 372 uint64_t cbData; 360 /** The total image size. 361 * @todo not sure if this is desirable. */ 362 uint64_t cbTotal; 373 /** Number of volume descriptors. */ 374 uint8_t cVolumeDescriptors; 363 375 364 376 /** The 'now' timestamp we use for the whole image. … … 375 387 RTFMODE fDefaultDirMode; 376 388 389 /** The finalized image size. */ 390 uint64_t cbFinalizedImage; 391 //PISO9660PRIMARYVOLDESC 377 392 } RTFSISOMAKERINT; 378 393 /** Pointer to an ISO maker instance. */ … … 388 403 static const struct 389 404 { 390 /** The RTFSISOMAKER NAMESPACE_XXX indicator. */405 /** The RTFSISOMAKER_NAMESPACE_XXX indicator. */ 391 406 uint32_t fNamespace; 392 407 /** Offset into RTFSISOMAKERINT of the namespace member. */ … … 398 413 } g_aRTFsIsoNamespaces[] = 399 414 { 400 { RTFSISOMAKER NAMESPACE_ISO_9660, RT_OFFSETOF(RTFSISOMAKERINT, PrimaryIso), RT_OFFSETOF(RTFSISOMAKEROBJ, pPrimaryName), "iso-9660" },401 { RTFSISOMAKER NAMESPACE_JOLIET, RT_OFFSETOF(RTFSISOMAKERINT, Joliet), RT_OFFSETOF(RTFSISOMAKEROBJ, pJolietName), "joliet" },402 { RTFSISOMAKER NAMESPACE_UDF, RT_OFFSETOF(RTFSISOMAKERINT, Udf), RT_OFFSETOF(RTFSISOMAKEROBJ, pUdfName), "udf" },403 { RTFSISOMAKER NAMESPACE_HFS, RT_OFFSETOF(RTFSISOMAKERINT, Hfs), RT_OFFSETOF(RTFSISOMAKEROBJ, pHfsName), "hfs" },415 { RTFSISOMAKER_NAMESPACE_ISO_9660, RT_OFFSETOF(RTFSISOMAKERINT, PrimaryIso), RT_OFFSETOF(RTFSISOMAKEROBJ, pPrimaryName), "iso-9660" }, 416 { RTFSISOMAKER_NAMESPACE_JOLIET, RT_OFFSETOF(RTFSISOMAKERINT, Joliet), RT_OFFSETOF(RTFSISOMAKEROBJ, pJolietName), "joliet" }, 417 { RTFSISOMAKER_NAMESPACE_UDF, RT_OFFSETOF(RTFSISOMAKERINT, Udf), RT_OFFSETOF(RTFSISOMAKEROBJ, pUdfName), "udf" }, 418 { RTFSISOMAKER_NAMESPACE_HFS, RT_OFFSETOF(RTFSISOMAKERINT, Hfs), RT_OFFSETOF(RTFSISOMAKEROBJ, pHfsName), "hfs" }, 404 419 }; 405 420 406 421 /** 407 * Translates a single namespace flag (RTFSISOMAKER NAMESPACE_XXX) to an422 * Translates a single namespace flag (RTFSISOMAKER_NAMESPACE_XXX) to an 408 423 * index into g_aRTFsIsoNamespaces. 409 424 */ … … 411 426 { 412 427 /*[0] = */ RT_ELEMENTS(g_aRTFsIsoNamespaces), 413 /*[RTFSISOMAKER NAMESPACE_ISO_9660] = */ 0,428 /*[RTFSISOMAKER_NAMESPACE_ISO_9660] = */ 0, 414 429 /*[2] = */ RT_ELEMENTS(g_aRTFsIsoNamespaces), 415 430 /*[3] = */ RT_ELEMENTS(g_aRTFsIsoNamespaces), 416 /*[RTFSISOMAKER NAMESPACE_JOLIET] = */ 1,431 /*[RTFSISOMAKER_NAMESPACE_JOLIET] = */ 1, 417 432 /*[5] = */ RT_ELEMENTS(g_aRTFsIsoNamespaces), 418 433 /*[6] = */ RT_ELEMENTS(g_aRTFsIsoNamespaces), 419 434 /*[7] = */ RT_ELEMENTS(g_aRTFsIsoNamespaces), 420 /*[RTFSISOMAKER NAMESPACE_UDF] = */ 2,435 /*[RTFSISOMAKER_NAMESPACE_UDF] = */ 2, 421 436 /*[9] = */ RT_ELEMENTS(g_aRTFsIsoNamespaces), 422 437 /*[10] = */ RT_ELEMENTS(g_aRTFsIsoNamespaces), … … 426 441 /*[14] = */ RT_ELEMENTS(g_aRTFsIsoNamespaces), 427 442 /*[15] = */ RT_ELEMENTS(g_aRTFsIsoNamespaces), 428 /*[RTFSISOMAKER NAMESPACE_HFS] = */ 3,443 /*[RTFSISOMAKER_NAMESPACE_HFS] = */ 3, 429 444 /*[17] = */ RT_ELEMENTS(g_aRTFsIsoNamespaces), 430 445 /*[18] = */ RT_ELEMENTS(g_aRTFsIsoNamespaces), … … 444 459 }; 445 460 461 /** The default translation table filename. */ 462 static char g_szTransTbl[] = "TRANS.TBL"; 463 446 464 447 465 /********************************************************************************************************************************* 448 466 * Internal Functions * 449 467 *********************************************************************************************************************************/ 468 static int rtFsIsoMakerObjSetName(PRTFSISOMAKERINT pThis, PRTFSISOMAKERNAMESPACE pNamespace, PRTFSISOMAKEROBJ pObj, 469 PRTFSISOMAKERNAME pParent, const char *pchSpec, size_t cchSpec, PPRTFSISOMAKERNAME ppNewName); 470 static int rtFsIsoMakerObjUnsetName(PRTFSISOMAKERINT pThis, PRTFSISOMAKERNAMESPACE pNamespace, PRTFSISOMAKEROBJ pObj); 450 471 static int rtFsIsoMakerAddUnnamedDirWorker(PRTFSISOMAKERINT pThis, PRTFSISOMAKERDIR *ppDir); 451 452 RTDECL(int) RTFsIsoMakerObjSetPath(RTFSISOMAKER hIsoMaker, uint32_t idxObj, uint32_t fNamespaces, const char *pszPath); 472 static int rtFsIsoMakerAddUnnamedFileWorker(PRTFSISOMAKERINT pThis, PCRTFSOBJINFO pObjInfo, size_t cbExtra, 473 PRTFSISOMAKERFILE *ppFile); 474 static int rtFsIsoMakerObjRemoveWorker(PRTFSISOMAKERINT pThis, PRTFSISOMAKEROBJ pObj); 475 453 476 454 477 … … 464 487 * Do some integrity checks first. 465 488 */ 466 AssertReturn(g_aRTFsIsoNamespaces[g_aidxRTFsIsoNamespaceFlagToIdx[RTFSISOMAKER NAMESPACE_ISO_9660]].fNamespace == RTFSISOMAKERNAMESPACE_ISO_9660,489 AssertReturn(g_aRTFsIsoNamespaces[g_aidxRTFsIsoNamespaceFlagToIdx[RTFSISOMAKER_NAMESPACE_ISO_9660]].fNamespace == RTFSISOMAKER_NAMESPACE_ISO_9660, 467 490 VERR_INTERNAL_ERROR_5); 468 AssertReturn(g_aRTFsIsoNamespaces[g_aidxRTFsIsoNamespaceFlagToIdx[RTFSISOMAKER NAMESPACE_JOLIET]].fNamespace == RTFSISOMAKERNAMESPACE_JOLIET,491 AssertReturn(g_aRTFsIsoNamespaces[g_aidxRTFsIsoNamespaceFlagToIdx[RTFSISOMAKER_NAMESPACE_JOLIET]].fNamespace == RTFSISOMAKER_NAMESPACE_JOLIET, 469 492 VERR_INTERNAL_ERROR_5); 470 AssertReturn(g_aRTFsIsoNamespaces[g_aidxRTFsIsoNamespaceFlagToIdx[RTFSISOMAKER NAMESPACE_UDF]].fNamespace == RTFSISOMAKERNAMESPACE_UDF,493 AssertReturn(g_aRTFsIsoNamespaces[g_aidxRTFsIsoNamespaceFlagToIdx[RTFSISOMAKER_NAMESPACE_UDF]].fNamespace == RTFSISOMAKER_NAMESPACE_UDF, 471 494 VERR_INTERNAL_ERROR_5); 472 AssertReturn(g_aRTFsIsoNamespaces[g_aidxRTFsIsoNamespaceFlagToIdx[RTFSISOMAKER NAMESPACE_HFS]].fNamespace == RTFSISOMAKERNAMESPACE_HFS,495 AssertReturn(g_aRTFsIsoNamespaces[g_aidxRTFsIsoNamespaceFlagToIdx[RTFSISOMAKER_NAMESPACE_HFS]].fNamespace == RTFSISOMAKER_NAMESPACE_HFS, 473 496 VERR_INTERNAL_ERROR_5); 474 497 … … 483 506 //pThis->fSeenContent = false; 484 507 485 pThis->PrimaryIso.fNamespace = RTFSISOMAKER NAMESPACE_ISO_9660;508 pThis->PrimaryIso.fNamespace = RTFSISOMAKER_NAMESPACE_ISO_9660; 486 509 pThis->PrimaryIso.offName = RT_OFFSETOF(RTFSISOMAKEROBJ, pPrimaryName); 487 510 pThis->PrimaryIso.uLevel = 3; /* 30 char names, large files */ 488 511 pThis->PrimaryIso.uRockRidgeLevel = 1; 489 pThis->PrimaryIso. fTransTbl = true;490 pThis->Joliet.fNamespace = RTFSISOMAKER NAMESPACE_JOLIET;512 pThis->PrimaryIso.pszTransTbl = g_szTransTbl; 513 pThis->Joliet.fNamespace = RTFSISOMAKER_NAMESPACE_JOLIET; 491 514 pThis->Joliet.offName = RT_OFFSETOF(RTFSISOMAKEROBJ, pJolietName); 492 515 pThis->Joliet.uLevel = 3; 493 516 //pThis->Joliet.uRockRidgeLevel = 0; 494 //pThis->Joliet. fTransTbl = false;495 pThis->Udf.fNamespace = RTFSISOMAKER NAMESPACE_UDF;517 //pThis->Joliet.pszTransTbl = NULL; 518 pThis->Udf.fNamespace = RTFSISOMAKER_NAMESPACE_UDF; 496 519 pThis->Udf.offName = RT_OFFSETOF(RTFSISOMAKEROBJ, pUdfName); 497 520 //pThis->Udf.uLevel = 0; 498 521 //pThis->Udf.uRockRidgeLevel = 0; 499 //pThis->Udf. fTransTbl = false;500 pThis->Hfs.fNamespace = RTFSISOMAKER NAMESPACE_HFS;522 //pThis->Udf.pszTransTbl = NULL; 523 pThis->Hfs.fNamespace = RTFSISOMAKER_NAMESPACE_HFS; 501 524 pThis->Hfs.offName = RT_OFFSETOF(RTFSISOMAKEROBJ, pHfsName); 502 525 //pThis->Hfs.uLevel = 0; 503 526 //pThis->Hfs.uRockRidgeLevel = 0; 504 //pThis->Hfs. fTransTbl = false;527 //pThis->Hfs.pszTransTbl = NULL; 505 528 506 529 RTListInit(&pThis->ObjectHead); … … 508 531 //pThis->cbData = 0; 509 532 510 pThis->cbTotal = _32K /* The system area size. */ 511 + RTFSISOMAKER_SECTOR_SIZE /* Primary volume descriptor. */ 512 + RTFSISOMAKER_SECTOR_SIZE /* Secondary volume descriptor for joliet. */ 513 + RTFSISOMAKER_SECTOR_SIZE /* Terminator descriptor. */; 533 pThis->cVolumeDescriptors = 3; /* primary, secondary joliet, terminator. */ 514 534 515 535 //pThis->uidDefault = 0; … … 542 562 { 543 563 case RTFSISOMAKERSRCTYPE_PATH: 544 /* do nothing. */ 564 pFile->u.pszSrcPath = NULL; 565 break; 566 567 case RTFSISOMAKERSRCTYPE_TRANS_TBL: 568 pFile->u.pTransTblDir = NULL; 545 569 break; 546 570 … … 587 611 588 612 /** 589 * Recursively destroy a name space tree. 590 * @param pRoot The root node. 591 */ 592 static void rtFsIsoMakerDestroyTree(PRTFSISOMAKERNAME pRoot) 593 { 594 Assert(!pRoot->pParent); 595 PRTFSISOMAKERNAME pCur = pRoot; 596 597 for (;;) 598 { 599 if ( pCur->pDir 600 && pCur->pDir->cChildren) 601 pCur = pCur->pDir->papChildren[pCur->pDir->cChildren - 1]; 602 else 603 { 604 PRTFSISOMAKERNAME pNext = pCur->pParent; 605 rtFsIsoMakerDestroyName(pCur); 606 607 /* Unlink from parent, we're the last entry. */ 608 if (pNext) 609 { 610 Assert(pNext->pDir->cChildren > 0); 611 pNext->pDir->cChildren--; 612 Assert(pNext->pDir->papChildren[pNext->pDir->cChildren] == pCur); 613 pNext->pDir->papChildren[pNext->pDir->cChildren] = NULL; 614 pCur = pNext; 615 } 613 * Destroys a namespace. 614 * 615 * @param pNamespace The namespace to destroy. 616 */ 617 static void rtFsIsoMakerDestroyTree(PRTFSISOMAKERNAMESPACE pNamespace) 618 { 619 /* 620 * Recursively destroy the tree first. 621 */ 622 PRTFSISOMAKERNAME pCur = pNamespace->pRoot; 623 if (pCur) 624 { 625 Assert(!pCur->pParent); 626 for (;;) 627 { 628 if ( pCur->pDir 629 && pCur->pDir->cChildren) 630 pCur = pCur->pDir->papChildren[pCur->pDir->cChildren - 1]; 616 631 else 617 632 { 618 Assert(pRoot == pCur); 619 break; 633 PRTFSISOMAKERNAME pNext = pCur->pParent; 634 rtFsIsoMakerDestroyName(pCur); 635 636 /* Unlink from parent, we're the last entry. */ 637 if (pNext) 638 { 639 Assert(pNext->pDir->cChildren > 0); 640 pNext->pDir->cChildren--; 641 Assert(pNext->pDir->papChildren[pNext->pDir->cChildren] == pCur); 642 pNext->pDir->papChildren[pNext->pDir->cChildren] = NULL; 643 pCur = pNext; 644 } 645 else 646 { 647 Assert(pNamespace->pRoot == pCur); 648 break; 649 } 620 650 } 621 651 } 652 pNamespace->pRoot = NULL; 653 } 654 655 /* 656 * Free the translation table filename if allocated. 657 */ 658 if (pNamespace->pszTransTbl) 659 { 660 if (pNamespace->pszTransTbl != g_szTransTbl) 661 RTMemFree(pNamespace->pszTransTbl); 662 pNamespace->pszTransTbl = NULL; 622 663 } 623 664 } … … 631 672 static void rtFsIsoMakerDestroy(PRTFSISOMAKERINT pThis) 632 673 { 633 rtFsIsoMakerDestroyTree( pThis->PrimaryIso.pRoot);634 rtFsIsoMakerDestroyTree( pThis->Joliet.pRoot);635 rtFsIsoMakerDestroyTree( pThis->Udf.pRoot);636 rtFsIsoMakerDestroyTree( pThis->Hfs.pRoot);674 rtFsIsoMakerDestroyTree(&pThis->PrimaryIso); 675 rtFsIsoMakerDestroyTree(&pThis->Joliet); 676 rtFsIsoMakerDestroyTree(&pThis->Udf); 677 rtFsIsoMakerDestroyTree(&pThis->Hfs); 637 678 638 679 PRTFSISOMAKEROBJ pCur; … … 727 768 { 728 769 if (uJolietLevel == 0) 729 pThis->c bTotal -= RTFSISOMAKER_SECTOR_SIZE;770 pThis->cVolumeDescriptors--; 730 771 else if (pThis->Joliet.uLevel == 0) 731 pThis->c bTotal += RTFSISOMAKER_SECTOR_SIZE;772 pThis->cVolumeDescriptors++; 732 773 pThis->Joliet.uLevel = uJolietLevel; 733 774 } … … 785 826 */ 786 827 787 #if 0788 /**789 * Gets the pointer to the root member for the given namespace.790 *791 * @returns Pointer to root pointer.792 * @param pThis The ISO maker instance.793 * @param fNamespace The namespace which name to find.794 */795 static PPRTFSISOMAKERNAME rtFsIsoMakerGetRootForNamespace(PRTFSISOMAKERINT pThis, uint32_t fNamespace)796 {797 Assert(RT_IS_POWER_OF_TWO(fNamespace));798 Assert(fNamespace);799 Assert(fNamespace <= RTFSISOMAKERNAMESPACE_HFS);800 return (PPRTFSISOMAKERNAME)((uintptr_t)pThis + g_aRTFsIsoNamespaces[g_aidxRTFsIsoNamespaceFlagToIdx[fNamespace]].offRoot);801 }802 #endif803 804 828 805 829 /** … … 842 866 return NULL; 843 867 } 868 869 870 /** 871 * Compares the two names according to ISO-9660 directory sorting rules. 872 * 873 * As long as we don't want to do case insensitive joliet sorting, this works 874 * for joliet names to, I think. 875 * 876 * @returns 0 if equal, -1 if pszName1 comes first, 1 if pszName2 comes first. 877 * @param pszName1 The first name. 878 * @param pszName2 The second name. 879 */ 880 DECLINLINE(int) rtFsIsoMakerCompareIso9660Names(const char *pszName1, const char *pszName2) 881 { 882 for (;;) 883 { 884 char const ch1 = *pszName1++; 885 char const ch2 = *pszName2++; 886 if (ch1 == ch2) 887 { 888 if (ch1) 889 { /* likely */ } 890 else 891 return 0; 892 } 893 else if (ch1 == ';' || ch2 == ';') 894 return ch1 == ';' ? -1 : 1; 895 else if (ch1 == '.' || ch2 == '.') 896 return ch1 == '.' ? -1 : 1; 897 else 898 return (unsigned char)ch1 < (unsigned char)ch2 ? -1 : 1; 899 } 900 } 901 902 903 /** 904 * Finds the index into papChildren where the given name should be inserted. 905 * 906 * @returns Index of the given name. 907 * @param pNamespace The namspace. 908 * @param pParent The parent namespace node. 909 * @param pszName The name. 910 */ 911 static uint32_t rtFsIsoMakerFindInsertIndex(PRTFSISOMAKERNAMESPACE pNamespace, PRTFSISOMAKERNAME pParent, const char *pszName) 912 { 913 uint32_t idxRet = pParent->pDir->cChildren; 914 if (idxRet > 0) 915 { 916 /* 917 * The idea is to do binary search using a namespace specific compare 918 * function. However, it looks like we can get away with using the 919 * same compare function for all namespaces. 920 */ 921 uint32_t idxStart = 0; 922 uint32_t idxEnd = idxRet; 923 PPRTFSISOMAKERNAME papChildren = pParent->pDir->papChildren; 924 switch (pNamespace->fNamespace) 925 { 926 case RTFSISOMAKER_NAMESPACE_ISO_9660: 927 case RTFSISOMAKER_NAMESPACE_JOLIET: 928 case RTFSISOMAKER_NAMESPACE_UDF: 929 case RTFSISOMAKER_NAMESPACE_HFS: 930 for (;;) 931 { 932 idxRet = idxStart + (idxEnd - idxStart) / 2; 933 PRTFSISOMAKERNAME pCur = papChildren[idxRet]; 934 int iDiff = rtFsIsoMakerCompareIso9660Names(pszName, pCur->szName); 935 if (iDiff < 0) 936 { 937 if (idxRet > idxStart) 938 idxEnd = idxRet; 939 else 940 break; 941 } 942 else 943 { 944 idxRet++; 945 if ( iDiff != 0 946 && idxRet < idxEnd) 947 idxStart = idxRet; 948 else 949 break; 950 } 951 } 952 break; 953 954 default: 955 AssertFailed(); 956 break; 957 } 958 } 959 return idxRet; 960 } 961 844 962 845 963 … … 911 1029 } 912 1030 return NULL; 1031 } 1032 1033 1034 /** 1035 * Walks the given path by specified object names in a namespace. 1036 * 1037 * @returns IPRT status code. 1038 * @param pNamespace The namespace to walk the path in. 1039 * @param pszPath The path to walk. 1040 * @param ppName Where to return the name node that the path ends with. 1041 */ 1042 static int rtFsIsoMakerWalkPathBySpec(PRTFSISOMAKERNAMESPACE pNamespace, const char *pszPath, PPRTFSISOMAKERNAME ppName) 1043 { 1044 *ppName = NULL; 1045 AssertReturn(RTPATH_IS_SLASH(*pszPath), VERR_INVALID_NAME); 1046 1047 /* 1048 * Deal with the special case of the root. 1049 */ 1050 while (RTPATH_IS_SLASH(*pszPath)) 1051 pszPath++; 1052 AssertReturn(*pszPath, VERR_INTERNAL_ERROR_4); 1053 1054 PRTFSISOMAKERNAME pCur = pNamespace->pRoot; 1055 if (!pCur) 1056 return *pszPath ? VERR_PATH_NOT_FOUND : VERR_FILE_NOT_FOUND; 1057 if (!*pszPath) 1058 { 1059 *ppName = pCur; 1060 return VINF_SUCCESS; 1061 } 1062 1063 /* 1064 * Now, do the rest of the path. 1065 */ 1066 for (;;) 1067 { 1068 /* 1069 * Find the end of the component. 1070 */ 1071 char ch; 1072 size_t cchComponent = 0; 1073 while ((ch = pszPath[cchComponent]) != '\0' && RTPATH_IS_SLASH(ch)) 1074 cchComponent++; 1075 if (!cchComponent) 1076 { 1077 *ppName = pCur; 1078 return VINF_SUCCESS; 1079 } 1080 1081 size_t offNext = cchComponent; 1082 while (RTPATH_IS_SLASH(ch)) 1083 ch = pszPath[offNext++]; 1084 1085 /* 1086 * Deal with dot and dot-dot. 1087 */ 1088 if (cchComponent == 1 && pszPath[0] == '.') 1089 { /* nothing to do */ } 1090 else if (cchComponent == 2 && pszPath[0] == '.' && pszPath[1] == '.') 1091 { 1092 if (pCur->pParent) 1093 pCur = pCur->pParent; 1094 } 1095 /* 1096 * Look up the name. 1097 */ 1098 else 1099 { 1100 PRTFSISOMAKERNAME pChild = rtFsIsoMakerFindEntryInDirBySpec(pCur, pszPath, cchComponent); 1101 if (!pChild) 1102 return pszPath[offNext] ? VERR_PATH_NOT_FOUND : VERR_FILE_NOT_FOUND; 1103 if ( (offNext > cchComponent) 1104 && !pChild->pDir) 1105 return VERR_NOT_A_DIRECTORY; 1106 pCur = pChild; 1107 } 1108 1109 /* 1110 * Skip ahead in the path. 1111 */ 1112 pszPath += offNext; 1113 } 913 1114 } 914 1115 … … 1112 1313 * This one is a lot of work, so separate function. 1113 1314 */ 1114 case RTFSISOMAKER NAMESPACE_ISO_9660:1315 case RTFSISOMAKER_NAMESPACE_ISO_9660: 1115 1316 return rtFsIsoMakerNormalizeNameForPrimaryIso9660(pThis, pParent, pchSrc, cchSrc, fIsDir, pszDst, cbDst, pcchDst); 1116 1317 … … 1118 1319 * At the moment we don't give darn about UCS-2 limitations here... 1119 1320 */ 1120 case RTFSISOMAKER NAMESPACE_JOLIET:1321 case RTFSISOMAKER_NAMESPACE_JOLIET: 1121 1322 { 1122 1323 /** @todo Joliet name limit and check for duplicates. */ … … 1128 1329 } 1129 1330 1130 case RTFSISOMAKER NAMESPACE_UDF:1131 case RTFSISOMAKER NAMESPACE_HFS:1331 case RTFSISOMAKER_NAMESPACE_UDF: 1332 case RTFSISOMAKER_NAMESPACE_HFS: 1132 1333 AssertFailedReturn(VERR_NOT_IMPLEMENTED); 1133 1334 … … 1150 1351 1151 1352 /** 1353 * Creates a TRANS.TBL file object for a newly named directory. 1354 * 1355 * The file is associated with the namespace node for the directory. The file 1356 * will be generated on the fly from the directory object. 1357 * 1358 * @returns IPRT status code. 1359 * @param pThis The ISO maker instance. 1360 * @param pNamespace The namespace. 1361 * @param pDirName The new name space node for the directory. 1362 */ 1363 static int rtFsIsoMakerAddTransTblFileToNewDir(PRTFSISOMAKERINT pThis, PRTFSISOMAKERNAMESPACE pNamespace, 1364 PRTFSISOMAKERNAME pDirName) 1365 { 1366 /* 1367 * Create a file object for it. 1368 */ 1369 PRTFSISOMAKERFILE pFile; 1370 int rc = rtFsIsoMakerAddUnnamedFileWorker(pThis, NULL, 0, &pFile); 1371 if (RT_SUCCESS(rc)) 1372 { 1373 pFile->enmSrcType = RTFSISOMAKERSRCTYPE_TRANS_TBL; 1374 pFile->u.pTransTblDir = pDirName; 1375 pDirName->pDir->pTransTblFile = pFile; 1376 1377 /* 1378 * Add it to the directory. 1379 */ 1380 rc = rtFsIsoMakerObjSetName(pThis, pNamespace, &pFile->Core, pDirName, 1381 pNamespace->pszTransTbl, strlen(pNamespace->pszTransTbl), NULL /*ppNewName*/); 1382 if (RT_SUCCESS(rc)) 1383 return VINF_SUCCESS; 1384 1385 /* 1386 * Bail. 1387 */ 1388 pDirName->pDir->pTransTblFile = NULL; 1389 rtFsIsoMakerObjRemoveWorker(pThis, &pFile->Core); 1390 } 1391 return rc; 1392 } 1393 1394 1395 /** 1152 1396 * Sets the name of an object in a namespace. 1153 1397 * 1154 * The object cannot currently have a name in that namespace. 1398 * If the object is already named in the name space, it will first be removed 1399 * from that namespace. Should we run out of memory or into normalization 1400 * issues after removing it, its original state will _not_ be restored. 1155 1401 * 1156 1402 * @returns IPRT status code. … … 1167 1413 { 1168 1414 Assert(cchSpec < _32K); 1415 1416 /* 1417 * If the object is already named, unset that name before continuing. 1418 */ 1419 if (*rtFsIsoMakerObjGetNameForNamespace(pObj, pNamespace)) 1420 { 1421 int rc = rtFsIsoMakerObjUnsetName(pThis, pNamespace, pObj); 1422 if (RT_FAILURE(rc)) 1423 return rc; 1424 } 1169 1425 1170 1426 /* … … 1246 1502 pDir->papChildren = NULL; 1247 1503 pDir->pTransTblFile = NULL; 1248 /** @todo TRANS.TBL files. */1249 1250 1504 pName->pDir = pDir; 1505 1506 /* Create the TRANS.TBL file object and enter it into this directory as the first entry. */ 1507 if (pNamespace->pszTransTbl) 1508 { 1509 rc = rtFsIsoMakerAddTransTblFileToNewDir(pThis, pNamespace, pName); 1510 if (RT_FAILURE(rc)) 1511 { 1512 RTMemFree(pName); 1513 return rc; 1514 } 1515 } 1251 1516 } 1252 1517 1253 1518 /* 1254 * Do the linking and stats. 1519 * Do the linking and stats. We practice insertion sorting. 1255 1520 */ 1256 1521 if (pParent) 1257 pParent->pDir->papChildren[pParent->pDir->cChildren++] = pName; 1522 { 1523 uint32_t idxName = rtFsIsoMakerFindInsertIndex(pNamespace, pParent, pName->szName); 1524 uint32_t cChildren = pParent->pDir->cChildren; 1525 if (idxName < cChildren) 1526 memmove(&pParent->pDir->papChildren[idxName + 1], &pParent->pDir->papChildren[idxName], 1527 (cChildren - idxName) * sizeof(pParent->pDir->papChildren[0])); 1528 pParent->pDir->papChildren[idxName] = pName; 1529 pParent->pDir->cChildren++; 1530 } 1258 1531 else 1259 1532 pNamespace->pRoot = pName; … … 1273 1546 1274 1547 1275 static int rtFsIsoMakerPathToParent(PRTFSISOMAKERINT pThis, PRTFSISOMAKERNAMESPACE pNamespace, const char *pszPath, 1276 PPRTFSISOMAKERNAME ppParent, const char **ppszEntry, size_t *pcchEntry) 1548 /** 1549 * Walks the path up to the parent, creating missing directories as needed. 1550 * 1551 * As usual, we walk the specified names rather than the mangled ones. 1552 * 1553 * @returns IPRT status code. 1554 * @param pThis The ISO maker instance. 1555 * @param pNamespace The namespace to walk. 1556 * @param pszPath The path to walk. 1557 * @param ppParent Where to return the pointer to the parent 1558 * namespace node. 1559 * @param ppszEntry Where to return the pointer to the final name component. 1560 * @param pcchEntry Where to return the length of the final name component. 1561 */ 1562 static int rtFsIsoMakerCreatePathToParent(PRTFSISOMAKERINT pThis, PRTFSISOMAKERNAMESPACE pNamespace, const char *pszPath, 1563 PPRTFSISOMAKERNAME ppParent, const char **ppszEntry, size_t *pcchEntry) 1277 1564 { 1278 1565 int rc; … … 1284 1571 while (RTPATH_IS_SLASH(*pszPath)) 1285 1572 pszPath++; 1286 AssertReturn(*pszPath, VERR_INTERNAL_ERROR_4); 1573 AssertReturn(*pszPath, VERR_INTERNAL_ERROR_4); /* We should not be called on a root path. */ 1287 1574 1288 1575 PRTFSISOMAKERNAME pParent = pNamespace->pRoot; … … 1357 1644 pParent = pParent->pParent; 1358 1645 } 1646 /* 1647 * Look it up. 1648 */ 1359 1649 else 1360 1650 { 1361 /*1362 * Look it up.1363 */1364 1651 PRTFSISOMAKERNAME pChild = rtFsIsoMakerFindEntryInDirBySpec(pParent, pszPath, cchComponent); 1365 1652 if (pChild) 1366 pParent = pChild; 1653 { 1654 if (pChild->pDir) 1655 pParent = pChild; 1656 else 1657 return VERR_NOT_A_DIRECTORY; 1658 } 1367 1659 else 1368 1660 { … … 1427 1719 int rc; 1428 1720 if (pszPath[1] != '\0') 1429 rc = rtFsIsoMaker PathToParent(pThis, pNamespace, pszPath, &pParent, &pszEntry, &cchEntry);1721 rc = rtFsIsoMakerCreatePathToParent(pThis, pNamespace, pszPath, &pParent, &pszEntry, &cchEntry); 1430 1722 else 1431 1723 { … … 1524 1816 1525 1817 1818 1819 1820 1526 1821 /* 1527 1822 * … … 1569 1864 1570 1865 /** 1866 * Resolves a path into a object ID. 1867 * 1868 * This will be doing the looking up using the specified object names rather 1869 * than the version adjusted and mangled according to the namespace setup. 1870 * 1871 * @returns The object ID corresponding to @a pszPath, or UINT32_MAX if not 1872 * found or invalid parameters. 1873 * @param hIsoMaker The ISO maker instance. 1874 * @param fNamespaces The namespace to resolve @a pszPath in. It's 1875 * possible to specify multiple namespaces here, of 1876 * course, but that's inefficient. 1877 * @param pszPath The path to the object. 1878 */ 1879 RTDECL(uint32_t) RTFsIsoMakerGetObjIdxForPath(RTFSISOMAKER hIsoMaker, uint32_t fNamespaces, const char *pszPath) 1880 { 1881 /* 1882 * Validate input. 1883 */ 1884 PRTFSISOMAKERINT pThis = hIsoMaker; 1885 RTFSISOMAKER_ASSER_VALID_HANDLE_RET_EX(pThis, UINT32_MAX); 1886 1887 /* 1888 * Do the searching. 1889 */ 1890 for (uint32_t i = 0; i < RT_ELEMENTS(g_aRTFsIsoNamespaces); i++) 1891 if (fNamespaces & g_aRTFsIsoNamespaces[i].fNamespace) 1892 { 1893 PRTFSISOMAKERNAMESPACE pNamespace = (PRTFSISOMAKERNAMESPACE)((uintptr_t)pThis + g_aRTFsIsoNamespaces[i].offNamespace); 1894 if (pNamespace->pRoot) 1895 { 1896 PRTFSISOMAKERNAME pName; 1897 int rc = rtFsIsoMakerWalkPathBySpec(pNamespace, pszPath, &pName); 1898 if (RT_SUCCESS(rc)) 1899 return pName->pObj->idxObj; 1900 } 1901 } 1902 1903 return UINT32_MAX; 1904 } 1905 1906 1907 /** 1571 1908 * Removes the specified object from the image. 1909 * 1910 * This is a worker for RTFsIsoMakerObjRemove and 1911 * rtFsIsoMakerFinalizeRemoveOrphans. 1572 1912 * 1573 1913 * @returns IPRT status code. 1574 1914 * @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 1915 * @param pObj The object to remove from the image. 1916 */ 1917 static int rtFsIsoMakerObjRemoveWorker(PRTFSISOMAKERINT pThis, PRTFSISOMAKEROBJ pObj) 1918 { 1587 1919 /* 1588 1920 * Remove the object from all name spaces. … … 1612 1944 rtFsIsoMakerObjDestroy(pObj); 1613 1945 } 1614 1615 1946 return rc; 1947 } 1948 1949 1950 /** 1951 * Removes the specified object from the image. 1952 * 1953 * @returns IPRT status code. 1954 * @param hIsoMaker The ISO maker instance. 1955 * @param idxObj The index of the object to remove. 1956 */ 1957 RTDECL(int) RTFsIsoMakerObjRemove(RTFSISOMAKER hIsoMaker, uint32_t idxObj) 1958 { 1959 /* 1960 * Validate and translate input. 1961 */ 1962 PRTFSISOMAKERINT pThis = hIsoMaker; 1963 RTFSISOMAKER_ASSER_VALID_HANDLE_RET(pThis); 1964 PRTFSISOMAKEROBJ pObj = rtFsIsoMakerIndexToObj(pThis, idxObj); 1965 AssertReturn(pObj, VERR_OUT_OF_RANGE); 1966 AssertReturn(!pThis->fFinalized, VERR_WRONG_ORDER); 1967 1968 /* 1969 * Call worker. 1970 */ 1971 return rtFsIsoMakerObjRemoveWorker(pThis, pObj); 1616 1972 } 1617 1973 … … 1629 1985 * @param idxObj The configuration index of to name. 1630 1986 * @param fNamespaces The namespaces to apply the path to 1631 * (RTFSISOMAKER NAMESPACE_XXX).1987 * (RTFSISOMAKER_NAMESPACE_XXX). 1632 1988 * @param pszPath The path. 1633 1989 */ … … 1639 1995 PRTFSISOMAKERINT pThis = hIsoMaker; 1640 1996 RTFSISOMAKER_ASSER_VALID_HANDLE_RET(pThis); 1641 AssertReturn(!(fNamespaces & ~RTFSISOMAKER NAMESPACE_VALID_MASK), VERR_INVALID_FLAGS);1997 AssertReturn(!(fNamespaces & ~RTFSISOMAKER_NAMESPACE_VALID_MASK), VERR_INVALID_FLAGS); 1642 1998 AssertPtrReturn(pszPath, VERR_INVALID_POINTER); 1643 1999 AssertReturn(RTPATH_IS_SLASH(*pszPath), VERR_INVALID_NAME); 1644 2000 PRTFSISOMAKEROBJ pObj = rtFsIsoMakerIndexToObj(pThis, idxObj); 1645 2001 AssertReturn(pObj, VERR_OUT_OF_RANGE); 2002 AssertReturn(!pThis->fFinalized, VERR_WRONG_ORDER); 1646 2003 1647 2004 /* … … 1671 2028 * The name will be transformed as necessary. 1672 2029 * 1673 * The initial implementation does not allow this function to be called more1674 * than once on an object.1675 *1676 2030 * @returns IPRT status code. 1677 2031 * @param hIsoMaker The ISO maker handle. … … 1679 2033 * @param idxParentObj The parent directory object. 1680 2034 * @param fNamespaces The namespaces to apply the path to 1681 * (RTFSISOMAKER NAMESPACE_XXX).2035 * (RTFSISOMAKER_NAMESPACE_XXX). 1682 2036 * @param pszName The name. 1683 2037 */ … … 1690 2044 PRTFSISOMAKERINT pThis = hIsoMaker; 1691 2045 RTFSISOMAKER_ASSER_VALID_HANDLE_RET(pThis); 1692 AssertReturn(!(fNamespaces & ~RTFSISOMAKER NAMESPACE_VALID_MASK), VERR_INVALID_FLAGS);2046 AssertReturn(!(fNamespaces & ~RTFSISOMAKER_NAMESPACE_VALID_MASK), VERR_INVALID_FLAGS); 1693 2047 AssertPtrReturn(pszName, VERR_INVALID_POINTER); 1694 2048 size_t cchName = strlen(pszName); … … 1699 2053 PRTFSISOMAKEROBJ pParentObj = rtFsIsoMakerIndexToObj(pThis, idxParentObj); 1700 2054 AssertReturn(pParentObj, VERR_OUT_OF_RANGE); 2055 AssertReturn(!pThis->fFinalized, VERR_WRONG_ORDER); 1701 2056 1702 2057 /* … … 1738 2093 RTFSISOMAKEROBJTYPE enmType, PCRTFSOBJINFO pObjInfo) 1739 2094 { 2095 Assert(!pThis->fFinalized); 1740 2096 AssertReturn(pThis->cObjects < RTFSISOMAKER_MAX_OBJECTS, VERR_OUT_OF_RANGE); 2097 1741 2098 pObj->enmType = enmType; 1742 2099 pObj->pPrimaryName = NULL; … … 1745 2102 pObj->pHfsName = NULL; 1746 2103 pObj->idxObj = pThis->cObjects++; 2104 pObj->fNotOrphan = false; 1747 2105 if (pObjInfo) 1748 2106 { … … 1810 2168 RTFSISOMAKER_ASSER_VALID_HANDLE_RET(pThis); 1811 2169 AssertPtrReturn(pidxObj, VERR_INVALID_POINTER); 2170 AssertReturn(!pThis->fFinalized, VERR_WRONG_ORDER); 1812 2171 1813 2172 PRTFSISOMAKERDIR pDir; … … 1840 2199 if (RT_SUCCESS(rc)) 1841 2200 { 1842 rc = RTFsIsoMakerObjSetPath(hIsoMaker, idxObj, RTFSISOMAKER NAMESPACE_ALL, pszDir);2201 rc = RTFsIsoMakerObjSetPath(hIsoMaker, idxObj, RTFSISOMAKER_NAMESPACE_ALL, pszDir); 1843 2202 if (RT_SUCCESS(rc)) 1844 2203 { … … 1903 2262 AssertPtrReturn(pidxObj, VERR_INVALID_POINTER); 1904 2263 *pidxObj = UINT32_MAX; 2264 AssertReturn(!pThis->fFinalized, VERR_WRONG_ORDER); 1905 2265 1906 2266 /* … … 1948 2308 AssertPtrReturn(pidxObj, VERR_INVALID_POINTER); 1949 2309 *pidxObj = UINT32_MAX; 2310 AssertReturn(!pThis->fFinalized, VERR_WRONG_ORDER); 1950 2311 1951 2312 /* … … 2004 2365 if (RT_SUCCESS(rc)) 2005 2366 { 2006 rc = RTFsIsoMakerObjSetPath(hIsoMaker, idxObj, RTFSISOMAKER NAMESPACE_ALL, pszFile);2367 rc = RTFsIsoMakerObjSetPath(hIsoMaker, idxObj, RTFSISOMAKER_NAMESPACE_ALL, pszFile); 2007 2368 if (RT_SUCCESS(rc)) 2008 2369 { … … 2041 2402 if (RT_SUCCESS(rc)) 2042 2403 { 2043 rc = RTFsIsoMakerObjSetPath(hIsoMaker, idxObj, RTFSISOMAKER NAMESPACE_ALL, pszFile);2404 rc = RTFsIsoMakerObjSetPath(hIsoMaker, idxObj, RTFSISOMAKER_NAMESPACE_ALL, pszFile); 2044 2405 if (RT_SUCCESS(rc)) 2045 2406 { … … 2053 2414 } 2054 2415 2416 2417 2418 2419 2420 /* 2421 * 2422 * Image finalization. 2423 * Image finalization. 2424 * Image finalization. 2425 * 2426 */ 2427 2428 2429 /** 2430 * Remove any orphaned object from the disk. 2431 * 2432 * @returns IPRT status code. 2433 * @param pThis The ISO maker instance. 2434 */ 2435 static int rtFsIsoMakerFinalizeRemoveOrphans(PRTFSISOMAKERINT pThis) 2436 { 2437 for (;;) 2438 { 2439 uint32_t cRemoved = 0; 2440 PRTFSISOMAKEROBJ pCur; 2441 PRTFSISOMAKEROBJ pNext; 2442 RTListForEachSafe(&pThis->ObjectHead, pCur, pNext, RTFSISOMAKEROBJ, Entry) 2443 { 2444 if ( pCur->pPrimaryName 2445 || pCur->pJolietName 2446 || pCur->pUdfName 2447 || pCur->pHfsName 2448 || pCur->fNotOrphan) 2449 { /* likely */ } 2450 else 2451 { 2452 int rc = rtFsIsoMakerObjRemoveWorker(pThis, pCur); 2453 if (RT_SUCCESS(rc)) 2454 cRemoved++; 2455 else 2456 return rc; 2457 } 2458 } 2459 if (!cRemoved) 2460 return VINF_SUCCESS; 2461 } 2462 } 2463 2464 2465 /** 2466 * Finalizes the El Torito boot stuff. 2467 * 2468 * This includes generating the boot catalog data and fixing the location of all 2469 * related image files. 2470 * 2471 * @returns IPRT status code. 2472 * @param pThis The ISO maker instance. 2473 * @param poffData The data offset (in/out). 2474 */ 2475 static int rtFsIsoMakerFinalizeBootStuff(PRTFSISOMAKERINT pThis, uint64_t *poffData) 2476 { 2477 RT_NOREF(pThis, poffData); 2478 return VINF_SUCCESS; 2479 } 2480 2481 2482 /** 2483 * Finalizes directories and related stuff. 2484 * 2485 * This will not generate actual directory data, but calculate the size of it 2486 * once it's generated. Ditto for the path tables. The exception is the rock 2487 * ridge spill file, which will be generated in memory. 2488 * 2489 * @returns IPRT status code. 2490 * @param pThis The ISO maker instance. 2491 * @param poffData The data offset (in/out). 2492 */ 2493 static int rtFsIsoMakerFinalizeDirectories(PRTFSISOMAKERINT pThis, uint64_t *poffData) 2494 { 2495 RT_NOREF(pThis, poffData); 2496 return VINF_SUCCESS; 2497 } 2498 2499 2500 /** 2501 * Finalizes data allocations. 2502 * 2503 * This will set the RTFSISOMAKERFILE::offData members. 2504 * 2505 * @returns IPRT status code. 2506 * @param pThis The ISO maker instance. 2507 * @param poffData The data offset (in/out). 2508 */ 2509 static int rtFsIsoMakerFinalizeData(PRTFSISOMAKERINT pThis, uint64_t *poffData) 2510 { 2511 RT_NOREF(pThis, poffData); 2512 return VINF_SUCCESS; 2513 } 2514 2515 2516 /** 2517 * Finalizes the volume descriptors. 2518 * 2519 * This will set the RTFSISOMAKERFILE::offData members. 2520 * 2521 * @returns IPRT status code. 2522 * @param pThis The ISO maker instance. 2523 */ 2524 static int rtFsIsoMakerFinalizeVolumeDescriptors(PRTFSISOMAKERINT pThis) 2525 { 2526 RT_NOREF(pThis); 2527 return VINF_SUCCESS; 2528 } 2529 2530 2531 /** 2532 * Finalizes the image. 2533 * 2534 * @returns IPRT status code. 2535 * @param hIsoMaker The ISO maker handle. 2536 */ 2537 RTDECL(int) RTFsIsoMakerFinalize(RTFSISOMAKER hIsoMaker) 2538 { 2539 PRTFSISOMAKERINT pThis = hIsoMaker; 2540 RTFSISOMAKER_ASSER_VALID_HANDLE_RET(pThis); 2541 AssertReturn(!pThis->fFinalized, VERR_WRONG_ORDER); 2542 2543 /* 2544 * Remove orphaned objects. 2545 */ 2546 int rc = rtFsIsoMakerFinalizeRemoveOrphans(pThis); 2547 if (RT_FAILURE(rc)) 2548 return rc; 2549 2550 /* 2551 * If there is any boot related stuff to be included, it ends up right after 2552 * the descriptors. 2553 */ 2554 uint64_t offData = _32K + pThis->cVolumeDescriptors * RTFSISOMAKER_SECTOR_SIZE; 2555 rc = rtFsIsoMakerFinalizeBootStuff(pThis, &offData); 2556 if (RT_SUCCESS(rc)) 2557 { 2558 rc = rtFsIsoMakerFinalizeDirectories(pThis, &offData); 2559 if (RT_SUCCESS(rc)) 2560 { 2561 rc = rtFsIsoMakerFinalizeData(pThis, &offData); 2562 if (RT_SUCCESS(rc)) 2563 { 2564 pThis->cbFinalizedImage = offData; 2565 2566 /* 2567 * Finally, finalize the volume descriptors. 2568 */ 2569 rc = rtFsIsoMakerFinalizeVolumeDescriptors(pThis); 2570 if (RT_SUCCESS(rc)) 2571 { 2572 pThis->fFinalized = true; 2573 return VINF_SUCCESS; 2574 } 2575 } 2576 } 2577 } 2578 return rc; 2579 } 2580 2581
Note:
See TracChangeset
for help on using the changeset viewer.