VirtualBox

Changeset 33945 in vbox


Ignore:
Timestamp:
Nov 10, 2010 5:49:56 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
67606
Message:

More vfs code, new iprt error range..

Location:
trunk
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/err.h

    r33903 r33945  
    44
    55/*
    6  * Copyright (C) 2006-2009 Oracle Corporation
     6 * Copyright (C) 2006-2010 Oracle Corporation
    77 *
    88 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3030#include <iprt/types.h>
    3131
    32 RT_C_DECLS_BEGIN
    3332
    3433/** @defgroup grp_rt_err            RTErr - Status Codes
    3534 * @ingroup grp_rt
     35 *
     36 * The IPRT status codes are in two ranges: {0..999} and {22000..32766}.  The
     37 * IPRT users are free to use the range {1000..21999}.  See RTERR_RANGE1_FIRST,
     38 * RTERR_RANGE1_LAST, RTERR_RANGE2_FIRST, RTERR_RANGE2_LAST, RTERR_USER_FIRST
     39 * and RTERR_USER_LAST.
     40 *
    3641 * @{
    3742 */
     
    176181 */
    177182#define RT_FAILURE_NP(rc)   ( !RT_SUCCESS_NP(rc) )
     183
     184RT_C_DECLS_BEGIN
    178185
    179186/**
     
    386393#endif /* IN_RING3 */
    387394
    388 /** @} */
     395RT_C_DECLS_END
     396
     397/** @} */
     398
     399/** @name Status Code Ranges
     400 * @{ */
     401/** The first status code in the primary IPRT range. */
     402#define RTERR_RANGE1_FIRST                  0
     403/** The last status code in the primary IPRT range. */
     404#define RTERR_RANGE1_LAST                   999
     405
     406/** The first status code in the secondary IPRT range. */
     407#define RTERR_RANGE2_FIRST                  22000
     408/** The last status code in the secondary IPRT range. */
     409#define RTERR_RANGE2_LAST                   32766
     410
     411/** The first status code in the user range. */
     412#define RTERR_USER_FIRST                    1000
     413/** The last status code in the user range. */
     414#define RTERR_USER_LAST                     21999
     415/** @}  */
    389416
    390417
     
    12811308/** @} */
    12821309
    1283 
    12841310/** @name RTZip status codes
    12851311 * @{ */
    12861312/** Generic zip error. */
    1287 #define VERR_ZIP_ERROR                          (-950)
     1313#define VERR_ZIP_ERROR                          (-22000)
    12881314/** The compressed data was corrupted. */
    1289 #define VERR_ZIP_CORRUPTED                      (-951)
     1315#define VERR_ZIP_CORRUPTED                      (-22001)
    12901316/** Ran out of memory while compressing or uncompressing. */
    1291 #define VERR_ZIP_NO_MEMORY                      (-952)
     1317#define VERR_ZIP_NO_MEMORY                      (-22002)
    12921318/** The compression format version is unsupported. */
    1293 #define VERR_ZIP_UNSUPPORTED_VERSION            (-953)
     1319#define VERR_ZIP_UNSUPPORTED_VERSION            (-22003)
    12941320/** The compression method is unsupported. */
    1295 #define VERR_ZIP_UNSUPPORTED_METHOD             (-954)
     1321#define VERR_ZIP_UNSUPPORTED_METHOD             (-22004)
    12961322/** The compressed data started with a bad header. */
    1297 #define VERR_ZIP_BAD_HEADER                     (-955)
     1323#define VERR_ZIP_BAD_HEADER                     (-22005)
     1324/** @} */
     1325
     1326/** @name RTVfs status codes
     1327 * @{ */
     1328/** The VFS chain specification does not have a valid prefix. */
     1329#define VERR_VFS_CHAIN_NO_PREFIX                (-22100)
     1330/** The VFS chain specification is empty. */
     1331#define VERR_VFS_CHAIN_EMPTY                        (-22101)
     1332/** Expected an element. */
     1333#define VERR_VFS_CHAIN_EXPECTED_ELEMENT              (-22102)
     1334/** The VFS object type is not known. */
     1335#define VERR_VFS_CHAIN_UNKNOWN_TYPE                 (-22103)
     1336/** Expected a left paranthese. */
     1337#define VERR_VFS_CHAIN_EXPECTED_LEFT_PARENTHESES    (-22104)
     1338/** Expected a right paranthese. */
     1339#define VERR_VFS_CHAIN_EXPECTED_RIGHT_PARENTHESES   (-22105)
     1340/** Expected a provider name. */
     1341#define VERR_VFS_CHAIN_EXPECTED_PROVIDER_NAME       (-22106)
     1342/** Expected an action (> or |). */
     1343#define VERR_VFS_CHAIN_EXPECTED_ACTION              (-22107)
     1344/** Only one action element is currently supported. */
     1345#define VERR_VFS_CHAIN_MULTIPLE_ACTIONS             (-22108)
     1346/** Expected to find a driving action (>), but there is none. */
     1347#define VERR_VFS_CHAIN_NO_ACTION                    (-22109)
     1348/** Expected pipe action. */
     1349#define VERR_VFS_CHAIN_EXPECTED_PIPE                (-22110)
     1350/** Unexpected action type. */
     1351#define VERR_VFS_CHAIN_UNEXPECTED_ACTION_TYPE       (-22111)
    12981352/** @} */
    12991353
     
    13021356/** @} */
    13031357
    1304 RT_C_DECLS_END
    1305 
    13061358#endif
    13071359
  • trunk/include/iprt/vfs.h

    r33903 r33945  
    6161/** Pointer to a VFS handle. */
    6262typedef RTVFS                          *PRTVFS;
    63 /** A NIL VFS directory handle. */
     63/** A NIL VFS handle. */
    6464#define NIL_RTVFS                       ((RTVFS)~(uintptr_t)0)
     65
     66/** Virtual Filesystem base object handle. */
     67typedef struct RTVFSOBJINTERNAL        *RTVFSOBJ;
     68/** Pointer to a VFS base object handle. */
     69typedef RTVFSOBJ                       *PRTVFSOBJ;
     70/** A NIL VFS base object handle. */
     71#define NIL_RTVFSOBJ                    ((RTVFSOBJ)~(uintptr_t)0)
    6572
    6673/** Virtual Filesystem directory handle. */
     
    7077/** A NIL VFS directory handle. */
    7178#define NIL_RTVFSDIR                    ((RTVFSDIR)~(uintptr_t)0)
     79
     80/** Virtual Filesystem filesystem stream handle. */
     81typedef struct RTVFSFSSTREAMINTERNAL   *RTVFSFSSTREAM;
     82/** Pointer to a VFS filesystem stream handle. */
     83typedef RTVFSFSSTREAM                  *PRTVFSFSSTREAM;
     84/** A NIL VFS filesystem stream handle. */
     85#define NIL_RTVFSFSSTREAM               ((RTVFSFSSTREAM)~(uintptr_t)0)
    7286
    7387/** Virtual Filesystem I/O stream handle. */
     
    119133RTDECL(int)         RTVfsGetAttachment(RTVFS hVfs, uint32_t iOrdinal, PRTVFS *phVfsAttached, uint32_t *pfFlags,
    120134                                       char *pszMountPoint, size_t cbMountPoint);
     135
     136
     137/** @defgroup grp_vfs_dir           VFS Directory API
     138 * @{
     139 */
     140
     141RTDECL(RTVFS)           RTVfsObjToVfs(RTVFSOBJ hVfsObj);
     142RTDECL(RTVFSFSSTREAM)   RTVfsObjToFsStream(RTVFSOBJ hVfsObj);
     143RTDECL(RTVFSDIR)        RTVfsObjToDir(RTVFSOBJ hVfsObj);
     144RTDECL(RTVFSIOSTREAM)   RTVfsObjToIoStream(RTVFSOBJ hVfsObj);
     145RTDECL(RTVFSFILE)       RTVfsObjToFile(RTVFSOBJ hVfsObj);
     146RTDECL(RTVFSSYMLINK)    RTVfsObjToSymlink(RTVFSOBJ hVfsObj);
     147
     148RTDECL(RTVFSOBJ)        RTVfsObjFromVfs(RTVFS hVfs);
     149RTDECL(RTVFSOBJ)        RTVfsObjFromFsStream(RTVFSFSSTREAM hVfsFss);
     150RTDECL(RTVFSOBJ)        RTVfsObjFromDir(RTVFSDIR hVfsDir);
     151RTDECL(RTVFSOBJ)        RTVfsObjFromIoStream(RTVFSIOSTREAM hVfsIos);
     152RTDECL(RTVFSOBJ)        RTVfsObjFromFile(RTVFSFILE hVfsFile);
     153RTDECL(RTVFSOBJ)        RTVfsObjFromSymlink(RTVFSSYMLINK hVfsSym);
     154
     155/** @} */
    121156
    122157
     
    399434/** @} */
    400435
     436
     437/** @defgroup grp_rt_vfs_chain  VFS Chains
     438 *
     439 * VFS chains is for doing pipe like things with VFS objects from the command
     440 * line.  Imagine you want to cat the readme.gz of an ISO you could do
     441 * something like:
     442 *      RTCat :iprtvfs:vfs(isofs,./mycd.iso)|ios(open,readme.gz)|ios(gunzip)
     443 * or
     444 *      RTCat :iprtvfs:ios(isofs,./mycd.iso,/readme.gz)|ios(gunzip)
     445 *
     446 * The "isofs", "open" and "gunzip" bits in the above examples are chain
     447 * element providers registered with IPRT.  See RTVFSCHAINELEMENTREG for how
     448 * these works.
     449 *
     450 * @{ */
     451
     452/** The path prefix used to identify an VFS chain specification. */
     453#define RTVFSCHAIN_SPEC_PREFIX   ":iprtvfs:"
     454
     455RTDECL(int) RTVfsChainOpenVfs(      const char *pszSpec,                 PRTVFS          phVfs,     const char **ppszError);
     456RTDECL(int) RTVfsChainOpenFsStream( const char *pszSpec,                 PRTVFSFSSTREAM  phVfsFss,  const char **ppszError);
     457RTDECL(int) RTVfsChainOpenDir(      const char *pszSpec, uint32_t fOpen, PRTVFSDIR       phVfsDir,  const char **ppszError);
     458RTDECL(int) RTVfsChainOpenFile(     const char *pszSpec, uint32_t fOpen, PRTVFSFILE      phVfsFile, const char **ppszError);
     459RTDECL(int) RTVfsChainOpenSymlink(  const char *pszSpec,                 PRTVFSSYMLINK   phVfsSym,  const char **ppszError);
     460RTDECL(int) RTVfsChainOpenIoStream( const char *pszSpec, uint32_t fOpen, PRTVFSIOSTREAM  phVfsIos,  const char **ppszError);
     461
     462/** @}  */
     463
     464
    401465/** @} */
    402466
  • trunk/include/iprt/vfslowlevel.h

    r33903 r33945  
    2828
    2929#include <iprt/vfs.h>
     30#include <iprt/err.h>
     31#include <iprt/list.h>
    3032#include <iprt/param.h>
    3133
     
    107109    /** Invalid type. */
    108110    RTVFSOBJTYPE_INVALID = 0,
     111    /** Pure base object.
     112     * This is returned by the filesystem stream to represent directories,
     113     * devices, fifos and similar that needs to be created. */
     114    RTVFSOBJTYPE_BASE,
     115    /** Virtual filesystem. */
     116    RTVFSOBJTYPE_VFS,
     117    /** Filesystem stream. */
     118    RTVFSOBJTYPE_FS_STREAM,
     119    /** Pure I/O stream. */
     120    RTVFSOBJTYPE_IO_STREAM,
    109121    /** Directory. */
    110122    RTVFSOBJTYPE_DIR,
    111     /** Pure I/O stream. */
    112     RTVFSOBJTYPE_IOSTREAM,
    113123    /** File. */
    114124    RTVFSOBJTYPE_FILE,
     
    120130    RTVFSOBJTYPE_32BIT_HACK = 0x7fffffff
    121131} RTVFSOBJTYPE;
     132/** Pointer to a VFS object type. */
     133typedef RTVFSOBJTYPE *PRTVFSOBJTYPE;
     134
    122135
    123136/**
     
    228241
    229242/**
     243 * The filesystem stream operations.
     244 *
     245 * @extends RTVFSOBJOPS
     246 */
     247typedef struct RTVFSFSSTREAMOPS
     248{
     249    /** The basic object operation.  */
     250    RTVFSOBJOPS             Obj;
     251    /** The structure version (RTVFSFSSTREAMOPS_VERSION). */
     252    uint32_t                uVersion;
     253    /** Reserved field, MBZ. */
     254    uint32_t                fReserved;
     255
     256    /**
     257     * Gets the next object in the stream.
     258     *
     259     * @returns IPRT status code.
     260     * @retval  VINF_SUCCESS if a new object was retrieved.
     261     * @retval  VERR_EOF when there are no more objects.
     262     * @param   pvThis      The implementation specific directory data.
     263     * @param   ppszName    Where to return the object name.  Must be freed by
     264     *                      calling RTStrFree.
     265     * @param   penmType    Where to return the object type.
     266     * @param   hVfsObj     Where to return the object handle (referenced).
     267     *                      This must be cast to the desired type before use.
     268     */
     269    DECLCALLBACKMEMBER(int, pfnNext)(void *pvThis, char **ppszName, RTVFSOBJTYPE *penmType, PRTVFSOBJ phVfsObj);
     270
     271    /** Marks the end of the structure (RTVFSFSSTREAMOPS_VERSION). */
     272    uintptr_t               uEndMarker;
     273} RTVFSFSSTREAMOPS;
     274/** Pointer to const object attribute setter operations. */
     275typedef RTVFSFSSTREAMOPS const *PCRTVFSFSSTREAMOPS;
     276
     277/** The RTVFSFSSTREAMOPS structure version. */
     278#define RTVFSFSSTREAMOPS_VERSION    RT_MAKE_U32_FROM_U8(0xff,0x3f,1,0)
     279
     280
     281/**
    230282 * The directory operations.
    231283 *
     
    365417    DECLCALLBACKMEMBER(int, pfnReadDir)(void *pvThis, PRTDIRENTRYEX pDirEntry, size_t *pcbDirEntry, RTFSOBJATTRADD enmAddAttr);
    366418
    367 
    368419    /** Marks the end of the structure (RTVFSDIROPS_VERSION). */
    369420    uintptr_t               uEndMarker;
     
    372423typedef RTVFSDIROPS const *PCRTVFSDIROPS;
    373424/** The RTVFSDIROPS structure version. */
    374 #define RTVFSDIROPS_VERSION         RT_MAKE_U32_FROM_U8(0xff,0x3f,1,0)
     425#define RTVFSDIROPS_VERSION         RT_MAKE_U32_FROM_U8(0xff,0x4f,1,0)
    375426
    376427
     
    409460typedef RTVFSSYMLINKOPS const *PCRTVFSSYMLINKOPS;
    410461/** The RTVFSSYMLINKOPS structure version. */
    411 #define RTVFSSYMLINKOPS_VERSION     RT_MAKE_U32_FROM_U8(0xff,0x4f,1,0)
     462#define RTVFSSYMLINKOPS_VERSION     RT_MAKE_U32_FROM_U8(0xff,0x5f,1,0)
    412463
    413464
     
    524575
    525576/** The RTVFSIOSTREAMOPS structure version. */
    526 #define RTVFSIOSTREAMOPS_VERSION    RT_MAKE_U32_FROM_U8(0xff,0x5f,1,0)
     577#define RTVFSIOSTREAMOPS_VERSION    RT_MAKE_U32_FROM_U8(0xff,0x6f,1,0)
    527578
    528579
     
    596647
    597648/** The RTVFSFILEOPS structure version. */
    598 #define RTVFSFILEOPS_VERSION        RT_MAKE_U32_FROM_U8(0xff,0x6f,1,0)
     649#define RTVFSFILEOPS_VERSION        RT_MAKE_U32_FROM_U8(0xff,0x7f,1,0)
    599650
    600651/**
     
    703754/** @}  */
    704755
     756
     757/** @defgroup grp_rt_vfs_lowlevel_chain     VFS Chains
     758 * @ref grp_rt_vfs_chain
     759 * @{
     760 */
     761
     762
     763/**
     764 * Chain element input actions.
     765 */
     766typedef enum RTVFSCHAINACTION
     767{
     768    /** Invalid action. */
     769    RTVFSCHAINACTION_INVALID,
     770    /** No action (start of the chain). */
     771    RTVFSCHAINACTION_NONE,
     772    /** Passive filtering (expressed by pipe symbol). */
     773    RTVFSCHAINACTION_PASSIVE,
     774    /** Push filtering (expressed by redirection-out symbol). */
     775    RTVFSCHAINACTION_PUSH,
     776    /** The end of the valid actions. */
     777    RTVFSCHAINACTION_END,
     778    /** Make sure it's a 32-bit type. */
     779    RTVFSCHAINACTION_32BIT_HACK = 0x7fffffff
     780} RTVFSCHAINACTION;
     781
     782
     783/**
     784 * VFS chain element specification.
     785 */
     786typedef struct RTVFSCHAINELEMSPEC
     787{
     788    /** The provider name. */
     789    char               *pszProvider;
     790    /** The input type. */
     791    RTVFSOBJTYPE        enmTypeIn;
     792    /** The output type. */
     793    RTVFSOBJTYPE        enmTypeOut;
     794    /** The action to take (or not). */
     795    RTVFSCHAINACTION    enmAction;
     796    /** The number of arguments. */
     797    uint32_t            cArgs;
     798    /** Arguments. */
     799    char               **papszArgs;
     800} RTVFSCHAINELEMSPEC;
     801/** Pointer to a chain element specification. */
     802typedef RTVFSCHAINELEMSPEC *PRTVFSCHAINELEMSPEC;
     803/** Pointer to a const chain element specification. */
     804typedef RTVFSCHAINELEMSPEC const *PCRTVFSCHAINELEMSPEC;
     805
     806
     807/**
     808 * Parsed VFS chain specification.
     809 */
     810typedef struct RTVFSCHAINSPEC
     811{
     812    /** The action element, UINT32_MAX if none.
     813     * Currently we only support one action element (RTVFSCHAINACTION_PASSIVE
     814     * is not considered). */
     815    uint32_t            iActionElement;
     816    /** The number of elements. */
     817    uint32_t            cElements;
     818    /** The elements. */
     819    PRTVFSCHAINELEMSPEC paElements;
     820} RTVFSCHAINSPEC;
     821/** Pointer to a parsed VFS chain specification. */
     822typedef RTVFSCHAINSPEC *PRTVFSCHAINSPEC;
     823/** Pointer to a const, parsed VFS chain specification. */
     824typedef RTVFSCHAINSPEC const *PCRTVFSCHAINSPEC;
     825
     826
     827/**
     828 * A chain element provider registration record.
     829 */
     830typedef struct RTVFSCHAINELEMENTREG
     831{
     832    /** The version (RTVFSCHAINELEMENTREG_VERSION). */
     833    uint32_t                uVersion;
     834    /** Reserved, MBZ. */
     835    uint32_t                fReserved;
     836    /** The provider name (unique). */
     837    const char             *pszName;
     838    /** For chaining the providers. */
     839    RTLISTNODE              ListEntry;
     840
     841    /**
     842     * Create a VFS from the given chain element specficiation.
     843     *
     844     * @returns IPRT status code.
     845     * @param   pSpec           The chain element specification.
     846     * @param   phVfs           Where to returned the VFS handle.
     847     */
     848    DECLCALLBACKMEMBER(int, pfnOpenVfs)(     PCRTVFSCHAINELEMSPEC pSpec,                 PRTVFS           phVfs);
     849
     850    /**
     851     * Open a directory from the given chain element specficiation.
     852     *
     853     * @returns IPRT status code.
     854     * @param   pSpec           The chain element specification.
     855     * @param   phVfsDir        Where to returned the directory handle.
     856     */
     857    DECLCALLBACKMEMBER(int, pfnOpenDir)(     PCRTVFSCHAINELEMSPEC pSpec,                 PRTVFSDIR        phVfsDir);
     858
     859    /**
     860     * Open a file from the given chain element specficiation.
     861     *
     862     * @returns IPRT status code.
     863     * @param   pSpec           The chain element specification.
     864     * @param   fOpen           The open flag.  Can be zero and the
     865     *                          specification may modify it.
     866     * @param   phVfsFile       Where to returned the file handle.
     867     */
     868    DECLCALLBACKMEMBER(int, pfnOpenFile)(    PCRTVFSCHAINELEMSPEC pSpec, uint32_t fOpen, PRTVFSFILE       phVfsFile);
     869
     870    /**
     871     * Open a symlink from the given chain element specficiation.
     872     *
     873     * @returns IPRT status code.
     874     * @param   pSpec           The chain element specification.
     875     * @param   phVfsSym        Where to returned the symlink handle.
     876     */
     877    DECLCALLBACKMEMBER(int, pfnOpenSymlink)( PCRTVFSCHAINELEMSPEC pSpec,                 PRTVFSSYMLINK    phVfsSym);
     878
     879    /**
     880     * Open a I/O stream from the given chain element specficiation.
     881     *
     882     * @returns IPRT status code.
     883     * @param   pSpec           The chain element specification.
     884     * @param   fOpen           The open flag.  Can be zero and the
     885     *                          specification may modify it.
     886     * @param   phVfsIos        Where to returned the I/O stream handle.
     887     */
     888    DECLCALLBACKMEMBER(int, pfnOpenIoStream)(PCRTVFSCHAINELEMSPEC pSpec, uint32_t fOpen, PRTVFSIOSTREAM   phVfsIos);
     889
     890    /**
     891     * Open a filesystem stream from the given chain element specficiation.
     892     *
     893     * @returns IPRT status code.
     894     * @param   pSpec           The chain element specification.
     895     * @param   phVfsFss        Where to returned the filesystem stream handle.
     896     */
     897    DECLCALLBACKMEMBER(int, pfnOpenFsStream)(PCRTVFSCHAINELEMSPEC pSpec,                 PRTVFSFSSTREAM   phVfsFss);
     898
     899    /** End marker (RTVFSCHAINELEMENTREG_VERSION). */
     900    uintptr_t               uEndMarker;
     901} RTVFSCHAINELEMENTREG;
     902/** Pointer to a VFS chain element registration record. */
     903typedef RTVFSCHAINELEMENTREG *PRTVFSCHAINELEMENTREG;
     904/** Pointer to a const VFS chain element registration record. */
     905typedef RTVFSCHAINELEMENTREG const *PCRTVFSCHAINELEMENTREG;
     906
     907/** The VFS chain element registration record version number. */
     908#define RTVFSCHAINELEMENTREG_VERSION        RT_MAKE_U32_FROM_U8(0xff, 0x7f, 1, 0)
     909
     910
     911/**
     912 * Parses the specification.
     913 *
     914 * @returns IPRT status code.
     915 * @param   pszSpec             The specification string to parse.
     916 * @param   fFlags              Flags, see RTVFSCHAIN_PF_XXX.
     917 * @param   enmLeadingAction    The only allowed leading action type.
     918 * @param   enmTrailingAction   The only allowed trailing action type.
     919 * @param   ppSpec              Where to return the pointer to the parsed
     920 *                              specification.  This must be freed by calling
     921 *                              RTVfsChainSpecFree.  Will always be set (unless
     922 *                              invalid parameters.)
     923 * @param   ppszError           On failure, this will point at the error
     924 *                              location in @a pszSpec.  Optional.
     925 */
     926RTDECL(int)             RTVfsChainSpecParse(const char *pszSpec, RTVFSCHAINACTION enmLeadingAction,
     927                                            RTVFSCHAINACTION enmTrailingAction,
     928                                            PRTVFSCHAINSPEC *ppSpec, const char *ppszError);
     929
     930/** @name RTVfsChainSpecParse
     931 * @{ */
     932/** No real action is permitted, i.e. only passive filtering (aka pipe).  */
     933#define RTVFSCHAIN_PF_NO_REAL_ACTION            RT_BIT_32(0)
     934/** The specified leading action is optional. */
     935#define RTVFSCHAIN_PF_LEADING_ACTION_OPTIONAL   RT_BIT_32(1)
     936/** The specified trailing action is optional. */
     937#define RTVFSCHAIN_PF_TRAILING_ACTION_OPTIONAL  RT_BIT_32(2)
     938/** Mask of valid flags. */
     939#define RTVFSCHAIN_PF_VALID_MASK                UINT32_C(0x00000007)
     940/** @}*/
     941
     942/**
     943 * Frees a parsed chain specification.
     944 *
     945 * @param   pSpec               What RTVfsChainSpecParse returned.  NULL is
     946 *                              quietly ignored.
     947 */
     948RTDECL(void)            RTVfsChainSpecFree(PRTVFSCHAINSPEC pSpec);
     949
     950/**
     951 * Registers a chain element provider.
     952 *
     953 * @returns IPRT status code
     954 * @param   pRegRec             The registration record.
     955 * @param   fFromCtor           Indicates where we're called from.
     956 */
     957RTDECL(int) RTVfsChainElementRegisterProvider(PRTVFSCHAINELEMENTREG pRegRec, bool fFromCtor);
     958
     959/**
     960 * Deregisters a chain element provider.
     961 *
     962 * @returns IPRT status code
     963 * @param   pRegRec             The registration record.
     964 * @param   fFromDtor           Indicates where we're called from.
     965 */
     966RTDECL(int) RTVfsChainElementDeregisterProvider(PRTVFSCHAINELEMENTREG pRegRec, bool fFromDtor);
     967
     968
     969/** @def RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER
     970 * Automatically registers a chain element provider using a global constructor
     971 * and destructor hack.
     972 *
     973 * @param   pRegRec     Pointer to the registration record.
     974 * @param   name        Some unique variable name prefix.
     975 */
     976
     977#ifdef __cplusplus
     978/**
     979 * Class used for registering a VFS chain element provider.
     980 */
     981class RTVfsChainElementAutoRegisterHack
     982{
     983    PRTVFSCHAINELEMENTREG m_pRegRec;
     984    RTVfsChainElementAutoRegisterHack(PRTVFSCHAINELEMENTREG a_pRegRec)
     985        : m_pRegRec(a_pRegRec)
     986    {
     987        int rc = RTVfsChainElementRegisterProvider(m_pRegRec, true);
     988        if (RT_FAILURE(rc))
     989            m_pRegRec = NULL;
     990    }
     991    ~RTVfsChainElementAutoRegisterHack()
     992    {
     993        RTVfsChainElementDeregisterProvider(m_pRegRec, true);
     994        m_pRegRec = NULL;
     995    }
     996};
     997
     998# define RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER(pRegRec, name) \
     999    static RTVfsChainElementAutoRegisterHack name ## AutoRegistrationHack(pRegRec)
     1000
     1001#else
     1002# define RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER(pRegRec, name) \
     1003    extern void *name ## AutoRegistrationHack = \
     1004        &Sorry_but_RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER_does_not_work_in_c_source_files
     1005#endif
     1006
     1007
     1008/** @}  */
     1009
     1010
    7051011/** @} */
    7061012
     
    7091015#endif /* !___iprt_vfslowlevel_h */
    7101016
    711 
    712 
    713 
  • trunk/src/VBox/Main/Global.cpp

    r33743 r33945  
    492492
    493493            /* try categorize it */
    494             if (aVBoxStatus < 0 && aVBoxStatus > -1000)
     494            if (   aVBoxStatus < 0
     495                && (   aVBoxStatus > -1000
     496                    || (aVBoxStatus < -22000 && aVBoxStatus > -32766) )
    495497                return VBOX_E_IPRT_ERROR;
    496498            if (    aVBoxStatus <  VERR_PDM_NO_SUCH_LUN / 100 * 10
  • trunk/src/VBox/Runtime/Makefile.kmk

    r33887 r33945  
    370370        common/time/timesup.cpp \
    371371        common/vfs/vfsbase.cpp \
     372        common/vfs/vfschain.cpp \
    372373        common/vfs/vfsstdfile.cpp \
    373374        common/zip/zipgzip.cpp \
  • trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp

    r33911 r33945  
    4848*   Defined Constants And Macros                                               *
    4949*******************************************************************************/
    50 #define RTVFS_MAGIC                 UINT32_C(0x11112222)
     50#define RTVFSOBJ_MAGIC              UINT32_C(0x20109901)
     51#define RTVFSOBJ_MAGIC_DEAD         (~RTVFSOBJ_MAGIC)
     52#define RTVFS_MAGIC                 UINT32_C(0x20109902)
    5153#define RTVFS_MAGIC_DEAD            (~RTVFS_MAGIC)
    52 #define RTVFSDIR_MAGIC              UINT32_C(0x77778888)
     54#define RTVFSFSSTREAM_MAGIC         UINT32_C(0x20109903)
     55#define RTVFSFSSTREAM_MAGIC_DEAD    (~RTVFSFSSTREAM_MAGIC)
     56#define RTVFSDIR_MAGIC              UINT32_C(0x20109904)
    5357#define RTVFSDIR_MAGIC_DEAD         (~RTVFSDIR_MAGIC)
    54 #define RTVFSFILE_MAGIC             UINT32_C(0x55556666)
     58#define RTVFSFILE_MAGIC             UINT32_C(0x20109905)
    5559#define RTVFSFILE_MAGIC_DEAD        (~RTVFSFILE_MAGIC)
    56 #define RTVFSIOSTREAM_MAGIC         UINT32_C(0x33334444)
     60#define RTVFSIOSTREAM_MAGIC         UINT32_C(0x20109906)
    5761#define RTVFSIOSTREAM_MAGIC_DEAD    (~RTVFSIOSTREAM_MAGIC)
    58 #define RTVFSSYMLINK_MAGIC          UINT32_C(0x9999aaaa)
     62#define RTVFSSYMLINK_MAGIC          UINT32_C(0x20109907)
    5963#define RTVFSSYMLINK_MAGIC_DEAD     (~RTVFSSYMLINK_MAGIC)
    6064
     
    6569#define RTVFS_MAX_LINKS             20U
    6670
    67 
    68 /** Takes a write lock. */
    69 #define RTVFS_WRITE_LOCK(hSemRW)  \
    70     do { \
    71         if ((hSemRW) != NIL_RTSEMRW) \
    72         { \
    73             int rcSemEnter = RTSemRWRequestWrite(hSemRW, RT_INDEFINITE_WAIT); \
    74             AssertRC(rcSemEnter); \
    75         } \
    76     } while (0)
    77 
    78 /** Releases a write lock. */
    79 #define RTVFS_WRITE_UNLOCK(hSemRW)  \
    80     do { \
    81         if ((hSemRW) != NIL_RTSEMRW) \
    82         { \
    83             int rcSemLeave = RTSemRWReleaseWrite(hSemRW); \
    84             AssertRC(rcSemLeave); \
    85         } \
    86     } while (0)
    87 
    88 /** Takes a read lock. */
    89 #define RTVFS_READ_LOCK(hSemRW)  \
    90     do { \
    91         if ((hSemRW) != NIL_RTSEMRW) \
    92         { \
    93             int rcSemEnter = RTSemRWRequestRead(hSemRW, RT_INDEFINITE_WAIT); \
    94             AssertRC(rcSemEnter); \
    95         } \
    96     } while (0)
    97 
    98 /** Releases a read lock. */
    99 #define RTVFS_READ_UNLOCK(hSemRW)  \
    100     do { \
    101         if ((hSemRW) != NIL_RTSEMRW) \
    102         { \
    103             int rcSemLeave = RTSemRWReleaseRead(hSemRW); \
    104             AssertRC(rcSemLeave); \
    105         } \
    106     } while (0)
    10771
    10872
     
    11377
    11478/**
     79 * The VFS base object handle data.
     80 *
     81 * All other VFS handles are derived from this one.  The final handle type is
     82 * indicated by RTVFSOBJOPS::enmType via the RTVFSOBJINTERNAL::pOps member.
     83 */
     84typedef struct RTVFSOBJINTERNAL
     85{
     86    /** The VFS magic (RTVFSOBJ_MAGIC). */
     87    uint32_t                uMagic;
     88    /** The number of references to this VFS object. */
     89    uint32_t volatile       cRefs;
     90    /** Pointer to the instance data. */
     91    void                   *pvThis;
     92    /** The vtable. */
     93    PCRTVFSOBJOPS           pOps;
     94    /** Read-write semaphore protecting all access to the VFS
     95     * Only valid RTVFS_C_THREAD_SAFE is set, otherwise it is NIL_RTSEMRW. */
     96    RTSEMRW                 hSemRW;
     97    /** Reference back to the VFS containing this object. */
     98    RTVFS                   hVfs;
     99} RTVFSOBJINTERNAL;
     100
     101
     102/**
     103 * The VFS filesystem stream handle data.
     104 *
     105 * @extends RTVFSOBJINTERNAL
     106 */
     107typedef struct RTVFSFSSTREAMINTERNAL
     108{
     109    /** The VFS magic (RTVFSFSTREAM_MAGIC). */
     110    uint32_t                uMagic;
     111    /** File open flags, at a minimum the access mask. */
     112    uint32_t                fFlags;
     113    /** The vtable. */
     114    PCRTVFSFSSTREAMOPS      pOps;
     115    /** The base object handle data. */
     116    RTVFSOBJINTERNAL        Base;
     117} RTVFSFSSTREAMINTERNAL;
     118
     119
     120/**
    115121 * The VFS handle data.
     122 *
     123 * @extends RTVFSOBJINTERNAL
    116124 */
    117125typedef struct RTVFSINTERNAL
     
    121129    /** Creation flags (RTVFS_C_XXX). */
    122130    uint32_t                fFlags;
    123     /** Pointer to the instance data. */
    124     void                   *pvThis;
    125131    /** The vtable. */
    126132    PCRTVFSOPS              pOps;
    127     /** Read-write semaphore protecting all access to the VFS
    128      * Only valid RTVFS_C_THREAD_SAFE is set, otherwise it is NIL_RTSEMRW. */
    129     RTSEMRW                 hSemRW;
    130     /** The number of references to this VFS.
    131      * This count includes objects within the file system, so that the VFS
    132      * won't be destroyed before all objects are closed. */
    133     uint32_t volatile       cRefs;
     133    /** The base object handle data. */
     134    RTVFSOBJINTERNAL        Base;
    134135} RTVFSINTERNAL;
    135136
     
    137138/**
    138139 * The VFS directory handle data.
     140 *
     141 * @extends RTVFSOBJINTERNAL
    139142 */
    140143typedef struct RTVFSDIRINTERNAL
     
    144147    /** Reserved for flags or something. */
    145148    uint32_t                fReserved;
    146     /** Pointer to the instance data. */
    147     void                   *pvThis;
    148149    /** The vtable. */
    149150    PCRTVFSDIROPS           pOps;
    150     /** The VFS RW sem if serialized. */
    151     RTSEMRW                 hSemRW;
    152     /** Reference back to the VFS containing this directory. */
    153     RTVFS                   hVfs;
    154     /** The number of references to this directory handle.  This does not
    155      * include files or anything. */
    156     uint32_t volatile       cRefs;
     151    /** The base object handle data. */
     152    RTVFSOBJINTERNAL        Base;
    157153} RTVFSDIRINTERNAL;
    158154
     
    160156/**
    161157 * The VFS symbolic link handle data.
     158 *
     159 * @extends RTVFSOBJINTERNAL
    162160 */
    163161typedef struct RTVFSSYMLINKINTERNAL
     
    167165    /** Reserved for flags or something. */
    168166    uint32_t                fReserved;
    169     /** Pointer to the instance data. */
    170     void                   *pvThis;
    171167    /** The vtable. */
    172168    PCRTVFSSYMLINKOPS       pOps;
    173     /** The VFS RW sem if serialized. */
    174     RTSEMRW                 hSemRW;
    175     /** Reference back to the VFS containing this symbolic link. */
    176     RTVFS                   hVfs;
    177     /** The number of references to this symbolic link handle. */
    178     uint32_t volatile       cRefs;
     169    /** The base object handle data. */
     170    RTVFSOBJINTERNAL        Base;
    179171} RTVFSSYMLINKINTERNAL;
    180172
     
    183175 * The VFS I/O stream handle data.
    184176 *
    185  * This is normally part of a type specific handle, like a file or pipe.
     177 * This is often part of a type specific handle, like a file or pipe.
     178 *
     179 * @extends RTVFSOBJINTERNAL
    186180 */
    187181typedef struct RTVFSIOSTREAMINTERNAL
     
    191185    /** File open flags, at a minimum the access mask. */
    192186    uint32_t                fFlags;
    193     /** Pointer to the instance data. */
    194     void                   *pvThis;
    195187    /** The vtable. */
    196188    PCRTVFSIOSTREAMOPS      pOps;
    197     /** The VFS RW sem if serialized. */
    198     RTSEMRW                 hSemRW;
    199     /** Reference back to the VFS containing this directory. */
    200     RTVFS                   hVfs;
    201     /** The number of references to this file VFS. */
    202     uint32_t volatile       cRefs;
     189    /** The base object handle data. */
     190    RTVFSOBJINTERNAL        Base;
    203191} RTVFSIOSTREAMINTERNAL;
    204192
     
    221209} RTVFSFILEINTERNAL;
    222210
     211#if 0 /* later */
     212
     213/**
     214 * The VFS pipe handle data.
     215 *
     216 * @extends RTVFSIOSTREAMINTERNAL
     217 */
     218typedef struct RTVFSPIPEINTERNAL
     219{
     220    /** The VFS magic (RTVFSPIPE_MAGIC). */
     221    uint32_t                uMagic;
     222    /** Reserved for flags or something. */
     223    uint32_t                fReserved;
     224    /** The vtable. */
     225    PCRTVFSPIPEOPS          pOps;
     226    /** The stream handle data. */
     227    RTVFSIOSTREAMINTERNAL   Stream;
     228} RTVFSPIPEINTERNAL;
     229
     230
     231/**
     232 * The VFS socket handle data.
     233 *
     234 * @extends RTVFSIOSTREAMINTERNAL
     235 */
     236typedef struct RTVFSSOCKETINTERNAL
     237{
     238    /** The VFS magic (RTVFSSOCKET_MAGIC). */
     239    uint32_t                uMagic;
     240    /** Reserved for flags or something. */
     241    uint32_t                fReserved;
     242    /** The vtable. */
     243    PCRTVFSSOCKETOPS        pOps;
     244    /** The stream handle data. */
     245    RTVFSIOSTREAMINTERNAL   Stream;
     246} RTVFSSOCKETINTERNAL;
     247
     248#endif /* later */
     249
     250
     251/*
     252 *
     253 *  B A S E   O B J E C T
     254 *  B A S E   O B J E C T
     255 *  B A S E   O B J E C T
     256 *
     257 */
     258
     259/**
     260 * Write locks the object.
     261 *
     262 * @param   pThis               The object to lock.
     263 */
     264DECLINLINE(void) rtVfsObjWriteLock(RTVFSOBJINTERNAL *pThis)
     265{
     266    if (pThis->hSemRW != NIL_RTSEMRW)
     267    {
     268        int rc = RTSemRWRequestWrite(pThis->hSemRW, RT_INDEFINITE_WAIT);
     269        AssertRC(rc);
     270    }
     271}
     272
     273
     274/**
     275 * Undoing the effects of rtVfsObjWriteLock.
     276 *
     277 * @param   pThis               The object to lock.
     278 */
     279DECLINLINE(void) rtVfsObjWriteUnlock(RTVFSOBJINTERNAL *pThis)
     280{
     281    if (pThis->hSemRW != NIL_RTSEMRW)
     282    {
     283        int rc = RTSemRWReleaseWrite(pThis->hSemRW);
     284        AssertRC(rc);
     285    }
     286}
     287
     288/**
     289 * Read locks the object.
     290 *
     291 * @param   pThis               The object to lock.
     292 */
     293DECLINLINE(void) rtVfsObjReadLock(RTVFSOBJINTERNAL *pThis)
     294{
     295    if (pThis->hSemRW != NIL_RTSEMRW)
     296    {
     297        int rc = RTSemRWRequestRead(pThis->hSemRW, RT_INDEFINITE_WAIT);
     298        AssertRC(rc);
     299    }
     300}
     301
     302
     303/**
     304 * Undoing the effects of rtVfsObjReadLock.
     305 *
     306 * @param   pThis               The object to lock.
     307 */
     308DECLINLINE(void) rtVfsObjReadUnlock(RTVFSOBJINTERNAL *pThis)
     309{
     310    if (pThis->hSemRW != NIL_RTSEMRW)
     311    {
     312        int rc = RTSemRWReleaseRead(pThis->hSemRW);
     313        AssertRC(rc);
     314    }
     315}
     316
    223317
    224318
    225319/**
    226320 * Internal object retainer that asserts sanity in strict builds.
     321 *
     322 * @returns The new reference count.
     323 * @param   pThis               The base object handle data.
     324 */
     325DECLINLINE(uint32_t) rtVfsObjRetain(RTVFSOBJINTERNAL *pThis)
     326{
     327    uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
     328    AssertMsg(cRefs > 1 && cRefs < _1M,
     329              ("%#x %p ops=%p %s (%d)\n", cRefs, pThis, pThis->pOps, pThis->pOps->pszName, pThis->pOps->enmType));
     330    return cRefs;
     331}
     332
     333
     334/**
     335 * Internal object retainer that asserts sanity in strict builds.
     336 *
     337 * @param   pThis               The base object handle data.
     338 */
     339DECLINLINE(void) rtVfsObjRetainVoid(RTVFSOBJINTERNAL *pThis)
     340{
     341    uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
     342    AssertMsg(cRefs > 1 && cRefs < _1M,
     343              ("%#x %p ops=%p %s (%d)\n", cRefs, pThis, pThis->pOps, pThis->pOps->pszName, pThis->pOps->enmType));
     344    NOREF(cRefs);
     345}
     346
     347
     348RTDECL(uint32_t) RTVfsObjRetain(RTVFSOBJ hVfsObj)
     349{
     350    RTVFSOBJINTERNAL *pThis = hVfsObj;
     351    AssertPtrReturn(pThis, UINT32_MAX);
     352    AssertReturn(pThis->uMagic == RTVFSOBJ_MAGIC, UINT32_MAX);
     353
     354    return rtVfsObjRetain(pThis);
     355}
     356
     357
     358/**
     359 * Does the actual object destruction for rtVfsObjRelease().
     360 *
     361 * @param   pThis               The object to destroy.
     362 */
     363static void rtVfsObjDestroy(RTVFSOBJINTERNAL *pThis)
     364{
     365    RTVFSOBJTYPE const enmType = pThis->pOps->enmType;
     366
     367    /*
     368     * Invalidate the object.
     369     */
     370    rtVfsObjWriteLock(pThis);           /* paranoia */
     371    switch (enmType)
     372    {
     373        case RTVFSOBJTYPE_BASE:
     374            break;
     375
     376        case RTVFSOBJTYPE_VFS:
     377            ASMAtomicWriteU32(&RT_FROM_MEMBER(pThis, RTVFSINTERNAL, Base)->uMagic, RTVFS_MAGIC_DEAD);
     378            break;
     379
     380        case RTVFSOBJTYPE_FS_STREAM:
     381            ASMAtomicWriteU32(&RT_FROM_MEMBER(pThis, RTVFSFSSTREAMINTERNAL, Base)->uMagic, RTVFSFSSTREAM_MAGIC_DEAD);
     382            break;
     383
     384        case RTVFSOBJTYPE_IO_STREAM:
     385            ASMAtomicWriteU32(&RT_FROM_MEMBER(pThis, RTVFSIOSTREAMINTERNAL, Base)->uMagic, RTVFSIOSTREAM_MAGIC_DEAD);
     386            break;
     387
     388        case RTVFSOBJTYPE_DIR:
     389            ASMAtomicWriteU32(&RT_FROM_MEMBER(pThis, RTVFSDIRINTERNAL, Base)->uMagic, RTVFSDIR_MAGIC_DEAD);
     390            break;
     391
     392        case RTVFSOBJTYPE_FILE:
     393            ASMAtomicWriteU32(&RT_FROM_MEMBER(pThis, RTVFSIOSTREAMINTERNAL, Base)->uMagic, RTVFSIOSTREAM_MAGIC_DEAD);
     394            ASMAtomicWriteU32(&RT_FROM_MEMBER(pThis, RTVFSFILEINTERNAL, Stream.Base)->uMagic, RTVFSFILE_MAGIC_DEAD);
     395            break;
     396
     397        case RTVFSOBJTYPE_SYMLINK:
     398            ASMAtomicWriteU32(&RT_FROM_MEMBER(pThis, RTVFSSYMLINKINTERNAL, Base)->uMagic, RTVFSSYMLINK_MAGIC_DEAD);
     399            break;
     400
     401        case RTVFSOBJTYPE_INVALID:
     402        case RTVFSOBJTYPE_END:
     403        case RTVFSOBJTYPE_32BIT_HACK:
     404            AssertMsgFailed(("enmType=%d ops=%p %s\n", enmType, pThis->pOps, pThis->pOps->pszName));
     405            break;
     406        /* no default as we want gcc warnings. */
     407    }
     408    ASMAtomicWriteU32(&pThis->uMagic, RTVFSOBJ_MAGIC_DEAD);
     409    rtVfsObjWriteUnlock(pThis);
     410
     411    /*
     412     * Close the object and free the handle.
     413     */
     414    int rc = pThis->pOps->pfnClose(pThis->pvThis);
     415    AssertRC(rc);
     416    RTMemFree(pThis);
     417}
     418
     419
     420/**
     421 * Internal object releaser that asserts sanity in strict builds.
    227422 *
    228423 * @returns The new reference count.
    229424 * @param   pcRefs              The reference counter.
    230425 */
    231 DECLINLINE(uint32_t) rtVfsRetain(uint32_t volatile *pcRefs)
    232 {
    233     uint32_t cRefs = ASMAtomicIncU32(pcRefs);
    234     AssertMsg(cRefs > 1 && cRefs < _1M, ("%#x\n", cRefs));
     426DECLINLINE(uint32_t) rtVfsObjRelease(RTVFSOBJINTERNAL *pThis)
     427{
     428    uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs);
     429    AssertMsg(cRefs < _1M, ("%#x %p ops=%p %s (%d)\n", cRefs, pThis, pThis->pOps, pThis->pOps->pszName, pThis->pOps->enmType));
     430    if (cRefs == 0)
     431        rtVfsObjDestroy(pThis);
    235432    return cRefs;
    236433}
    237434
    238435
    239 /**
    240  * Internal object retainer that asserts sanity in strict builds.
    241  *
    242  * @param   pcRefs              The reference counter.
    243  */
    244 DECLINLINE(void) rtVfsRetainVoid(uint32_t volatile *pcRefs)
    245 {
    246     (void)rtVfsRetain(pcRefs);
    247 }
    248 
    249 
    250 /**
    251  * Internal object releaser that asserts sanity in strict builds.
    252  *
    253  * @returns The new reference count.
    254  * @param   pcRefs              The reference counter.
    255  */
    256 DECLINLINE(uint32_t) rtVfsRelease(uint32_t volatile *pcRefs)
    257 {
    258     uint32_t cRefs = ASMAtomicDecU32(pcRefs);
    259     AssertMsg(cRefs < _1M, ("%#x\n", cRefs));
    260     return cRefs;
    261 }
     436RTDECL(uint32_t) RTVfsObjRelease(RTVFSOBJ hVfsObj)
     437{
     438    RTVFSOBJINTERNAL *pThis = hVfsObj;
     439    AssertPtrReturn(pThis, UINT32_MAX);
     440    AssertReturn(pThis->uMagic == RTVFSOBJ_MAGIC, UINT32_MAX);
     441    return rtVfsObjRelease(pThis);
     442}
     443
    262444
    263445
     
    527709    AssertPtr(pThis);
    528710    Assert(pThis->uMagic == RTVFS_MAGIC);
    529     Assert(pThis->cRefs > 0);
     711    Assert(pThis->Base.cRefs > 0);
    530712    AssertPtr(pPath);
    531713    AssertPtr(ppVfsParentDir);
     
    538720    /** @todo Union mounts, traversal optimization methods, races, ++ */
    539721    RTVFSDIRINTERNAL *pCurDir;
    540     RTVFS_READ_LOCK(pThis->hSemRW);
    541     int rc = pThis->pOps->pfnOpenRoot(pThis->pvThis, &pCurDir);
    542     RTVFS_READ_UNLOCK(pThis->hSemRW);
     722    rtVfsObjReadLock(&pThis->Base);
     723    int rc = pThis->pOps->pfnOpenRoot(pThis->Base.pvThis, &pCurDir);
     724    rtVfsObjReadUnlock(&pThis->Base);
    543725    if (RT_FAILURE(rc))
    544726        return rc;
     
    573755        if (fFinal)
    574756        {
    575             RTVFS_READ_LOCK(pCurDir->hSemRW);
    576             rc = pCurDir->pOps->pfnTraversalOpen(pCurDir->pvThis, pszEntry, NULL, &hSymlink, NULL);
    577             RTVFS_READ_UNLOCK(pCurDir->hSemRW);
     757            rtVfsObjReadLock(&pCurDir->Base);
     758            rc = pCurDir->pOps->pfnTraversalOpen(pCurDir->Base.pvThis, pszEntry, NULL, &hSymlink, NULL);
     759            rtVfsObjReadUnlock(&pCurDir->Base);
    578760            *pszEntryEnd = '\0';
    579761            if (rc == VERR_PATH_NOT_FOUND)
     
    590772        else
    591773        {
    592             RTVFS_READ_LOCK(pCurDir->hSemRW);
    593             rc = pCurDir->pOps->pfnTraversalOpen(pCurDir->pvThis, pszEntry, &hDir, &hSymlink, &hVfsMnt);
    594             RTVFS_READ_UNLOCK(pCurDir->hSemRW);
     774            rtVfsObjReadLock(&pCurDir->Base);
     775            rc = pCurDir->pOps->pfnTraversalOpen(pCurDir->Base.pvThis, pszEntry, &hDir, &hSymlink, &hVfsMnt);
     776            rtVfsObjReadUnlock(&pCurDir->Base);
    595777            *pszEntryEnd = '/';
    596778            if (RT_FAILURE(rc))
     
    641823                /* Must restart from the root (optimize this). */
    642824                RTVfsDirRelease(pCurDir);
    643                 RTVFS_READ_LOCK(pThis->hSemRW);
    644                 rc = pThis->pOps->pfnOpenRoot(pThis->pvThis, &pCurDir);
    645                 RTVFS_READ_UNLOCK(pThis->hSemRW);
     825                rtVfsObjReadLock(&pThis->Base);
     826                rc = pThis->pOps->pfnOpenRoot(pThis->Base.pvThis, &pCurDir);
     827                rtVfsObjReadUnlock(&pThis->Base);
    646828                if (RT_FAILURE(rc))
    647829                {
     
    658840             */
    659841            RTVfsDirRelease(pCurDir);
    660             RTVFS_READ_LOCK(hVfsMnt->hSemRW);
    661             rc = pThis->pOps->pfnOpenRoot(hVfsMnt->pvThis, &pCurDir);
    662             RTVFS_READ_UNLOCK(hVfsMnt->hSemRW);
     842            rtVfsObjReadLock(&hVfsMnt->Base);
     843            rc = pThis->pOps->pfnOpenRoot(hVfsMnt->Base.pvThis, &pCurDir);
     844            rtVfsObjReadUnlock(&hVfsMnt->Base);
    663845            if (RT_FAILURE(rc))
    664846            {
     
    692874    AssertPtrReturn(pThis, UINT32_MAX);
    693875    AssertReturn(pThis->uMagic == RTVFSDIR_MAGIC, UINT32_MAX);
    694     return rtVfsRetain(&pThis->cRefs);
     876    return rtVfsObjRetain(&pThis->Base);
    695877}
    696878
     
    701883    AssertPtrReturn(pThis, UINT32_MAX);
    702884    AssertReturn(pThis->uMagic == RTVFSDIR_MAGIC, UINT32_MAX);
    703 
    704     uint32_t cRefs = rtVfsRelease(&pThis->cRefs);
    705     if (!cRefs)
    706     {
    707         RTVFS_WRITE_LOCK(pThis->hSemRW);
    708         ASMAtomicWriteU32(&pThis->uMagic, RTVFSDIR_MAGIC_DEAD);
    709         RTVFS_WRITE_UNLOCK(pThis->hSemRW);
    710         pThis->pOps->Obj.pfnClose(pThis->pvThis);
    711         RTMemFree(pThis);
    712     }
    713 
    714     return cRefs;
     885    return rtVfsObjRelease(&pThis->Base);
    715886}
    716887
     
    730901    AssertPtrReturn(pThis, UINT32_MAX);
    731902    AssertReturn(pThis->uMagic == RTVFSSYMLINK_MAGIC, UINT32_MAX);
    732     return rtVfsRetain(&pThis->cRefs);
     903    return rtVfsObjRetain(&pThis->Base);
    733904}
    734905
     
    739910    AssertPtrReturn(pThis, UINT32_MAX);
    740911    AssertReturn(pThis->uMagic == RTVFSSYMLINK_MAGIC, UINT32_MAX);
    741 
    742     uint32_t cRefs = rtVfsRelease(&pThis->cRefs);
    743     if (!cRefs)
    744     {
    745         RTVFS_WRITE_LOCK(pThis->hSemRW);
    746         ASMAtomicWriteU32(&pThis->uMagic, RTVFSSYMLINK_MAGIC_DEAD);
    747         RTVFS_WRITE_UNLOCK(pThis->hSemRW);
    748         pThis->pOps->Obj.pfnClose(pThis->pvThis);
    749         RTMemFree(pThis);
    750     }
    751 
    752     return cRefs;
     912    return rtVfsObjRelease(&pThis->Base);
    753913}
    754914
     
    760920    AssertReturn(pThis->uMagic == RTVFSSYMLINK_MAGIC, VERR_INVALID_HANDLE);
    761921
    762     RTVFS_WRITE_LOCK(pThis->hSemRW);
    763     int rc = pThis->pOps->pfnRead(pThis->pvThis, pszTarget, cbTarget);
    764     RTVFS_WRITE_UNLOCK(pThis->hSemRW);
     922    rtVfsObjWriteLock(&pThis->Base);
     923    int rc = pThis->pOps->pfnRead(pThis->Base.pvThis, pszTarget, cbTarget);
     924    rtVfsObjWriteUnlock(&pThis->Base);
    765925
    766926    return rc;
     
    809969        return VERR_NO_MEMORY;
    810970
    811     pThis->uMagic   = RTVFSIOSTREAM_MAGIC;
    812     pThis->fFlags   = fOpen;
    813     pThis->pvThis   = (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT);
    814     pThis->pOps     = pIoStreamOps;
    815     pThis->hSemRW   = hSemRW != NIL_RTSEMRW ? hSemRW : pVfs ? pVfs->hSemRW : NIL_RTSEMRW;
    816     pThis->hVfs     = hVfs;
    817     pThis->cRefs    = 1;
     971    pThis->uMagic       = RTVFSIOSTREAM_MAGIC;
     972    pThis->fFlags       = fOpen;
     973    pThis->pOps         = pIoStreamOps;
     974    pThis->Base.uMagic  = RTVFSOBJ_MAGIC;
     975    pThis->Base.pvThis  = (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT);
     976    pThis->Base.hSemRW  = hSemRW != NIL_RTSEMRW ? hSemRW : pVfs ? pVfs->Base.hSemRW : NIL_RTSEMRW;
     977    pThis->Base.hVfs    = hVfs;
     978    pThis->Base.cRefs   = 1;
    818979    if (hVfs != NIL_RTVFS)
    819         rtVfsRetainVoid(&pVfs->cRefs);
     980        rtVfsObjRetainVoid(&pVfs->Base);
    820981
    821982    *phVfsIos    = pThis;
    822     *ppvInstance = pThis->pvThis;
     983    *ppvInstance = pThis->Base.pvThis;
    823984    return VINF_SUCCESS;
    824985}
     
    830991    AssertPtrReturn(pThis, UINT32_MAX);
    831992    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, UINT32_MAX);
    832     return rtVfsRetain(&pThis->cRefs);
     993    return rtVfsObjRetain(&pThis->Base);
    833994}
    834995
     
    8391000    AssertPtrReturn(pThis, UINT32_MAX);
    8401001    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, UINT32_MAX);
    841 
    842     uint32_t cRefs = rtVfsRelease(&pThis->cRefs);
    843     if (!cRefs)
    844     {
    845         /*
    846          * That was the last reference, close the stream.
    847          *
    848          * This is a little bit more complicated than when releasing a file or
    849          * directory handle because the I/O stream can be a sub-object and we
    850          * need to get to the real one before handing it to RTMemFree.
    851          */
    852         RTVFS_WRITE_LOCK(pThis->hSemRW);
    853         ASMAtomicWriteU32(&pThis->uMagic, RTVFSIOSTREAM_MAGIC_DEAD);
    854         RTVFS_WRITE_UNLOCK(pThis->hSemRW);
    855         pThis->pOps->Obj.pfnClose(pThis->pvThis);
    856 
    857         switch (pThis->pOps->Obj.enmType)
    858         {
    859             case RTVFSOBJTYPE_IOSTREAM:
    860                 RTMemFree(pThis);
    861                 break;
    862 
    863             case RTVFSOBJTYPE_FILE:
    864             {
    865                 RTVFSFILEINTERNAL *pThisFile = RT_FROM_MEMBER(pThis, RTVFSFILEINTERNAL, Stream);
    866                 ASMAtomicWriteU32(&pThisFile->uMagic, RTVFSIOSTREAM_MAGIC_DEAD);
    867                 RTMemFree(pThisFile);
    868                 break;
    869             }
    870 
    871             /* Add new I/O stream compatible handle types here. */
    872 
    873             default:
    874                 AssertMsgFailed(("%d\n", pThis->pOps->Obj.enmType));
    875                 break;
    876         }
    877     }
    878 
    879     return cRefs;
    880 
     1002    return rtVfsObjRelease(&pThis->Base);
    8811003}
    8821004
     
    8901012    if (pThis->pOps->Obj.enmType == RTVFSOBJTYPE_FILE)
    8911013    {
    892         rtVfsRetainVoid(&pThis->cRefs);
     1014        rtVfsObjRetainVoid(&pThis->Base);
    8931015        return RT_FROM_MEMBER(pThis, RTVFSFILEINTERNAL, Stream);
    8941016    }
     
    9051027    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, VERR_INVALID_HANDLE);
    9061028
    907     RTVFS_READ_LOCK(pThis->hSemRW);
    908     int rc = pThis->pOps->Obj.pfnQueryInfo(pThis->pvThis, pObjInfo, enmAddAttr);
    909     RTVFS_READ_UNLOCK(pThis->hSemRW);
     1029    rtVfsObjReadLock(&pThis->Base);
     1030    int rc = pThis->pOps->Obj.pfnQueryInfo(pThis->Base.pvThis, pObjInfo, enmAddAttr);
     1031    rtVfsObjReadUnlock(&pThis->Base);
    9101032    return rc;
    9111033}
     
    9251047    RTSgBufInit(&SgBuf, &Seg, 1);
    9261048
    927     RTVFS_WRITE_LOCK(pThis->hSemRW);
    928     int rc = pThis->pOps->pfnRead(pThis->pvThis, -1 /*off*/, &SgBuf, pcbRead == NULL /*fBlocking*/, pcbRead);
    929     RTVFS_WRITE_UNLOCK(pThis->hSemRW);
     1049    rtVfsObjWriteLock(&pThis->Base);
     1050    int rc = pThis->pOps->pfnRead(pThis->Base.pvThis, -1 /*off*/, &SgBuf, pcbRead == NULL /*fBlocking*/, pcbRead);
     1051    rtVfsObjWriteUnlock(&pThis->Base);
    9301052    return rc;
    9311053}
     
    9451067    RTSgBufInit(&SgBuf, &Seg, 1);
    9461068
    947     RTVFS_WRITE_LOCK(pThis->hSemRW);
    948     int rc = pThis->pOps->pfnWrite(pThis->pvThis, -1 /*off*/, &SgBuf, pcbWritten == NULL /*fBlocking*/, pcbWritten);
    949     RTVFS_WRITE_UNLOCK(pThis->hSemRW);
     1069    rtVfsObjWriteLock(&pThis->Base);
     1070    int rc = pThis->pOps->pfnWrite(pThis->Base.pvThis, -1 /*off*/, &SgBuf, pcbWritten == NULL /*fBlocking*/, pcbWritten);
     1071    rtVfsObjWriteUnlock(&pThis->Base);
    9501072    return rc;
    9511073}
     
    9631085    AssertReturn(fBlocking || pcbRead, VERR_INVALID_PARAMETER);
    9641086
    965     RTVFS_WRITE_LOCK(pThis->hSemRW);
    966     int rc = pThis->pOps->pfnRead(pThis->pvThis, -1 /*off*/, pSgBuf, fBlocking, pcbRead);
    967     RTVFS_WRITE_UNLOCK(pThis->hSemRW);
     1087    rtVfsObjWriteLock(&pThis->Base);
     1088    int rc = pThis->pOps->pfnRead(pThis->Base.pvThis, -1 /*off*/, pSgBuf, fBlocking, pcbRead);
     1089    rtVfsObjWriteUnlock(&pThis->Base);
    9681090    return rc;
    9691091}
     
    9811103    AssertReturn(fBlocking || pcbWritten, VERR_INVALID_PARAMETER);
    9821104
    983     RTVFS_WRITE_LOCK(pThis->hSemRW);
    984     int rc = pThis->pOps->pfnWrite(pThis->pvThis, -1 /*off*/, pSgBuf, fBlocking, pcbWritten);
    985     RTVFS_WRITE_UNLOCK(pThis->hSemRW);
     1105    rtVfsObjWriteLock(&pThis->Base);
     1106    int rc = pThis->pOps->pfnWrite(pThis->Base.pvThis, -1 /*off*/, pSgBuf, fBlocking, pcbWritten);
     1107    rtVfsObjWriteUnlock(&pThis->Base);
    9861108    return rc;
    9871109}
     
    9941116    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, VERR_INVALID_HANDLE);
    9951117
    996     RTVFS_WRITE_LOCK(pThis->hSemRW);
    997     int rc = pThis->pOps->pfnFlush(pThis->pvThis);
    998     RTVFS_WRITE_UNLOCK(pThis->hSemRW);
     1118    rtVfsObjWriteLock(&pThis->Base);
     1119    int rc = pThis->pOps->pfnFlush(pThis->Base.pvThis);
     1120    rtVfsObjWriteUnlock(&pThis->Base);
    9991121    return rc;
    10001122}
     
    10081130    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, VERR_INVALID_HANDLE);
    10091131
    1010     RTVFS_WRITE_LOCK(pThis->hSemRW);
    1011     int rc = pThis->pOps->pfnPollOne(pThis->pvThis, fEvents, cMillies, fIntr, pfRetEvents);
    1012     RTVFS_WRITE_UNLOCK(pThis->hSemRW);
     1132    rtVfsObjWriteLock(&pThis->Base);
     1133    int rc = pThis->pOps->pfnPollOne(pThis->Base.pvThis, fEvents, cMillies, fIntr, pfRetEvents);
     1134    rtVfsObjWriteUnlock(&pThis->Base);
    10131135    return rc;
    10141136}
     
    10221144
    10231145    RTFOFF off;
    1024     RTVFS_READ_LOCK(pThis->hSemRW);
    1025     int rc = pThis->pOps->pfnTell(pThis->pvThis, &off);
    1026     RTVFS_READ_UNLOCK(pThis->hSemRW);
     1146    rtVfsObjReadLock(&pThis->Base);
     1147    int rc = pThis->pOps->pfnTell(pThis->Base.pvThis, &off);
     1148    rtVfsObjReadUnlock(&pThis->Base);
    10271149    if (RT_FAILURE(rc))
    10281150        off = rc;
     
    10411163    if (pThis->pOps->pfnSkip)
    10421164    {
    1043         RTVFS_WRITE_LOCK(pThis->hSemRW);
    1044         rc = pThis->pOps->pfnSkip(pThis->pvThis, cb);
    1045         RTVFS_WRITE_UNLOCK(pThis->hSemRW);
     1165        rtVfsObjWriteLock(&pThis->Base);
     1166        rc = pThis->pOps->pfnSkip(pThis->Base.pvThis, cb);
     1167        rtVfsObjWriteUnlock(&pThis->Base);
    10461168    }
    10471169    else
     
    10541176            {
    10551177                size_t cbToRead = RT_MIN(cb, _64K);
    1056                 RTVFS_WRITE_LOCK(pThis->hSemRW);
     1178                rtVfsObjWriteLock(&pThis->Base);
    10571179                rc = RTVfsIoStrmRead(hVfsIos, pvBuf, cbToRead, NULL);
    1058                 RTVFS_WRITE_UNLOCK(pThis->hSemRW);
     1180                rtVfsObjWriteUnlock(&pThis->Base);
    10591181                if (RT_FAILURE(rc))
    10601182                    break;
     
    10801202    if (pThis->pOps->pfnSkip)
    10811203    {
    1082         RTVFS_WRITE_LOCK(pThis->hSemRW);
    1083         rc = pThis->pOps->pfnZeroFill(pThis->pvThis, cb);
    1084         RTVFS_WRITE_UNLOCK(pThis->hSemRW);
     1204        rtVfsObjWriteLock(&pThis->Base);
     1205        rc = pThis->pOps->pfnZeroFill(pThis->Base.pvThis, cb);
     1206        rtVfsObjWriteUnlock(&pThis->Base);
    10851207    }
    10861208    else
     
    10931215            {
    10941216                size_t cbToWrite = RT_MIN(cb, _64K);
    1095                 RTVFS_WRITE_LOCK(pThis->hSemRW);
     1217                rtVfsObjWriteLock(&pThis->Base);
    10961218                rc = RTVfsIoStrmWrite(hVfsIos, pvBuf, cbToWrite, NULL);
    1097                 RTVFS_WRITE_UNLOCK(pThis->hSemRW);
     1219                rtVfsObjWriteUnlock(&pThis->Base);
    10981220                if (RT_FAILURE(rc))
    10991221                    break;
     
    11541276        return VERR_NO_MEMORY;
    11551277
    1156     pThis->uMagic           = RTVFSFILE_MAGIC;
    1157     pThis->fReserved        = 0;
    1158     pThis->pOps             = pFileOps;
    1159     pThis->Stream.uMagic    = RTVFSIOSTREAM_MAGIC;
    1160     pThis->Stream.fFlags    = fOpen;
    1161     pThis->Stream.pvThis    = (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT);
    1162     pThis->Stream.pOps      = &pFileOps->Stream;
    1163     pThis->Stream.hSemRW    = pVfs ? pVfs->hSemRW : NIL_RTSEMRW;
    1164     pThis->Stream.hVfs      = hVfs;
    1165     pThis->Stream.cRefs     = 1;
     1278    pThis->uMagic               = RTVFSFILE_MAGIC;
     1279    pThis->fReserved            = 0;
     1280    pThis->pOps                 = pFileOps;
     1281    pThis->Stream.uMagic        = RTVFSIOSTREAM_MAGIC;
     1282    pThis->Stream.fFlags        = fOpen;
     1283    pThis->Stream.pOps          = &pFileOps->Stream;
     1284    pThis->Stream.Base.pvThis   = (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT);
     1285    pThis->Stream.Base.hSemRW   = pVfs ? pVfs->Base.hSemRW : NIL_RTSEMRW;
     1286    pThis->Stream.Base.hVfs     = hVfs;
     1287    pThis->Stream.Base.cRefs    = 1;
    11661288    if (hVfs != NIL_RTVFS)
    1167         rtVfsRetainVoid(&pVfs->cRefs);
     1289        rtVfsObjRetainVoid(&pVfs->Base);
    11681290
    11691291    *phVfsFile   = pThis;
    1170     *ppvInstance = pThis->Stream.pvThis;
     1292    *ppvInstance = pThis->Stream.Base.pvThis;
    11711293    return VINF_SUCCESS;
    11721294}
     
    12091331
    12101332                /** @todo there is a symlink creation race here. */
    1211                 RTVFS_WRITE_LOCK(pVfsParentDir->hSemRW);
    1212                 rc = pVfsParentDir->pOps->pfnOpenFile(pVfsParentDir->pvThis, pszEntryName, fOpen, phVfsFile);
    1213                 RTVFS_WRITE_UNLOCK(pVfsParentDir->hSemRW);
     1333                rtVfsObjWriteLock(&pVfsParentDir->Base);
     1334                rc = pVfsParentDir->pOps->pfnOpenFile(pVfsParentDir->Base.pvThis, pszEntryName, fOpen, phVfsFile);
     1335                rtVfsObjWriteUnlock(&pVfsParentDir->Base);
    12141336
    12151337                RTVfsDirRelease(pVfsParentDir);
     
    12351357    AssertPtrReturn(pThis, UINT32_MAX);
    12361358    AssertReturn(pThis->uMagic == RTVFSFILE_MAGIC, UINT32_MAX);
    1237     return rtVfsRetain(&pThis->Stream.cRefs);
     1359    return rtVfsObjRetain(&pThis->Stream.Base);
    12381360}
    12391361
     
    12441366    AssertPtrReturn(pThis, UINT32_MAX);
    12451367    AssertReturn(pThis->uMagic == RTVFSFILE_MAGIC, UINT32_MAX);
    1246 
    1247     uint32_t cRefs = rtVfsRelease(&pThis->Stream.cRefs);
    1248     if (!cRefs)
    1249     {
    1250         RTVFS_WRITE_LOCK(pThis->Stream.hSemRW);
    1251         ASMAtomicWriteU32(&pThis->uMagic, RTVFSFILE_MAGIC_DEAD);
    1252         ASMAtomicWriteU32(&pThis->Stream.uMagic, RTVFSIOSTREAM_MAGIC_DEAD);
    1253         RTVFS_WRITE_UNLOCK(pThis->Stream.hSemRW);
    1254 
    1255         pThis->pOps->Stream.Obj.pfnClose(pThis->Stream.pvThis);
    1256         RTMemFree(pThis);
    1257     }
    1258 
    1259     return cRefs;
     1368    return rtVfsObjRelease(&pThis->Stream.Base);
    12601369}
    12611370
     
    12671376    AssertReturn(pThis->uMagic == RTVFSFILE_MAGIC, NIL_RTVFSIOSTREAM);
    12681377
    1269     rtVfsRetainVoid(&pThis->Stream.cRefs);
     1378    rtVfsObjRetainVoid(&pThis->Stream.Base);
    12701379    return &pThis->Stream;
    12711380}
    12721381
    12731382
    1274 
    1275 #if 0 /* unfinished code => laptop */
    1276 
    1277 /*
    1278  *
    1279  *  V F S   c h a i n   s p e c i f i c a t i o n s
    1280  *  V F S   c h a i n   s p e c i f i c a t i o n s
    1281  *  V F S   c h a i n   s p e c i f i c a t i o n s
    1282  *
    1283  */
    1284 
    1285 /**
    1286  * A parsed VFS setup specficiation.
    1287  *
    1288  * Some specification examples.
    1289  *   :iprtvfs:ios(stdfile="./foo.tgz")|ios(gzip)|vfs(tar)
    1290  */
    1291 typedef struct RTVFSPARSEDSPEC
    1292 {
    1293     uint32_t    cElements;
    1294 } RTVFSPARSEDSPEC;
    1295 /** Pointer to a parse VFS setup specification. */
    1296 typedef RTVFSPARSEDSPEC *PRTVFSPARSEDSPEC;
    1297 
    1298 
    1299 /**
    1300  * Parses the VFS setup specficiation.
    1301  *
    1302  * @returns
    1303  * @param   pInfo       The output.
    1304  * @param   pszSpec     The input.  This needs some more work but the basic
    1305  *                      are that anything that does not start with ":iprtvfs:"
    1306  *                      will be treated like a file.  ":iprtvfs:" prefixed
    1307  *                      specifications will be understood as a VFS chain
    1308  *                      specification and parsed and constructured (by the
    1309  *                      caller).
    1310  * @param
    1311  */
    1312 static int rtVfsSpecParse(PRTVFSPARSEDSPEC pInfo, const char *pszSpec)
    1313 {
    1314 
    1315 }
    1316 
    1317 
    1318 RTDECL(int) RTVfsOpenIoStreamFromSpec(const char *pszSpec, uint32_t fOpen, RTVFSIOSTREAM hVfs)
    1319 {
    1320 
    1321 }
    1322 
    1323 #endif
    1324 
  • trunk/src/VBox/Runtime/common/zip/zipgzip.cpp

    r33941 r33945  
    452452    { /* Obj */
    453453        RTVFSOBJOPS_VERSION,
    454         RTVFSOBJTYPE_IOSTREAM,
     454        RTVFSOBJTYPE_IO_STREAM,
    455455        "gzip",
    456456        rtZipGzip_Close,
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette