VirtualBox

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

Last change on this file since 76585 was 76585, checked in by vboxsync, 6 years ago

*: scm --fix-header-guard-endif

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 58.8 KB
Line 
1/** @file
2 * IPRT - Virtual Filesystem.
3 */
4
5/*
6 * Copyright (C) 2010-2019 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_INCLUDED_vfslowlevel_h
27#define IPRT_INCLUDED_vfslowlevel_h
28#ifndef RT_WITHOUT_PRAGMA_ONCE
29# pragma once
30#endif
31
32#include <iprt/vfs.h>
33#include <iprt/errcore.h>
34#include <iprt/list.h>
35#include <iprt/param.h>
36
37
38RT_C_DECLS_BEGIN
39
40/** @defgroup grp_rt_vfs_lowlevel RTVfs - Low-level Interface.
41 * @ingroup grp_rt_vfs
42 * @{
43 */
44
45
46/** @name VFS Lock Abstraction
47 * @todo This should be moved somewhere else as it is of general use.
48 * @{ */
49
50/**
51 * VFS lock types.
52 */
53typedef enum RTVFSLOCKTYPE
54{
55 /** Invalid lock type. */
56 RTVFSLOCKTYPE_INVALID = 0,
57 /** Read write semaphore. */
58 RTVFSLOCKTYPE_RW,
59 /** Fast mutex semaphore (critical section in ring-3). */
60 RTVFSLOCKTYPE_FASTMUTEX,
61 /** Full fledged mutex semaphore. */
62 RTVFSLOCKTYPE_MUTEX,
63 /** The end of valid lock types. */
64 RTVFSLOCKTYPE_END,
65 /** The customary 32-bit type hack. */
66 RTVFSLOCKTYPE_32BIT_HACK = 0x7fffffff
67} RTVFSLOCKTYPE;
68
69/** VFS lock handle. */
70typedef struct RTVFSLOCKINTERNAL *RTVFSLOCK;
71/** Pointer to a VFS lock handle. */
72typedef RTVFSLOCK *PRTVFSLOCK;
73/** Nil VFS lock handle. */
74#define NIL_RTVFSLOCK ((RTVFSLOCK)~(uintptr_t)0)
75
76/** Special handle value for creating a new read/write semaphore based lock. */
77#define RTVFSLOCK_CREATE_RW ((RTVFSLOCK)~(uintptr_t)1)
78/** Special handle value for creating a new fast mutex semaphore based lock. */
79#define RTVFSLOCK_CREATE_FASTMUTEX ((RTVFSLOCK)~(uintptr_t)2)
80/** Special handle value for creating a new mutex semaphore based lock. */
81#define RTVFSLOCK_CREATE_MUTEX ((RTVFSLOCK)~(uintptr_t)3)
82
83/**
84 * Retains a reference to the VFS lock handle.
85 *
86 * @returns New reference count on success, UINT32_MAX on failure.
87 * @param hLock The VFS lock handle.
88 */
89RTDECL(uint32_t) RTVfsLockRetain(RTVFSLOCK hLock);
90
91/**
92 * Releases a reference to the VFS lock handle.
93 *
94 * @returns New reference count on success (0 if closed), UINT32_MAX on failure.
95 * @param hLock The VFS lock handle.
96 */
97RTDECL(uint32_t) RTVfsLockRelease(RTVFSLOCK hLock);
98
99/**
100 * Gets the lock type.
101 *
102 * @returns The lock type on success, RTVFSLOCKTYPE_INVALID if the handle is
103 * not valid.
104 * @param hLock The lock handle.
105 */
106RTDECL(RTVFSLOCKTYPE) RTVfsLockGetType(RTVFSLOCK hLock);
107
108
109
110RTDECL(void) RTVfsLockAcquireReadSlow(RTVFSLOCK hLock);
111RTDECL(void) RTVfsLockReleaseReadSlow(RTVFSLOCK hLock);
112RTDECL(void) RTVfsLockAcquireWriteSlow(RTVFSLOCK hLock);
113RTDECL(void) RTVfsLockReleaseWriteSlow(RTVFSLOCK hLock);
114
115/**
116 * Acquire a read lock.
117 *
118 * @param hLock The lock handle, can be NIL.
119 */
120DECLINLINE(void) RTVfsLockAcquireRead(RTVFSLOCK hLock)
121{
122 if (hLock != NIL_RTVFSLOCK)
123 RTVfsLockAcquireReadSlow(hLock);
124}
125
126
127/**
128 * Release a read lock.
129 *
130 * @param hLock The lock handle, can be NIL.
131 */
132DECLINLINE(void) RTVfsLockReleaseRead(RTVFSLOCK hLock)
133{
134 if (hLock != NIL_RTVFSLOCK)
135 RTVfsLockReleaseReadSlow(hLock);
136}
137
138
139/**
140 * Acquire a write lock.
141 *
142 * @param hLock The lock handle, can be NIL.
143 */
144DECLINLINE(void) RTVfsLockAcquireWrite(RTVFSLOCK hLock)
145{
146 if (hLock != NIL_RTVFSLOCK)
147 RTVfsLockAcquireWriteSlow(hLock);
148}
149
150
151/**
152 * Release a write lock.
153 *
154 * @param hLock The lock handle, can be NIL.
155 */
156DECLINLINE(void) RTVfsLockReleaseWrite(RTVFSLOCK hLock)
157{
158 if (hLock != NIL_RTVFSLOCK)
159 RTVfsLockReleaseWriteSlow(hLock);
160}
161
162/** @} */
163
164/**
165 * The basis for all virtual file system objects.
166 */
167typedef struct RTVFSOBJOPS
168{
169 /** The structure version (RTVFSOBJOPS_VERSION). */
170 uint32_t uVersion;
171 /** The object type for type introspection. */
172 RTVFSOBJTYPE enmType;
173 /** The name of the operations. */
174 const char *pszName;
175
176 /**
177 * Close the object.
178 *
179 * @returns IPRT status code.
180 * @param pvThis The implementation specific file data.
181 */
182 DECLCALLBACKMEMBER(int, pfnClose)(void *pvThis);
183
184 /**
185 * Get information about the file.
186 *
187 * @returns IPRT status code. See RTVfsObjQueryInfo.
188 * @retval VERR_WRONG_TYPE if file system or file system stream.
189 * @param pvThis The implementation specific file data.
190 * @param pObjInfo Where to return the object info on success.
191 * @param enmAddAttr Which set of additional attributes to request.
192 * @sa RTVfsObjQueryInfo, RTFileQueryInfo, RTPathQueryInfo
193 */
194 DECLCALLBACKMEMBER(int, pfnQueryInfo)(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr);
195
196 /** Marks the end of the structure (RTVFSOBJOPS_VERSION). */
197 uintptr_t uEndMarker;
198} RTVFSOBJOPS;
199/** Pointer to constant VFS object operations. */
200typedef RTVFSOBJOPS const *PCRTVFSOBJOPS;
201
202/** The RTVFSOBJOPS structure version. */
203#define RTVFSOBJOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x1f,1,0)
204
205
206/**
207 * The VFS operations.
208 */
209typedef struct RTVFSOPS
210{
211 /** The basic object operation. */
212 RTVFSOBJOPS Obj;
213 /** The structure version (RTVFSOPS_VERSION). */
214 uint32_t uVersion;
215 /** The virtual file system feature mask. */
216 uint32_t fFeatures;
217
218 /**
219 * Opens the root directory.
220 *
221 * @returns IPRT status code.
222 * @param pvThis The implementation specific data.
223 * @param phVfsDir Where to return the handle to the root directory.
224 */
225 DECLCALLBACKMEMBER(int, pfnOpenRoot)(void *pvThis, PRTVFSDIR phVfsDir);
226
227 /**
228 * Query the status of the given storage range (optional).
229 *
230 * This can be used by the image compaction utilites to evict non-zero blocks
231 * that aren't currently being used by the file system.
232 *
233 * @returns IPRT status code.
234 * @param pvThis The implementation specific data.
235 * @param off Start offset to check.
236 * @param cb Number of bytes to check.
237 * @param pfUsed Where to store whether the given range is in use.
238 */
239 DECLCALLBACKMEMBER(int, pfnQueryRangeState)(void *pvThis, uint64_t off, size_t cb, bool *pfUsed);
240
241 /** @todo There will be more methods here to optimize opening and
242 * querying. */
243
244#if 0
245 /**
246 * Optional entry point for optimizing path traversal within the file system.
247 *
248 * @returns IPRT status code.
249 * @param pvThis The implementation specific data.
250 * @param pszPath The path to resolve.
251 * @param poffPath The current path offset on input, what we've
252 * traversed to on successful return.
253 * @param phVfs??? Return handle to what we've traversed.
254 * @param p??? Return other stuff...
255 */
256 DECLCALLBACKMEMBER(int, pfnTraverse)(void *pvThis, const char *pszPath, size_t *poffPath, PRTVFS??? phVfs?, ???* p???);
257#endif
258
259 /** @todo need rename API */
260
261 /** Marks the end of the structure (RTVFSOPS_VERSION). */
262 uintptr_t uEndMarker;
263} RTVFSOPS;
264/** Pointer to constant VFS operations. */
265typedef RTVFSOPS const *PCRTVFSOPS;
266
267/** The RTVFSOPS structure version. */
268#define RTVFSOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x0f,1,0)
269
270/** @name RTVFSOPS::fFeatures
271 * @{ */
272/** The VFS supports attaching other systems. */
273#define RTVFSOPS_FEAT_ATTACH RT_BIT_32(0)
274/** @} */
275
276/**
277 * Creates a new VFS handle.
278 *
279 * @returns IPRT status code
280 * @param pVfsOps The VFS operations.
281 * @param cbInstance The size of the instance data.
282 * @param hVfs The VFS handle to associate this VFS with.
283 * NIL_VFS is ok.
284 * @param hLock Handle to a custom lock to be used with the new
285 * object. The reference is consumed. NIL and
286 * special lock handles are fine.
287 * @param phVfs Where to return the new handle.
288 * @param ppvInstance Where to return the pointer to the instance data
289 * (size is @a cbInstance).
290 */
291RTDECL(int) RTVfsNew(PCRTVFSOPS pVfsOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock,
292 PRTVFS phVfs, void **ppvInstance);
293
294
295/**
296 * Creates a new VFS base object handle.
297 *
298 * @returns IPRT status code
299 * @param pObjOps The base object operations.
300 * @param cbInstance The size of the instance data.
301 * @param hVfs The VFS handle to associate this base object
302 * with. NIL_VFS is ok.
303 * @param hLock Handle to a custom lock to be used with the new
304 * object. The reference is consumed. NIL and
305 * special lock handles are fine.
306 * @param phVfsObj Where to return the new handle.
307 * @param ppvInstance Where to return the pointer to the instance data
308 * (size is @a cbInstance).
309 */
310RTDECL(int) RTVfsNewBaseObj(PCRTVFSOBJOPS pObjOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock,
311 PRTVFSOBJ phVfsObj, void **ppvInstance);
312
313
314/**
315 * Additional operations for setting object attributes.
316 */
317typedef struct RTVFSOBJSETOPS
318{
319 /** The structure version (RTVFSOBJSETOPS_VERSION). */
320 uint32_t uVersion;
321 /** The offset back to the RTVFSOBJOPS structure. */
322 uint32_t offObjOps;
323
324 /**
325 * Set the unix style owner and group.
326 *
327 * @returns IPRT status code.
328 * @param pvThis The implementation specific file data.
329 * @param fMode The new mode bits.
330 * @param fMask The mask indicating which bits we are
331 * changing.
332 * @note Optional, failing with VERR_WRITE_PROTECT if NULL.
333 * @sa RTFileSetMode
334 */
335 DECLCALLBACKMEMBER(int, pfnSetMode)(void *pvThis, RTFMODE fMode, RTFMODE fMask);
336
337 /**
338 * Set the timestamps associated with the object.
339 *
340 * @returns IPRT status code.
341 * @param pvThis The implementation specific file data.
342 * @param pAccessTime Pointer to the new access time. NULL if not
343 * to be changed.
344 * @param pModificationTime Pointer to the new modifcation time. NULL if
345 * not to be changed.
346 * @param pChangeTime Pointer to the new change time. NULL if not
347 * to be changed.
348 * @param pBirthTime Pointer to the new time of birth. NULL if
349 * not to be changed.
350 * @remarks See RTFileSetTimes for restrictions and behavior imposed by the
351 * host OS or underlying VFS provider.
352 * @note Optional, failing with VERR_WRITE_PROTECT if NULL.
353 * @sa RTFileSetTimes
354 */
355 DECLCALLBACKMEMBER(int, pfnSetTimes)(void *pvThis, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
356 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime);
357
358 /**
359 * Set the unix style owner and group.
360 *
361 * @returns IPRT status code.
362 * @param pvThis The implementation specific file data.
363 * @param uid The user ID of the new owner. NIL_RTUID if
364 * unchanged.
365 * @param gid The group ID of the new owner group. NIL_RTGID if
366 * unchanged.
367 * @note Optional, failing with VERR_WRITE_PROTECT if NULL.
368 * @sa RTFileSetOwner
369 */
370 DECLCALLBACKMEMBER(int, pfnSetOwner)(void *pvThis, RTUID uid, RTGID gid);
371
372 /** Marks the end of the structure (RTVFSOBJSETOPS_VERSION). */
373 uintptr_t uEndMarker;
374} RTVFSOBJSETOPS;
375/** Pointer to const object attribute setter operations. */
376typedef RTVFSOBJSETOPS const *PCRTVFSOBJSETOPS;
377
378/** The RTVFSOBJSETOPS structure version. */
379#define RTVFSOBJSETOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x2f,1,0)
380
381
382/**
383 * The filesystem stream operations.
384 *
385 * @extends RTVFSOBJOPS
386 */
387typedef struct RTVFSFSSTREAMOPS
388{
389 /** The basic object operation. */
390 RTVFSOBJOPS Obj;
391 /** The structure version (RTVFSFSSTREAMOPS_VERSION). */
392 uint32_t uVersion;
393 /** Reserved field, MBZ. */
394 uint32_t fReserved;
395
396 /**
397 * Gets the next object in the stream.
398 *
399 * Readable streams only.
400 *
401 * @returns IPRT status code.
402 * @retval VINF_SUCCESS if a new object was retrieved.
403 * @retval VERR_EOF when there are no more objects.
404 * @param pvThis The implementation specific directory data.
405 * @param ppszName Where to return the object name. Must be freed by
406 * calling RTStrFree.
407 * @param penmType Where to return the object type.
408 * @param phVfsObj Where to return the object handle (referenced). This
409 * must be cast to the desired type before use.
410 * @sa RTVfsFsStrmNext
411 *
412 * @note Setting this member to NULL is okay for write-only streams.
413 */
414 DECLCALLBACKMEMBER(int, pfnNext)(void *pvThis, char **ppszName, RTVFSOBJTYPE *penmType, PRTVFSOBJ phVfsObj);
415
416 /**
417 * Adds another object into the stream.
418 *
419 * Writable streams only.
420 *
421 * @returns IPRT status code.
422 * @param pvThis The implementation specific directory data.
423 * @param pszPath The path to the object.
424 * @param hVfsObj The object to add.
425 * @param fFlags Reserved for the future, MBZ.
426 * @sa RTVfsFsStrmAdd
427 *
428 * @note Setting this member to NULL is okay for read-only streams.
429 */
430 DECLCALLBACKMEMBER(int, pfnAdd)(void *pvThis, const char *pszPath, RTVFSOBJ hVfsObj, uint32_t fFlags);
431
432 /**
433 * Pushes an byte stream onto the stream (optional).
434 *
435 * Writable streams only.
436 *
437 * This differs from RTVFSFSSTREAMOPS::pfnAdd() in that it will create a regular
438 * file in the output file system stream and provide the actual content bytes
439 * via the returned I/O stream object.
440 *
441 * @returns IPRT status code.
442 * @param pvThis The implementation specific directory data.
443 * @param pszPath The path to the file.
444 * @param cbFile The file size. This can also be set to UINT64_MAX if
445 * the file system stream is backed by a file.
446 * @param paObjInfo Array of zero or more RTFSOBJINFO structures containing
447 * different pieces of information about the file. If any
448 * provided, the first one should be a RTFSOBJATTRADD_UNIX
449 * one, additional can be supplied if wanted. What exactly
450 * is needed depends on the underlying FS stream
451 * implementation.
452 * @param cObjInfo Number of items in the array @a paObjInfo points at.
453 * @param fFlags RTVFSFSSTRM_PUSH_F_XXX.
454 * @param phVfsIos Where to return the I/O stream to feed the file content
455 * to. If the FS stream is backed by a file, the returned
456 * handle can be cast to a file if necessary.
457 */
458 DECLCALLBACKMEMBER(int, pfnPushFile)(void *pvThis, const char *pszPath, uint64_t cbFile,
459 PCRTFSOBJINFO paObjInfo, uint32_t cObjInfo, uint32_t fFlags, PRTVFSIOSTREAM phVfsIos);
460
461 /**
462 * Marks the end of the stream.
463 *
464 * Writable streams only.
465 *
466 * @returns IPRT status code.
467 * @param pvThis The implementation specific directory data.
468 * @sa RTVfsFsStrmEnd
469 *
470 * @note Setting this member to NULL is okay for read-only streams.
471 */
472 DECLCALLBACKMEMBER(int, pfnEnd)(void *pvThis);
473
474 /** Marks the end of the structure (RTVFSFSSTREAMOPS_VERSION). */
475 uintptr_t uEndMarker;
476} RTVFSFSSTREAMOPS;
477/** Pointer to const object attribute setter operations. */
478typedef RTVFSFSSTREAMOPS const *PCRTVFSFSSTREAMOPS;
479
480/** The RTVFSFSSTREAMOPS structure version. */
481#define RTVFSFSSTREAMOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x3f,2,0)
482
483
484/**
485 * Creates a new VFS filesystem stream handle.
486 *
487 * @returns IPRT status code
488 * @param pFsStreamOps The filesystem stream operations.
489 * @param cbInstance The size of the instance data.
490 * @param hVfs The VFS handle to associate this filesystem
491 * stream with. NIL_VFS is ok.
492 * @param hLock Handle to a custom lock to be used with the new
493 * object. The reference is consumed. NIL and
494 * special lock handles are fine.
495 * @param fReadOnly Set if read-only, clear if write-only.
496 * @param phVfsFss Where to return the new handle.
497 * @param ppvInstance Where to return the pointer to the instance data
498 * (size is @a cbInstance).
499 */
500RTDECL(int) RTVfsNewFsStream(PCRTVFSFSSTREAMOPS pFsStreamOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock, bool fReadOnly,
501 PRTVFSFSSTREAM phVfsFss, void **ppvInstance);
502
503/**
504 * Gets the private data of an filesystem stream.
505 *
506 * @returns Pointer to the private data. NULL if the handle is invalid in some
507 * way.
508 * @param hVfsFss The FS stream handle.
509 * @param pFsStreamOps The FS stream operations. This servers as a
510 * sort of password.
511 */
512RTDECL(void *) RTVfsFsStreamToPrivate(RTVFSFSSTREAM hVfsFss, PCRTVFSFSSTREAMOPS pFsStreamOps);
513
514
515/**
516 * The directory operations.
517 *
518 * @extends RTVFSOBJOPS
519 * @extends RTVFSOBJSETOPS
520 */
521typedef struct RTVFSDIROPS
522{
523 /** The basic object operation. */
524 RTVFSOBJOPS Obj;
525 /** The structure version (RTVFSDIROPS_VERSION). */
526 uint32_t uVersion;
527 /** Reserved field, MBZ. */
528 uint32_t fReserved;
529 /** The object setter operations. */
530 RTVFSOBJSETOPS ObjSet;
531
532 /**
533 * Generic method for opening any kind of file system object.
534 *
535 * Can also create files and directories. Symbolic links, devices and such
536 * needs to be created using special methods or this would end up being way more
537 * complicated than it already is.
538 *
539 * There are optional specializations available.
540 *
541 * @returns IPRT status code.
542 * @retval VERR_PATH_NOT_FOUND or VERR_FILE_NOT_FOUND if @a pszEntry was not
543 * found.
544 * @retval VERR_IS_A_FILE if @a pszEntry is a file or similar but @a fFlags
545 * indicates that the type of object should not be opened.
546 * @retval VERR_IS_A_DIRECTORY if @a pszEntry is a directory but @a fFlags
547 * indicates that directories should not be opened.
548 * @retval VERR_IS_A_SYMLINK if @a pszEntry is a symbolic link but @a fFlags
549 * indicates that symbolic links should not be opened (or followed).
550 * @retval VERR_IS_A_FIFO if @a pszEntry is a FIFO but @a fFlags indicates that
551 * FIFOs should not be opened.
552 * @retval VERR_IS_A_SOCKET if @a pszEntry is a socket but @a fFlags indicates
553 * that sockets should not be opened.
554 * @retval VERR_IS_A_BLOCK_DEVICE if @a pszEntry is a block device but
555 * @a fFlags indicates that block devices should not be opened.
556 * @retval VERR_IS_A_BLOCK_DEVICE if @a pszEntry is a character device but
557 * @a fFlags indicates that character devices should not be opened.
558 *
559 * @param pvThis The implementation specific directory data.
560 * @param pszEntry The name of the immediate file to open or create.
561 * @param fOpenFile RTFILE_O_XXX combination.
562 * @param fObjFlags More flags: RTVFSOBJ_F_XXX, RTPATH_F_XXX.
563 * The meaning of RTPATH_F_FOLLOW_LINK differs here, if
564 * @a pszEntry is a symlink it should be opened for
565 * traversal rather than according to @a fOpenFile.
566 * @param phVfsObj Where to return the handle to the opened object.
567 * @sa RTFileOpen, RTDirOpen
568 */
569 DECLCALLBACKMEMBER(int, pfnOpen)(void *pvThis, const char *pszEntry, uint64_t fOpenFile,
570 uint32_t fObjFlags, PRTVFSOBJ phVfsObj);
571
572 /**
573 * Optional method for symbolic link handling in the vfsstddir.cpp.
574 *
575 * This is really just a hack to make symbolic link handling work when working
576 * with directory objects that doesn't have an associated VFS. It also helps
577 * deal with drive letters in symbolic links on Windows and OS/2.
578 *
579 * @returns IPRT status code.
580 * @retval VERR_PATH_IS_RELATIVE if @a pszPath isn't absolute and should be
581 * handled using pfnOpen().
582 *
583 * @param pvThis The implementation specific directory data.
584 * @param pszRoot Path to the alleged root.
585 * @param phVfsDir Where to return the handle to the specified root
586 * directory (or may current dir on a drive letter).
587 */
588 DECLCALLBACKMEMBER(int, pfnFollowAbsoluteSymlink)(void *pvThis, const char *pszRoot, PRTVFSDIR phVfsDir);
589
590 /**
591 * Open or create a file.
592 *
593 * @returns IPRT status code.
594 * @param pvThis The implementation specific directory data.
595 * @param pszFilename The name of the immediate file to open or create.
596 * @param fOpen The open flags (RTFILE_O_XXX).
597 * @param phVfsFile Where to return the handle to the opened file.
598 * @note Optional. RTVFSDIROPS::pfnOpenObj will be used if NULL.
599 * @sa RTFileOpen.
600 */
601 DECLCALLBACKMEMBER(int, pfnOpenFile)(void *pvThis, const char *pszFilename, uint64_t fOpen, PRTVFSFILE phVfsFile);
602
603 /**
604 * Open an existing subdirectory.
605 *
606 * @returns IPRT status code.
607 * @retval VERR_IS_A_SYMLINK if @a pszSubDir is a symbolic link.
608 * @retval VERR_NOT_A_DIRECTORY is okay for symbolic links too.
609 *
610 * @param pvThis The implementation specific directory data.
611 * @param pszSubDir The name of the immediate subdirectory to open.
612 * @param fFlags RTDIR_F_XXX.
613 * @param phVfsDir Where to return the handle to the opened directory.
614 * Optional.
615 * @note Optional. RTVFSDIROPS::pfnOpenObj will be used if NULL.
616 * @sa RTDirOpen.
617 */
618 DECLCALLBACKMEMBER(int, pfnOpenDir)(void *pvThis, const char *pszSubDir, uint32_t fFlags, PRTVFSDIR phVfsDir);
619
620 /**
621 * Creates a new subdirectory.
622 *
623 * @returns IPRT status code.
624 * @param pvThis The implementation specific directory data.
625 * @param pszSubDir The name of the immediate subdirectory to create.
626 * @param fMode The mode mask of the new directory.
627 * @param phVfsDir Where to optionally return the handle to the newly
628 * create directory.
629 * @note Optional. RTVFSDIROPS::pfnOpenObj will be used if NULL.
630 * @sa RTDirCreate.
631 */
632 DECLCALLBACKMEMBER(int, pfnCreateDir)(void *pvThis, const char *pszSubDir, RTFMODE fMode, PRTVFSDIR phVfsDir);
633
634 /**
635 * Opens an existing symbolic link.
636 *
637 * @returns IPRT status code.
638 * @param pvThis The implementation specific directory data.
639 * @param pszSymlink The name of the immediate symbolic link to open.
640 * @param phVfsSymlink Where to optionally return the handle to the
641 * newly create symbolic link.
642 * @note Optional. RTVFSDIROPS::pfnOpenObj will be used if NULL.
643 * @sa RTSymlinkCreate.
644 */
645 DECLCALLBACKMEMBER(int, pfnOpenSymlink)(void *pvThis, const char *pszSymlink, PRTVFSSYMLINK phVfsSymlink);
646
647 /**
648 * Creates a new symbolic link.
649 *
650 * @returns IPRT status code.
651 * @param pvThis The implementation specific directory data.
652 * @param pszSymlink The name of the immediate symbolic link to create.
653 * @param pszTarget The symbolic link target.
654 * @param enmType The symbolic link type.
655 * @param phVfsSymlink Where to optionally return the handle to the
656 * newly create symbolic link.
657 * @sa RTSymlinkCreate.
658 */
659 DECLCALLBACKMEMBER(int, pfnCreateSymlink)(void *pvThis, const char *pszSymlink, const char *pszTarget,
660 RTSYMLINKTYPE enmType, PRTVFSSYMLINK phVfsSymlink);
661
662 /**
663 * Query information about an entry.
664 *
665 * @returns IPRT status code.
666 * @param pvThis The implementation specific directory data.
667 * @param pszEntry The name of the directory entry to remove.
668 * @param pObjInfo Where to return the info on success.
669 * @param enmAddAttr Which set of additional attributes to request.
670 * @note Optional. RTVFSDIROPS::pfnOpenObj and RTVFSOBJOPS::pfnQueryInfo
671 * will be used if NULL.
672 * @sa RTPathQueryInfo, RTVFSOBJOPS::pfnQueryInfo
673 */
674 DECLCALLBACKMEMBER(int, pfnQueryEntryInfo)(void *pvThis, const char *pszEntry,
675 PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr);
676
677 /**
678 * Removes a directory entry.
679 *
680 * @returns IPRT status code.
681 * @param pvThis The implementation specific directory data.
682 * @param pszEntry The name of the directory entry to remove.
683 * @param fType If non-zero, this restricts the type of the entry to
684 * the object type indicated by the mask
685 * (RTFS_TYPE_XXX).
686 * @sa RTFileRemove, RTDirRemove, RTSymlinkRemove.
687 */
688 DECLCALLBACKMEMBER(int, pfnUnlinkEntry)(void *pvThis, const char *pszEntry, RTFMODE fType);
689
690 /**
691 * Renames a directory entry.
692 *
693 * @returns IPRT status code.
694 * @param pvThis The implementation specific directory data.
695 * @param pszEntry The name of the directory entry to rename.
696 * @param fType If non-zero, this restricts the type of the entry to
697 * the object type indicated by the mask
698 * (RTFS_TYPE_XXX).
699 * @param pszNewName The new entry name.
700 * @sa RTPathRename
701 *
702 * @todo This API is not flexible enough, must be able to rename between
703 * directories within a file system.
704 */
705 DECLCALLBACKMEMBER(int, pfnRenameEntry)(void *pvThis, const char *pszEntry, RTFMODE fType, const char *pszNewName);
706
707 /**
708 * Rewind the directory stream so that the next read returns the first
709 * entry.
710 *
711 * @returns IPRT status code.
712 * @param pvThis The implementation specific directory data.
713 */
714 DECLCALLBACKMEMBER(int, pfnRewindDir)(void *pvThis);
715
716 /**
717 * Rewind the directory stream so that the next read returns the first
718 * entry.
719 *
720 * @returns IPRT status code.
721 * @param pvThis The implementation specific directory data.
722 * @param pDirEntry Output buffer.
723 * @param pcbDirEntry Complicated, see RTDirReadEx.
724 * @param enmAddAttr Which set of additional attributes to request.
725 * @sa RTDirReadEx
726 */
727 DECLCALLBACKMEMBER(int, pfnReadDir)(void *pvThis, PRTDIRENTRYEX pDirEntry, size_t *pcbDirEntry, RTFSOBJATTRADD enmAddAttr);
728
729 /** Marks the end of the structure (RTVFSDIROPS_VERSION). */
730 uintptr_t uEndMarker;
731} RTVFSDIROPS;
732/** Pointer to const directory operations. */
733typedef RTVFSDIROPS const *PCRTVFSDIROPS;
734/** The RTVFSDIROPS structure version. */
735#define RTVFSDIROPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x4f,1,0)
736
737
738/**
739 * Creates a new VFS directory handle.
740 *
741 * @returns IPRT status code
742 * @param pDirOps The directory operations.
743 * @param cbInstance The size of the instance data.
744 * @param fFlags RTVFSDIR_F_XXX
745 * @param hVfs The VFS handle to associate this directory with.
746 * NIL_VFS is ok.
747 * @param hLock Handle to a custom lock to be used with the new
748 * object. The reference is consumed. NIL and
749 * special lock handles are fine.
750 * @param phVfsDir Where to return the new handle.
751 * @param ppvInstance Where to return the pointer to the instance data
752 * (size is @a cbInstance).
753 */
754RTDECL(int) RTVfsNewDir(PCRTVFSDIROPS pDirOps, size_t cbInstance, uint32_t fFlags, RTVFS hVfs, RTVFSLOCK hLock,
755 PRTVFSDIR phVfsDir, void **ppvInstance);
756
757/** @name RTVFSDIR_F_XXX
758 * @{ */
759/** Don't reference the @a hVfs parameter passed to RTVfsNewDir.
760 * This is a permanent root directory hack. */
761#define RTVFSDIR_F_NO_VFS_REF RT_BIT_32(0)
762/** @} */
763
764
765/**
766 * The symbolic link operations.
767 *
768 * @extends RTVFSOBJOPS
769 * @extends RTVFSOBJSETOPS
770 */
771typedef struct RTVFSSYMLINKOPS
772{
773 /** The basic object operation. */
774 RTVFSOBJOPS Obj;
775 /** The structure version (RTVFSSYMLINKOPS_VERSION). */
776 uint32_t uVersion;
777 /** Reserved field, MBZ. */
778 uint32_t fReserved;
779 /** The object setter operations. */
780 RTVFSOBJSETOPS ObjSet;
781
782 /**
783 * Read the symbolic link target.
784 *
785 * @returns IPRT status code.
786 * @param pvThis The implementation specific symbolic link data.
787 * @param pszTarget The target buffer.
788 * @param cbTarget The size of the target buffer.
789 * @sa RTSymlinkRead
790 */
791 DECLCALLBACKMEMBER(int, pfnRead)(void *pvThis, char *pszTarget, size_t cbTarget);
792
793 /** Marks the end of the structure (RTVFSSYMLINKOPS_VERSION). */
794 uintptr_t uEndMarker;
795} RTVFSSYMLINKOPS;
796/** Pointer to const symbolic link operations. */
797typedef RTVFSSYMLINKOPS const *PCRTVFSSYMLINKOPS;
798/** The RTVFSSYMLINKOPS structure version. */
799#define RTVFSSYMLINKOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x5f,1,0)
800
801
802/**
803 * Creates a new VFS symlink handle.
804 *
805 * @returns IPRT status code
806 * @param pSymlinkOps The symlink operations.
807 * @param cbInstance The size of the instance data.
808 * @param hVfs The VFS handle to associate this symlink object
809 * with. NIL_VFS is ok.
810 * @param hLock Handle to a custom lock to be used with the new
811 * object. The reference is consumed. NIL and
812 * special lock handles are fine.
813 * @param phVfsSym Where to return the new handle.
814 * @param ppvInstance Where to return the pointer to the instance data
815 * (size is @a cbInstance).
816 */
817RTDECL(int) RTVfsNewSymlink(PCRTVFSSYMLINKOPS pSymlinkOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock,
818 PRTVFSSYMLINK phVfsSym, void **ppvInstance);
819
820
821/**
822 * The basis for all I/O objects (files, pipes, sockets, devices, ++).
823 *
824 * @extends RTVFSOBJOPS
825 */
826typedef struct RTVFSIOSTREAMOPS
827{
828 /** The basic object operation. */
829 RTVFSOBJOPS Obj;
830 /** The structure version (RTVFSIOSTREAMOPS_VERSION). */
831 uint32_t uVersion;
832 /** Feature field. */
833 uint32_t fFeatures;
834
835 /**
836 * Reads from the file/stream.
837 *
838 * @returns IPRT status code. See RTVfsIoStrmRead.
839 * @param pvThis The implementation specific file data.
840 * @param off Where to read at, -1 for the current position.
841 * @param pSgBuf Gather buffer describing the bytes that are to be
842 * written.
843 * @param fBlocking If @c true, the call is blocking, if @c false it
844 * should not block.
845 * @param pcbRead Where return the number of bytes actually read.
846 * This is set it 0 by the caller. If NULL, try read
847 * all and fail if incomplete.
848 * @sa RTVfsIoStrmRead, RTVfsIoStrmSgRead, RTVfsFileRead,
849 * RTVfsFileReadAt, RTFileRead, RTFileReadAt.
850 */
851 DECLCALLBACKMEMBER(int, pfnRead)(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead);
852
853 /**
854 * Writes to the file/stream.
855 *
856 * @returns IPRT status code.
857 * @param pvThis The implementation specific file data.
858 * @param off Where to start wrinting, -1 for the current
859 * position.
860 * @param pSgBuf Gather buffers describing the bytes that are to be
861 * written.
862 * @param fBlocking If @c true, the call is blocking, if @c false it
863 * should not block.
864 * @param pcbWritten Where to return the number of bytes actually
865 * written. This is set it 0 by the caller. If
866 * NULL, try write it all and fail if incomplete.
867 * @note Optional, failing with VERR_WRITE_PROTECT if NULL.
868 * @sa RTFileWrite, RTFileWriteAt.
869 */
870 DECLCALLBACKMEMBER(int, pfnWrite)(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten);
871
872 /**
873 * Flushes any pending data writes to the stream.
874 *
875 * @returns IPRT status code.
876 * @param pvThis The implementation specific file data.
877 * @sa RTFileFlush.
878 */
879 DECLCALLBACKMEMBER(int, pfnFlush)(void *pvThis);
880
881 /**
882 * Poll for events.
883 *
884 * @returns IPRT status code.
885 * @param pvThis The implementation specific file data.
886 * @param fEvents The events to poll for (RTPOLL_EVT_XXX).
887 * @param cMillies How long to wait for event to eventuate.
888 * @param fIntr Whether the wait is interruptible and can return
889 * VERR_INTERRUPTED (@c true) or if this condition
890 * should be hidden from the caller (@c false).
891 * @param pfRetEvents Where to return the event mask.
892 * @note Optional. If NULL, immediately return all requested non-error
893 * events, waiting for errors works like sleep.
894 * @sa RTPollSetAdd, RTPoll, RTPollNoResume.
895 */
896 DECLCALLBACKMEMBER(int, pfnPollOne)(void *pvThis, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr,
897 uint32_t *pfRetEvents);
898
899 /**
900 * Tells the current file/stream position.
901 *
902 * @returns IPRT status code.
903 * @param pvThis The implementation specific file data.
904 * @param poffActual Where to return the actual offset.
905 * @sa RTFileTell
906 */
907 DECLCALLBACKMEMBER(int, pfnTell)(void *pvThis, PRTFOFF poffActual);
908
909 /**
910 * Skips @a cb ahead in the stream.
911 *
912 * @returns IPRT status code.
913 * @param pvThis The implementation specific file data.
914 * @param cb The number bytes to skip.
915 * @remarks This is optional and can be NULL.
916 */
917 DECLCALLBACKMEMBER(int, pfnSkip)(void *pvThis, RTFOFF cb);
918
919 /**
920 * Fills the stream with @a cb zeros.
921 *
922 * @returns IPRT status code.
923 * @param pvThis The implementation specific file data.
924 * @param cb The number of zero bytes to insert.
925 * @remarks This is optional and can be NULL.
926 */
927 DECLCALLBACKMEMBER(int, pfnZeroFill)(void *pvThis, RTFOFF cb);
928
929 /** Marks the end of the structure (RTVFSIOSTREAMOPS_VERSION). */
930 uintptr_t uEndMarker;
931} RTVFSIOSTREAMOPS;
932/** Pointer to const I/O stream operations. */
933typedef RTVFSIOSTREAMOPS const *PCRTVFSIOSTREAMOPS;
934
935/** The RTVFSIOSTREAMOPS structure version. */
936#define RTVFSIOSTREAMOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x6f,1,0)
937
938/** @name RTVFSIOSTREAMOPS::fFeatures
939 * @{ */
940/** No scatter gather lists, thank you. */
941#define RTVFSIOSTREAMOPS_FEAT_NO_SG RT_BIT_32(0)
942/** Mask of the valid I/O stream feature flags. */
943#define RTVFSIOSTREAMOPS_FEAT_VALID_MASK UINT32_C(0x00000001)
944/** @} */
945
946
947/**
948 * Creates a new VFS I/O stream handle.
949 *
950 * @returns IPRT status code
951 * @param pIoStreamOps The I/O stream operations.
952 * @param cbInstance The size of the instance data.
953 * @param fOpen The open flags. The minimum is the access mask.
954 * @param hVfs The VFS handle to associate this I/O stream
955 * with. NIL_VFS is ok.
956 * @param hLock Handle to a custom lock to be used with the new
957 * object. The reference is consumed. NIL and
958 * special lock handles are fine.
959 * @param phVfsIos Where to return the new handle.
960 * @param ppvInstance Where to return the pointer to the instance data
961 * (size is @a cbInstance).
962 */
963RTDECL(int) RTVfsNewIoStream(PCRTVFSIOSTREAMOPS pIoStreamOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs, RTVFSLOCK hLock,
964 PRTVFSIOSTREAM phVfsIos, void **ppvInstance);
965
966
967/**
968 * Gets the private data of an I/O stream.
969 *
970 * @returns Pointer to the private data. NULL if the handle is invalid in some
971 * way.
972 * @param hVfsIos The I/O stream handle.
973 * @param pIoStreamOps The I/O stream operations. This servers as a
974 * sort of password.
975 */
976RTDECL(void *) RTVfsIoStreamToPrivate(RTVFSIOSTREAM hVfsIos, PCRTVFSIOSTREAMOPS pIoStreamOps);
977
978
979/**
980 * The file operations.
981 *
982 * @extends RTVFSIOSTREAMOPS
983 * @extends RTVFSOBJSETOPS
984 */
985typedef struct RTVFSFILEOPS
986{
987 /** The I/O stream and basis object operations. */
988 RTVFSIOSTREAMOPS Stream;
989 /** The structure version (RTVFSFILEOPS_VERSION). */
990 uint32_t uVersion;
991 /** Reserved field, MBZ. */
992 uint32_t fReserved;
993 /** The object setter operations. */
994 RTVFSOBJSETOPS ObjSet;
995
996 /**
997 * Changes the current file position.
998 *
999 * @returns IPRT status code.
1000 * @param pvThis The implementation specific file data.
1001 * @param offSeek The offset to seek.
1002 * @param uMethod The seek method, i.e. what the seek is relative to.
1003 * @param poffActual Where to return the actual offset.
1004 * @sa RTFileSeek
1005 */
1006 DECLCALLBACKMEMBER(int, pfnSeek)(void *pvThis, RTFOFF offSeek, unsigned uMethod, PRTFOFF poffActual);
1007
1008 /**
1009 * Get the current file size.
1010 *
1011 * @returns IPRT status code.
1012 * @param pvThis The implementation specific file data.
1013 * @param pcbFile Where to store the current file size.
1014 * @sa RTFileGetSize
1015 */
1016 DECLCALLBACKMEMBER(int, pfnQuerySize)(void *pvThis, uint64_t *pcbFile);
1017
1018 /**
1019 * Change the file size.
1020 *
1021 * @returns IPRT status code.
1022 * @retval VERR_ACCESS_DENIED if handle isn't writable.
1023 * @retval VERR_WRITE_PROTECT if read-only file system.
1024 * @retval VERR_FILE_TOO_BIG if cbSize is larger than what the file system can
1025 * theoretically deal with.
1026 * @retval VERR_DISK_FULL if the file system if full.
1027 * @retval VERR_NOT_SUPPORTED if fFlags indicates some operation that's not
1028 * supported by the file system / host operating system.
1029 *
1030 * @param pvThis The implementation specific file data.
1031 * @param pcbFile Where to store the current file size.
1032 * @param fFlags RTVFSFILE_SET_SIZE_F_XXX.
1033 * @note Optional. If NULL, VERR_WRITE_PROTECT will be returned.
1034 * @sa RTFileSetSize, RTFileSetAllocationSize
1035 */
1036 DECLCALLBACKMEMBER(int, pfnSetSize)(void *pvThis, uint64_t cbFile, uint32_t fFlags);
1037
1038 /**
1039 * Determine the maximum file size.
1040 *
1041 * This won't take amount of freespace into account, just the limitations of the
1042 * underlying file system / host operating system.
1043 *
1044 * @returns IPRT status code.
1045 * @param pvThis The implementation specific file data.
1046 * @param pcbMax Where to return the max file size.
1047 * @note Optional. If NULL, VERR_NOT_IMPLEMENTED will be returned.
1048 * @sa RTFileGetMaxSizeEx
1049 */
1050 DECLCALLBACKMEMBER(int, pfnQueryMaxSize)(void *pvThis, uint64_t *pcbMax);
1051
1052 /** @todo There will be more methods here. */
1053
1054 /** Marks the end of the structure (RTVFSFILEOPS_VERSION). */
1055 uintptr_t uEndMarker;
1056} RTVFSFILEOPS;
1057/** Pointer to const file operations. */
1058typedef RTVFSFILEOPS const *PCRTVFSFILEOPS;
1059
1060/** The RTVFSFILEOPS structure version. */
1061#define RTVFSFILEOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x7f,2,0)
1062
1063/**
1064 * Creates a new VFS file handle.
1065 *
1066 * @returns IPRT status code
1067 * @param pFileOps The file operations.
1068 * @param cbInstance The size of the instance data.
1069 * @param fOpen The open flags. The minimum is the access mask.
1070 * @param hVfs The VFS handle to associate this file with.
1071 * NIL_VFS is ok.
1072 * @param hLock Handle to a custom lock to be used with the new
1073 * object. The reference is consumed. NIL and
1074 * special lock handles are fine.
1075 * @param phVfsFile Where to return the new handle.
1076 * @param ppvInstance Where to return the pointer to the instance data
1077 * (size is @a cbInstance).
1078 */
1079RTDECL(int) RTVfsNewFile(PCRTVFSFILEOPS pFileOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs, RTVFSLOCK hLock,
1080 PRTVFSFILE phVfsFile, void **ppvInstance);
1081
1082
1083/** @defgroup grp_rt_vfs_ll_util VFS Utility APIs
1084 * @{ */
1085
1086/**
1087 * Parsed path.
1088 */
1089typedef struct RTVFSPARSEDPATH
1090{
1091 /** The length of the path in szCopy. */
1092 uint16_t cch;
1093 /** The number of path components. */
1094 uint16_t cComponents;
1095 /** Set if the path ends with slash, indicating that it's a directory
1096 * reference and not a file reference. The slash has been removed from
1097 * the copy. */
1098 bool fDirSlash;
1099 /** Set if absolute. */
1100 bool fAbsolute;
1101 /** The offset where each path component starts, i.e. the char after the
1102 * slash. The array has cComponents + 1 entries, where the final one is
1103 * cch + 1 so that one can always terminate the current component by
1104 * szPath[aoffComponent[i] - 1] = '\0'. */
1105 uint16_t aoffComponents[RTPATH_MAX / 2 + 1];
1106 /** A normalized copy of the path.
1107 * Reserve some extra space so we can be more relaxed about overflow
1108 * checks and terminator paddings, especially when recursing. */
1109 char szPath[RTPATH_MAX];
1110} RTVFSPARSEDPATH;
1111/** Pointer to a parsed path. */
1112typedef RTVFSPARSEDPATH *PRTVFSPARSEDPATH;
1113
1114/** The max accepted path length.
1115 * This must be a few chars shorter than RTVFSPARSEDPATH::szPath because we
1116 * use two terminators and wish be a little bit lazy with checking. */
1117#define RTVFSPARSEDPATH_MAX (RTPATH_MAX - 4)
1118
1119/**
1120 * Appends @a pszPath (relative) to the already parsed path @a pPath.
1121 *
1122 * @retval VINF_SUCCESS
1123 * @retval VERR_FILENAME_TOO_LONG
1124 * @retval VERR_INTERNAL_ERROR_4
1125 * @param pPath The parsed path to append @a pszPath onto.
1126 * This is both input and output.
1127 * @param pszPath The path to append. This must be relative.
1128 * @param piRestartComp The component to restart parsing at. This is
1129 * input/output. The input does not have to be
1130 * within the valid range. Optional.
1131 */
1132RTDECL(int) RTVfsParsePathAppend(PRTVFSPARSEDPATH pPath, const char *pszPath, uint16_t *piRestartComp);
1133
1134/**
1135 * Parses a path.
1136 *
1137 * @retval VINF_SUCCESS
1138 * @retval VERR_FILENAME_TOO_LONG
1139 * @param pPath Where to store the parsed path.
1140 * @param pszPath The path to parse. Absolute or relative to @a
1141 * pszCwd.
1142 * @param pszCwd The current working directory. Must be
1143 * absolute.
1144 */
1145RTDECL(int) RTVfsParsePath(PRTVFSPARSEDPATH pPath, const char *pszPath, const char *pszCwd);
1146
1147/**
1148 * Same as RTVfsParsePath except that it allocates a temporary buffer.
1149 *
1150 * @retval VINF_SUCCESS
1151 * @retval VERR_NO_TMP_MEMORY
1152 * @retval VERR_FILENAME_TOO_LONG
1153 * @param pszPath The path to parse. Absolute or relative to @a
1154 * pszCwd.
1155 * @param pszCwd The current working directory. Must be
1156 * absolute.
1157 * @param ppPath Where to store the pointer to the allocated
1158 * buffer containing the parsed path. This must
1159 * be freed by calling RTVfsParsePathFree. NULL
1160 * will be stored on failured.
1161 */
1162RTDECL(int) RTVfsParsePathA(const char *pszPath, const char *pszCwd, PRTVFSPARSEDPATH *ppPath);
1163
1164/**
1165 * Frees a buffer returned by RTVfsParsePathA.
1166 *
1167 * @param pPath The parsed path buffer to free. NULL is fine.
1168 */
1169RTDECL(void) RTVfsParsePathFree(PRTVFSPARSEDPATH pPath);
1170
1171/**
1172 * Dummy implementation of RTVFSIOSTREAMOPS::pfnPollOne.
1173 *
1174 * This handles the case where there is no chance any events my be raised and
1175 * all that is required is to wait according to the parameters.
1176 *
1177 * @returns IPRT status code.
1178 * @param fEvents The events to poll for (RTPOLL_EVT_XXX).
1179 * @param cMillies How long to wait for event to eventuate.
1180 * @param fIntr Whether the wait is interruptible and can return
1181 * VERR_INTERRUPTED (@c true) or if this condition
1182 * should be hidden from the caller (@c false).
1183 * @param pfRetEvents Where to return the event mask.
1184 * @sa RTVFSIOSTREAMOPS::pfnPollOne, RTPollSetAdd, RTPoll, RTPollNoResume.
1185 */
1186RTDECL(int) RTVfsUtilDummyPollOne(uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr, uint32_t *pfRetEvents);
1187
1188/** @} */
1189
1190
1191/** @defgroup grp_rt_vfs_lowlevel_chain VFS Chains (Low Level)
1192 * @ref grp_rt_vfs_chain
1193 * @{
1194 */
1195
1196/** Pointer to a VFS chain element registration record. */
1197typedef struct RTVFSCHAINELEMENTREG *PRTVFSCHAINELEMENTREG;
1198/** Pointer to a const VFS chain element registration record. */
1199typedef struct RTVFSCHAINELEMENTREG const *PCRTVFSCHAINELEMENTREG;
1200
1201/**
1202 * VFS chain element argument.
1203 */
1204typedef struct RTVFSCHAINELEMENTARG
1205{
1206 /** The string argument value. */
1207 char *psz;
1208 /** The specification offset of this argument. */
1209 uint16_t offSpec;
1210 /** Provider specific value. */
1211 uint64_t uProvider;
1212} RTVFSCHAINELEMENTARG;
1213/** Pointer to a VFS chain element argument. */
1214typedef RTVFSCHAINELEMENTARG *PRTVFSCHAINELEMENTARG;
1215
1216
1217/**
1218 * VFS chain element specification.
1219 */
1220typedef struct RTVFSCHAINELEMSPEC
1221{
1222 /** The provider name.
1223 * This can be NULL if this is the final component and it's just a path. */
1224 char *pszProvider;
1225 /** The input type, RTVFSOBJTYPE_INVALID if first. */
1226 RTVFSOBJTYPE enmTypeIn;
1227 /** The element type.
1228 * RTVFSOBJTYPE_END if this is the final component and it's just a path. */
1229 RTVFSOBJTYPE enmType;
1230 /** The input spec offset of this element. */
1231 uint16_t offSpec;
1232 /** The length of the input spec. */
1233 uint16_t cchSpec;
1234 /** The number of arguments. */
1235 uint32_t cArgs;
1236 /** Arguments. */
1237 PRTVFSCHAINELEMENTARG paArgs;
1238
1239 /** The provider. */
1240 PCRTVFSCHAINELEMENTREG pProvider;
1241 /** Provider specific value. */
1242 uint64_t uProvider;
1243 /** The object (with reference). */
1244 RTVFSOBJ hVfsObj;
1245} RTVFSCHAINELEMSPEC;
1246/** Pointer to a chain element specification. */
1247typedef RTVFSCHAINELEMSPEC *PRTVFSCHAINELEMSPEC;
1248/** Pointer to a const chain element specification. */
1249typedef RTVFSCHAINELEMSPEC const *PCRTVFSCHAINELEMSPEC;
1250
1251
1252/**
1253 * Parsed VFS chain specification.
1254 */
1255typedef struct RTVFSCHAINSPEC
1256{
1257 /** Open directory flags (RTFILE_O_XXX). */
1258 uint64_t fOpenFile;
1259 /** To be defined. */
1260 uint32_t fOpenDir;
1261 /** The type desired by the caller. */
1262 RTVFSOBJTYPE enmDesiredType;
1263 /** The number of elements. */
1264 uint32_t cElements;
1265 /** The elements. */
1266 PRTVFSCHAINELEMSPEC paElements;
1267} RTVFSCHAINSPEC;
1268/** Pointer to a parsed VFS chain specification. */
1269typedef RTVFSCHAINSPEC *PRTVFSCHAINSPEC;
1270/** Pointer to a const, parsed VFS chain specification. */
1271typedef RTVFSCHAINSPEC const *PCRTVFSCHAINSPEC;
1272
1273
1274/**
1275 * A chain element provider registration record.
1276 */
1277typedef struct RTVFSCHAINELEMENTREG
1278{
1279 /** The version (RTVFSCHAINELEMENTREG_VERSION). */
1280 uint32_t uVersion;
1281 /** Reserved, MBZ. */
1282 uint32_t fReserved;
1283 /** The provider name (unique). */
1284 const char *pszName;
1285 /** For chaining the providers. */
1286 RTLISTNODE ListEntry;
1287 /** Help text. */
1288 const char *pszHelp;
1289
1290 /**
1291 * Checks the element specification.
1292 *
1293 * This is allowed to parse arguments and use pSpec->uProvider and
1294 * pElement->paArgs[].uProvider to store information that pfnInstantiate and
1295 * pfnCanReuseElement may use later on, thus avoiding duplicating work/code.
1296 *
1297 * @returns IPRT status code.
1298 * @param pProviderReg Pointer to the element provider registration.
1299 * @param pSpec The chain specification.
1300 * @param pElement The chain element specification to validate.
1301 * @param poffError Where to return error offset on failure. This is
1302 * set to the pElement->offSpec on input, so it only
1303 * needs to be adjusted if an argument is at fault.
1304 * @param pErrInfo Where to return additional error information, if
1305 * available. Optional.
1306 */
1307 DECLCALLBACKMEMBER(int, pfnValidate)(PCRTVFSCHAINELEMENTREG pProviderReg, PRTVFSCHAINSPEC pSpec,
1308 PRTVFSCHAINELEMSPEC pElement, uint32_t *poffError, PRTERRINFO pErrInfo);
1309
1310 /**
1311 * Create a VFS object according to the element specification.
1312 *
1313 * @returns IPRT status code.
1314 * @param pProviderReg Pointer to the element provider registration.
1315 * @param pSpec The chain specification.
1316 * @param pElement The chain element specification to instantiate.
1317 * @param hPrevVfsObj Handle to the previous VFS object, NIL_RTVFSOBJ if
1318 * first.
1319 * @param phVfsObj Where to return the VFS object handle.
1320 * @param poffError Where to return error offset on failure. This is
1321 * set to the pElement->offSpec on input, so it only
1322 * needs to be adjusted if an argument is at fault.
1323 * @param pErrInfo Where to return additional error information, if
1324 * available. Optional.
1325 */
1326 DECLCALLBACKMEMBER(int, pfnInstantiate)(PCRTVFSCHAINELEMENTREG pProviderReg, PCRTVFSCHAINSPEC pSpec,
1327 PCRTVFSCHAINELEMSPEC pElement, RTVFSOBJ hPrevVfsObj,
1328 PRTVFSOBJ phVfsObj, uint32_t *poffError, PRTERRINFO pErrInfo);
1329
1330 /**
1331 * Determins whether the element can be reused.
1332 *
1333 * This is for handling situations accessing the same file system twice, like
1334 * for both the source and destiation of a copy operation. This allows not only
1335 * sharing resources and avoid doing things twice, but also helps avoid file
1336 * sharing violations and inconsistencies araising from the image being updated
1337 * and read independently.
1338 *
1339 * @returns true if the element from @a pReuseSpec an be reused, false if not.
1340 * @param pProviderReg Pointer to the element provider registration.
1341 * @param pSpec The chain specification.
1342 * @param pElement The chain element specification.
1343 * @param pReuseSpec The chain specification of the existing chain.
1344 * @param pReuseElement The chain element specification of the existing
1345 * element that is being considered for reuse.
1346 */
1347 DECLCALLBACKMEMBER(bool, pfnCanReuseElement)(PCRTVFSCHAINELEMENTREG pProviderReg,
1348 PCRTVFSCHAINSPEC pSpec, PCRTVFSCHAINELEMSPEC pElement,
1349 PCRTVFSCHAINSPEC pReuseSpec, PCRTVFSCHAINELEMSPEC pReuseElement);
1350
1351 /** End marker (RTVFSCHAINELEMENTREG_VERSION). */
1352 uintptr_t uEndMarker;
1353} RTVFSCHAINELEMENTREG;
1354
1355/** The VFS chain element registration record version number. */
1356#define RTVFSCHAINELEMENTREG_VERSION RT_MAKE_U32_FROM_U8(0xff, 0x7f, 1, 0)
1357
1358
1359/**
1360 * Parses the specification.
1361 *
1362 * @returns IPRT status code.
1363 * @param pszSpec The specification string to parse.
1364 * @param fFlags Flags, see RTVFSCHAIN_PF_XXX.
1365 * @param enmDesiredType The object type the caller wants to interface with.
1366 * @param ppSpec Where to return the pointer to the parsed
1367 * specification. This must be freed by calling
1368 * RTVfsChainSpecFree. Will always be set (unless
1369 * invalid parameters.)
1370 * @param poffError Where to return the offset into the input
1371 * specification of what's causing trouble. Always
1372 * set, unless this argument causes an invalid pointer
1373 * error.
1374 */
1375RTDECL(int) RTVfsChainSpecParse(const char *pszSpec, uint32_t fFlags, RTVFSOBJTYPE enmDesiredType,
1376 PRTVFSCHAINSPEC *ppSpec, uint32_t *poffError);
1377
1378/** @name RTVfsChainSpecParse
1379 * @{ */
1380/** Mask of valid flags. */
1381#define RTVFSCHAIN_PF_VALID_MASK UINT32_C(0x00000000)
1382/** @} */
1383
1384/**
1385 * Checks and setups the chain.
1386 *
1387 * @returns IPRT status code.
1388 * @param pSpec The parsed specification.
1389 * @param pReuseSpec Spec to reuse if applicable. Optional.
1390 * @param phVfsObj Where to return the VFS object.
1391 * @param ppszFinalPath Where to return the pointer to the final path if
1392 * applicable. The caller needs to check whether this
1393 * is NULL or a path, in the former case nothing more
1394 * needs doing, whereas in the latter the caller must
1395 * perform the desired operation(s) on *phVfsObj using
1396 * the final path.
1397 * @param poffError Where to return the offset into the input
1398 * specification of what's causing trouble. Always
1399 * set, unless this argument causes an invalid pointer
1400 * error.
1401 * @param pErrInfo Where to return additional error information, if
1402 * available. Optional.
1403 */
1404RTDECL(int) RTVfsChainSpecCheckAndSetup(PRTVFSCHAINSPEC pSpec, PCRTVFSCHAINSPEC pReuseSpec,
1405 PRTVFSOBJ phVfsObj, const char **ppszFinalPath, uint32_t *poffError, PRTERRINFO pErrInfo);
1406
1407/**
1408 * Frees a parsed chain specification.
1409 *
1410 * @param pSpec What RTVfsChainSpecParse returned. NULL is
1411 * quietly ignored.
1412 */
1413RTDECL(void) RTVfsChainSpecFree(PRTVFSCHAINSPEC pSpec);
1414
1415/**
1416 * Registers a chain element provider.
1417 *
1418 * @returns IPRT status code
1419 * @param pRegRec The registration record.
1420 * @param fFromCtor Indicates where we're called from.
1421 */
1422RTDECL(int) RTVfsChainElementRegisterProvider(PRTVFSCHAINELEMENTREG pRegRec, bool fFromCtor);
1423
1424/**
1425 * Deregisters a chain element provider.
1426 *
1427 * @returns IPRT status code
1428 * @param pRegRec The registration record.
1429 * @param fFromDtor Indicates where we're called from.
1430 */
1431RTDECL(int) RTVfsChainElementDeregisterProvider(PRTVFSCHAINELEMENTREG pRegRec, bool fFromDtor);
1432
1433
1434/** @def RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER
1435 * Automatically registers a chain element provider using a global constructor
1436 * and destructor hack.
1437 *
1438 * @param pRegRec Pointer to the registration record.
1439 * @param name Some unique variable name prefix.
1440 */
1441
1442#ifdef __cplusplus
1443/**
1444 * Class used for registering a VFS chain element provider.
1445 */
1446class RTVfsChainElementAutoRegisterHack
1447{
1448private:
1449 /** The registration record, NULL if registration failed. */
1450 PRTVFSCHAINELEMENTREG m_pRegRec;
1451
1452public:
1453 RTVfsChainElementAutoRegisterHack(PRTVFSCHAINELEMENTREG a_pRegRec)
1454 : m_pRegRec(a_pRegRec)
1455 {
1456 int rc = RTVfsChainElementRegisterProvider(m_pRegRec, true);
1457 if (RT_FAILURE(rc))
1458 m_pRegRec = NULL;
1459 }
1460
1461 ~RTVfsChainElementAutoRegisterHack()
1462 {
1463 RTVfsChainElementDeregisterProvider(m_pRegRec, true);
1464 m_pRegRec = NULL;
1465 }
1466};
1467
1468# define RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER(pRegRec, name) \
1469 static RTVfsChainElementAutoRegisterHack name ## AutoRegistrationHack(pRegRec)
1470
1471#else
1472# define RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER(pRegRec, name) \
1473 extern void *name ## AutoRegistrationHack = \
1474 &Sorry_but_RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER_does_not_work_in_c_source_files
1475#endif
1476
1477
1478/**
1479 * Common worker for the 'stdfile' and 'open' providers for implementing
1480 * RTVFSCHAINELEMENTREG::pfnValidate.
1481 *
1482 * Stores the RTFILE_O_XXX flags in pSpec->uProvider.
1483 *
1484 * @returns IPRT status code.
1485 * @param pSpec The chain specification.
1486 * @param pElement The chain element specification to validate.
1487 * @param poffError Where to return error offset on failure. This is set to
1488 * the pElement->offSpec on input, so it only needs to be
1489 * adjusted if an argument is at fault.
1490 * @param pErrInfo Where to return additional error information, if
1491 * available. Optional.
1492 */
1493RTDECL(int) RTVfsChainValidateOpenFileOrIoStream(PRTVFSCHAINSPEC pSpec, PRTVFSCHAINELEMSPEC pElement,
1494 uint32_t *poffError, PRTERRINFO pErrInfo);
1495
1496
1497/** @} */
1498
1499
1500/** @} */
1501
1502RT_C_DECLS_END
1503
1504#endif /* !IPRT_INCLUDED_vfslowlevel_h */
1505
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