VirtualBox

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

Last change on this file since 54506 was 54403, checked in by vboxsync, 10 years ago

Storage/VDFilterrypt,Main: Move key store implementation to the crypto filter plugin and make it accessible to Main from there by extending the interfaces to save key stores and query passwords for unlocking key stores

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