VirtualBox

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

Last change on this file since 58371 was 58106, checked in by vboxsync, 9 years ago

include,misc: Corrected a bunch of doxygen errors.

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