VirtualBox

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

Last change on this file since 91688 was 90792, checked in by vboxsync, 3 years ago

*: More VALID_PTR -> RT_VALID_PTR/AssertPtr.

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