VirtualBox

source: vbox/trunk/include/VBox/vd-ifs.h@ 99396

Last change on this file since 99396 was 98103, checked in by vboxsync, 23 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 64.5 KB
Line 
1/** @file
2 * VD Container API - interfaces.
3 */
4
5/*
6 * Copyright (C) 2011-2023 Oracle and/or its affiliates.
7 *
8 * This file is part of VirtualBox base platform packages, as
9 * available from https://www.virtualbox.org.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation, in version 3 of the
14 * License.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <https://www.gnu.org/licenses>.
23 *
24 * The contents of this file may alternatively be used under the terms
25 * of the Common Development and Distribution License Version 1.0
26 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
27 * in the VirtualBox distribution, in which case the provisions of the
28 * CDDL are applicable instead of those of the GPL.
29 *
30 * You may elect to license modified versions of this file under the
31 * terms and conditions of either the GPL or the CDDL or both.
32 *
33 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
34 */
35
36#ifndef VBOX_INCLUDED_vd_ifs_h
37#define VBOX_INCLUDED_vd_ifs_h
38#ifndef RT_WITHOUT_PRAGMA_ONCE
39# pragma once
40#endif
41
42#include <iprt/assert.h>
43#include <iprt/string.h>
44#include <iprt/mem.h>
45#include <iprt/file.h>
46#include <iprt/net.h>
47#include <iprt/sg.h>
48#include <VBox/cdefs.h>
49#include <VBox/types.h>
50#include <VBox/err.h>
51
52RT_C_DECLS_BEGIN
53
54/** @addtogroup grp_vd
55 * @{ */
56
57/** Interface header magic. */
58#define VDINTERFACE_MAGIC UINT32_C(0x19701015)
59
60/**
61 * Supported interface types.
62 */
63typedef enum VDINTERFACETYPE
64{
65 /** First valid interface. */
66 VDINTERFACETYPE_FIRST = 0,
67 /** Interface to pass error message to upper layers. Per-disk. */
68 VDINTERFACETYPE_ERROR = VDINTERFACETYPE_FIRST,
69 /** Interface for I/O operations. Per-image. */
70 VDINTERFACETYPE_IO,
71 /** Interface for progress notification. Per-operation. */
72 VDINTERFACETYPE_PROGRESS,
73 /** Interface for configuration information. Per-image. */
74 VDINTERFACETYPE_CONFIG,
75 /** Interface for TCP network stack. Per-image. */
76 VDINTERFACETYPE_TCPNET,
77 /** Interface for getting parent image state. Per-operation. */
78 VDINTERFACETYPE_PARENTSTATE,
79 /** Interface for synchronizing accesses from several threads. Per-disk. */
80 VDINTERFACETYPE_THREADSYNC,
81 /** Interface for I/O between the generic VBoxHDD code and the backend. Per-image (internal).
82 * This interface is completely internal and must not be used elsewhere. */
83 VDINTERFACETYPE_IOINT,
84 /** Interface to query the use of block ranges on the disk. Per-operation. */
85 VDINTERFACETYPE_QUERYRANGEUSE,
86 /** Interface for the metadata traverse callback. Per-operation. */
87 VDINTERFACETYPE_TRAVERSEMETADATA,
88 /** Interface for crypto operations. Per-filter. */
89 VDINTERFACETYPE_CRYPTO,
90 /** invalid interface. */
91 VDINTERFACETYPE_INVALID
92} VDINTERFACETYPE;
93
94/**
95 * Common structure for all interfaces and at the beginning of all types.
96 */
97typedef struct VDINTERFACE
98{
99 uint32_t u32Magic;
100 /** Human readable interface name. */
101 const char *pszInterfaceName;
102 /** Pointer to the next common interface structure. */
103 struct VDINTERFACE *pNext;
104 /** Interface type. */
105 VDINTERFACETYPE enmInterface;
106 /** Size of the interface. */
107 size_t cbSize;
108 /** Opaque user data which is passed on every call. */
109 void *pvUser;
110} VDINTERFACE;
111/** Pointer to a VDINTERFACE. */
112typedef VDINTERFACE *PVDINTERFACE;
113/** Pointer to a const VDINTERFACE. */
114typedef const VDINTERFACE *PCVDINTERFACE;
115
116/**
117 * Helper functions to handle interface lists.
118 *
119 * @note These interface lists are used consistently to pass per-disk,
120 * per-image and/or per-operation callbacks. Those three purposes are strictly
121 * separate. See the individual interface declarations for what context they
122 * apply to. The caller is responsible for ensuring that the lifetime of the
123 * interface descriptors is appropriate for the category of interface.
124 */
125
126/**
127 * Get a specific interface from a list of interfaces specified by the type.
128 *
129 * @return Pointer to the matching interface or NULL if none was found.
130 * @param pVDIfs Pointer to the VD interface list.
131 * @param enmInterface Interface to search for.
132 */
133DECLINLINE(PVDINTERFACE) VDInterfaceGet(PVDINTERFACE pVDIfs, VDINTERFACETYPE enmInterface)
134{
135 AssertMsgReturn( enmInterface >= VDINTERFACETYPE_FIRST
136 && enmInterface < VDINTERFACETYPE_INVALID,
137 ("enmInterface=%u", enmInterface), NULL);
138
139 while (pVDIfs)
140 {
141 AssertMsgBreak(pVDIfs->u32Magic == VDINTERFACE_MAGIC,
142 ("u32Magic=%#x\n", pVDIfs->u32Magic));
143
144 if (pVDIfs->enmInterface == enmInterface)
145 return pVDIfs;
146 pVDIfs = pVDIfs->pNext;
147 }
148
149 /* No matching interface was found. */
150 return NULL;
151}
152
153/**
154 * Add an interface to a list of interfaces.
155 *
156 * @return VBox status code.
157 * @param pInterface Pointer to an unitialized common interface structure.
158 * @param pszName Name of the interface.
159 * @param enmInterface Type of the interface.
160 * @param pvUser Opaque user data passed on every function call.
161 * @param cbInterface The interface size.
162 * @param ppVDIfs Pointer to the VD interface list.
163 */
164DECLINLINE(int) VDInterfaceAdd(PVDINTERFACE pInterface, const char *pszName, VDINTERFACETYPE enmInterface, void *pvUser,
165 size_t cbInterface, PVDINTERFACE *ppVDIfs)
166{
167 /* Argument checks. */
168 AssertMsgReturn( enmInterface >= VDINTERFACETYPE_FIRST
169 && enmInterface < VDINTERFACETYPE_INVALID,
170 ("enmInterface=%u", enmInterface), VERR_INVALID_PARAMETER);
171
172 AssertPtrReturn(ppVDIfs, VERR_INVALID_PARAMETER);
173
174 /* Fill out interface descriptor. */
175 pInterface->u32Magic = VDINTERFACE_MAGIC;
176 pInterface->cbSize = cbInterface;
177 pInterface->pszInterfaceName = pszName;
178 pInterface->enmInterface = enmInterface;
179 pInterface->pvUser = pvUser;
180 pInterface->pNext = *ppVDIfs;
181
182 /* Remember the new start of the list. */
183 *ppVDIfs = pInterface;
184
185 return VINF_SUCCESS;
186}
187
188/**
189 * Removes an interface from a list of interfaces.
190 *
191 * @return VBox status code
192 * @param pInterface Pointer to an initialized common interface structure to remove.
193 * @param ppVDIfs Pointer to the VD interface list to remove from.
194 */
195DECLINLINE(int) VDInterfaceRemove(PVDINTERFACE pInterface, PVDINTERFACE *ppVDIfs)
196{
197 int rc = VERR_NOT_FOUND;
198
199 /* Argument checks. */
200 AssertPtrReturn(pInterface, VERR_INVALID_PARAMETER);
201 AssertPtrReturn(ppVDIfs, VERR_INVALID_PARAMETER);
202
203 if (*ppVDIfs)
204 {
205 PVDINTERFACE pPrev = NULL;
206 PVDINTERFACE pCurr = *ppVDIfs;
207
208 while ( pCurr
209 && (pCurr != pInterface))
210 {
211 pPrev = pCurr;
212 pCurr = pCurr->pNext;
213 }
214
215 /* First interface */
216 if (!pPrev)
217 {
218 *ppVDIfs = pCurr->pNext;
219 rc = VINF_SUCCESS;
220 }
221 else if (pCurr)
222 {
223 Assert(pPrev->pNext == pCurr);
224 pPrev->pNext = pCurr->pNext;
225 rc = VINF_SUCCESS;
226 }
227 }
228
229 return rc;
230}
231
232/**
233 * Interface to deliver error messages (and also informational messages)
234 * to upper layers.
235 *
236 * Per-disk interface. Optional, but think twice if you want to miss the
237 * opportunity of reporting better human-readable error messages.
238 */
239typedef struct VDINTERFACEERROR
240{
241 /**
242 * Common interface header.
243 */
244 VDINTERFACE Core;
245
246 /**
247 * Error message callback. Must be able to accept special IPRT format
248 * strings.
249 *
250 * @param pvUser The opaque data passed on container creation.
251 * @param rc The VBox error code.
252 * @param SRC_POS Use RT_SRC_POS.
253 * @param pszFormat Error message format string.
254 * @param va Error message arguments.
255 */
256 DECLR3CALLBACKMEMBER(void, pfnError, (void *pvUser, int rc, RT_SRC_POS_DECL,
257 const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(6, 0));
258
259 /**
260 * Informational message callback. May be NULL. Used e.g. in
261 * VDDumpImages(). Must be able to accept special IPRT format strings.
262 *
263 * @return VBox status code.
264 * @param pvUser The opaque data passed on container creation.
265 * @param pszFormat Message format string.
266 * @param va Message arguments.
267 */
268 DECLR3CALLBACKMEMBER(int, pfnMessage, (void *pvUser, const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(2, 0));
269
270} VDINTERFACEERROR, *PVDINTERFACEERROR;
271
272/**
273 * Get error interface from interface list.
274 *
275 * @return Pointer to the first error interface in the list.
276 * @param pVDIfs Pointer to the interface list.
277 */
278DECLINLINE(PVDINTERFACEERROR) VDIfErrorGet(PVDINTERFACE pVDIfs)
279{
280 PVDINTERFACE pIf = VDInterfaceGet(pVDIfs, VDINTERFACETYPE_ERROR);
281
282 /* Check that the interface descriptor is a progress interface. */
283 AssertMsgReturn( !pIf
284 || ( (pIf->enmInterface == VDINTERFACETYPE_ERROR)
285 && (pIf->cbSize == sizeof(VDINTERFACEERROR))),
286 ("Not an error interface\n"), NULL);
287
288 return (PVDINTERFACEERROR)pIf;
289}
290
291/**
292 * Signal an error to the frontend.
293 *
294 * @returns VBox status code.
295 * @param pIfError The error interface.
296 * @param rc The status code.
297 * @param SRC_POS The position in the source code.
298 * @param pszFormat The format string to pass.
299 * @param ... Arguments to the format string.
300 */
301DECLINLINE(int) RT_IPRT_FORMAT_ATTR(6, 7) vdIfError(PVDINTERFACEERROR pIfError, int rc, RT_SRC_POS_DECL,
302 const char *pszFormat, ...)
303{
304 va_list va;
305 va_start(va, pszFormat);
306 if (pIfError)
307 pIfError->pfnError(pIfError->Core.pvUser, rc, RT_SRC_POS_ARGS, pszFormat, va);
308 va_end(va);
309
310#if defined(LOG_ENABLED) && defined(Log)
311 va_start(va, pszFormat);
312 Log(("vdIfError: %N\n", pszFormat, &va));
313 va_end(va);
314#endif
315 return rc;
316}
317
318/**
319 * Signal an informational message to the frontend.
320 *
321 * @returns VBox status code.
322 * @param pIfError The error interface.
323 * @param pszFormat The format string to pass.
324 * @param ... Arguments to the format string.
325 */
326DECLINLINE(int) RT_IPRT_FORMAT_ATTR(2, 3) vdIfErrorMessage(PVDINTERFACEERROR pIfError, const char *pszFormat, ...)
327{
328 int rc = VINF_SUCCESS;
329 va_list va;
330 va_start(va, pszFormat);
331 if (pIfError && pIfError->pfnMessage)
332 rc = pIfError->pfnMessage(pIfError->Core.pvUser, pszFormat, va);
333 va_end(va);
334
335#if defined(LOG_ENABLED) && defined(Log)
336 va_start(va, pszFormat);
337 Log(("vdIfErrorMessage: %N\n", pszFormat, &va));
338 va_end(va);
339#endif
340 return rc;
341}
342
343/**
344 * Completion callback which is called by the interface owner
345 * to inform the backend that a task finished.
346 *
347 * @return VBox status code.
348 * @param pvUser Opaque user data which is passed on request submission.
349 * @param rcReq Status code of the completed request.
350 */
351typedef DECLCALLBACKTYPE(int, FNVDCOMPLETED,(void *pvUser, int rcReq));
352/** Pointer to FNVDCOMPLETED() */
353typedef FNVDCOMPLETED *PFNVDCOMPLETED;
354
355/**
356 * Support interface for I/O
357 *
358 * Per-image. Optional as input.
359 */
360typedef struct VDINTERFACEIO
361{
362 /**
363 * Common interface header.
364 */
365 VDINTERFACE Core;
366
367 /**
368 * Open callback
369 *
370 * @return VBox status code.
371 * @param pvUser The opaque data passed on container creation.
372 * @param pszLocation Name of the location to open.
373 * @param fOpen Flags for opening the backend.
374 * See RTFILE_O_* \#defines, inventing another set
375 * of open flags is not worth the mapping effort.
376 * @param pfnCompleted The callback which is called whenever a task
377 * completed. The backend has to pass the user data
378 * of the request initiator (ie the one who calls
379 * VDAsyncRead or VDAsyncWrite) in pvCompletion
380 * if this is NULL.
381 * @param ppvStorage Where to store the opaque storage handle.
382 */
383 DECLR3CALLBACKMEMBER(int, pfnOpen, (void *pvUser, const char *pszLocation,
384 uint32_t fOpen,
385 PFNVDCOMPLETED pfnCompleted,
386 void **ppvStorage));
387
388 /**
389 * Close callback.
390 *
391 * @return VBox status code.
392 * @param pvUser The opaque data passed on container creation.
393 * @param pvStorage The opaque storage handle to close.
394 */
395 DECLR3CALLBACKMEMBER(int, pfnClose, (void *pvUser, void *pvStorage));
396
397 /**
398 * Delete callback.
399 *
400 * @return VBox status code.
401 * @param pvUser The opaque data passed on container creation.
402 * @param pcszFilename Name of the file to delete.
403 */
404 DECLR3CALLBACKMEMBER(int, pfnDelete, (void *pvUser, const char *pcszFilename));
405
406 /**
407 * Move callback.
408 *
409 * @return VBox status code.
410 * @param pvUser The opaque data passed on container creation.
411 * @param pcszSrc The path to the source file.
412 * @param pcszDst The path to the destination file.
413 * This file will be created.
414 * @param fMove A combination of the RTFILEMOVE_* flags.
415 */
416 DECLR3CALLBACKMEMBER(int, pfnMove, (void *pvUser, const char *pcszSrc, const char *pcszDst, unsigned fMove));
417
418 /**
419 * Returns the free space on a disk.
420 *
421 * @return VBox status code.
422 * @param pvUser The opaque data passed on container creation.
423 * @param pcszFilename Name of a file to identify the disk.
424 * @param pcbFreeSpace Where to store the free space of the disk.
425 */
426 DECLR3CALLBACKMEMBER(int, pfnGetFreeSpace, (void *pvUser, const char *pcszFilename, int64_t *pcbFreeSpace));
427
428 /**
429 * Returns the last modification timestamp of a file.
430 *
431 * @return VBox status code.
432 * @param pvUser The opaque data passed on container creation.
433 * @param pcszFilename Name of a file to identify the disk.
434 * @param pModificationTime Where to store the timestamp of the file.
435 */
436 DECLR3CALLBACKMEMBER(int, pfnGetModificationTime, (void *pvUser, const char *pcszFilename, PRTTIMESPEC pModificationTime));
437
438 /**
439 * Returns the size of the opened storage backend.
440 *
441 * @return VBox status code.
442 * @param pvUser The opaque data passed on container creation.
443 * @param pvStorage The opaque storage handle to get the size from.
444 * @param pcb Where to store the size of the storage backend.
445 */
446 DECLR3CALLBACKMEMBER(int, pfnGetSize, (void *pvUser, void *pvStorage, uint64_t *pcb));
447
448 /**
449 * Sets the size of the opened storage backend if possible.
450 *
451 * @return VBox status code.
452 * @retval VERR_NOT_SUPPORTED if the backend does not support this operation.
453 * @param pvUser The opaque data passed on container creation.
454 * @param pvStorage The opaque storage handle to set the size for.
455 * @param cb The new size of the image.
456 *
457 * @note Depending on the host the underlying storage (backing file, etc.)
458 * might not have all required storage allocated (sparse file) which
459 * can delay writes or fail with a not enough free space error if there
460 * is not enough space on the storage medium when writing to the range for
461 * the first time.
462 * Use VDINTERFACEIO::pfnSetAllocationSize to make sure the storage is
463 * really alloacted.
464 */
465 DECLR3CALLBACKMEMBER(int, pfnSetSize, (void *pvUser, void *pvStorage, uint64_t cb));
466
467 /**
468 * Sets the size of the opened storage backend making sure the given size
469 * is really allocated.
470 *
471 * @return VBox status code.
472 * @retval VERR_NOT_SUPPORTED if the implementer of the interface doesn't support
473 * this method.
474 * @param pvUser The opaque data passed on container creation.
475 * @param pvStorage The storage handle.
476 * @param cbSize The new size of the image.
477 * @param fFlags Flags for controlling the allocation strategy.
478 * Reserved for future use, MBZ.
479 */
480 DECLR3CALLBACKMEMBER(int, pfnSetAllocationSize, (void *pvUser, void *pvStorage,
481 uint64_t cbSize, uint32_t fFlags));
482
483 /**
484 * Synchronous write callback.
485 *
486 * @return VBox status code.
487 * @param pvUser The opaque data passed on container creation.
488 * @param pvStorage The storage handle to use.
489 * @param off The offset to start from.
490 * @param pvBuf Pointer to the bits need to be written.
491 * @param cbToWrite How many bytes to write.
492 * @param pcbWritten Where to store how many bytes were actually written.
493 */
494 DECLR3CALLBACKMEMBER(int, pfnWriteSync, (void *pvUser, void *pvStorage, uint64_t off,
495 const void *pvBuf, size_t cbToWrite, size_t *pcbWritten));
496
497 /**
498 * Synchronous read callback.
499 *
500 * @return VBox status code.
501 * @param pvUser The opaque data passed on container creation.
502 * @param pvStorage The storage handle to use.
503 * @param off The offset to start from.
504 * @param pvBuf Where to store the read bits.
505 * @param cbToRead How many bytes to read.
506 * @param pcbRead Where to store how many bytes were actually read.
507 */
508 DECLR3CALLBACKMEMBER(int, pfnReadSync, (void *pvUser, void *pvStorage, uint64_t off,
509 void *pvBuf, size_t cbToRead, size_t *pcbRead));
510
511 /**
512 * Flush data to the storage backend.
513 *
514 * @return VBox status code.
515 * @param pvUser The opaque data passed on container creation.
516 * @param pvStorage The storage handle to flush.
517 */
518 DECLR3CALLBACKMEMBER(int, pfnFlushSync, (void *pvUser, void *pvStorage));
519
520 /**
521 * Initiate an asynchronous read request.
522 *
523 * @return VBox status code.
524 * @param pvUser The opaque user data passed on container creation.
525 * @param pvStorage The storage handle.
526 * @param uOffset The offset to start reading from.
527 * @param paSegments Scatter gather list to store the data in.
528 * @param cSegments Number of segments in the list.
529 * @param cbRead How many bytes to read.
530 * @param pvCompletion The opaque user data which is returned upon completion.
531 * @param ppTask Where to store the opaque task handle.
532 */
533 DECLR3CALLBACKMEMBER(int, pfnReadAsync, (void *pvUser, void *pvStorage, uint64_t uOffset,
534 PCRTSGSEG paSegments, size_t cSegments,
535 size_t cbRead, void *pvCompletion,
536 void **ppTask));
537
538 /**
539 * Initiate an asynchronous write request.
540 *
541 * @return VBox status code.
542 * @param pvUser The opaque user data passed on conatiner creation.
543 * @param pvStorage The storage handle.
544 * @param uOffset The offset to start writing to.
545 * @param paSegments Scatter gather list of the data to write
546 * @param cSegments Number of segments in the list.
547 * @param cbWrite How many bytes to write.
548 * @param pvCompletion The opaque user data which is returned upon completion.
549 * @param ppTask Where to store the opaque task handle.
550 */
551 DECLR3CALLBACKMEMBER(int, pfnWriteAsync, (void *pvUser, void *pvStorage, uint64_t uOffset,
552 PCRTSGSEG paSegments, size_t cSegments,
553 size_t cbWrite, void *pvCompletion,
554 void **ppTask));
555
556 /**
557 * Initiates an async flush request.
558 *
559 * @return VBox status code.
560 * @param pvUser The opaque data passed on container creation.
561 * @param pvStorage The storage handle to flush.
562 * @param pvCompletion The opaque user data which is returned upon completion.
563 * @param ppTask Where to store the opaque task handle.
564 */
565 DECLR3CALLBACKMEMBER(int, pfnFlushAsync, (void *pvUser, void *pvStorage,
566 void *pvCompletion, void **ppTask));
567
568} VDINTERFACEIO, *PVDINTERFACEIO;
569
570/**
571 * Get I/O interface from interface list.
572 *
573 * @return Pointer to the first I/O interface in the list.
574 * @param pVDIfs Pointer to the interface list.
575 */
576DECLINLINE(PVDINTERFACEIO) VDIfIoGet(PVDINTERFACE pVDIfs)
577{
578 PVDINTERFACE pIf = VDInterfaceGet(pVDIfs, VDINTERFACETYPE_IO);
579
580 /* Check that the interface descriptor is a progress interface. */
581 AssertMsgReturn( !pIf
582 || ( (pIf->enmInterface == VDINTERFACETYPE_IO)
583 && (pIf->cbSize == sizeof(VDINTERFACEIO))),
584 ("Not a I/O interface"), NULL);
585
586 return (PVDINTERFACEIO)pIf;
587}
588
589DECLINLINE(int) vdIfIoFileOpen(PVDINTERFACEIO pIfIo, const char *pszFilename,
590 uint32_t fOpen, PFNVDCOMPLETED pfnCompleted,
591 void **ppStorage)
592{
593 return pIfIo->pfnOpen(pIfIo->Core.pvUser, pszFilename, fOpen, pfnCompleted, ppStorage);
594}
595
596DECLINLINE(int) vdIfIoFileClose(PVDINTERFACEIO pIfIo, void *pStorage)
597{
598 return pIfIo->pfnClose(pIfIo->Core.pvUser, pStorage);
599}
600
601DECLINLINE(int) vdIfIoFileDelete(PVDINTERFACEIO pIfIo, const char *pszFilename)
602{
603 return pIfIo->pfnDelete(pIfIo->Core.pvUser, pszFilename);
604}
605
606DECLINLINE(int) vdIfIoFileMove(PVDINTERFACEIO pIfIo, const char *pszSrc,
607 const char *pszDst, unsigned fMove)
608{
609 return pIfIo->pfnMove(pIfIo->Core.pvUser, pszSrc, pszDst, fMove);
610}
611
612DECLINLINE(int) vdIfIoFileGetFreeSpace(PVDINTERFACEIO pIfIo, const char *pszFilename,
613 int64_t *pcbFree)
614{
615 return pIfIo->pfnGetFreeSpace(pIfIo->Core.pvUser, pszFilename, pcbFree);
616}
617
618DECLINLINE(int) vdIfIoFileGetModificationTime(PVDINTERFACEIO pIfIo, const char *pcszFilename,
619 PRTTIMESPEC pModificationTime)
620{
621 return pIfIo->pfnGetModificationTime(pIfIo->Core.pvUser, pcszFilename,
622 pModificationTime);
623}
624
625DECLINLINE(int) vdIfIoFileGetSize(PVDINTERFACEIO pIfIo, void *pStorage,
626 uint64_t *pcbSize)
627{
628 return pIfIo->pfnGetSize(pIfIo->Core.pvUser, pStorage, pcbSize);
629}
630
631DECLINLINE(int) vdIfIoFileSetSize(PVDINTERFACEIO pIfIo, void *pStorage,
632 uint64_t cbSize)
633{
634 return pIfIo->pfnSetSize(pIfIo->Core.pvUser, pStorage, cbSize);
635}
636
637DECLINLINE(int) vdIfIoFileWriteSync(PVDINTERFACEIO pIfIo, void *pStorage,
638 uint64_t uOffset, const void *pvBuffer, size_t cbBuffer,
639 size_t *pcbWritten)
640{
641 return pIfIo->pfnWriteSync(pIfIo->Core.pvUser, pStorage, uOffset,
642 pvBuffer, cbBuffer, pcbWritten);
643}
644
645DECLINLINE(int) vdIfIoFileReadSync(PVDINTERFACEIO pIfIo, void *pStorage,
646 uint64_t uOffset, void *pvBuffer, size_t cbBuffer,
647 size_t *pcbRead)
648{
649 return pIfIo->pfnReadSync(pIfIo->Core.pvUser, pStorage, uOffset,
650 pvBuffer, cbBuffer, pcbRead);
651}
652
653DECLINLINE(int) vdIfIoFileFlushSync(PVDINTERFACEIO pIfIo, void *pStorage)
654{
655 return pIfIo->pfnFlushSync(pIfIo->Core.pvUser, pStorage);
656}
657
658/**
659 * Create a VFS stream handle around a VD I/O interface.
660 *
661 * The I/O interface will not be closed or free by the stream, the caller will
662 * do so after it is done with the stream and has released the instances of the
663 * I/O stream object returned by this API.
664 *
665 * @return VBox status code.
666 * @param pVDIfsIo Pointer to the VD I/O interface.
667 * @param pvStorage The storage argument to pass to the interface
668 * methods.
669 * @param fFlags RTFILE_O_XXX, access mask requied.
670 * @param phVfsIos Where to return the VFS I/O stream handle on
671 * success.
672 */
673VBOXDDU_DECL(int) VDIfCreateVfsStream(PVDINTERFACEIO pVDIfsIo, void *pvStorage, uint32_t fFlags, PRTVFSIOSTREAM phVfsIos);
674
675struct VDINTERFACEIOINT;
676
677/**
678 * Create a VFS file handle around a VD I/O interface.
679 *
680 * The I/O interface will not be closed or free by the VFS file, the caller will
681 * do so after it is done with the VFS file and has released the instances of
682 * the VFS object returned by this API.
683 *
684 * @return VBox status code.
685 * @param pVDIfs Pointer to the VD I/O interface. If NULL, then @a
686 * pVDIfsInt must be specified.
687 * @param pVDIfsInt Pointer to the internal VD I/O interface. If NULL,
688 * then @ pVDIfs must be specified.
689 * @param pvStorage The storage argument to pass to the interface
690 * methods.
691 * @param fFlags RTFILE_O_XXX, access mask requied.
692 * @param phVfsFile Where to return the VFS file handle on success.
693 */
694VBOXDDU_DECL(int) VDIfCreateVfsFile(PVDINTERFACEIO pVDIfs, struct VDINTERFACEIOINT *pVDIfsInt, void *pvStorage,
695 uint32_t fFlags, PRTVFSFILE phVfsFile);
696
697/**
698 * Creates an VD I/O interface wrapper around an IPRT VFS I/O stream.
699 *
700 * @return VBox status code.
701 * @param hVfsIos The IPRT VFS I/O stream handle. The handle will be
702 * retained by the returned I/O interface (released on
703 * close or destruction).
704 * @param fAccessMode The access mode (RTFILE_O_ACCESS_MASK) to accept.
705 * @param ppIoIf Where to return the pointer to the VD I/O interface.
706 * This must be passed to VDIfDestroyFromVfsStream().
707 */
708VBOXDDU_DECL(int) VDIfCreateFromVfsStream(RTVFSIOSTREAM hVfsIos, uint32_t fAccessMode, PVDINTERFACEIO *ppIoIf);
709
710/**
711 * Destroys the VD I/O interface returned by VDIfCreateFromVfsStream.
712 *
713 * @returns VBox status code.
714 * @param pIoIf The I/O interface pointer returned by
715 * VDIfCreateFromVfsStream. NULL will be quietly
716 * ignored.
717 */
718VBOXDDU_DECL(int) VDIfDestroyFromVfsStream(PVDINTERFACEIO pIoIf);
719
720
721/**
722 * Callback which provides progress information about a currently running
723 * lengthy operation.
724 *
725 * @return VBox status code.
726 * @param pvUser The opaque user data associated with this interface.
727 * @param uPercentage Completion percentage.
728 */
729typedef DECLCALLBACKTYPE(int, FNVDPROGRESS,(void *pvUser, unsigned uPercentage));
730/** Pointer to FNVDPROGRESS() */
731typedef FNVDPROGRESS *PFNVDPROGRESS;
732
733/**
734 * Progress notification interface
735 *
736 * Per-operation. Optional.
737 */
738typedef struct VDINTERFACEPROGRESS
739{
740 /**
741 * Common interface header.
742 */
743 VDINTERFACE Core;
744
745 /**
746 * Progress notification callbacks.
747 */
748 PFNVDPROGRESS pfnProgress;
749
750} VDINTERFACEPROGRESS, *PVDINTERFACEPROGRESS;
751
752/** Initializer for VDINTERFACEPROGRESS. */
753#define VDINTERFACEPROGRESS_INITALIZER(a_pfnProgress) { { 0, NULL, NULL, VDINTERFACETYPE_INVALID, 0, NULL }, a_pfnProgress }
754
755/**
756 * Get progress interface from interface list.
757 *
758 * @return Pointer to the first progress interface in the list.
759 * @param pVDIfs Pointer to the interface list.
760 */
761DECLINLINE(PVDINTERFACEPROGRESS) VDIfProgressGet(PVDINTERFACE pVDIfs)
762{
763 PVDINTERFACE pIf = VDInterfaceGet(pVDIfs, VDINTERFACETYPE_PROGRESS);
764
765 /* Check that the interface descriptor is a progress interface. */
766 AssertMsgReturn( !pIf
767 || ( (pIf->enmInterface == VDINTERFACETYPE_PROGRESS)
768 && (pIf->cbSize == sizeof(VDINTERFACEPROGRESS))),
769 ("Not a progress interface"), NULL);
770
771 return (PVDINTERFACEPROGRESS)pIf;
772}
773
774/**
775 * Signal new progress information to the frontend.
776 *
777 * @returns VBox status code.
778 * @param pIfProgress The progress interface.
779 * @param uPercentage Completion percentage.
780 */
781DECLINLINE(int) vdIfProgress(PVDINTERFACEPROGRESS pIfProgress, unsigned uPercentage)
782{
783 if (pIfProgress)
784 return pIfProgress->pfnProgress(pIfProgress->Core.pvUser, uPercentage);
785 return VINF_SUCCESS;
786}
787
788/**
789 * Configuration information interface
790 *
791 * Per-image. Optional for most backends, but mandatory for images which do
792 * not operate on files (including standard block or character devices).
793 */
794typedef struct VDINTERFACECONFIG
795{
796 /**
797 * Common interface header.
798 */
799 VDINTERFACE Core;
800
801 /**
802 * Validates that the keys are within a set of valid names.
803 *
804 * @return true if all key names are found in pszzAllowed.
805 * @return false if not.
806 * @param pvUser The opaque user data associated with this interface.
807 * @param pszzValid List of valid key names separated by '\\0' and ending with
808 * a double '\\0'.
809 */
810 DECLR3CALLBACKMEMBER(bool, pfnAreKeysValid, (void *pvUser, const char *pszzValid));
811
812 /**
813 * Retrieves the length of the string value associated with a key (including
814 * the terminator, for compatibility with CFGMR3QuerySize).
815 *
816 * @return VBox status code.
817 * VERR_CFGM_VALUE_NOT_FOUND means that the key is not known.
818 * @param pvUser The opaque user data associated with this interface.
819 * @param pszName Name of the key to query.
820 * @param pcbValue Where to store the value length. Non-NULL.
821 */
822 DECLR3CALLBACKMEMBER(int, pfnQuerySize, (void *pvUser, const char *pszName, size_t *pcbValue));
823
824 /**
825 * Query the string value associated with a key.
826 *
827 * @return VBox status code.
828 * VERR_CFGM_VALUE_NOT_FOUND means that the key is not known.
829 * VERR_CFGM_NOT_ENOUGH_SPACE means that the buffer is not big enough.
830 * @param pvUser The opaque user data associated with this interface.
831 * @param pszName Name of the key to query.
832 * @param pszValue Pointer to buffer where to store value.
833 * @param cchValue Length of value buffer.
834 */
835 DECLR3CALLBACKMEMBER(int, pfnQuery, (void *pvUser, const char *pszName, char *pszValue, size_t cchValue));
836
837 /**
838 * Query the bytes value associated with a key.
839 *
840 * @return VBox status code.
841 * VERR_CFGM_VALUE_NOT_FOUND means that the key is not known.
842 * VERR_CFGM_NOT_ENOUGH_SPACE means that the buffer is not big enough.
843 * @param pvUser The opaque user data associated with this interface.
844 * @param pszName Name of the key to query.
845 * @param ppvData Pointer to buffer where to store the data.
846 * @param cbData Length of data buffer.
847 */
848 DECLR3CALLBACKMEMBER(int, pfnQueryBytes, (void *pvUser, const char *pszName, void *ppvData, size_t cbData));
849
850 /**
851 * Set a named property to a specified string value, optionally creating if it doesn't exist.
852 *
853 * @return VBox status code.
854 * VERR_CFGM_VALUE_NOT_FOUND means that the key is not known and fCreate flag was not set.
855 * @param pvUser The opaque user data associated with this interface.
856 * @param fCreate Create property if it doesn't exist (if property exists, it is not an error)
857 * @param pszName Name of the key to query.
858 * @param pszValue String value to set the name property to.
859 */
860 DECLR3CALLBACKMEMBER(int, pfnUpdate, (void *pvUser, bool fCreate,
861 const char *pszName, const char *pszValue));
862
863} VDINTERFACECONFIG, *PVDINTERFACECONFIG;
864
865/**
866 * Get configuration information interface from interface list.
867 *
868 * @return Pointer to the first configuration information interface in the list.
869 * @param pVDIfs Pointer to the interface list.
870 */
871DECLINLINE(PVDINTERFACECONFIG) VDIfConfigGet(PVDINTERFACE pVDIfs)
872{
873 PVDINTERFACE pIf = VDInterfaceGet(pVDIfs, VDINTERFACETYPE_CONFIG);
874
875 /* Check that the interface descriptor is a progress interface. */
876 AssertMsgReturn( !pIf
877 || ( (pIf->enmInterface == VDINTERFACETYPE_CONFIG)
878 && (pIf->cbSize == sizeof(VDINTERFACECONFIG))),
879 ("Not a config interface"), NULL);
880
881 return (PVDINTERFACECONFIG)pIf;
882}
883
884/**
885 * Query configuration, validates that the keys are within a set of valid names.
886 *
887 * @return true if all key names are found in pszzAllowed.
888 * @return false if not.
889 * @param pCfgIf Pointer to configuration callback table.
890 * @param pszzValid List of valid names separated by '\\0' and ending with
891 * a double '\\0'.
892 */
893DECLINLINE(bool) VDCFGAreKeysValid(PVDINTERFACECONFIG pCfgIf, const char *pszzValid)
894{
895 return pCfgIf->pfnAreKeysValid(pCfgIf->Core.pvUser, pszzValid);
896}
897
898/**
899 * Checks whether a given key is existing.
900 *
901 * @return true if the key exists.
902 * @return false if the key does not exist.
903 * @param pCfgIf Pointer to configuration callback table.
904 * @param pszName Name of the key.
905 */
906DECLINLINE(bool) VDCFGIsKeyExisting(PVDINTERFACECONFIG pCfgIf, const char *pszName)
907{
908 size_t cb = 0;
909 int rc = pCfgIf->pfnQuerySize(pCfgIf->Core.pvUser, pszName, &cb);
910 return rc == VERR_CFGM_VALUE_NOT_FOUND ? false : true;
911}
912
913/**
914 * Query configuration, unsigned 64-bit integer value with default.
915 *
916 * @return VBox status code.
917 * @param pCfgIf Pointer to configuration callback table.
918 * @param pszName Name of an integer value
919 * @param pu64 Where to store the value. Set to default on failure.
920 * @param u64Def The default value.
921 */
922DECLINLINE(int) VDCFGQueryU64Def(PVDINTERFACECONFIG pCfgIf,
923 const char *pszName, uint64_t *pu64,
924 uint64_t u64Def)
925{
926 char aszBuf[32];
927 int rc = pCfgIf->pfnQuery(pCfgIf->Core.pvUser, pszName, aszBuf, sizeof(aszBuf));
928 if (RT_SUCCESS(rc))
929 {
930 rc = RTStrToUInt64Full(aszBuf, 0, pu64);
931 }
932 else if (rc == VERR_CFGM_VALUE_NOT_FOUND)
933 {
934 rc = VINF_SUCCESS;
935 *pu64 = u64Def;
936 }
937 return rc;
938}
939
940/**
941 * Query configuration, unsigned 64-bit integer value.
942 *
943 * @return VBox status code.
944 * @param pCfgIf Pointer to configuration callback table.
945 * @param pszName Name of an integer value
946 * @param pu64 Where to store the value.
947 */
948DECLINLINE(int) VDCFGQueryU64(PVDINTERFACECONFIG pCfgIf, const char *pszName,
949 uint64_t *pu64)
950{
951 char aszBuf[32];
952 int rc = pCfgIf->pfnQuery(pCfgIf->Core.pvUser, pszName, aszBuf, sizeof(aszBuf));
953 if (RT_SUCCESS(rc))
954 {
955 rc = RTStrToUInt64Full(aszBuf, 0, pu64);
956 }
957
958 return rc;
959}
960
961/**
962 * Query configuration, unsigned 32-bit integer value with default.
963 *
964 * @return VBox status code.
965 * @param pCfgIf Pointer to configuration callback table.
966 * @param pszName Name of an integer value
967 * @param pu32 Where to store the value. Set to default on failure.
968 * @param u32Def The default value.
969 */
970DECLINLINE(int) VDCFGQueryU32Def(PVDINTERFACECONFIG pCfgIf,
971 const char *pszName, uint32_t *pu32,
972 uint32_t u32Def)
973{
974 uint64_t u64;
975 int rc = VDCFGQueryU64Def(pCfgIf, pszName, &u64, u32Def);
976 if (RT_SUCCESS(rc))
977 {
978 if (!(u64 & UINT64_C(0xffffffff00000000)))
979 *pu32 = (uint32_t)u64;
980 else
981 rc = VERR_CFGM_INTEGER_TOO_BIG;
982 }
983 return rc;
984}
985
986/**
987 * Query configuration, bool value with default.
988 *
989 * @return VBox status code.
990 * @param pCfgIf Pointer to configuration callback table.
991 * @param pszName Name of an integer value
992 * @param pf Where to store the value. Set to default on failure.
993 * @param fDef The default value.
994 */
995DECLINLINE(int) VDCFGQueryBoolDef(PVDINTERFACECONFIG pCfgIf,
996 const char *pszName, bool *pf,
997 bool fDef)
998{
999 uint64_t u64;
1000 int rc = VDCFGQueryU64Def(pCfgIf, pszName, &u64, fDef);
1001 if (RT_SUCCESS(rc))
1002 *pf = u64 ? true : false;
1003 return rc;
1004}
1005
1006/**
1007 * Query configuration, bool value.
1008 *
1009 * @return VBox status code.
1010 * @param pCfgIf Pointer to configuration callback table.
1011 * @param pszName Name of an integer value
1012 * @param pf Where to store the value.
1013 */
1014DECLINLINE(int) VDCFGQueryBool(PVDINTERFACECONFIG pCfgIf, const char *pszName,
1015 bool *pf)
1016{
1017 uint64_t u64;
1018 int rc = VDCFGQueryU64(pCfgIf, pszName, &u64);
1019 if (RT_SUCCESS(rc))
1020 *pf = u64 ? true : false;
1021 return rc;
1022}
1023
1024/**
1025 * Query configuration, dynamically allocated (RTMemAlloc) zero terminated
1026 * character value.
1027 *
1028 * @return VBox status code.
1029 * @param pCfgIf Pointer to configuration callback table.
1030 * @param pszName Name of an zero terminated character value
1031 * @param ppszString Where to store the string pointer. Not set on failure.
1032 * Free this using RTMemFree().
1033 */
1034DECLINLINE(int) VDCFGQueryStringAlloc(PVDINTERFACECONFIG pCfgIf,
1035 const char *pszName, char **ppszString)
1036{
1037 size_t cb;
1038 int rc = pCfgIf->pfnQuerySize(pCfgIf->Core.pvUser, pszName, &cb);
1039 if (RT_SUCCESS(rc))
1040 {
1041 char *pszString = (char *)RTMemAlloc(cb);
1042 if (pszString)
1043 {
1044 rc = pCfgIf->pfnQuery(pCfgIf->Core.pvUser, pszName, pszString, cb);
1045 if (RT_SUCCESS(rc))
1046 *ppszString = pszString;
1047 else
1048 RTMemFree(pszString);
1049 }
1050 else
1051 rc = VERR_NO_MEMORY;
1052 }
1053 return rc;
1054}
1055
1056/**
1057 * Query configuration, dynamically allocated (RTMemAlloc) zero terminated
1058 * character value with default.
1059 *
1060 * @return VBox status code.
1061 * @param pCfgIf Pointer to configuration callback table.
1062 * @param pszName Name of an zero terminated character value
1063 * @param ppszString Where to store the string pointer. Not set on failure.
1064 * Free this using RTMemFree().
1065 * @param pszDef The default value.
1066 */
1067DECLINLINE(int) VDCFGQueryStringAllocDef(PVDINTERFACECONFIG pCfgIf,
1068 const char *pszName,
1069 char **ppszString,
1070 const char *pszDef)
1071{
1072 size_t cb;
1073 int rc = pCfgIf->pfnQuerySize(pCfgIf->Core.pvUser, pszName, &cb);
1074 if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)
1075 {
1076 cb = strlen(pszDef) + 1;
1077 rc = VINF_SUCCESS;
1078 }
1079 if (RT_SUCCESS(rc))
1080 {
1081 char *pszString = (char *)RTMemAlloc(cb);
1082 if (pszString)
1083 {
1084 rc = pCfgIf->pfnQuery(pCfgIf->Core.pvUser, pszName, pszString, cb);
1085 if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)
1086 {
1087 memcpy(pszString, pszDef, cb);
1088 rc = VINF_SUCCESS;
1089 }
1090 if (RT_SUCCESS(rc))
1091 *ppszString = pszString;
1092 else
1093 RTMemFree(pszString);
1094 }
1095 else
1096 rc = VERR_NO_MEMORY;
1097 }
1098 return rc;
1099}
1100
1101/**
1102 * Query configuration, dynamically allocated (RTMemAlloc) byte string value.
1103 *
1104 * @return VBox status code.
1105 * @param pCfgIf Pointer to configuration callback table.
1106 * @param pszName Name of an zero terminated character value
1107 * @param ppvData Where to store the byte string pointer. Not set on failure.
1108 * Free this using RTMemFree().
1109 * @param pcbData Where to store the byte string length.
1110 */
1111DECLINLINE(int) VDCFGQueryBytesAlloc(PVDINTERFACECONFIG pCfgIf,
1112 const char *pszName, void **ppvData, size_t *pcbData)
1113{
1114 size_t cb;
1115 int rc = pCfgIf->pfnQuerySize(pCfgIf->Core.pvUser, pszName, &cb);
1116 if (RT_SUCCESS(rc))
1117 {
1118 char *pbData;
1119 Assert(cb);
1120
1121 pbData = (char *)RTMemAlloc(cb);
1122 if (pbData)
1123 {
1124 if(pCfgIf->pfnQueryBytes)
1125 rc = pCfgIf->pfnQueryBytes(pCfgIf->Core.pvUser, pszName, pbData, cb);
1126 else
1127 rc = pCfgIf->pfnQuery(pCfgIf->Core.pvUser, pszName, pbData, cb);
1128
1129 if (RT_SUCCESS(rc))
1130 {
1131 *ppvData = pbData;
1132 /* Exclude terminator if the byte data was obtained using the string query callback. */
1133 *pcbData = cb;
1134 if (!pCfgIf->pfnQueryBytes)
1135 (*pcbData)--;
1136 }
1137 else
1138 RTMemFree(pbData);
1139 }
1140 else
1141 rc = VERR_NO_MEMORY;
1142 }
1143 return rc;
1144}
1145
1146/**
1147 * Set property value to string (optionally create if non-existent).
1148 *
1149 * @return VBox status code.
1150 * @param pCfgIf Pointer to configuration callback table.
1151 * @param fCreate Create the property if it doesn't exist
1152 * @param pszName Name of property
1153 * @param pszValue String value to assign to property
1154 */
1155DECLINLINE(int) VDCFGUpdate(PVDINTERFACECONFIG pCfgIf, bool fCreate, const char *pszName, const char *pszValue)
1156{
1157 int rc = pCfgIf->pfnUpdate(pCfgIf->Core.pvUser, fCreate, pszName, pszValue);
1158 return rc;
1159}
1160
1161/**
1162 * Set property value to Unsigned Int 64-bit (optionally create if non-existent).
1163 *
1164 * @return VBox status code.
1165 * @param pCfgIf Pointer to configuration callback table.
1166 * @param fCreate Create the property if it doesn't exist
1167 * @param pszName Name of property
1168 * @param u64Value 64-bit unsigned value to save with property.
1169 */
1170
1171DECLINLINE(int) VDCFGUpdateU64(PVDINTERFACECONFIG pCfgIf, bool fCreate, const char *pszName, uint64_t u64Value)
1172{
1173 int rc = 0;
1174 char pszValue[21];
1175 (void) RTStrPrintf(pszValue, sizeof(pszValue), "%RU64", u64Value);
1176 rc = VDCFGUpdate(pCfgIf, fCreate, pszName, pszValue);
1177 return rc;
1178}
1179
1180
1181
1182/** Forward declaration of a VD socket. */
1183typedef struct VDSOCKETINT *VDSOCKET;
1184/** Pointer to a VD socket. */
1185typedef VDSOCKET *PVDSOCKET;
1186/** Nil socket handle. */
1187#define NIL_VDSOCKET ((VDSOCKET)0)
1188
1189/** Connect flag to indicate that the backend wants to use the extended
1190 * socket I/O multiplexing call. This might not be supported on all configurations
1191 * (internal networking and iSCSI)
1192 * and the backend needs to take appropriate action.
1193 */
1194#define VD_INTERFACETCPNET_CONNECT_EXTENDED_SELECT RT_BIT_32(0)
1195
1196/** @name Select events
1197 * @{ */
1198/** Readable without blocking. */
1199#define VD_INTERFACETCPNET_EVT_READ RT_BIT_32(0)
1200/** Writable without blocking. */
1201#define VD_INTERFACETCPNET_EVT_WRITE RT_BIT_32(1)
1202/** Error condition, hangup, exception or similar. */
1203#define VD_INTERFACETCPNET_EVT_ERROR RT_BIT_32(2)
1204/** Hint for the select that getting interrupted while waiting is more likely.
1205 * The interface implementation can optimize the waiting strategy based on this.
1206 * It is assumed that it is more likely to get one of the above socket events
1207 * instead of being interrupted if the flag is not set. */
1208#define VD_INTERFACETCPNET_HINT_INTERRUPT RT_BIT_32(3)
1209/** Mask of the valid bits. */
1210#define VD_INTERFACETCPNET_EVT_VALID_MASK UINT32_C(0x0000000f)
1211/** @} */
1212
1213/**
1214 * TCP network stack interface
1215 *
1216 * Per-image. Mandatory for backends which have the VD_CAP_TCPNET bit set.
1217 */
1218typedef struct VDINTERFACETCPNET
1219{
1220 /**
1221 * Common interface header.
1222 */
1223 VDINTERFACE Core;
1224
1225 /**
1226 * Creates a socket. The socket is not connected if this succeeds.
1227 *
1228 * @return iprt status code.
1229 * @retval VERR_NOT_SUPPORTED if the combination of flags is not supported.
1230 * @param fFlags Combination of the VD_INTERFACETCPNET_CONNECT_* \#defines.
1231 * @param phVdSock Where to store the handle.
1232 */
1233 DECLR3CALLBACKMEMBER(int, pfnSocketCreate, (uint32_t fFlags, PVDSOCKET phVdSock));
1234
1235 /**
1236 * Destroys the socket.
1237 *
1238 * @return iprt status code.
1239 * @param hVdSock Socket handle (/ pointer).
1240 */
1241 DECLR3CALLBACKMEMBER(int, pfnSocketDestroy, (VDSOCKET hVdSock));
1242
1243 /**
1244 * Connect as a client to a TCP port.
1245 *
1246 * @return iprt status code.
1247 * @param hVdSock Socket handle (/ pointer)..
1248 * @param pszAddress The address to connect to.
1249 * @param uPort The port to connect to.
1250 * @param cMillies Number of milliseconds to wait for the connect attempt to complete.
1251 * Use RT_INDEFINITE_WAIT to wait for ever.
1252 * Use RT_SOCKETCONNECT_DEFAULT_WAIT to wait for the default time
1253 * configured on the running system.
1254 */
1255 DECLR3CALLBACKMEMBER(int, pfnClientConnect, (VDSOCKET hVdSock, const char *pszAddress, uint32_t uPort,
1256 RTMSINTERVAL cMillies));
1257
1258 /**
1259 * Close a TCP connection.
1260 *
1261 * @return iprt status code.
1262 * @param hVdSock Socket handle (/ pointer).
1263 */
1264 DECLR3CALLBACKMEMBER(int, pfnClientClose, (VDSOCKET hVdSock));
1265
1266 /**
1267 * Returns whether the socket is currently connected to the client.
1268 *
1269 * @returns true if the socket is connected.
1270 * false otherwise.
1271 * @param hVdSock Socket handle (/ pointer).
1272 */
1273 DECLR3CALLBACKMEMBER(bool, pfnIsClientConnected, (VDSOCKET hVdSock));
1274
1275 /**
1276 * Socket I/O multiplexing.
1277 * Checks if the socket is ready for reading.
1278 *
1279 * @return iprt status code.
1280 * @param hVdSock Socket handle (/ pointer).
1281 * @param cMillies Number of milliseconds to wait for the socket.
1282 * Use RT_INDEFINITE_WAIT to wait for ever.
1283 */
1284 DECLR3CALLBACKMEMBER(int, pfnSelectOne, (VDSOCKET hVdSock, RTMSINTERVAL cMillies));
1285
1286 /**
1287 * Receive data from a socket.
1288 *
1289 * @return iprt status code.
1290 * @param hVdSock Socket handle (/ pointer).
1291 * @param pvBuffer Where to put the data we read.
1292 * @param cbBuffer Read buffer size.
1293 * @param pcbRead Number of bytes read.
1294 * If NULL the entire buffer will be filled upon successful return.
1295 * If not NULL a partial read can be done successfully.
1296 */
1297 DECLR3CALLBACKMEMBER(int, pfnRead, (VDSOCKET hVdSock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead));
1298
1299 /**
1300 * Send data to a socket.
1301 *
1302 * @return iprt status code.
1303 * @param hVdSock Socket handle (/ pointer).
1304 * @param pvBuffer Buffer to write data to socket.
1305 * @param cbBuffer How much to write.
1306 */
1307 DECLR3CALLBACKMEMBER(int, pfnWrite, (VDSOCKET hVdSock, const void *pvBuffer, size_t cbBuffer));
1308
1309 /**
1310 * Send data from scatter/gather buffer to a socket.
1311 *
1312 * @return iprt status code.
1313 * @param hVdSock Socket handle (/ pointer).
1314 * @param pSgBuf Scatter/gather buffer to write data to socket.
1315 */
1316 DECLR3CALLBACKMEMBER(int, pfnSgWrite, (VDSOCKET hVdSock, PCRTSGBUF pSgBuf));
1317
1318 /**
1319 * Receive data from a socket - not blocking.
1320 *
1321 * @return iprt status code.
1322 * @param hVdSock Socket handle (/ pointer).
1323 * @param pvBuffer Where to put the data we read.
1324 * @param cbBuffer Read buffer size.
1325 * @param pcbRead Number of bytes read.
1326 */
1327 DECLR3CALLBACKMEMBER(int, pfnReadNB, (VDSOCKET hVdSock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead));
1328
1329 /**
1330 * Send data to a socket - not blocking.
1331 *
1332 * @return iprt status code.
1333 * @param hVdSock Socket handle (/ pointer).
1334 * @param pvBuffer Buffer to write data to socket.
1335 * @param cbBuffer How much to write.
1336 * @param pcbWritten Number of bytes written.
1337 */
1338 DECLR3CALLBACKMEMBER(int, pfnWriteNB, (VDSOCKET hVdSock, const void *pvBuffer, size_t cbBuffer, size_t *pcbWritten));
1339
1340 /**
1341 * Send data from scatter/gather buffer to a socket - not blocking.
1342 *
1343 * @return iprt status code.
1344 * @param hVdSock Socket handle (/ pointer).
1345 * @param pSgBuf Scatter/gather buffer to write data to socket.
1346 * @param pcbWritten Number of bytes written.
1347 */
1348 DECLR3CALLBACKMEMBER(int, pfnSgWriteNB, (VDSOCKET hVdSock, PRTSGBUF pSgBuf, size_t *pcbWritten));
1349
1350 /**
1351 * Flush socket write buffers.
1352 *
1353 * @return iprt status code.
1354 * @param hVdSock Socket handle (/ pointer).
1355 */
1356 DECLR3CALLBACKMEMBER(int, pfnFlush, (VDSOCKET hVdSock));
1357
1358 /**
1359 * Enables or disables delaying sends to coalesce packets.
1360 *
1361 * @return iprt status code.
1362 * @param hVdSock Socket handle (/ pointer).
1363 * @param fEnable When set to true enables coalescing.
1364 */
1365 DECLR3CALLBACKMEMBER(int, pfnSetSendCoalescing, (VDSOCKET hVdSock, bool fEnable));
1366
1367 /**
1368 * Gets the address of the local side.
1369 *
1370 * @return iprt status code.
1371 * @param hVdSock Socket handle (/ pointer).
1372 * @param pAddr Where to store the local address on success.
1373 */
1374 DECLR3CALLBACKMEMBER(int, pfnGetLocalAddress, (VDSOCKET hVdSock, PRTNETADDR pAddr));
1375
1376 /**
1377 * Gets the address of the other party.
1378 *
1379 * @return iprt status code.
1380 * @param hVdSock Socket handle (/ pointer).
1381 * @param pAddr Where to store the peer address on success.
1382 */
1383 DECLR3CALLBACKMEMBER(int, pfnGetPeerAddress, (VDSOCKET hVdSock, PRTNETADDR pAddr));
1384
1385 /**
1386 * Socket I/O multiplexing - extended version which can be woken up.
1387 * Checks if the socket is ready for reading or writing.
1388 *
1389 * @return iprt status code.
1390 * @retval VERR_INTERRUPTED if the thread was woken up by a pfnPoke call.
1391 * @param hVdSock VD Socket handle(/pointer).
1392 * @param fEvents Mask of events to wait for.
1393 * @param pfEvents Where to store the received events.
1394 * @param cMillies Number of milliseconds to wait for the socket.
1395 * Use RT_INDEFINITE_WAIT to wait for ever.
1396 */
1397 DECLR3CALLBACKMEMBER(int, pfnSelectOneEx, (VDSOCKET hVdSock, uint32_t fEvents,
1398 uint32_t *pfEvents, RTMSINTERVAL cMillies));
1399
1400 /**
1401 * Wakes up the thread waiting in pfnSelectOneEx.
1402 *
1403 * @return iprt status code.
1404 * @param hVdSock VD Socket handle(/pointer).
1405 */
1406 DECLR3CALLBACKMEMBER(int, pfnPoke, (VDSOCKET hVdSock));
1407
1408} VDINTERFACETCPNET, *PVDINTERFACETCPNET;
1409
1410/**
1411 * Get TCP network stack interface from interface list.
1412 *
1413 * @return Pointer to the first TCP network stack interface in the list.
1414 * @param pVDIfs Pointer to the interface list.
1415 */
1416DECLINLINE(PVDINTERFACETCPNET) VDIfTcpNetGet(PVDINTERFACE pVDIfs)
1417{
1418 PVDINTERFACE pIf = VDInterfaceGet(pVDIfs, VDINTERFACETYPE_TCPNET);
1419
1420 /* Check that the interface descriptor is a progress interface. */
1421 AssertMsgReturn( !pIf
1422 || ( (pIf->enmInterface == VDINTERFACETYPE_TCPNET)
1423 && (pIf->cbSize == sizeof(VDINTERFACETCPNET))),
1424 ("Not a TCP net interface"), NULL);
1425
1426 return (PVDINTERFACETCPNET)pIf;
1427}
1428
1429
1430/**
1431 * Interface to synchronize concurrent accesses by several threads.
1432 *
1433 * @note The scope of this interface is to manage concurrent accesses after
1434 * the HDD container has been created, and they must stop before destroying the
1435 * container. Opening or closing images is covered by the synchronization, but
1436 * that does not mean it is safe to close images while a thread executes
1437 * #VDMerge or #VDCopy operating on these images. Making them safe would require
1438 * the lock to be held during the entire operation, which prevents other
1439 * concurrent acitivities.
1440 *
1441 * @note Right now this is kept as simple as possible, and does not even
1442 * attempt to provide enough information to allow e.g. concurrent write
1443 * accesses to different areas of the disk. The reason is that it is very
1444 * difficult to predict which area of a disk is affected by a write,
1445 * especially when different image formats are mixed. Maybe later a more
1446 * sophisticated interface will be provided which has the necessary information
1447 * about worst case affected areas.
1448 *
1449 * Per-disk interface. Optional, needed if the disk is accessed concurrently
1450 * by several threads, e.g. when merging diff images while a VM is running.
1451 */
1452typedef struct VDINTERFACETHREADSYNC
1453{
1454 /**
1455 * Common interface header.
1456 */
1457 VDINTERFACE Core;
1458
1459 /**
1460 * Start a read operation.
1461 */
1462 DECLR3CALLBACKMEMBER(int, pfnStartRead, (void *pvUser));
1463
1464 /**
1465 * Finish a read operation.
1466 */
1467 DECLR3CALLBACKMEMBER(int, pfnFinishRead, (void *pvUser));
1468
1469 /**
1470 * Start a write operation.
1471 */
1472 DECLR3CALLBACKMEMBER(int, pfnStartWrite, (void *pvUser));
1473
1474 /**
1475 * Finish a write operation.
1476 */
1477 DECLR3CALLBACKMEMBER(int, pfnFinishWrite, (void *pvUser));
1478
1479} VDINTERFACETHREADSYNC, *PVDINTERFACETHREADSYNC;
1480
1481/**
1482 * Get thread synchronization interface from interface list.
1483 *
1484 * @return Pointer to the first thread synchronization interface in the list.
1485 * @param pVDIfs Pointer to the interface list.
1486 */
1487DECLINLINE(PVDINTERFACETHREADSYNC) VDIfThreadSyncGet(PVDINTERFACE pVDIfs)
1488{
1489 PVDINTERFACE pIf = VDInterfaceGet(pVDIfs, VDINTERFACETYPE_THREADSYNC);
1490
1491 /* Check that the interface descriptor is a progress interface. */
1492 AssertMsgReturn( !pIf
1493 || ( (pIf->enmInterface == VDINTERFACETYPE_THREADSYNC)
1494 && (pIf->cbSize == sizeof(VDINTERFACETHREADSYNC))),
1495 ("Not a thread synchronization interface"), NULL);
1496
1497 return (PVDINTERFACETHREADSYNC)pIf;
1498}
1499
1500/**
1501 * Interface to query usage of disk ranges.
1502 *
1503 * Per-operation interface. Optional.
1504 */
1505typedef struct VDINTERFACEQUERYRANGEUSE
1506{
1507 /**
1508 * Common interface header.
1509 */
1510 VDINTERFACE Core;
1511
1512 /**
1513 * Query use of a disk range.
1514 */
1515 DECLR3CALLBACKMEMBER(int, pfnQueryRangeUse, (void *pvUser, uint64_t off, uint64_t cb,
1516 bool *pfUsed));
1517
1518} VDINTERFACEQUERYRANGEUSE, *PVDINTERFACEQUERYRANGEUSE;
1519
1520/**
1521 * Get query range use interface from interface list.
1522 *
1523 * @return Pointer to the first thread synchronization interface in the list.
1524 * @param pVDIfs Pointer to the interface list.
1525 */
1526DECLINLINE(PVDINTERFACEQUERYRANGEUSE) VDIfQueryRangeUseGet(PVDINTERFACE pVDIfs)
1527{
1528 PVDINTERFACE pIf = VDInterfaceGet(pVDIfs, VDINTERFACETYPE_QUERYRANGEUSE);
1529
1530 /* Check that the interface descriptor is a progress interface. */
1531 AssertMsgReturn( !pIf
1532 || ( (pIf->enmInterface == VDINTERFACETYPE_QUERYRANGEUSE)
1533 && (pIf->cbSize == sizeof(VDINTERFACEQUERYRANGEUSE))),
1534 ("Not a query range use interface"), NULL);
1535
1536 return (PVDINTERFACEQUERYRANGEUSE)pIf;
1537}
1538
1539DECLINLINE(int) vdIfQueryRangeUse(PVDINTERFACEQUERYRANGEUSE pIfQueryRangeUse, uint64_t off, uint64_t cb,
1540 bool *pfUsed)
1541{
1542 return pIfQueryRangeUse->pfnQueryRangeUse(pIfQueryRangeUse->Core.pvUser, off, cb, pfUsed);
1543}
1544
1545
1546/**
1547 * Interface used to retrieve keys for cryptographic operations.
1548 *
1549 * Per-module interface. Optional but cryptographic modules might fail and
1550 * return an error if this is not present.
1551 */
1552typedef struct VDINTERFACECRYPTO
1553{
1554 /**
1555 * Common interface header.
1556 */
1557 VDINTERFACE Core;
1558
1559 /**
1560 * Retains a key identified by the ID. The caller will only hold a reference
1561 * to the key and must not modify the key buffer in any way.
1562 *
1563 * @returns VBox status code.
1564 * @param pvUser The opaque user data associated with this interface.
1565 * @param pszId The alias/id for the key to retrieve.
1566 * @param ppbKey Where to store the pointer to the key buffer on success.
1567 * @param pcbKey Where to store the size of the key in bytes on success.
1568 */
1569 DECLR3CALLBACKMEMBER(int, pfnKeyRetain, (void *pvUser, const char *pszId, const uint8_t **ppbKey, size_t *pcbKey));
1570
1571 /**
1572 * Releases one reference of the key identified by the given identifier.
1573 * The caller must not access the key buffer after calling this operation.
1574 *
1575 * @returns VBox status code.
1576 * @param pvUser The opaque user data associated with this interface.
1577 * @param pszId The alias/id for the key to release.
1578 *
1579 * @note It is advised to release the key whenever it is not used anymore so
1580 * the entity storing the key can do anything to make retrieving the key
1581 * from memory more difficult like scrambling the memory buffer for
1582 * instance.
1583 */
1584 DECLR3CALLBACKMEMBER(int, pfnKeyRelease, (void *pvUser, const char *pszId));
1585
1586 /**
1587 * Gets a reference to the password identified by the given ID to open a key store supplied through the config interface.
1588 *
1589 * @returns VBox status code.
1590 * @param pvUser The opaque user data associated with this interface.
1591 * @param pszId The alias/id for the password to retain.
1592 * @param ppszPassword Where to store the password to unlock the key store on success.
1593 */
1594 DECLR3CALLBACKMEMBER(int, pfnKeyStorePasswordRetain, (void *pvUser, const char *pszId, const char **ppszPassword));
1595
1596 /**
1597 * Releases a reference of the password previously acquired with VDINTERFACECRYPTO::pfnKeyStorePasswordRetain()
1598 * identified by the given ID.
1599 *
1600 * @returns VBox status code.
1601 * @param pvUser The opaque user data associated with this interface.
1602 * @param pszId The alias/id for the password to release.
1603 */
1604 DECLR3CALLBACKMEMBER(int, pfnKeyStorePasswordRelease, (void *pvUser, const char *pszId));
1605
1606 /**
1607 * Saves a key store.
1608 *
1609 * @returns VBox status code.
1610 * @param pvUser The opaque user data associated with this interface.
1611 * @param pvKeyStore The key store to save.
1612 * @param cbKeyStore Size of the key store in bytes.
1613 *
1614 * @note The format is filter specific and should be treated as binary data.
1615 */
1616 DECLR3CALLBACKMEMBER(int, pfnKeyStoreSave, (void *pvUser, const void *pvKeyStore, size_t cbKeyStore));
1617
1618 /**
1619 * Returns the parameters after the key store was loaded successfully.
1620 *
1621 * @returns VBox status code.
1622 * @param pvUser The opaque user data associated with this interface.
1623 * @param pszCipher The cipher identifier the DEK is used for.
1624 * @param pbDek The raw DEK which was contained in the key store loaded by
1625 * VDINTERFACECRYPTO::pfnKeyStoreLoad().
1626 * @param cbDek The size of the DEK.
1627 *
1628 * @note The provided pointer to the DEK is only valid until this call returns.
1629 * The content might change afterwards with out notice (when scrambling the key
1630 * for further protection for example) or might be even freed.
1631 *
1632 * @note This method is optional and can be NULL if the caller does not require the
1633 * parameters.
1634 */
1635 DECLR3CALLBACKMEMBER(int, pfnKeyStoreReturnParameters, (void *pvUser, const char *pszCipher,
1636 const uint8_t *pbDek, size_t cbDek));
1637
1638} VDINTERFACECRYPTO, *PVDINTERFACECRYPTO;
1639
1640
1641/**
1642 * Get error interface from interface list.
1643 *
1644 * @return Pointer to the first error interface in the list.
1645 * @param pVDIfs Pointer to the interface list.
1646 */
1647DECLINLINE(PVDINTERFACECRYPTO) VDIfCryptoGet(PVDINTERFACE pVDIfs)
1648{
1649 PVDINTERFACE pIf = VDInterfaceGet(pVDIfs, VDINTERFACETYPE_CRYPTO);
1650
1651 /* Check that the interface descriptor is a crypto interface. */
1652 AssertMsgReturn( !pIf
1653 || ( (pIf->enmInterface == VDINTERFACETYPE_CRYPTO)
1654 && (pIf->cbSize == sizeof(VDINTERFACECRYPTO))),
1655 ("Not an crypto interface\n"), NULL);
1656
1657 return (PVDINTERFACECRYPTO)pIf;
1658}
1659
1660/**
1661 * Retains a key identified by the ID. The caller will only hold a reference
1662 * to the key and must not modify the key buffer in any way.
1663 *
1664 * @returns VBox status code.
1665 * @param pIfCrypto Pointer to the crypto interface.
1666 * @param pszId The alias/id for the key to retrieve.
1667 * @param ppbKey Where to store the pointer to the key buffer on success.
1668 * @param pcbKey Where to store the size of the key in bytes on success.
1669 */
1670DECLINLINE(int) vdIfCryptoKeyRetain(PVDINTERFACECRYPTO pIfCrypto, const char *pszId, const uint8_t **ppbKey, size_t *pcbKey)
1671{
1672 return pIfCrypto->pfnKeyRetain(pIfCrypto->Core.pvUser, pszId, ppbKey, pcbKey);
1673}
1674
1675/**
1676 * Releases one reference of the key identified by the given identifier.
1677 * The caller must not access the key buffer after calling this operation.
1678 *
1679 * @returns VBox status code.
1680 * @param pIfCrypto Pointer to the crypto interface.
1681 * @param pszId The alias/id for the key to release.
1682 *
1683 * @note It is advised to release the key whenever it is not used anymore so
1684 * the entity storing the key can do anything to make retrieving the key
1685 * from memory more difficult like scrambling the memory buffer for
1686 * instance.
1687 */
1688DECLINLINE(int) vdIfCryptoKeyRelease(PVDINTERFACECRYPTO pIfCrypto, const char *pszId)
1689{
1690 return pIfCrypto->pfnKeyRelease(pIfCrypto->Core.pvUser, pszId);
1691}
1692
1693/**
1694 * Gets a reference to the password identified by the given ID to open a key store supplied through the config interface.
1695 *
1696 * @returns VBox status code.
1697 * @param pIfCrypto Pointer to the crypto interface.
1698 * @param pszId The alias/id for the password to retain.
1699 * @param ppszPassword Where to store the password to unlock the key store on success.
1700 */
1701DECLINLINE(int) vdIfCryptoKeyStorePasswordRetain(PVDINTERFACECRYPTO pIfCrypto, const char *pszId, const char **ppszPassword)
1702{
1703 return pIfCrypto->pfnKeyStorePasswordRetain(pIfCrypto->Core.pvUser, pszId, ppszPassword);
1704}
1705
1706/**
1707 * Releases a reference of the password previously acquired with VDINTERFACECRYPTO::pfnKeyStorePasswordRetain()
1708 * identified by the given ID.
1709 *
1710 * @returns VBox status code.
1711 * @param pIfCrypto Pointer to the crypto interface.
1712 * @param pszId The alias/id for the password to release.
1713 */
1714DECLINLINE(int) vdIfCryptoKeyStorePasswordRelease(PVDINTERFACECRYPTO pIfCrypto, const char *pszId)
1715{
1716 return pIfCrypto->pfnKeyStorePasswordRelease(pIfCrypto->Core.pvUser, pszId);
1717}
1718
1719/**
1720 * Saves a key store.
1721 *
1722 * @returns VBox status code.
1723 * @param pIfCrypto Pointer to the crypto interface.
1724 * @param pvKeyStore The key store to save.
1725 * @param cbKeyStore Size of the key store in bytes.
1726 *
1727 * @note The format is filter specific and should be treated as binary data.
1728 */
1729DECLINLINE(int) vdIfCryptoKeyStoreSave(PVDINTERFACECRYPTO pIfCrypto, const void *pvKeyStore, size_t cbKeyStore)
1730{
1731 return pIfCrypto->pfnKeyStoreSave(pIfCrypto->Core.pvUser, pvKeyStore, cbKeyStore);
1732}
1733
1734/**
1735 * Returns the parameters after the key store was loaded successfully.
1736 *
1737 * @returns VBox status code.
1738 * @param pIfCrypto Pointer to the crypto interface.
1739 * @param pszCipher The cipher identifier the DEK is used for.
1740 * @param pbDek The raw DEK which was contained in the key store loaded by
1741 * VDINTERFACECRYPTO::pfnKeyStoreLoad().
1742 * @param cbDek The size of the DEK.
1743 *
1744 * @note The provided pointer to the DEK is only valid until this call returns.
1745 * The content might change afterwards with out notice (when scrambling the key
1746 * for further protection for example) or might be even freed.
1747 *
1748 * @note This method is optional and can be NULL if the caller does not require the
1749 * parameters.
1750 */
1751DECLINLINE(int) vdIfCryptoKeyStoreReturnParameters(PVDINTERFACECRYPTO pIfCrypto, const char *pszCipher,
1752 const uint8_t *pbDek, size_t cbDek)
1753{
1754 if (pIfCrypto->pfnKeyStoreReturnParameters)
1755 return pIfCrypto->pfnKeyStoreReturnParameters(pIfCrypto->Core.pvUser, pszCipher, pbDek, cbDek);
1756
1757 return VINF_SUCCESS;
1758}
1759
1760
1761RT_C_DECLS_END
1762
1763/** @} */
1764
1765#endif /* !VBOX_INCLUDED_vd_ifs_h */
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