VirtualBox

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

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

iprt/isomaker: Optimized native handle (file descriptor) usage when adding real directories.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 59.2 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 * Gets the private data of a directory.
766 *
767 * @returns Pointer to the private data. NULL if the handle is invalid in some
768 * way.
769 * @param hVfsDir The directory handle.
770 * @param pDirOps The directory operations. This servers as a
771 * sort of password.
772 */
773RTDECL(void *) RTVfsDirToPrivate(RTVFSDIR hVfsDir, PCRTVFSDIROPS pDirOps);
774
775
776/**
777 * The symbolic link operations.
778 *
779 * @extends RTVFSOBJOPS
780 * @extends RTVFSOBJSETOPS
781 */
782typedef struct RTVFSSYMLINKOPS
783{
784 /** The basic object operation. */
785 RTVFSOBJOPS Obj;
786 /** The structure version (RTVFSSYMLINKOPS_VERSION). */
787 uint32_t uVersion;
788 /** Reserved field, MBZ. */
789 uint32_t fReserved;
790 /** The object setter operations. */
791 RTVFSOBJSETOPS ObjSet;
792
793 /**
794 * Read the symbolic link target.
795 *
796 * @returns IPRT status code.
797 * @param pvThis The implementation specific symbolic link data.
798 * @param pszTarget The target buffer.
799 * @param cbTarget The size of the target buffer.
800 * @sa RTSymlinkRead
801 */
802 DECLCALLBACKMEMBER(int, pfnRead)(void *pvThis, char *pszTarget, size_t cbTarget);
803
804 /** Marks the end of the structure (RTVFSSYMLINKOPS_VERSION). */
805 uintptr_t uEndMarker;
806} RTVFSSYMLINKOPS;
807/** Pointer to const symbolic link operations. */
808typedef RTVFSSYMLINKOPS const *PCRTVFSSYMLINKOPS;
809/** The RTVFSSYMLINKOPS structure version. */
810#define RTVFSSYMLINKOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x5f,1,0)
811
812
813/**
814 * Creates a new VFS symlink handle.
815 *
816 * @returns IPRT status code
817 * @param pSymlinkOps The symlink operations.
818 * @param cbInstance The size of the instance data.
819 * @param hVfs The VFS handle to associate this symlink object
820 * with. NIL_VFS is ok.
821 * @param hLock Handle to a custom lock to be used with the new
822 * object. The reference is consumed. NIL and
823 * special lock handles are fine.
824 * @param phVfsSym Where to return the new handle.
825 * @param ppvInstance Where to return the pointer to the instance data
826 * (size is @a cbInstance).
827 */
828RTDECL(int) RTVfsNewSymlink(PCRTVFSSYMLINKOPS pSymlinkOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock,
829 PRTVFSSYMLINK phVfsSym, void **ppvInstance);
830
831
832/**
833 * The basis for all I/O objects (files, pipes, sockets, devices, ++).
834 *
835 * @extends RTVFSOBJOPS
836 */
837typedef struct RTVFSIOSTREAMOPS
838{
839 /** The basic object operation. */
840 RTVFSOBJOPS Obj;
841 /** The structure version (RTVFSIOSTREAMOPS_VERSION). */
842 uint32_t uVersion;
843 /** Feature field. */
844 uint32_t fFeatures;
845
846 /**
847 * Reads from the file/stream.
848 *
849 * @returns IPRT status code. See RTVfsIoStrmRead.
850 * @param pvThis The implementation specific file data.
851 * @param off Where to read at, -1 for the current position.
852 * @param pSgBuf Gather buffer describing the bytes that are to be
853 * written.
854 * @param fBlocking If @c true, the call is blocking, if @c false it
855 * should not block.
856 * @param pcbRead Where return the number of bytes actually read.
857 * This is set it 0 by the caller. If NULL, try read
858 * all and fail if incomplete.
859 * @sa RTVfsIoStrmRead, RTVfsIoStrmSgRead, RTVfsFileRead,
860 * RTVfsFileReadAt, RTFileRead, RTFileReadAt.
861 */
862 DECLCALLBACKMEMBER(int, pfnRead)(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead);
863
864 /**
865 * Writes to the file/stream.
866 *
867 * @returns IPRT status code.
868 * @param pvThis The implementation specific file data.
869 * @param off Where to start wrinting, -1 for the current
870 * position.
871 * @param pSgBuf Gather buffers describing the bytes that are to be
872 * written.
873 * @param fBlocking If @c true, the call is blocking, if @c false it
874 * should not block.
875 * @param pcbWritten Where to return the number of bytes actually
876 * written. This is set it 0 by the caller. If
877 * NULL, try write it all and fail if incomplete.
878 * @note Optional, failing with VERR_WRITE_PROTECT if NULL.
879 * @sa RTFileWrite, RTFileWriteAt.
880 */
881 DECLCALLBACKMEMBER(int, pfnWrite)(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten);
882
883 /**
884 * Flushes any pending data writes to the stream.
885 *
886 * @returns IPRT status code.
887 * @param pvThis The implementation specific file data.
888 * @sa RTFileFlush.
889 */
890 DECLCALLBACKMEMBER(int, pfnFlush)(void *pvThis);
891
892 /**
893 * Poll for events.
894 *
895 * @returns IPRT status code.
896 * @param pvThis The implementation specific file data.
897 * @param fEvents The events to poll for (RTPOLL_EVT_XXX).
898 * @param cMillies How long to wait for event to eventuate.
899 * @param fIntr Whether the wait is interruptible and can return
900 * VERR_INTERRUPTED (@c true) or if this condition
901 * should be hidden from the caller (@c false).
902 * @param pfRetEvents Where to return the event mask.
903 * @note Optional. If NULL, immediately return all requested non-error
904 * events, waiting for errors works like sleep.
905 * @sa RTPollSetAdd, RTPoll, RTPollNoResume.
906 */
907 DECLCALLBACKMEMBER(int, pfnPollOne)(void *pvThis, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr,
908 uint32_t *pfRetEvents);
909
910 /**
911 * Tells the current file/stream position.
912 *
913 * @returns IPRT status code.
914 * @param pvThis The implementation specific file data.
915 * @param poffActual Where to return the actual offset.
916 * @sa RTFileTell
917 */
918 DECLCALLBACKMEMBER(int, pfnTell)(void *pvThis, PRTFOFF poffActual);
919
920 /**
921 * Skips @a cb ahead in the stream.
922 *
923 * @returns IPRT status code.
924 * @param pvThis The implementation specific file data.
925 * @param cb The number bytes to skip.
926 * @remarks This is optional and can be NULL.
927 */
928 DECLCALLBACKMEMBER(int, pfnSkip)(void *pvThis, RTFOFF cb);
929
930 /**
931 * Fills the stream with @a cb zeros.
932 *
933 * @returns IPRT status code.
934 * @param pvThis The implementation specific file data.
935 * @param cb The number of zero bytes to insert.
936 * @remarks This is optional and can be NULL.
937 */
938 DECLCALLBACKMEMBER(int, pfnZeroFill)(void *pvThis, RTFOFF cb);
939
940 /** Marks the end of the structure (RTVFSIOSTREAMOPS_VERSION). */
941 uintptr_t uEndMarker;
942} RTVFSIOSTREAMOPS;
943/** Pointer to const I/O stream operations. */
944typedef RTVFSIOSTREAMOPS const *PCRTVFSIOSTREAMOPS;
945
946/** The RTVFSIOSTREAMOPS structure version. */
947#define RTVFSIOSTREAMOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x6f,1,0)
948
949/** @name RTVFSIOSTREAMOPS::fFeatures
950 * @{ */
951/** No scatter gather lists, thank you. */
952#define RTVFSIOSTREAMOPS_FEAT_NO_SG RT_BIT_32(0)
953/** Mask of the valid I/O stream feature flags. */
954#define RTVFSIOSTREAMOPS_FEAT_VALID_MASK UINT32_C(0x00000001)
955/** @} */
956
957
958/**
959 * Creates a new VFS I/O stream handle.
960 *
961 * @returns IPRT status code
962 * @param pIoStreamOps The I/O stream operations.
963 * @param cbInstance The size of the instance data.
964 * @param fOpen The open flags. The minimum is the access mask.
965 * @param hVfs The VFS handle to associate this I/O stream
966 * with. NIL_VFS is ok.
967 * @param hLock Handle to a custom lock to be used with the new
968 * object. The reference is consumed. NIL and
969 * special lock handles are fine.
970 * @param phVfsIos Where to return the new handle.
971 * @param ppvInstance Where to return the pointer to the instance data
972 * (size is @a cbInstance).
973 */
974RTDECL(int) RTVfsNewIoStream(PCRTVFSIOSTREAMOPS pIoStreamOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs, RTVFSLOCK hLock,
975 PRTVFSIOSTREAM phVfsIos, void **ppvInstance);
976
977
978/**
979 * Gets the private data of an I/O stream.
980 *
981 * @returns Pointer to the private data. NULL if the handle is invalid in some
982 * way.
983 * @param hVfsIos The I/O stream handle.
984 * @param pIoStreamOps The I/O stream operations. This servers as a
985 * sort of password.
986 */
987RTDECL(void *) RTVfsIoStreamToPrivate(RTVFSIOSTREAM hVfsIos, PCRTVFSIOSTREAMOPS pIoStreamOps);
988
989
990/**
991 * The file operations.
992 *
993 * @extends RTVFSIOSTREAMOPS
994 * @extends RTVFSOBJSETOPS
995 */
996typedef struct RTVFSFILEOPS
997{
998 /** The I/O stream and basis object operations. */
999 RTVFSIOSTREAMOPS Stream;
1000 /** The structure version (RTVFSFILEOPS_VERSION). */
1001 uint32_t uVersion;
1002 /** Reserved field, MBZ. */
1003 uint32_t fReserved;
1004 /** The object setter operations. */
1005 RTVFSOBJSETOPS ObjSet;
1006
1007 /**
1008 * Changes the current file position.
1009 *
1010 * @returns IPRT status code.
1011 * @param pvThis The implementation specific file data.
1012 * @param offSeek The offset to seek.
1013 * @param uMethod The seek method, i.e. what the seek is relative to.
1014 * @param poffActual Where to return the actual offset.
1015 * @sa RTFileSeek
1016 */
1017 DECLCALLBACKMEMBER(int, pfnSeek)(void *pvThis, RTFOFF offSeek, unsigned uMethod, PRTFOFF poffActual);
1018
1019 /**
1020 * Get the current file size.
1021 *
1022 * @returns IPRT status code.
1023 * @param pvThis The implementation specific file data.
1024 * @param pcbFile Where to store the current file size.
1025 * @sa RTFileGetSize
1026 */
1027 DECLCALLBACKMEMBER(int, pfnQuerySize)(void *pvThis, uint64_t *pcbFile);
1028
1029 /**
1030 * Change the file size.
1031 *
1032 * @returns IPRT status code.
1033 * @retval VERR_ACCESS_DENIED if handle isn't writable.
1034 * @retval VERR_WRITE_PROTECT if read-only file system.
1035 * @retval VERR_FILE_TOO_BIG if cbSize is larger than what the file system can
1036 * theoretically deal with.
1037 * @retval VERR_DISK_FULL if the file system if full.
1038 * @retval VERR_NOT_SUPPORTED if fFlags indicates some operation that's not
1039 * supported by the file system / host operating system.
1040 *
1041 * @param pvThis The implementation specific file data.
1042 * @param pcbFile Where to store the current file size.
1043 * @param fFlags RTVFSFILE_SET_SIZE_F_XXX.
1044 * @note Optional. If NULL, VERR_WRITE_PROTECT will be returned.
1045 * @sa RTFileSetSize, RTFileSetAllocationSize
1046 */
1047 DECLCALLBACKMEMBER(int, pfnSetSize)(void *pvThis, uint64_t cbFile, uint32_t fFlags);
1048
1049 /**
1050 * Determine the maximum file size.
1051 *
1052 * This won't take amount of freespace into account, just the limitations of the
1053 * underlying file system / host operating system.
1054 *
1055 * @returns IPRT status code.
1056 * @param pvThis The implementation specific file data.
1057 * @param pcbMax Where to return the max file size.
1058 * @note Optional. If NULL, VERR_NOT_IMPLEMENTED will be returned.
1059 * @sa RTFileGetMaxSizeEx
1060 */
1061 DECLCALLBACKMEMBER(int, pfnQueryMaxSize)(void *pvThis, uint64_t *pcbMax);
1062
1063 /** @todo There will be more methods here. */
1064
1065 /** Marks the end of the structure (RTVFSFILEOPS_VERSION). */
1066 uintptr_t uEndMarker;
1067} RTVFSFILEOPS;
1068/** Pointer to const file operations. */
1069typedef RTVFSFILEOPS const *PCRTVFSFILEOPS;
1070
1071/** The RTVFSFILEOPS structure version. */
1072#define RTVFSFILEOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x7f,2,0)
1073
1074/**
1075 * Creates a new VFS file handle.
1076 *
1077 * @returns IPRT status code
1078 * @param pFileOps The file operations.
1079 * @param cbInstance The size of the instance data.
1080 * @param fOpen The open flags. The minimum is the access mask.
1081 * @param hVfs The VFS handle to associate this file with.
1082 * NIL_VFS is ok.
1083 * @param hLock Handle to a custom lock to be used with the new
1084 * object. The reference is consumed. NIL and
1085 * special lock handles are fine.
1086 * @param phVfsFile Where to return the new handle.
1087 * @param ppvInstance Where to return the pointer to the instance data
1088 * (size is @a cbInstance).
1089 */
1090RTDECL(int) RTVfsNewFile(PCRTVFSFILEOPS pFileOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs, RTVFSLOCK hLock,
1091 PRTVFSFILE phVfsFile, void **ppvInstance);
1092
1093
1094/** @defgroup grp_rt_vfs_ll_util VFS Utility APIs
1095 * @{ */
1096
1097/**
1098 * Parsed path.
1099 */
1100typedef struct RTVFSPARSEDPATH
1101{
1102 /** The length of the path in szCopy. */
1103 uint16_t cch;
1104 /** The number of path components. */
1105 uint16_t cComponents;
1106 /** Set if the path ends with slash, indicating that it's a directory
1107 * reference and not a file reference. The slash has been removed from
1108 * the copy. */
1109 bool fDirSlash;
1110 /** Set if absolute. */
1111 bool fAbsolute;
1112 /** The offset where each path component starts, i.e. the char after the
1113 * slash. The array has cComponents + 1 entries, where the final one is
1114 * cch + 1 so that one can always terminate the current component by
1115 * szPath[aoffComponent[i] - 1] = '\0'. */
1116 uint16_t aoffComponents[RTPATH_MAX / 2 + 1];
1117 /** A normalized copy of the path.
1118 * Reserve some extra space so we can be more relaxed about overflow
1119 * checks and terminator paddings, especially when recursing. */
1120 char szPath[RTPATH_MAX];
1121} RTVFSPARSEDPATH;
1122/** Pointer to a parsed path. */
1123typedef RTVFSPARSEDPATH *PRTVFSPARSEDPATH;
1124
1125/** The max accepted path length.
1126 * This must be a few chars shorter than RTVFSPARSEDPATH::szPath because we
1127 * use two terminators and wish be a little bit lazy with checking. */
1128#define RTVFSPARSEDPATH_MAX (RTPATH_MAX - 4)
1129
1130/**
1131 * Appends @a pszPath (relative) to the already parsed path @a pPath.
1132 *
1133 * @retval VINF_SUCCESS
1134 * @retval VERR_FILENAME_TOO_LONG
1135 * @retval VERR_INTERNAL_ERROR_4
1136 * @param pPath The parsed path to append @a pszPath onto.
1137 * This is both input and output.
1138 * @param pszPath The path to append. This must be relative.
1139 * @param piRestartComp The component to restart parsing at. This is
1140 * input/output. The input does not have to be
1141 * within the valid range. Optional.
1142 */
1143RTDECL(int) RTVfsParsePathAppend(PRTVFSPARSEDPATH pPath, const char *pszPath, uint16_t *piRestartComp);
1144
1145/**
1146 * Parses a path.
1147 *
1148 * @retval VINF_SUCCESS
1149 * @retval VERR_FILENAME_TOO_LONG
1150 * @param pPath Where to store the parsed path.
1151 * @param pszPath The path to parse. Absolute or relative to @a
1152 * pszCwd.
1153 * @param pszCwd The current working directory. Must be
1154 * absolute.
1155 */
1156RTDECL(int) RTVfsParsePath(PRTVFSPARSEDPATH pPath, const char *pszPath, const char *pszCwd);
1157
1158/**
1159 * Same as RTVfsParsePath except that it allocates a temporary buffer.
1160 *
1161 * @retval VINF_SUCCESS
1162 * @retval VERR_NO_TMP_MEMORY
1163 * @retval VERR_FILENAME_TOO_LONG
1164 * @param pszPath The path to parse. Absolute or relative to @a
1165 * pszCwd.
1166 * @param pszCwd The current working directory. Must be
1167 * absolute.
1168 * @param ppPath Where to store the pointer to the allocated
1169 * buffer containing the parsed path. This must
1170 * be freed by calling RTVfsParsePathFree. NULL
1171 * will be stored on failured.
1172 */
1173RTDECL(int) RTVfsParsePathA(const char *pszPath, const char *pszCwd, PRTVFSPARSEDPATH *ppPath);
1174
1175/**
1176 * Frees a buffer returned by RTVfsParsePathA.
1177 *
1178 * @param pPath The parsed path buffer to free. NULL is fine.
1179 */
1180RTDECL(void) RTVfsParsePathFree(PRTVFSPARSEDPATH pPath);
1181
1182/**
1183 * Dummy implementation of RTVFSIOSTREAMOPS::pfnPollOne.
1184 *
1185 * This handles the case where there is no chance any events my be raised and
1186 * all that is required is to wait according to the parameters.
1187 *
1188 * @returns IPRT status code.
1189 * @param fEvents The events to poll for (RTPOLL_EVT_XXX).
1190 * @param cMillies How long to wait for event to eventuate.
1191 * @param fIntr Whether the wait is interruptible and can return
1192 * VERR_INTERRUPTED (@c true) or if this condition
1193 * should be hidden from the caller (@c false).
1194 * @param pfRetEvents Where to return the event mask.
1195 * @sa RTVFSIOSTREAMOPS::pfnPollOne, RTPollSetAdd, RTPoll, RTPollNoResume.
1196 */
1197RTDECL(int) RTVfsUtilDummyPollOne(uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr, uint32_t *pfRetEvents);
1198
1199/** @} */
1200
1201
1202/** @defgroup grp_rt_vfs_lowlevel_chain VFS Chains (Low Level)
1203 * @ref grp_rt_vfs_chain
1204 * @{
1205 */
1206
1207/** Pointer to a VFS chain element registration record. */
1208typedef struct RTVFSCHAINELEMENTREG *PRTVFSCHAINELEMENTREG;
1209/** Pointer to a const VFS chain element registration record. */
1210typedef struct RTVFSCHAINELEMENTREG const *PCRTVFSCHAINELEMENTREG;
1211
1212/**
1213 * VFS chain element argument.
1214 */
1215typedef struct RTVFSCHAINELEMENTARG
1216{
1217 /** The string argument value. */
1218 char *psz;
1219 /** The specification offset of this argument. */
1220 uint16_t offSpec;
1221 /** Provider specific value. */
1222 uint64_t uProvider;
1223} RTVFSCHAINELEMENTARG;
1224/** Pointer to a VFS chain element argument. */
1225typedef RTVFSCHAINELEMENTARG *PRTVFSCHAINELEMENTARG;
1226
1227
1228/**
1229 * VFS chain element specification.
1230 */
1231typedef struct RTVFSCHAINELEMSPEC
1232{
1233 /** The provider name.
1234 * This can be NULL if this is the final component and it's just a path. */
1235 char *pszProvider;
1236 /** The input type, RTVFSOBJTYPE_INVALID if first. */
1237 RTVFSOBJTYPE enmTypeIn;
1238 /** The element type.
1239 * RTVFSOBJTYPE_END if this is the final component and it's just a path. */
1240 RTVFSOBJTYPE enmType;
1241 /** The input spec offset of this element. */
1242 uint16_t offSpec;
1243 /** The length of the input spec. */
1244 uint16_t cchSpec;
1245 /** The number of arguments. */
1246 uint32_t cArgs;
1247 /** Arguments. */
1248 PRTVFSCHAINELEMENTARG paArgs;
1249
1250 /** The provider. */
1251 PCRTVFSCHAINELEMENTREG pProvider;
1252 /** Provider specific value. */
1253 uint64_t uProvider;
1254 /** The object (with reference). */
1255 RTVFSOBJ hVfsObj;
1256} RTVFSCHAINELEMSPEC;
1257/** Pointer to a chain element specification. */
1258typedef RTVFSCHAINELEMSPEC *PRTVFSCHAINELEMSPEC;
1259/** Pointer to a const chain element specification. */
1260typedef RTVFSCHAINELEMSPEC const *PCRTVFSCHAINELEMSPEC;
1261
1262
1263/**
1264 * Parsed VFS chain specification.
1265 */
1266typedef struct RTVFSCHAINSPEC
1267{
1268 /** Open directory flags (RTFILE_O_XXX). */
1269 uint64_t fOpenFile;
1270 /** To be defined. */
1271 uint32_t fOpenDir;
1272 /** The type desired by the caller. */
1273 RTVFSOBJTYPE enmDesiredType;
1274 /** The number of elements. */
1275 uint32_t cElements;
1276 /** The elements. */
1277 PRTVFSCHAINELEMSPEC paElements;
1278} RTVFSCHAINSPEC;
1279/** Pointer to a parsed VFS chain specification. */
1280typedef RTVFSCHAINSPEC *PRTVFSCHAINSPEC;
1281/** Pointer to a const, parsed VFS chain specification. */
1282typedef RTVFSCHAINSPEC const *PCRTVFSCHAINSPEC;
1283
1284
1285/**
1286 * A chain element provider registration record.
1287 */
1288typedef struct RTVFSCHAINELEMENTREG
1289{
1290 /** The version (RTVFSCHAINELEMENTREG_VERSION). */
1291 uint32_t uVersion;
1292 /** Reserved, MBZ. */
1293 uint32_t fReserved;
1294 /** The provider name (unique). */
1295 const char *pszName;
1296 /** For chaining the providers. */
1297 RTLISTNODE ListEntry;
1298 /** Help text. */
1299 const char *pszHelp;
1300
1301 /**
1302 * Checks the element specification.
1303 *
1304 * This is allowed to parse arguments and use pSpec->uProvider and
1305 * pElement->paArgs[].uProvider to store information that pfnInstantiate and
1306 * pfnCanReuseElement may use later on, thus avoiding duplicating work/code.
1307 *
1308 * @returns IPRT status code.
1309 * @param pProviderReg Pointer to the element provider registration.
1310 * @param pSpec The chain specification.
1311 * @param pElement The chain element specification to validate.
1312 * @param poffError Where to return error offset on failure. This is
1313 * set to the pElement->offSpec on input, so it only
1314 * needs to be adjusted if an argument is at fault.
1315 * @param pErrInfo Where to return additional error information, if
1316 * available. Optional.
1317 */
1318 DECLCALLBACKMEMBER(int, pfnValidate)(PCRTVFSCHAINELEMENTREG pProviderReg, PRTVFSCHAINSPEC pSpec,
1319 PRTVFSCHAINELEMSPEC pElement, uint32_t *poffError, PRTERRINFO pErrInfo);
1320
1321 /**
1322 * Create a VFS object according to the element specification.
1323 *
1324 * @returns IPRT status code.
1325 * @param pProviderReg Pointer to the element provider registration.
1326 * @param pSpec The chain specification.
1327 * @param pElement The chain element specification to instantiate.
1328 * @param hPrevVfsObj Handle to the previous VFS object, NIL_RTVFSOBJ if
1329 * first.
1330 * @param phVfsObj Where to return the VFS object handle.
1331 * @param poffError Where to return error offset on failure. This is
1332 * set to the pElement->offSpec on input, so it only
1333 * needs to be adjusted if an argument is at fault.
1334 * @param pErrInfo Where to return additional error information, if
1335 * available. Optional.
1336 */
1337 DECLCALLBACKMEMBER(int, pfnInstantiate)(PCRTVFSCHAINELEMENTREG pProviderReg, PCRTVFSCHAINSPEC pSpec,
1338 PCRTVFSCHAINELEMSPEC pElement, RTVFSOBJ hPrevVfsObj,
1339 PRTVFSOBJ phVfsObj, uint32_t *poffError, PRTERRINFO pErrInfo);
1340
1341 /**
1342 * Determins whether the element can be reused.
1343 *
1344 * This is for handling situations accessing the same file system twice, like
1345 * for both the source and destiation of a copy operation. This allows not only
1346 * sharing resources and avoid doing things twice, but also helps avoid file
1347 * sharing violations and inconsistencies araising from the image being updated
1348 * and read independently.
1349 *
1350 * @returns true if the element from @a pReuseSpec an be reused, false if not.
1351 * @param pProviderReg Pointer to the element provider registration.
1352 * @param pSpec The chain specification.
1353 * @param pElement The chain element specification.
1354 * @param pReuseSpec The chain specification of the existing chain.
1355 * @param pReuseElement The chain element specification of the existing
1356 * element that is being considered for reuse.
1357 */
1358 DECLCALLBACKMEMBER(bool, pfnCanReuseElement)(PCRTVFSCHAINELEMENTREG pProviderReg,
1359 PCRTVFSCHAINSPEC pSpec, PCRTVFSCHAINELEMSPEC pElement,
1360 PCRTVFSCHAINSPEC pReuseSpec, PCRTVFSCHAINELEMSPEC pReuseElement);
1361
1362 /** End marker (RTVFSCHAINELEMENTREG_VERSION). */
1363 uintptr_t uEndMarker;
1364} RTVFSCHAINELEMENTREG;
1365
1366/** The VFS chain element registration record version number. */
1367#define RTVFSCHAINELEMENTREG_VERSION RT_MAKE_U32_FROM_U8(0xff, 0x7f, 1, 0)
1368
1369
1370/**
1371 * Parses the specification.
1372 *
1373 * @returns IPRT status code.
1374 * @param pszSpec The specification string to parse.
1375 * @param fFlags Flags, see RTVFSCHAIN_PF_XXX.
1376 * @param enmDesiredType The object type the caller wants to interface with.
1377 * @param ppSpec Where to return the pointer to the parsed
1378 * specification. This must be freed by calling
1379 * RTVfsChainSpecFree. Will always be set (unless
1380 * invalid parameters.)
1381 * @param poffError Where to return the offset into the input
1382 * specification of what's causing trouble. Always
1383 * set, unless this argument causes an invalid pointer
1384 * error.
1385 */
1386RTDECL(int) RTVfsChainSpecParse(const char *pszSpec, uint32_t fFlags, RTVFSOBJTYPE enmDesiredType,
1387 PRTVFSCHAINSPEC *ppSpec, uint32_t *poffError);
1388
1389/** @name RTVfsChainSpecParse
1390 * @{ */
1391/** Mask of valid flags. */
1392#define RTVFSCHAIN_PF_VALID_MASK UINT32_C(0x00000000)
1393/** @} */
1394
1395/**
1396 * Checks and setups the chain.
1397 *
1398 * @returns IPRT status code.
1399 * @param pSpec The parsed specification.
1400 * @param pReuseSpec Spec to reuse if applicable. Optional.
1401 * @param phVfsObj Where to return the VFS object.
1402 * @param ppszFinalPath Where to return the pointer to the final path if
1403 * applicable. The caller needs to check whether this
1404 * is NULL or a path, in the former case nothing more
1405 * needs doing, whereas in the latter the caller must
1406 * perform the desired operation(s) on *phVfsObj using
1407 * the final path.
1408 * @param poffError Where to return the offset into the input
1409 * specification of what's causing trouble. Always
1410 * set, unless this argument causes an invalid pointer
1411 * error.
1412 * @param pErrInfo Where to return additional error information, if
1413 * available. Optional.
1414 */
1415RTDECL(int) RTVfsChainSpecCheckAndSetup(PRTVFSCHAINSPEC pSpec, PCRTVFSCHAINSPEC pReuseSpec,
1416 PRTVFSOBJ phVfsObj, const char **ppszFinalPath, uint32_t *poffError, PRTERRINFO pErrInfo);
1417
1418/**
1419 * Frees a parsed chain specification.
1420 *
1421 * @param pSpec What RTVfsChainSpecParse returned. NULL is
1422 * quietly ignored.
1423 */
1424RTDECL(void) RTVfsChainSpecFree(PRTVFSCHAINSPEC pSpec);
1425
1426/**
1427 * Registers a chain element provider.
1428 *
1429 * @returns IPRT status code
1430 * @param pRegRec The registration record.
1431 * @param fFromCtor Indicates where we're called from.
1432 */
1433RTDECL(int) RTVfsChainElementRegisterProvider(PRTVFSCHAINELEMENTREG pRegRec, bool fFromCtor);
1434
1435/**
1436 * Deregisters a chain element provider.
1437 *
1438 * @returns IPRT status code
1439 * @param pRegRec The registration record.
1440 * @param fFromDtor Indicates where we're called from.
1441 */
1442RTDECL(int) RTVfsChainElementDeregisterProvider(PRTVFSCHAINELEMENTREG pRegRec, bool fFromDtor);
1443
1444
1445/** @def RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER
1446 * Automatically registers a chain element provider using a global constructor
1447 * and destructor hack.
1448 *
1449 * @param pRegRec Pointer to the registration record.
1450 * @param name Some unique variable name prefix.
1451 */
1452
1453#ifdef __cplusplus
1454/**
1455 * Class used for registering a VFS chain element provider.
1456 */
1457class RTVfsChainElementAutoRegisterHack
1458{
1459private:
1460 /** The registration record, NULL if registration failed. */
1461 PRTVFSCHAINELEMENTREG m_pRegRec;
1462
1463public:
1464 RTVfsChainElementAutoRegisterHack(PRTVFSCHAINELEMENTREG a_pRegRec)
1465 : m_pRegRec(a_pRegRec)
1466 {
1467 int rc = RTVfsChainElementRegisterProvider(m_pRegRec, true);
1468 if (RT_FAILURE(rc))
1469 m_pRegRec = NULL;
1470 }
1471
1472 ~RTVfsChainElementAutoRegisterHack()
1473 {
1474 RTVfsChainElementDeregisterProvider(m_pRegRec, true);
1475 m_pRegRec = NULL;
1476 }
1477};
1478
1479# define RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER(pRegRec, name) \
1480 static RTVfsChainElementAutoRegisterHack name ## AutoRegistrationHack(pRegRec)
1481
1482#else
1483# define RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER(pRegRec, name) \
1484 extern void *name ## AutoRegistrationHack = \
1485 &Sorry_but_RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER_does_not_work_in_c_source_files
1486#endif
1487
1488
1489/**
1490 * Common worker for the 'stdfile' and 'open' providers for implementing
1491 * RTVFSCHAINELEMENTREG::pfnValidate.
1492 *
1493 * Stores the RTFILE_O_XXX flags in pSpec->uProvider.
1494 *
1495 * @returns IPRT status code.
1496 * @param pSpec The chain specification.
1497 * @param pElement The chain element specification to validate.
1498 * @param poffError Where to return error offset on failure. This is set to
1499 * the pElement->offSpec on input, so it only needs to be
1500 * adjusted if an argument is at fault.
1501 * @param pErrInfo Where to return additional error information, if
1502 * available. Optional.
1503 */
1504RTDECL(int) RTVfsChainValidateOpenFileOrIoStream(PRTVFSCHAINSPEC pSpec, PRTVFSCHAINELEMSPEC pElement,
1505 uint32_t *poffError, PRTERRINFO pErrInfo);
1506
1507
1508/** @} */
1509
1510
1511/** @} */
1512
1513RT_C_DECLS_END
1514
1515#endif /* !IPRT_INCLUDED_vfslowlevel_h */
1516
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