Changeset 69813 in vbox
- Timestamp:
- Nov 23, 2017 6:33:30 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 119237
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/err.h
r69716 r69813 1198 1198 /** Symbolic link not allowed. */ 1199 1199 #define VERR_SYMLINK_NOT_ALLOWED (-159) 1200 /** Is a symbolic link. */ 1201 #define VERR_IS_A_SYMLINK (-160) 1202 /** Is a FIFO. */ 1203 #define VERR_IS_A_FIFO (-161) 1204 /** Is a socket. */ 1205 #define VERR_IS_A_SOCKET (-162) 1206 /** Is a block device. */ 1207 #define VERR_IS_A_BLOCK_DEVICE (-163) 1208 /** Is a character device. */ 1209 #define VERR_IS_A_CHAR_DEVICE (-164) 1200 1210 /** @} */ 1201 1211 … … 2786 2796 /** Unsupported file system format. */ 2787 2797 #define VERR_VFS_UNSUPPORTED_FORMAT (-24803) 2798 /** Unsupported create type in an RTVfsObjOpen or RTVfsDirOpenObj call. */ 2799 #define VERR_VFS_UNSUPPORTED_CREATE_TYPE (-24804) 2788 2800 /** @} */ 2789 2801 -
trunk/include/iprt/mangling.h
r69757 r69813 2421 2421 # define RTVfsChainMsgError RT_MANGLER(RTVfsChainMsgError) 2422 2422 # define RTVfsChainMsgErrorExitFailure RT_MANGLER(RTVfsChainMsgErrorExitFailure) 2423 # define RTVfsChainOpenObj RT_MANGLER(RTVfsChainOpenObj) 2423 2424 # define RTVfsChainOpenDir RT_MANGLER(RTVfsChainOpenDir) 2424 2425 # define RTVfsChainOpenParentDir RT_MANGLER(RTVfsChainOpenParentDir) … … 2440 2441 # define RTVfsDirOpenFile RT_MANGLER(RTVfsDirOpenFile) 2441 2442 # define RTVfsDirOpenFileAsIoStream RT_MANGLER(RTVfsDirOpenFileAsIoStream) 2443 # define RTVfsDirOpenObj RT_MANGLER(RTVfsDirOpenObj) 2442 2444 # define RTVfsDirQueryPathInfo RT_MANGLER(RTVfsDirQueryPathInfo) 2443 2445 # define RTVfsDirReadEx RT_MANGLER(RTVfsDirReadEx) 2444 2446 # define RTVfsDirRemoveDir RT_MANGLER(RTVfsDirRemoveDir) 2447 # define RTVfsDirSetPathMode RT_MANGLER(RTVfsDirSetPathMode) 2445 2448 # define RTVfsFileFlush RT_MANGLER(RTVfsFileFlush) 2446 2449 # define RTVfsFileFromBuffer RT_MANGLER(RTVfsFileFromBuffer) … … 2527 2530 # define RTVfsObjFromSymlink RT_MANGLER(RTVfsObjFromSymlink) 2528 2531 # define RTVfsObjFromVfs RT_MANGLER(RTVfsObjFromVfs) 2532 # define RTVfsObjGetType RT_MANGLER(RTVfsObjGetType) 2533 # define RTVfsObjOpen RT_MANGLER(RTVfsObjOpen) 2529 2534 # define RTVfsObjQueryInfo RT_MANGLER(RTVfsObjQueryInfo) 2530 2535 # define RTVfsObjRelease RT_MANGLER(RTVfsObjRelease) 2531 2536 # define RTVfsObjRetain RT_MANGLER(RTVfsObjRetain) 2532 2537 # define RTVfsObjRetainDebug RT_MANGLER(RTVfsObjRetainDebug) 2538 # define RTVfsObjSetMode RT_MANGLER(RTVfsObjSetMode) 2539 # define RTVfsObjSetOwner RT_MANGLER(RTVfsObjSetOwner) 2540 # define RTVfsObjSetTimes RT_MANGLER(RTVfsObjSetTimes) 2533 2541 # define RTVfsObjToDir RT_MANGLER(RTVfsObjToDir) 2534 2542 # define RTVfsObjToFile RT_MANGLER(RTVfsObjToFile) -
trunk/include/iprt/vfs.h
r69753 r69813 166 166 RTDECL(uint32_t) RTVfsObjRelease(RTVFSOBJ hVfsObj); 167 167 168 /** @name RTVFSOBJ_F_XXX - Flags or RTVfsObjOpen and RTVfsDirOpenObj. 169 * @note Must leave space for RTPATH_F_XXX. 170 * @{ */ 171 /** Directory (RTFS_TYPE_DIRECTORY). */ 172 #define RTVFSOBJ_F_OPEN_DIRECTORY RT_BIT_32(8) 173 /** Symbolic link (RTFS_TYPE_SYMLINK). */ 174 #define RTVFSOBJ_F_OPEN_SYMLINK RT_BIT_32(9) 175 /** Regular file (RTFS_TYPE_FILE). */ 176 #define RTVFSOBJ_F_OPEN_FILE RT_BIT_32(10) 177 /** Character device (RTFS_TYPE_DEV_CHAR). */ 178 #define RTVFSOBJ_F_OPEN_DEV_CHAR RT_BIT_32(11) 179 /** Block device (RTFS_TYPE_DEV_BLOCK). */ 180 #define RTVFSOBJ_F_OPEN_DEV_BLOCK RT_BIT_32(12) 181 /** Named pipe (fifo) (RTFS_TYPE_FIFO). */ 182 #define RTVFSOBJ_F_OPEN_FIFO RT_BIT_32(13) 183 /** Socket (RTFS_TYPE_SOCKET). */ 184 #define RTVFSOBJ_F_OPEN_SOCKET RT_BIT_32(14) 185 /** Mask object types we wish to open. */ 186 #define RTVFSOBJ_F_OPEN_MASK UINT32_C(0x00003f00) 187 /** Any kind of object that translates to RTVFSOBJTYPE_FILE. */ 188 #define RTVFSOBJ_F_OPEN_ANY_FILE (RTVFSOBJ_F_FILE | RTVFSOBJ_F_DEV_BLOCK) 189 /** Any kind of object that translates to RTVFSOBJTYPE_IOS or 190 * RTVFSOBJTYPE_FILE. */ 191 #define RTVFSOBJ_F_OPEN_ANY_IO_STREAM (RTVFSOBJ_F_ANY_FILE | RTVFSOBJ_F_DEV_BLOCK | RTVFSOBJ_F_FIFO | RTVFSOBJ_F_SOCKET) 192 /** Any kind of object. */ 193 #define RTVFSOBJ_F_OPEN_ANY RTVFSOBJ_F_OPEN_MASK 194 195 /** Do't create anything, return file not found. */ 196 #define RTVFSOBJ_F_CREATE_NOTHING UINT32_C(0x00000000) 197 /** Create a file if the if the object was not found and the RTFILE_O_XXX 198 * flags allows it. */ 199 #define RTVFSOBJ_F_CREATE_FILE UINT32_C(0x00010000) 200 /** Create a directory if the object was not found and the RTFILE_O_XXX 201 * flags allows it. */ 202 #define RTVFSOBJ_F_CREATE_DIRECTORY UINT32_C(0x00020000) 203 /** The creation type mask. */ 204 #define RTVFSOBJ_F_CREATE_MASK UINT32_C(0x00070000) 205 206 /** Indicate that this call is for traversal. 207 * @internal only */ 208 #define RTVFSOBJ_F_TRAVERSAL RT_BIT_32(31) 209 /** Valid mask for external callers. */ 210 #define RTVFSOBJ_F_VALID_MASK UINT32_C(0x00003f00) 211 /** @} */ 212 213 /** 214 * Opens any file system object in the given VFS. 215 * 216 * @returns IPRT status code. 217 * @param hVfs The VFS to open the object within. 218 * @param pszPath Path to the file. 219 * @param fFileOpen RTFILE_O_XXX flags. 220 * @param fObjFlags More flags: RTVFSOBJ_F_XXX, RTPATH_F_XXX. 221 * @param phVfsObj Where to return the object handle. 222 * @sa RTVfsDirOpenObj, RTVfsDirOpenDir, RTVfsDirOpenFile 223 */ 224 RTDECL(int) RTVfsObjOpen(RTVFS hVfs, const char *pszPath, uint64_t fFileOpen, uint32_t fObjFlags, PRTVFSOBJ phVfsObj); 225 168 226 /** 169 227 * Query information about the object. … … 181 239 RTDECL(int) RTVfsObjQueryInfo(RTVFSOBJ hVfsObj, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr); 182 240 241 /** 242 * Sets the file mode for the given VFS object. 243 * 244 * @returns IPRT status code. 245 * @retval VERR_INVALID_FUNCTION if the object type has no file mode to set. 246 * Only directories, files and symbolic links support this operation. 247 * 248 * @param hVfsObj The VFS object handle. 249 * @param fMode The mode mask. 250 * @param fMask The bits in the mode mask which should be changed. 251 */ 252 RTDECL(int) RTVfsObjSetMode(RTVFSOBJ hVfsObj, RTFMODE fMode, RTFMODE fMask); 253 254 /** 255 * Sets one or more timestamps for the given VFS object. 256 * 257 * @returns IPRT status code. 258 * @retval VERR_INVALID_FUNCTION if the object type has no file mode to set. 259 * Only directories, files and symbolic links support this operation. 260 * 261 * @param hVfsObj The VFS object handle. 262 * @param pAccessTime Pointer to the new access time. NULL if not to 263 * be changed. 264 * @param pModificationTime Pointer to the new modifcation time. NULL if not 265 * to be changed. 266 * @param pChangeTime Pointer to the new change time. NULL if not to 267 * be changed. 268 * @param pBirthTime Pointer to the new time of birth. NULL if not to 269 * be changed. 270 * 271 * @remarks See RTFileSetTimes for restrictions and behavior imposed by the 272 * host OS or underlying VFS provider. 273 * @sa RTFileSetTimes, RTPathSetTimes 274 */ 275 RTDECL(int) RTVfsObjSetTimes(RTVFSOBJ hVfsObj, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime, 276 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime); 277 278 /** 279 * Set the unix style owner and group on the given VFS object. 280 * 281 * @returns IPRT status code. 282 * @retval VERR_INVALID_FUNCTION if the object type has no file mode to set. 283 * Only directories, files and symbolic links support this operation. 284 * 285 * @param hVfsObj The VFS object handle. 286 * @param uid The user ID of the new owner. NIL_RTUID if 287 * unchanged. 288 * @param gid The group ID of the new owner group. NIL_RTGID if 289 * unchanged. 290 * 291 * @sa RTFileSetOwner, RTPathSetOwner. 292 */ 293 RTDECL(int) RTVfsObjSetOwner(RTVFSOBJ hVfsObj, RTUID uid, RTGID gid); 294 295 296 /** 297 * Gets the type of a VFS object. 298 * 299 * @returns The VFS object type on success, RTVFSOBJTYPE_INVALID on failure. 300 * @param hVfsObj The VFS base object handle. 301 */ 302 RTDECL(RTVFSOBJTYPE) RTVfsObjGetType(RTVFSOBJ hVfsObj); 183 303 184 304 /** … … 440 560 441 561 /** 562 * Opens any file system object in or under the given directory. 563 * 564 * @returns IPRT status code. 565 * @param hVfsDir The VFS directory start walking the @a pszPath 566 * relative to. 567 * @param pszPath Path to the file. 568 * @param fFileOpen RTFILE_O_XXX flags. 569 * @param fObjFlags More flags: RTVFSOBJ_F_XXX, RTPATH_F_XXX. 570 * @param phVfsObj Where to return the object handle. 571 * @sa RTVfsObjOpen, RTVfsDirOpenDir, RTVfsDirOpenFile 572 */ 573 RTDECL(int) RTVfsDirOpenObj(RTVFSDIR hVfsDir, const char *pszPath, uint64_t fFileOpen, uint32_t fObjFlags, PRTVFSOBJ phVfsObj); 574 575 /** 442 576 * Opens a file in or under the given directory. 443 577 * … … 1559 1693 RTDECL(int) RTVfsChainOpenVfs(const char *pszSpec, PRTVFS phVfs, uint32_t *poffError, PRTERRINFO pErrInfo); 1560 1694 RTDECL(int) RTVfsChainOpenFsStream(const char *pszSpec, PRTVFSFSSTREAM phVfsFss, uint32_t *poffError, PRTERRINFO pErrInfo); 1695 1696 /** 1697 * Opens any kind of file system object. 1698 * 1699 * @returns IPRT status code. 1700 * @param pszSpec The VFS chain specification or plain path. 1701 * @param fFileOpen RTFILE_O_XXX flags. 1702 * @param fObjFlags More flags: RTVFSOBJ_F_XXX, RTPATH_F_XXX. 1703 * @param phVfsObj Where to return the handle to the opened object. 1704 * @param poffError Where to on error return an offset into @a pszSpec 1705 * of what cause the error. Optional. 1706 * @param pErrInfo Where to return additional error information. 1707 * Optional. 1708 */ 1709 RTDECL(int) RTVfsChainOpenObj(const char *pszSpec, uint64_t fFileOpen, uint32_t fObjOpen, 1710 PRTVFSOBJ phVfsObj, uint32_t *poffError, PRTERRINFO pErrInfo); 1711 1561 1712 RTDECL(int) RTVfsChainOpenDir(const char *pszSpec, uint32_t fOpen, PRTVFSDIR phVfsDir, uint32_t *poffError, PRTERRINFO pErrInfo); 1562 1713 RTDECL(int) RTVfsChainOpenParentDir(const char *pszSpec, uint32_t fOpen, PRTVFSDIR phVfsDir, const char **ppszChild, -
trunk/include/iprt/vfslowlevel.h
r69716 r69813 523 523 524 524 /** 525 * Generic method for opening any kind of file system object. 526 * 527 * Can also create files and directories. Symbolic links, devices and such 528 * needs to be created using special methods or this would end up being way more 529 * complicated than it already is. 530 * 531 * There are optional specializations available. 532 * 533 * @returns IPRT status code. 534 * @retval VERR_PATH_NOT_FOUND or VERR_FILE_NOT_FOUND if @a pszEntry was not 535 * found. 536 * @retval VERR_IS_A_FILE if @a pszEntry is a file or similar but @a fFlags 537 * indicates that the type of object should not be opened. 538 * @retval VERR_IS_A_DIRECTORY if @a pszEntry is a directory but @a fFlags 539 * indicates that directories should not be opened. 540 * @retval VERR_IS_A_SYMLINK if @a pszEntry is a symbolic link but @a fFlags 541 * indicates that symbolic links should not be opened (or followed). 542 * @retval VERR_IS_A_FIFO if @a pszEntry is a FIFO but @a fFlags indicates that 543 * FIFOs should not be opened. 544 * @retval VERR_IS_A_SOCKET if @a pszEntry is a socket but @a fFlags indicates 545 * that sockets should not be opened. 546 * @retval VERR_IS_A_BLOCK_DEVICE if @a pszEntry is a block device but 547 * @a fFlags indicates that block devices should not be opened. 548 * @retval VERR_IS_A_BLOCK_DEVICE if @a pszEntry is a character device but 549 * @a fFlags indicates that character devices should not be opened. 550 * 551 * @param pvThis The implementation specific directory data. 552 * @param pszEntry The name of the immediate file to open or create. 553 * @param fOpenFile RTFILE_O_XXX combination. Currently RTFILE_O_OPEN is 554 * required, but this may change. 555 * @param fObjFlags More flags: RTVFSOBJ_F_XXX, RTPATH_F_XXX. 556 * The meaning of RTPATH_F_FOLLOW_LINK differs here, if 557 * @a pszEntry is a symlink it should be opened for 558 * traversal rather than according to @a fOpenFile. 559 * @param phVfsObj Where to return the handle to the opened object. 560 * @sa RTFileOpen, RTDirOpen 561 */ 562 DECLCALLBACKMEMBER(int, pfnOpen)(void *pvThis, const char *pszEntry, uint64_t fOpenFile, 563 uint32_t fObjFlags, PRTVFSOBJ phVfsObj); 564 565 /** 525 566 * Opens a directory entry for traversal purposes. 526 567 * … … 542 583 * @todo Should com dir, symlinks and mount points using some common 543 584 * ancestor "class". 585 * @note Will be replaced by pfnOpenObj. 544 586 */ 545 587 DECLCALLBACKMEMBER(int, pfnTraversalOpen)(void *pvThis, const char *pszEntry, PRTVFSDIR phVfsDir, … … 553 595 * @param pszFilename The name of the immediate file to open or create. 554 596 * @param fOpen The open flags (RTFILE_O_XXX). 555 * @param phVfsFile Where to return the thandle to the opened file. 597 * @param phVfsFile Where to return the handle to the opened file. 598 * @note Optional. RTVFSDIROPS::pfnOpenObj will be used if NULL. 556 599 * @sa RTFileOpen. 557 600 */ 558 DECLCALLBACKMEMBER(int, pfnOpenFile)(void *pvThis, const char *pszFilename, uint 32_t fOpen, PRTVFSFILE phVfsFile);601 DECLCALLBACKMEMBER(int, pfnOpenFile)(void *pvThis, const char *pszFilename, uint64_t fOpen, PRTVFSFILE phVfsFile); 559 602 560 603 /** … … 567 610 * @param phVfsDir Where to return the handle to the opened directory. 568 611 * Optional. 612 * @note Optional. RTVFSDIROPS::pfnOpenObj will be used if NULL. 569 613 * @sa RTDirOpen. 570 614 */ … … 580 624 * @param phVfsDir Where to optionally return the handle to the newly 581 625 * create directory. 626 * @note Optional. RTVFSDIROPS::pfnOpenObj will be used if NULL. 582 627 * @sa RTDirCreate. 583 628 */ … … 592 637 * @param phVfsSymlink Where to optionally return the handle to the 593 638 * newly create symbolic link. 639 * @note Optional. RTVFSDIROPS::pfnOpenObj will be used if NULL. 594 640 * @sa RTSymlinkCreate. 595 641 */ … … 619 665 * @param pObjInfo Where to return the info on success. 620 666 * @param enmAddAttr Which set of additional attributes to request. 621 * 667 * @note Optional. RTVFSDIROPS::pfnOpenObj and RTVFSOBJOPS::pfnQueryInfo 668 * will be used if NULL. 622 669 * @sa RTPathQueryInfo, RTVFSOBJOPS::pfnQueryInfo 623 670 */ … … 1169 1216 { 1170 1217 /** Open directory flags (RTFILE_O_XXX). */ 1171 uint 32_t fOpenFile;1218 uint64_t fOpenFile; 1172 1219 /** To be defined. */ 1173 1220 uint32_t fOpenDir; -
trunk/src/VBox/Runtime/common/dvm/dvmvfs.cpp
r69616 r69813 736 736 737 737 /** 738 * @interface_method_impl{RTVFSDIROPS,pfnOpen File}739 */ 740 static DECLCALLBACK(int) rtDvmVfsDir_Open File(void *pvThis, const char *pszFilename, uint32_t fOpen, PRTVFSFILE phVfsFile)738 * @interface_method_impl{RTVFSDIROPS,pfnOpen} 739 */ 740 static DECLCALLBACK(int) rtDvmVfsDir_Open(void *pvThis, const char *pszEntry, uint64_t fOpen, uint32_t fFlags, PRTVFSOBJ phVfsObj) 741 741 { 742 742 PRTDVMVFSDIR pThis = (PRTDVMVFSDIR)pvThis; 743 743 RTDVMVOLUME hVolume; 744 int rc = rtDvmVfsDir_FindEntry(pThis, psz Filename, &hVolume);744 int rc = rtDvmVfsDir_FindEntry(pThis, pszEntry, &hVolume); 745 745 if (RT_SUCCESS(rc)) 746 746 { … … 749 749 || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE) 750 750 { 751 if ( !(fOpen & RTFILE_O_WRITE) 752 || !pThis->pVfsVol->fReadOnly) 753 rc = rtDvmVfsCreateFileForVolume(pThis->pVfsVol, hVolume, fOpen, phVfsFile); 751 if (fFlags & (RTVFSOBJ_F_OPEN_FILE | RTVFSOBJ_F_OPEN_DEV_BLOCK)) 752 { 753 if ( !(fOpen & RTFILE_O_WRITE) 754 || !pThis->pVfsVol->fReadOnly) 755 { 756 RTVFSFILE hVfsFile; 757 rc = rtDvmVfsCreateFileForVolume(pThis->pVfsVol, hVolume, fOpen, &hVfsFile); 758 if (RT_SUCCESS(rc)) 759 { 760 *phVfsObj = RTVfsObjFromFile(hVfsFile); 761 RTVfsFileRelease(hVfsFile); 762 AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3); 763 } 764 } 765 else 766 rc = VERR_WRITE_PROTECT; 767 } 754 768 else 755 rc = VERR_ WRITE_PROTECT;769 rc = VERR_IS_A_FILE; 756 770 } 757 771 else 758 772 rc = VERR_ALREADY_EXISTS; 759 773 RTDvmVolumeRelease(hVolume); 774 } 775 return rc; 776 } 777 778 779 /** 780 * @interface_method_impl{RTVFSDIROPS,pfnOpenFile} 781 */ 782 static DECLCALLBACK(int) rtDvmVfsDir_OpenFile(void *pvThis, const char *pszFilename, uint64_t fOpen, PRTVFSFILE phVfsFile) 783 { 784 RTVFSOBJ hVfsObj; 785 int rc = rtDvmVfsDir_Open(pvThis, pszFilename, fOpen, RTVFSOBJ_F_OPEN_FILE, &hVfsObj); 786 if (RT_SUCCESS(rc)) 787 { 788 *phVfsFile = RTVfsObjToFile(hVfsObj); 789 RTVfsObjRelease(hVfsObj); 760 790 } 761 791 return rc; … … 983 1013 RTVFSOBJSETOPS_VERSION 984 1014 }, 1015 rtDvmVfsDir_Open, 985 1016 rtDvmVfsDir_TraversalOpen, 986 1017 rtDvmVfsDir_OpenFile, -
trunk/src/VBox/Runtime/common/fs/fatvfs.cpp
r69678 r69813 2074 2074 static int rtFsFatObj_SetMode(PRTFSFATOBJ pThis, RTFMODE fMode, RTFMODE fMask) 2075 2075 { 2076 __debugbreak(); 2076 2077 #if 0 2077 2078 if (fMask != ~RTFS_TYPE_MASK) … … 4054 4055 4055 4056 /** 4057 * @interface_method_impl{RTVFSDIROPS,pfnOpen} 4058 */ 4059 static DECLCALLBACK(int) rtFsFatDir_Open(void *pvThis, const char *pszEntry, uint64_t fOpen, 4060 uint32_t fFlags, PRTVFSOBJ phVfsObj) 4061 { 4062 PRTFSFATDIR pThis = (PRTFSFATDIR)pvThis; 4063 PRTFSFATDIRSHRD pShared = pThis->pShared; 4064 4065 /* 4066 * Try open existing file. 4067 */ 4068 uint32_t offEntryInDir; 4069 bool fLong; 4070 FATDIRENTRY DirEntry; 4071 int rc = rtFsFatDirShrd_FindEntry(pShared, pszEntry, &offEntryInDir, &fLong, &DirEntry); 4072 if (RT_SUCCESS(rc)) 4073 { 4074 switch (DirEntry.fAttrib & (FAT_ATTR_DIRECTORY | FAT_ATTR_VOLUME)) 4075 { 4076 case 0: 4077 if (fFlags & RTVFSOBJ_F_OPEN_FILE) 4078 { 4079 if ( !(DirEntry.fAttrib & FAT_ATTR_READONLY) 4080 || !(fOpen & RTFILE_O_WRITE)) 4081 { 4082 if ( (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN 4083 || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE 4084 || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE) 4085 { 4086 RTVFSFILE hVfsFile; 4087 rc = rtFsFatFile_New(pShared->Core.pVol, pShared, &DirEntry, offEntryInDir, fOpen, &hVfsFile); 4088 if (RT_SUCCESS(rc)) 4089 { 4090 *phVfsObj = RTVfsObjFromFile(hVfsFile); 4091 RTVfsFileRelease(hVfsFile); 4092 AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3); 4093 } 4094 } 4095 else 4096 rc = VERR_ALREADY_EXISTS; 4097 } 4098 else 4099 rc = VERR_ACCESS_DENIED; 4100 } 4101 else 4102 rc = VERR_IS_A_FILE; 4103 break; 4104 4105 case FAT_ATTR_DIRECTORY: 4106 if (fFlags & RTVFSOBJ_F_OPEN_DIRECTORY) 4107 { 4108 if ( !(DirEntry.fAttrib & FAT_ATTR_READONLY) 4109 || !(fOpen & RTFILE_O_WRITE)) 4110 { 4111 if ( (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN 4112 || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE) 4113 { 4114 RTVFSDIR hVfsDir; 4115 rc = rtFsFatDir_New(pShared->Core.pVol, pShared, &DirEntry, offEntryInDir, 4116 RTFSFAT_GET_CLUSTER(&DirEntry, pShared->Core.pVol), UINT64_MAX /*offDisk*/, 4117 DirEntry.cbFile, &hVfsDir); 4118 if (RT_SUCCESS(rc)) 4119 { 4120 *phVfsObj = RTVfsObjFromDir(hVfsDir); 4121 RTVfsDirRelease(hVfsDir); 4122 AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3); 4123 } 4124 } 4125 else if ((fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE) 4126 rc = VERR_INVALID_FUNCTION; 4127 else 4128 rc = VERR_ALREADY_EXISTS; 4129 } 4130 else 4131 rc = VERR_ACCESS_DENIED; 4132 } 4133 else 4134 rc = VERR_IS_A_DIRECTORY; 4135 break; 4136 4137 default: 4138 rc = VERR_PATH_NOT_FOUND; 4139 break; 4140 } 4141 } 4142 /* 4143 * Create a file or directory? 4144 */ 4145 else if (rc == VERR_FILE_NOT_FOUND) 4146 { 4147 if ( ( (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE 4148 || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE 4149 || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE) 4150 && (fFlags & RTVFSOBJ_F_CREATE_MASK) != RTVFSOBJ_F_CREATE_NOTHING) 4151 { 4152 if ((fFlags & RTVFSOBJ_F_CREATE_MASK) == RTVFSOBJ_F_CREATE_FILE) 4153 { 4154 rc = rtFsFatDirShrd_CreateEntry(pShared, pszEntry, FAT_ATTR_ARCHIVE, 0 /*cbInitial*/, &offEntryInDir, &DirEntry); 4155 if (RT_SUCCESS(rc)) 4156 { 4157 RTVFSFILE hVfsFile; 4158 rc = rtFsFatFile_New(pShared->Core.pVol, pShared, &DirEntry, offEntryInDir, fOpen, &hVfsFile); 4159 if (RT_SUCCESS(rc)) 4160 { 4161 *phVfsObj = RTVfsObjFromFile(hVfsFile); 4162 RTVfsFileRelease(hVfsFile); 4163 AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3); 4164 } 4165 } 4166 } 4167 else if ((fFlags & RTVFSOBJ_F_CREATE_MASK) == RTVFSOBJ_F_CREATE_DIRECTORY) 4168 { 4169 rc = rtFsFatDirShrd_CreateEntry(pShared, pszEntry, FAT_ATTR_ARCHIVE | FAT_ATTR_DIRECTORY, 4170 pShared->Core.pVol->cbCluster, &offEntryInDir, &DirEntry); 4171 if (RT_SUCCESS(rc)) 4172 { 4173 RTVFSDIR hVfsDir; 4174 rc = rtFsFatDir_New(pShared->Core.pVol, pShared, &DirEntry, offEntryInDir, 4175 RTFSFAT_GET_CLUSTER(&DirEntry, pShared->Core.pVol), UINT64_MAX /*offDisk*/, 4176 DirEntry.cbFile, &hVfsDir); 4177 if (RT_SUCCESS(rc)) 4178 { 4179 *phVfsObj = RTVfsObjFromDir(hVfsDir); 4180 RTVfsDirRelease(hVfsDir); 4181 AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3); 4182 } 4183 } 4184 } 4185 else 4186 rc = VERR_VFS_UNSUPPORTED_CREATE_TYPE; 4187 } 4188 } 4189 4190 return rc; 4191 } 4192 4193 4194 /** 4056 4195 * @interface_method_impl{RTVFSDIROPS,pfnOpenFile} 4057 4196 */ 4058 static DECLCALLBACK(int) rtFsFatDir_OpenFile(void *pvThis, const char *pszFilename, uint 32_t fOpen, PRTVFSFILE phVfsFile)4197 static DECLCALLBACK(int) rtFsFatDir_OpenFile(void *pvThis, const char *pszFilename, uint64_t fOpen, PRTVFSFILE phVfsFile) 4059 4198 { 4060 4199 PRTFSFATDIR pThis = (PRTFSFATDIR)pvThis; … … 4639 4778 RTVFSOBJSETOPS_VERSION 4640 4779 }, 4780 rtFsFatDir_Open, 4641 4781 rtFsFatDir_TraversalOpen, 4642 4782 rtFsFatDir_OpenFile, -
trunk/src/VBox/Runtime/common/fs/isovfs.cpp
r69594 r69813 2993 2993 2994 2994 /** 2995 * @interface_method_impl{RTVFSDIROPS,pfnOpen} 2996 */ 2997 static DECLCALLBACK(int) rtFsIsoDir_Open(void *pvThis, const char *pszEntry, uint64_t fOpen, 2998 uint32_t fFlags, PRTVFSOBJ phVfsObj) 2999 { 3000 PRTFSISODIROBJ pThis = (PRTFSISODIROBJ)pvThis; 3001 PRTFSISODIRSHRD pShared = pThis->pShared; 3002 3003 /* 3004 * We cannot create or replace anything, just open stuff. 3005 */ 3006 if ( (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE 3007 || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE) 3008 return VERR_WRITE_PROTECT; 3009 3010 /* 3011 * Try open whatever it is. 3012 */ 3013 int rc; 3014 if (pShared->Core.pVol->enmType != RTFSISOVOLTYPE_UDF) 3015 { 3016 /* 3017 * ISO 9660 3018 */ 3019 PCISO9660DIRREC pDirRec; 3020 uint64_t offDirRec; 3021 uint32_t cDirRecs; 3022 RTFMODE fMode; 3023 uint32_t uVersion; 3024 rc = rtFsIsoDir_FindEntry9660(pShared, pszEntry, &offDirRec, &pDirRec, &cDirRecs, &fMode, &uVersion); 3025 Log2(("rtFsIsoDir_Open: FindEntry9660(,%s,) -> %Rrc\n", pszEntry, rc)); 3026 if (RT_SUCCESS(rc)) 3027 { 3028 switch (fMode & RTFS_TYPE_MASK) 3029 { 3030 case RTFS_TYPE_FILE: 3031 if (fFlags & RTVFSOBJ_F_OPEN_FILE) 3032 { 3033 RTVFSFILE hVfsFile; 3034 rc = rtFsIsoFile_New9660(pShared->Core.pVol, pShared, pDirRec, cDirRecs, 3035 offDirRec, fOpen, uVersion, &hVfsFile); 3036 if (RT_SUCCESS(rc)) 3037 { 3038 *phVfsObj = RTVfsObjFromFile(hVfsFile); 3039 RTVfsFileRelease(hVfsFile); 3040 AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3); 3041 } 3042 } 3043 else 3044 rc = VERR_IS_A_FILE; 3045 break; 3046 3047 case RTFS_TYPE_DIRECTORY: 3048 if (fFlags & RTVFSOBJ_F_OPEN_DIRECTORY) 3049 { 3050 RTVFSDIR hVfsDir; 3051 rc = rtFsIsoDir_New9660(pShared->Core.pVol, pShared, pDirRec, cDirRecs, offDirRec, &hVfsDir); 3052 if (RT_SUCCESS(rc)) 3053 { 3054 *phVfsObj = RTVfsObjFromDir(hVfsDir); 3055 RTVfsDirRelease(hVfsDir); 3056 AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3); 3057 } 3058 } 3059 else 3060 rc = VERR_IS_A_DIRECTORY; 3061 break; 3062 3063 case RTFS_TYPE_SYMLINK: 3064 case RTFS_TYPE_DEV_BLOCK: 3065 case RTFS_TYPE_DEV_CHAR: 3066 case RTFS_TYPE_FIFO: 3067 case RTFS_TYPE_SOCKET: 3068 case RTFS_TYPE_WHITEOUT: 3069 rc = VERR_NOT_IMPLEMENTED; 3070 break; 3071 3072 default: 3073 rc = VERR_PATH_NOT_FOUND; 3074 break; 3075 } 3076 } 3077 } 3078 else 3079 { 3080 /* 3081 * UDF 3082 */ 3083 PCUDFFILEIDDESC pFid; 3084 rc = rtFsIsoDir_FindEntryUdf(pShared, pszEntry, &pFid); 3085 Log2(("rtFsIsoDir_Open: FindEntryUdf(,%s,) -> %Rrc\n", pszEntry, rc)); 3086 if (RT_SUCCESS(rc)) 3087 { 3088 if (!(pFid->fFlags & UDF_FILE_FLAGS_DELETED)) 3089 { 3090 if (!(pFid->fFlags & UDF_FILE_FLAGS_DIRECTORY)) 3091 { 3092 if (fFlags & RTVFSOBJ_F_OPEN_FILE) 3093 { 3094 RTVFSFILE hVfsFile; 3095 rc = rtFsIsoFile_NewUdf(pShared->Core.pVol, pShared, pFid, fOpen, &hVfsFile); 3096 if (RT_SUCCESS(rc)) 3097 { 3098 *phVfsObj = RTVfsObjFromFile(hVfsFile); 3099 RTVfsFileRelease(hVfsFile); 3100 AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3); 3101 } 3102 } 3103 else 3104 rc = VERR_IS_A_FILE; 3105 } 3106 else 3107 { 3108 if (fFlags & RTVFSOBJ_F_OPEN_DIRECTORY) 3109 { 3110 RTVFSDIR hVfsDir; 3111 rc = rtFsIsoDir_NewUdf(pShared->Core.pVol, pShared, pFid, &hVfsDir); 3112 if (RT_SUCCESS(rc)) 3113 { 3114 *phVfsObj = RTVfsObjFromDir(hVfsDir); 3115 RTVfsDirRelease(hVfsDir); 3116 AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3); 3117 } 3118 } 3119 else 3120 rc = VERR_IS_A_DIRECTORY; 3121 } 3122 } 3123 /* We treat UDF_FILE_FLAGS_DELETED like RTFS_TYPE_WHITEOUT for now. */ 3124 else 3125 rc = VERR_PATH_NOT_FOUND; 3126 } 3127 } 3128 return rc; 3129 3130 } 3131 3132 3133 /** 2995 3134 * @interface_method_impl{RTVFSDIROPS,pfnOpenFile} 2996 3135 */ 2997 static DECLCALLBACK(int) rtFsIsoDir_OpenFile(void *pvThis, const char *pszFilename, uint 32_t fOpen, PRTVFSFILE phVfsFile)3136 static DECLCALLBACK(int) rtFsIsoDir_OpenFile(void *pvThis, const char *pszFilename, uint64_t fOpen, PRTVFSFILE phVfsFile) 2998 3137 { 2999 3138 PRTFSISODIROBJ pThis = (PRTFSISODIROBJ)pvThis; … … 3654 3793 RTVFSOBJSETOPS_VERSION 3655 3794 }, 3795 rtFsIsoDir_Open, 3656 3796 rtFsIsoDir_TraversalOpen, 3657 3797 rtFsIsoDir_OpenFile, -
trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp
r69720 r69813 352 352 *********************************************************************************************************************************/ 353 353 DECLINLINE(uint32_t) rtVfsObjRelease(RTVFSOBJINTERNAL *pThis); 354 static int rtVfsTraverseToParent(RTVFSINTERNAL *pThis, PRTVFSPARSEDPATH pPath, uint32_t fFlags, RTVFSDIRINTERNAL **ppVfsParentDir); 354 355 355 356 … … 966 967 967 968 969 RTDECL(RTVFSOBJTYPE) RTVfsObjGetType(RTVFSOBJ hVfsObj) 970 { 971 RTVFSOBJINTERNAL *pThis = hVfsObj; 972 if (pThis != NIL_RTVFSOBJ) 973 { 974 AssertPtrReturn(pThis, RTVFSOBJTYPE_INVALID); 975 AssertReturn(pThis->uMagic == RTVFSOBJ_MAGIC, RTVFSOBJTYPE_INVALID); 976 return pThis->pOps->enmType; 977 } 978 return RTVFSOBJTYPE_INVALID; 979 } 980 981 968 982 RTDECL(RTVFS) RTVfsObjToVfs(RTVFSOBJ hVfsObj) 969 983 { … … 1167 1181 1168 1182 1183 RTDECL(int) RTVfsObjOpen(RTVFS hVfs, const char *pszPath, uint64_t fFileOpen, uint32_t fObjFlags, PRTVFSOBJ phVfsObj) 1184 { 1185 /* 1186 * Validate input. 1187 */ 1188 RTVFSINTERNAL *pThis = hVfs; 1189 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 1190 AssertReturn(pThis->uMagic == RTVFS_MAGIC, VERR_INVALID_HANDLE); 1191 AssertPtrReturn(pszPath, VERR_INVALID_POINTER); 1192 AssertPtrReturn(phVfsObj, VERR_INVALID_POINTER); 1193 1194 int rc = rtFileRecalcAndValidateFlags(&fFileOpen); 1195 if (RT_FAILURE(rc)) 1196 return rc; 1197 AssertMsgReturn( RTPATH_F_IS_VALID(fObjFlags, RTVFSOBJ_F_VALID_MASK) 1198 && (fObjFlags & RTVFSOBJ_F_CREATE_MASK) <= RTVFSOBJ_F_CREATE_DIRECTORY, 1199 ("fObjFlags=%#x\n", fObjFlags), 1200 VERR_INVALID_FLAGS); 1201 /* 1202 * Parse the path, assume current directory is root since we've got no 1203 * caller context here. 1204 */ 1205 PRTVFSPARSEDPATH pPath; 1206 rc = RTVfsParsePathA(pszPath, "/", &pPath); 1207 if (RT_SUCCESS(rc)) 1208 { 1209 if (pPath->cComponents > 0) 1210 { 1211 /* 1212 * Tranverse the path, resolving the parent node, not 1213 * checking for symbolic links in the final element. 1214 */ 1215 RTVFSDIRINTERNAL *pVfsParentDir; 1216 rc = rtVfsTraverseToParent(pThis, pPath, RTPATH_F_ON_LINK, &pVfsParentDir); 1217 if (RT_SUCCESS(rc)) 1218 { 1219 const char *pszEntryName = &pPath->szPath[pPath->aoffComponents[pPath->cComponents - 1]]; 1220 1221 /* 1222 * If we've got a trailing directory slash, use pfnOpenDir 1223 * instead of pfnOpenObj. 1224 */ 1225 if (pPath->fDirSlash) 1226 { 1227 RTVFSDIR hVfsDir; 1228 RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock); 1229 rc = pVfsParentDir->pOps->pfnOpenDir(pVfsParentDir->Base.pvThis, pszEntryName, 0 /** @todo fFlags*/, &hVfsDir); 1230 RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock); 1231 if (RT_SUCCESS(rc)) 1232 { 1233 *phVfsObj = RTVfsObjFromDir(hVfsDir); 1234 RTVfsDirRelease(hVfsDir); 1235 AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3); 1236 } 1237 } 1238 else 1239 { 1240 RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock); 1241 rc = pVfsParentDir->pOps->pfnOpen(pVfsParentDir->Base.pvThis, pszEntryName, fFileOpen, fObjFlags, phVfsObj); 1242 RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock); 1243 } 1244 RTVfsDirRelease(pVfsParentDir); 1245 } 1246 } 1247 /* 1248 * The path boils down to '.', call pfnOpenDir on pThis with '.' as input. 1249 * The caller may wish for a new directory instance to enumerate the entries 1250 * in parallel or some such thing. 1251 */ 1252 else 1253 { 1254 RTVFSDIR hVfsDir; 1255 RTVfsLockAcquireRead(pThis->Base.hLock); 1256 rc = pThis->pOps->pfnOpenRoot(pThis->Base.pvThis, &hVfsDir); /** @todo flags */ 1257 RTVfsLockReleaseRead(pThis->Base.hLock); 1258 if (RT_SUCCESS(rc)) 1259 { 1260 *phVfsObj = RTVfsObjFromDir(hVfsDir); 1261 RTVfsDirRelease(hVfsDir); 1262 AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3); 1263 } 1264 } 1265 1266 RTVfsParsePathFree(pPath); 1267 } 1268 return rc; 1269 } 1270 1169 1271 1170 1272 RTDECL(int) RTVfsObjQueryInfo(RTVFSOBJ hVfsObj, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr) … … 1180 1282 } 1181 1283 1284 1285 /** 1286 * Gets the RTVFSOBJSETOPS for the given base object. 1287 * 1288 * @returns Pointer to the vtable if supported by the type, otherwise NULL. 1289 * @param pThis The base object. 1290 */ 1291 static PCRTVFSOBJSETOPS rtVfsObjGetSetOps(RTVFSOBJINTERNAL *pThis) 1292 { 1293 switch (pThis->pOps->enmType) 1294 { 1295 case RTVFSOBJTYPE_DIR: 1296 return &RT_FROM_MEMBER(pThis, RTVFSDIRINTERNAL, Base)->pOps->ObjSet; 1297 case RTVFSOBJTYPE_FILE: 1298 return &RT_FROM_MEMBER(pThis, RTVFSFILEINTERNAL, Stream.Base)->pOps->ObjSet; 1299 case RTVFSOBJTYPE_SYMLINK: 1300 return &RT_FROM_MEMBER(pThis, RTVFSSYMLINKINTERNAL, Base)->pOps->ObjSet; 1301 default: 1302 return NULL; 1303 } 1304 } 1305 1306 1307 RTDECL(int) RTVfsObjSetMode(RTVFSOBJ hVfsObj, RTFMODE fMode, RTFMODE fMask) 1308 { 1309 RTVFSOBJINTERNAL *pThis = hVfsObj; 1310 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 1311 AssertReturn(pThis->uMagic == RTVFSOBJ_MAGIC, VERR_INVALID_HANDLE); 1312 1313 fMode = rtFsModeNormalize(fMode, NULL, 0); 1314 if (!rtFsModeIsValid(fMode)) 1315 return VERR_INVALID_PARAMETER; 1316 1317 PCRTVFSOBJSETOPS pObjSetOps = rtVfsObjGetSetOps(pThis); 1318 AssertReturn(pObjSetOps, VERR_INVALID_FUNCTION); 1319 1320 RTVfsLockAcquireWrite(pThis->hLock); 1321 int rc = pObjSetOps->pfnSetMode(pThis->pvThis, fMode, fMask); 1322 RTVfsLockReleaseWrite(pThis->hLock); 1323 return rc; 1324 } 1325 1326 1327 RTDECL(int) RTVfsObjSetTimes(RTVFSOBJ hVfsObj, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime, 1328 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime) 1329 { 1330 RTVFSOBJINTERNAL *pThis = hVfsObj; 1331 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 1332 AssertReturn(pThis->uMagic == RTVFSOBJ_MAGIC, VERR_INVALID_HANDLE); 1333 1334 AssertPtrNullReturn(pAccessTime, VERR_INVALID_POINTER); 1335 AssertPtrNullReturn(pModificationTime, VERR_INVALID_POINTER); 1336 AssertPtrNullReturn(pChangeTime, VERR_INVALID_POINTER); 1337 AssertPtrNullReturn(pBirthTime, VERR_INVALID_POINTER); 1338 1339 PCRTVFSOBJSETOPS pObjSetOps = rtVfsObjGetSetOps(pThis); 1340 AssertReturn(pObjSetOps, VERR_INVALID_FUNCTION); 1341 1342 RTVfsLockAcquireWrite(pThis->hLock); 1343 int rc = pObjSetOps->pfnSetTimes(pThis->pvThis, pAccessTime, pModificationTime, pChangeTime, pBirthTime); 1344 RTVfsLockReleaseWrite(pThis->hLock); 1345 return rc; 1346 } 1347 1348 1349 RTDECL(int) RTVfsObjSetOwner(RTVFSOBJ hVfsObj, RTUID uid, RTGID gid) 1350 { 1351 RTVFSOBJINTERNAL *pThis = hVfsObj; 1352 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 1353 AssertReturn(pThis->uMagic == RTVFSOBJ_MAGIC, VERR_INVALID_HANDLE); 1354 1355 PCRTVFSOBJSETOPS pObjSetOps = rtVfsObjGetSetOps(pThis); 1356 AssertReturn(pObjSetOps, VERR_INVALID_FUNCTION); 1357 1358 RTVfsLockAcquireWrite(pThis->hLock); 1359 int rc = pObjSetOps->pfnSetOwner(pThis->pvThis, uid, gid); 1360 RTVfsLockReleaseWrite(pThis->hLock); 1361 return rc; 1362 } 1182 1363 1183 1364 … … 2426 2607 2427 2608 /* 2428 * Parse the path, assume current directory is root since we've got no 2429 * caller context here. 2609 * Parse the relative path. 2430 2610 */ 2431 2611 PRTVFSPARSEDPATH pPath; … … 2481 2661 } 2482 2662 2663 2664 RTDECL(int) RTVfsDirOpenObj(RTVFSDIR hVfsDir, const char *pszPath, uint64_t fFileOpen, uint32_t fObjFlags, PRTVFSOBJ phVfsObj) 2665 { 2666 /* 2667 * Validate input. 2668 */ 2669 RTVFSDIRINTERNAL *pThis = hVfsDir; 2670 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 2671 AssertReturn(pThis->uMagic == RTVFSDIR_MAGIC, VERR_INVALID_HANDLE); 2672 AssertPtrReturn(pszPath, VERR_INVALID_POINTER); 2673 AssertPtrReturn(phVfsObj, VERR_INVALID_POINTER); 2674 2675 int rc = rtFileRecalcAndValidateFlags(&fFileOpen); 2676 if (RT_FAILURE(rc)) 2677 return rc; 2678 AssertMsgReturn( RTPATH_F_IS_VALID(fObjFlags, RTVFSOBJ_F_VALID_MASK) 2679 && (fObjFlags & RTVFSOBJ_F_CREATE_MASK) <= RTVFSOBJ_F_CREATE_DIRECTORY, 2680 ("fObjFlags=%#x\n", fObjFlags), 2681 VERR_INVALID_FLAGS); 2682 2683 /* 2684 * Parse the relative path. 2685 */ 2686 PRTVFSPARSEDPATH pPath; 2687 rc = RTVfsParsePathA(pszPath, NULL, &pPath); 2688 if (RT_SUCCESS(rc)) 2689 { 2690 if (pPath->cComponents > 0) 2691 { 2692 /* 2693 * Tranverse the path, resolving the parent node, not 2694 * checking for symbolic links in the final element. 2695 */ 2696 RTVFSDIRINTERNAL *pVfsParentDir; 2697 rc = rtVfsDirTraverseToParent(pThis, pPath, RTPATH_F_ON_LINK, &pVfsParentDir); 2698 if (RT_SUCCESS(rc)) 2699 { 2700 const char *pszEntryName = &pPath->szPath[pPath->aoffComponents[pPath->cComponents - 1]]; 2701 2702 /* 2703 * If we've got a trailing directory slash, use pfnOpenDir 2704 * instead of pfnOpenObj. 2705 */ 2706 if (pPath->fDirSlash) 2707 { 2708 RTVFSDIR hVfsDir; 2709 RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock); 2710 rc = pVfsParentDir->pOps->pfnOpenDir(pVfsParentDir->Base.pvThis, pszEntryName, 0 /** @todo fFlags*/, &hVfsDir); 2711 RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock); 2712 if (RT_SUCCESS(rc)) 2713 { 2714 *phVfsObj = RTVfsObjFromDir(hVfsDir); 2715 RTVfsDirRelease(hVfsDir); 2716 AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3); 2717 } 2718 } 2719 else 2720 { 2721 RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock); 2722 rc = pVfsParentDir->pOps->pfnOpen(pVfsParentDir->Base.pvThis, pszEntryName, fFileOpen, fObjFlags, phVfsObj); 2723 RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock); 2724 } 2725 RTVfsDirRelease(pVfsParentDir); 2726 } 2727 } 2728 /* 2729 * The path boils down to '.', call pfnOpenDir on pThis with '.' as input. 2730 * The caller may wish for a new directory instance to enumerate the entries 2731 * in parallel or some such thing. 2732 */ 2733 else 2734 { 2735 RTVFSDIR hVfsDir; 2736 RTVfsLockAcquireWrite(pThis->Base.hLock); 2737 rc = pThis->pOps->pfnOpenDir(pThis->Base.pvThis, ".", 0 /** @todo fFlags*/, &hVfsDir); 2738 RTVfsLockReleaseWrite(pThis->Base.hLock); 2739 if (RT_SUCCESS(rc)) 2740 { 2741 *phVfsObj = RTVfsObjFromDir(hVfsDir); 2742 RTVfsDirRelease(hVfsDir); 2743 AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3); 2744 } 2745 } 2746 2747 RTVfsParsePathFree(pPath); 2748 } 2749 return rc; 2750 } 2483 2751 2484 2752 … … 3245 3513 RTVFSIOSTREAM_ASSERT_OPS(&pFileOps->Stream, RTVFSOBJTYPE_FILE); 3246 3514 Assert(cbInstance > 0); 3247 Assert(fOpen & RTFILE_O_ACCESS_MASK);3515 Assert(fOpen & (RTFILE_O_ACCESS_MASK | RTFILE_O_ACCESS_ATTR_MASK)); 3248 3516 AssertPtr(ppvInstance); 3249 3517 AssertPtr(phVfsFile); -
trunk/src/VBox/Runtime/common/vfs/vfschain.cpp
r69716 r69813 1114 1114 1115 1115 1116 RTDECL(int) RTVfsChainOpenObj(const char *pszSpec, uint64_t fFileOpen, uint32_t fObjFlags, 1117 PRTVFSOBJ phVfsObj, uint32_t *poffError, PRTERRINFO pErrInfo) 1118 { 1119 /* 1120 * Validate input. 1121 */ 1122 uint32_t offErrorIgn; 1123 if (!poffError) 1124 poffError = &offErrorIgn; 1125 *poffError = 0; 1126 AssertPtrReturn(pszSpec, VERR_INVALID_POINTER); 1127 AssertReturn(*pszSpec != '\0', VERR_INVALID_PARAMETER); 1128 AssertPtrReturn(phVfsObj, VERR_INVALID_POINTER); 1129 AssertPtrNullReturn(pErrInfo, VERR_INVALID_POINTER); 1130 1131 int rc = rtFileRecalcAndValidateFlags(&fFileOpen); 1132 if (RT_FAILURE(rc)) 1133 return rc; 1134 AssertMsgReturn( RTPATH_F_IS_VALID(fObjFlags, RTVFSOBJ_F_VALID_MASK) 1135 && (fObjFlags & RTVFSOBJ_F_CREATE_MASK) <= RTVFSOBJ_F_CREATE_DIRECTORY, 1136 ("fObjFlags=%#x\n", fObjFlags), 1137 VERR_INVALID_FLAGS); 1138 1139 /* 1140 * Try for a VFS chain first, falling back on regular file system stuff if it's just a path. 1141 */ 1142 PRTVFSCHAINSPEC pSpec = NULL; 1143 if (strncmp(pszSpec, RTVFSCHAIN_SPEC_PREFIX, sizeof(RTVFSCHAIN_SPEC_PREFIX) - 1) == 0) 1144 { 1145 rc = RTVfsChainSpecParse(pszSpec, 0 /*fFlags*/, RTVFSOBJTYPE_DIR, &pSpec, poffError); 1146 if (RT_FAILURE(rc)) 1147 return rc; 1148 1149 Assert(pSpec->cElements > 0); 1150 if ( pSpec->cElements > 1 1151 || pSpec->paElements[0].enmType != RTVFSOBJTYPE_END) 1152 { 1153 const char *pszFinal = NULL; 1154 RTVFSOBJ hVfsObj = NIL_RTVFSOBJ; 1155 pSpec->fOpenFile = fFileOpen; 1156 rc = RTVfsChainSpecCheckAndSetup(pSpec, NULL /*pReuseSpec*/, &hVfsObj, &pszFinal, poffError, pErrInfo); 1157 if (RT_SUCCESS(rc)) 1158 { 1159 if (!pszFinal) 1160 { 1161 *phVfsObj = hVfsObj; 1162 rc = VINF_SUCCESS; 1163 } 1164 else 1165 { 1166 /* 1167 * Do a file open with the final path on the returned object. 1168 */ 1169 RTVFS hVfs = RTVfsObjToVfs(hVfsObj); 1170 RTVFSDIR hVfsDir = RTVfsObjToDir(hVfsObj); 1171 RTVFSFSSTREAM hVfsFss = RTVfsObjToFsStream(hVfsObj); 1172 if (hVfs != NIL_RTVFS) 1173 rc = RTVfsObjOpen(hVfs, pszFinal, fFileOpen, fObjFlags, phVfsObj); 1174 else if (hVfsDir != NIL_RTVFSDIR) 1175 rc = RTVfsDirOpenObj(hVfsDir, pszFinal, fFileOpen, fObjFlags, phVfsObj); 1176 else if (hVfsFss != NIL_RTVFSFSSTREAM) 1177 rc = VERR_NOT_IMPLEMENTED; 1178 else 1179 rc = VERR_VFS_CHAIN_TYPE_MISMATCH_PATH_ONLY; 1180 RTVfsRelease(hVfs); 1181 RTVfsDirRelease(hVfsDir); 1182 RTVfsFsStrmRelease(hVfsFss); 1183 RTVfsObjRelease(hVfsObj); 1184 } 1185 } 1186 1187 RTVfsChainSpecFree(pSpec); 1188 return rc; 1189 } 1190 1191 /* Only a path element. */ 1192 pszSpec = pSpec->paElements[0].paArgs[0].psz; 1193 } 1194 1195 /* 1196 * Path to regular file system. 1197 * Go via the directory VFS wrapper to avoid duplicating code. 1198 */ 1199 RTVFSDIR hVfsParentDir = NIL_RTVFSDIR; 1200 const char *pszFilename; 1201 if (RTPathHasPath(pszSpec)) 1202 { 1203 char *pszCopy = RTStrDup(pszSpec); 1204 if (pszCopy) 1205 { 1206 RTPathStripFilename(pszCopy); 1207 rc = RTVfsDirOpenNormal(pszCopy, 0 /*fOpen*/, &hVfsParentDir); 1208 RTStrFree(pszCopy); 1209 } 1210 else 1211 rc = VERR_NO_STR_MEMORY; 1212 pszFilename = RTPathFilename(pszSpec); 1213 } 1214 else 1215 { 1216 pszFilename = pszSpec; 1217 rc = RTVfsDirOpenNormal(".", 0 /*fOpen*/, &hVfsParentDir); 1218 } 1219 if (RT_SUCCESS(rc)) 1220 { 1221 rc = RTVfsDirOpenObj(hVfsParentDir, pszFilename, fFileOpen, fObjFlags, phVfsObj); 1222 RTVfsDirRelease(hVfsParentDir); 1223 } 1224 1225 RTVfsChainSpecFree(pSpec); 1226 return rc; 1227 } 1228 1229 1116 1230 RTDECL(int) RTVfsChainOpenDir(const char *pszSpec, uint32_t fOpen, 1117 1231 PRTVFSDIR phVfsDir, uint32_t *poffError, PRTERRINFO pErrInfo) … … 1141 1255 || pSpec->paElements[0].enmType != RTVFSOBJTYPE_END) 1142 1256 { 1143 1144 1257 const char *pszFinal = NULL; 1145 1258 RTVFSOBJ hVfsObj = NIL_RTVFSOBJ; … … 1150 1263 if (!pszFinal) 1151 1264 { 1152 /* Try convert it to a fileobject and we're done. */1265 /* Try convert it to a directory object and we're done. */ 1153 1266 *phVfsDir = RTVfsObjToDir(hVfsObj); 1154 1267 if (*phVfsDir) … … 1195 1308 RTVfsChainSpecFree(pSpec); 1196 1309 return rc; 1197 1198 1310 } 1199 1311 … … 1630 1742 { 1631 1743 return pszSpec 1632 && str cmp(pszSpec, RTVFSCHAIN_SPEC_PREFIX) == 0;1744 && strncmp(pszSpec, RT_STR_TUPLE(RTVFSCHAIN_SPEC_PREFIX)) == 0; 1633 1745 } 1634 1746 -
trunk/src/VBox/Runtime/common/vfs/vfsstddir.cpp
r69753 r69813 305 305 306 306 /** 307 * @interface_method_impl{RTVFSDIROPS,pfnOpenObj} 308 */ 309 static DECLCALLBACK(int) rtVfsStdDir_OpenObj(void *pvThis, const char *pszEntry, uint64_t fOpen, 310 uint32_t fFlags, PRTVFSOBJ phVfsObj) 311 { 312 PRTVFSSTDDIR pThis = (PRTVFSSTDDIR)pvThis; 313 314 /* 315 * This is subject to race conditions, but we haven't too much of a choice 316 * without going platform specific here (we'll do that eventually). 317 */ 318 RTFSOBJINFO ObjInfo; 319 int rc = RTDirRelPathQueryInfo(pThis->hDir, pszEntry, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK); 320 if (RT_SUCCESS(rc)) 321 { 322 switch (ObjInfo.Attr.fMode & RTFS_TYPE_MASK) 323 { 324 case RTFS_TYPE_DIRECTORY: 325 if (!(fFlags & RTVFSOBJ_F_OPEN_DIRECTORY)) 326 { 327 if ( (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN 328 || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE 329 || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE) 330 { 331 RTDIR hSubDir; 332 rc = RTDirRelDirOpenFiltered(pThis->hDir, pszEntry, RTDIRFILTER_NONE, fFlags, &hSubDir); 333 if (RT_SUCCESS(rc)) 334 { 335 RTVFSDIR hVfsDir; 336 rc = rtVfsDirFromRTDir(hSubDir, 0 /** @todo subdir open/inherit flags... */, false, &hVfsDir); 337 if (RT_SUCCESS(rc)) 338 { 339 *phVfsObj = RTVfsObjFromDir(hVfsDir); 340 RTVfsDirRelease(hVfsDir); 341 AssertStmt(*phVfsObj == NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3); 342 } 343 else 344 RTDirClose(hSubDir); 345 } 346 } 347 else 348 rc = VERR_ALREADY_EXISTS; 349 } 350 else 351 rc = VERR_IS_A_DIRECTORY; 352 break; 353 354 case RTFS_TYPE_FILE: 355 case RTFS_TYPE_DEV_BLOCK: 356 case RTFS_TYPE_DEV_CHAR: 357 case RTFS_TYPE_FIFO: 358 case RTFS_TYPE_SOCKET: 359 switch (ObjInfo.Attr.fMode & RTFS_TYPE_MASK) 360 { 361 case RTFS_TYPE_FILE: 362 rc = fFlags & RTVFSOBJ_F_OPEN_FILE ? VINF_SUCCESS : VERR_IS_A_FILE; 363 break; 364 case RTFS_TYPE_DEV_BLOCK: 365 rc = fFlags & RTVFSOBJ_F_OPEN_DEV_BLOCK ? VINF_SUCCESS : VERR_IS_A_BLOCK_DEVICE; 366 break; 367 case RTFS_TYPE_DEV_CHAR: 368 rc = fFlags & RTVFSOBJ_F_OPEN_DEV_CHAR ? VINF_SUCCESS : VERR_IS_A_CHAR_DEVICE; 369 break; 370 /** @todo These two types should not result in files, but pure I/O streams. 371 * possibly char device too. */ 372 case RTFS_TYPE_FIFO: 373 rc = fFlags & RTVFSOBJ_F_OPEN_FIFO ? VINF_SUCCESS : VERR_IS_A_FIFO; 374 break; 375 case RTFS_TYPE_SOCKET: 376 rc = fFlags & RTVFSOBJ_F_OPEN_SOCKET ? VINF_SUCCESS : VERR_IS_A_SOCKET; 377 break; 378 default: 379 rc = VERR_INVALID_FLAGS; 380 break; 381 } 382 if (RT_SUCCESS(rc)) 383 { 384 if ( (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN 385 || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE 386 || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE) 387 { 388 RTFILE hFile; 389 rc = RTDirRelFileOpen(pThis->hDir, pszEntry, fOpen, &hFile); 390 if (RT_SUCCESS(rc)) 391 { 392 RTVFSFILE hVfsFile; 393 rc = RTVfsFileFromRTFile(hFile, fOpen, false /*fLeaveOpen*/, &hVfsFile); 394 if (RT_SUCCESS(rc)) 395 { 396 *phVfsObj = RTVfsObjFromFile(hVfsFile); 397 RTVfsFileRelease(hVfsFile); 398 AssertStmt(*phVfsObj == NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3); 399 } 400 else 401 RTFileClose(hFile); 402 } 403 } 404 else 405 rc = VERR_ALREADY_EXISTS; 406 } 407 break; 408 409 case RTFS_TYPE_SYMLINK: 410 if (fFlags & RTVFSOBJ_F_OPEN_SYMLINK) 411 { 412 uint32_t cRefs = RTVfsDirRetain(pThis->hSelf); 413 if (cRefs != UINT32_MAX) 414 { 415 RTVFSSYMLINK hVfsSymlink; 416 PRTVFSSTDSYMLINK pNewSymlink; 417 size_t cchSymlink = strlen(pszEntry); 418 rc = RTVfsNewSymlink(&g_rtVfsStdSymOps, RT_UOFFSETOF(RTVFSSTDSYMLINK, szSymlink[cchSymlink + 1]), 419 NIL_RTVFS, NIL_RTVFSLOCK, &hVfsSymlink, (void **)&pNewSymlink); 420 if (RT_SUCCESS(rc)) 421 { 422 memcpy(pNewSymlink->szSymlink, pszEntry, cchSymlink); 423 pNewSymlink->szSymlink[cchSymlink] = '\0'; 424 pNewSymlink->pDir = pThis; 425 426 *phVfsObj = RTVfsObjFromSymlink(hVfsSymlink); 427 RTVfsSymlinkRelease(hVfsSymlink); 428 AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3); 429 } 430 else 431 RTVfsDirRelease(pThis->hSelf); 432 } 433 else 434 rc = VERR_INTERNAL_ERROR_2; 435 } 436 else 437 rc = VERR_IS_A_SYMLINK; 438 break; 439 440 default: 441 break; 442 } 443 } 444 else if ( rc == VERR_FILE_NOT_FOUND 445 || rc == VERR_PATH_NOT_FOUND) 446 { 447 /* 448 * Consider file or directory creation. 449 */ 450 if ( ( (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE 451 || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE 452 || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE) 453 && (fFlags & RTVFSOBJ_F_CREATE_MASK) != RTVFSOBJ_F_CREATE_NOTHING) 454 { 455 456 if ((fFlags & RTVFSOBJ_F_CREATE_MASK) == RTVFSOBJ_F_CREATE_FILE) 457 { 458 RTFILE hFile; 459 rc = RTDirRelFileOpen(pThis->hDir, pszEntry, fOpen, &hFile); 460 if (RT_SUCCESS(rc)) 461 { 462 RTVFSFILE hVfsFile; 463 rc = RTVfsFileFromRTFile(hFile, fOpen, false /*fLeaveOpen*/, &hVfsFile); 464 if (RT_SUCCESS(rc)) 465 { 466 *phVfsObj = RTVfsObjFromFile(hVfsFile); 467 RTVfsFileRelease(hVfsFile); 468 AssertStmt(*phVfsObj == NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3); 469 } 470 else 471 RTFileClose(hFile); 472 } 473 } 474 else if ((fFlags & RTVFSOBJ_F_CREATE_MASK) == RTVFSOBJ_F_CREATE_DIRECTORY) 475 { 476 RTDIR hSubDir; 477 rc = RTDirRelDirCreate(pThis->hDir, pszEntry, (fOpen & RTFILE_O_CREATE_MODE_MASK) >> RTFILE_O_CREATE_MODE_SHIFT, 478 0 /* fFlags */, &hSubDir); 479 if (RT_SUCCESS(rc)) 480 { 481 RTVFSDIR hVfsDir; 482 rc = rtVfsDirFromRTDir(hSubDir, 0 /** @todo subdir open/inherit flags... */, false, &hVfsDir); 483 if (RT_SUCCESS(rc)) 484 { 485 *phVfsObj = RTVfsObjFromDir(hVfsDir); 486 RTVfsDirRelease(hVfsDir); 487 AssertStmt(*phVfsObj == NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3); 488 } 489 else 490 RTDirClose(hSubDir); 491 } 492 } 493 else 494 rc = VERR_VFS_UNSUPPORTED_CREATE_TYPE; 495 } 496 else 497 rc = VERR_FILE_NOT_FOUND; 498 } 499 return rc; 500 } 501 502 503 /** 307 504 * @interface_method_impl{RTVFSDIROPS,pfnOpenFile} 308 505 */ 309 static DECLCALLBACK(int) rtVfsStdDir_OpenFile(void *pvThis, const char *pszFilename, uint 32_t fOpen, PRTVFSFILE phVfsFile)506 static DECLCALLBACK(int) rtVfsStdDir_OpenFile(void *pvThis, const char *pszFilename, uint64_t fOpen, PRTVFSFILE phVfsFile) 310 507 { 311 508 PRTVFSSTDDIR pThis = (PRTVFSSTDDIR)pvThis; … … 523 720 RTVFSOBJSETOPS_VERSION 524 721 }, 722 rtVfsStdDir_OpenObj, 525 723 rtVfsStdDir_TraversalOpen, 526 724 rtVfsStdDir_OpenFile, -
trunk/src/VBox/Runtime/tools/RTChMod.cpp
r69802 r69813 29 29 * Header Files * 30 30 *********************************************************************************************************************************/ 31 #include <iprt/ path.h>31 #include <iprt/buildconfig.h> 32 32 #include <iprt/err.h> 33 #include <iprt/file.h> 34 #include <iprt/getopt.h> 33 35 #include <iprt/initterm.h> 34 36 #include <iprt/message.h> 35 37 #include <iprt/path.h> 38 #include <iprt/stream.h> 39 #include <iprt/string.h> 36 40 #include <iprt/vfs.h> 37 #include <iprt/string.h>38 #include <iprt/stream.h>39 #include <iprt/getopt.h>40 #include <iprt/buildconfig.h>41 41 42 42 … … 64 64 kRTCmdChModNoise_Verbose 65 65 } RTCMDCHMODNOISE; 66 66 67 67 68 typedef struct RTCMDCHMODOPTS … … 131 132 else 132 133 { 133 /* Try via parent first as that's generally faster and more reliable. */ 134 RTVFSDIR hVfsDir; 135 const char *pszChild; 134 RTVFSOBJ hVfsObj; 136 135 uint32_t offError; 137 136 RTERRINFOSTATIC ErrInfo; 138 rc = RTVfsChainOpenParentDir(pszPath, 0 /*fOpen*/, &hVfsDir, &pszChild, &offError, RTErrInfoInitStatic(&ErrInfo)); 137 rc = RTVfsChainOpenObj(pszPath, RTFILE_O_ACCESS_ATTR_READWRITE | RTFILE_O_DENY_NONE | RTFILE_O_OPEN, 138 RTVFSOBJ_F_OPEN_ANY | RTVFSOBJ_F_CREATE_NOTHING | RTPATH_F_FOLLOW_LINK, 139 &hVfsObj, &offError, RTErrInfoInitStatic(&ErrInfo)); 139 140 if (RT_SUCCESS(rc)) 140 141 { 141 rc = RTVfs DirQueryPathInfo(hVfsDir, pszChild, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK);142 rc = RTVfsObjQueryInfo(hVfsObj, &ObjInfo, RTFSOBJATTRADD_NOTHING); 142 143 if (RT_SUCCESS(rc)) 143 144 { … … 146 147 if (fChanges) 147 148 { 148 rc = VERR_NOT_IMPLEMENTED; //rc = RTVfsDirSetPathMode(hVfsDir, pszChild, fNewMode, RTPATH_F_FOLLOW_LINK);149 rc = RTVfsObjSetMode(hVfsObj, fNewMode, RTCHMOD_SET_ALL_MASK); 149 150 if (RT_FAILURE(rc)) 150 RTMsgError("RTVfsDirSetPathMode failed on '%s' with fNewMode=%#x: %Rrc", pszPath, fNewMode, rc); 151 } 152 } 153 RTVfsDirRelease(hVfsDir); 154 } 155 /* If we have no child part, work on the chain as a whole. */ 156 else if ( rc == VERR_VFS_CHAIN_TOO_SHORT_FOR_PARENT 157 || rc == VERR_VFS_CHAIN_NOT_PATH_ONLY) 158 { 159 rc = RTVfsChainQueryInfo(pszPath, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK, 160 &offError, RTErrInfoInitStatic(&ErrInfo)); 161 if (RT_SUCCESS(rc)) 162 { 163 RTFMODE fNewMode = rtCmdMkModCalcNewMode(pOpts, ObjInfo.Attr.fMode); 164 fChanges = fNewMode != ObjInfo.Attr.fMode; 165 if (fChanges) 166 { 167 rc = VERR_NOT_IMPLEMENTED; //rc = RTVfsChainSetMode(pszPath, fNewMode, &offError, RTErrInfoInitStatic(&ErrInfo)); 168 if (RT_FAILURE(rc)) 169 RTMsgError("RTVfsChainSetMode failed on '%s' with fNewMode=%#x: %Rrc", pszPath, fNewMode, rc); 151 RTMsgError("RTVfsObjSetMode failed on '%s' with fNewMode=%#x: %Rrc", pszPath, fNewMode, rc); 170 152 } 171 153 } 172 154 else 173 RTVfsChainMsgError("RTVfsChainQueryInfo", pszPath, rc, offError, &ErrInfo.Core); 155 RTVfsChainMsgError("RTVfsObjQueryInfo", pszPath, rc, offError, &ErrInfo.Core); 156 RTVfsObjRelease(hVfsObj); 174 157 } 175 else /** @todo we could implement a fallback here so we don't require a final path element. */176 RTVfsChainMsgError("RTVfsChainOpen ParentDir", pszPath, rc, offError, &ErrInfo.Core);158 else 159 RTVfsChainMsgError("RTVfsChainOpenObject", pszPath, rc, offError, &ErrInfo.Core); 177 160 } 178 161 … … 219 202 220 203 if (!RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode)) 221 return rtCmdChModOne(pOpts, pszPath); 222 223 /** @todo do root detection. */ 204 { 205 /* 206 * Don't bother redoing the above work if its not necessary. 207 */ 208 RTFMODE fNewMode = rtCmdMkModCalcNewMode(pOpts, ObjInfo.Attr.fMode); 209 if (fNewMode != ObjInfo.Attr.fMode) 210 return rtCmdChModOne(pOpts, pszPath); 211 if (pOpts->enmNoiseLevel >= kRTCmdChModNoise_Verbose) 212 RTPrintf("%s\n", pszPath); 213 return RTEXITCODE_SUCCESS; 214 } 224 215 225 216 /*
Note:
See TracChangeset
for help on using the changeset viewer.