VirtualBox

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

Last change on this file since 79853 was 79794, checked in by vboxsync, 5 years ago

include/VBox/vd-ifs.h: fix string buffer length and formatting for bugref:5899

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

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