VirtualBox

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

Last change on this file since 86620 was 85901, checked in by vboxsync, 4 years ago

VBox/vd-ifs.h: Log vdIfError[Warning] using the local logger config. bugref:9224

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