VirtualBox

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

Last change on this file since 76507 was 76507, checked in by vboxsync, 6 years ago

/include: scm --fix-header-guards. bugref:9344

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 62.1 KB
Line 
1/** @file
2 * VD Container API - interfaces.
3 */
4
5/*
6 * Copyright (C) 2011-2017 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_ifs_h
27#define ___VBox_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} VDINTERFACECONFIG, *PVDINTERFACECONFIG;
832
833/**
834 * Get configuration information interface from interface list.
835 *
836 * @return Pointer to the first configuration information interface in the list.
837 * @param pVDIfs Pointer to the interface list.
838 */
839DECLINLINE(PVDINTERFACECONFIG) VDIfConfigGet(PVDINTERFACE pVDIfs)
840{
841 PVDINTERFACE pIf = VDInterfaceGet(pVDIfs, VDINTERFACETYPE_CONFIG);
842
843 /* Check that the interface descriptor is a progress interface. */
844 AssertMsgReturn( !pIf
845 || ( (pIf->enmInterface == VDINTERFACETYPE_CONFIG)
846 && (pIf->cbSize == sizeof(VDINTERFACECONFIG))),
847 ("Not a config interface"), NULL);
848
849 return (PVDINTERFACECONFIG)pIf;
850}
851
852/**
853 * Query configuration, validates that the keys are within a set of valid names.
854 *
855 * @return true if all key names are found in pszzAllowed.
856 * @return false if not.
857 * @param pCfgIf Pointer to configuration callback table.
858 * @param pszzValid List of valid names separated by '\\0' and ending with
859 * a double '\\0'.
860 */
861DECLINLINE(bool) VDCFGAreKeysValid(PVDINTERFACECONFIG pCfgIf, const char *pszzValid)
862{
863 return pCfgIf->pfnAreKeysValid(pCfgIf->Core.pvUser, pszzValid);
864}
865
866/**
867 * Checks whether a given key is existing.
868 *
869 * @return true if the key exists.
870 * @return false if the key does not exist.
871 * @param pCfgIf Pointer to configuration callback table.
872 * @param pszName Name of the key.
873 */
874DECLINLINE(bool) VDCFGIsKeyExisting(PVDINTERFACECONFIG pCfgIf, const char *pszName)
875{
876 size_t cb = 0;
877 int rc = pCfgIf->pfnQuerySize(pCfgIf->Core.pvUser, pszName, &cb);
878 return rc == VERR_CFGM_VALUE_NOT_FOUND ? false : true;
879}
880
881/**
882 * Query configuration, unsigned 64-bit integer value with default.
883 *
884 * @return VBox status code.
885 * @param pCfgIf Pointer to configuration callback table.
886 * @param pszName Name of an integer value
887 * @param pu64 Where to store the value. Set to default on failure.
888 * @param u64Def The default value.
889 */
890DECLINLINE(int) VDCFGQueryU64Def(PVDINTERFACECONFIG pCfgIf,
891 const char *pszName, uint64_t *pu64,
892 uint64_t u64Def)
893{
894 char aszBuf[32];
895 int rc = pCfgIf->pfnQuery(pCfgIf->Core.pvUser, pszName, aszBuf, sizeof(aszBuf));
896 if (RT_SUCCESS(rc))
897 {
898 rc = RTStrToUInt64Full(aszBuf, 0, pu64);
899 }
900 else if (rc == VERR_CFGM_VALUE_NOT_FOUND)
901 {
902 rc = VINF_SUCCESS;
903 *pu64 = u64Def;
904 }
905 return rc;
906}
907
908/**
909 * Query configuration, unsigned 64-bit integer value.
910 *
911 * @return VBox status code.
912 * @param pCfgIf Pointer to configuration callback table.
913 * @param pszName Name of an integer value
914 * @param pu64 Where to store the value.
915 */
916DECLINLINE(int) VDCFGQueryU64(PVDINTERFACECONFIG pCfgIf, const char *pszName,
917 uint64_t *pu64)
918{
919 char aszBuf[32];
920 int rc = pCfgIf->pfnQuery(pCfgIf->Core.pvUser, pszName, aszBuf, sizeof(aszBuf));
921 if (RT_SUCCESS(rc))
922 {
923 rc = RTStrToUInt64Full(aszBuf, 0, pu64);
924 }
925
926 return rc;
927}
928
929/**
930 * Query configuration, unsigned 32-bit integer value with default.
931 *
932 * @return VBox status code.
933 * @param pCfgIf Pointer to configuration callback table.
934 * @param pszName Name of an integer value
935 * @param pu32 Where to store the value. Set to default on failure.
936 * @param u32Def The default value.
937 */
938DECLINLINE(int) VDCFGQueryU32Def(PVDINTERFACECONFIG pCfgIf,
939 const char *pszName, uint32_t *pu32,
940 uint32_t u32Def)
941{
942 uint64_t u64;
943 int rc = VDCFGQueryU64Def(pCfgIf, pszName, &u64, u32Def);
944 if (RT_SUCCESS(rc))
945 {
946 if (!(u64 & UINT64_C(0xffffffff00000000)))
947 *pu32 = (uint32_t)u64;
948 else
949 rc = VERR_CFGM_INTEGER_TOO_BIG;
950 }
951 return rc;
952}
953
954/**
955 * Query configuration, bool value with default.
956 *
957 * @return VBox status code.
958 * @param pCfgIf Pointer to configuration callback table.
959 * @param pszName Name of an integer value
960 * @param pf Where to store the value. Set to default on failure.
961 * @param fDef The default value.
962 */
963DECLINLINE(int) VDCFGQueryBoolDef(PVDINTERFACECONFIG pCfgIf,
964 const char *pszName, bool *pf,
965 bool fDef)
966{
967 uint64_t u64;
968 int rc = VDCFGQueryU64Def(pCfgIf, pszName, &u64, fDef);
969 if (RT_SUCCESS(rc))
970 *pf = u64 ? true : false;
971 return rc;
972}
973
974/**
975 * Query configuration, bool value.
976 *
977 * @return VBox status code.
978 * @param pCfgIf Pointer to configuration callback table.
979 * @param pszName Name of an integer value
980 * @param pf Where to store the value.
981 */
982DECLINLINE(int) VDCFGQueryBool(PVDINTERFACECONFIG pCfgIf, const char *pszName,
983 bool *pf)
984{
985 uint64_t u64;
986 int rc = VDCFGQueryU64(pCfgIf, pszName, &u64);
987 if (RT_SUCCESS(rc))
988 *pf = u64 ? true : false;
989 return rc;
990}
991
992/**
993 * Query configuration, dynamically allocated (RTMemAlloc) zero terminated
994 * character value.
995 *
996 * @return VBox status code.
997 * @param pCfgIf Pointer to configuration callback table.
998 * @param pszName Name of an zero terminated character value
999 * @param ppszString Where to store the string pointer. Not set on failure.
1000 * Free this using RTMemFree().
1001 */
1002DECLINLINE(int) VDCFGQueryStringAlloc(PVDINTERFACECONFIG pCfgIf,
1003 const char *pszName, char **ppszString)
1004{
1005 size_t cb;
1006 int rc = pCfgIf->pfnQuerySize(pCfgIf->Core.pvUser, pszName, &cb);
1007 if (RT_SUCCESS(rc))
1008 {
1009 char *pszString = (char *)RTMemAlloc(cb);
1010 if (pszString)
1011 {
1012 rc = pCfgIf->pfnQuery(pCfgIf->Core.pvUser, pszName, pszString, cb);
1013 if (RT_SUCCESS(rc))
1014 *ppszString = pszString;
1015 else
1016 RTMemFree(pszString);
1017 }
1018 else
1019 rc = VERR_NO_MEMORY;
1020 }
1021 return rc;
1022}
1023
1024/**
1025 * Query configuration, dynamically allocated (RTMemAlloc) zero terminated
1026 * character value with default.
1027 *
1028 * @return VBox status code.
1029 * @param pCfgIf Pointer to configuration callback table.
1030 * @param pszName Name of an zero terminated character value
1031 * @param ppszString Where to store the string pointer. Not set on failure.
1032 * Free this using RTMemFree().
1033 * @param pszDef The default value.
1034 */
1035DECLINLINE(int) VDCFGQueryStringAllocDef(PVDINTERFACECONFIG pCfgIf,
1036 const char *pszName,
1037 char **ppszString,
1038 const char *pszDef)
1039{
1040 size_t cb;
1041 int rc = pCfgIf->pfnQuerySize(pCfgIf->Core.pvUser, pszName, &cb);
1042 if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)
1043 {
1044 cb = strlen(pszDef) + 1;
1045 rc = VINF_SUCCESS;
1046 }
1047 if (RT_SUCCESS(rc))
1048 {
1049 char *pszString = (char *)RTMemAlloc(cb);
1050 if (pszString)
1051 {
1052 rc = pCfgIf->pfnQuery(pCfgIf->Core.pvUser, pszName, pszString, cb);
1053 if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)
1054 {
1055 memcpy(pszString, pszDef, cb);
1056 rc = VINF_SUCCESS;
1057 }
1058 if (RT_SUCCESS(rc))
1059 *ppszString = pszString;
1060 else
1061 RTMemFree(pszString);
1062 }
1063 else
1064 rc = VERR_NO_MEMORY;
1065 }
1066 return rc;
1067}
1068
1069/**
1070 * Query configuration, dynamically allocated (RTMemAlloc) byte string value.
1071 *
1072 * @return VBox status code.
1073 * @param pCfgIf Pointer to configuration callback table.
1074 * @param pszName Name of an zero terminated character value
1075 * @param ppvData Where to store the byte string pointer. Not set on failure.
1076 * Free this using RTMemFree().
1077 * @param pcbData Where to store the byte string length.
1078 */
1079DECLINLINE(int) VDCFGQueryBytesAlloc(PVDINTERFACECONFIG pCfgIf,
1080 const char *pszName, void **ppvData, size_t *pcbData)
1081{
1082 size_t cb;
1083 int rc = pCfgIf->pfnQuerySize(pCfgIf->Core.pvUser, pszName, &cb);
1084 if (RT_SUCCESS(rc))
1085 {
1086 char *pbData;
1087 Assert(cb);
1088
1089 pbData = (char *)RTMemAlloc(cb);
1090 if (pbData)
1091 {
1092 if(pCfgIf->pfnQueryBytes)
1093 rc = pCfgIf->pfnQueryBytes(pCfgIf->Core.pvUser, pszName, pbData, cb);
1094 else
1095 rc = pCfgIf->pfnQuery(pCfgIf->Core.pvUser, pszName, pbData, cb);
1096
1097 if (RT_SUCCESS(rc))
1098 {
1099 *ppvData = pbData;
1100 /* Exclude terminator if the byte data was obtained using the string query callback. */
1101 *pcbData = cb;
1102 if (!pCfgIf->pfnQueryBytes)
1103 (*pcbData)--;
1104 }
1105 else
1106 RTMemFree(pbData);
1107 }
1108 else
1109 rc = VERR_NO_MEMORY;
1110 }
1111 return rc;
1112}
1113
1114/** Forward declaration of a VD socket. */
1115typedef struct VDSOCKETINT *VDSOCKET;
1116/** Pointer to a VD socket. */
1117typedef VDSOCKET *PVDSOCKET;
1118/** Nil socket handle. */
1119#define NIL_VDSOCKET ((VDSOCKET)0)
1120
1121/** Connect flag to indicate that the backend wants to use the extended
1122 * socket I/O multiplexing call. This might not be supported on all configurations
1123 * (internal networking and iSCSI)
1124 * and the backend needs to take appropriate action.
1125 */
1126#define VD_INTERFACETCPNET_CONNECT_EXTENDED_SELECT RT_BIT_32(0)
1127
1128/** @name Select events
1129 * @{ */
1130/** Readable without blocking. */
1131#define VD_INTERFACETCPNET_EVT_READ RT_BIT_32(0)
1132/** Writable without blocking. */
1133#define VD_INTERFACETCPNET_EVT_WRITE RT_BIT_32(1)
1134/** Error condition, hangup, exception or similar. */
1135#define VD_INTERFACETCPNET_EVT_ERROR RT_BIT_32(2)
1136/** Hint for the select that getting interrupted while waiting is more likely.
1137 * The interface implementation can optimize the waiting strategy based on this.
1138 * It is assumed that it is more likely to get one of the above socket events
1139 * instead of being interrupted if the flag is not set. */
1140#define VD_INTERFACETCPNET_HINT_INTERRUPT RT_BIT_32(3)
1141/** Mask of the valid bits. */
1142#define VD_INTERFACETCPNET_EVT_VALID_MASK UINT32_C(0x0000000f)
1143/** @} */
1144
1145/**
1146 * TCP network stack interface
1147 *
1148 * Per-image. Mandatory for backends which have the VD_CAP_TCPNET bit set.
1149 */
1150typedef struct VDINTERFACETCPNET
1151{
1152 /**
1153 * Common interface header.
1154 */
1155 VDINTERFACE Core;
1156
1157 /**
1158 * Creates a socket. The socket is not connected if this succeeds.
1159 *
1160 * @return iprt status code.
1161 * @retval VERR_NOT_SUPPORTED if the combination of flags is not supported.
1162 * @param fFlags Combination of the VD_INTERFACETCPNET_CONNECT_* \#defines.
1163 * @param phVdSock Where to store the handle.
1164 */
1165 DECLR3CALLBACKMEMBER(int, pfnSocketCreate, (uint32_t fFlags, PVDSOCKET phVdSock));
1166
1167 /**
1168 * Destroys the socket.
1169 *
1170 * @return iprt status code.
1171 * @param hVdSock Socket handle (/ pointer).
1172 */
1173 DECLR3CALLBACKMEMBER(int, pfnSocketDestroy, (VDSOCKET hVdSock));
1174
1175 /**
1176 * Connect as a client to a TCP port.
1177 *
1178 * @return iprt status code.
1179 * @param hVdSock Socket handle (/ pointer)..
1180 * @param pszAddress The address to connect to.
1181 * @param uPort The port to connect to.
1182 * @param cMillies Number of milliseconds to wait for the connect attempt to complete.
1183 * Use RT_INDEFINITE_WAIT to wait for ever.
1184 * Use RT_SOCKETCONNECT_DEFAULT_WAIT to wait for the default time
1185 * configured on the running system.
1186 */
1187 DECLR3CALLBACKMEMBER(int, pfnClientConnect, (VDSOCKET hVdSock, const char *pszAddress, uint32_t uPort,
1188 RTMSINTERVAL cMillies));
1189
1190 /**
1191 * Close a TCP connection.
1192 *
1193 * @return iprt status code.
1194 * @param hVdSock Socket handle (/ pointer).
1195 */
1196 DECLR3CALLBACKMEMBER(int, pfnClientClose, (VDSOCKET hVdSock));
1197
1198 /**
1199 * Returns whether the socket is currently connected to the client.
1200 *
1201 * @returns true if the socket is connected.
1202 * false otherwise.
1203 * @param hVdSock Socket handle (/ pointer).
1204 */
1205 DECLR3CALLBACKMEMBER(bool, pfnIsClientConnected, (VDSOCKET hVdSock));
1206
1207 /**
1208 * Socket I/O multiplexing.
1209 * Checks if the socket is ready for reading.
1210 *
1211 * @return iprt status code.
1212 * @param hVdSock Socket handle (/ pointer).
1213 * @param cMillies Number of milliseconds to wait for the socket.
1214 * Use RT_INDEFINITE_WAIT to wait for ever.
1215 */
1216 DECLR3CALLBACKMEMBER(int, pfnSelectOne, (VDSOCKET hVdSock, RTMSINTERVAL cMillies));
1217
1218 /**
1219 * Receive data from a socket.
1220 *
1221 * @return iprt status code.
1222 * @param hVdSock Socket handle (/ pointer).
1223 * @param pvBuffer Where to put the data we read.
1224 * @param cbBuffer Read buffer size.
1225 * @param pcbRead Number of bytes read.
1226 * If NULL the entire buffer will be filled upon successful return.
1227 * If not NULL a partial read can be done successfully.
1228 */
1229 DECLR3CALLBACKMEMBER(int, pfnRead, (VDSOCKET hVdSock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead));
1230
1231 /**
1232 * Send data to a socket.
1233 *
1234 * @return iprt status code.
1235 * @param hVdSock Socket handle (/ pointer).
1236 * @param pvBuffer Buffer to write data to socket.
1237 * @param cbBuffer How much to write.
1238 */
1239 DECLR3CALLBACKMEMBER(int, pfnWrite, (VDSOCKET hVdSock, const void *pvBuffer, size_t cbBuffer));
1240
1241 /**
1242 * Send data from scatter/gather buffer to a socket.
1243 *
1244 * @return iprt status code.
1245 * @param hVdSock Socket handle (/ pointer).
1246 * @param pSgBuf Scatter/gather buffer to write data to socket.
1247 */
1248 DECLR3CALLBACKMEMBER(int, pfnSgWrite, (VDSOCKET hVdSock, PCRTSGBUF pSgBuf));
1249
1250 /**
1251 * Receive data from a socket - not blocking.
1252 *
1253 * @return iprt status code.
1254 * @param hVdSock Socket handle (/ pointer).
1255 * @param pvBuffer Where to put the data we read.
1256 * @param cbBuffer Read buffer size.
1257 * @param pcbRead Number of bytes read.
1258 */
1259 DECLR3CALLBACKMEMBER(int, pfnReadNB, (VDSOCKET hVdSock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead));
1260
1261 /**
1262 * Send data to a socket - not blocking.
1263 *
1264 * @return iprt status code.
1265 * @param hVdSock Socket handle (/ pointer).
1266 * @param pvBuffer Buffer to write data to socket.
1267 * @param cbBuffer How much to write.
1268 * @param pcbWritten Number of bytes written.
1269 */
1270 DECLR3CALLBACKMEMBER(int, pfnWriteNB, (VDSOCKET hVdSock, const void *pvBuffer, size_t cbBuffer, size_t *pcbWritten));
1271
1272 /**
1273 * Send data from scatter/gather buffer to a socket - not blocking.
1274 *
1275 * @return iprt status code.
1276 * @param hVdSock Socket handle (/ pointer).
1277 * @param pSgBuf Scatter/gather buffer to write data to socket.
1278 * @param pcbWritten Number of bytes written.
1279 */
1280 DECLR3CALLBACKMEMBER(int, pfnSgWriteNB, (VDSOCKET hVdSock, PRTSGBUF pSgBuf, size_t *pcbWritten));
1281
1282 /**
1283 * Flush socket write buffers.
1284 *
1285 * @return iprt status code.
1286 * @param hVdSock Socket handle (/ pointer).
1287 */
1288 DECLR3CALLBACKMEMBER(int, pfnFlush, (VDSOCKET hVdSock));
1289
1290 /**
1291 * Enables or disables delaying sends to coalesce packets.
1292 *
1293 * @return iprt status code.
1294 * @param hVdSock Socket handle (/ pointer).
1295 * @param fEnable When set to true enables coalescing.
1296 */
1297 DECLR3CALLBACKMEMBER(int, pfnSetSendCoalescing, (VDSOCKET hVdSock, bool fEnable));
1298
1299 /**
1300 * Gets the address of the local side.
1301 *
1302 * @return iprt status code.
1303 * @param hVdSock Socket handle (/ pointer).
1304 * @param pAddr Where to store the local address on success.
1305 */
1306 DECLR3CALLBACKMEMBER(int, pfnGetLocalAddress, (VDSOCKET hVdSock, PRTNETADDR pAddr));
1307
1308 /**
1309 * Gets the address of the other party.
1310 *
1311 * @return iprt status code.
1312 * @param hVdSock Socket handle (/ pointer).
1313 * @param pAddr Where to store the peer address on success.
1314 */
1315 DECLR3CALLBACKMEMBER(int, pfnGetPeerAddress, (VDSOCKET hVdSock, PRTNETADDR pAddr));
1316
1317 /**
1318 * Socket I/O multiplexing - extended version which can be woken up.
1319 * Checks if the socket is ready for reading or writing.
1320 *
1321 * @return iprt status code.
1322 * @retval VERR_INTERRUPTED if the thread was woken up by a pfnPoke call.
1323 * @param hVdSock VD Socket handle(/pointer).
1324 * @param fEvents Mask of events to wait for.
1325 * @param pfEvents Where to store the received events.
1326 * @param cMillies Number of milliseconds to wait for the socket.
1327 * Use RT_INDEFINITE_WAIT to wait for ever.
1328 */
1329 DECLR3CALLBACKMEMBER(int, pfnSelectOneEx, (VDSOCKET hVdSock, uint32_t fEvents,
1330 uint32_t *pfEvents, RTMSINTERVAL cMillies));
1331
1332 /**
1333 * Wakes up the thread waiting in pfnSelectOneEx.
1334 *
1335 * @return iprt status code.
1336 * @param hVdSock VD Socket handle(/pointer).
1337 */
1338 DECLR3CALLBACKMEMBER(int, pfnPoke, (VDSOCKET hVdSock));
1339
1340} VDINTERFACETCPNET, *PVDINTERFACETCPNET;
1341
1342/**
1343 * Get TCP network stack interface from interface list.
1344 *
1345 * @return Pointer to the first TCP network stack interface in the list.
1346 * @param pVDIfs Pointer to the interface list.
1347 */
1348DECLINLINE(PVDINTERFACETCPNET) VDIfTcpNetGet(PVDINTERFACE pVDIfs)
1349{
1350 PVDINTERFACE pIf = VDInterfaceGet(pVDIfs, VDINTERFACETYPE_TCPNET);
1351
1352 /* Check that the interface descriptor is a progress interface. */
1353 AssertMsgReturn( !pIf
1354 || ( (pIf->enmInterface == VDINTERFACETYPE_TCPNET)
1355 && (pIf->cbSize == sizeof(VDINTERFACETCPNET))),
1356 ("Not a TCP net interface"), NULL);
1357
1358 return (PVDINTERFACETCPNET)pIf;
1359}
1360
1361
1362/**
1363 * Interface to synchronize concurrent accesses by several threads.
1364 *
1365 * @note The scope of this interface is to manage concurrent accesses after
1366 * the HDD container has been created, and they must stop before destroying the
1367 * container. Opening or closing images is covered by the synchronization, but
1368 * that does not mean it is safe to close images while a thread executes
1369 * #VDMerge or #VDCopy operating on these images. Making them safe would require
1370 * the lock to be held during the entire operation, which prevents other
1371 * concurrent acitivities.
1372 *
1373 * @note Right now this is kept as simple as possible, and does not even
1374 * attempt to provide enough information to allow e.g. concurrent write
1375 * accesses to different areas of the disk. The reason is that it is very
1376 * difficult to predict which area of a disk is affected by a write,
1377 * especially when different image formats are mixed. Maybe later a more
1378 * sophisticated interface will be provided which has the necessary information
1379 * about worst case affected areas.
1380 *
1381 * Per-disk interface. Optional, needed if the disk is accessed concurrently
1382 * by several threads, e.g. when merging diff images while a VM is running.
1383 */
1384typedef struct VDINTERFACETHREADSYNC
1385{
1386 /**
1387 * Common interface header.
1388 */
1389 VDINTERFACE Core;
1390
1391 /**
1392 * Start a read operation.
1393 */
1394 DECLR3CALLBACKMEMBER(int, pfnStartRead, (void *pvUser));
1395
1396 /**
1397 * Finish a read operation.
1398 */
1399 DECLR3CALLBACKMEMBER(int, pfnFinishRead, (void *pvUser));
1400
1401 /**
1402 * Start a write operation.
1403 */
1404 DECLR3CALLBACKMEMBER(int, pfnStartWrite, (void *pvUser));
1405
1406 /**
1407 * Finish a write operation.
1408 */
1409 DECLR3CALLBACKMEMBER(int, pfnFinishWrite, (void *pvUser));
1410
1411} VDINTERFACETHREADSYNC, *PVDINTERFACETHREADSYNC;
1412
1413/**
1414 * Get thread synchronization interface from interface list.
1415 *
1416 * @return Pointer to the first thread synchronization interface in the list.
1417 * @param pVDIfs Pointer to the interface list.
1418 */
1419DECLINLINE(PVDINTERFACETHREADSYNC) VDIfThreadSyncGet(PVDINTERFACE pVDIfs)
1420{
1421 PVDINTERFACE pIf = VDInterfaceGet(pVDIfs, VDINTERFACETYPE_THREADSYNC);
1422
1423 /* Check that the interface descriptor is a progress interface. */
1424 AssertMsgReturn( !pIf
1425 || ( (pIf->enmInterface == VDINTERFACETYPE_THREADSYNC)
1426 && (pIf->cbSize == sizeof(VDINTERFACETHREADSYNC))),
1427 ("Not a thread synchronization interface"), NULL);
1428
1429 return (PVDINTERFACETHREADSYNC)pIf;
1430}
1431
1432/**
1433 * Interface to query usage of disk ranges.
1434 *
1435 * Per-operation interface. Optional.
1436 */
1437typedef struct VDINTERFACEQUERYRANGEUSE
1438{
1439 /**
1440 * Common interface header.
1441 */
1442 VDINTERFACE Core;
1443
1444 /**
1445 * Query use of a disk range.
1446 */
1447 DECLR3CALLBACKMEMBER(int, pfnQueryRangeUse, (void *pvUser, uint64_t off, uint64_t cb,
1448 bool *pfUsed));
1449
1450} VDINTERFACEQUERYRANGEUSE, *PVDINTERFACEQUERYRANGEUSE;
1451
1452/**
1453 * Get query range use interface from interface list.
1454 *
1455 * @return Pointer to the first thread synchronization interface in the list.
1456 * @param pVDIfs Pointer to the interface list.
1457 */
1458DECLINLINE(PVDINTERFACEQUERYRANGEUSE) VDIfQueryRangeUseGet(PVDINTERFACE pVDIfs)
1459{
1460 PVDINTERFACE pIf = VDInterfaceGet(pVDIfs, VDINTERFACETYPE_QUERYRANGEUSE);
1461
1462 /* Check that the interface descriptor is a progress interface. */
1463 AssertMsgReturn( !pIf
1464 || ( (pIf->enmInterface == VDINTERFACETYPE_QUERYRANGEUSE)
1465 && (pIf->cbSize == sizeof(VDINTERFACEQUERYRANGEUSE))),
1466 ("Not a query range use interface"), NULL);
1467
1468 return (PVDINTERFACEQUERYRANGEUSE)pIf;
1469}
1470
1471DECLINLINE(int) vdIfQueryRangeUse(PVDINTERFACEQUERYRANGEUSE pIfQueryRangeUse, uint64_t off, uint64_t cb,
1472 bool *pfUsed)
1473{
1474 return pIfQueryRangeUse->pfnQueryRangeUse(pIfQueryRangeUse->Core.pvUser, off, cb, pfUsed);
1475}
1476
1477
1478/**
1479 * Interface used to retrieve keys for cryptographic operations.
1480 *
1481 * Per-module interface. Optional but cryptographic modules might fail and
1482 * return an error if this is not present.
1483 */
1484typedef struct VDINTERFACECRYPTO
1485{
1486 /**
1487 * Common interface header.
1488 */
1489 VDINTERFACE Core;
1490
1491 /**
1492 * Retains a key identified by the ID. The caller will only hold a reference
1493 * to the key and must not modify the key buffer in any way.
1494 *
1495 * @returns VBox status code.
1496 * @param pvUser The opaque user data associated with this interface.
1497 * @param pszId The alias/id for the key to retrieve.
1498 * @param ppbKey Where to store the pointer to the key buffer on success.
1499 * @param pcbKey Where to store the size of the key in bytes on success.
1500 */
1501 DECLR3CALLBACKMEMBER(int, pfnKeyRetain, (void *pvUser, const char *pszId, const uint8_t **ppbKey, size_t *pcbKey));
1502
1503 /**
1504 * Releases one reference of the key identified by the given identifier.
1505 * The caller must not access the key buffer after calling this operation.
1506 *
1507 * @returns VBox status code.
1508 * @param pvUser The opaque user data associated with this interface.
1509 * @param pszId The alias/id for the key to release.
1510 *
1511 * @note It is advised to release the key whenever it is not used anymore so
1512 * the entity storing the key can do anything to make retrieving the key
1513 * from memory more difficult like scrambling the memory buffer for
1514 * instance.
1515 */
1516 DECLR3CALLBACKMEMBER(int, pfnKeyRelease, (void *pvUser, const char *pszId));
1517
1518 /**
1519 * Gets a reference to the password identified by the given ID to open a key store supplied through the config interface.
1520 *
1521 * @returns VBox status code.
1522 * @param pvUser The opaque user data associated with this interface.
1523 * @param pszId The alias/id for the password to retain.
1524 * @param ppszPassword Where to store the password to unlock the key store on success.
1525 */
1526 DECLR3CALLBACKMEMBER(int, pfnKeyStorePasswordRetain, (void *pvUser, const char *pszId, const char **ppszPassword));
1527
1528 /**
1529 * Releases a reference of the password previously acquired with VDINTERFACECRYPTO::pfnKeyStorePasswordRetain()
1530 * identified by the given ID.
1531 *
1532 * @returns VBox status code.
1533 * @param pvUser The opaque user data associated with this interface.
1534 * @param pszId The alias/id for the password to release.
1535 */
1536 DECLR3CALLBACKMEMBER(int, pfnKeyStorePasswordRelease, (void *pvUser, const char *pszId));
1537
1538 /**
1539 * Saves a key store.
1540 *
1541 * @returns VBox status code.
1542 * @param pvUser The opaque user data associated with this interface.
1543 * @param pvKeyStore The key store to save.
1544 * @param cbKeyStore Size of the key store in bytes.
1545 *
1546 * @note The format is filter specific and should be treated as binary data.
1547 */
1548 DECLR3CALLBACKMEMBER(int, pfnKeyStoreSave, (void *pvUser, const void *pvKeyStore, size_t cbKeyStore));
1549
1550 /**
1551 * Returns the parameters after the key store was loaded successfully.
1552 *
1553 * @returns VBox status code.
1554 * @param pvUser The opaque user data associated with this interface.
1555 * @param pszCipher The cipher identifier the DEK is used for.
1556 * @param pbDek The raw DEK which was contained in the key store loaded by
1557 * VDINTERFACECRYPTO::pfnKeyStoreLoad().
1558 * @param cbDek The size of the DEK.
1559 *
1560 * @note The provided pointer to the DEK is only valid until this call returns.
1561 * The content might change afterwards with out notice (when scrambling the key
1562 * for further protection for example) or might be even freed.
1563 *
1564 * @note This method is optional and can be NULL if the caller does not require the
1565 * parameters.
1566 */
1567 DECLR3CALLBACKMEMBER(int, pfnKeyStoreReturnParameters, (void *pvUser, const char *pszCipher,
1568 const uint8_t *pbDek, size_t cbDek));
1569
1570} VDINTERFACECRYPTO, *PVDINTERFACECRYPTO;
1571
1572
1573/**
1574 * Get error interface from interface list.
1575 *
1576 * @return Pointer to the first error interface in the list.
1577 * @param pVDIfs Pointer to the interface list.
1578 */
1579DECLINLINE(PVDINTERFACECRYPTO) VDIfCryptoGet(PVDINTERFACE pVDIfs)
1580{
1581 PVDINTERFACE pIf = VDInterfaceGet(pVDIfs, VDINTERFACETYPE_CRYPTO);
1582
1583 /* Check that the interface descriptor is a crypto interface. */
1584 AssertMsgReturn( !pIf
1585 || ( (pIf->enmInterface == VDINTERFACETYPE_CRYPTO)
1586 && (pIf->cbSize == sizeof(VDINTERFACECRYPTO))),
1587 ("Not an crypto interface\n"), NULL);
1588
1589 return (PVDINTERFACECRYPTO)pIf;
1590}
1591
1592/**
1593 * Retains a key identified by the ID. The caller will only hold a reference
1594 * to the key and must not modify the key buffer in any way.
1595 *
1596 * @returns VBox status code.
1597 * @param pIfCrypto Pointer to the crypto interface.
1598 * @param pszId The alias/id for the key to retrieve.
1599 * @param ppbKey Where to store the pointer to the key buffer on success.
1600 * @param pcbKey Where to store the size of the key in bytes on success.
1601 */
1602DECLINLINE(int) vdIfCryptoKeyRetain(PVDINTERFACECRYPTO pIfCrypto, const char *pszId, const uint8_t **ppbKey, size_t *pcbKey)
1603{
1604 return pIfCrypto->pfnKeyRetain(pIfCrypto->Core.pvUser, pszId, ppbKey, pcbKey);
1605}
1606
1607/**
1608 * Releases one reference of the key identified by the given identifier.
1609 * The caller must not access the key buffer after calling this operation.
1610 *
1611 * @returns VBox status code.
1612 * @param pIfCrypto Pointer to the crypto interface.
1613 * @param pszId The alias/id for the key to release.
1614 *
1615 * @note It is advised to release the key whenever it is not used anymore so
1616 * the entity storing the key can do anything to make retrieving the key
1617 * from memory more difficult like scrambling the memory buffer for
1618 * instance.
1619 */
1620DECLINLINE(int) vdIfCryptoKeyRelease(PVDINTERFACECRYPTO pIfCrypto, const char *pszId)
1621{
1622 return pIfCrypto->pfnKeyRelease(pIfCrypto->Core.pvUser, pszId);
1623}
1624
1625/**
1626 * Gets a reference to the password identified by the given ID to open a key store supplied through the config interface.
1627 *
1628 * @returns VBox status code.
1629 * @param pIfCrypto Pointer to the crypto interface.
1630 * @param pszId The alias/id for the password to retain.
1631 * @param ppszPassword Where to store the password to unlock the key store on success.
1632 */
1633DECLINLINE(int) vdIfCryptoKeyStorePasswordRetain(PVDINTERFACECRYPTO pIfCrypto, const char *pszId, const char **ppszPassword)
1634{
1635 return pIfCrypto->pfnKeyStorePasswordRetain(pIfCrypto->Core.pvUser, pszId, ppszPassword);
1636}
1637
1638/**
1639 * Releases a reference of the password previously acquired with VDINTERFACECRYPTO::pfnKeyStorePasswordRetain()
1640 * identified by the given ID.
1641 *
1642 * @returns VBox status code.
1643 * @param pIfCrypto Pointer to the crypto interface.
1644 * @param pszId The alias/id for the password to release.
1645 */
1646DECLINLINE(int) vdIfCryptoKeyStorePasswordRelease(PVDINTERFACECRYPTO pIfCrypto, const char *pszId)
1647{
1648 return pIfCrypto->pfnKeyStorePasswordRelease(pIfCrypto->Core.pvUser, pszId);
1649}
1650
1651/**
1652 * Saves a key store.
1653 *
1654 * @returns VBox status code.
1655 * @param pIfCrypto Pointer to the crypto interface.
1656 * @param pvKeyStore The key store to save.
1657 * @param cbKeyStore Size of the key store in bytes.
1658 *
1659 * @note The format is filter specific and should be treated as binary data.
1660 */
1661DECLINLINE(int) vdIfCryptoKeyStoreSave(PVDINTERFACECRYPTO pIfCrypto, const void *pvKeyStore, size_t cbKeyStore)
1662{
1663 return pIfCrypto->pfnKeyStoreSave(pIfCrypto->Core.pvUser, pvKeyStore, cbKeyStore);
1664}
1665
1666/**
1667 * Returns the parameters after the key store was loaded successfully.
1668 *
1669 * @returns VBox status code.
1670 * @param pIfCrypto Pointer to the crypto interface.
1671 * @param pszCipher The cipher identifier the DEK is used for.
1672 * @param pbDek The raw DEK which was contained in the key store loaded by
1673 * VDINTERFACECRYPTO::pfnKeyStoreLoad().
1674 * @param cbDek The size of the DEK.
1675 *
1676 * @note The provided pointer to the DEK is only valid until this call returns.
1677 * The content might change afterwards with out notice (when scrambling the key
1678 * for further protection for example) or might be even freed.
1679 *
1680 * @note This method is optional and can be NULL if the caller does not require the
1681 * parameters.
1682 */
1683DECLINLINE(int) vdIfCryptoKeyStoreReturnParameters(PVDINTERFACECRYPTO pIfCrypto, const char *pszCipher,
1684 const uint8_t *pbDek, size_t cbDek)
1685{
1686 if (pIfCrypto->pfnKeyStoreReturnParameters)
1687 return pIfCrypto->pfnKeyStoreReturnParameters(pIfCrypto->Core.pvUser, pszCipher, pbDek, cbDek);
1688
1689 return VINF_SUCCESS;
1690}
1691
1692
1693RT_C_DECLS_END
1694
1695/** @} */
1696
1697#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