VirtualBox

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

Last change on this file since 85704 was 85121, checked in by vboxsync, 4 years ago

iprt/cdefs.h: Refactored the typedef use of DECLCALLBACK as well as DECLCALLBACKMEMBER to wrap the whole expression, similar to the DECLR?CALLBACKMEMBER macros. This allows adding a throw() at the end when compiling with the VC++ compiler to indicate that the callbacks won't throw anything, so we can stop supressing the C5039 warning about passing functions that can potential throw C++ exceptions to extern C code that can't necessarily cope with such (unwind,++). Introduced a few _EX variations that allows specifying different/no calling convention too, as that's handy when dynamically resolving host APIs. Fixed numerous places missing DECLCALLBACK and such. Left two angry @todos regarding use of CreateThread. bugref:9794

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