VirtualBox

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

最後變更 在這個檔案從58092是 58092,由 vboxsync 提交於 9 年 前

vd-ifs.h: VDINTERFACECRYPTO: Cannot use @copydoc when the parameters aren't the same (pIfCrypto vs pvUser), so gotta duplicate the documentation (or redesign the interface so the pvUser stuff is invisible, like we do for most of the other interfaces).

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 59.1 KB
 
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.alldomusa.eu.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 ppVDIfs Pointer to the VD interface list.
146 */
147DECLINLINE(int) VDInterfaceAdd(PVDINTERFACE pInterface, const char *pszName,
148 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 RT_SRC_POS_DECL 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 RT_SRC_POS_DECL 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 * <link to="VDMerge"/> or <link to="VDCopy"/> operating on these images.
1301 * Making them safe would require the lock to be held during the entire
1302 * operation, which prevents other 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
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette