VirtualBox

source: vbox/trunk/include/iprt/vfslowlevel.h@ 41549

Last change on this file since 41549 was 41549, checked in by vboxsync, 12 years ago

VFS/Filesystem: Convert the filesystem specific code to the VFS framework and make it work

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 45.3 KB
Line 
1/** @file
2 * IPRT - Virtual Filesystem.
3 */
4
5/*
6 * Copyright (C) 2010 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___iprt_vfslowlevel_h
27#define ___iprt_vfslowlevel_h
28
29#include <iprt/vfs.h>
30#include <iprt/err.h>
31#include <iprt/list.h>
32#include <iprt/param.h>
33
34
35RT_C_DECLS_BEGIN
36
37/** @defgroup grp_rt_vfs_lowlevel RTVfs - Low-level Interface.
38 * @ingroup grp_rt_vfs
39 * @{
40 */
41
42
43/** @name VFS Lock Abstraction
44 * @todo This should be moved somewhere else as it is of general use.
45 * @{ */
46
47/**
48 * VFS lock types.
49 */
50typedef enum RTVFSLOCKTYPE
51{
52 /** Invalid lock type. */
53 RTVFSLOCKTYPE_INVALID = 0,
54 /** Read write semaphore. */
55 RTVFSLOCKTYPE_RW,
56 /** Fast mutex semaphore (critical section in ring-3). */
57 RTVFSLOCKTYPE_FASTMUTEX,
58 /** Full fledged mutex semaphore. */
59 RTVFSLOCKTYPE_MUTEX,
60 /** The end of valid lock types. */
61 RTVFSLOCKTYPE_END,
62 /** The customary 32-bit type hack. */
63 RTVFSLOCKTYPE_32BIT_HACK = 0x7fffffff
64} RTVFSLOCKTYPE;
65
66/** VFS lock handle. */
67typedef struct RTVFSLOCKINTERNAL *RTVFSLOCK;
68/** Pointer to a VFS lock handle. */
69typedef RTVFSLOCK *PRTVFSLOCK;
70/** Nil VFS lock handle. */
71#define NIL_RTVFSLOCK ((RTVFSLOCK)~(uintptr_t)0)
72
73/** Special handle value for creating a new read/write semaphore based lock. */
74#define RTVFSLOCK_CREATE_RW ((RTVFSLOCK)~(uintptr_t)1)
75/** Special handle value for creating a new fast mutex semaphore based lock. */
76#define RTVFSLOCK_CREATE_FASTMUTEX ((RTVFSLOCK)~(uintptr_t)2)
77/** Special handle value for creating a new mutex semaphore based lock. */
78#define RTVFSLOCK_CREATE_MUTEX ((RTVFSLOCK)~(uintptr_t)3)
79
80/**
81 * Retains a reference to the VFS lock handle.
82 *
83 * @returns New reference count on success, UINT32_MAX on failure.
84 * @param hLock The VFS lock handle.
85 */
86RTDECL(uint32_t) RTVfsLockRetain(RTVFSLOCK hLock);
87
88/**
89 * Releases a reference to the VFS lock handle.
90 *
91 * @returns New reference count on success (0 if closed), UINT32_MAX on failure.
92 * @param hLock The VFS lock handle.
93 */
94RTDECL(uint32_t) RTVfsLockRelease(RTVFSLOCK hLock);
95
96/**
97 * Gets the lock type.
98 *
99 * @returns The lock type on success, RTVFSLOCKTYPE_INVALID if the handle is
100 * not valid.
101 * @param hLock The lock handle.
102 */
103RTDECL(RTVFSLOCKTYPE) RTVfsLockGetType(RTVFSLOCK hLock);
104
105
106
107RTDECL(void) RTVfsLockAcquireReadSlow(RTVFSLOCK hLock);
108RTDECL(void) RTVfsLockReleaseReadSlow(RTVFSLOCK hLock);
109RTDECL(void) RTVfsLockAcquireWriteSlow(RTVFSLOCK hLock);
110RTDECL(void) RTVfsLockReleaseWriteSlow(RTVFSLOCK hLock);
111
112/**
113 * Acquire a read lock.
114 *
115 * @param hLock The lock handle, can be NIL.
116 */
117DECLINLINE(void) RTVfsLockAcquireRead(RTVFSLOCK hLock)
118{
119 if (hLock != NIL_RTVFSLOCK)
120 RTVfsLockAcquireReadSlow(hLock);
121}
122
123
124/**
125 * Release a read lock.
126 *
127 * @param hLock The lock handle, can be NIL.
128 */
129DECLINLINE(void) RTVfsLockReleaseRead(RTVFSLOCK hLock)
130{
131 if (hLock != NIL_RTVFSLOCK)
132 RTVfsLockReleaseReadSlow(hLock);
133}
134
135
136/**
137 * Acquire a write lock.
138 *
139 * @param hLock The lock handle, can be NIL.
140 */
141DECLINLINE(void) RTVfsLockAcquireWrite(RTVFSLOCK hLock)
142{
143 if (hLock != NIL_RTVFSLOCK)
144 RTVfsLockAcquireWriteSlow(hLock);
145}
146
147
148/**
149 * Release a write lock.
150 *
151 * @param hLock The lock handle, can be NIL.
152 */
153DECLINLINE(void) RTVfsLockReleaseWrite(RTVFSLOCK hLock)
154{
155 if (hLock != NIL_RTVFSLOCK)
156 RTVfsLockReleaseWriteSlow(hLock);
157}
158
159/** @} */
160
161/**
162 * The VFS operations.
163 */
164typedef struct RTVFSOPS
165{
166 /** The structure version (RTVFSOPS_VERSION). */
167 uint32_t uVersion;
168 /** The virtual file system feature mask. */
169 uint32_t fFeatures;
170 /** The name of the operations. */
171 const char *pszName;
172
173 /**
174 * Destructor.
175 *
176 * @param pvThis The implementation specific data.
177 */
178 DECLCALLBACKMEMBER(void, pfnDestroy)(void *pvThis);
179
180 /**
181 * Opens the root directory.
182 *
183 * @returns IPRT status code.
184 * @param pvThis The implementation specific data.
185 * @param phVfsDir Where to return the handle to the root directory.
186 */
187 DECLCALLBACKMEMBER(int, pfnOpenRoot)(void *pvThis, PRTVFSDIR phVfsDir);
188
189 /**
190 * Checks whether a given range in the underlying medium
191 * is in use by the virtual filesystem.
192 *
193 * @returns IPRT status code.
194 * @param pvThis The implementation specific data.
195 * @param off Start offset to check.
196 * @param cb Number of bytes to check.
197 * @param pfUsed Where to store whether the given range is in use.
198 */
199 DECLCALLBACKMEMBER(int, pfnIsRangeInUse)(void *pvThis, RTFOFF off, size_t cb,
200 bool *pfUsed);
201
202 /** @todo There will be more methods here to optimize opening and
203 * querying. */
204
205#if 0
206 /**
207 * Optional entry point for optimizing path traversal within the file system.
208 *
209 * @returns IPRT status code.
210 * @param pvThis The implementation specific data.
211 * @param pszPath The path to resolve.
212 * @param poffPath The current path offset on input, what we've
213 * traversed to on successful return.
214 * @param phVfs??? Return handle to what we've traversed.
215 * @param p??? Return other stuff...
216 */
217 DECLCALLBACKMEMBER(int, pfnTraverse)(void *pvThis, const char *pszPath, size_t *poffPath, PRTVFS??? phVfs?, ???* p???);
218#endif
219
220 /** Marks the end of the structure (RTVFSOPS_VERSION). */
221 uintptr_t uEndMarker;
222} RTVFSOPS;
223/** Pointer to constant VFS operations. */
224typedef RTVFSOPS const *PCRTVFSOPS;
225
226/** The RTVFSOPS structure version. */
227#define RTVFSOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x0f,1,0)
228
229/** @name RTVFSOPS::fFeatures
230 * @{ */
231/** The VFS supports attaching other systems. */
232#define RTVFSOPS_FEAT_ATTACH RT_BIT_32(0)
233/** @} */
234
235/**
236 * Creates a new VFS handle.
237 *
238 * @returns IPRT status code
239 * @param pVfs Ops The VFS operations.
240 * @param cbInstance The size of the instance data.
241 * @param hVfs The VFS handle to associate this VFS with.
242 * NIL_VFS is ok.
243 * @param hLock Handle to a custom lock to be used with the new
244 * object. The reference is consumed. NIL and
245 * special lock handles are fine.
246 * @param phVfs Where to return the new handle.
247 * @param ppvInstance Where to return the pointer to the instance data
248 * (size is @a cbInstance).
249 */
250RTDECL(int) RTVfsNew(PCRTVFSOPS pVfsOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock,
251 PRTVFS phVfs, void **ppvInstance);
252
253/**
254 * The basis for all virtual file system objects except RTVFS.
255 */
256typedef struct RTVFSOBJOPS
257{
258 /** The structure version (RTVFSOBJOPS_VERSION). */
259 uint32_t uVersion;
260 /** The object type for type introspection. */
261 RTVFSOBJTYPE enmType;
262 /** The name of the operations. */
263 const char *pszName;
264
265 /**
266 * Close the object.
267 *
268 * @returns IPRT status code.
269 * @param pvThis The implementation specific file data.
270 */
271 DECLCALLBACKMEMBER(int, pfnClose)(void *pvThis);
272
273 /**
274 * Get information about the file.
275 *
276 * @returns IPRT status code. See RTVfsObjQueryInfo.
277 * @param pvThis The implementation specific file data.
278 * @param pObjInfo Where to return the object info on success.
279 * @param enmAddAttr Which set of additional attributes to request.
280 * @sa RTVfsObjQueryInfo, RTFileQueryInfo, RTPathQueryInfo
281 */
282 DECLCALLBACKMEMBER(int, pfnQueryInfo)(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr);
283
284 /** Marks the end of the structure (RTVFSOBJOPS_VERSION). */
285 uintptr_t uEndMarker;
286} RTVFSOBJOPS;
287/** Pointer to constant VFS object operations. */
288typedef RTVFSOBJOPS const *PCRTVFSOBJOPS;
289
290/** The RTVFSOBJOPS structure version. */
291#define RTVFSOBJOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x1f,1,0)
292
293
294/**
295 * Creates a new VFS base object handle.
296 *
297 * @returns IPRT status code
298 * @param pObjOps The base object operations.
299 * @param cbInstance The size of the instance data.
300 * @param hVfs The VFS handle to associate this base object
301 * with. NIL_VFS is ok.
302 * @param hLock Handle to a custom lock to be used with the new
303 * object. The reference is consumed. NIL and
304 * special lock handles are fine.
305 * @param phVfsFss Where to return the new handle.
306 * @param ppvInstance Where to return the pointer to the instance data
307 * (size is @a cbInstance).
308 */
309RTDECL(int) RTVfsNewBaseObj(PCRTVFSOBJOPS pObjOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock,
310 PRTVFSOBJ phVfsObj, void **ppvInstance);
311
312
313/**
314 * Additional operations for setting object attributes.
315 */
316typedef struct RTVFSOBJSETOPS
317{
318 /** The structure version (RTVFSOBJSETOPS_VERSION). */
319 uint32_t uVersion;
320 /** The offset to the RTVFSOBJOPS structure. */
321 int32_t offObjOps;
322
323 /**
324 * Set the unix style owner and group.
325 *
326 * @returns IPRT status code.
327 * @param pvThis The implementation specific file data.
328 * @param fMode The new mode bits.
329 * @param fMask The mask indicating which bits we are
330 * changing.
331 * @sa RTFileSetMode
332 */
333 DECLCALLBACKMEMBER(int, pfnSetMode)(void *pvThis, RTFMODE fMode, RTFMODE fMask);
334
335 /**
336 * Set the timestamps associated with the object.
337 *
338 * @returns IPRT status code.
339 * @param pvThis The implementation specific file data.
340 * @param pAccessTime Pointer to the new access time. NULL if not
341 * to be changed.
342 * @param pModificationTime Pointer to the new modifcation time. NULL if
343 * not to be changed.
344 * @param pChangeTime Pointer to the new change time. NULL if not
345 * to be changed.
346 * @param pBirthTime Pointer to the new time of birth. NULL if
347 * not to be changed.
348 * @remarks See RTFileSetTimes for restrictions and behavior imposed by the
349 * host OS or underlying VFS provider.
350 * @sa RTFileSetTimes
351 */
352 DECLCALLBACKMEMBER(int, pfnSetTimes)(void *pvThis, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
353 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime);
354
355 /**
356 * Set the unix style owner and group.
357 *
358 * @returns IPRT status code.
359 * @param pvThis The implementation specific file data.
360 * @param uid The user ID of the new owner. NIL_RTUID if
361 * unchanged.
362 * @param gid The group ID of the new owner group. NIL_RTGID if
363 * unchanged.
364 * @sa RTFileSetOwner
365 */
366 DECLCALLBACKMEMBER(int, pfnSetOwner)(void *pvThis, RTUID uid, RTGID gid);
367
368 /** Marks the end of the structure (RTVFSOBJSETOPS_VERSION). */
369 uintptr_t uEndMarker;
370} RTVFSOBJSETOPS;
371/** Pointer to const object attribute setter operations. */
372typedef RTVFSOBJSETOPS const *PCRTVFSOBJSETOPS;
373
374/** The RTVFSOBJSETOPS structure version. */
375#define RTVFSOBJSETOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x2f,1,0)
376
377
378/**
379 * The filesystem stream operations.
380 *
381 * @extends RTVFSOBJOPS
382 */
383typedef struct RTVFSFSSTREAMOPS
384{
385 /** The basic object operation. */
386 RTVFSOBJOPS Obj;
387 /** The structure version (RTVFSFSSTREAMOPS_VERSION). */
388 uint32_t uVersion;
389 /** Reserved field, MBZ. */
390 uint32_t fReserved;
391
392 /**
393 * Gets the next object in the stream.
394 *
395 * @returns IPRT status code.
396 * @retval VINF_SUCCESS if a new object was retrieved.
397 * @retval VERR_EOF when there are no more objects.
398 * @param pvThis The implementation specific directory data.
399 * @param ppszName Where to return the object name. Must be freed by
400 * calling RTStrFree.
401 * @param penmType Where to return the object type.
402 * @param hVfsObj Where to return the object handle (referenced).
403 * This must be cast to the desired type before use.
404 * @sa RTVfsFsStrmNext
405 */
406 DECLCALLBACKMEMBER(int, pfnNext)(void *pvThis, char **ppszName, RTVFSOBJTYPE *penmType, PRTVFSOBJ phVfsObj);
407
408 /** Marks the end of the structure (RTVFSFSSTREAMOPS_VERSION). */
409 uintptr_t uEndMarker;
410} RTVFSFSSTREAMOPS;
411/** Pointer to const object attribute setter operations. */
412typedef RTVFSFSSTREAMOPS const *PCRTVFSFSSTREAMOPS;
413
414/** The RTVFSFSSTREAMOPS structure version. */
415#define RTVFSFSSTREAMOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x3f,1,0)
416
417
418/**
419 * Creates a new VFS filesystem stream handle.
420 *
421 * @returns IPRT status code
422 * @param pFsStreamOps The filesystem stream operations.
423 * @param cbInstance The size of the instance data.
424 * @param hVfs The VFS handle to associate this filesystem
425 * stream with. NIL_VFS is ok.
426 * @param hLock Handle to a custom lock to be used with the new
427 * object. The reference is consumed. NIL and
428 * special lock handles are fine.
429 * @param phVfsFss Where to return the new handle.
430 * @param ppvInstance Where to return the pointer to the instance data
431 * (size is @a cbInstance).
432 */
433RTDECL(int) RTVfsNewFsStream(PCRTVFSFSSTREAMOPS pFsStreamOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock,
434 PRTVFSFSSTREAM phVfsFss, void **ppvInstance);
435
436
437/**
438 * The directory operations.
439 *
440 * @extends RTVFSOBJOPS
441 * @extends RTVFSOBJSETOPS
442 */
443typedef struct RTVFSDIROPS
444{
445 /** The basic object operation. */
446 RTVFSOBJOPS Obj;
447 /** The structure version (RTVFSDIROPS_VERSION). */
448 uint32_t uVersion;
449 /** Reserved field, MBZ. */
450 uint32_t fReserved;
451 /** The object setter operations. */
452 RTVFSOBJSETOPS ObjSet;
453
454 /**
455 * Opens a directory entry for traversal purposes.
456 *
457 * Method which sole purpose is helping the path traversal. Only one of
458 * the three output variables will be set, the others will left untouched
459 * (caller sets them to NIL).
460 *
461 * @returns IPRT status code.
462 * @retval VERR_PATH_NOT_FOUND if @a pszEntry was not found.
463 * @param pvThis The implementation specific directory data.
464 * @param pszEntry The name of the directory entry to remove.
465 * @param phVfsDir If not NULL and it is a directory, open it and
466 * return the handle here.
467 * @param phVfsSymlink If not NULL and it is a symbolic link, open it
468 * and return the handle here.
469 * @param phVfsMounted If not NULL and it is a mounted VFS directory,
470 * reference it and return the handle here.
471 * @todo Should com dir, symlinks and mount points using some common
472 * ancestor "class".
473 */
474 DECLCALLBACKMEMBER(int, pfnTraversalOpen)(void *pvThis, const char *pszEntry, PRTVFSDIR phVfsDir,
475 PRTVFSSYMLINK phVfsSymlink, PRTVFS phVfsMounted);
476
477 /**
478 * Open or create a file.
479 *
480 * @returns IPRT status code.
481 * @param pvThis The implementation specific directory data.
482 * @param pszFilename The name of the immediate file to open or create.
483 * @param fOpen The open flags (RTFILE_O_XXX).
484 * @param phVfsFile Where to return the thandle to the opened file.
485 * @sa RTFileOpen.
486 */
487 DECLCALLBACKMEMBER(int, pfnOpenFile)(void *pvThis, const char *pszFilename, uint32_t fOpen, PRTVFSFILE phVfsFile);
488
489 /**
490 * Open an existing subdirectory.
491 *
492 * @returns IPRT status code.
493 * @param pvThis The implementation specific directory data.
494 * @param pszSubDir The name of the immediate subdirectory to open.
495 * @param phVfsDir Where to return the handle to the opened directory.
496 * @sa RTDirOpen.
497 */
498 DECLCALLBACKMEMBER(int, pfnOpenDir)(void *pvThis, const char *pszSubDir, PRTVFSDIR phVfsDir);
499
500 /**
501 * Creates a new subdirectory.
502 *
503 * @returns IPRT status code.
504 * @param pvThis The implementation specific directory data.
505 * @param pszSubDir The name of the immediate subdirectory to create.
506 * @param fMode The mode mask of the new directory.
507 * @param phVfsDir Where to optionally return the handle to the newly
508 * create directory.
509 * @sa RTDirCreate.
510 */
511 DECLCALLBACKMEMBER(int, pfnCreateDir)(void *pvThis, const char *pszSubDir, RTFMODE fMode, PRTVFSDIR phVfsDir);
512
513 /**
514 * Opens an existing symbolic link.
515 *
516 * @returns IPRT status code.
517 * @param pvThis The implementation specific directory data.
518 * @param pszSymlink The name of the immediate symbolic link to open.
519 * @param phVfsSymlink Where to optionally return the handle to the
520 * newly create symbolic link.
521 * @sa RTSymlinkCreate.
522 */
523 DECLCALLBACKMEMBER(int, pfnOpenSymlink)(void *pvThis, const char *pszSymlink, PRTVFSSYMLINK phVfsSymlink);
524
525 /**
526 * Creates a new symbolic link.
527 *
528 * @returns IPRT status code.
529 * @param pvThis The implementation specific directory data.
530 * @param pszSymlink The name of the immediate symbolic link to create.
531 * @param pszTarget The symbolic link target.
532 * @param enmType The symbolic link type.
533 * @param phVfsSymlink Where to optionally return the handle to the
534 * newly create symbolic link.
535 * @sa RTSymlinkCreate.
536 */
537 DECLCALLBACKMEMBER(int, pfnCreateSymlink)(void *pvThis, const char *pszSymlink, const char *pszTarget,
538 RTSYMLINKTYPE enmType, PRTVFSSYMLINK phVfsSymlink);
539
540 /**
541 * Removes a directory entry.
542 *
543 * @returns IPRT status code.
544 * @param pvThis The implementation specific directory data.
545 * @param pszEntry The name of the directory entry to remove.
546 * @param fType If non-zero, this restricts the type of the entry to
547 * the object type indicated by the mask
548 * (RTFS_TYPE_XXX).
549 * @sa RTFileRemove, RTDirRemove, RTSymlinkRemove.
550 */
551 DECLCALLBACKMEMBER(int, pfnUnlinkEntry)(void *pvThis, const char *pszEntry, RTFMODE fType, PRTVFSDIR phVfsDir);
552
553 /**
554 * Rewind the directory stream so that the next read returns the first
555 * entry.
556 *
557 * @returns IPRT status code.
558 * @param pvThis The implementation specific directory data.
559 */
560 DECLCALLBACKMEMBER(int, pfnRewindDir)(void *pvThis);
561
562 /**
563 * Rewind the directory stream so that the next read returns the first
564 * entry.
565 *
566 * @returns IPRT status code.
567 * @param pvThis The implementation specific directory data.
568 * @param pDirEntry Output buffer.
569 * @param pcbDirEntry Complicated, see RTDirReadEx.
570 * @param enmAddAttr Which set of additional attributes to request.
571 * @sa RTDirReadEx
572 */
573 DECLCALLBACKMEMBER(int, pfnReadDir)(void *pvThis, PRTDIRENTRYEX pDirEntry, size_t *pcbDirEntry, RTFSOBJATTRADD enmAddAttr);
574
575 /** Marks the end of the structure (RTVFSDIROPS_VERSION). */
576 uintptr_t uEndMarker;
577} RTVFSDIROPS;
578/** Pointer to const directory operations. */
579typedef RTVFSDIROPS const *PCRTVFSDIROPS;
580/** The RTVFSDIROPS structure version. */
581#define RTVFSDIROPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x4f,1,0)
582
583
584/**
585 * The symbolic link operations.
586 *
587 * @extends RTVFSOBJOPS
588 * @extends RTVFSOBJSETOPS
589 */
590typedef struct RTVFSSYMLINKOPS
591{
592 /** The basic object operation. */
593 RTVFSOBJOPS Obj;
594 /** The structure version (RTVFSSYMLINKOPS_VERSION). */
595 uint32_t uVersion;
596 /** Reserved field, MBZ. */
597 uint32_t fReserved;
598 /** The object setter operations. */
599 RTVFSOBJSETOPS ObjSet;
600
601 /**
602 * Read the symbolic link target.
603 *
604 * @returns IPRT status code.
605 * @param pvThis The implementation specific symbolic link data.
606 * @param pszTarget The target buffer.
607 * @param cbTarget The size of the target buffer.
608 * @sa RTSymlinkRead
609 */
610 DECLCALLBACKMEMBER(int, pfnRead)(void *pvThis, char *pszTarget, size_t cbTarget);
611
612 /** Marks the end of the structure (RTVFSSYMLINKOPS_VERSION). */
613 uintptr_t uEndMarker;
614} RTVFSSYMLINKOPS;
615/** Pointer to const symbolic link operations. */
616typedef RTVFSSYMLINKOPS const *PCRTVFSSYMLINKOPS;
617/** The RTVFSSYMLINKOPS structure version. */
618#define RTVFSSYMLINKOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x5f,1,0)
619
620
621/**
622 * Creates a new VFS symlink handle.
623 *
624 * @returns IPRT status code
625 * @param pSymlinkOps The symlink operations.
626 * @param cbInstance The size of the instance data.
627 * @param hVfs The VFS handle to associate this symlink object
628 * with. NIL_VFS is ok.
629 * @param hLock Handle to a custom lock to be used with the new
630 * object. The reference is consumed. NIL and
631 * special lock handles are fine.
632 * @param phVfsSym Where to return the new handle.
633 * @param ppvInstance Where to return the pointer to the instance data
634 * (size is @a cbInstance).
635 */
636RTDECL(int) RTVfsNewSymlink(PCRTVFSSYMLINKOPS pSymlinkOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock,
637 PRTVFSSYMLINK phVfsSym, void **ppvInstance);
638
639
640/**
641 * The basis for all I/O objects (files, pipes, sockets, devices, ++).
642 *
643 * @extends RTVFSOBJOPS
644 */
645typedef struct RTVFSIOSTREAMOPS
646{
647 /** The basic object operation. */
648 RTVFSOBJOPS Obj;
649 /** The structure version (RTVFSIOSTREAMOPS_VERSION). */
650 uint32_t uVersion;
651 /** Feature field. */
652 uint32_t fFeatures;
653
654 /**
655 * Reads from the file/stream.
656 *
657 * @returns IPRT status code. See RTVfsIoStrmRead.
658 * @param pvThis The implementation specific file data.
659 * @param off Where to read at, -1 for the current position.
660 * @param pSgBuf Gather buffer describing the bytes that are to be
661 * written.
662 * @param fBlocking If @c true, the call is blocking, if @c false it
663 * should not block.
664 * @param pcbRead Where return the number of bytes actually read.
665 * This is set it 0 by the caller. If NULL, try read
666 * all and fail if incomplete.
667 * @sa RTVfsIoStrmRead, RTVfsIoStrmSgRead, RTVfsFileRead,
668 * RTVfsFileReadAt, RTFileRead, RTFileReadAt.
669 */
670 DECLCALLBACKMEMBER(int, pfnRead)(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead);
671
672 /**
673 * Writes to the file/stream.
674 *
675 * @returns IPRT status code.
676 * @param pvThis The implementation specific file data.
677 * @param off Where to start wrinting, -1 for the current
678 * position.
679 * @param pSgBuf Gather buffers describing the bytes that are to be
680 * written.
681 * @param fBlocking If @c true, the call is blocking, if @c false it
682 * should not block.
683 * @param pcbWritten Where to return the number of bytes actually
684 * written. This is set it 0 by the caller. If
685 * NULL, try write it all and fail if incomplete.
686 * @sa RTFileWrite, RTFileWriteAt.
687 */
688 DECLCALLBACKMEMBER(int, pfnWrite)(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten);
689
690 /**
691 * Flushes any pending data writes to the stream.
692 *
693 * @returns IPRT status code.
694 * @param pvThis The implementation specific file data.
695 * @sa RTFileFlush.
696 */
697 DECLCALLBACKMEMBER(int, pfnFlush)(void *pvThis);
698
699 /**
700 * Poll for events.
701 *
702 * @returns IPRT status code.
703 * @param pvThis The implementation specific file data.
704 * @param fEvents The events to poll for (RTPOLL_EVT_XXX).
705 * @param cMillies How long to wait for event to eventuate.
706 * @param fIntr Whether the wait is interruptible and can return
707 * VERR_INTERRUPTED (@c true) or if this condition
708 * should be hidden from the caller (@c false).
709 * @param pfRetEvents Where to return the event mask.
710 * @sa RTPollSetAdd, RTPoll, RTPollNoResume.
711 */
712 DECLCALLBACKMEMBER(int, pfnPollOne)(void *pvThis, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr,
713 uint32_t *pfRetEvents);
714
715 /**
716 * Tells the current file/stream position.
717 *
718 * @returns IPRT status code.
719 * @param pvThis The implementation specific file data.
720 * @param poffActual Where to return the actual offset.
721 * @sa RTFileTell
722 */
723 DECLCALLBACKMEMBER(int, pfnTell)(void *pvThis, PRTFOFF poffActual);
724
725 /**
726 * Skips @a cb ahead in the stream.
727 *
728 * @returns IPRT status code.
729 * @param pvThis The implementation specific file data.
730 * @param cb The number bytes to skip.
731 * @remarks This is optional and can be NULL.
732 */
733 DECLCALLBACKMEMBER(int, pfnSkip)(void *pvThis, RTFOFF cb);
734
735 /**
736 * Fills the stream with @a cb zeros.
737 *
738 * @returns IPRT status code.
739 * @param pvThis The implementation specific file data.
740 * @param cb The number of zero bytes to insert.
741 * @remarks This is optional and can be NULL.
742 */
743 DECLCALLBACKMEMBER(int, pfnZeroFill)(void *pvThis, RTFOFF cb);
744
745 /** Marks the end of the structure (RTVFSIOSTREAMOPS_VERSION). */
746 uintptr_t uEndMarker;
747} RTVFSIOSTREAMOPS;
748/** Pointer to const I/O stream operations. */
749typedef RTVFSIOSTREAMOPS const *PCRTVFSIOSTREAMOPS;
750
751/** The RTVFSIOSTREAMOPS structure version. */
752#define RTVFSIOSTREAMOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x6f,1,0)
753
754/** @name RTVFSIOSTREAMOPS::fFeatures
755 * @{ */
756/** No scatter gather lists, thank you. */
757#define RTVFSIOSTREAMOPS_FEAT_NO_SG RT_BIT_32(0)
758/** Mask of the valid I/O stream feature flags. */
759#define RTVFSIOSTREAMOPS_FEAT_VALID_MASK UINT32_C(0x00000001)
760/** @} */
761
762
763/**
764 * Creates a new VFS I/O stream handle.
765 *
766 * @returns IPRT status code
767 * @param pIoStreamOps The I/O stream operations.
768 * @param cbInstance The size of the instance data.
769 * @param fOpen The open flags. The minimum is the access mask.
770 * @param hVfs The VFS handle to associate this I/O stream
771 * with. NIL_VFS is ok.
772 * @param hLock Handle to a custom lock to be used with the new
773 * object. The reference is consumed. NIL and
774 * special lock handles are fine.
775 * @param phVfsIos Where to return the new handle.
776 * @param ppvInstance Where to return the pointer to the instance data
777 * (size is @a cbInstance).
778 */
779RTDECL(int) RTVfsNewIoStream(PCRTVFSIOSTREAMOPS pIoStreamOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs, RTVFSLOCK hLock,
780 PRTVFSIOSTREAM phVfsIos, void **ppvInstance);
781
782
783/**
784 * Gets the private data of an I/O stream.
785 *
786 * @returns Pointer to the private data. NULL if the handle is invalid in some
787 * way.
788 * @param hVfsIos The I/O stream handle.
789 * @param pIoStreamOps The I/O stream operations. This servers as a
790 * sort of password.
791 */
792RTDECL(void *) RTVfsIoStreamToPrivate(RTVFSIOSTREAM hVfsIos, PCRTVFSIOSTREAMOPS pIoStreamOps);
793
794
795/**
796 * The file operations.
797 *
798 * @extends RTVFSIOSTREAMOPS
799 * @extends RTVFSOBJSETOPS
800 */
801typedef struct RTVFSFILEOPS
802{
803 /** The I/O stream and basis object operations. */
804 RTVFSIOSTREAMOPS Stream;
805 /** The structure version (RTVFSFILEOPS_VERSION). */
806 uint32_t uVersion;
807 /** Reserved field, MBZ. */
808 uint32_t fReserved;
809 /** The object setter operations. */
810 RTVFSOBJSETOPS ObjSet;
811
812 /**
813 * Changes the current file position.
814 *
815 * @returns IPRT status code.
816 * @param pvThis The implementation specific file data.
817 * @param offSeek The offset to seek.
818 * @param uMethod The seek method, i.e. what the seek is relative to.
819 * @param poffActual Where to return the actual offset.
820 * @sa RTFileSeek
821 */
822 DECLCALLBACKMEMBER(int, pfnSeek)(void *pvThis, RTFOFF offSeek, unsigned uMethod, PRTFOFF poffActual);
823
824 /**
825 * Get the current file/stream size.
826 *
827 * @returns IPRT status code.
828 * @param pvThis The implementation specific file data.
829 * @param pcbFile Where to store the current file size.
830 * @sa RTFileGetSize
831 */
832 DECLCALLBACKMEMBER(int, pfnQuerySize)(void *pvThis, uint64_t *pcbFile);
833
834 /** @todo There will be more methods here. */
835
836 /** Marks the end of the structure (RTVFSFILEOPS_VERSION). */
837 uintptr_t uEndMarker;
838} RTVFSFILEOPS;
839/** Pointer to const file operations. */
840typedef RTVFSFILEOPS const *PCRTVFSFILEOPS;
841
842/** The RTVFSFILEOPS structure version. */
843#define RTVFSFILEOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x7f,1,0)
844
845/**
846 * Creates a new VFS file handle.
847 *
848 * @returns IPRT status code
849 * @param pFileOps The file operations.
850 * @param cbInstance The size of the instance data.
851 * @param fOpen The open flags. The minimum is the access mask.
852 * @param hVfs The VFS handle to associate this file with.
853 * NIL_VFS is ok.
854 * @param hLock Handle to a custom lock to be used with the new
855 * object. The reference is consumed. NIL and
856 * special lock handles are fine.
857 * @param phVfsFile Where to return the new handle.
858 * @param ppvInstance Where to return the pointer to the instance data
859 * (size is @a cbInstance).
860 */
861RTDECL(int) RTVfsNewFile(PCRTVFSFILEOPS pFileOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs, RTVFSLOCK hLock,
862 PRTVFSFILE phVfsFile, void **ppvInstance);
863
864
865/** @defgroup grp_rt_vfs_ll_util VFS Utility APIs
866 * @{ */
867
868/**
869 * Parsed path.
870 */
871typedef struct RTVFSPARSEDPATH
872{
873 /** The length of the path in szCopy. */
874 uint16_t cch;
875 /** The number of path components. */
876 uint16_t cComponents;
877 /** Set if the path ends with slash, indicating that it's a directory
878 * reference and not a file reference. The slash has been removed from
879 * the copy. */
880 bool fDirSlash;
881 /** The offset where each path component starts, i.e. the char after the
882 * slash. The array has cComponents + 1 entries, where the final one is
883 * cch + 1 so that one can always terminate the current component by
884 * szPath[aoffComponent[i] - 1] = '\0'. */
885 uint16_t aoffComponents[RTPATH_MAX / 2 + 1];
886 /** A normalized copy of the path.
887 * Reserve some extra space so we can be more relaxed about overflow
888 * checks and terminator paddings, especially when recursing. */
889 char szPath[RTPATH_MAX];
890} RTVFSPARSEDPATH;
891/** Pointer to a parsed path. */
892typedef RTVFSPARSEDPATH *PRTVFSPARSEDPATH;
893
894/** The max accepted path length.
895 * This must be a few chars shorter than RTVFSPARSEDPATH::szPath because we
896 * use two terminators and wish be a little bit lazy with checking. */
897#define RTVFSPARSEDPATH_MAX (RTPATH_MAX - 4)
898
899/**
900 * Appends @a pszPath (relative) to the already parsed path @a pPath.
901 *
902 * @retval VINF_SUCCESS
903 * @retval VERR_FILENAME_TOO_LONG
904 * @retval VERR_INTERNAL_ERROR_4
905 * @param pPath The parsed path to append @a pszPath onto.
906 * This is both input and output.
907 * @param pszPath The path to append. This must be relative.
908 * @param piRestartComp The component to restart parsing at. This is
909 * input/output. The input does not have to be
910 * within the valid range. Optional.
911 */
912RTDECL(int) RTVfsParsePathAppend(PRTVFSPARSEDPATH pPath, const char *pszPath, uint16_t *piRestartComp);
913
914/**
915 * Parses a path.
916 *
917 * @retval VINF_SUCCESS
918 * @retval VERR_FILENAME_TOO_LONG
919 * @param pPath Where to store the parsed path.
920 * @param pszPath The path to parse. Absolute or relative to @a
921 * pszCwd.
922 * @param pszCwd The current working directory. Must be
923 * absolute.
924 */
925RTDECL(int) RTVfsParsePath(PRTVFSPARSEDPATH pPath, const char *pszPath, const char *pszCwd);
926
927/**
928 * Same as RTVfsParsePath except that it allocates a temporary buffer.
929 *
930 * @retval VINF_SUCCESS
931 * @retval VERR_NO_TMP_MEMORY
932 * @retval VERR_FILENAME_TOO_LONG
933 * @param pszPath The path to parse. Absolute or relative to @a
934 * pszCwd.
935 * @param pszCwd The current working directory. Must be
936 * absolute.
937 * @param ppPath Where to store the pointer to the allocated
938 * buffer containing the parsed path. This must
939 * be freed by calling RTVfsParsePathFree. NULL
940 * will be stored on failured.
941 */
942RTDECL(int) RTVfsParsePathA(const char *pszPath, const char *pszCwd, PRTVFSPARSEDPATH *ppPath);
943
944/**
945 * Frees a buffer returned by RTVfsParsePathA.
946 *
947 * @param pPath The parsed path buffer to free. NULL is fine.
948 */
949RTDECL(void) RTVfsParsePathFree(PRTVFSPARSEDPATH pPath);
950
951/**
952 * Dummy implementation of RTVFSIOSTREAMOPS::pfnPollOne.
953 *
954 * This handles the case where there is no chance any events my be raised and
955 * all that is required is to wait according to the parameters.
956 *
957 * @returns IPRT status code.
958 * @param pvThis The implementation specific file data.
959 * @param fEvents The events to poll for (RTPOLL_EVT_XXX).
960 * @param cMillies How long to wait for event to eventuate.
961 * @param fIntr Whether the wait is interruptible and can return
962 * VERR_INTERRUPTED (@c true) or if this condition
963 * should be hidden from the caller (@c false).
964 * @param pfRetEvents Where to return the event mask.
965 * @sa RTVFSIOSTREAMOPS::pfnPollOne, RTPollSetAdd, RTPoll, RTPollNoResume.
966 */
967RTDECL(int) RTVfsUtilDummyPollOne(uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr, uint32_t *pfRetEvents);
968
969/** @} */
970
971
972/** @defgroup grp_rt_vfs_lowlevel_chain VFS Chains
973 * @ref grp_rt_vfs_chain
974 * @{
975 */
976
977
978/**
979 * Chain element input actions.
980 */
981typedef enum RTVFSCHAINACTION
982{
983 /** Invalid action. */
984 RTVFSCHAINACTION_INVALID = 0,
985 /** No action (start of the chain). */
986 RTVFSCHAINACTION_NONE,
987 /** Passive filtering (expressed by pipe symbol). */
988 RTVFSCHAINACTION_PASSIVE,
989 /** Push filtering (expressed by redirection-out symbol). */
990 RTVFSCHAINACTION_PUSH,
991 /** The end of the valid actions. */
992 RTVFSCHAINACTION_END,
993 /** Make sure it's a 32-bit type. */
994 RTVFSCHAINACTION_32BIT_HACK = 0x7fffffff
995} RTVFSCHAINACTION;
996
997
998/**
999 * VFS chain element specification.
1000 */
1001typedef struct RTVFSCHAINELEMSPEC
1002{
1003 /** The provider name. */
1004 char *pszProvider;
1005 /** The input type. */
1006 RTVFSOBJTYPE enmTypeIn;
1007 /** The output type. */
1008 RTVFSOBJTYPE enmTypeOut;
1009 /** The action to take (or not). */
1010 RTVFSCHAINACTION enmAction;
1011 /** The number of arguments. */
1012 uint32_t cArgs;
1013 /** Arguments. */
1014 char **papszArgs;
1015} RTVFSCHAINELEMSPEC;
1016/** Pointer to a chain element specification. */
1017typedef RTVFSCHAINELEMSPEC *PRTVFSCHAINELEMSPEC;
1018/** Pointer to a const chain element specification. */
1019typedef RTVFSCHAINELEMSPEC const *PCRTVFSCHAINELEMSPEC;
1020
1021
1022/**
1023 * Parsed VFS chain specification.
1024 */
1025typedef struct RTVFSCHAINSPEC
1026{
1027 /** The action element, UINT32_MAX if none.
1028 * Currently we only support one action element (RTVFSCHAINACTION_PASSIVE
1029 * is not considered). */
1030 uint32_t iActionElement;
1031 /** The number of elements. */
1032 uint32_t cElements;
1033 /** The elements. */
1034 PRTVFSCHAINELEMSPEC paElements;
1035} RTVFSCHAINSPEC;
1036/** Pointer to a parsed VFS chain specification. */
1037typedef RTVFSCHAINSPEC *PRTVFSCHAINSPEC;
1038/** Pointer to a const, parsed VFS chain specification. */
1039typedef RTVFSCHAINSPEC const *PCRTVFSCHAINSPEC;
1040
1041
1042/**
1043 * A chain element provider registration record.
1044 */
1045typedef struct RTVFSCHAINELEMENTREG
1046{
1047 /** The version (RTVFSCHAINELEMENTREG_VERSION). */
1048 uint32_t uVersion;
1049 /** Reserved, MBZ. */
1050 uint32_t fReserved;
1051 /** The provider name (unique). */
1052 const char *pszName;
1053 /** For chaining the providers. */
1054 RTLISTNODE ListEntry;
1055
1056 /**
1057 * Create a VFS from the given chain element specficiation.
1058 *
1059 * @returns IPRT status code.
1060 * @param pSpec The chain element specification.
1061 * @param phVfs Where to returned the VFS handle.
1062 */
1063 DECLCALLBACKMEMBER(int, pfnOpenVfs)( PCRTVFSCHAINELEMSPEC pSpec, PRTVFS phVfs);
1064
1065 /**
1066 * Open a directory from the given chain element specficiation.
1067 *
1068 * @returns IPRT status code.
1069 * @param pSpec The chain element specification.
1070 * @param phVfsDir Where to returned the directory handle.
1071 */
1072 DECLCALLBACKMEMBER(int, pfnOpenDir)( PCRTVFSCHAINELEMSPEC pSpec, PRTVFSDIR phVfsDir);
1073
1074 /**
1075 * Open a file from the given chain element specficiation.
1076 *
1077 * @returns IPRT status code.
1078 * @param pSpec The chain element specification.
1079 * @param fOpen The open flag. Can be zero and the
1080 * specification may modify it.
1081 * @param phVfsFile Where to returned the file handle.
1082 */
1083 DECLCALLBACKMEMBER(int, pfnOpenFile)( PCRTVFSCHAINELEMSPEC pSpec, uint32_t fOpen, PRTVFSFILE phVfsFile);
1084
1085 /**
1086 * Open a symlink from the given chain element specficiation.
1087 *
1088 * @returns IPRT status code.
1089 * @param pSpec The chain element specification.
1090 * @param phVfsSym Where to returned the symlink handle.
1091 */
1092 DECLCALLBACKMEMBER(int, pfnOpenSymlink)( PCRTVFSCHAINELEMSPEC pSpec, PRTVFSSYMLINK phVfsSym);
1093
1094 /**
1095 * Open a I/O stream from the given chain element specficiation.
1096 *
1097 * @returns IPRT status code.
1098 * @param pSpec The chain element specification.
1099 * @param fOpen The open flag. Can be zero and the
1100 * specification may modify it.
1101 * @param phVfsIos Where to returned the I/O stream handle.
1102 */
1103 DECLCALLBACKMEMBER(int, pfnOpenIoStream)(PCRTVFSCHAINELEMSPEC pSpec, uint32_t fOpen, PRTVFSIOSTREAM phVfsIos);
1104
1105 /**
1106 * Open a filesystem stream from the given chain element specficiation.
1107 *
1108 * @returns IPRT status code.
1109 * @param pSpec The chain element specification.
1110 * @param phVfsFss Where to returned the filesystem stream handle.
1111 */
1112 DECLCALLBACKMEMBER(int, pfnOpenFsStream)(PCRTVFSCHAINELEMSPEC pSpec, PRTVFSFSSTREAM phVfsFss);
1113
1114 /** End marker (RTVFSCHAINELEMENTREG_VERSION). */
1115 uintptr_t uEndMarker;
1116} RTVFSCHAINELEMENTREG;
1117/** Pointer to a VFS chain element registration record. */
1118typedef RTVFSCHAINELEMENTREG *PRTVFSCHAINELEMENTREG;
1119/** Pointer to a const VFS chain element registration record. */
1120typedef RTVFSCHAINELEMENTREG const *PCRTVFSCHAINELEMENTREG;
1121
1122/** The VFS chain element registration record version number. */
1123#define RTVFSCHAINELEMENTREG_VERSION RT_MAKE_U32_FROM_U8(0xff, 0x7f, 1, 0)
1124
1125
1126/**
1127 * Parses the specification.
1128 *
1129 * @returns IPRT status code.
1130 * @param pszSpec The specification string to parse.
1131 * @param fFlags Flags, see RTVFSCHAIN_PF_XXX.
1132 * @param enmLeadingAction The only allowed leading action type.
1133 * @param enmTrailingAction The only allowed trailing action type.
1134 * @param ppSpec Where to return the pointer to the parsed
1135 * specification. This must be freed by calling
1136 * RTVfsChainSpecFree. Will always be set (unless
1137 * invalid parameters.)
1138 * @param ppszError On failure, this will point at the error
1139 * location in @a pszSpec. Optional.
1140 */
1141RTDECL(int) RTVfsChainSpecParse(const char *pszSpec, uint32_t fFlags, RTVFSCHAINACTION enmLeadingAction,
1142 RTVFSCHAINACTION enmTrailingAction,
1143 PRTVFSCHAINSPEC *ppSpec, const char **ppszError);
1144
1145/** @name RTVfsChainSpecParse
1146 * @{ */
1147/** No real action is permitted, i.e. only passive filtering (aka pipe). */
1148#define RTVFSCHAIN_PF_NO_REAL_ACTION RT_BIT_32(0)
1149/** The specified leading action is optional. */
1150#define RTVFSCHAIN_PF_LEADING_ACTION_OPTIONAL RT_BIT_32(1)
1151/** The specified trailing action is optional. */
1152#define RTVFSCHAIN_PF_TRAILING_ACTION_OPTIONAL RT_BIT_32(2)
1153/** Mask of valid flags. */
1154#define RTVFSCHAIN_PF_VALID_MASK UINT32_C(0x00000007)
1155/** @}*/
1156
1157/**
1158 * Frees a parsed chain specification.
1159 *
1160 * @param pSpec What RTVfsChainSpecParse returned. NULL is
1161 * quietly ignored.
1162 */
1163RTDECL(void) RTVfsChainSpecFree(PRTVFSCHAINSPEC pSpec);
1164
1165/**
1166 * Registers a chain element provider.
1167 *
1168 * @returns IPRT status code
1169 * @param pRegRec The registration record.
1170 * @param fFromCtor Indicates where we're called from.
1171 */
1172RTDECL(int) RTVfsChainElementRegisterProvider(PRTVFSCHAINELEMENTREG pRegRec, bool fFromCtor);
1173
1174/**
1175 * Deregisters a chain element provider.
1176 *
1177 * @returns IPRT status code
1178 * @param pRegRec The registration record.
1179 * @param fFromDtor Indicates where we're called from.
1180 */
1181RTDECL(int) RTVfsChainElementDeregisterProvider(PRTVFSCHAINELEMENTREG pRegRec, bool fFromDtor);
1182
1183
1184/** @def RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER
1185 * Automatically registers a chain element provider using a global constructor
1186 * and destructor hack.
1187 *
1188 * @param pRegRec Pointer to the registration record.
1189 * @param name Some unique variable name prefix.
1190 */
1191
1192#ifdef __cplusplus
1193/**
1194 * Class used for registering a VFS chain element provider.
1195 */
1196class RTVfsChainElementAutoRegisterHack
1197{
1198private:
1199 /** The registration record, NULL if registration failed. */
1200 PRTVFSCHAINELEMENTREG m_pRegRec;
1201
1202public:
1203 RTVfsChainElementAutoRegisterHack(PRTVFSCHAINELEMENTREG a_pRegRec)
1204 : m_pRegRec(a_pRegRec)
1205 {
1206 int rc = RTVfsChainElementRegisterProvider(m_pRegRec, true);
1207 if (RT_FAILURE(rc))
1208 m_pRegRec = NULL;
1209 }
1210
1211 ~RTVfsChainElementAutoRegisterHack()
1212 {
1213 RTVfsChainElementDeregisterProvider(m_pRegRec, true);
1214 m_pRegRec = NULL;
1215 }
1216};
1217
1218# define RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER(pRegRec, name) \
1219 static RTVfsChainElementAutoRegisterHack name ## AutoRegistrationHack(pRegRec)
1220
1221#else
1222# define RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER(pRegRec, name) \
1223 extern void *name ## AutoRegistrationHack = \
1224 &Sorry_but_RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER_does_not_work_in_c_source_files
1225#endif
1226
1227
1228/** @} */
1229
1230
1231/** @} */
1232
1233RT_C_DECLS_END
1234
1235#endif /* !___iprt_vfslowlevel_h */
1236
Note: See TracBrowser for help on using the repository browser.

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