Changeset 69029 in vbox for trunk/src/VBox/Runtime/common/fs
- Timestamp:
- Oct 10, 2017 8:33:05 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 118304
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fs/isovfs.cpp
r69027 r69029 99 99 : (a_pStruct)->a_Member.uType == UDF_AD_TYPE_FREE ? "free" : "next", \ 100 100 (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)) 101 104 102 105 #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 ":", \ 104 107 (a_pStruct)->a_Member.iYear, (a_pStruct)->a_Member.uMonth, (a_pStruct)->a_Member.uDay, \ 105 108 (a_pStruct)->a_Member.uHour, (a_pStruct)->a_Member.uMinute, (a_pStruct)->a_Member.uSecond, \ 106 109 (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 )) 108 111 #define UDF_LOG2_MEMBER_CHARSPEC(a_pStruct, a_Member) \ 109 112 do { \ … … 475 478 * @param offByteAddend The byte offset relative to the block. 476 479 * @param pvBuf The output buffer. 477 * @param cb BufThe number of bytes to read.480 * @param cbToRead The number of bytes to read. 478 481 */ 479 482 static int rtFsIsoVolUdfVpRead(PRTFSISOVOL pThis, uint32_t idxPart, uint32_t idxBlock, uint64_t offByteAddend, … … 677 680 678 681 /** 679 * Converts a ISO 9660 binary timestamp into an IPRT timesspec.682 * Converts an ISO 9660 binary timestamp into an IPRT timesspec. 680 683 * 681 684 * @param pTimeSpec Where to return the IRPT time. … … 701 704 if (RT_ABS(pIso9660->offUtc) <= 13*4) 702 705 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 */ 715 static 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); 703 744 } 704 745 … … 795 836 } 796 837 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 814 838 815 839 /** … … 817 841 * 818 842 * @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. 826 851 */ 827 852 static int rtFsIsoCore_InitExtentsUdfIcbEntry(PRTFSISOCORE pCore, uint8_t const *pbAllocDescs, uint32_t cbAllocDescs, 828 853 uint32_t fIcbTagFlags, uint32_t idxDefaultPart, uint64_t offAllocDescs, 829 PRTFSISOVOL p This)854 PRTFSISOVOL pVol) 830 855 { 831 856 /* … … 909 934 idxPart = uPtr.pExt->Location.uPartitionNo; 910 935 cbAllocDescs -= uPtr.pExt->cbInformation; 911 uPtr.pb += uPtr.pExt->cbInformation;936 uPtr.pb += uPtr.pExt->cbInformation; 912 937 break; 913 938 default: … … 917 942 /* Check if we can extend the current extent. This is useful since 918 943 the descriptors can typically only cover 1GB. */ 919 uint64_t const off = (uint64_t)idxBlock << p This->Udf.VolInfo.cShiftBlock;944 uint64_t const off = (uint64_t)idxBlock << pVol->Udf.VolInfo.cShiftBlock; 920 945 if ( pCurExtent != NULL 921 946 && ( pCurExtent->off != UINT64_MAX … … 986 1011 987 1012 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 */ 1023 static 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 */ 1148 static 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 991 1222 /* 992 1223 * Basic sanity checking of what we use. 993 1224 */ 994 1225 if ( RT_OFFSETOF(UDFFILEENTRY, abExtAttribs) + pFileEntry->cbExtAttribs + pFileEntry->cbAllocDescs 995 > p This->Udf.VolInfo.cbBlock1226 > pVol->Udf.VolInfo.cbBlock 996 1227 || (pFileEntry->cbExtAttribs & 3) != 0 997 || pFileEntry->cbExtAttribs >= p This->Udf.VolInfo.cbBlock1228 || pFileEntry->cbExtAttribs >= pVol->Udf.VolInfo.cbBlock 998 1229 || (pFileEntry->cbAllocDescs & 3) != 0 999 || pFileEntry->cbAllocDescs >= p This->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, p This->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)); 1003 1234 return VERR_ISOFS_BAD_FILE_ENTRY; 1004 1235 } 1005 1236 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, 1011 1266 &pFileEntry->abExtAttribs[pFileEntry->cbExtAttribs], 1012 1267 pFileEntry->cbAllocDescs, 1013 1268 pFileEntry->IcbTag.fFlags, 1014 1269 idxDefaultPart, 1015 ((uint64_t)pFileEntry->Tag.offTag << p This->Udf.VolInfo.cShiftBlock)1270 ((uint64_t)pFileEntry->Tag.offTag << pVol->Udf.VolInfo.cShiftBlock) 1016 1271 + 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 */ 1304 static 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 */ 1032 1465 static int rtFsIsoCore_InitFromUdfIcbRecursive(PRTFSISOCORE pCore, UDFLONGAD AllocDesc, uint8_t *pbBuf, uint32_t cNestings, 1033 uint32_t *pcProcessed, uint32_t *pcIndirections, PRTFSISOVOL p This)1466 uint32_t *pcProcessed, uint32_t *pcIndirections, PRTFSISOVOL pVol) 1034 1467 { 1035 1468 if (cNestings >= 8) … … 1061 1494 * Process it block by block. 1062 1495 */ 1063 uint32_t cBlocks = (AllocDesc.cb + p This->Udf.VolInfo.cbBlock - 1) >> pThis->Udf.VolInfo.cShiftBlock;1496 uint32_t cBlocks = (AllocDesc.cb + pVol->Udf.VolInfo.cbBlock - 1) >> pVol->Udf.VolInfo.cShiftBlock; 1064 1497 for (uint32_t idxBlock = 0; ; idxBlock++) 1065 1498 { … … 1067 1500 * Read a block 1068 1501 */ 1069 size_t cbToRead = RT_MIN(p This->Udf.VolInfo.cbBlock, AllocDesc.cb);1070 int rc = rtFsIsoVolUdfVpRead(p This, 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, 1071 1504 pbBuf, cbToRead); 1072 1505 if (RT_FAILURE(rc)) 1073 1506 return rc; 1074 if (cbToRead < p This->Udf.VolInfo.cbBlock)1075 RT_BZERO(&pbBuf[cbToRead], p This->Udf.VolInfo.cbBlock - cbToRead);1507 if (cbToRead < pVol->Udf.VolInfo.cbBlock) 1508 RT_BZERO(&pbBuf[cbToRead], pVol->Udf.VolInfo.cbBlock - cbToRead); 1076 1509 1077 1510 /* … … 1079 1512 */ 1080 1513 PUDFICBHDR pHdr = (PUDFICBHDR)pbBuf; 1081 rc = rtFsIsoVolValidateUdfDescTagAndCrc(&pHdr->Tag, p This->Udf.VolInfo.cbBlock, UINT16_MAX,1514 rc = rtFsIsoVolValidateUdfDescTagAndCrc(&pHdr->Tag, pVol->Udf.VolInfo.cbBlock, UINT16_MAX, 1082 1515 AllocDesc.Location.off + idxBlock, NULL); 1083 1516 if (RT_FAILURE(rc)) … … 1088 1521 */ 1089 1522 if (pHdr->Tag.idTag == UDF_TAG_ID_FILE_ENTRY) 1090 {1091 Log2(("ISO/UDF: ICB: File entry\n"));1092 1523 rc = rtFsIsoCore_InitFromUdfIcbFileEntry(pCore, (PCUDFFILEENTRY)pHdr, AllocDesc.Location.uPartitionNo, 1093 pcProcessed, pThis); 1094 } 1524 pcProcessed, pVol); 1095 1525 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); 1101 1528 else if (pHdr->Tag.idTag == UDF_TAG_ID_INDIRECT_ENTRY) 1102 1529 { … … 1116 1543 pIndir->IndirectIcb.cb, pIndir->IndirectIcb.uType)); 1117 1544 rc = rtFsIsoCore_InitFromUdfIcbRecursive(pCore, pIndir->IndirectIcb, pbBuf, cNestings, 1118 pcProcessed, pcIndirections, p This);1545 pcProcessed, pcIndirections, pVol); 1119 1546 } 1120 1547 else … … 1148 1575 /* If we get here, we've jumped thru an indirect entry. */ 1149 1576 } 1150 1151 1577 /* never reached */ 1152 1578 } … … 1154 1580 1155 1581 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 */ 1156 1592 static 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 1159 1600 RT_NOREF(pFileIdDesc); 1160 1601 if (pAllocDesc->cb > _64K) … … 1166 1607 * Allocate a temporary buffer, one logical block in size. 1167 1608 */ 1168 uint8_t * const pbBuf = (uint8_t *)RTMemTmpAlloc(p This->Udf.VolInfo.cbBlock);1609 uint8_t * const pbBuf = (uint8_t *)RTMemTmpAlloc(pVol->Udf.VolInfo.cbBlock); 1169 1610 if (pbBuf) 1170 1611 { 1171 1612 uint32_t cProcessed = 0; 1172 1613 uint32_t cIndirections = 0; 1173 int rc = rtFsIsoCore_InitFromUdfIcbRecursive(pCore, *pAllocDesc, pbBuf, 0, &cProcessed, &cIndirections, p This);1614 int rc = rtFsIsoCore_InitFromUdfIcbRecursive(pCore, *pAllocDesc, pbBuf, 0, &cProcessed, &cIndirections, pVol); 1174 1615 RTMemTmpFree(pbBuf); 1175 1616 if (RT_SUCCESS(rc)) 1176 1617 { 1177 1618 if (cProcessed > 0) 1619 { 1620 pCore->cRefs = 1; 1621 pCore->pVol = pVol; 1178 1622 return VINF_SUCCESS; 1623 } 1179 1624 rc = VERR_ISOFS_NO_DIRECT_ICB_ENTRIES; 1180 1625 } 1181 1626 return rc; 1182 1627 } 1628 1629 pCore->pVol = NULL; 1183 1630 return VERR_NO_TMP_MEMORY; 1184 1631 } 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 */ 1647 static 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 1185 1776 1186 1777 … … 2652 3243 if (pShared->pbDir) 2653 3244 { 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); 2655 3246 if (RT_SUCCESS(rc)) 2656 3247 { 3248 Log3(("ISO/UDF: Directory content\n%.*RhxD\n", pShared->cbDir, pShared->pbDir)); 2657 3249 #ifdef LOG_ENABLED 2658 3250 //rtFsIsoDirShrd_Log9660Content(pShared); … … 4642 5234 * If we found a UDF VRS and are interested in UDF, we have more work to do here. 4643 5235 */ 4644 #if 05236 #if defined(DEBUG_bird) && 0 4645 5237 if (uUdfLevel > 0 && !(fFlags & RTFSISO9660_F_NO_UDF) )// && /* Just disable this code for now: */ (fFlags & RT_BIT(24))) 4646 5238 { … … 4671 5263 NULL /*pFileIdDesc*/, &pThis->pRootDir); 4672 5264 /** @todo fall back on failure? */ 5265 if (RT_SUCCESS(rc)) 5266 rc = VERR_NOT_IMPLEMENTED; 4673 5267 return rc; 4674 5268 }
Note:
See TracChangeset
for help on using the changeset viewer.