VirtualBox

Changeset 69029 in vbox for trunk/src/VBox/Runtime/common/fs


Ignore:
Timestamp:
Oct 10, 2017 8:33:05 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
118304
Message:

iprt: udf updates

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/fs/isovfs.cpp

    r69027 r69029  
    9999          : (a_pStruct)->a_Member.uType == UDF_AD_TYPE_FREE ? "free" : "next", \
    100100          (a_pStruct)->a_Member.ImplementationUse.Fid.idUnique, (a_pStruct)->a_Member.ImplementationUse.Fid.fFlags ))
     101#define UDF_LOG2_MEMBER_LBADDR(a_pStruct, a_Member) \
     102    Log2(("ISO/UDF:   %-32s block %#010RX32 in partition %#06RX16\n", #a_Member ":", \
     103          (a_pStruct)->a_Member.off, (a_pStruct)->a_Member.uPartitionNo))
    101104
    102105#define UDF_LOG2_MEMBER_TIMESTAMP(a_pStruct, a_Member) \
    103     Log2(("ISO/UDF:   %-32s %04d-%02u-%02u %02u:%02u:%02u.%02u%02u%02u uTypeAndZone=%#x\n", #a_Member ":", \
     106    Log2(("ISO/UDF:   %-32s %04d-%02u-%02u %02u:%02u:%02u.%02u%02u%02u offUtc=%d type=%#x\n", #a_Member ":", \
    104107          (a_pStruct)->a_Member.iYear, (a_pStruct)->a_Member.uMonth, (a_pStruct)->a_Member.uDay, \
    105108          (a_pStruct)->a_Member.uHour, (a_pStruct)->a_Member.uMinute, (a_pStruct)->a_Member.uSecond, \
    106109          (a_pStruct)->a_Member.cCentiseconds, (a_pStruct)->a_Member.cHundredsOfMicroseconds, \
    107           (a_pStruct)->a_Member.cMicroseconds, (a_pStruct)->a_Member.uTypeAndZone))
     110          (a_pStruct)->a_Member.cMicroseconds, (a_pStruct)->a_Member.offUtcInMin, (a_pStruct)->a_Member.fType ))
    108111#define UDF_LOG2_MEMBER_CHARSPEC(a_pStruct, a_Member) \
    109112    do { \
     
    475478 * @param   offByteAddend   The byte offset relative to the block.
    476479 * @param   pvBuf           The output buffer.
    477  * @param   cbBuf           The number of bytes to read.
     480 * @param   cbToRead        The number of bytes to read.
    478481 */
    479482static int rtFsIsoVolUdfVpRead(PRTFSISOVOL pThis, uint32_t idxPart, uint32_t idxBlock, uint64_t offByteAddend,
     
    677680
    678681/**
    679  * Converts a ISO 9660 binary timestamp into an IPRT timesspec.
     682 * Converts an ISO 9660 binary timestamp into an IPRT timesspec.
    680683 *
    681684 * @param   pTimeSpec       Where to return the IRPT time.
     
    701704    if (RT_ABS(pIso9660->offUtc) <= 13*4)
    702705        RTTimeSpecSubSeconds(pTimeSpec, pIso9660->offUtc * 15 * 60 * 60);
     706}
     707
     708
     709/**
     710 * Converts an UDF timestamp into an IPRT timesspec.
     711 *
     712 * @param   pTimeSpec       Where to return the IRPT time.
     713 * @param   pUdf            The UDF timestamp.
     714 */
     715static void rtFsIsoUdfTimestamp2TimeSpec(PRTTIMESPEC pTimeSpec, PCUDFTIMESTAMP pUdf)
     716{
     717    /* Check the year range before we try convert anything as it's quite possible
     718       that this is zero. */
     719    if (   pUdf->iYear > 1678
     720        && pUdf->iYear < 2262)
     721    {
     722        RTTIME Time;
     723        Time.fFlags         = RTTIME_FLAGS_TYPE_UTC;
     724        Time.offUTC         = 0;
     725        Time.i32Year        = pUdf->iYear;
     726        Time.u8Month        = RT_MIN(RT_MAX(pUdf->uMonth, 1), 12);
     727        Time.u8MonthDay     = RT_MIN(RT_MAX(pUdf->uDay, 1), 31);
     728        Time.u8WeekDay      = UINT8_MAX;
     729        Time.u16YearDay     = 0;
     730        Time.u8Hour         = RT_MIN(pUdf->uHour, 23);
     731        Time.u8Minute       = RT_MIN(pUdf->uMinute, 59);
     732        Time.u8Second       = RT_MIN(pUdf->uSecond, 59);
     733        Time.u32Nanosecond  = pUdf->cCentiseconds           * UINT32_C(10000000)
     734                            + pUdf->cHundredsOfMicroseconds *   UINT32_C(100000)
     735                            + pUdf->cMicroseconds           *     UINT32_C(1000);
     736        RTTimeImplode(pTimeSpec, RTTimeNormalize(&Time));
     737
     738        /* Only apply the UTC offset if it's within reasons. */
     739        if (RT_ABS(pUdf->offUtcInMin) <= 13*60)
     740            RTTimeSpecSubSeconds(pTimeSpec, pUdf->offUtcInMin * 60);
     741    }
     742    else
     743        RTTimeSpecSetNano(pTimeSpec, 0);
    703744}
    704745
     
    795836}
    796837
    797 /** No direct ICB entries found. */
    798 #define VERR_ISOFS_NO_DIRECT_ICB_ENTRIES                (-25336)
    799 /** Too many ICB indirections, possibly a loop. */
    800 #define VERR_ISOFS_TOO_MANY_ICB_INDIRECTIONS            (-25337)
    801 /** Too deep ICB recursion. */
    802 #define VERR_ISOFS_TOO_DEEP_ICB_RECURSION               (-25338)
    803 /** ICB is too small to contain anything useful.   */
    804 #define VERR_ISOFS_ICB_TOO_SMALL                        (-25339)
    805 /** Unsupported tag encountered in ICB. */
    806 #define VERR_ISOFS_UNSUPPORTED_ICB                      (-25340)
    807 /** Bad file entry (ICB). */
    808 #define VERR_ISOFS_BAD_FILE_ENTRY                       (-25341)
    809 /** Unknown allocation descriptor type.   */
    810 #define VERR_ISO_FS_UNKNOWN_AD_TYPE                     (-25342)
    811 /** Malformed extended allocation descriptor. */
    812 #define VERR_ISOFS_BAD_EXTAD                            (-25343)
    813 
    814838
    815839/**
     
    817841 *
    818842 * @returns IPRT status code
    819  * @param   pCore           .
    820  * @param   pbAllocDescs    .
    821  * @param   cbAllocDescs    .
    822  * @param   fIcbTagFlags    .
    823  * @param   idxDefaultPart  .
    824  * @param   offAllocDescs   .
    825  * @param   pThis           .
     843 * @param   pCore           The core structure.
     844 * @param   pbAllocDescs    Pointer to the allocation descriptor data.
     845 * @param   cbAllocDescs    The size of the allocation descriptor data.
     846 * @param   fIcbTagFlags    The ICB tag flags.
     847 * @param   idxDefaultPart  The default data partition.
     848 * @param   offAllocDescs   The disk byte offset corresponding to @a pbAllocDesc
     849 *                          in case it's used as data storage (type 3).
     850 * @param   pVol            The volume instance data.
    826851 */
    827852static int rtFsIsoCore_InitExtentsUdfIcbEntry(PRTFSISOCORE pCore, uint8_t const *pbAllocDescs, uint32_t cbAllocDescs,
    828853                                              uint32_t fIcbTagFlags, uint32_t idxDefaultPart, uint64_t offAllocDescs,
    829                                               PRTFSISOVOL pThis)
     854                                              PRTFSISOVOL pVol)
    830855{
    831856    /*
     
    909934                    idxPart  = uPtr.pExt->Location.uPartitionNo;
    910935                    cbAllocDescs -= uPtr.pExt->cbInformation;
    911                     uPtr.pb += uPtr.pExt->cbInformation;
     936                    uPtr.pb      += uPtr.pExt->cbInformation;
    912937                    break;
    913938                default:
     
    917942            /* Check if we can extend the current extent.  This is useful since
    918943               the descriptors can typically only cover 1GB. */
    919             uint64_t const off = (uint64_t)idxBlock << pThis->Udf.VolInfo.cShiftBlock;
     944            uint64_t const off = (uint64_t)idxBlock << pVol->Udf.VolInfo.cShiftBlock;
    920945            if (   pCurExtent != NULL
    921946                && (   pCurExtent->off != UINT64_MAX
     
    9861011
    9871012
    988 static int rtFsIsoCore_InitFromUdfIcbFileEntry(PRTFSISOCORE pCore, PCUDFFILEENTRY pFileEntry, uint32_t idxDefaultPart,
    989                                                uint32_t *pcProcessed, PRTFSISOVOL pThis)
    990 {
     1013/**
     1014 * Converts ICB flags, ICB file type and file entry permissions to an IPRT file
     1015 * mode mask.
     1016 *
     1017 * @returns IPRT status ocde
     1018 * @param   fIcbTagFlags    The ICB flags.
     1019 * @param   bFileType       The ICB file type.
     1020 * @param   fPermission     The file entry permission mask.
     1021 * @param   pfAttrib        Where to return the IRPT file mode mask.
     1022 */
     1023static int rtFsIsoCore_UdfStuffToFileMode(uint32_t fIcbTagFlags, uint8_t bFileType, uint32_t fPermission, PRTFMODE pfAttrib)
     1024{
     1025    /*
     1026     * Type:
     1027     */
     1028    RTFMODE fAttrib;
     1029    switch (bFileType)
     1030    {
     1031        case UDF_FILE_TYPE_DIRECTORY:
     1032            fAttrib = RTFS_TYPE_DIRECTORY | RTFS_DOS_DIRECTORY;
     1033            break;
     1034
     1035        case UDF_FILE_TYPE_REGULAR_FILE:
     1036        case UDF_FILE_TYPE_REAL_TIME_FILE:
     1037            fAttrib = RTFS_TYPE_FILE;
     1038            break;
     1039
     1040        case UDF_FILE_TYPE_SYMBOLIC_LINK:
     1041            fAttrib = RTFS_TYPE_SYMLINK;
     1042            break;
     1043
     1044        case UDF_FILE_TYPE_BLOCK_DEVICE:
     1045            fAttrib = RTFS_TYPE_DEV_BLOCK;
     1046            break;
     1047        case UDF_FILE_TYPE_CHARACTER_DEVICE:
     1048            fAttrib = RTFS_TYPE_DEV_CHAR;
     1049            break;
     1050
     1051        case UDF_FILE_TYPE_FIFO:
     1052            fAttrib = RTFS_TYPE_FIFO;
     1053            break;
     1054
     1055        case UDF_FILE_TYPE_SOCKET:
     1056            fAttrib = RTFS_TYPE_SOCKET;
     1057            break;
     1058
     1059        case UDF_FILE_TYPE_STREAM_DIRECTORY:
     1060        case UDF_FILE_TYPE_EXTENDED_ATTRIBUTES:
     1061        case UDF_FILE_TYPE_TERMINAL_ENTRY:
     1062        case UDF_FILE_TYPE_VAT:
     1063        case UDF_FILE_TYPE_METADATA_FILE:
     1064        case UDF_FILE_TYPE_METADATA_MIRROR_FILE:
     1065        case UDF_FILE_TYPE_METADATA_BITMAP_FILE:
     1066        case UDF_FILE_TYPE_NOT_SPECIFIED:
     1067        case UDF_FILE_TYPE_INDIRECT_ENTRY:
     1068        case UDF_FILE_TYPE_UNALLOCATED_SPACE_ENTRY:
     1069        case UDF_FILE_TYPE_PARTITION_INTEGRITY_ENTRY:
     1070            LogRelMax(45, ("ISO/UDF: Warning! Wrong file type: %#x\n", bFileType));
     1071            return VERR_ISOFS_WRONG_FILE_TYPE;
     1072
     1073        default:
     1074            LogRelMax(45, ("ISO/UDF: Warning! Unknown file type: %#x\n", bFileType));
     1075            return VERR_ISOFS_UNKNOWN_FILE_TYPE;
     1076    }
     1077
     1078    /*
     1079     * Permissions:
     1080     */
     1081    if (fPermission & UDF_PERM_OTH_EXEC)
     1082        fAttrib |= RTFS_UNIX_IXOTH;
     1083    if (fPermission & UDF_PERM_OTH_READ)
     1084        fAttrib |= RTFS_UNIX_IROTH;
     1085    if (fPermission & UDF_PERM_OTH_WRITE)
     1086        fAttrib |= RTFS_UNIX_IWOTH;
     1087
     1088    if (fPermission & UDF_PERM_GRP_EXEC)
     1089        fAttrib |= RTFS_UNIX_IXGRP;
     1090    if (fPermission & UDF_PERM_GRP_READ)
     1091        fAttrib |= RTFS_UNIX_IRGRP;
     1092    if (fPermission & UDF_PERM_GRP_WRITE)
     1093        fAttrib |= RTFS_UNIX_IWGRP;
     1094
     1095    if (fPermission & UDF_PERM_USR_EXEC)
     1096        fAttrib |= RTFS_UNIX_IXUSR;
     1097    if (fPermission & UDF_PERM_USR_READ)
     1098        fAttrib |= RTFS_UNIX_IRUSR;
     1099    if (fPermission & UDF_PERM_USR_WRITE)
     1100        fAttrib |= RTFS_UNIX_IWUSR;
     1101
     1102    if (   !(fAttrib & (UDF_PERM_OTH_WRITE | UDF_PERM_GRP_WRITE | UDF_PERM_USR_WRITE))
     1103        && (fAttrib & (UDF_PERM_OTH_READ | UDF_PERM_GRP_READ | UDF_PERM_USR_READ)) )
     1104        fAttrib |= RTFS_DOS_READONLY;
     1105
     1106    /*
     1107     * Attributes:
     1108     */
     1109    if (fIcbTagFlags & UDF_ICB_FLAGS_ARCHIVE)
     1110        fAttrib |= RTFS_DOS_ARCHIVED;
     1111    if (fIcbTagFlags & UDF_ICB_FLAGS_SYSTEM)
     1112        fAttrib |= RTFS_DOS_SYSTEM;
     1113    if (fIcbTagFlags & UDF_ICB_FLAGS_ARCHIVE)
     1114        fAttrib |= RTFS_DOS_ARCHIVED;
     1115
     1116    if (fIcbTagFlags & UDF_ICB_FLAGS_SET_UID)
     1117        fAttrib |= RTFS_UNIX_ISUID;
     1118    if (fIcbTagFlags & UDF_ICB_FLAGS_SET_GID)
     1119        fAttrib |= RTFS_UNIX_ISGID;
     1120    if (fIcbTagFlags & UDF_ICB_FLAGS_STICKY)
     1121        fAttrib |= RTFS_UNIX_ISTXT;
     1122
     1123    /* Warn about weird flags. */
     1124    if (fIcbTagFlags & UDF_ICB_FLAGS_TRANSFORMED)
     1125        LogRelMax(45, ("ISO/UDF: Warning! UDF_ICB_FLAGS_TRANSFORMED!\n"));
     1126    if (fIcbTagFlags & UDF_ICB_FLAGS_MULTI_VERSIONS)
     1127        LogRelMax(45, ("ISO/UDF: Warning! UDF_ICB_FLAGS_MULTI_VERSIONS!\n"));
     1128    if (fIcbTagFlags & UDF_ICB_FLAGS_STREAM)
     1129        LogRelMax(45, ("ISO/UDF: Warning! UDF_ICB_FLAGS_STREAM!\n"));
     1130    if (fIcbTagFlags & UDF_ICB_FLAGS_RESERVED_MASK)
     1131        LogRelMax(45, ("ISO/UDF: Warning! UDF_ICB_FLAGS_RESERVED_MASK (%#x)!\n", fIcbTagFlags & UDF_ICB_FLAGS_RESERVED_MASK));
     1132
     1133    *pfAttrib = fAttrib;
     1134    return VINF_SUCCESS;
     1135}
     1136
     1137
     1138/**
     1139 * Initialize/update a core object structure from an UDF extended file entry.
     1140 *
     1141 * @returns IPRT status code
     1142 * @param   pCore           The core object structure to initialize.
     1143 * @param   pFileEntry      The file entry.
     1144 * @param   idxDefaultPart  The default data partition.
     1145 * @param   pcProcessed     Variable to increment on success.
     1146 * @param   pVol            The volume instance.
     1147 */
     1148static int rtFsIsoCore_InitFromUdfIcbExFileEntry(PRTFSISOCORE pCore, PCUDFEXFILEENTRY pFileEntry, uint32_t idxDefaultPart,
     1149                                                 uint32_t *pcProcessed, PRTFSISOVOL pVol)
     1150{
     1151#ifdef LOG_ENABLED
     1152    /*
     1153     * Log it.
     1154     */
     1155    if (LogIs2Enabled())
     1156    {
     1157        UDF_LOG2_MEMBER(pFileEntry, "#010RX32",  IcbTag.cEntiresBeforeThis);
     1158        UDF_LOG2_MEMBER(pFileEntry, "#06RX16",  IcbTag.uStrategyType);
     1159        UDF_LOG2_MEMBER(pFileEntry, "#04RX8",   IcbTag.abStrategyParams[0]);
     1160        UDF_LOG2_MEMBER(pFileEntry, "#04RX8",   IcbTag.abStrategyParams[1]);
     1161        UDF_LOG2_MEMBER(pFileEntry, "#06RX16",  IcbTag.cMaxEntries);
     1162        UDF_LOG2_MEMBER(pFileEntry, "#04RX8",   IcbTag.bReserved);
     1163        UDF_LOG2_MEMBER(pFileEntry, "#04RX8",   IcbTag.bFileType);
     1164        UDF_LOG2_MEMBER_LBADDR(pFileEntry,      IcbTag.ParentIcb);
     1165        UDF_LOG2_MEMBER(pFileEntry, "#06RX16",  IcbTag.fFlags);
     1166        UDF_LOG2_MEMBER(pFileEntry, "#010RX32", uid);
     1167        UDF_LOG2_MEMBER(pFileEntry, "#010RX32", gid);
     1168        UDF_LOG2_MEMBER(pFileEntry, "#010RX32", fPermissions);
     1169        UDF_LOG2_MEMBER(pFileEntry, "#06RX16", cHardlinks);
     1170        UDF_LOG2_MEMBER(pFileEntry, "#04RX8", uRecordFormat);
     1171        UDF_LOG2_MEMBER(pFileEntry, "#04RX8", fRecordDisplayAttribs);
     1172        UDF_LOG2_MEMBER(pFileEntry, "#010RX32", cbRecord);
     1173        UDF_LOG2_MEMBER(pFileEntry, "#018RX64", cbData);
     1174        UDF_LOG2_MEMBER(pFileEntry, "#018RX64", cbObject);
     1175        UDF_LOG2_MEMBER(pFileEntry, "#018RX64", cLogicalBlocks);
     1176        UDF_LOG2_MEMBER_TIMESTAMP(pFileEntry, AccessTime);
     1177        UDF_LOG2_MEMBER_TIMESTAMP(pFileEntry, ModificationTime);
     1178        UDF_LOG2_MEMBER_TIMESTAMP(pFileEntry, BirthTime);
     1179        UDF_LOG2_MEMBER_TIMESTAMP(pFileEntry, ChangeTime);
     1180        UDF_LOG2_MEMBER(pFileEntry, "#010RX32", uCheckpoint);
     1181        UDF_LOG2_MEMBER(pFileEntry, "#010RX32", uReserved);
     1182        UDF_LOG2_MEMBER_LONGAD(pFileEntry, ExtAttribIcb);
     1183        UDF_LOG2_MEMBER_LONGAD(pFileEntry, StreamDirIcb);
     1184        UDF_LOG2_MEMBER_ENTITY_ID(pFileEntry, idImplementation);
     1185        UDF_LOG2_MEMBER(pFileEntry, "#018RX64", INodeId);
     1186        UDF_LOG2_MEMBER(pFileEntry, "#010RX32", cbExtAttribs);
     1187        UDF_LOG2_MEMBER(pFileEntry, "#010RX32", cbAllocDescs);
     1188        if (pFileEntry->cbExtAttribs > 0)
     1189            Log2((pFileEntry->cbExtAttribs <= 16 ? "ISO/UDF:   %-32s %.*Rhxs\n" : "ISO/UDF:   %-32s\n%.*RhxD\n",
     1190                  "abExtAttribs:", pFileEntry->cbExtAttribs, pFileEntry->abExtAttribs));
     1191        if (pFileEntry->cbAllocDescs > 0)
     1192            switch (pFileEntry->IcbTag.fFlags & UDF_ICB_FLAGS_AD_TYPE_MASK)
     1193            {
     1194                case UDF_ICB_FLAGS_AD_TYPE_SHORT:
     1195                {
     1196                    PCUDFSHORTAD paDescs = (PCUDFSHORTAD)&pFileEntry->abExtAttribs[pFileEntry->cbExtAttribs];
     1197                    uint32_t     cDescs  = pFileEntry->cbAllocDescs / sizeof(paDescs[0]);
     1198                    for (uint32_t i = 0; i < cDescs; i++)
     1199                        Log2(("ISO/UDF:   ShortAD[%u]:                      %#010RX32 LB %#010RX32; type=%u\n",
     1200                              i, paDescs[i].off, paDescs[i].cb, paDescs[i].uType));
     1201                    break;
     1202                }
     1203                case UDF_ICB_FLAGS_AD_TYPE_LONG:
     1204                {
     1205                    PCUDFLONGAD  paDescs = (PCUDFLONGAD)&pFileEntry->abExtAttribs[pFileEntry->cbExtAttribs];
     1206                    uint32_t     cDescs  = pFileEntry->cbAllocDescs / sizeof(paDescs[0]);
     1207                    for (uint32_t i = 0; i < cDescs; i++)
     1208                        Log2(("ISO/UDF:   LongAD[%u]:                       %#06RX16:%#010RX32 LB %#010RX32; type=%u iu=%.6Rhxs\n",
     1209                              i, paDescs[i].Location.uPartitionNo, paDescs[i].Location.off,
     1210                              paDescs[i].cb, paDescs[i].uType, &paDescs[i].ImplementationUse));
     1211                    break;
     1212                }
     1213                default:
     1214                    Log2(("ISO/UDF:   %-32s Type=%u\n%.*RhxD\n",
     1215                          "abExtAttribs:", pFileEntry->IcbTag.fFlags & UDF_ICB_FLAGS_AD_TYPE_MASK,
     1216                          pFileEntry->cbAllocDescs, &pFileEntry->abExtAttribs[pFileEntry->cbExtAttribs]));
     1217                    break;
     1218            }
     1219    }
     1220#endif
     1221
    9911222    /*
    9921223     * Basic sanity checking of what we use.
    9931224     */
    9941225    if (     RT_OFFSETOF(UDFFILEENTRY, abExtAttribs) + pFileEntry->cbExtAttribs + pFileEntry->cbAllocDescs
    995            > pThis->Udf.VolInfo.cbBlock
     1226           > pVol->Udf.VolInfo.cbBlock
    9961227        || (pFileEntry->cbExtAttribs & 3) != 0
    997         || pFileEntry->cbExtAttribs >= pThis->Udf.VolInfo.cbBlock
     1228        || pFileEntry->cbExtAttribs >= pVol->Udf.VolInfo.cbBlock
    9981229        || (pFileEntry->cbAllocDescs & 3) != 0
    999         || pFileEntry->cbAllocDescs >= pThis->Udf.VolInfo.cbBlock)
    1000     {
    1001         LogRelMax(45, ("ISO/UDF: File entry (ICB) is bad size values: cbAllocDesc=%#x cbExtAttribs=%#x (cbBlock=%#x)\n",
    1002                        pFileEntry->cbAllocDescs, pFileEntry->cbExtAttribs, pThis->Udf.VolInfo.cbBlock));
     1230        || pFileEntry->cbAllocDescs >= pVol->Udf.VolInfo.cbBlock)
     1231    {
     1232        LogRelMax(45, ("ISO/UDF: Extended file entry (ICB) is bad size values: cbAllocDesc=%#x cbExtAttribs=%#x (cbBlock=%#x)\n",
     1233                       pFileEntry->cbAllocDescs, pFileEntry->cbExtAttribs, pVol->Udf.VolInfo.cbBlock));
    10031234        return VERR_ISOFS_BAD_FILE_ENTRY;
    10041235    }
    10051236
    1006     /*
    1007      * Process the file size and extract allocation information.
    1008      */
    1009     pCore->cbObject = pFileEntry->cbData;
    1010     int rc = rtFsIsoCore_InitExtentsUdfIcbEntry(pCore,
     1237    //pCore->uid        = pFileEntry->uid;
     1238    //pCore->gid        = pFileEntry->gid;
     1239    //pCore->cHardlinks = RT_MIN(pFileEntry->cHardlinks, 1);
     1240    pCore->cbObject     = pFileEntry->cbData;
     1241    //pCore->cbAllocated = pFileEntry->cLogicalBlocks << pVol->Udf.VolInfo.cShiftBlock;
     1242    //pCore->idINode    = pFileEntry->INodeId;
     1243
     1244    rtFsIsoUdfTimestamp2TimeSpec(&pCore->AccessTime,        &pFileEntry->AccessTime);
     1245    rtFsIsoUdfTimestamp2TimeSpec(&pCore->ModificationTime,  &pFileEntry->ModificationTime);
     1246    rtFsIsoUdfTimestamp2TimeSpec(&pCore->BirthTime,         &pFileEntry->BirthTime);
     1247    rtFsIsoUdfTimestamp2TimeSpec(&pCore->ChangeTime,        &pFileEntry->ChangeTime);
     1248
     1249    if (   pFileEntry->uRecordFormat
     1250        || pFileEntry->fRecordDisplayAttribs
     1251        || pFileEntry->cbRecord)
     1252        LogRelMax(45, ("ISO/UDF: uRecordFormat=%#x fRecordDisplayAttribs=%#x cbRecord=%#x\n",
     1253                       pFileEntry->uRecordFormat, pFileEntry->fRecordDisplayAttribs, pFileEntry->cbRecord));
     1254
     1255    /*
     1256     * Conver the file mode.
     1257     */
     1258    int rc = rtFsIsoCore_UdfStuffToFileMode(pFileEntry->IcbTag.fFlags, pFileEntry->IcbTag.bFileType,
     1259                                            pFileEntry->fPermissions, &pCore->fAttrib);
     1260    if (RT_SUCCESS(rc))
     1261    {
     1262        /*
     1263         * Convert extent info.
     1264         */
     1265        rc = rtFsIsoCore_InitExtentsUdfIcbEntry(pCore,
    10111266                                                &pFileEntry->abExtAttribs[pFileEntry->cbExtAttribs],
    10121267                                                pFileEntry->cbAllocDescs,
    10131268                                                pFileEntry->IcbTag.fFlags,
    10141269                                                idxDefaultPart,
    1015                                                   ((uint64_t)pFileEntry->Tag.offTag << pThis->Udf.VolInfo.cShiftBlock)
     1270                                                  ((uint64_t)pFileEntry->Tag.offTag << pVol->Udf.VolInfo.cShiftBlock)
    10161271                                                + RT_OFFSETOF(UDFFILEENTRY, abExtAttribs) + pFileEntry->cbExtAttribs,
    1017                                                 pThis);
    1018     if (RT_FAILURE(rc))
    1019     {
    1020         return rc;
    1021     }
    1022 
    1023 
    1024 
    1025     /*
    1026      * We're good.
    1027      */
    1028     *pcProcessed += 1;
    1029     return VINF_SUCCESS;
    1030 }
    1031 
     1272                                                pVol);
     1273        if (RT_SUCCESS(rc))
     1274        {
     1275            /*
     1276             * We're good.
     1277             */
     1278            *pcProcessed += 1;
     1279            return VINF_SUCCESS;
     1280        }
     1281
     1282        /* Just in case. */
     1283        if (pCore->paExtents)
     1284        {
     1285            RTMemFree(pCore->paExtents);
     1286            pCore->paExtents = NULL;
     1287        }
     1288        pCore->cExtents = 0;
     1289    }
     1290    return rc;
     1291}
     1292
     1293
     1294/**
     1295 * Initialize/update a core object structure from an UDF file entry.
     1296 *
     1297 * @returns IPRT status code
     1298 * @param   pCore           The core object structure to initialize.
     1299 * @param   pFileEntry      The file entry.
     1300 * @param   idxDefaultPart  The default data partition.
     1301 * @param   pcProcessed     Variable to increment on success.
     1302 * @param   pVol            The volume instance.
     1303 */
     1304static int rtFsIsoCore_InitFromUdfIcbFileEntry(PRTFSISOCORE pCore, PCUDFFILEENTRY pFileEntry, uint32_t idxDefaultPart,
     1305                                               uint32_t *pcProcessed, PRTFSISOVOL pVol)
     1306{
     1307#ifdef LOG_ENABLED
     1308    /*
     1309     * Log it.
     1310     */
     1311    if (LogIs2Enabled())
     1312    {
     1313        UDF_LOG2_MEMBER(pFileEntry, "#010RX32",  IcbTag.cEntiresBeforeThis);
     1314        UDF_LOG2_MEMBER(pFileEntry, "#06RX16",  IcbTag.uStrategyType);
     1315        UDF_LOG2_MEMBER(pFileEntry, "#04RX8",   IcbTag.abStrategyParams[0]);
     1316        UDF_LOG2_MEMBER(pFileEntry, "#04RX8",   IcbTag.abStrategyParams[1]);
     1317        UDF_LOG2_MEMBER(pFileEntry, "#06RX16",  IcbTag.cMaxEntries);
     1318        UDF_LOG2_MEMBER(pFileEntry, "#04RX8",   IcbTag.bReserved);
     1319        UDF_LOG2_MEMBER(pFileEntry, "#04RX8",   IcbTag.bFileType);
     1320        UDF_LOG2_MEMBER_LBADDR(pFileEntry,      IcbTag.ParentIcb);
     1321        UDF_LOG2_MEMBER(pFileEntry, "#06RX16",  IcbTag.fFlags);
     1322        UDF_LOG2_MEMBER(pFileEntry, "#010RX32", uid);
     1323        UDF_LOG2_MEMBER(pFileEntry, "#010RX32", gid);
     1324        UDF_LOG2_MEMBER(pFileEntry, "#010RX32", fPermissions);
     1325        UDF_LOG2_MEMBER(pFileEntry, "#06RX16", cHardlinks);
     1326        UDF_LOG2_MEMBER(pFileEntry, "#04RX8", uRecordFormat);
     1327        UDF_LOG2_MEMBER(pFileEntry, "#04RX8", fRecordDisplayAttribs);
     1328        UDF_LOG2_MEMBER(pFileEntry, "#010RX32", cbRecord);
     1329        UDF_LOG2_MEMBER(pFileEntry, "#018RX64", cbData);
     1330        UDF_LOG2_MEMBER(pFileEntry, "#018RX64", cLogicalBlocks);
     1331        UDF_LOG2_MEMBER_TIMESTAMP(pFileEntry, AccessTime);
     1332        UDF_LOG2_MEMBER_TIMESTAMP(pFileEntry, ModificationTime);
     1333        UDF_LOG2_MEMBER_TIMESTAMP(pFileEntry, ChangeTime);
     1334        UDF_LOG2_MEMBER(pFileEntry, "#010RX32", uCheckpoint);
     1335        UDF_LOG2_MEMBER_LONGAD(pFileEntry, ExtAttribIcb);
     1336        UDF_LOG2_MEMBER_ENTITY_ID(pFileEntry, idImplementation);
     1337        UDF_LOG2_MEMBER(pFileEntry, "#018RX64", INodeId);
     1338        UDF_LOG2_MEMBER(pFileEntry, "#010RX32", cbExtAttribs);
     1339        UDF_LOG2_MEMBER(pFileEntry, "#010RX32", cbAllocDescs);
     1340        if (pFileEntry->cbExtAttribs > 0)
     1341            Log2((pFileEntry->cbExtAttribs <= 16 ? "ISO/UDF:   %-32s %.*Rhxs\n" : "ISO/UDF:   %-32s\n%.*RhxD\n",
     1342                  "abExtAttribs:", pFileEntry->cbExtAttribs, pFileEntry->abExtAttribs));
     1343        if (pFileEntry->cbAllocDescs > 0)
     1344            switch (pFileEntry->IcbTag.fFlags & UDF_ICB_FLAGS_AD_TYPE_MASK)
     1345            {
     1346                case UDF_ICB_FLAGS_AD_TYPE_SHORT:
     1347                {
     1348                    PCUDFSHORTAD paDescs = (PCUDFSHORTAD)&pFileEntry->abExtAttribs[pFileEntry->cbExtAttribs];
     1349                    uint32_t     cDescs  = pFileEntry->cbAllocDescs / sizeof(paDescs[0]);
     1350                    for (uint32_t i = 0; i < cDescs; i++)
     1351                        Log2(("ISO/UDF:   ShortAD[%u]:                      %#010RX32 LB %#010RX32; type=%u\n",
     1352                              i, paDescs[i].off, paDescs[i].cb, paDescs[i].uType));
     1353                    break;
     1354                }
     1355                case UDF_ICB_FLAGS_AD_TYPE_LONG:
     1356                {
     1357                    PCUDFLONGAD  paDescs = (PCUDFLONGAD)&pFileEntry->abExtAttribs[pFileEntry->cbExtAttribs];
     1358                    uint32_t     cDescs  = pFileEntry->cbAllocDescs / sizeof(paDescs[0]);
     1359                    for (uint32_t i = 0; i < cDescs; i++)
     1360                        Log2(("ISO/UDF:   LongAD[%u]:                       %#06RX16:%#010RX32 LB %#010RX32; type=%u iu=%.6Rhxs\n",
     1361                              i, paDescs[i].Location.uPartitionNo, paDescs[i].Location.off,
     1362                              paDescs[i].cb, paDescs[i].uType, &paDescs[i].ImplementationUse));
     1363                    break;
     1364                }
     1365                default:
     1366                    Log2(("ISO/UDF:   %-32s Type=%u\n%.*RhxD\n",
     1367                          "abExtAttribs:", pFileEntry->IcbTag.fFlags & UDF_ICB_FLAGS_AD_TYPE_MASK,
     1368                          pFileEntry->cbAllocDescs, &pFileEntry->abExtAttribs[pFileEntry->cbExtAttribs]));
     1369                    break;
     1370            }
     1371    }
     1372#endif
     1373
     1374    /*
     1375     * Basic sanity checking of what we use.
     1376     */
     1377    if (     RT_OFFSETOF(UDFFILEENTRY, abExtAttribs) + pFileEntry->cbExtAttribs + pFileEntry->cbAllocDescs
     1378           > pVol->Udf.VolInfo.cbBlock
     1379        || (pFileEntry->cbExtAttribs & 3) != 0
     1380        || pFileEntry->cbExtAttribs >= pVol->Udf.VolInfo.cbBlock
     1381        || (pFileEntry->cbAllocDescs & 3) != 0
     1382        || pFileEntry->cbAllocDescs >= pVol->Udf.VolInfo.cbBlock)
     1383    {
     1384        LogRelMax(45, ("ISO/UDF: File entry (ICB) is bad size values: cbAllocDesc=%#x cbExtAttribs=%#x (cbBlock=%#x)\n",
     1385                       pFileEntry->cbAllocDescs, pFileEntry->cbExtAttribs, pVol->Udf.VolInfo.cbBlock));
     1386        return VERR_ISOFS_BAD_FILE_ENTRY;
     1387    }
     1388
     1389    //pCore->uid        = pFileEntry->uid;
     1390    //pCore->gid        = pFileEntry->gid;
     1391    //pCore->cHardlinks = RT_MIN(pFileEntry->cHardlinks, 1);
     1392    pCore->cbObject     = pFileEntry->cbData;
     1393    //pCore->cbAllocated = pFileEntry->cLogicalBlocks << pVol->Udf.VolInfo.cShiftBlock;
     1394    //pCore->idINode    = pFileEntry->INodeId;
     1395
     1396    rtFsIsoUdfTimestamp2TimeSpec(&pCore->AccessTime,        &pFileEntry->AccessTime);
     1397    rtFsIsoUdfTimestamp2TimeSpec(&pCore->ModificationTime,  &pFileEntry->ModificationTime);
     1398    rtFsIsoUdfTimestamp2TimeSpec(&pCore->ChangeTime,        &pFileEntry->ChangeTime);
     1399    pCore->BirthTime = pCore->ModificationTime;
     1400    if (RTTimeSpecCompare(&pCore->BirthTime, &pCore->ChangeTime) > 0)
     1401        pCore->BirthTime = pCore->ChangeTime;
     1402    if (RTTimeSpecCompare(&pCore->BirthTime, &pCore->AccessTime) > 0)
     1403        pCore->BirthTime = pCore->AccessTime;
     1404
     1405    if (   pFileEntry->uRecordFormat
     1406        || pFileEntry->fRecordDisplayAttribs
     1407        || pFileEntry->cbRecord)
     1408        LogRelMax(45, ("ISO/UDF: uRecordFormat=%#x fRecordDisplayAttribs=%#x cbRecord=%#x\n",
     1409                       pFileEntry->uRecordFormat, pFileEntry->fRecordDisplayAttribs, pFileEntry->cbRecord));
     1410
     1411    /*
     1412     * Conver the file mode.
     1413     */
     1414    int rc = rtFsIsoCore_UdfStuffToFileMode(pFileEntry->IcbTag.fFlags, pFileEntry->IcbTag.bFileType,
     1415                                            pFileEntry->fPermissions, &pCore->fAttrib);
     1416    if (RT_SUCCESS(rc))
     1417    {
     1418        /*
     1419         * Convert extent info.
     1420         */
     1421        rc = rtFsIsoCore_InitExtentsUdfIcbEntry(pCore,
     1422                                                &pFileEntry->abExtAttribs[pFileEntry->cbExtAttribs],
     1423                                                pFileEntry->cbAllocDescs,
     1424                                                pFileEntry->IcbTag.fFlags,
     1425                                                idxDefaultPart,
     1426                                                  ((uint64_t)pFileEntry->Tag.offTag << pVol->Udf.VolInfo.cShiftBlock)
     1427                                                + RT_OFFSETOF(UDFFILEENTRY, abExtAttribs) + pFileEntry->cbExtAttribs,
     1428                                                pVol);
     1429        if (RT_SUCCESS(rc))
     1430        {
     1431            /*
     1432             * We're good.
     1433             */
     1434            *pcProcessed += 1;
     1435            return VINF_SUCCESS;
     1436        }
     1437
     1438        /* Just in case. */
     1439        if (pCore->paExtents)
     1440        {
     1441            RTMemFree(pCore->paExtents);
     1442            pCore->paExtents = NULL;
     1443        }
     1444        pCore->cExtents = 0;
     1445    }
     1446    return rc;
     1447}
     1448
     1449
     1450/**
     1451 * Recursive helper for rtFsIsoCore_InitFromUdfIcbAndFileIdDesc.
     1452 *
     1453 * @returns IRPT status code.
     1454 * @param   pCore           The core structure to initialize.
     1455 * @param   AllocDesc       The ICB allocation descriptor.
     1456 * @param   pbBuf           The buffer, one logical block in size.
     1457 * @param   cNestings       The number of recursive nestings (should be zero).
     1458 * @param   pcProcessed     Variable to update when we've processed something
     1459 *                          useful.
     1460 * @param   pcIndirections  Variable tracing the number of indirections we've
     1461 *                          taken during the processing.  This is used to
     1462 *                          prevent us from looping forever on a bad chain
     1463 * @param   pVol            The volue instance data.
     1464 */
    10321465static int rtFsIsoCore_InitFromUdfIcbRecursive(PRTFSISOCORE pCore, UDFLONGAD AllocDesc, uint8_t *pbBuf, uint32_t cNestings,
    1033                                                uint32_t *pcProcessed, uint32_t *pcIndirections, PRTFSISOVOL pThis)
     1466                                               uint32_t *pcProcessed, uint32_t *pcIndirections, PRTFSISOVOL pVol)
    10341467{
    10351468    if (cNestings >= 8)
     
    10611494         * Process it block by block.
    10621495         */
    1063         uint32_t cBlocks = (AllocDesc.cb + pThis->Udf.VolInfo.cbBlock - 1) >> pThis->Udf.VolInfo.cShiftBlock;
     1496        uint32_t cBlocks = (AllocDesc.cb + pVol->Udf.VolInfo.cbBlock - 1) >> pVol->Udf.VolInfo.cShiftBlock;
    10641497        for (uint32_t idxBlock = 0; ; idxBlock++)
    10651498        {
     
    10671500             * Read a block
    10681501             */
    1069             size_t cbToRead = RT_MIN(pThis->Udf.VolInfo.cbBlock, AllocDesc.cb);
    1070             int rc = rtFsIsoVolUdfVpRead(pThis, AllocDesc.Location.uPartitionNo, AllocDesc.Location.off + idxBlock, 0,
     1502            size_t cbToRead = RT_MIN(pVol->Udf.VolInfo.cbBlock, AllocDesc.cb);
     1503            int rc = rtFsIsoVolUdfVpRead(pVol, AllocDesc.Location.uPartitionNo, AllocDesc.Location.off + idxBlock, 0,
    10711504                                         pbBuf, cbToRead);
    10721505            if (RT_FAILURE(rc))
    10731506                return rc;
    1074             if (cbToRead < pThis->Udf.VolInfo.cbBlock)
    1075                 RT_BZERO(&pbBuf[cbToRead], pThis->Udf.VolInfo.cbBlock - cbToRead);
     1507            if (cbToRead < pVol->Udf.VolInfo.cbBlock)
     1508                RT_BZERO(&pbBuf[cbToRead], pVol->Udf.VolInfo.cbBlock - cbToRead);
    10761509
    10771510            /*
     
    10791512             */
    10801513            PUDFICBHDR pHdr = (PUDFICBHDR)pbBuf;
    1081             rc = rtFsIsoVolValidateUdfDescTagAndCrc(&pHdr->Tag, pThis->Udf.VolInfo.cbBlock, UINT16_MAX,
     1514            rc = rtFsIsoVolValidateUdfDescTagAndCrc(&pHdr->Tag, pVol->Udf.VolInfo.cbBlock, UINT16_MAX,
    10821515                                                    AllocDesc.Location.off + idxBlock, NULL);
    10831516            if (RT_FAILURE(rc))
     
    10881521             */
    10891522            if (pHdr->Tag.idTag == UDF_TAG_ID_FILE_ENTRY)
    1090             {
    1091                 Log2(("ISO/UDF: ICB: File entry\n"));
    10921523                rc = rtFsIsoCore_InitFromUdfIcbFileEntry(pCore, (PCUDFFILEENTRY)pHdr, AllocDesc.Location.uPartitionNo,
    1093                                                          pcProcessed, pThis);
    1094             }
     1524                                                         pcProcessed, pVol);
    10951525            else if (pHdr->Tag.idTag == UDF_TAG_ID_EXTENDED_FILE_ENTRY)
    1096             {
    1097                 Log2(("ISO/UDF: ICB: Extended file entry\n"));
    1098                 //UDFEXFILEENTRY
    1099                 //*pcProcessed += 1;
    1100             }
     1526                rc = rtFsIsoCore_InitFromUdfIcbExFileEntry(pCore, (PCUDFEXFILEENTRY)pHdr, AllocDesc.Location.uPartitionNo,
     1527                                                           pcProcessed, pVol);
    11011528            else if (pHdr->Tag.idTag == UDF_TAG_ID_INDIRECT_ENTRY)
    11021529            {
     
    11161543                          pIndir->IndirectIcb.cb, pIndir->IndirectIcb.uType));
    11171544                    rc = rtFsIsoCore_InitFromUdfIcbRecursive(pCore, pIndir->IndirectIcb, pbBuf, cNestings,
    1118                                                              pcProcessed, pcIndirections, pThis);
     1545                                                             pcProcessed, pcIndirections, pVol);
    11191546                }
    11201547                else
     
    11481575        /* If we get here, we've jumped thru an indirect entry. */
    11491576    }
    1150 
    11511577    /* never reached */
    11521578}
     
    11541580
    11551581
     1582/**
     1583 * Initialize a core structure from an UDF ICB range and optionally a file ID.
     1584 *
     1585 * @returns IPRT status code.
     1586 * @param   pCore               The core structure to initialize.
     1587 *                              Caller must've ZEROed this structure!
     1588 * @param   pAllocDesc          The ICB allocation descriptor.
     1589 * @param   pFileIdDesc         The file ID descriptor.  Optional.
     1590 * @param   pVol                The instance.
     1591 */
    11561592static int rtFsIsoCore_InitFromUdfIcbAndFileIdDesc(PRTFSISOCORE pCore, PCUDFLONGAD pAllocDesc,
    1157                                                    PCUDFFILEIDDESC pFileIdDesc, PRTFSISOVOL pThis)
    1158 {
     1593                                                   PCUDFFILEIDDESC pFileIdDesc, PRTFSISOVOL pVol)
     1594{
     1595    Assert(pCore->cRefs == 0);
     1596    Assert(pCore->cExtents == 0);
     1597    Assert(pCore->paExtents == NULL);
     1598    Assert(pCore->pVol == NULL);
     1599
    11591600RT_NOREF(pFileIdDesc);
    11601601    if (pAllocDesc->cb > _64K)
     
    11661607     * Allocate a temporary buffer, one logical block in size.
    11671608     */
    1168     uint8_t * const pbBuf = (uint8_t *)RTMemTmpAlloc(pThis->Udf.VolInfo.cbBlock);
     1609    uint8_t * const pbBuf = (uint8_t *)RTMemTmpAlloc(pVol->Udf.VolInfo.cbBlock);
    11691610    if (pbBuf)
    11701611    {
    11711612        uint32_t cProcessed = 0;
    11721613        uint32_t cIndirections = 0;
    1173         int rc = rtFsIsoCore_InitFromUdfIcbRecursive(pCore, *pAllocDesc, pbBuf, 0, &cProcessed, &cIndirections, pThis);
     1614        int rc = rtFsIsoCore_InitFromUdfIcbRecursive(pCore, *pAllocDesc, pbBuf, 0, &cProcessed, &cIndirections, pVol);
    11741615        RTMemTmpFree(pbBuf);
    11751616        if (RT_SUCCESS(rc))
    11761617        {
    11771618            if (cProcessed > 0)
     1619            {
     1620                pCore->cRefs = 1;
     1621                pCore->pVol  = pVol;
    11781622                return VINF_SUCCESS;
     1623            }
    11791624            rc = VERR_ISOFS_NO_DIRECT_ICB_ENTRIES;
    11801625        }
    11811626        return rc;
    11821627    }
     1628
     1629    pCore->pVol = NULL;
    11831630    return VERR_NO_TMP_MEMORY;
    11841631}
     1632
     1633
     1634/**
     1635 * Simple UDF read function.
     1636 *
     1637 * This deals with extent mappings as well as virtual partition related block
     1638 * mapping and such.
     1639 *
     1640 * @returns VBox status code.
     1641 * @param   pCore           The core object to read data from.
     1642 * @param   offRead         The offset to start reading at.
     1643 * @param   pvBuf           The output buffer.
     1644 * @param   cbToRead        The number of bytes to read.
     1645 * @param   pcbRead         Where to return the number of bytes read.
     1646 */
     1647static int rtFsIsoVolUdfExtentRead(PRTFSISOCORE pCore, uint64_t offRead, void *pvBuf, size_t cbToRead, size_t *pcbRead)
     1648{
     1649    /*
     1650     * Check for EOF.
     1651     */
     1652    if (offRead >= pCore->cbObject)
     1653    {
     1654        if (pcbRead)
     1655        {
     1656            *pcbRead = 0;
     1657            return VINF_EOF;
     1658        }
     1659        return VERR_EOF;
     1660    }
     1661    if (   cbToRead           > pCore->cbObject
     1662        || offRead + cbToRead > pCore->cbObject)
     1663    {
     1664        if (!pcbRead)
     1665            return VERR_EOF;
     1666        cbToRead = pCore->cbObject - offRead;
     1667    }
     1668
     1669    /*
     1670     * Don't bother looking up the extent if we're not going to
     1671      * read anything from it.
     1672     */
     1673    if (cbToRead == 0)
     1674    {
     1675        if (pcbRead)
     1676            *pcbRead = 0;
     1677        return VINF_SUCCESS;
     1678    }
     1679
     1680    /*
     1681     * Locate the first extent.
     1682     */
     1683    uint64_t        offExtent  = 0;
     1684    uint32_t        iExtent    = 0;
     1685    PCRTFSISOEXTENT pCurExtent = &pCore->FirstExtent;
     1686    if (offRead < pCurExtent->cbExtent)
     1687    { /* likely */ }
     1688    else
     1689        do
     1690        {
     1691            offExtent += pCurExtent->cbExtent;
     1692            pCurExtent = &pCore->paExtents[iExtent++];
     1693            if (iExtent >= pCore->cExtents)
     1694            {
     1695                memset(pvBuf, 0, cbToRead);
     1696                return VINF_SUCCESS;
     1697            }
     1698        } while (offExtent < offRead);
     1699    Assert(offRead - offExtent < pCurExtent->cbExtent);
     1700
     1701    /*
     1702     * Do the reading part.
     1703     */
     1704    PRTFSISOVOL pVol     = pCore->pVol;
     1705    uint64_t    cbActual = 0;
     1706    for (;;)
     1707    {
     1708        uint64_t offIntoExtent = offRead - offExtent;
     1709        size_t   cbThisRead = pCurExtent->cbExtent - offIntoExtent;
     1710        if (cbThisRead > cbToRead)
     1711            cbThisRead = cbToRead;
     1712
     1713        if (pCurExtent->off == UINT64_MAX)
     1714            RT_BZERO(pvBuf, cbThisRead);
     1715        else
     1716        {
     1717            int rc;
     1718            if (pCurExtent->idxPart == UINT16_MAX)
     1719                rc = RTVfsFileReadAt(pVol->hVfsBacking, pCurExtent->off + offIntoExtent, pvBuf, cbThisRead, NULL);
     1720            else
     1721            {
     1722                Assert(pVol->enmType == RTFSISOVOLTYPE_UDF);
     1723                if (pCurExtent->idxPart < pVol->Udf.VolInfo.cPartitions)
     1724                {
     1725                    PRTFSISOVOLUDFPMAP pPart = &pVol->Udf.VolInfo.paPartitions[pCurExtent->idxPart];
     1726                    switch (pPart->bType)
     1727                    {
     1728                        case RTFSISO_UDF_PMAP_T_PLAIN:
     1729                            rc = RTVfsFileReadAt(pVol->hVfsBacking, pPart->offByteLocation + pCurExtent->off + offIntoExtent,
     1730                                                 pvBuf, cbThisRead, NULL);
     1731                            break;
     1732                        default:
     1733                            AssertFailed();
     1734                            rc = VERR_ISOFS_IPE_1;
     1735                            break;
     1736                    }
     1737                }
     1738                else
     1739                {
     1740                    Log(("ISO/UDF: Invalid partition index %#x (offset %#RX64), max partitions %#x; iExtent=%#x\n",
     1741                         pCurExtent->idxPart, pCurExtent->off + offIntoExtent, pVol->Udf.VolInfo.cPartitions, iExtent));
     1742                    rc = VERR_ISOFS_INVALID_PARTITION_INDEX;
     1743                }
     1744            }
     1745            if (RT_FAILURE(rc))
     1746            {
     1747                if (pcbRead)
     1748                    *pcbRead = cbActual;
     1749                return rc;
     1750            }
     1751        }
     1752
     1753        /*
     1754         * Advance to the next extent.
     1755         */
     1756        cbActual += cbActual;
     1757        cbToRead -= cbThisRead;
     1758        if (!cbToRead)
     1759        {
     1760            if (pcbRead)
     1761                *pcbRead = cbActual;
     1762            return VINF_SUCCESS;
     1763        }
     1764        pvBuf = (uint8_t *)pvBuf + cbThisRead;
     1765
     1766        offExtent += pCurExtent->cbExtent;
     1767        pCurExtent = &pCore->paExtents[iExtent++];
     1768        if (iExtent >= pCore->cExtents)
     1769        {
     1770            memset(pvBuf, 0, cbToRead);
     1771            return VINF_SUCCESS;
     1772        }
     1773    }
     1774}
     1775
    11851776
    11861777
     
    26523243                if (pShared->pbDir)
    26533244                {
    2654                     rc = RTVfsFileReadAt(pThis->hVfsBacking, pShared->Core.FirstExtent.off, pShared->pbDir, pShared->cbDir, NULL);
     3245                    rc = rtFsIsoVolUdfExtentRead(&pShared->Core, 0, pShared->pbDir, pShared->cbDir, NULL);
    26553246                    if (RT_SUCCESS(rc))
    26563247                    {
     3248                        Log3(("ISO/UDF: Directory content\n%.*RhxD\n", pShared->cbDir, pShared->pbDir));
    26573249#ifdef LOG_ENABLED
    26583250                        //rtFsIsoDirShrd_Log9660Content(pShared);
     
    46425234     * If we found a UDF VRS and are interested in UDF, we have more work to do here.
    46435235     */
    4644 #if 0
     5236#if defined(DEBUG_bird) && 0
    46455237    if (uUdfLevel > 0 && !(fFlags & RTFSISO9660_F_NO_UDF) )// && /* Just disable this code for now: */ (fFlags & RT_BIT(24)))
    46465238    {
     
    46715263                                   NULL /*pFileIdDesc*/, &pThis->pRootDir);
    46725264        /** @todo fall back on failure? */
     5265        if (RT_SUCCESS(rc))
     5266            rc = VERR_NOT_IMPLEMENTED;
    46735267        return rc;
    46745268    }
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette