VirtualBox

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

Last change on this file since 93922 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

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