Changeset 69013 in vbox for trunk/src/VBox/Runtime/common/fs
- Timestamp:
- Oct 9, 2017 12:08:12 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fs/isovfs.cpp
r68991 r69013 49 49 #include <iprt/formats/udf.h> 50 50 51 /** @todo move to err.h: */ 52 #define VERR_ISOFS_IPE_0 (-25390) 51 53 52 54 … … 176 178 177 179 /** Pointer to info about a UDF volume. */ 178 typedef struct RTFSISOVOLUDFVOL *PRTFSISOVOLUDFVOL; 180 typedef struct RTFSISOUDFVOLINFO *PRTFSISOUDFVOLINFO; 181 182 183 /** @name RTFSISO_UDF_PMAP_T_XXX 184 * @{ */ 185 #define RTFSISO_UDF_PMAP_T_PLAIN 1 186 #define RTFSISO_UDF_PMAP_T_VPM_15 2 187 #define RTFSISO_UDF_PMAP_T_VPM_20 3 188 #define RTFSISO_UDF_PMAP_T_SPM 4 189 #define RTFSISO_UDF_PMAP_T_MPM 5 190 /** @} */ 179 191 180 192 /** … … 184 196 * and the UDFPARTMAPTYPE2 structure. 185 197 */ 186 typedef struct RTFSISOVOLUDFPART 187 { 188 /** Partition number (not index). */ 189 uint16_t uPartitionNo; 190 /** Parition flags (UDF_PARTITION_FLAGS_XXX). */ 191 uint16_t fFlags; 192 /** Number of sectors. */ 193 uint32_t cSectors; 198 typedef struct RTFSISOVOLUDFPMAP 199 { 194 200 /** Partition starting location as a byte offset. */ 195 201 uint64_t offByteLocation; 196 202 /** Partition starting location (logical sector number). */ 197 203 uint32_t offLocation; 204 /** Number of sectors. */ 205 uint32_t cSectors; 206 207 /** Partition descriptor index (for processing). */ 208 uint16_t idxPartDesc; 209 /** Offset info the map table. */ 210 uint16_t offMapTable; 211 /** Partition number (not index). */ 212 uint16_t uPartitionNo; 213 /** Partition number (not index). */ 214 uint16_t uVolumeSeqNo; 215 216 /** The access type (UDF_PART_ACCESS_TYPE_XXX). */ 217 uint32_t uAccessType; 218 /** Partition flags (UDF_PARTITION_FLAGS_XXX). */ 219 uint16_t fFlags; 220 /** RTFSISO_UDF_PMAP_T_XXX. */ 221 uint8_t bType; 198 222 /** Set if Hdr is valid. */ 199 223 bool fHaveHdr; … … 201 225 UDFPARTITIONHDRDESC Hdr; 202 226 203 /** Pointer to the volume this partition belongs to. */ 204 PRTFSISOVOLUDFVOL pVol; 205 } RTFSISOVOLUDFPART; 206 typedef RTFSISOVOLUDFPART *PRTFSISOVOLUDFPART; 227 } RTFSISOVOLUDFPMAP; 228 typedef RTFSISOVOLUDFPMAP *PRTFSISOVOLUDFPMAP; 207 229 208 230 /** … … 214 236 * implementation. So, this can be considered a volume and a volume set. 215 237 */ 216 typedef struct RTFSISO VOLUDFVOL238 typedef struct RTFSISOUDFVOLINFO 217 239 { 218 240 /** The extent containing the file set descriptor. */ 219 241 UDFLONGAD FileSetDescriptor; 220 242 243 /** The root directory location (from the file set descriptor). */ 244 UDFLONGAD RootDirIcb; 245 /** Location of the system stream directory associated with the file set. */ 246 UDFLONGAD SystemStreamDirIcb; 247 221 248 /** The logical block size on this volume. */ 222 249 uint32_t cbBlock; 223 /** Primary volume descriptor number. */ 224 uint32_t uPrimaryVolumeDescNo; 225 /** Volume sequence number. */ 226 uint16_t uVolumeSeqNo; 227 /** Maximum volume sequence number. */ 228 uint16_t uMaxVolumeSeqNo; 250 /** The log2 of cbBlock. */ 251 uint32_t cShiftBlock; 229 252 /** Flags (UDF_PVD_FLAGS_XXX). */ 230 253 uint16_t fFlags; 231 254 232 /** Number of partitions in this volume. */255 /** Number of partitions mapp in this volume. */ 233 256 uint16_t cPartitions; 234 257 /** Partitions in this volume. */ 235 PRTFSISOVOLUDFPART paPartitions; 236 237 /** Volume identifier (dstring). */ 238 UDFDSTRING achVolumeID[32]; 258 PRTFSISOVOLUDFPMAP paPartitions; 259 239 260 /** The volume ID string. */ 240 261 UDFDSTRING achLogicalVolumeID[128]; 241 } RTFSISOVOLUDFVOL; 242 262 } RTFSISOUDFVOLINFO; 263 264 265 /** 266 * Indicates which of the possible content types we're accessing. 267 */ 268 typedef enum RTFSISOVOLTYPE 269 { 270 /** Accessing the primary ISO-9660 volume. */ 271 RTFSISOVOLTYPE_ISO9960 = 0, 272 /** Accessing the joliet volume (secondary ISO-9660). */ 273 RTFSISOVOLTYPE_JOLIET, 274 /** Accessing the UDF volume. */ 275 RTFSISOVOLTYPE_UDF 276 } RTFSISOVOLTYPE; 243 277 244 278 /** … … 259 293 /** The sector size (in bytes). */ 260 294 uint32_t cbSector; 295 /** What we're accessing. */ 296 RTFSISOVOLTYPE enmType; 261 297 262 298 /** @name ISO 9660 specific data … … 279 315 struct 280 316 { 281 /** Offset of the Anchor volume descriptor sequence. */ 282 uint64_t offAvdp; 283 /** Length of the anchor volume descriptor sequence. */ 284 uint32_t cbAvdp; 317 /** Volume information. */ 318 RTFSISOUDFVOLINFO VolInfo; 285 319 /** The UDF level. */ 286 uint8_t uLevel; 287 /** Number of volume sets. */ 288 uint8_t cVolumeSets; 289 /** Number of entries in the array paPartitions points to. */ 290 uint8_t cPartitions; 291 /** Set if we already seen the primary volume descriptor. */ 292 bool fSeenPrimaryDesc : 1; 293 /** Partitions. */ 294 PRTFSISOVOLUDFPART paPartitions; 295 296 #if 0 297 /** Volume sets. */ 298 struct 299 { 300 /** Number of partitions in the set. */ 301 uint16_t cPartitions; 302 303 304 } aVolumeSets[1]; 305 306 #endif 307 } udf; 320 uint8_t uLevel; 321 } Udf; 308 322 309 323 /** The root directory shared data. */ … … 311 325 } RTFSISOVOL; 312 326 327 328 /** 329 * Info gathered from a VDS sequence. 330 */ 331 typedef struct RTFSISOVDSINFO 332 { 333 /** Number of entries in apPrimaryVols. */ 334 uint32_t cPrimaryVols; 335 /** Number of entries in apLogicalVols. */ 336 uint32_t cLogicalVols; 337 /** Number of entries in apPartitions. */ 338 uint32_t cPartitions; 339 /** Pointer to primary volume descriptors (native endian). */ 340 PUDFPRIMARYVOLUMEDESC apPrimaryVols[8]; 341 /** Pointer to logical volume descriptors (native endian). */ 342 PUDFLOGICALVOLUMEDESC apLogicalVols[8]; 343 /** Pointer to partition descriptors (native endian). */ 344 PUDFPARTITIONDESC apPartitions[16]; 345 346 /** Created after scanning the sequence (here for cleanup purposes). */ 347 PRTFSISOVOLUDFPMAP paPartMaps; 348 } RTFSISOVDSINFO; 349 /** Pointer to VDS sequence info. */ 350 typedef RTFSISOVDSINFO *PRTFSISOVDSINFO; 351 352 353 354 /********************************************************************************************************************************* 355 * Defined Constants And Macros * 356 *********************************************************************************************************************************/ 357 /** Check if an entity ID field equals the given ID string. */ 358 #define UDF_ENTITY_ID_EQUALS(a_pEntityId, a_szId) \ 359 ( memcmp(&(a_pEntityId)->achIdentifier[0], a_szId, RT_MIN(sizeof(a_szId), sizeof(a_pEntityId)->achIdentifier)) == 0 ) 360 /** Checks if a character set indicator indicates OSTA compressed unicode. */ 361 #define UDF_IS_CHAR_SET_OSTA(a_pCharSet) \ 362 ( (a_pCharSet)->uType == UDF_CHAR_SET_OSTA_COMPRESSED_UNICODE \ 363 && memcmp((a_pCharSet)->abInfo, UDF_CHAR_SET_OSTA_COMPRESSED_UNICODE_INFO, \ 364 sizeof(UDF_CHAR_SET_OSTA_COMPRESSED_UNICODE_INFO)) == 0 ) 365 366 367 /** @name UDF structure logging macros 368 * @{ */ 369 #define UDF_LOG2_MEMBER(a_pStruct, a_szFmt, a_Member) \ 370 Log2(("ISO/UDF: %-32s %" a_szFmt "\n", #a_Member ":", (a_pStruct)->a_Member)) 371 #define UDF_LOG2_MEMBER_EX(a_pStruct, a_szFmt, a_Member, a_cchIndent) \ 372 Log2(("ISO/UDF: %*s%-32s %" a_szFmt "\n", a_cchIndent, "", #a_Member ":", (a_pStruct)->a_Member)) 373 #define UDF_LOG2_MEMBER_ENTITY_ID_EX(a_pStruct, a_Member, a_cchIndent) \ 374 Log2(("ISO/UDF: %*s%-32s '%.23s' fFlags=%#06x Suffix=%.8Rhxs\n", a_cchIndent, "", #a_Member ":", \ 375 (a_pStruct)->a_Member.achIdentifier, (a_pStruct)->a_Member.fFlags, &(a_pStruct)->a_Member.Suffix)) 376 #define UDF_LOG2_MEMBER_ENTITY_ID(a_pStruct, a_Member) UDF_LOG2_MEMBER_ENTITY_ID_EX(a_pStruct, a_Member, 0) 377 #define UDF_LOG2_MEMBER_EXTENTAD(a_pStruct, a_Member) \ 378 Log2(("ISO/UDF: %-32s sector %#010RX32 LB %#010RX32\n", #a_Member ":", (a_pStruct)->a_Member.off, (a_pStruct)->a_Member.cb)) 379 #define UDF_LOG2_MEMBER_SHORTAD(a_pStruct, a_Member) \ 380 Log2(("ISO/UDF: %-32s sector %#010RX32 LB %#010RX32 %s\n", #a_Member ":", (a_pStruct)->a_Member.off, (a_pStruct)->a_Member.cb, \ 381 (a_pStruct)->a_Member.uType == UDF_AD_TYPE_RECORDED_AND_ALLOCATED ? "alloced+recorded" \ 382 : (a_pStruct)->a_Member.uType == UDF_AD_TYPE_ONLY_ALLOCATED ? "alloced" \ 383 : (a_pStruct)->a_Member.uType == UDF_AD_TYPE_FREE ? "free" : "next" )) 384 #define UDF_LOG2_MEMBER_LONGAD(a_pStruct, a_Member) \ 385 Log2(("ISO/UDF: %-32s partition %#RX16, block %#010RX32 LB %#010RX32 %s idUnique=%#010RX32 fFlags=%#RX16\n", #a_Member ":", \ 386 (a_pStruct)->a_Member.Location.uPartitionNo, (a_pStruct)->a_Member.Location.off, (a_pStruct)->a_Member.cb, \ 387 (a_pStruct)->a_Member.uType == UDF_AD_TYPE_RECORDED_AND_ALLOCATED ? "alloced+recorded" \ 388 : (a_pStruct)->a_Member.uType == UDF_AD_TYPE_ONLY_ALLOCATED ? "alloced" \ 389 : (a_pStruct)->a_Member.uType == UDF_AD_TYPE_FREE ? "free" : "next", \ 390 (a_pStruct)->a_Member.ImplementationUse.Fid.idUnique, (a_pStruct)->a_Member.ImplementationUse.Fid.fFlags )) 391 392 #define UDF_LOG2_MEMBER_TIMESTAMP(a_pStruct, a_Member) \ 393 Log2(("ISO/UDF: %-32s %04d-%02u-%02u %02u:%02u:%02u.%02u%02u%02u uTypeAndZone=%#x\n", #a_Member ":", \ 394 (a_pStruct)->a_Member.iYear, (a_pStruct)->a_Member.uMonth, (a_pStruct)->a_Member.uDay, \ 395 (a_pStruct)->a_Member.uHour, (a_pStruct)->a_Member.uMinute, (a_pStruct)->a_Member.uSecond, \ 396 (a_pStruct)->a_Member.cCentiseconds, (a_pStruct)->a_Member.cHundredsOfMicroseconds, \ 397 (a_pStruct)->a_Member.cMicroseconds, (a_pStruct)->a_Member.uTypeAndZone)) 398 #define UDF_LOG2_MEMBER_CHARSPEC(a_pStruct, a_Member) \ 399 do { \ 400 if ( (a_pStruct)->a_Member.uType == UDF_CHAR_SET_OSTA_COMPRESSED_UNICODE \ 401 && memcmp(&(a_pStruct)->a_Member.abInfo[0], UDF_CHAR_SET_OSTA_COMPRESSED_UNICODE_INFO, \ 402 sizeof(UDF_CHAR_SET_OSTA_COMPRESSED_UNICODE_INFO)) == 0) \ 403 Log2(("ISO/UDF: %-32s OSTA COMPRESSED UNICODE INFO\n", #a_Member ":")); \ 404 else if (ASMMemIsZero(&(a_pStruct)->a_Member, sizeof((a_pStruct)->a_Member))) \ 405 Log2(("ISO/UDF: %-32s all zeros\n", #a_Member ":")); \ 406 else \ 407 Log2(("ISO/UDF: %-32s %#x info: %.63Rhxs\n", #a_Member ":", \ 408 (a_pStruct)->a_Member.uType, (a_pStruct)->a_Member.abInfo)); \ 409 } while (0) 410 #define UDF_LOG2_MEMBER_DSTRING(a_pStruct, a_Member) \ 411 do { \ 412 if ((a_pStruct)->a_Member[0] == 8) \ 413 Log2(("ISO/UDF: %-32s 8: '%s' len=%u (actual=%u)\n", #a_Member ":", &(a_pStruct)->a_Member[1], \ 414 (a_pStruct)->a_Member[sizeof((a_pStruct)->a_Member) - 1], \ 415 RTStrNLen(&(a_pStruct)->a_Member[1], sizeof((a_pStruct)->a_Member) - 2) + 1 )); \ 416 else if ((a_pStruct)->a_Member[0] == 16) \ 417 { \ 418 PCRTUTF16 pwszTmp = (PCRTUTF16)&(a_pStruct)->a_Member[1]; \ 419 char *pszTmp = NULL; \ 420 RTUtf16BigToUtf8Ex(pwszTmp, (sizeof((a_pStruct)->a_Member) - 2) / sizeof(RTUTF16), &pszTmp, 0, NULL); \ 421 Log2(("ISO/UDF: %-32s 16: '%s' len=%u (actual=%u)\n", #a_Member ":", pszTmp, \ 422 (a_pStruct)->a_Member[sizeof((a_pStruct)->a_Member) - 1], \ 423 RTUtf16NLen(pwszTmp, (sizeof((a_pStruct)->a_Member) - 2) / sizeof(RTUTF16)) * sizeof(RTUTF16) + 1 /*??*/ )); \ 424 } \ 425 else if (ASMMemIsZero(&(a_pStruct)->a_Member[0], sizeof((a_pStruct)->a_Member))) \ 426 Log2(("ISO/UDF: %-32s empty\n", #a_Member ":")); \ 427 else \ 428 Log2(("ISO/UDF: %-32s bad: %.*Rhxs\n", #a_Member ":", sizeof((a_pStruct)->a_Member), &(a_pStruct)->a_Member[0] )); \ 429 } while (0) 430 /** @} */ 313 431 314 432 … … 325 443 uint32_t cDirRecs, uint64_t offDirRec, PRTVFSDIR phVfsDir); 326 444 static PRTFSISOCORE rtFsIsoDir_LookupShared(PRTFSISODIRSHRD pThis, uint64_t offDirRec); 445 446 447 /** 448 * UDF virtual partition read function. 449 * 450 * This deals with all the fun related to block mapping and such. 451 * 452 * @returns VBox status code. 453 * @param pThis The instance. 454 * @param idxPart The virtual partition number. 455 * @param idxBlock The block number. 456 * @param offByteAddend The byte offset relative to the block. 457 * @param pvBuf The output buffer. 458 * @param cbBuf The number of bytes to read. 459 */ 460 static int rtFsIsoVolUdfVpRead(PRTFSISOVOL pThis, uint32_t idxPart, uint32_t idxBlock, uint64_t offByteAddend, 461 void *pvBuf, size_t cbToRead) 462 { 463 uint64_t const offByte = ((uint64_t)idxBlock << pThis->Udf.VolInfo.cShiftBlock) + offByteAddend; 464 465 int rc; 466 if (idxPart < pThis->Udf.VolInfo.cPartitions) 467 { 468 PRTFSISOVOLUDFPMAP pPart = &pThis->Udf.VolInfo.paPartitions[idxPart]; 469 switch (pPart->bType) 470 { 471 case RTFSISO_UDF_PMAP_T_PLAIN: 472 rc = RTVfsFileReadAt(pThis->hVfsBacking, offByte + pPart->offByteLocation, pvBuf, cbToRead, NULL); 473 if (RT_SUCCESS(rc)) 474 { 475 Log3(("ISO/UDF: Read %#x bytes at %#RX64 (%#x:%#RX64)\n", 476 cbToRead, offByte + pPart->offByteLocation, idxPart, offByte)); 477 return VINF_SUCCESS; 478 } 479 Log(("ISO/UDF: Error reading %#x bytes at %#RX64 (%#x:%#RX64): %Rrc\n", 480 cbToRead, offByte + pPart->offByteLocation, idxPart, offByte, rc)); 481 break; 482 483 default: 484 AssertFailed(); 485 rc = VERR_ISOFS_IPE_1; 486 break; 487 } 488 } 489 else 490 { 491 Log(("ISO/UDF: Invalid partition index %#x (offset %#RX64), max partitions %#x\n", 492 idxPart, offByte, pThis->Udf.VolInfo.cPartitions)); 493 rc = VERR_ISOFS_INVALID_PARTITION_INDEX; 494 } 495 return rc; 496 } 327 497 328 498 … … 619 789 switch (enmAddAttr) 620 790 { 621 case RTFSOBJATTRADD_NOTHING: /* fall thru */791 case RTFSOBJATTRADD_NOTHING: RT_FALL_THRU(); 622 792 case RTFSOBJATTRADD_UNIX: 623 793 pObjInfo->Attr.u.Unix.uid = NIL_RTUID; … … 2036 2206 2037 2207 2208 #if 0 2209 /** 2210 * Instantiates a new shared directory structure, given 9660 records. 2211 * 2212 * @returns IPRT status code. 2213 * @param pThis The FAT volume instance. 2214 * @param pParentDir The parent directory. This is NULL for the root 2215 * directory. 2216 * @param pDirRec The directory record. Will access @a cDirRecs 2217 * records. 2218 * @param cDirRecs Number of directory records if more than one. 2219 * @param offDirRec The byte offset of the directory record. 2220 * @param ppShared Where to return the shared directory structure. 2221 */ 2222 static int rtFsIsoDirShrd_NewUdf(PRTFSISOVOL pThis, PRTFSISODIRSHRD pParentDir, 2223 PCUDFEXTVOLDESCNSR 2224 2225 PCISO9660DIRREC pDirRec, uint32_t cDirRecs, uint64_t offDirRec, 2226 PRTFSISODIRSHRD *ppShared) 2227 { 2228 /* 2229 * Allocate a new structure and initialize it. 2230 */ 2231 int rc = VERR_NO_MEMORY; 2232 PRTFSISODIRSHRD pShared = (PRTFSISODIRSHRD)RTMemAllocZ(sizeof(*pShared)); 2233 if (pShared) 2234 { 2235 rc = rtFsIsoCore_InitFrom9660DirRec(&pShared->Core, pDirRec, cDirRecs, offDirRec, 0 /*uVersion*/, pThis); 2236 if (RT_SUCCESS(rc)) 2237 { 2238 RTListInit(&pShared->OpenChildren); 2239 pShared->cbDir = ISO9660_GET_ENDIAN(&pDirRec->cbData); 2240 pShared->pbDir = (uint8_t *)RTMemAllocZ(pShared->cbDir + 256); 2241 if (pShared->pbDir) 2242 { 2243 rc = RTVfsFileReadAt(pThis->hVfsBacking, pShared->Core.FirstExtent.offDisk, pShared->pbDir, pShared->cbDir, NULL); 2244 if (RT_SUCCESS(rc)) 2245 { 2246 #ifdef LOG_ENABLED 2247 rtFsIsoDirShrd_Log9660Content(pShared); 2248 #endif 2249 2250 /* 2251 * Link into parent directory so we can use it to update 2252 * our directory entry. 2253 */ 2254 if (pParentDir) 2255 rtFsIsoDirShrd_AddOpenChild(pParentDir, &pShared->Core); 2256 *ppShared = pShared; 2257 return VINF_SUCCESS; 2258 } 2259 } 2260 } 2261 RTMemFree(pShared); 2262 } 2263 *ppShared = NULL; 2264 return rc; 2265 } 2266 #endif 2267 2268 2038 2269 /** 2039 2270 * Instantiates a new directory with a shared structure presupplied. … … 2235 2466 Log(("rtFsIsoVolValidateUdfDescTag(,%#x,%#010RX32,): Sector mismatch: %#RX32 (%.*Rhxs)\n", 2236 2467 idTag, offTag, pTag->offTag, sizeof(*pTag), pTag)); 2237 return RTE rrInfoSetF(pErrInfo, VERR_ISOFS_TAG_SECTOR_MISMATCH,2238 "Descriptor tag sector number mismatch: %#x, expected %#x (%.*Rhxs)",2239 pTag->offTag, offTag, sizeof(*pTag), pTag);2468 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_TAG_SECTOR_MISMATCH, 2469 "Descriptor tag sector number mismatch: %#x, expected %#x (%.*Rhxs)", 2470 pTag->offTag, offTag, sizeof(*pTag), pTag); 2240 2471 } 2241 2472 Log(("rtFsIsoVolValidateUdfDescTag(,%#x,%#010RX32,): Tag ID mismatch: %#x (%.*Rhxs)\n", 2242 2473 idTag, offTag, pTag->idTag, sizeof(*pTag), pTag)); 2243 return RTE rrInfoSetF(pErrInfo, VERR_MISMATCH, "Descriptor tag ID mismatch: %#x, expected %#x (%.*Rhxs)",2244 pTag->idTag, idTag, sizeof(*pTag), pTag);2474 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_MISMATCH, "Descriptor tag ID mismatch: %#x, expected %#x (%.*Rhxs)", 2475 pTag->idTag, idTag, sizeof(*pTag), pTag); 2245 2476 } 2246 2477 if (ASMMemIsZero(pTag, sizeof(*pTag))) 2247 2478 { 2248 2479 Log(("rtFsIsoVolValidateUdfDescTag(,%#x,%#010RX32,): All zeros\n", idTag, offTag)); 2249 return RTE rrInfoSet(pErrInfo, VERR_ISOFS_TAG_IS_ALL_ZEROS, "Descriptor is all zeros");2480 return RTERRINFO_LOG_SET(pErrInfo, VERR_ISOFS_TAG_IS_ALL_ZEROS, "Descriptor is all zeros"); 2250 2481 } 2251 2482 2252 2483 Log(("rtFsIsoVolValidateUdfDescTag(,%#x,%#010RX32,): Unsupported version: %#x (%.*Rhxs)\n", 2253 2484 idTag, offTag, pTag->uVersion, sizeof(*pTag), pTag)); 2254 return RTE rrInfoSetF(pErrInfo, VERR_ISOFS_UNSUPPORTED_TAG_VERSION, "Unsupported descriptor tag version: %#x, expected 2 or 3 (%.*Rhxs)",2255 pTag->uVersion, sizeof(*pTag), pTag);2485 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_UNSUPPORTED_TAG_VERSION, "Unsupported descriptor tag version: %#x, expected 2 or 3 (%.*Rhxs)", 2486 pTag->uVersion, sizeof(*pTag), pTag); 2256 2487 } 2257 2488 Log(("rtFsIsoVolValidateUdfDescTag(,%#x,%#010RX32,): checksum error: %#x, calc %#x (%.*Rhxs)\n", 2258 2489 idTag, offTag, pTag->uChecksum, bChecksum, sizeof(*pTag), pTag)); 2259 return RTE rrInfoSetF(pErrInfo, VERR_ISOFS_BAD_TAG_CHECKSUM,2260 "Descriptor tag checksum error: %#x, calculated %#x (%.*Rhxs)",2261 pTag->uChecksum, bChecksum, sizeof(*pTag), pTag);2490 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_BAD_TAG_CHECKSUM, 2491 "Descriptor tag checksum error: %#x, calculated %#x (%.*Rhxs)", 2492 pTag->uChecksum, bChecksum, sizeof(*pTag), pTag); 2262 2493 } 2263 2494 … … 2284 2515 Log(("rtFsIsoVolValidateUdfDescCrc(,%#x,%#010RX32,): Descriptor CRC mismatch: expected %#x, calculated %#x (cbDescriptorCrc=%#x)\n", 2285 2516 pTag->idTag, pTag->offTag, pTag->uDescriptorCrc, uCrc, pTag->cbDescriptorCrc)); 2286 return RTE rrInfoSetF(pErrInfo, VERR_ISOFS_DESC_CRC_MISMATCH,2287 "Descriptor CRC mismatch: exepcted %#x, calculated %#x (cbDescriptor=%#x, idTag=%#x, offTag=%#010RX32)",2288 pTag->uDescriptorCrc, uCrc, pTag->cbDescriptorCrc, pTag->idTag, pTag->offTag);2517 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_DESC_CRC_MISMATCH, 2518 "Descriptor CRC mismatch: exepcted %#x, calculated %#x (cbDescriptor=%#x, idTag=%#x, offTag=%#010RX32)", 2519 pTag->uDescriptorCrc, uCrc, pTag->cbDescriptorCrc, pTag->idTag, pTag->offTag); 2289 2520 } 2290 2521 2291 2522 Log(("rtFsIsoVolValidateUdfDescCrc(,%#x,%#010RX32,): Insufficient data to CRC: cbDescriptorCrc=%#x cbDesc=%#zx\n", 2292 2523 pTag->idTag, pTag->offTag, pTag->cbDescriptorCrc, cbDesc)); 2293 return RTE rrInfoSetF(pErrInfo, VERR_ISOFS_INSUFFICIENT_DATA_FOR_DESC_CRC,2294 "Insufficient data to CRC: cbDescriptorCrc=%#x cbDesc=%#zx (idTag=%#x, offTag=%#010RX32)",2295 pTag->cbDescriptorCrc, cbDesc, pTag->idTag, pTag->offTag);2524 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_INSUFFICIENT_DATA_FOR_DESC_CRC, 2525 "Insufficient data to CRC: cbDescriptorCrc=%#x cbDesc=%#zx (idTag=%#x, offTag=%#010RX32)", 2526 pTag->cbDescriptorCrc, cbDesc, pTag->idTag, pTag->offTag); 2296 2527 } 2297 2528 … … 2326 2557 2327 2558 2328 #define UDF_LOG2_MEMBER(a_pStruct, a_szFmt, a_Member) \ 2329 Log2(("ISO/UDF: %-32s %" a_szFmt "\n", #a_Member ":", (a_pStruct)->a_Member)) 2330 #define UDF_LOG2_MEMBER_EX(a_pStruct, a_szFmt, a_Member, a_cchIndent) \ 2331 Log2(("ISO/UDF: %*s%-32s %" a_szFmt "\n", a_cchIndent, "", #a_Member ":", (a_pStruct)->a_Member)) 2332 #define UDF_LOG2_MEMBER_ENTITY_ID_EX(a_pStruct, a_Member, a_cchIndent) \ 2333 Log2(("ISO/UDF: %*s%-32s '%.23s' fFlags=%#06x Suffix=%.8Rhxs\n", a_cchIndent, "", #a_Member ":", \ 2334 (a_pStruct)->a_Member.achIdentifier, (a_pStruct)->a_Member.fFlags, &(a_pStruct)->a_Member.Suffix)) 2335 #define UDF_LOG2_MEMBER_ENTITY_ID(a_pStruct, a_Member) UDF_LOG2_MEMBER_ENTITY_ID_EX(a_pStruct, a_Member, 0) 2336 #define UDF_LOG2_MEMBER_EXTENTAD(a_pStruct, a_Member) \ 2337 Log2(("ISO/UDF: %-32s sector %#010RX32 LB %#010RX32\n", #a_Member ":", (a_pStruct)->a_Member.off, (a_pStruct)->a_Member.cb)) 2338 #define UDF_LOG2_MEMBER_SHORTAD(a_pStruct, a_Member) \ 2339 Log2(("ISO/UDF: %-32s sector %#010RX32 LB %#010RX32 %s\n", #a_Member ":", (a_pStruct)->a_Member.off, (a_pStruct)->a_Member.cb, \ 2340 (a_pStruct)->a_Member.uType == UDF_AD_TYPE_RECORDED_AND_ALLOCATED ? "alloced+recorded" \ 2341 : (a_pStruct)->a_Member.uType == UDF_AD_TYPE_ONLY_ALLOCATED ? "alloced" \ 2342 : (a_pStruct)->a_Member.uType == UDF_AD_TYPE_FREE ? "free" : "next" )) 2343 #define UDF_LOG2_MEMBER_LONGAD(a_pStruct, a_Member) \ 2344 Log2(("ISO/UDF: %-32s partition %#RX16, sector %#010RX32 LB %#010RX32 %s idUnique=%#010RX32 fFlags=%#RX16\n", #a_Member ":", \ 2345 (a_pStruct)->a_Member.Location.uPartitionNo, (a_pStruct)->a_Member.Location.off, (a_pStruct)->a_Member.cb, \ 2346 (a_pStruct)->a_Member.uType == UDF_AD_TYPE_RECORDED_AND_ALLOCATED ? "alloced+recorded" \ 2347 : (a_pStruct)->a_Member.uType == UDF_AD_TYPE_ONLY_ALLOCATED ? "alloced" \ 2348 : (a_pStruct)->a_Member.uType == UDF_AD_TYPE_FREE ? "free" : "next", \ 2349 (a_pStruct)->a_Member.ImplementationUse.Fid.idUnique, (a_pStruct)->a_Member.ImplementationUse.Fid.fFlags )) 2350 2351 #define UDF_LOG2_MEMBER_TIMESTAMP(a_pStruct, a_Member) \ 2352 Log2(("ISO/UDF: %-32s %04d-%02u-%02u %02u:%02u:%02u.%02u%02u%02u uTypeAndZone=%#x\n", #a_Member ":", \ 2353 (a_pStruct)->a_Member.iYear, (a_pStruct)->a_Member.uMonth, (a_pStruct)->a_Member.uDay, \ 2354 (a_pStruct)->a_Member.uHour, (a_pStruct)->a_Member.uMinute, (a_pStruct)->a_Member.uSecond, \ 2355 (a_pStruct)->a_Member.cCentiseconds, (a_pStruct)->a_Member.cHundredsOfMicroseconds, \ 2356 (a_pStruct)->a_Member.cMicroseconds, (a_pStruct)->a_Member.uTypeAndZone)) 2357 #define UDF_LOG2_MEMBER_CHARSPEC(a_pStruct, a_Member) \ 2358 do { \ 2359 if ( (a_pStruct)->a_Member.uType == UDF_CHAR_SET_OSTA_COMPRESSED_UNICODE \ 2360 && memcmp(&(a_pStruct)->a_Member.abInfo[0], UDF_CHAR_SET_OSTA_COMPRESSED_UNICODE_INFO, \ 2361 sizeof(UDF_CHAR_SET_OSTA_COMPRESSED_UNICODE_INFO)) == 0) \ 2362 Log2(("ISO/UDF: %-32s OSTA COMPRESSED UNICODE INFO\n", #a_Member ":")); \ 2363 else if (ASMMemIsZero(&(a_pStruct)->a_Member, sizeof((a_pStruct)->a_Member))) \ 2364 Log2(("ISO/UDF: %-32s all zeros\n", #a_Member ":")); \ 2365 else \ 2366 Log2(("ISO/UDF: %-32s %#x info: %.63Rhxs\n", #a_Member ":", \ 2367 (a_pStruct)->a_Member.uType, (a_pStruct)->a_Member.abInfo)); \ 2368 } while (0) 2369 #define UDF_LOG2_MEMBER_DSTRING(a_pStruct, a_Member) \ 2370 do { \ 2371 if ((a_pStruct)->a_Member[0] == 8) \ 2372 Log2(("ISO/UDF: %-32s 8: '%s' len=%u (actual=%u)\n", #a_Member ":", &(a_pStruct)->a_Member[1], \ 2373 (a_pStruct)->a_Member[sizeof((a_pStruct)->a_Member) - 1], strlen(&(a_pStruct)->a_Member[1]) + 1 )); \ 2374 else if ((a_pStruct)->a_Member[0] == 16) \ 2375 { \ 2376 PCRTUTF16 pwszTmp = (PCRTUTF16)&(a_pStruct)->a_Member[1]; \ 2377 char *pszTmp = NULL; \ 2378 RTUtf16BigToUtf8Ex(pwszTmp, (sizeof((a_pStruct)->a_Member) - 2) / sizeof(RTUTF16), &pszTmp, 0, NULL); \ 2379 Log2(("ISO/UDF: %-32s 16: '%s' len=%u (actual=%u)\n", #a_Member ":", pszTmp, \ 2380 (a_pStruct)->a_Member[sizeof((a_pStruct)->a_Member) - 1], RTUtf16Len(pwszTmp) * sizeof(RTUTF16) + 1 /*??*/ )); \ 2381 } \ 2382 else if (ASMMemIsZero(&(a_pStruct)->a_Member[0], sizeof((a_pStruct)->a_Member))) \ 2383 Log2(("ISO/UDF: %-32s empty\n", #a_Member ":")); \ 2384 else \ 2385 Log2(("ISO/UDF: %-32s bad: %.*Rhxs\n", #a_Member ":", sizeof((a_pStruct)->a_Member), &(a_pStruct)->a_Member[0] )); \ 2386 } while (0) 2387 2559 2560 2561 static int rtFsIsoVolProcessUdfFileSetDescs(PRTFSISOVOL pThis, uint8_t *pbBuf, size_t cbBuf, PRTERRINFO pErrInfo) 2562 { 2563 2564 /* 2565 * We assume there is a single file descriptor and don't bother checking what comes next. 2566 */ 2567 PUDFFILESETDESC pFsd = (PUDFFILESETDESC)pbBuf; 2568 Assert(cbBuf > sizeof(*pFsd)); NOREF(cbBuf); 2569 RT_ZERO(*pFsd); 2570 size_t cbToRead = RT_MAX(pThis->Udf.VolInfo.FileSetDescriptor.cb, sizeof(*pFsd)); 2571 int rc = rtFsIsoVolUdfVpRead(pThis, pThis->Udf.VolInfo.FileSetDescriptor.Location.uPartitionNo, 2572 pThis->Udf.VolInfo.FileSetDescriptor.Location.off, 0, pFsd, cbToRead); 2573 if (RT_SUCCESS(rc)) 2574 { 2575 rc = rtFsIsoVolValidateUdfDescTagAndCrc(&pFsd->Tag, cbToRead, UDF_TAG_ID_FILE_SET_DESC, 2576 pThis->Udf.VolInfo.FileSetDescriptor.Location.off, pErrInfo); 2577 if (RT_SUCCESS(rc)) 2578 { 2579 #ifdef LOG_ENABLED 2580 Log(("ISO/UDF: File set descriptor at %#RX32 (%#RX32:%#RX32)\n", pFsd->Tag.offTag, 2581 pThis->Udf.VolInfo.FileSetDescriptor.Location.uPartitionNo, 2582 pThis->Udf.VolInfo.FileSetDescriptor.Location.off)); 2583 if (LogIs2Enabled()) 2584 { 2585 UDF_LOG2_MEMBER_TIMESTAMP(pFsd, RecordingTimestamp); 2586 UDF_LOG2_MEMBER(pFsd, "#06RX16", uInterchangeLevel); 2587 UDF_LOG2_MEMBER(pFsd, "#06RX16", uMaxInterchangeLevel); 2588 UDF_LOG2_MEMBER(pFsd, "#010RX32", fCharacterSets); 2589 UDF_LOG2_MEMBER(pFsd, "#010RX32", fMaxCharacterSets); 2590 UDF_LOG2_MEMBER(pFsd, "#010RX32", uFileSetNo); 2591 UDF_LOG2_MEMBER(pFsd, "#010RX32", uFileSetDescNo); 2592 UDF_LOG2_MEMBER_CHARSPEC(pFsd, LogicalVolumeIDCharSet); 2593 UDF_LOG2_MEMBER_DSTRING(pFsd, achLogicalVolumeID); 2594 UDF_LOG2_MEMBER_CHARSPEC(pFsd, FileSetCharSet); 2595 UDF_LOG2_MEMBER_DSTRING(pFsd, achFileSetID); 2596 UDF_LOG2_MEMBER_DSTRING(pFsd, achCopyrightFile); 2597 UDF_LOG2_MEMBER_DSTRING(pFsd, achAbstractFile); 2598 UDF_LOG2_MEMBER_LONGAD(pFsd, RootDirIcb); 2599 UDF_LOG2_MEMBER_ENTITY_ID(pFsd, idDomain); 2600 UDF_LOG2_MEMBER_LONGAD(pFsd, NextExtent); 2601 UDF_LOG2_MEMBER_LONGAD(pFsd, SystemStreamDirIcb); 2602 if (!ASMMemIsZero(&pFsd->abReserved[0], sizeof(pFsd->abReserved))) 2603 UDF_LOG2_MEMBER(pFsd, "%.32Rhxs", abReserved); 2604 } 2605 #endif 2606 2607 /* 2608 * Do some basic sanity checking. 2609 */ 2610 if (!UDF_IS_CHAR_SET_OSTA(&pFsd->FileSetCharSet)) 2611 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_FSD_UNSUPPORTED_CHAR_SET, 2612 "Invalid file set charset %.64Rhxs", &pFsd->FileSetCharSet); 2613 if ( pFsd->RootDirIcb.cb == 0 2614 || pFsd->RootDirIcb.uType != UDF_AD_TYPE_RECORDED_AND_ALLOCATED) 2615 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_FSD_ZERO_ROOT_DIR, 2616 "Root Dir ICB location is zero or malformed: uType=%#x cb=%#x loc=%#x:%#RX32", 2617 pFsd->RootDirIcb.uType, pFsd->RootDirIcb.cb, 2618 pFsd->RootDirIcb.Location.uPartitionNo, pFsd->RootDirIcb.Location.off); 2619 if ( pFsd->NextExtent.cb != 0 2620 && pFsd->NextExtent.uType == UDF_AD_TYPE_RECORDED_AND_ALLOCATED) 2621 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_FSD_NEXT_EXTENT, 2622 "NextExtent isn't zero: uType=%#x cb=%#x loc=%#x:%#RX32", 2623 pFsd->NextExtent.uType, pFsd->NextExtent.cb, 2624 pFsd->NextExtent.Location.uPartitionNo, pFsd->NextExtent.Location.off); 2625 2626 /* 2627 * Copy the information we need. 2628 */ 2629 pThis->Udf.VolInfo.RootDirIcb = pFsd->RootDirIcb; 2630 if ( pFsd->SystemStreamDirIcb.cb > 0 2631 && pFsd->SystemStreamDirIcb.uType == UDF_AD_TYPE_RECORDED_AND_ALLOCATED) 2632 pThis->Udf.VolInfo.SystemStreamDirIcb = pFsd->SystemStreamDirIcb; 2633 else 2634 RT_ZERO(pThis->Udf.VolInfo.SystemStreamDirIcb); 2635 return VINF_SUCCESS; 2636 } 2637 return rc; 2638 } 2639 return RTERRINFO_LOG_SET(pErrInfo, rc, "Error reading file set descriptor"); 2640 } 2641 2642 2643 /** 2644 * Check validatity and extract information from the descriptors in the VDS seq. 2645 * 2646 * @returns IPRT status code 2647 * @param pThis The instance. 2648 * @param pInfo The VDS sequence info. 2649 * @param pErrInfo Where to return extended error info. 2650 */ 2651 static int rtFsIsoVolProcessUdfVdsSeqInfo(PRTFSISOVOL pThis, PRTFSISOVDSINFO pInfo, PRTERRINFO pErrInfo) 2652 { 2653 /* 2654 * Check the basic descriptor counts. 2655 */ 2656 PUDFPRIMARYVOLUMEDESC pPvd; 2657 if (pInfo->cPrimaryVols == 1) 2658 pPvd = pInfo->apPrimaryVols[0]; 2659 else 2660 { 2661 if (pInfo->cPrimaryVols == 0) 2662 return RTERRINFO_LOG_SET(pErrInfo, VERR_ISOFS_NO_PVD, "No primary volume descriptor was found"); 2663 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_MULTIPLE_PVDS, 2664 "More than one primary volume descriptor was found: %u", pInfo->cPrimaryVols); 2665 } 2666 2667 PUDFLOGICALVOLUMEDESC pLvd; 2668 if (pInfo->cLogicalVols == 1) 2669 pLvd = pInfo->apLogicalVols[0]; 2670 else 2671 { 2672 if (pInfo->cLogicalVols == 0) 2673 return RTERRINFO_LOG_SET(pErrInfo, VERR_ISOFS_NO_LVD, "No logical volume descriptor was found"); 2674 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_MULTIPLE_LVDS, 2675 "More than one logical volume descriptor was found: %u", pInfo->cLogicalVols); 2676 } 2677 2678 #if 0 2679 if (pInfo->cPartitions == 0) 2680 return RTERRINFO_LOG_SET(pErrInfo, VERR_ISOFS_NO_PD, "No partition descriptors was found"); 2681 #endif 2682 2683 /* 2684 * Check out the partition map in the logical volume descriptor. 2685 * Produce the mapping table while going about that. 2686 */ 2687 if (pLvd->cPartitionMaps > 64) 2688 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_TOO_MANY_PART_MAPS, 2689 "Too many partition maps: %u (max 64)", pLvd->cPartitionMaps); 2690 2691 PRTFSISOVOLUDFPMAP paPartMaps = NULL; 2692 if (pLvd->cPartitionMaps > 0) 2693 { 2694 pInfo->paPartMaps = paPartMaps = (PRTFSISOVOLUDFPMAP)RTMemAllocZ(sizeof(paPartMaps[0]) * pLvd->cPartitionMaps); 2695 if (!paPartMaps) 2696 return VERR_NO_MEMORY; 2697 } 2698 uint32_t cPartMaps = 0; 2699 2700 if (pLvd->cbMapTable) 2701 { 2702 uint32_t off = 0; 2703 while (off + sizeof(UDFPARTMAPHDR) <= pLvd->cbMapTable) 2704 { 2705 PCUDFPARTMAPHDR pHdr = (PCUDFPARTMAPHDR)&pLvd->abPartitionMaps[off]; 2706 2707 /* 2708 * Bounds checking. 2709 */ 2710 if (off + pHdr->cb > pLvd->cbMapTable) 2711 { 2712 if (cPartMaps < pLvd->cbMapTable) 2713 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_MALFORMED_PART_MAP_TABLE, 2714 "Incomplete partition map entry at offset %#x: cb=%#x -> offEnd=%#x cbMapTable=%#x (type=%#x)", 2715 off, pHdr->cb, off + pHdr->cb, pLvd->cbMapTable, pHdr->bType); 2716 LogRel(("ISO/UDF: Warning: Incomplete partition map entry at offset %#x: cb=%#x -> offEnd=%#x cbMapTable=%#x (type=%#x)\n", 2717 off, pHdr->cb, off + pHdr->cb, pLvd->cbMapTable, pHdr->bType)); 2718 break; 2719 } 2720 if (cPartMaps >= pLvd->cPartitionMaps) 2721 { 2722 LogRel(("ISO/UDF: Warning: LVD::cPartitionMaps is %u but there are more bytes in the table. (off=%#x cb=%#x cbMapTable=%#x bType=%#x)\n", 2723 off, pHdr->cb, pLvd->cbMapTable, pHdr->bType)); 2724 break; 2725 } 2726 2727 /* 2728 * Extract relevant info out of the entry. 2729 */ 2730 paPartMaps[cPartMaps].offMapTable = (uint16_t)off; 2731 uint16_t uPartitionNo; 2732 if (pHdr->bType == 1) 2733 { 2734 PCUDFPARTMAPTYPE1 pType1 = (PCUDFPARTMAPTYPE1)pHdr; 2735 paPartMaps[cPartMaps].uVolumeSeqNo = pType1->uVolumeSeqNo; 2736 paPartMaps[cPartMaps].bType = RTFSISO_UDF_PMAP_T_PLAIN; 2737 uPartitionNo = pType1->uPartitionNo; 2738 } 2739 else if (pHdr->bType == 2) 2740 { 2741 PCUDFPARTMAPTYPE2 pType2 = (PCUDFPARTMAPTYPE2)pHdr; 2742 if (UDF_ENTITY_ID_EQUALS(&pType2->idPartitionType, UDF_ENTITY_ID_VPM_PARTITION_TYPE)) 2743 { 2744 paPartMaps[cPartMaps].bType = pType2->idPartitionType.Suffix.Udf.uUdfRevision >= 0x200 2745 ? RTFSISO_UDF_PMAP_T_VPM_20 : RTFSISO_UDF_PMAP_T_VPM_15; 2746 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_VPM_NOT_SUPPORTED, "Partition type '%.23s' (%#x) not supported", 2747 pType2->idPartitionType.achIdentifier, pType2->idPartitionType.Suffix.Udf.uUdfRevision); 2748 } 2749 else if (UDF_ENTITY_ID_EQUALS(&pType2->idPartitionType, UDF_ENTITY_ID_SPM_PARTITION_TYPE)) 2750 { 2751 paPartMaps[cPartMaps].bType = RTFSISO_UDF_PMAP_T_SPM; 2752 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_SPM_NOT_SUPPORTED, "Partition type '%.23s' (%#x) not supported", 2753 pType2->idPartitionType.achIdentifier, pType2->idPartitionType.Suffix.Udf.uUdfRevision); 2754 } 2755 else if (UDF_ENTITY_ID_EQUALS(&pType2->idPartitionType, UDF_ENTITY_ID_MPM_PARTITION_TYPE)) 2756 { 2757 paPartMaps[cPartMaps].bType = RTFSISO_UDF_PMAP_T_MPM; 2758 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_MPM_NOT_SUPPORTED, "Partition type '%.23s' (%#x) not supported", 2759 pType2->idPartitionType.achIdentifier, pType2->idPartitionType.Suffix.Udf.uUdfRevision); 2760 } 2761 else 2762 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_UNKNOWN_PART_MAP_TYPE_ID, 2763 "Unknown partition map ID for #%u @ %#x: %.23s", 2764 cPartMaps, off, pType2->idPartitionType.achIdentifier); 2765 #if 0 /* unreachable code */ 2766 paPartMaps[cPartMaps].uVolumeSeqNo = pType2->uVolumeSeqNo; 2767 uPartitionNo = pType2->uPartitionNo; 2768 #endif 2769 } 2770 else 2771 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_UNKNOWN_PART_MAP_ENTRY_TYPE, 2772 "Unknown partition map entry type #%u @ %#x: %u", cPartMaps, off, pHdr->bType); 2773 paPartMaps[cPartMaps].uPartitionNo = uPartitionNo; 2774 2775 /* 2776 * Lookup the partition number and retrieve the relevant info from the partition descriptor. 2777 */ 2778 uint32_t i = pInfo->cPartitions; 2779 while (i-- > 0) 2780 { 2781 PUDFPARTITIONDESC pPd = pInfo->apPartitions[i]; 2782 if (paPartMaps[cPartMaps].uPartitionNo == pPd->uPartitionNo) 2783 { 2784 paPartMaps[cPartMaps].idxPartDesc = (uint16_t)i; 2785 paPartMaps[cPartMaps].cSectors = pPd->cSectors; 2786 paPartMaps[cPartMaps].offLocation = pPd->offLocation; 2787 paPartMaps[cPartMaps].offByteLocation = (uint64_t)pPd->offLocation * pThis->cbSector; 2788 paPartMaps[cPartMaps].fFlags = pPd->fFlags; 2789 paPartMaps[cPartMaps].uAccessType = pPd->uAccessType; 2790 if (!UDF_ENTITY_ID_EQUALS(&pPd->PartitionContents, UDF_ENTITY_ID_PD_PARTITION_CONTENTS_UDF)) 2791 paPartMaps[cPartMaps].fHaveHdr = false; 2792 else 2793 { 2794 paPartMaps[cPartMaps].fHaveHdr = true; 2795 paPartMaps[cPartMaps].Hdr = pPd->ContentsUse.Hdr; 2796 } 2797 break; 2798 } 2799 } 2800 if (i > pInfo->cPartitions) 2801 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_PARTITION_NOT_FOUND, 2802 "Partition #%u (%#x) specified by mapping entry #%u (@ %#x) was not found! (int-type %u)", 2803 uPartitionNo, uPartitionNo, cPartMaps, off, paPartMaps[cPartMaps].bType); 2804 2805 /* 2806 * Advance. 2807 */ 2808 cPartMaps++; 2809 off += pHdr->cb; 2810 } 2811 2812 if (cPartMaps < pLvd->cPartitionMaps) 2813 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_INCOMPLETE_PART_MAP_TABLE, 2814 "Only found %u of the %u announced partition mapping table entries", 2815 cPartMaps, pLvd->cPartitionMaps); 2816 } 2817 2818 /* It might be theoretically possible to not use virtual partitions for 2819 accessing data, so just warn if there aren't any. */ 2820 if (cPartMaps == 0) 2821 LogRel(("ISO/UDF: Warning: No partition maps!\n")); 2822 2823 /* 2824 * Check out the logical volume descriptor. 2825 */ 2826 if ( pLvd->cbLogicalBlock < pThis->cbSector 2827 || pLvd->cbLogicalBlock > _16K 2828 || (pLvd->cbLogicalBlock % pThis->cbSector) != 0) 2829 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_UNSUPPORTED_LOGICAL_BLOCK_SIZE, 2830 "Logical block size of %#x is not supported with a sector size of %#x", 2831 pLvd->cbLogicalBlock, pThis->cbSector); 2832 2833 if (!UDF_ENTITY_ID_EQUALS(&pLvd->idDomain, UDF_ENTITY_ID_LVD_DOMAIN)) 2834 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_BAD_LVD_DOMAIN_ID, 2835 "Unsupported domain ID in logical volume descriptor: '%.23s'", pLvd->idDomain.achIdentifier); 2836 2837 if ( pLvd->ContentsUse.FileSetDescriptor.uType != UDF_AD_TYPE_RECORDED_AND_ALLOCATED 2838 || pLvd->ContentsUse.FileSetDescriptor.cb == 0 2839 || pLvd->ContentsUse.FileSetDescriptor.Location.uPartitionNo >= cPartMaps) 2840 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_BAD_LVD_FILE_SET_DESC_LOCATION, 2841 "Malformed file set descriptor location (type=%u cb=%#x part=%#x)", 2842 pLvd->ContentsUse.FileSetDescriptor.uType, 2843 pLvd->ContentsUse.FileSetDescriptor.cb, 2844 pLvd->ContentsUse.FileSetDescriptor.Location.uPartitionNo); 2845 2846 bool fLvdHaveVolId = !ASMMemIsZero(pLvd->achLogicalVolumeID, sizeof(pLvd->achLogicalVolumeID)); 2847 if ( fLvdHaveVolId 2848 && !UDF_IS_CHAR_SET_OSTA(&pLvd->DescCharSet)) 2849 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_BAD_LVD_DESC_CHAR_SET, 2850 "Logical volume ID is not using OSTA compressed unicode"); 2851 2852 /* 2853 * We can ignore much, if not all of the primary volume descriptor. 2854 */ 2855 2856 /* 2857 * We're good. So copy over the data. 2858 */ 2859 pThis->Udf.VolInfo.FileSetDescriptor = pLvd->ContentsUse.FileSetDescriptor; 2860 pThis->Udf.VolInfo.cbBlock = pLvd->cbLogicalBlock; 2861 pThis->Udf.VolInfo.cShiftBlock = 9; 2862 while (pThis->Udf.VolInfo.cbBlock != RT_BIT_32(pThis->Udf.VolInfo.cShiftBlock)) 2863 pThis->Udf.VolInfo.cShiftBlock++; 2864 pThis->Udf.VolInfo.fFlags = pPvd->fFlags; 2865 pThis->Udf.VolInfo.cPartitions = cPartMaps; 2866 pThis->Udf.VolInfo.paPartitions = paPartMaps; 2867 pInfo->paPartMaps = NULL; 2868 if (fLvdHaveVolId) 2869 memcpy(pThis->Udf.VolInfo.achLogicalVolumeID, pLvd->achLogicalVolumeID, sizeof(pThis->Udf.VolInfo.achLogicalVolumeID)); 2870 else 2871 RT_ZERO(pThis->Udf.VolInfo.achLogicalVolumeID); 2872 2873 return VINF_SUCCESS; 2874 } 2388 2875 2389 2876 … … 2392 2879 * 2393 2880 * @returns IPRT status code. 2394 * @param p This The instance.2881 * @param pInfo Where we gather descriptor information. 2395 2882 * @param pDesc The descriptor. 2396 2883 * @param pErrInfo Where to return extended error information. 2397 2884 */ 2398 2885 //cmd: kmk VBoxRT && kmk_redirect -E VBOX_LOG_DEST="nofile stderr" -E VBOX_LOG="rt_fs=~0" -E VBOX_LOG_FLAGS="unbuffered enabled" -- e:\vbox\svn\trunk\out\win.amd64\debug\bin\tools\RTLs.exe :iprtvfs:file(open,d:\Downloads\en_windows_10_enterprise_version_1703_updated_march_2017_x64_dvd_10189290.iso,r):vfs(isofs):/ -la 2399 static int rtFsIsoVolProcessUdfPrimaryVolDesc(PRTFSISOV OL pThis, PCUDFPRIMARYVOLUMEDESC pDesc, PRTERRINFO pErrInfo)2886 static int rtFsIsoVolProcessUdfPrimaryVolDesc(PRTFSISOVDSINFO pInfo, PCUDFPRIMARYVOLUMEDESC pDesc, PRTERRINFO pErrInfo) 2400 2887 { 2401 2888 #ifdef LOG_ENABLED … … 2430 2917 #endif 2431 2918 2432 RT_NOREF(pThis, pDesc, pErrInfo); 2919 /* 2920 * Check if this is a new revision of an existing primary volume descriptor. 2921 */ 2922 PUDFPRIMARYVOLUMEDESC pEndianConvert = NULL; 2923 uint32_t i = pInfo->cPrimaryVols; 2924 while (i--> 0) 2925 { 2926 if ( memcmp(pDesc->achVolumeID, pInfo->apPrimaryVols[i]->achVolumeID, sizeof(pDesc->achVolumeID)) == 0 2927 && memcmp(&pDesc->DescCharSet, &pInfo->apPrimaryVols[i]->DescCharSet, sizeof(pDesc->DescCharSet)) == 0) 2928 { 2929 if (RT_LE2H_U32(pDesc->uVolumeDescSeqNo) >= pInfo->apPrimaryVols[i]->uVolumeDescSeqNo) 2930 { 2931 Log(("ISO/UDF: Primary descriptor prevails over previous! (%u >= %u)\n", 2932 RT_LE2H_U32(pDesc->uVolumeDescSeqNo), pInfo->apPartitions[i]->uVolumeDescSeqNo)); 2933 pEndianConvert = pInfo->apPrimaryVols[i]; 2934 memcpy(pEndianConvert, pDesc, sizeof(*pDesc)); 2935 } 2936 else 2937 Log(("ISO/UDF: Primary descriptor has lower sequence number than the previous! (%u < %u)\n", 2938 RT_LE2H_U32(pDesc->uVolumeDescSeqNo), pInfo->apPartitions[i]->uVolumeDescSeqNo)); 2939 break; 2940 } 2941 } 2942 if (i >= pInfo->cPrimaryVols) 2943 { 2944 /* 2945 * It wasn't. Append it. 2946 */ 2947 i = pInfo->cPrimaryVols; 2948 if (i < RT_ELEMENTS(pInfo->apPrimaryVols)) 2949 { 2950 pInfo->apPrimaryVols[i] = pEndianConvert = (PUDFPRIMARYVOLUMEDESC)RTMemDup(pDesc, sizeof(*pDesc)); 2951 if (pEndianConvert) 2952 pInfo->cPrimaryVols = i + 1; 2953 else 2954 return VERR_NO_MEMORY; 2955 Log2(("ISO/UDF: ++New primary descriptor.\n")); 2956 } 2957 else 2958 return RTERRINFO_LOG_SET(pErrInfo, VERR_ISOFS_TOO_MANY_PVDS, "Encountered too many primary volume descriptors"); 2959 } 2960 2961 #ifdef RT_BIG_ENDIAN 2962 /* 2963 * Do endian conversion of the descriptor. 2964 */ 2965 if (pEndianConvert) 2966 { 2967 AssertFailed(); 2968 } 2969 #else 2970 RT_NOREF(pEndianConvert); 2971 #endif 2433 2972 return VINF_SUCCESS; 2434 2973 } … … 2439 2978 * 2440 2979 * @returns IPRT status code. 2441 * @param p This The instance.2980 * @param pInfo Where we gather descriptor information. 2442 2981 * @param pDesc The descriptor. 2982 * @param cbSector The sector size (UDF defines the logical and physical 2983 * sector size to be the same). 2443 2984 * @param pErrInfo Where to return extended error information. 2444 2985 */ 2445 static int rtFsIsoVolProcessUdfLogicalVolumeDesc(PRTFSISOVOL pThis, PCUDFLOGICALVOLUMEDESC pDesc, PRTERRINFO pErrInfo) 2986 static int rtFsIsoVolProcessUdfLogicalVolumeDesc(PRTFSISOVDSINFO pInfo, PCUDFLOGICALVOLUMEDESC pDesc, 2987 uint32_t cbSector, PRTERRINFO pErrInfo) 2446 2988 { 2447 2989 #ifdef LOG_ENABLED … … 2450 2992 { 2451 2993 UDF_LOG2_MEMBER(pDesc, "#010RX32", uVolumeDescSeqNo); 2452 UDF_LOG2_MEMBER_CHARSPEC(pDesc, Desc riptorCharSet);2994 UDF_LOG2_MEMBER_CHARSPEC(pDesc, DescCharSet); 2453 2995 UDF_LOG2_MEMBER_DSTRING(pDesc, achLogicalVolumeID); 2454 2996 UDF_LOG2_MEMBER(pDesc, "#010RX32", cbLogicalBlock); 2455 2997 UDF_LOG2_MEMBER_ENTITY_ID(pDesc, idDomain); 2456 if ( memcmp(&pDesc->idDomain.achIdentifier[0], RT_STR_TUPLE(UDF_ENTITY_ID_LVD_DOMAIN) + 1) == 0)2998 if (UDF_ENTITY_ID_EQUALS(&pDesc->idDomain, UDF_ENTITY_ID_LVD_DOMAIN)) 2457 2999 UDF_LOG2_MEMBER_LONGAD(pDesc, ContentsUse.FileSetDescriptor); 2458 3000 else if (!ASMMemIsZero(&pDesc->ContentsUse.ab[0], sizeof(pDesc->ContentsUse.ab))) … … 2502 3044 #endif 2503 3045 2504 RT_NOREF(pThis, pDesc, pErrInfo); 3046 /* 3047 * Check if this is a newer revision of an existing primary volume descriptor. 3048 */ 3049 size_t cbDesc = (size_t)pDesc->cbMapTable + RT_UOFFSETOF(UDFLOGICALVOLUMEDESC, abPartitionMaps); 3050 if ( pDesc->cbMapTable >= (UINT32_MAX >> 1) 3051 || cbDesc > cbSector) 3052 { 3053 Log(("ISO/UDF: Logical volume descriptor is too big: %#zx (cbSector=%#x)\n", cbDesc, cbSector)); 3054 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_TOO_BIT_PARTMAP_IN_LVD, 3055 "Logical volume descriptor is too big: %#zx (cbSector=%#x)\n", cbDesc, cbSector); 3056 } 3057 3058 PUDFLOGICALVOLUMEDESC pEndianConvert = NULL; 3059 uint32_t i = pInfo->cLogicalVols; 3060 while (i--> 0) 3061 if ( memcmp(pDesc->achLogicalVolumeID, pInfo->apLogicalVols[i]->achLogicalVolumeID, 3062 sizeof(pDesc->achLogicalVolumeID)) == 0 3063 && memcmp(&pDesc->DescCharSet, &pInfo->apLogicalVols[i]->DescCharSet, 3064 sizeof(pDesc->DescCharSet)) == 0) 3065 { 3066 if (RT_LE2H_U32(pDesc->uVolumeDescSeqNo) >= pInfo->apLogicalVols[i]->uVolumeDescSeqNo) 3067 { 3068 Log(("ISO/UDF: Logical descriptor prevails over previous! (%u >= %u)\n", 3069 RT_LE2H_U32(pDesc->uVolumeDescSeqNo), pInfo->apLogicalVols[i]->uVolumeDescSeqNo)); 3070 pEndianConvert = (PUDFLOGICALVOLUMEDESC)RTMemDup(pDesc, cbDesc); 3071 if (!pEndianConvert) 3072 return VERR_NO_MEMORY; 3073 RTMemFree(pInfo->apLogicalVols[i]); 3074 pInfo->apLogicalVols[i] = pEndianConvert; 3075 } 3076 else 3077 Log(("ISO/UDF: Logical descriptor has lower sequence number than the previous! (%u >= %u)\n", 3078 RT_LE2H_U32(pDesc->uVolumeDescSeqNo), pInfo->apLogicalVols[i]->uVolumeDescSeqNo)); 3079 break; 3080 } 3081 if (i >= pInfo->cLogicalVols) 3082 { 3083 /* 3084 * It wasn't. Append it. 3085 */ 3086 i = pInfo->cLogicalVols; 3087 if (i < RT_ELEMENTS(pInfo->apLogicalVols)) 3088 { 3089 pInfo->apLogicalVols[i] = pEndianConvert = (PUDFLOGICALVOLUMEDESC)RTMemDup(pDesc, cbDesc); 3090 if (pEndianConvert) 3091 pInfo->cLogicalVols = i + 1; 3092 else 3093 return VERR_NO_MEMORY; 3094 Log2(("ISO/UDF: ++New logical volume descriptor.\n")); 3095 } 3096 else 3097 return RTERRINFO_LOG_SET(pErrInfo, VERR_ISOFS_TOO_MANY_LVDS, "Too many logical volume descriptors"); 3098 } 3099 3100 #ifdef RT_BIG_ENDIAN 3101 /* 3102 * Do endian conversion of the descriptor. 3103 */ 3104 if (pEndianConvert) 3105 { 3106 AssertFailed(); 3107 } 3108 #else 3109 RT_NOREF(pEndianConvert); 3110 #endif 2505 3111 return VINF_SUCCESS; 2506 3112 } … … 2511 3117 * 2512 3118 * @returns IPRT status code. 2513 * @param p This The instance.3119 * @param pInfo Where we gather descriptor information. 2514 3120 * @param pDesc The descriptor. 2515 3121 * @param pErrInfo Where to return extended error information. 2516 3122 */ 2517 static int rtFsIsoVolProcessUdfPartitionDesc(PRTFSISOV OL pThis, PCUDFPARTITIONDESC pDesc, PRTERRINFO pErrInfo)3123 static int rtFsIsoVolProcessUdfPartitionDesc(PRTFSISOVDSINFO pInfo, PCUDFPARTITIONDESC pDesc, PRTERRINFO pErrInfo) 2518 3124 { 2519 3125 #ifdef LOG_ENABLED … … 2525 3131 UDF_LOG2_MEMBER(pDesc, "#06RX16", uPartitionNo); 2526 3132 UDF_LOG2_MEMBER_ENTITY_ID(pDesc, PartitionContents); 2527 if ( memcmp(&pDesc->PartitionContents.achIdentifier[0], RT_STR_TUPLE(UDF_ENTITY_ID_PD_PARTITION_CONTENTS_UDF) + 1) == 0)3133 if (UDF_ENTITY_ID_EQUALS(&pDesc->PartitionContents, UDF_ENTITY_ID_PD_PARTITION_CONTENTS_UDF)) 2528 3134 { 2529 3135 UDF_LOG2_MEMBER_SHORTAD(&pDesc->ContentsUse, Hdr.UnallocatedSpaceTable); … … 2549 3155 #endif 2550 3156 2551 RT_NOREF(pThis, pDesc, pErrInfo); 3157 /* 3158 * Check if this is a newer revision of an existing primary volume descriptor. 3159 */ 3160 PUDFPARTITIONDESC pEndianConvert = NULL; 3161 uint32_t i = pInfo->cPartitions; 3162 while (i--> 0) 3163 if (pDesc->uPartitionNo == pInfo->apPartitions[i]->uPartitionNo) 3164 { 3165 if (RT_LE2H_U32(pDesc->uVolumeDescSeqNo) >= pInfo->apPartitions[i]->uVolumeDescSeqNo) 3166 { 3167 Log(("ISO/UDF: Partition descriptor for part %#u prevails over previous! (%u >= %u)\n", 3168 pDesc->uPartitionNo, RT_LE2H_U32(pDesc->uVolumeDescSeqNo), pInfo->apPartitions[i]->uVolumeDescSeqNo)); 3169 pEndianConvert = pInfo->apPartitions[i]; 3170 memcpy(pEndianConvert, pDesc, sizeof(*pDesc)); 3171 } 3172 else 3173 Log(("ISO/UDF: Partition descriptor for part %#u has a lower sequence number than the previous! (%u < %u)\n", 3174 pDesc->uPartitionNo, RT_LE2H_U32(pDesc->uVolumeDescSeqNo), pInfo->apPartitions[i]->uVolumeDescSeqNo)); 3175 break; 3176 } 3177 if (i >= pInfo->cPartitions) 3178 { 3179 /* 3180 * It wasn't. Append it. 3181 */ 3182 i = pInfo->cPartitions; 3183 if (i < RT_ELEMENTS(pInfo->apPartitions)) 3184 { 3185 pInfo->apPartitions[i] = pEndianConvert = (PUDFPARTITIONDESC)RTMemDup(pDesc, sizeof(*pDesc)); 3186 if (pEndianConvert) 3187 pInfo->cPartitions = i + 1; 3188 else 3189 return VERR_NO_MEMORY; 3190 Log2(("ISO/UDF: ++New partition descriptor.\n")); 3191 } 3192 else 3193 return RTERRINFO_LOG_SET(pErrInfo, VERR_ISOFS_TOO_MANY_PDS, "Too many physical volume descriptors"); 3194 } 3195 3196 #ifdef RT_BIG_ENDIAN 3197 /* 3198 * Do endian conversion of the descriptor. 3199 */ 3200 if (pEndianConvert) 3201 { 3202 AssertFailed(); 3203 } 3204 #else 3205 RT_NOREF(pEndianConvert); 3206 #endif 2552 3207 return VINF_SUCCESS; 2553 3208 } … … 2558 3213 * 2559 3214 * @returns IPRT status code. 2560 * @param p This The instance.3215 * @param pInfo Where we gather descriptor information. 2561 3216 * @param pDesc The descriptor. 2562 3217 * @param pErrInfo Where to return extended error information. 2563 3218 */ 2564 static int rtFsIsoVolProcessUdfImplUseVolDesc(PRTFSISOV OL pThis, PCUDFIMPLEMENTATIONUSEVOLUMEDESC pDesc, PRTERRINFO pErrInfo)3219 static int rtFsIsoVolProcessUdfImplUseVolDesc(PRTFSISOVDSINFO pInfo, PCUDFIMPLEMENTATIONUSEVOLUMEDESC pDesc, PRTERRINFO pErrInfo) 2565 3220 { 2566 3221 #ifdef LOG_ENABLED … … 2570 3225 UDF_LOG2_MEMBER(pDesc, "#010RX32", uVolumeDescSeqNo); 2571 3226 UDF_LOG2_MEMBER_ENTITY_ID(pDesc, idImplementation); 2572 if ( memcmp(pDesc->idImplementation.achIdentifier, RT_STR_TUPLE(UDF_ENTITY_ID_IUVD_IMPLEMENTATION) + 1) == 0)3227 if (UDF_ENTITY_ID_EQUALS(&pDesc->idImplementation, UDF_ENTITY_ID_IUVD_IMPLEMENTATION)) 2573 3228 { 2574 3229 UDF_LOG2_MEMBER_CHARSPEC(&pDesc->ImplementationUse, Lvi.Charset); … … 2586 3241 #endif 2587 3242 2588 RT_NOREF(p This, pDesc, pErrInfo);3243 RT_NOREF(pInfo, pDesc, pErrInfo); 2589 3244 return VINF_SUCCESS; 2590 3245 } … … 2606 3261 2607 3262 3263 2608 3264 /** 2609 3265 * Process a VDS sequence, recursively dealing with volume descriptor pointers. 3266 * 3267 * This function only gathers information from the sequence, handling the 3268 * prevailing descriptor fun. 2610 3269 * 2611 3270 * @returns IPRT status code. 2612 3271 * @param pThis The instance. 3272 * @param pInfo Where to store info from the VDS sequence. 2613 3273 * @param offSeq The byte offset of the sequence. 2614 3274 * @param cbSeq The length of the sequence. … … 2619 3279 * @param pErrInfo Where to return extended error info. 2620 3280 */ 2621 static int rtFsIsoVolReadAndProcessUdfVdsSeq(PRTFSISOVOL pThis, uint64_t offSeq, uint32_t cbSeq, uint8_t *pbBuf, size_t cbBuf,2622 uint 32_t cNestings, PRTERRINFO pErrInfo)3281 static int rtFsIsoVolReadAndProcessUdfVdsSeq(PRTFSISOVOL pThis, PRTFSISOVDSINFO pInfo, uint64_t offSeq, uint32_t cbSeq, 3282 uint8_t *pbBuf, size_t cbBuf, uint32_t cNestings, PRTERRINFO pErrInfo) 2623 3283 { 2624 3284 AssertReturn(cbBuf >= pThis->cbSector, VERR_INTERNAL_ERROR); … … 2628 3288 */ 2629 3289 if (cNestings > 5) 2630 return RTE rrInfoSet(pErrInfo, VERR_TOO_MUCH_DATA, "The volume descriptor sequence (VDS) is nested too deeply.");3290 return RTERRINFO_LOG_SET(pErrInfo, VERR_TOO_MUCH_DATA, "The volume descriptor sequence (VDS) is nested too deeply."); 2631 3291 2632 3292 … … 2645 3305 rc = RTVfsFileReadAt(pThis->hVfsBacking, offSeq + offInSeq, pbBuf, pThis->cbSector, NULL); 2646 3306 if (RT_FAILURE(rc)) 2647 return RTE rrInfoSetF(pErrInfo, rc, "Error reading VDS content at %RX64 (LB %#x): %Rrc",2648 offSeq + offInSeq, pThis->cbSector, rc);3307 return RTERRINFO_LOG_SET_F(pErrInfo, rc, "Error reading VDS content at %RX64 (LB %#x): %Rrc", 3308 offSeq + offInSeq, pThis->cbSector, rc); 2649 3309 if (cbSeq - offInSeq < pThis->cbSector) 2650 3310 memset(&pbBuf[cbSeq - offInSeq], 0, pThis->cbSector - (cbSeq - offInSeq)); … … 2667 3327 { 2668 3328 case UDF_TAG_ID_PRIMARY_VOL_DESC: 2669 rc = rtFsIsoVolProcessUdfPrimaryVolDesc(p This, (PCUDFPRIMARYVOLUMEDESC)pTag, pErrInfo);3329 rc = rtFsIsoVolProcessUdfPrimaryVolDesc(pInfo, (PCUDFPRIMARYVOLUMEDESC)pTag, pErrInfo); 2670 3330 break; 2671 3331 2672 3332 case UDF_TAG_ID_IMPLEMENTATION_USE_VOLUME_DESC: 2673 rc = rtFsIsoVolProcessUdfImplUseVolDesc(p This, (PCUDFIMPLEMENTATIONUSEVOLUMEDESC)pTag, pErrInfo);3333 rc = rtFsIsoVolProcessUdfImplUseVolDesc(pInfo, (PCUDFIMPLEMENTATIONUSEVOLUMEDESC)pTag, pErrInfo); 2674 3334 break; 2675 3335 2676 3336 case UDF_TAG_ID_PARTITION_DESC: 2677 rc = rtFsIsoVolProcessUdfPartitionDesc(p This, (PCUDFPARTITIONDESC)pTag, pErrInfo);3337 rc = rtFsIsoVolProcessUdfPartitionDesc(pInfo, (PCUDFPARTITIONDESC)pTag, pErrInfo); 2678 3338 break; 2679 3339 2680 3340 case UDF_TAG_ID_LOGICAL_VOLUME_DESC: 2681 rc = rtFsIsoVolProcessUdfLogicalVolumeDesc(pThis, (PCUDFLOGICALVOLUMEDESC)pTag, pErrInfo); 3341 if (rc != VERR_ISOFS_INSUFFICIENT_DATA_FOR_DESC_CRC) 3342 rc = rtFsIsoVolProcessUdfLogicalVolumeDesc(pInfo, (PCUDFLOGICALVOLUMEDESC)pTag, 3343 pThis->cbSector, pErrInfo); 3344 else 3345 rc = VERR_ISOFS_TOO_BIT_PARTMAP_IN_LVD; 2682 3346 break; 2683 3347 … … 2703 3367 offSeq + offInSeq, pVdp->NextVolumeDescSeq.off, pVdp->NextVolumeDescSeq.cb, 2704 3368 pVdp->uVolumeDescSeqNo, cNestings)); 2705 rc = rtFsIsoVolReadAndProcessUdfVdsSeq(pThis, (uint64_t)pVdp->NextVolumeDescSeq.off * pThis->cbSector,3369 rc = rtFsIsoVolReadAndProcessUdfVdsSeq(pThis, pInfo, (uint64_t)pVdp->NextVolumeDescSeq.off * pThis->cbSector, 2706 3370 pVdp->NextVolumeDescSeq.cb, pbBuf, cbBuf, cNestings + 1, pErrInfo); 2707 3371 break; … … 2713 3377 2714 3378 default: 2715 return RTE rrInfoSetF(pErrInfo, VERR_ISOFS_UNEXPECTED_VDS_DESC,2716 "Unexpected/unknown VDS descriptor %#x at byte offset %#RX64",2717 pThis->cbSector, offSeq + offInSeq);3379 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_UNEXPECTED_VDS_DESC, 3380 "Unexpected/unknown VDS descriptor %#x at byte offset %#RX64", 3381 pThis->cbSector, offSeq + offInSeq); 2718 3382 } 3383 if (RT_FAILURE(rc)) 3384 return rc; 2719 3385 } 2720 3386 /* The descriptor sequence is usually zero padded to 16 sectors. Just … … 2771 3437 2772 3438 /* 2773 * Reset the state before we start processing the descriptors. 3439 * Gather relevant descriptor info from the VDS then process it and on 3440 * success copy it into the instance. 2774 3441 * 2775 3442 * The processing has to be done in a different function because there may … … 2777 3444 * recursing and check that we don't go to deep. 2778 3445 */ 2779 2780 /** @todo state reset */ 2781 2782 return rtFsIsoVolReadAndProcessUdfVdsSeq(pThis, offSeq, cbSeq, pbBuf, cbBuf, 0, pErrInfo); 3446 RTFSISOVDSINFO Info; 3447 RT_ZERO(Info); 3448 int rc = rtFsIsoVolReadAndProcessUdfVdsSeq(pThis, &Info, offSeq, cbSeq, pbBuf, cbBuf, 0, pErrInfo); 3449 if (RT_SUCCESS(rc)) 3450 { 3451 rc = rtFsIsoVolProcessUdfVdsSeqInfo(pThis, &Info, pErrInfo); 3452 if (RT_SUCCESS(rc)) 3453 rc = rtFsIsoVolProcessUdfFileSetDescs(pThis, pbBuf, cbBuf, pErrInfo); 3454 } 3455 3456 /* 3457 * Clean up info. 3458 */ 3459 i = Info.cPrimaryVols; 3460 while (i-- > 0) 3461 RTMemFree(Info.apPrimaryVols[i]); 3462 3463 i = Info.cLogicalVols; 3464 while (i-- > 0) 3465 RTMemFree(Info.apLogicalVols[i]); 3466 3467 i = Info.cPartitions; 3468 while (i-- > 0) 3469 RTMemFree(Info.apPartitions[i]); 3470 3471 RTMemFree(Info.paPartMaps); 3472 3473 return rc; 2783 3474 } 2784 3475 … … 2817 3508 } 2818 3509 else 2819 rc = RTE rrInfoSetF(pErrInfo, VERR_NOT_FOUND,2820 "MainVolumeDescSeq is out of bounds: sector %#RX32 LB %#RX32 bytes, image is %#RX64 sectors",2821 pAvdp->MainVolumeDescSeq.off, pAvdp->MainVolumeDescSeq.cb, pThis->cBackingSectors);3510 rc = RTERRINFO_LOG_SET_F(pErrInfo, VERR_NOT_FOUND, 3511 "MainVolumeDescSeq is out of bounds: sector %#RX32 LB %#RX32 bytes, image is %#RX64 sectors", 3512 pAvdp->MainVolumeDescSeq.off, pAvdp->MainVolumeDescSeq.cb, pThis->cBackingSectors); 2822 3513 if (ReserveVolumeDescSeq.cb > 0) 2823 3514 { … … 2833 3524 } 2834 3525 else if (RT_SUCCESS(rc)) 2835 rc = RTE rrInfoSetF(pErrInfo, VERR_NOT_FOUND,2836 "ReserveVolumeDescSeq is out of bounds: sector %#RX32 LB %#RX32 bytes, image is %#RX64 sectors",2837 ReserveVolumeDescSeq.off, ReserveVolumeDescSeq.cb, pThis->cBackingSectors);3526 rc = RTERRINFO_LOG_SET_F(pErrInfo, VERR_NOT_FOUND, 3527 "ReserveVolumeDescSeq is out of bounds: sector %#RX32 LB %#RX32 bytes, image is %#RX64 sectors", 3528 ReserveVolumeDescSeq.off, ReserveVolumeDescSeq.cb, pThis->cBackingSectors); 2838 3529 } 2839 3530 } 2840 3531 } 2841 3532 else 2842 rc = RTE rrInfoSetF(pErrInfo, rc,2843 "Error reading sector at offset %#RX64 (anchor volume descriptor pointer): %Rrc", offAvdp, rc);3533 rc = RTERRINFO_LOG_SET_F(pErrInfo, rc, 3534 "Error reading sector at offset %#RX64 (anchor volume descriptor pointer): %Rrc", offAvdp, rc); 2844 3535 2845 3536 return rc; … … 2878 3569 * again when alternative AVDP sectors points to the same sequences. 2879 3570 */ 3571 pThis->Udf.uLevel = *puUdfLevel; 2880 3572 RTFSISOSEENSEQENCES SeenSequences = { 0 }; 2881 int rc = rtFsIsoVolReadAndHandleUdfAvdp(pThis, 256 * pThis->cbSector, pbBuf, cbBuf, 2882 &SeenSequences, pErrInfo); 2883 if (RT_FAILURE(rc)) 2884 rc = rtFsIsoVolReadAndHandleUdfAvdp(pThis, pThis->cbBacking - 256 * pThis->cbSector, 2885 pbBuf, cbBuf, &SeenSequences, pErrInfo); 2886 if (RT_FAILURE(rc)) 2887 rc = rtFsIsoVolReadAndHandleUdfAvdp(pThis, pThis->cbBacking - pThis->cbSector, 2888 pbBuf, cbBuf, &SeenSequences, pErrInfo); 2889 if (RT_SUCCESS(rc)) 2890 return rc; 2891 *puUdfLevel = 0; 3573 int rc1 = rtFsIsoVolReadAndHandleUdfAvdp(pThis, 256 * pThis->cbSector, pbBuf, cbBuf, 3574 &SeenSequences, pErrInfo); 3575 if (RT_SUCCESS(rc1)) 3576 return rc1; 3577 3578 int rc2 = rtFsIsoVolReadAndHandleUdfAvdp(pThis, pThis->cbBacking - 256 * pThis->cbSector, 3579 pbBuf, cbBuf, &SeenSequences, pErrInfo); 3580 if (RT_SUCCESS(rc2)) 3581 return rc2; 3582 3583 int rc3 = rtFsIsoVolReadAndHandleUdfAvdp(pThis, pThis->cbBacking - pThis->cbSector, 3584 pbBuf, cbBuf, &SeenSequences, pErrInfo); 3585 if (RT_SUCCESS(rc3)) 3586 return rc3; 3587 3588 /* 3589 * Return failure if the alternatives have been excluded. 3590 * 3591 * Note! The error info won't be correct here. 3592 */ 3593 pThis->Udf.uLevel = *puUdfLevel = 0; 3594 3595 if (RTFSISO9660_F_IS_ONLY_TYPE(pThis->fFlags, RTFSISO9660_F_NO_UDF)) 3596 return rc1 != VERR_NOT_FOUND ? rc1 : rc2 != VERR_NOT_FOUND ? rc2 : rc3; 2892 3597 return VINF_SUCCESS; 2893 3598 } … … 3124 3829 { 3125 3830 if (pRootDir->cbDirRec < RT_OFFSETOF(ISO9660DIRREC, achFileId)) 3126 return RTE rrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Root dir record size is too small: %#x (min %#x)",3127 pRootDir->cbDirRec, RT_OFFSETOF(ISO9660DIRREC, achFileId));3831 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Root dir record size is too small: %#x (min %#x)", 3832 pRootDir->cbDirRec, RT_OFFSETOF(ISO9660DIRREC, achFileId)); 3128 3833 3129 3834 if (!(pRootDir->fFileFlags & ISO9660_FILE_FLAGS_DIRECTORY)) 3130 return RTE rrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT,3131 "Root dir is not flagged as directory: %#x", pRootDir->fFileFlags);3835 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, 3836 "Root dir is not flagged as directory: %#x", pRootDir->fFileFlags); 3132 3837 if (pRootDir->fFileFlags & ISO9660_FILE_FLAGS_MULTI_EXTENT) 3133 return RTE rrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT,3134 "Root dir is cannot be multi-extent: %#x", pRootDir->fFileFlags);3838 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, 3839 "Root dir is cannot be multi-extent: %#x", pRootDir->fFileFlags); 3135 3840 3136 3841 if (RT_LE2H_U32(pRootDir->cbData.le) != RT_BE2H_U32(pRootDir->cbData.be)) 3137 return RTE rrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid root dir size: {%#RX32,%#RX32}",3138 RT_BE2H_U32(pRootDir->cbData.be), RT_LE2H_U32(pRootDir->cbData.le));3842 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid root dir size: {%#RX32,%#RX32}", 3843 RT_BE2H_U32(pRootDir->cbData.be), RT_LE2H_U32(pRootDir->cbData.le)); 3139 3844 if (RT_LE2H_U32(pRootDir->cbData.le) == 0) 3140 return RTE rrInfoSet(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Zero sized root dir");3845 return RTERRINFO_LOG_SET(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Zero sized root dir"); 3141 3846 3142 3847 if (RT_LE2H_U32(pRootDir->offExtent.le) != RT_BE2H_U32(pRootDir->offExtent.be)) 3143 return RTE rrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid root dir extent: {%#RX32,%#RX32}",3144 RT_BE2H_U32(pRootDir->offExtent.be), RT_LE2H_U32(pRootDir->offExtent.le));3848 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid root dir extent: {%#RX32,%#RX32}", 3849 RT_BE2H_U32(pRootDir->offExtent.be), RT_LE2H_U32(pRootDir->offExtent.le)); 3145 3850 3146 3851 if (RT_LE2H_U16(pRootDir->VolumeSeqNo.le) != RT_BE2H_U16(pRootDir->VolumeSeqNo.be)) 3147 return RTE rrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid root dir volume sequence ID: {%#RX16,%#RX16}",3148 RT_BE2H_U16(pRootDir->VolumeSeqNo.be), RT_LE2H_U16(pRootDir->VolumeSeqNo.le));3852 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid root dir volume sequence ID: {%#RX16,%#RX16}", 3853 RT_BE2H_U16(pRootDir->VolumeSeqNo.be), RT_LE2H_U16(pRootDir->VolumeSeqNo.le)); 3149 3854 if (RT_LE2H_U16(pRootDir->VolumeSeqNo.le) != pThis->idPrimaryVol) 3150 return RTE rrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,3151 "Expected root dir to have same volume sequence number as primary volume: %#x, expected %#x",3152 RT_LE2H_U16(pRootDir->VolumeSeqNo.le), pThis->idPrimaryVol);3855 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, 3856 "Expected root dir to have same volume sequence number as primary volume: %#x, expected %#x", 3857 RT_LE2H_U16(pRootDir->VolumeSeqNo.le), pThis->idPrimaryVol); 3153 3858 3154 3859 /* … … 3175 3880 { 3176 3881 if (pVolDesc->bFileStructureVersion != ISO9660_FILE_STRUCTURE_VERSION) 3177 return RTE rrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,3178 "Unsupported file structure version: %#x", pVolDesc->bFileStructureVersion);3882 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, 3883 "Unsupported file structure version: %#x", pVolDesc->bFileStructureVersion); 3179 3884 3180 3885 /* … … 3185 3890 || !RT_IS_POWER_OF_TWO(pThis->cbBlock) 3186 3891 || pThis->cbBlock / pThis->cbSector < 1) 3187 return RTE rrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid logical block size: {%#RX16,%#RX16}",3188 RT_BE2H_U16(pVolDesc->cbLogicalBlock.be), RT_LE2H_U16(pVolDesc->cbLogicalBlock.le));3892 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid logical block size: {%#RX16,%#RX16}", 3893 RT_BE2H_U16(pVolDesc->cbLogicalBlock.be), RT_LE2H_U16(pVolDesc->cbLogicalBlock.le)); 3189 3894 if (pThis->cbBlock / pThis->cbSector > 128) 3190 return RTE rrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, "Unsupported block size: %#x\n", pThis->cbBlock);3895 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, "Unsupported block size: %#x\n", pThis->cbBlock); 3191 3896 3192 3897 /* … … 3195 3900 pThis->cBlocksInPrimaryVolumeSpace = RT_LE2H_U32(pVolDesc->VolumeSpaceSize.le); 3196 3901 if (pThis->cBlocksInPrimaryVolumeSpace != RT_BE2H_U32(pVolDesc->VolumeSpaceSize.be)) 3197 return RTE rrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid volume space size: {%#RX32,%#RX32}",3198 RT_BE2H_U32(pVolDesc->VolumeSpaceSize.be), RT_LE2H_U32(pVolDesc->VolumeSpaceSize.le));3902 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid volume space size: {%#RX32,%#RX32}", 3903 RT_BE2H_U32(pVolDesc->VolumeSpaceSize.be), RT_LE2H_U32(pVolDesc->VolumeSpaceSize.le)); 3199 3904 pThis->cbPrimaryVolumeSpace = pThis->cBlocksInPrimaryVolumeSpace * (uint64_t)pThis->cbBlock; 3200 3905 … … 3205 3910 if ( pThis->cVolumesInSet != RT_BE2H_U16(pVolDesc->cVolumesInSet.be) 3206 3911 || pThis->cVolumesInSet == 0) 3207 return RTE rrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid volume set size: {%#RX16,%#RX16}",3208 RT_BE2H_U16(pVolDesc->cVolumesInSet.be), RT_LE2H_U16(pVolDesc->cVolumesInSet.le));3912 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid volume set size: {%#RX16,%#RX16}", 3913 RT_BE2H_U16(pVolDesc->cVolumesInSet.be), RT_LE2H_U16(pVolDesc->cVolumesInSet.le)); 3209 3914 if (pThis->cVolumesInSet > 32) 3210 return RTE rrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, "Too large volume set size: %#x\n", pThis->cVolumesInSet);3915 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, "Too large volume set size: %#x\n", pThis->cVolumesInSet); 3211 3916 3212 3917 /* … … 3215 3920 pThis->idPrimaryVol = RT_LE2H_U16(pVolDesc->VolumeSeqNo.le); 3216 3921 if (pThis->idPrimaryVol != RT_BE2H_U16(pVolDesc->VolumeSeqNo.be)) 3217 return RTE rrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid volume sequence ID: {%#RX16,%#RX16}",3218 RT_BE2H_U16(pVolDesc->VolumeSeqNo.be), RT_LE2H_U16(pVolDesc->VolumeSeqNo.le));3922 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid volume sequence ID: {%#RX16,%#RX16}", 3923 RT_BE2H_U16(pVolDesc->VolumeSeqNo.be), RT_LE2H_U16(pVolDesc->VolumeSeqNo.le)); 3219 3924 if ( pThis->idPrimaryVol > pThis->cVolumesInSet 3220 3925 || pThis->idPrimaryVol < 1) 3221 return RTE rrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,3222 "Volume sequence ID out of of bound: %#x (1..%#x)\n", pThis->idPrimaryVol, pThis->cVolumesInSet);3926 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, 3927 "Volume sequence ID out of of bound: %#x (1..%#x)\n", pThis->idPrimaryVol, pThis->cVolumesInSet); 3223 3928 3224 3929 /* … … 3249 3954 { 3250 3955 if (pVolDesc->bFileStructureVersion != ISO9660_FILE_STRUCTURE_VERSION) 3251 return RTE rrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,3252 "Unsupported file structure version: %#x", pVolDesc->bFileStructureVersion);3956 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, 3957 "Unsupported file structure version: %#x", pVolDesc->bFileStructureVersion); 3253 3958 3254 3959 /* … … 3274 3979 */ 3275 3980 if (pThis->cbBlock == 0) 3276 return RTE rrInfoSet(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,3277 "Supplementary joliet volume descriptor is not supported when appearing before the primary volume descriptor");3981 return RTERRINFO_LOG_SET(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, 3982 "Supplementary joliet volume descriptor is not supported when appearing before the primary volume descriptor"); 3278 3983 if (ISO9660_GET_ENDIAN(&pVolDesc->cbLogicalBlock) != pThis->cbBlock) 3279 return RTE rrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,3280 "Logical block size for joliet volume descriptor differs from primary: %#RX16 vs %#RX16\n",3281 ISO9660_GET_ENDIAN(&pVolDesc->cbLogicalBlock), pThis->cbBlock);3984 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, 3985 "Logical block size for joliet volume descriptor differs from primary: %#RX16 vs %#RX16\n", 3986 ISO9660_GET_ENDIAN(&pVolDesc->cbLogicalBlock), pThis->cbBlock); 3282 3987 if (ISO9660_GET_ENDIAN(&pVolDesc->VolumeSpaceSize) != pThis->cBlocksInPrimaryVolumeSpace) 3283 return RTE rrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,3284 "Volume space size for joliet volume descriptor differs from primary: %#RX32 vs %#RX32\n",3285 ISO9660_GET_ENDIAN(&pVolDesc->VolumeSpaceSize), pThis->cBlocksInPrimaryVolumeSpace);3988 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, 3989 "Volume space size for joliet volume descriptor differs from primary: %#RX32 vs %#RX32\n", 3990 ISO9660_GET_ENDIAN(&pVolDesc->VolumeSpaceSize), pThis->cBlocksInPrimaryVolumeSpace); 3286 3991 if (ISO9660_GET_ENDIAN(&pVolDesc->cVolumesInSet) != pThis->cVolumesInSet) 3287 return RTE rrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,3288 "Volume set size for joliet volume descriptor differs from primary: %#RX16 vs %#RX32\n",3289 ISO9660_GET_ENDIAN(&pVolDesc->cVolumesInSet), pThis->cVolumesInSet);3992 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, 3993 "Volume set size for joliet volume descriptor differs from primary: %#RX16 vs %#RX32\n", 3994 ISO9660_GET_ENDIAN(&pVolDesc->cVolumesInSet), pThis->cVolumesInSet); 3290 3995 if (ISO9660_GET_ENDIAN(&pVolDesc->VolumeSeqNo) != pThis->idPrimaryVol) 3291 return RTE rrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,3292 "Volume sequence ID for joliet volume descriptor differs from primary: %#RX16 vs %#RX32\n",3293 ISO9660_GET_ENDIAN(&pVolDesc->VolumeSeqNo), pThis->idPrimaryVol);3996 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, 3997 "Volume sequence ID for joliet volume descriptor differs from primary: %#RX16 vs %#RX32\n", 3998 ISO9660_GET_ENDIAN(&pVolDesc->VolumeSeqNo), pThis->idPrimaryVol); 3294 3999 3295 4000 if (*pbUcs2Level != 0) 3296 return RTE rrInfoSet(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, "More than one supplementary joliet volume descriptor");4001 return RTERRINFO_LOG_SET(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, "More than one supplementary joliet volume descriptor"); 3297 4002 3298 4003 /* … … 3395 4100 { 3396 4101 if (iVolDesc > 32) 3397 return RTE rrInfoSet(pErrInfo, VERR_VFS_BOGUS_FORMAT, "More than 32 volume descriptors, doesn't seem right...");4102 return RTERRINFO_LOG_SET(pErrInfo, VERR_VFS_BOGUS_FORMAT, "More than 32 volume descriptors, doesn't seem right..."); 3398 4103 3399 4104 /* Read the next one and check the signature. */ 3400 4105 rc = RTVfsFileReadAt(hVfsBacking, offVolDesc, &Buf, cbSector, NULL); 3401 4106 if (RT_FAILURE(rc)) 3402 return RTE rrInfoSetF(pErrInfo, rc, "Unable to read volume descriptor #%u", iVolDesc);4107 return RTERRINFO_LOG_SET_F(pErrInfo, rc, "Unable to read volume descriptor #%u", iVolDesc); 3403 4108 3404 4109 #define MATCH_STD_ID(a_achStdId1, a_szStdId2) \ … … 3429 4134 cPrimaryVolDescs++; 3430 4135 if (Buf.VolDescHdr.bDescVersion != ISO9660PRIMARYVOLDESC_VERSION) 3431 return RTE rrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,3432 "Unsupported primary volume descriptor version: %#x", Buf.VolDescHdr.bDescVersion);4136 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, 4137 "Unsupported primary volume descriptor version: %#x", Buf.VolDescHdr.bDescVersion); 3433 4138 #ifdef LOG_ENABLED 3434 4139 rtFsIsoVolLogPrimarySupplementaryVolDesc(&Buf.SupVolDesc); 3435 4140 #endif 3436 4141 if (cPrimaryVolDescs > 1) 3437 return RTE rrInfoSet(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, "More than one primary volume descriptor");4142 return RTERRINFO_LOG_SET(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, "More than one primary volume descriptor"); 3438 4143 rc = rtFsIsoVolHandlePrimaryVolDesc(pThis, &Buf.PrimaryVolDesc, offVolDesc, &RootDir, &offRootDirRec, pErrInfo); 3439 4144 } … … 3442 4147 cSupplementaryVolDescs++; 3443 4148 if (Buf.VolDescHdr.bDescVersion != ISO9660SUPVOLDESC_VERSION) 3444 return RTE rrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,3445 "Unsupported supplemental volume descriptor version: %#x", Buf.VolDescHdr.bDescVersion);4149 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, 4150 "Unsupported supplemental volume descriptor version: %#x", Buf.VolDescHdr.bDescVersion); 3446 4151 #ifdef LOG_ENABLED 3447 4152 rtFsIsoVolLogPrimarySupplementaryVolDesc(&Buf.SupVolDesc); … … 3457 4162 { 3458 4163 if (!cPrimaryVolDescs) 3459 return RTE rrInfoSet(pErrInfo, VERR_VFS_BOGUS_FORMAT, "No primary volume descriptor");4164 return RTERRINFO_LOG_SET(pErrInfo, VERR_VFS_BOGUS_FORMAT, "No primary volume descriptor"); 3460 4165 enmState = kStateNoSeq; 3461 4166 } 3462 4167 else 3463 return RTE rrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,3464 "Unknown volume descriptor: %#x", Buf.VolDescHdr.bDescType);4168 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, 4169 "Unknown volume descriptor: %#x", Buf.VolDescHdr.bDescType); 3465 4170 } 3466 4171 /* … … 3474 4179 enmState = kStateUdfSeq; 3475 4180 else 3476 return RTE rrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Only one BEA01 sequence is supported");4181 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Only one BEA01 sequence is supported"); 3477 4182 } 3478 4183 else if ( enmState == kStateUdfSeq … … 3488 4193 offUdfBootVolDesc = iVolDesc * cbSector; 3489 4194 else 3490 return RTE rrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Only one BOOT2 descriptor is supported");4195 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Only one BOOT2 descriptor is supported"); 3491 4196 } 3492 4197 else if ( enmState == kStateUdfSeq … … 3496 4201 enmState = kStateNoSeq; 3497 4202 else 3498 return RTE rrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Found BEA01 & TEA01, but no NSR02 or NSR03 descriptors");4203 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Found BEA01 & TEA01, but no NSR02 or NSR03 descriptors"); 3499 4204 } 3500 4205 /* … … 3504 4209 break; 3505 4210 else if (enmState == kStateStart) 3506 return RTE rrInfoSetF(pErrInfo, VERR_VFS_UNKNOWN_FORMAT,3507 "Not ISO? Unable to recognize volume descriptor signature: %.5Rhxs", Buf.VolDescHdr.achStdId);4211 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNKNOWN_FORMAT, 4212 "Not ISO? Unable to recognize volume descriptor signature: %.5Rhxs", Buf.VolDescHdr.achStdId); 3508 4213 else if (enmState == kStateCdSeq) 3509 return RTE rrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT,3510 "Missing ISO 9660 terminator volume descriptor? (Found %.5Rhxs)", Buf.VolDescHdr.achStdId);4214 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, 4215 "Missing ISO 9660 terminator volume descriptor? (Found %.5Rhxs)", Buf.VolDescHdr.achStdId); 3511 4216 else if (enmState == kStateUdfSeq) 3512 return RTE rrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT,3513 "Missing UDF terminator volume descriptor? (Found %.5Rhxs)", Buf.VolDescHdr.achStdId);4217 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, 4218 "Missing UDF terminator volume descriptor? (Found %.5Rhxs)", Buf.VolDescHdr.achStdId); 3514 4219 else 3515 return RTE rrInfoSetF(pErrInfo, VERR_VFS_UNKNOWN_FORMAT,3516 "Unknown volume descriptor signature found at sector %u: %.5Rhxs",3517 16 + iVolDesc, Buf.VolDescHdr.achStdId);4220 return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNKNOWN_FORMAT, 4221 "Unknown volume descriptor signature found at sector %u: %.5Rhxs", 4222 16 + iVolDesc, Buf.VolDescHdr.achStdId); 3518 4223 if (RT_FAILURE(rc)) 3519 4224 return rc; … … 3523 4228 * If we found a UDF VRS and are interested in UDF, we have more work to do here. 3524 4229 */ 3525 if (uUdfLevel > 0 && !(fFlags & RTFSISO9660_F_NO_UDF) && /* Just disable this code for now: */ (fFlags & RT_BIT(24))) 4230 #if 0 4231 if (uUdfLevel > 0 && !(fFlags & RTFSISO9660_F_NO_UDF) )// && /* Just disable this code for now: */ (fFlags & RT_BIT(24))) 3526 4232 { 3527 4233 Log(("rtFsIsoVolTryInit: uUdfLevel=%d\n", uUdfLevel)); … … 3530 4236 return rc; 3531 4237 } 3532 #if 0 3533 return VERR_NOT_IMPLEMENTED; 4238 4239 /* 4240 * Decide which to prefer. 4241 * 4242 * By default we pick UDF over any of the two ISO 9960, there is currently 4243 * no way to override this without using the RTFSISO9660_F_NO_XXX options. 4244 * 4245 * If there isn't UDF, we may faced with choosing between joliet and rock 4246 * ridge. The joliet option is generally favorable as we don't have to 4247 * guess wrt to the file name encoding. So, we'll pick that for now. 4248 * 4249 * Note! Should we change this preference for joliet, there fun wrt making sure 4250 * there really is rock ridge stuff in the primary volume as well as 4251 * making sure there really is anything of value in the primary volume. 4252 */ 4253 if (uUdfLevel > 0) 4254 { 4255 pThis->enmType = RTFSISOVOLTYPE_UDF; 4256 //return rtFsIsoDirShrd_NewUdf(pThis, xxx); 4257 return VERR_NOT_IMPLEMENTED; 4258 } 3534 4259 #else 4260 if (uUdfLevel > 0 && !(fFlags & RTFSISO9660_F_NO_UDF) && /* Just disable this code for now: */ (fFlags & RT_BIT(24))) 4261 rc = rtFsIsoVolHandleUdfDetection(pThis, &uUdfLevel, offUdfBootVolDesc, Buf.ab, sizeof(Buf), pErrInfo); 3535 4262 3536 4263 /* … … 3544 4271 * making sure there really is anything of value in the primary volume. 3545 4272 */ 4273 #endif 3546 4274 if (bJolietUcs2Level != 0) 3547 4275 { 4276 pThis->enmType = RTFSISOVOLTYPE_JOLIET; 3548 4277 pThis->fIsUtf16 = true; 3549 4278 return rtFsIsoDirShrd_New9660(pThis, NULL, &JolietRootDir, 1, offJolietRootDirRec, &pThis->pRootDir); 3550 4279 } 4280 pThis->enmType = RTFSISOVOLTYPE_ISO9960; 3551 4281 return rtFsIsoDirShrd_New9660(pThis, NULL, &RootDir, 1, offRootDirRec, &pThis->pRootDir); 3552 #endif3553 4282 } 3554 4283 … … 3634 4363 { 3635 4364 *poffError = pElement->paArgs[iArg].offSpec; 3636 return RTE rrInfoSet(pErrInfo, VERR_VFS_CHAIN_INVALID_ARGUMENT, "Only knows: 'nojoliet' and 'norock'");4365 return RTERRINFO_LOG_SET(pErrInfo, VERR_VFS_CHAIN_INVALID_ARGUMENT, "Only knows: 'nojoliet' and 'norock'"); 3637 4366 } 3638 4367 }
Note:
See TracChangeset
for help on using the changeset viewer.