Changeset 66765 in vbox for trunk/src/VBox/Runtime/common/fs/iso9660vfs.cpp
- Timestamp:
- May 3, 2017 11:59:50 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fs/iso9660vfs.cpp
r66762 r66765 57 57 58 58 /** Pointer to a ISO 9660 directory instance. */ 59 typedef struct RTFSISO9660DIR *PRTFSISO9660DIR;59 typedef struct RTFSISO9660DIRSHRD *PRTFSISO9660DIRSHRD; 60 60 61 61 … … 78 78 79 79 /** 80 * ISO 9660 file system object (common part to files and dirs).81 */ 82 typedef struct RTFSISO9660 OBJ83 { 84 /** The parent directory keeps a list of open objects (RTFSISO9660 OBJ). */80 * ISO 9660 file system object, shared part. 81 */ 82 typedef struct RTFSISO9660CORE 83 { 84 /** The parent directory keeps a list of open objects (RTFSISO9660CORE). */ 85 85 RTLISTNODE Entry; 86 /** Reference counter. */ 87 uint32_t volatile cRefs; 86 88 /** The parent directory (not released till all children are close). */ 87 PRTFSISO9660DIR pParentDir;89 PRTFSISO9660DIRSHRD pParentDir; 88 90 /** The byte offset of the first directory record. */ 89 91 uint64_t offDirRec; … … 108 110 /** Array of additional extents. */ 109 111 PRTFSISO9660EXTENT paExtents; 110 } RTFSISO9660 OBJ;111 typedef RTFSISO9660 OBJ *PRTFSISO9660OBJ;112 113 /** 114 * ISO 9660 file .115 */ 116 typedef struct RTFSISO9660FILE 112 } RTFSISO9660CORE; 113 typedef RTFSISO9660CORE *PRTFSISO9660CORE; 114 115 /** 116 * ISO 9660 file, shared data. 117 */ 118 typedef struct RTFSISO9660FILESHRD 117 119 { 118 120 /** Core ISO9660 object info. */ 119 RTFSISO9660OBJ Core; 120 /** The current file offset. */ 121 uint64_t offFile; 122 } RTFSISO9660FILE; 121 RTFSISO9660CORE Core; 122 } RTFSISO9660FILESHRD; 123 123 /** Pointer to a ISO 9660 file object. */ 124 typedef RTFSISO9660FILE *PRTFSISO9660FILE;125 126 127 /** 128 * ISO 9660 directory .124 typedef RTFSISO9660FILESHRD *PRTFSISO9660FILESHRD; 125 126 127 /** 128 * ISO 9660 directory, shared data. 129 129 * 130 130 * We will always read in the whole directory just to keep things really simple. 131 131 */ 132 typedef struct RTFSISO9660DIR 132 typedef struct RTFSISO9660DIRSHRD 133 133 { 134 134 /** Core ISO 9660 object info. */ 135 RTFSISO9660OBJ Core; 136 /** The VFS handle for this directory (for reference counting). */ 137 RTVFSDIR hVfsSelf; 138 /** Open child objects (RTFSISO9660OBJ). */ 135 RTFSISO9660CORE Core; 136 /** Open child objects (RTFSISO9660CORE). */ 139 137 RTLISTNODE OpenChildren; 140 138 … … 143 141 /** The size of the directory content (duplicate of Core.cbObject). */ 144 142 uint32_t cbDir; 145 } RTFSISO9660DIR ;143 } RTFSISO9660DIRSHRD; 146 144 /** Pointer to a ISO 9660 directory instance. */ 147 typedef RTFSISO9660DIR *PRTFSISO9660DIR; 148 145 typedef RTFSISO9660DIRSHRD *PRTFSISO9660DIRSHRD; 146 147 148 /** 149 * Private data for a VFS file object. 150 */ 151 typedef struct RTFSISO9660FILEOBJ 152 { 153 /** Pointer to the shared data. */ 154 PRTFSISO9660FILESHRD pShared; 155 /** The current file offset. */ 156 uint64_t offFile; 157 } RTFSISO9660FILEOBJ; 158 typedef RTFSISO9660FILEOBJ *PRTFSISO9660FILEOBJ; 159 160 /** 161 * Private data for a VFS directory object. 162 */ 163 typedef struct RTFSISO9660DIROBJ 164 { 165 /** Pointer to the shared data. */ 166 PRTFSISO9660DIRSHRD pShared; 167 /** The current directory offset. */ 168 uint32_t offDir; 169 } RTFSISO9660DIROBJ; 170 typedef RTFSISO9660DIROBJ *PRTFSISO9660DIROBJ; 149 171 150 172 … … 155 177 { 156 178 /** Handle to itself. */ 157 RTVFS hVfsSelf;179 RTVFS hVfsSelf; 158 180 /** The file, partition, or whatever backing the ISO 9660 volume. */ 159 RTVFSFILE hVfsBacking;181 RTVFSFILE hVfsBacking; 160 182 /** The size of the backing thingy. */ 161 uint64_t cbBacking;183 uint64_t cbBacking; 162 184 /** Flags. */ 163 uint32_t fFlags;185 uint32_t fFlags; 164 186 /** The sector size (in bytes). */ 165 uint32_t cbSector;187 uint32_t cbSector; 166 188 /** The size of a logical block in bytes. */ 167 uint32_t cbBlock;189 uint32_t cbBlock; 168 190 /** The primary volume space size in blocks. */ 169 uint32_t cBlocksInPrimaryVolumeSpace;191 uint32_t cBlocksInPrimaryVolumeSpace; 170 192 /** The primary volume space size in bytes. */ 171 uint64_t cbPrimaryVolumeSpace;193 uint64_t cbPrimaryVolumeSpace; 172 194 /** The number of volumes in the set. */ 173 uint32_t cVolumesInSet;195 uint32_t cVolumesInSet; 174 196 /** The primary volume sequence ID. */ 175 uint32_t idPrimaryVol;197 uint32_t idPrimaryVol; 176 198 /** Set if using UTF16-2 (joliet). */ 177 bool fIsUtf16; 178 179 /** The root directory handle. */ 180 RTVFSDIR hVfsRootDir; 181 /** The root directory instance data. */ 182 PRTFSISO9660DIR pRootDir; 199 bool fIsUtf16; 200 201 /** The root directory shared data. */ 202 PRTFSISO9660DIRSHRD pRootDir; 183 203 } RTFSISO9660VOL; 184 204 … … 193 213 * Internal Functions * 194 214 *********************************************************************************************************************************/ 195 static void rtFsIso9660Dir_AddOpenChild(PRTFSISO9660DIR pDir, PRTFSISO9660OBJ pChild); 196 static void rtFsIso9660Dir_RemoveOpenChild(PRTFSISO9660DIR pDir, PRTFSISO9660OBJ pChild); 197 static int rtFsIso9660Dir_New(PRTFSISO9660VOL pThis, PRTFSISO9660DIR pParentDir, PCISO9660DIRREC pDirRec, uint32_t cDirRecs, 198 uint64_t offDirRec, PRTVFSDIR phVfsDir, PRTFSISO9660DIR *ppDir); 215 static void rtFsIso9660DirShrd_AddOpenChild(PRTFSISO9660DIRSHRD pDir, PRTFSISO9660CORE pChild); 216 static void rtFsIso9660DirShrd_RemoveOpenChild(PRTFSISO9660DIRSHRD pDir, PRTFSISO9660CORE pChild); 217 static int rtFsIso9660Dir_New(PRTFSISO9660VOL pThis, PRTFSISO9660DIRSHRD pParentDir, PCISO9660DIRREC pDirRec, 218 uint32_t cDirRecs, uint64_t offDirRec, PRTVFSDIR phVfsDir); 219 static PRTFSISO9660CORE rtFsIso9660Dir_LookupShared(PRTFSISO9660DIRSHRD pThis, uint64_t offDirRec); 199 220 200 221 … … 229 250 230 251 /** 231 * Initialization of a RTFSISO9660 OBJstructure from a directory record.232 * 233 * @note The RTFSISO9660 OBJ::pParentDir and RTFSISO9660OBJ::Clusters members are252 * Initialization of a RTFSISO9660CORE structure from a directory record. 253 * 254 * @note The RTFSISO9660CORE::pParentDir and RTFSISO9660CORE::Clusters members are 234 255 * properly initialized elsewhere. 235 256 * 236 * @param p ObjThe structure to initialize.257 * @param pCore The structure to initialize. 237 258 * @param pDirRec The primary directory record. 238 259 * @param cDirRecs Number of directory records. … … 240 261 * @param pVol The volume. 241 262 */ 242 static void rtFsIso9660 Obj_InitFromDirRec(PRTFSISO9660OBJ pObj, PCISO9660DIRREC pDirRec, uint32_t cDirRecs,243 uint64_t offDirRec, PRTFSISO9660VOL pVol)263 static void rtFsIso9660Core_InitFromDirRec(PRTFSISO9660CORE pCore, PCISO9660DIRREC pDirRec, uint32_t cDirRecs, 264 uint64_t offDirRec, PRTFSISO9660VOL pVol) 244 265 { 245 266 Assert(cDirRecs == 1); RT_NOREF(cDirRecs); 246 267 247 RTListInit(&pObj->Entry); 248 pObj->pParentDir = NULL; 249 pObj->pVol = pVol; 250 pObj->offDirRec = offDirRec; 251 pObj->fAttrib = pDirRec->fFileFlags & ISO9660_FILE_FLAGS_DIRECTORY 252 ? RTFS_DOS_DIRECTORY | RTFS_TYPE_DIRECTORY : RTFS_TYPE_FILE; 268 RTListInit(&pCore->Entry); 269 pCore->cRefs = 1; 270 pCore->pParentDir = NULL; 271 pCore->pVol = pVol; 272 pCore->offDirRec = offDirRec; 273 pCore->fAttrib = pDirRec->fFileFlags & ISO9660_FILE_FLAGS_DIRECTORY 274 ? RTFS_DOS_DIRECTORY | RTFS_TYPE_DIRECTORY : RTFS_TYPE_FILE; 253 275 if (pDirRec->fFileFlags & ISO9660_FILE_FLAGS_HIDDEN) 254 pObj->fAttrib |= RTFS_DOS_HIDDEN; 255 pObj->cbObject = ISO9660_GET_ENDIAN(&pDirRec->cbData); 256 pObj->cExtents = 1; 257 pObj->FirstExtent.cbExtent = pObj->cbObject; 258 pObj->FirstExtent.offDisk = ISO9660_GET_ENDIAN(&pDirRec->offExtent) * (uint64_t)pVol->cbBlock; 259 260 rtFsIso9660DateTime2TimeSpec(&pObj->ModificationTime, &pDirRec->RecTime); 261 pObj->BirthTime = pObj->ModificationTime; 262 pObj->AccessTime = pObj->ModificationTime; 263 pObj->ChangeTime = pObj->ModificationTime; 264 } 265 266 267 268 /** 269 * Worker for rtFsIso9660File_Close and rtFsIso9660Dir_Close that does common work. 270 * 271 * @returns IPRT status code. 272 * @param pObj The common object structure. 273 */ 274 static int rtFsIso9660Obj_Close(PRTFSISO9660OBJ pObj) 275 { 276 if (pObj->pParentDir) 277 rtFsIso9660Dir_RemoveOpenChild(pObj->pParentDir, pObj); 278 if (pObj->paExtents) 279 { 280 RTMemFree(pObj->paExtents); 281 pObj->paExtents = NULL; 282 } 283 return VINF_SUCCESS; 284 } 285 286 287 /** 288 * @interface_method_impl{RTVFSOBJOPS,pfnClose} 289 */ 290 static DECLCALLBACK(int) rtFsIso9660File_Close(void *pvThis) 291 { 292 PRTFSISO9660FILE pThis = (PRTFSISO9660FILE)pvThis; 293 LogFlow(("rtFsIso9660File_Close(%p)\n", pThis)); 294 return rtFsIso9660Obj_Close(&pThis->Core); 295 } 296 297 298 /** 299 * @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo} 300 */ 301 static DECLCALLBACK(int) rtFsIso9660Obj_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr) 302 { 303 PRTFSISO9660OBJ pThis = (PRTFSISO9660OBJ)pvThis; 304 305 pObjInfo->cbObject = pThis->cbObject; 306 pObjInfo->cbAllocated = RT_ALIGN_64(pThis->cbObject, pThis->pVol->cbBlock); 307 pObjInfo->AccessTime = pThis->AccessTime; 308 pObjInfo->ModificationTime = pThis->ModificationTime; 309 pObjInfo->ChangeTime = pThis->ChangeTime; 310 pObjInfo->BirthTime = pThis->BirthTime; 311 pObjInfo->Attr.fMode = pThis->fAttrib; 276 pCore->fAttrib |= RTFS_DOS_HIDDEN; 277 pCore->cbObject = ISO9660_GET_ENDIAN(&pDirRec->cbData); 278 pCore->cExtents = 1; 279 pCore->FirstExtent.cbExtent = pCore->cbObject; 280 pCore->FirstExtent.offDisk = ISO9660_GET_ENDIAN(&pDirRec->offExtent) * (uint64_t)pVol->cbBlock; 281 282 rtFsIso9660DateTime2TimeSpec(&pCore->ModificationTime, &pDirRec->RecTime); 283 pCore->BirthTime = pCore->ModificationTime; 284 pCore->AccessTime = pCore->ModificationTime; 285 pCore->ChangeTime = pCore->ModificationTime; 286 } 287 288 289 /** 290 * Worker for rtFsIso9660File_QueryInfo and rtFsIso9660Dir_QueryInfo. 291 */ 292 static int rtFsIso9660Core_QueryInfo(PRTFSISO9660CORE pCore, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr) 293 { 294 pObjInfo->cbObject = pCore->cbObject; 295 pObjInfo->cbAllocated = RT_ALIGN_64(pCore->cbObject, pCore->pVol->cbBlock); 296 pObjInfo->AccessTime = pCore->AccessTime; 297 pObjInfo->ModificationTime = pCore->ModificationTime; 298 pObjInfo->ChangeTime = pCore->ChangeTime; 299 pObjInfo->BirthTime = pCore->BirthTime; 300 pObjInfo->Attr.fMode = pCore->fAttrib; 312 301 pObjInfo->Attr.enmAdditional = enmAddAttr; 313 302 … … 344 333 345 334 /** 335 * Worker for rtFsIso9660File_Close and rtFsIso9660Dir_Close that does common work. 336 * 337 * @param pCore The common shared structure. 338 */ 339 static void rtFsIso9660Core_Destroy(PRTFSISO9660CORE pCore) 340 { 341 if (pCore->pParentDir) 342 rtFsIso9660DirShrd_RemoveOpenChild(pCore->pParentDir, pCore); 343 if (pCore->paExtents) 344 { 345 RTMemFree(pCore->paExtents); 346 pCore->paExtents = NULL; 347 } 348 } 349 350 351 /** 352 * @interface_method_impl{RTVFSOBJOPS,pfnClose} 353 */ 354 static DECLCALLBACK(int) rtFsIso9660File_Close(void *pvThis) 355 { 356 PRTFSISO9660FILEOBJ pThis = (PRTFSISO9660FILEOBJ)pvThis; 357 LogFlow(("rtFsIso9660File_Close(%p/%p)\n", pThis, pThis->pShared)); 358 359 PRTFSISO9660FILESHRD pShared = pThis->pShared; 360 pThis->pShared = NULL; 361 if (pShared) 362 { 363 if (ASMAtomicDecU32(&pShared->Core.cRefs) == 0) 364 { 365 LogFlow(("rtFsIso9660File_Close: Destroying shared structure %p\n", pShared)); 366 rtFsIso9660Core_Destroy(&pShared->Core); 367 RTMemFree(pShared); 368 } 369 } 370 return VINF_SUCCESS; 371 } 372 373 374 /** 375 * @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo} 376 */ 377 static DECLCALLBACK(int) rtFsIso9660File_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr) 378 { 379 PRTFSISO9660FILEOBJ pThis = (PRTFSISO9660FILEOBJ)pvThis; 380 return rtFsIso9660Core_QueryInfo(&pThis->pShared->Core, pObjInfo, enmAddAttr); 381 } 382 383 384 /** 346 385 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnRead} 347 386 */ 348 387 static DECLCALLBACK(int) rtFsIso9660File_Read(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead) 349 388 { 350 PRTFSISO9660FILE pThis = (PRTFSISO9660FILE)pvThis; 389 PRTFSISO9660FILEOBJ pThis = (PRTFSISO9660FILEOBJ)pvThis; 390 PRTFSISO9660FILESHRD pShared = pThis->pShared; 351 391 AssertReturn(pSgBuf->cSegs != 0, VERR_INTERNAL_ERROR_3); 352 392 RT_NOREF(fBlocking); … … 357 397 if (off == -1) 358 398 off = pThis->offFile; 359 if ((uint64_t)off >= p This->Core.cbObject)399 if ((uint64_t)off >= pShared->Core.cbObject) 360 400 { 361 401 if (pcbRead) … … 373 413 int rc = VINF_SUCCESS; 374 414 size_t cbRead = 0; 375 uint64_t cbFileLeft = p This->Core.cbObject - (uint64_t)off;415 uint64_t cbFileLeft = pShared->Core.cbObject - (uint64_t)off; 376 416 size_t cbLeft = pSgBuf->paSegs[0].cbSeg; 377 417 uint8_t *pbDst = (uint8_t *)pSgBuf->paSegs[0].pvSeg; 378 if (p This->Core.cExtents == 1)418 if (pShared->Core.cExtents == 1) 379 419 { 380 420 if (cbLeft > 0) … … 383 423 if (cbToRead > cbFileLeft) 384 424 cbToRead = (size_t)cbFileLeft; 385 rc = RTVfsFileReadAt(p This->Core.pVol->hVfsBacking, pThis->Core.FirstExtent.offDisk + off, pbDst, cbToRead, NULL);425 rc = RTVfsFileReadAt(pShared->Core.pVol->hVfsBacking, pShared->Core.FirstExtent.offDisk + off, pbDst, cbToRead, NULL); 386 426 if (RT_SUCCESS(rc)) 387 427 { … … 466 506 static DECLCALLBACK(int) rtFsIso9660File_Tell(void *pvThis, PRTFOFF poffActual) 467 507 { 468 PRTFSISO9660FILE pThis = (PRTFSISO9660FILE)pvThis;508 PRTFSISO9660FILEOBJ pThis = (PRTFSISO9660FILEOBJ)pvThis; 469 509 *poffActual = pThis->offFile; 470 510 return VINF_SUCCESS; … … 475 515 * @interface_method_impl{RTVFSOBJSETOPS,pfnMode} 476 516 */ 477 static DECLCALLBACK(int) rtFsIso9660 Obj_SetMode(void *pvThis, RTFMODE fMode, RTFMODE fMask)517 static DECLCALLBACK(int) rtFsIso9660File_SetMode(void *pvThis, RTFMODE fMode, RTFMODE fMask) 478 518 { 479 519 RT_NOREF(pvThis, fMode, fMask); … … 485 525 * @interface_method_impl{RTVFSOBJSETOPS,pfnSetTimes} 486 526 */ 487 static DECLCALLBACK(int) rtFsIso9660 Obj_SetTimes(void *pvThis, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,527 static DECLCALLBACK(int) rtFsIso9660File_SetTimes(void *pvThis, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime, 488 528 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime) 489 529 { … … 496 536 * @interface_method_impl{RTVFSOBJSETOPS,pfnSetOwner} 497 537 */ 498 static DECLCALLBACK(int) rtFsIso9660 Obj_SetOwner(void *pvThis, RTUID uid, RTGID gid)538 static DECLCALLBACK(int) rtFsIso9660File_SetOwner(void *pvThis, RTUID uid, RTGID gid) 499 539 { 500 540 RT_NOREF(pvThis, uid, gid); … … 508 548 static DECLCALLBACK(int) rtFsIso9660File_Seek(void *pvThis, RTFOFF offSeek, unsigned uMethod, PRTFOFF poffActual) 509 549 { 510 PRTFSISO9660FILE pThis = (PRTFSISO9660FILE)pvThis;550 PRTFSISO9660FILEOBJ pThis = (PRTFSISO9660FILEOBJ)pvThis; 511 551 RTFOFF offNew; 512 552 switch (uMethod) … … 516 556 break; 517 557 case RTFILE_SEEK_END: 518 offNew = (RTFOFF)pThis-> Core.cbObject + offSeek;558 offNew = (RTFOFF)pThis->pShared->Core.cbObject + offSeek; 519 559 break; 520 560 case RTFILE_SEEK_CURRENT: … … 543 583 static DECLCALLBACK(int) rtFsIso9660File_QuerySize(void *pvThis, uint64_t *pcbFile) 544 584 { 545 PRTFSISO9660FILE pThis = (PRTFSISO9660FILE)pvThis;546 *pcbFile = pThis-> Core.cbObject;585 PRTFSISO9660FILEOBJ pThis = (PRTFSISO9660FILEOBJ)pvThis; 586 *pcbFile = pThis->pShared->Core.cbObject; 547 587 return VINF_SUCCESS; 548 588 } … … 552 592 * FAT file operations. 553 593 */ 554 DECL_HIDDEN_CONST(const RTVFSFILEOPS) g_rtFsI so9660FileOps =594 DECL_HIDDEN_CONST(const RTVFSFILEOPS) g_rtFsIos9660FileOps = 555 595 { 556 596 { /* Stream */ … … 560 600 "FatFile", 561 601 rtFsIso9660File_Close, 562 rtFsIso9660 Obj_QueryInfo,602 rtFsIso9660File_QueryInfo, 563 603 RTVFSOBJOPS_VERSION 564 604 }, … … 579 619 RTVFSOBJSETOPS_VERSION, 580 620 RT_OFFSETOF(RTVFSFILEOPS, Stream.Obj) - RT_OFFSETOF(RTVFSFILEOPS, ObjSet), 581 rtFsIso9660 Obj_SetMode,582 rtFsIso9660 Obj_SetTimes,583 rtFsIso9660 Obj_SetOwner,621 rtFsIso9660File_SetMode, 622 rtFsIso9660File_SetTimes, 623 rtFsIso9660File_SetOwner, 584 624 RTVFSOBJSETOPS_VERSION 585 625 }, … … 595 635 * @returns IPRT status code. 596 636 * @param pThis The FAT volume instance. 597 * @param pParentDir The parent directory .637 * @param pParentDir The parent directory (shared part). 598 638 * @param pDirRec The directory record. 599 639 * @param cDirRecs Number of directory records if more than one. … … 604 644 * @param phVfsFile Where to return the file handle. 605 645 */ 606 static int rtFsIso9660File_New(PRTFSISO9660VOL pThis, PRTFSISO9660DIR pParentDir, PCISO9660DIRREC pDirRec, uint32_t cDirRecs,607 646 static int rtFsIso9660File_New(PRTFSISO9660VOL pThis, PRTFSISO9660DIRSHRD pParentDir, PCISO9660DIRREC pDirRec, uint32_t cDirRecs, 647 uint64_t offDirRec, uint64_t fOpen, PRTVFSFILE phVfsFile) 608 648 { 609 649 AssertPtr(pParentDir); 610 650 611 PRTFSISO9660FILE pNewFile; 612 int rc = RTVfsNewFile(&g_rtFsIso9660FileOps, sizeof(*pNewFile), fOpen, pThis->hVfsSelf, NIL_RTVFSLOCK /*use volume lock*/, 651 /* 652 * Create a VFS object. 653 */ 654 PRTFSISO9660FILEOBJ pNewFile; 655 int rc = RTVfsNewFile(&g_rtFsIos9660FileOps, sizeof(*pNewFile), fOpen, pThis->hVfsSelf, NIL_RTVFSLOCK /*use volume lock*/, 613 656 phVfsFile, (void **)&pNewFile); 614 657 if (RT_SUCCESS(rc)) 615 658 { 616 659 /* 617 * Initialize it all so rtFsIso9660File_Close doesn't trip up in anyway.660 * Look for existing shared object, create a new one if necessary. 618 661 */ 619 rtFsIso9660Obj_InitFromDirRec(&pNewFile->Core, pDirRec, cDirRecs, offDirRec, pThis); 620 pNewFile->offFile = 0; 621 622 /* 623 * Link into parent directory so we can use it to update 624 * our directory entry. 625 */ 626 rtFsIso9660Dir_AddOpenChild(pParentDir, &pNewFile->Core); 627 628 return VINF_SUCCESS; 629 662 PRTFSISO9660FILESHRD pShared = (PRTFSISO9660FILESHRD)rtFsIso9660Dir_LookupShared(pParentDir, offDirRec); 663 if (!pShared) 664 { 665 pShared = (PRTFSISO9660FILESHRD)RTMemAllocZ(sizeof(*pShared)); 666 if (pShared) 667 { 668 /* 669 * Initialize it all so rtFsIso9660File_Close doesn't trip up in anyway. 670 */ 671 rtFsIso9660Core_InitFromDirRec(&pShared->Core, pDirRec, cDirRecs, offDirRec, pThis); 672 rtFsIso9660DirShrd_AddOpenChild(pParentDir, &pShared->Core); 673 } 674 } 675 if (pShared) 676 { 677 pNewFile->offFile = 0; 678 pNewFile->pShared = pShared; 679 return VINF_SUCCESS; 680 } 681 682 rc = VERR_NO_MEMORY; 630 683 } 631 684 *phVfsFile = NIL_RTVFSFILE; … … 652 705 } 653 706 707 708 /** 709 * Looks up the shared structure for a child. 710 * 711 * @returns Referenced pointer to the shared structure, NULL if not found. 712 * @param pThis The directory. 713 * @param offDirRec The directory record offset of the child. 714 */ 715 static PRTFSISO9660CORE rtFsIso9660Dir_LookupShared(PRTFSISO9660DIRSHRD pThis, uint64_t offDirRec) 716 { 717 PRTFSISO9660CORE pCur; 718 RTListForEach(&pThis->OpenChildren, pCur, RTFSISO9660CORE, Entry) 719 { 720 if (pCur->offDirRec == offDirRec) 721 { 722 uint32_t cRefs = ASMAtomicIncU32(&pCur->cRefs); 723 Assert(cRefs > 1); 724 return pCur; 725 } 726 } 727 return NULL; 728 } 654 729 655 730 … … 669 744 * @param pfMode Where to return the file type, rock ridge adjusted. 670 745 */ 671 static int rtFsIso9660Dir_FindEntry(PRTFSISO9660DIR pThis, const char *pszEntry, uint64_t *poffDirRec, PCISO9660DIRREC *ppDirRec,672 uint 32_t *pcDirRecs, PRTFMODE pfMode)746 static int rtFsIso9660Dir_FindEntry(PRTFSISO9660DIRSHRD pThis, const char *pszEntry, 747 uint64_t *poffDirRec, PCISO9660DIRREC *ppDirRec, uint32_t *pcDirRecs, PRTFMODE pfMode) 673 748 { 674 749 /* Set return values. */ … … 773 848 774 849 /** 850 * Releases a reference to a shared directory structure. 851 * 852 * @param pShared The shared directory structure. 853 */ 854 static void rtFsIso9660DirShrd_Release(PRTFSISO9660DIRSHRD pShared) 855 { 856 uint32_t cRefs = ASMAtomicDecU32(&pShared->Core.cRefs); 857 Assert(cRefs < UINT32_MAX / 2); 858 if (cRefs == 0) 859 { 860 LogFlow(("rtFsIso9660DirShrd_Release: Destroying shared structure %p\n", pShared)); 861 Assert(pShared->Core.cRefs == 0); 862 if (pShared->pbDir) 863 { 864 RTMemFree(pShared->pbDir); 865 pShared->pbDir = NULL; 866 } 867 rtFsIso9660Core_Destroy(&pShared->Core); 868 RTMemFree(pShared); 869 } 870 } 871 872 873 /** 874 * Retains a reference to a shared directory structure. 875 * 876 * @param pShared The shared directory structure. 877 */ 878 static void rtFsIso9660DirShrd_Retain(PRTFSISO9660DIRSHRD pShared) 879 { 880 uint32_t cRefs = ASMAtomicIncU32(&pShared->Core.cRefs); 881 Assert(cRefs > 1); NOREF(cRefs); 882 } 883 884 885 886 /** 775 887 * @interface_method_impl{RTVFSOBJOPS,pfnClose} 776 888 */ 777 889 static DECLCALLBACK(int) rtFsIso9660Dir_Close(void *pvThis) 778 890 { 779 PRTFSISO9660DIR pThis = (PRTFSISO9660DIR)pvThis; 780 LogFlow(("rtFsIso9660Dir_Close(%p)\n", pThis)); 781 if (pThis->pbDir) 782 { 783 RTMemFree(pThis->pbDir); 784 pThis->pbDir = NULL; 785 } 786 return rtFsIso9660Obj_Close(&pThis->Core); 891 PRTFSISO9660DIROBJ pThis = (PRTFSISO9660DIROBJ)pvThis; 892 LogFlow(("rtFsIso9660Dir_Close(%p/%p)\n", pThis, pThis->pShared)); 893 894 PRTFSISO9660DIRSHRD pShared = pThis->pShared; 895 pThis->pShared = NULL; 896 if (pShared) 897 rtFsIso9660DirShrd_Release(pShared); 898 return VINF_SUCCESS; 899 } 900 901 902 /** 903 * @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo} 904 */ 905 static DECLCALLBACK(int) rtFsIso9660Dir_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr) 906 { 907 PRTFSISO9660DIROBJ pThis = (PRTFSISO9660DIROBJ)pvThis; 908 return rtFsIso9660Core_QueryInfo(&pThis->pShared->Core, pObjInfo, enmAddAttr); 909 } 910 911 912 /** 913 * @interface_method_impl{RTVFSOBJSETOPS,pfnMode} 914 */ 915 static DECLCALLBACK(int) rtFsIso9660Dir_SetMode(void *pvThis, RTFMODE fMode, RTFMODE fMask) 916 { 917 RT_NOREF(pvThis, fMode, fMask); 918 return VERR_WRITE_PROTECT; 919 } 920 921 922 /** 923 * @interface_method_impl{RTVFSOBJSETOPS,pfnSetTimes} 924 */ 925 static DECLCALLBACK(int) rtFsIso9660Dir_SetTimes(void *pvThis, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime, 926 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime) 927 { 928 RT_NOREF(pvThis, pAccessTime, pModificationTime, pChangeTime, pBirthTime); 929 return VERR_WRITE_PROTECT; 930 } 931 932 933 /** 934 * @interface_method_impl{RTVFSOBJSETOPS,pfnSetOwner} 935 */ 936 static DECLCALLBACK(int) rtFsIso9660Dir_SetOwner(void *pvThis, RTUID uid, RTGID gid) 937 { 938 RT_NOREF(pvThis, uid, gid); 939 return VERR_WRITE_PROTECT; 787 940 } 788 941 … … 808 961 *phVfsDir = NIL_RTVFSDIR; 809 962 810 PRTFSISO9660DIR pThis = (PRTFSISO9660DIR)pvThis; 811 PCISO9660DIRREC pDirRec; 812 uint64_t offDirRec; 813 uint32_t cDirRecs; 814 RTFMODE fMode; 815 rc = rtFsIso9660Dir_FindEntry(pThis, pszEntry, &offDirRec, &pDirRec, &cDirRecs, &fMode); 963 PRTFSISO9660DIROBJ pThis = (PRTFSISO9660DIROBJ)pvThis; 964 PRTFSISO9660DIRSHRD pShared = pThis->pShared; 965 PCISO9660DIRREC pDirRec; 966 uint64_t offDirRec; 967 uint32_t cDirRecs; 968 RTFMODE fMode; 969 rc = rtFsIso9660Dir_FindEntry(pShared, pszEntry, &offDirRec, &pDirRec, &cDirRecs, &fMode); 816 970 Log2(("rtFsIso9660Dir_TraversalOpen: FindEntry(,%s,) -> %Rrc\n", pszEntry, rc)); 817 971 if (RT_SUCCESS(rc)) … … 820 974 { 821 975 case RTFS_TYPE_DIRECTORY: 822 rc = rtFsIso9660Dir_New(p This->Core.pVol, pThis, pDirRec, cDirRecs, offDirRec, phVfsDir, NULL /*ppDir*/);976 rc = rtFsIso9660Dir_New(pShared->Core.pVol, pShared, pDirRec, cDirRecs, offDirRec, phVfsDir); 823 977 break; 824 978 … … 853 1007 static DECLCALLBACK(int) rtFsIso9660Dir_OpenFile(void *pvThis, const char *pszFilename, uint32_t fOpen, PRTVFSFILE phVfsFile) 854 1008 { 855 PRTFSISO9660DIR pThis = (PRTFSISO9660DIR)pvThis; 1009 PRTFSISO9660DIROBJ pThis = (PRTFSISO9660DIROBJ)pvThis; 1010 PRTFSISO9660DIRSHRD pShared = pThis->pShared; 856 1011 857 1012 /* … … 869 1024 uint32_t cDirRecs; 870 1025 RTFMODE fMode; 871 int rc = rtFsIso9660Dir_FindEntry(p This, pszFilename, &offDirRec, &pDirRec, &cDirRecs, &fMode);1026 int rc = rtFsIso9660Dir_FindEntry(pShared, pszFilename, &offDirRec, &pDirRec, &cDirRecs, &fMode); 872 1027 Log2(("rtFsIso9660Dir_OpenFile: FindEntry(,%s,) -> %Rrc\n", pszFilename, rc)); 873 1028 if (RT_SUCCESS(rc)) … … 876 1031 { 877 1032 case RTFS_TYPE_FILE: 878 rc = rtFsIso9660File_New(p This->Core.pVol, pThis, pDirRec, cDirRecs, offDirRec, fOpen, phVfsFile);1033 rc = rtFsIso9660File_New(pShared->Core.pVol, pShared, pDirRec, cDirRecs, offDirRec, fOpen, phVfsFile); 879 1034 break; 880 1035 … … 953 1108 * Try locate the entry. 954 1109 */ 955 PRTFSISO9660DIR pThis = (PRTFSISO9660DIR)pvThis; 956 PCISO9660DIRREC pDirRec; 957 uint64_t offDirRec; 958 uint32_t cDirRecs; 959 RTFMODE fMode; 960 int rc = rtFsIso9660Dir_FindEntry(pThis, pszEntry, &offDirRec, &pDirRec, &cDirRecs, &fMode); 1110 PRTFSISO9660DIROBJ pThis = (PRTFSISO9660DIROBJ)pvThis; 1111 PRTFSISO9660DIRSHRD pShared = pThis->pShared; 1112 PCISO9660DIRREC pDirRec; 1113 uint64_t offDirRec; 1114 uint32_t cDirRecs; 1115 RTFMODE fMode; 1116 int rc = rtFsIso9660Dir_FindEntry(pShared, pszEntry, &offDirRec, &pDirRec, &cDirRecs, &fMode); 961 1117 Log2(("rtFsIso9660Dir_QueryEntryInfo: FindEntry(,%s,) -> %Rrc\n", pszEntry, rc)); 962 1118 if (RT_SUCCESS(rc)) 963 1119 { 964 1120 /* 965 * To avoid duplicating code in rtFsIso9660 Obj_InitFromDirRec and966 * rtFsIso9660 Obj_QueryInfo, we create a dummy RTFSISO9660OBJon the stack.1121 * To avoid duplicating code in rtFsIso9660Core_InitFromDirRec and 1122 * rtFsIso9660Core_QueryInfo, we create a dummy RTFSISO9660CORE on the stack. 967 1123 */ 968 RTFSISO9660 OBJTmpObj;1124 RTFSISO9660CORE TmpObj; 969 1125 RT_ZERO(TmpObj); 970 rtFsIso9660 Obj_InitFromDirRec(&TmpObj, pDirRec, cDirRecs, offDirRec, pThis->Core.pVol);971 rc = rtFsIso9660 Obj_QueryInfo(&TmpObj, pObjInfo, enmAddAttr);1126 rtFsIso9660Core_InitFromDirRec(&TmpObj, pDirRec, cDirRecs, offDirRec, pShared->Core.pVol); 1127 rc = rtFsIso9660Core_QueryInfo(&TmpObj, pObjInfo, enmAddAttr); 972 1128 } 973 1129 return rc; … … 1028 1184 "ISO 9660 Dir", 1029 1185 rtFsIso9660Dir_Close, 1030 rtFsIso9660 Obj_QueryInfo,1186 rtFsIso9660Dir_QueryInfo, 1031 1187 RTVFSOBJOPS_VERSION 1032 1188 }, … … 1036 1192 RTVFSOBJSETOPS_VERSION, 1037 1193 RT_OFFSETOF(RTVFSDIROPS, Obj) - RT_OFFSETOF(RTVFSDIROPS, ObjSet), 1038 rtFsIso9660 Obj_SetMode,1039 rtFsIso9660 Obj_SetTimes,1040 rtFsIso9660 Obj_SetOwner,1194 rtFsIso9660File_SetMode, 1195 rtFsIso9660File_SetTimes, 1196 rtFsIso9660File_SetOwner, 1041 1197 RTVFSOBJSETOPS_VERSION 1042 1198 }, … … 1057 1213 1058 1214 /** 1059 * Adds an open child to the parent directory .1215 * Adds an open child to the parent directory's shared structure. 1060 1216 * 1061 1217 * Maintains an additional reference to the parent dir to prevent it from going … … 1065 1221 * @param pDir The directory. 1066 1222 * @param pChild The child being opened. 1067 * @sa rtFsIso9660Dir_RemoveOpenChild 1068 */ 1069 static void rtFsIso9660Dir_AddOpenChild(PRTFSISO9660DIR pDir, PRTFSISO9660OBJ pChild) 1070 { 1071 /* First child that gets opened retains the parent directory. This is 1072 released by the final open child. */ 1073 if (RTListIsEmpty(&pDir->OpenChildren)) 1074 { 1075 uint32_t cRefs = RTVfsDirRetain(pDir->hVfsSelf); 1076 Assert(cRefs != UINT32_MAX); NOREF(cRefs); 1077 1078 /* Root also retains the whole file system. */ 1079 if (pDir->Core.pVol->pRootDir == pDir) 1080 { 1081 Assert(pDir->Core.pVol); 1082 Assert(pDir->Core.pVol == pChild->pVol); 1083 cRefs = RTVfsRetain(pDir->Core.pVol->hVfsSelf); 1084 Assert(cRefs != UINT32_MAX); NOREF(cRefs); 1085 LogFlow(("rtFsIso9660Dir_AddOpenChild(%p,%p) retains volume (%d)\n", pDir, pChild, cRefs)); 1086 } 1087 else 1088 LogFlow(("rtFsIso9660Dir_AddOpenChild(%p,%p) retains parent only (%d)\n", pDir, pChild, cRefs)); 1089 } 1090 else 1091 LogFlow(("rtFsIso9660Dir_AddOpenChild(%p,%p) retains nothing\n", pDir, pChild)); 1223 * @sa rtFsIso9660DirShrd_RemoveOpenChild 1224 */ 1225 static void rtFsIso9660DirShrd_AddOpenChild(PRTFSISO9660DIRSHRD pDir, PRTFSISO9660CORE pChild) 1226 { 1227 rtFsIso9660DirShrd_Retain(pDir); 1228 1092 1229 RTListAppend(&pDir->OpenChildren, &pChild->Entry); 1093 1230 pChild->pParentDir = pDir; … … 1104 1241 * objects to be released recursively (parent dir and the volume). 1105 1242 * 1106 * @sa rtFsIso9660Dir _AddOpenChild1107 */ 1108 static void rtFsIso9660Dir _RemoveOpenChild(PRTFSISO9660DIR pDir, PRTFSISO9660OBJpChild)1243 * @sa rtFsIso9660DirShrd_AddOpenChild 1244 */ 1245 static void rtFsIso9660DirShrd_RemoveOpenChild(PRTFSISO9660DIRSHRD pDir, PRTFSISO9660CORE pChild) 1109 1246 { 1110 1247 AssertReturnVoid(pChild->pParentDir == pDir); … … 1112 1249 pChild->pParentDir = NULL; 1113 1250 1114 /* Final child? If so, release directory. */ 1115 if (RTListIsEmpty(&pDir->OpenChildren)) 1116 { 1117 bool const fIsRootDir = pDir->Core.pVol->pRootDir == pDir; 1118 1119 uint32_t cRefs = RTVfsDirRelease(pDir->hVfsSelf); 1120 Assert(cRefs != UINT32_MAX); NOREF(cRefs); 1121 1122 /* Root directory releases the file system as well. Since the volume 1123 holds a reference to the root directory, it will remain valid after 1124 the above release. */ 1125 if (fIsRootDir) 1126 { 1127 Assert(cRefs > 0); 1128 Assert(pDir->Core.pVol); 1129 Assert(pDir->Core.pVol == pChild->pVol); 1130 cRefs = RTVfsRelease(pDir->Core.pVol->hVfsSelf); 1131 Assert(cRefs != UINT32_MAX); NOREF(cRefs); 1132 LogFlow(("rtFsIso9660Dir_RemoveOpenChild(%p,%p) releases volume (%d)\n", pDir, pChild, cRefs)); 1133 } 1134 else 1135 LogFlow(("rtFsIso9660Dir_RemoveOpenChild(%p,%p) releases parent only (%d)\n", pDir, pChild, cRefs)); 1136 } 1137 else 1138 LogFlow(("rtFsIso9660Dir_RemoveOpenChild(%p,%p) releases nothing\n", pDir, pChild)); 1251 rtFsIso9660DirShrd_Release(pDir); 1139 1252 } 1140 1253 … … 1144 1257 * Logs the content of a directory. 1145 1258 */ 1146 static void rtFsIso9660Dir _LogContent(PRTFSISO9660DIRpThis)1259 static void rtFsIso9660DirShrd_LogContent(PRTFSISO9660DIRSHRD pThis) 1147 1260 { 1148 1261 if (LogIs2Enabled()) … … 1211 1324 1212 1325 /** 1213 * Instantiates a new directory. 1326 * Instantiates a new shared directory structure. 1327 * 1328 * @returns IPRT status code. 1329 * @param pThis The FAT volume instance. 1330 * @param pParentDir The parent directory. This is NULL for the root 1331 * directory. 1332 * @param pDirRec The directory record. 1333 * @param cDirRecs Number of directory records if more than one. 1334 * @param offDirRec The byte offset of the directory record. 1335 * @param ppShared Where to return the shared directory structure. 1336 */ 1337 static int rtFsIso9660DirShrd_New(PRTFSISO9660VOL pThis, PRTFSISO9660DIRSHRD pParentDir, PCISO9660DIRREC pDirRec, 1338 uint32_t cDirRecs, uint64_t offDirRec, PRTFSISO9660DIRSHRD *ppShared) 1339 { 1340 /* 1341 * Allocate a new structure and initialize it. 1342 */ 1343 int rc = VERR_NO_MEMORY; 1344 PRTFSISO9660DIRSHRD pShared = (PRTFSISO9660DIRSHRD)RTMemAllocZ(sizeof(*pShared)); 1345 if (pShared) 1346 { 1347 rtFsIso9660Core_InitFromDirRec(&pShared->Core, pDirRec, cDirRecs, offDirRec, pThis); 1348 RTListInit(&pShared->OpenChildren); 1349 pShared->cbDir = ISO9660_GET_ENDIAN(&pDirRec->cbData); 1350 pShared->pbDir = (uint8_t *)RTMemAllocZ(pShared->cbDir + 256); 1351 if (pShared->pbDir) 1352 { 1353 rc = RTVfsFileReadAt(pThis->hVfsBacking, pShared->Core.FirstExtent.offDisk, pShared->pbDir, pShared->cbDir, NULL); 1354 if (RT_SUCCESS(rc)) 1355 { 1356 #ifdef LOG_ENABLED 1357 rtFsIso9660DirShrd_LogContent(pShared); 1358 #endif 1359 1360 /* 1361 * Link into parent directory so we can use it to update 1362 * our directory entry. 1363 */ 1364 if (pParentDir) 1365 rtFsIso9660DirShrd_AddOpenChild(pParentDir, &pShared->Core); 1366 *ppShared = pShared; 1367 return VINF_SUCCESS; 1368 } 1369 } 1370 } 1371 *ppShared = NULL; 1372 return rc; 1373 } 1374 1375 1376 /** 1377 * Instantiates a new directory with a shared structure presupplied. 1378 * 1379 * @returns IPRT status code. 1380 * @param pThis The FAT volume instance. 1381 * @param pShared Referenced pointer to the shared structure. The 1382 * reference is always CONSUMED. 1383 * @param phVfsDir Where to return the directory handle. 1384 */ 1385 static int rtFsIso9660Dir_NewWithShared(PRTFSISO9660VOL pThis, PRTFSISO9660DIRSHRD pShared, PRTVFSDIR phVfsDir) 1386 { 1387 /* 1388 * Create VFS object around the shared structure. 1389 */ 1390 PRTFSISO9660DIROBJ pNewDir; 1391 int rc = RTVfsNewDir(&g_rtFsIso9660DirOps, sizeof(*pNewDir), 0 /*fFlags*/, pThis->hVfsSelf, 1392 NIL_RTVFSLOCK /*use volume lock*/, phVfsDir, (void **)&pNewDir); 1393 if (RT_SUCCESS(rc)) 1394 { 1395 /* 1396 * Look for existing shared object, create a new one if necessary. 1397 * We CONSUME a reference to pShared here. 1398 */ 1399 pNewDir->offDir = 0; 1400 pNewDir->pShared = pShared; 1401 return VINF_SUCCESS; 1402 } 1403 1404 rtFsIso9660DirShrd_Release(pShared); 1405 *phVfsDir = NIL_RTVFSDIR; 1406 return rc; 1407 } 1408 1409 1410 1411 /** 1412 * Instantiates a new directory VFS instance, creating the shared structure as 1413 * necessary. 1214 1414 * 1215 1415 * @returns IPRT status code. … … 1221 1421 * @param offDirRec The byte offset of the directory record. 1222 1422 * @param phVfsDir Where to return the directory handle. 1223 * @param ppDir Where to return the FAT directory instance data. 1224 */ 1225 static int rtFsIso9660Dir_New(PRTFSISO9660VOL pThis, PRTFSISO9660DIR pParentDir, PCISO9660DIRREC pDirRec, uint32_t cDirRecs, 1226 uint64_t offDirRec, PRTVFSDIR phVfsDir, PRTFSISO9660DIR *ppDir) 1227 { 1228 if (ppDir) 1229 *ppDir = NULL; 1230 1231 PRTFSISO9660DIR pNewDir; 1232 int rc = RTVfsNewDir(&g_rtFsIso9660DirOps, sizeof(*pNewDir), pParentDir ? 0 : RTVFSDIR_F_NO_VFS_REF, 1233 pThis->hVfsSelf, NIL_RTVFSLOCK /*use volume lock*/, phVfsDir, (void **)&pNewDir); 1234 if (RT_SUCCESS(rc)) 1235 { 1236 /* 1237 * Initialize it all so rtFsIso9660Dir_Close doesn't trip up in anyway. 1238 */ 1239 rtFsIso9660Obj_InitFromDirRec(&pNewDir->Core, pDirRec, cDirRecs, offDirRec, pThis); 1240 RTListInit(&pNewDir->OpenChildren); 1241 pNewDir->hVfsSelf = *phVfsDir; 1242 pNewDir->cbDir = ISO9660_GET_ENDIAN(&pDirRec->cbData); 1243 pNewDir->pbDir = (uint8_t *)RTMemAllocZ(pNewDir->cbDir + 256); 1244 if (pNewDir->pbDir) 1245 { 1246 rc = RTVfsFileReadAt(pThis->hVfsBacking, pNewDir->Core.FirstExtent.offDisk, pNewDir->pbDir, pNewDir->cbDir, NULL); 1247 if (RT_SUCCESS(rc)) 1248 { 1249 #ifdef LOG_ENABLED 1250 rtFsIso9660Dir_LogContent(pNewDir); 1251 #endif 1252 1253 /* 1254 * Link into parent directory so we can use it to update 1255 * our directory entry. 1256 */ 1257 if (pParentDir) 1258 rtFsIso9660Dir_AddOpenChild(pParentDir, &pNewDir->Core); 1259 if (ppDir) 1260 *ppDir = pNewDir; 1261 return VINF_SUCCESS; 1262 } 1263 } 1264 else 1265 rc = VERR_NO_MEMORY; 1266 RTVfsDirRelease(*phVfsDir); 1267 } 1268 *phVfsDir = NIL_RTVFSDIR; 1269 if (ppDir) 1270 *ppDir = NULL; 1271 return rc; 1272 } 1273 1423 */ 1424 static int rtFsIso9660Dir_New(PRTFSISO9660VOL pThis, PRTFSISO9660DIRSHRD pParentDir, PCISO9660DIRREC pDirRec, 1425 uint32_t cDirRecs, uint64_t offDirRec, PRTVFSDIR phVfsDir) 1426 { 1427 /* 1428 * Look for existing shared object, create a new one if necessary. 1429 */ 1430 int rc = VINF_SUCCESS; 1431 PRTFSISO9660DIRSHRD pShared = (PRTFSISO9660DIRSHRD)rtFsIso9660Dir_LookupShared(pParentDir, offDirRec); 1432 if (!pShared) 1433 { 1434 rc = rtFsIso9660DirShrd_New(pThis, pParentDir, pDirRec, cDirRecs, offDirRec, &pShared); 1435 if (RT_FAILURE(rc)) 1436 { 1437 *phVfsDir = NIL_RTVFSDIR; 1438 return rc; 1439 } 1440 } 1441 return rtFsIso9660Dir_NewWithShared(pThis, pShared, phVfsDir); 1442 } 1274 1443 1275 1444 … … 1283 1452 Log(("rtFsIso9660Vol_Close(%p)\n", pThis)); 1284 1453 1285 if (pThis-> hVfsRootDir != NIL_RTVFSDIR)1454 if (pThis->pRootDir) 1286 1455 { 1287 1456 Assert(RTListIsEmpty(&pThis->pRootDir->OpenChildren)); 1288 uint32_t cRefs = RTVfsDirRelease(pThis->hVfsRootDir); 1289 Assert(cRefs == 0); NOREF(cRefs); 1290 pThis->hVfsRootDir = NIL_RTVFSDIR; 1291 pThis->pRootDir = NULL; 1457 Assert(pThis->pRootDir->Core.cRefs == 1); 1458 rtFsIso9660DirShrd_Release(pThis->pRootDir); 1459 pThis->pRootDir = NULL; 1292 1460 } 1293 1461 … … 1315 1483 { 1316 1484 PRTFSISO9660VOL pThis = (PRTFSISO9660VOL)pvThis; 1317 uint32_t cRefs = RTVfsDirRetain(pThis->hVfsRootDir); 1318 if (cRefs != UINT32_MAX) 1319 { 1320 *phVfsDir = pThis->hVfsRootDir; 1321 LogFlow(("rtFsIso9660Vol_OpenRoot -> %p\n", *phVfsDir)); 1322 return VINF_SUCCESS; 1323 } 1324 return VERR_INTERNAL_ERROR_5; 1485 1486 rtFsIso9660DirShrd_Retain(pThis->pRootDir); /* consumed by the next call */ 1487 return rtFsIso9660Dir_NewWithShared(pThis, pThis->pRootDir, phVfsDir); 1325 1488 } 1326 1489 … … 1695 1858 pThis->idPrimaryVol = UINT32_MAX; 1696 1859 pThis->fIsUtf16 = false; 1697 pThis->hVfsRootDir = NIL_RTVFSDIR;1698 1860 pThis->pRootDir = NULL; 1699 1861 … … 1813 1975 { 1814 1976 pThis->fIsUtf16 = true; 1815 return rtFsIso9660Dir _New(pThis, NULL, &JolietRootDir, 1, offJolietRootDirRec, &pThis->hVfsRootDir, &pThis->pRootDir);1816 } 1817 return rtFsIso9660Dir _New(pThis, NULL, &RootDir, 1, offRootDirRec, &pThis->hVfsRootDir, &pThis->pRootDir);1977 return rtFsIso9660DirShrd_New(pThis, NULL, &JolietRootDir, 1, offJolietRootDirRec, &pThis->pRootDir); 1978 } 1979 return rtFsIso9660DirShrd_New(pThis, NULL, &RootDir, 1, offRootDirRec, &pThis->pRootDir); 1818 1980 } 1819 1981
Note:
See TracChangeset
for help on using the changeset viewer.