Changeset 69861 in vbox for trunk/src/VBox/Runtime/common/vfs
- Timestamp:
- Nov 28, 2017 7:01:35 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 119307
- Location:
- trunk/src/VBox/Runtime/common/vfs
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp
r69844 r69861 3008 3008 if (RT_SUCCESS(rc)) 3009 3009 { 3010 if (pPath->cComponents > 0) 3010 /* 3011 * Tranverse the path, resolving the parent node. 3012 * We'll do the symbolic link checking here with help of pfnOpen. 3013 */ 3014 RTVFSDIRINTERNAL *pVfsParentDir; 3015 rc = rtVfsDirTraverseToParent(pThis, pPath, (fFlags & RTPATH_F_NO_SYMLINKS) | RTPATH_F_ON_LINK, &pVfsParentDir); 3016 if (RT_SUCCESS(rc)) 3011 3017 { 3012 RTVFSDIRINTERNAL *pVfsParentDir; 3013 rc = rtVfsDirTraverseToParent(pThis, pPath, fFlags, &pVfsParentDir); 3014 if (RT_SUCCESS(rc)) 3018 /* 3019 * Do the opening. Loop if we need to follow symbolic links. 3020 */ 3021 uint32_t fObjFlags = RTVFSOBJ_F_OPEN_ANY | RTVFSOBJ_F_CREATE_NOTHING; 3022 for (uint32_t cLoops = 1;; cLoops++) 3015 3023 { 3016 /* 3017 * Call the query method on the parent directory. 3018 */ 3019 /** @todo symlink race condition here :/ */ 3024 /* If we end with a directory slash, adjust open flags. */ 3025 if (pPath->fDirSlash) 3026 { 3027 fObjFlags &= ~RTVFSOBJ_F_OPEN_ANY | RTVFSOBJ_F_OPEN_DIRECTORY; 3028 if ((fObjFlags & RTVFSOBJ_F_CREATE_MASK) != RTVFSOBJ_F_CREATE_DIRECTORY) 3029 fObjFlags = (fObjFlags & ~RTVFSOBJ_F_CREATE_MASK) | RTVFSOBJ_F_CREATE_NOTHING; 3030 } 3031 if (fObjFlags & RTPATH_F_FOLLOW_LINK) 3032 fObjFlags |= RTVFSOBJ_F_OPEN_SYMLINK; 3033 3034 /* Do the querying. If pfnQueryEntryInfo is available, we use it first, 3035 falling back on pfnOpen in case of symbolic links that needs following. */ 3020 3036 const char *pszEntryName = &pPath->szPath[pPath->aoffComponents[pPath->cComponents - 1]]; 3021 RTVfsLockAcquireRead(pVfsParentDir->Base.hLock); 3022 rc = pVfsParentDir->pOps->pfnQueryEntryInfo(pVfsParentDir->Base.pvThis, pszEntryName, pObjInfo, enmAddAttr); 3023 RTVfsLockReleaseRead(pVfsParentDir->Base.hLock); 3024 3025 RTVfsDirRelease(pVfsParentDir); 3037 if (pVfsParentDir->pOps->pfnQueryEntryInfo) 3038 { 3039 RTVfsLockAcquireRead(pVfsParentDir->Base.hLock); 3040 rc = pVfsParentDir->pOps->pfnQueryEntryInfo(pVfsParentDir->Base.pvThis, pszEntryName, pObjInfo, enmAddAttr); 3041 RTVfsLockReleaseRead(pVfsParentDir->Base.hLock); 3042 if (RT_FAILURE(rc)) 3043 break; 3044 if ( !RTFS_IS_SYMLINK(pObjInfo->Attr.fMode) 3045 || !(fFlags & RTPATH_F_FOLLOW_LINK)) 3046 { 3047 if ( (fObjFlags & RTVFSOBJ_F_OPEN_MASK) != RTVFSOBJ_F_OPEN_ANY 3048 && RTFS_IS_DIRECTORY(pObjInfo->Attr.fMode)) 3049 rc = VERR_NOT_A_DIRECTORY; 3050 break; 3051 } 3052 } 3053 3054 RTVFSOBJ hVfsObj; 3055 RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock); 3056 rc = pVfsParentDir->pOps->pfnOpen(pVfsParentDir->Base.pvThis, pszEntryName, 3057 RTFILE_O_ACCESS_ATTR_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN, 3058 fObjFlags, &hVfsObj); 3059 RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock); 3060 if (RT_FAILURE(rc)) 3061 break; 3062 3063 /* If we don't follow links or this wasn't a link we just have to do the query and we're done. */ 3064 if ( !(fObjFlags & RTPATH_F_FOLLOW_LINK) 3065 || RTVfsObjGetType(hVfsObj) != RTVFSOBJTYPE_SYMLINK) 3066 { 3067 rc = RTVfsObjQueryInfo(hVfsObj, pObjInfo, enmAddAttr); 3068 RTVfsObjRelease(hVfsObj); 3069 break; 3070 } 3071 3072 /* Follow symbolic link. */ 3073 if (cLoops < RTVFS_MAX_LINKS) 3074 rc = rtVfsDirFollowSymlinkObjToParent(&pVfsParentDir, hVfsObj, pPath, fObjFlags & RTPATH_F_MASK); 3075 else 3076 rc = VERR_TOO_MANY_SYMLINKS; 3077 RTVfsObjRelease(hVfsObj); 3078 if (RT_FAILURE(rc)) 3079 break; 3026 3080 } 3027 else 3028 rc = VERR_INVALID_PARAMETER; 3029 } 3030 /* 3031 * The path boils down to '.' so just query the directory. 3032 */ 3033 else 3034 { 3035 RTVfsLockAcquireRead(pThis->Base.hLock); 3036 rc = pThis->Base.pOps->pfnQueryInfo(pThis->Base.pvThis, pObjInfo, enmAddAttr); 3037 RTVfsLockReleaseRead(pThis->Base.hLock); 3081 3082 RTVfsDirRelease(pVfsParentDir); 3038 3083 } 3039 3084 RTVfsParsePathFree(pPath); -
trunk/src/VBox/Runtime/common/vfs/vfsmount.cpp
r69853 r69861 35 35 #include <iprt/assert.h> 36 36 #include <iprt/err.h> 37 #include <iprt/file.h> 37 38 #include <iprt/fsvfs.h> 38 39 #include <iprt/mem.h> 39 40 #include <iprt/log.h> 40 41 #include <iprt/string.h> 42 #include <iprt/vfslowlevel.h> 41 43 42 44 #include <iprt/formats/fat.h> … … 422 424 423 425 if (rtVfsMountIsNtfs(&pBuf->Bootsector)) 424 return RT ERRINFO_LOG_SET(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, "NTFS not yet supported");426 return RTFsNtfsVolOpen(hVfsFileIn, fFlags, 0 /*fNtfsFlags*/, phVfs, pErrInfo); 425 427 426 428 if (rtVfsMountIsHpfs(&pBuf->Bootsector, hVfsFileIn, pBuf2)) … … 462 464 } 463 465 466 467 /** 468 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnValidate} 469 */ 470 static DECLCALLBACK(int) rtVfsChainMountVol_Validate(PCRTVFSCHAINELEMENTREG pProviderReg, PRTVFSCHAINSPEC pSpec, 471 PRTVFSCHAINELEMSPEC pElement, uint32_t *poffError, PRTERRINFO pErrInfo) 472 { 473 RT_NOREF(pProviderReg); 474 475 /* 476 * Basic checks. 477 */ 478 if (pElement->enmTypeIn != RTVFSOBJTYPE_FILE) 479 return pElement->enmTypeIn == RTVFSOBJTYPE_INVALID ? VERR_VFS_CHAIN_CANNOT_BE_FIRST_ELEMENT : VERR_VFS_CHAIN_TAKES_FILE; 480 if ( pElement->enmType != RTVFSOBJTYPE_VFS 481 && pElement->enmType != RTVFSOBJTYPE_DIR) 482 return VERR_VFS_CHAIN_ONLY_DIR_OR_VFS; 483 if (pElement->cArgs > 1) 484 return VERR_VFS_CHAIN_AT_MOST_ONE_ARG; 485 486 /* 487 * Parse the flag if present, save in pElement->uProvider. 488 */ 489 bool fReadOnly = (pSpec->fOpenFile & RTFILE_O_ACCESS_MASK) == RTFILE_O_READ; 490 if (pElement->cArgs > 0) 491 { 492 const char *psz = pElement->paArgs[0].psz; 493 if (*psz) 494 { 495 if (!strcmp(psz, "ro")) 496 fReadOnly = true; 497 else if (!strcmp(psz, "rw")) 498 fReadOnly = false; 499 else 500 { 501 *poffError = pElement->paArgs[0].offSpec; 502 return RTErrInfoSet(pErrInfo, VERR_VFS_CHAIN_INVALID_ARGUMENT, "Expected 'ro' or 'rw' as argument"); 503 } 504 } 505 } 506 507 pElement->uProvider = fReadOnly ? RTVFSMNT_F_READ_ONLY : 0; 508 return VINF_SUCCESS; 509 } 510 511 512 /** 513 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnInstantiate} 514 */ 515 static DECLCALLBACK(int) rtVfsChainMountVol_Instantiate(PCRTVFSCHAINELEMENTREG pProviderReg, PCRTVFSCHAINSPEC pSpec, 516 PCRTVFSCHAINELEMSPEC pElement, RTVFSOBJ hPrevVfsObj, 517 PRTVFSOBJ phVfsObj, uint32_t *poffError, PRTERRINFO pErrInfo) 518 { 519 RT_NOREF(pProviderReg, pSpec, poffError); 520 521 int rc; 522 RTVFSFILE hVfsFileIn = RTVfsObjToFile(hPrevVfsObj); 523 if (hVfsFileIn != NIL_RTVFSFILE) 524 { 525 RTVFS hVfs; 526 rc = RTVfsMountVol(hVfsFileIn, (uint32_t)pElement->uProvider, &hVfs, pErrInfo); 527 RTVfsFileRelease(hVfsFileIn); 528 if (RT_SUCCESS(rc)) 529 { 530 *phVfsObj = RTVfsObjFromVfs(hVfs); 531 RTVfsRelease(hVfs); 532 if (*phVfsObj != NIL_RTVFSOBJ) 533 return VINF_SUCCESS; 534 rc = VERR_VFS_CHAIN_CAST_FAILED; 535 } 536 } 537 else 538 rc = VERR_VFS_CHAIN_CAST_FAILED; 539 return rc; 540 } 541 542 543 /** 544 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnCanReuseElement} 545 */ 546 static DECLCALLBACK(bool) rtVfsChainMountVol_CanReuseElement(PCRTVFSCHAINELEMENTREG pProviderReg, 547 PCRTVFSCHAINSPEC pSpec, PCRTVFSCHAINELEMSPEC pElement, 548 PCRTVFSCHAINSPEC pReuseSpec, PCRTVFSCHAINELEMSPEC pReuseElement) 549 { 550 RT_NOREF(pProviderReg, pSpec, pReuseSpec); 551 if ( pElement->paArgs[0].uProvider == pReuseElement->paArgs[0].uProvider 552 || !pReuseElement->paArgs[0].uProvider) 553 return true; 554 return false; 555 } 556 557 558 /** VFS chain element 'file'. */ 559 static RTVFSCHAINELEMENTREG g_rtVfsChainMountVolReg = 560 { 561 /* uVersion = */ RTVFSCHAINELEMENTREG_VERSION, 562 /* fReserved = */ 0, 563 /* pszName = */ "mount", 564 /* ListEntry = */ { NULL, NULL }, 565 /* pszHelp = */ "Open a file system, requires a file object on the left side.\n" 566 "First argument is an optional 'ro' (read-only) or 'rw' (read-write) flag.\n", 567 /* pfnValidate = */ rtVfsChainMountVol_Validate, 568 /* pfnInstantiate = */ rtVfsChainMountVol_Instantiate, 569 /* pfnCanReuseElement = */ rtVfsChainMountVol_CanReuseElement, 570 /* uEndMarker = */ RTVFSCHAINELEMENTREG_VERSION 571 }; 572 573 RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER(&g_rtVfsChainMountVolReg, rtVfsChainMountVolReg); 574
Note:
See TracChangeset
for help on using the changeset viewer.