VirtualBox

source: vbox/trunk/include/VBox/VBoxHDD.h@ 32536

Last change on this file since 32536 was 32536, checked in by vboxsync, 14 years ago

Storage/VBoxHDD: replace custom open flags with regular IPRT file open flags, introduce user-providable filesystem access interface, eliminate dependency on PGM geometry structure, change pvBuffer/cbBuffer parameter ordering to the usual conventions, eliminate the remains of the old I/O code, make more plugin methods optional to reduce redundancy, lots of cleanups

Storage/DrvVD+testcases,Main/Medium+Frontends: adapt to VBoxHDD changes, logging fixes

Storage/VDI+VMDK+DMG+Raw+VHD+Parallels+VCI: made as similar to each other as possible, added inline VFS wrappers to improve readability, full VFS support, VDI files are now 4K aligned, eliminate the remains of the old I/O code, various more or less severe bugfixes, code sort

Storage/iSCSI: support disks bigger than 2T, streamline the code to be more similar to the file-based backends, memory leak fix, error code usage like file-based backends, code sort

log+err: added new error codes/log groups and eliminated unused old ones

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 102.3 KB
Line 
1/** @file
2 * VBox HDD Container API.
3 */
4
5/*
6 * Copyright (C) 2006-2010 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___VBox_VD_h
27#define ___VBox_VD_h
28
29#include <iprt/assert.h>
30#include <iprt/string.h>
31#include <iprt/mem.h>
32#include <iprt/file.h>
33#include <iprt/net.h>
34#include <iprt/sg.h>
35#include <VBox/cdefs.h>
36#include <VBox/types.h>
37#include <VBox/err.h>
38
39RT_C_DECLS_BEGIN
40
41#ifdef IN_RING0
42# error "There are no VBox HDD Container APIs available in Ring-0 Host Context!"
43#endif
44
45/** @defgroup grp_vd VBox HDD Container
46 * @{
47 */
48
49/** Current VMDK image version. */
50#define VMDK_IMAGE_VERSION (0x0001)
51
52/** Current VDI image major version. */
53#define VDI_IMAGE_VERSION_MAJOR (0x0001)
54/** Current VDI image minor version. */
55#define VDI_IMAGE_VERSION_MINOR (0x0001)
56/** Current VDI image version. */
57#define VDI_IMAGE_VERSION ((VDI_IMAGE_VERSION_MAJOR << 16) | VDI_IMAGE_VERSION_MINOR)
58
59/** Get VDI major version from combined version. */
60#define VDI_GET_VERSION_MAJOR(uVer) ((uVer) >> 16)
61/** Get VDI minor version from combined version. */
62#define VDI_GET_VERSION_MINOR(uVer) ((uVer) & 0xffff)
63
64/** Placeholder for specifying the last opened image. */
65#define VD_LAST_IMAGE 0xffffffffU
66
67/** @name VBox HDD container image flags
68 * @{
69 */
70/** No flags. */
71#define VD_IMAGE_FLAGS_NONE (0)
72/** Fixed image. */
73#define VD_IMAGE_FLAGS_FIXED (0x10000)
74/** Diff image. Mutually exclusive with fixed image. */
75#define VD_IMAGE_FLAGS_DIFF (0x20000)
76/** VMDK: Split image into 2GB extents. */
77#define VD_VMDK_IMAGE_FLAGS_SPLIT_2G (0x0001)
78/** VMDK: Raw disk image (giving access to a number of host partitions). */
79#define VD_VMDK_IMAGE_FLAGS_RAWDISK (0x0002)
80/** VMDK: stream optimized image, read only. */
81#define VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED (0x0004)
82/** VMDK: ESX variant, use in addition to other flags. */
83#define VD_VMDK_IMAGE_FLAGS_ESX (0x0008)
84/** VDI: Fill new blocks with zeroes while expanding image file. Only valid
85 * for newly created images, never set for opened existing images. */
86#define VD_VDI_IMAGE_FLAGS_ZERO_EXPAND (0x0100)
87
88/** Mask of valid image flags for VMDK. */
89#define VD_VMDK_IMAGE_FLAGS_MASK ( VD_IMAGE_FLAGS_FIXED | VD_IMAGE_FLAGS_DIFF | VD_IMAGE_FLAGS_NONE \
90 | VD_VMDK_IMAGE_FLAGS_SPLIT_2G | VD_VMDK_IMAGE_FLAGS_RAWDISK \
91 | VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED | VD_VMDK_IMAGE_FLAGS_ESX)
92
93/** Mask of valid image flags for VDI. */
94#define VD_VDI_IMAGE_FLAGS_MASK (VD_IMAGE_FLAGS_FIXED | VD_IMAGE_FLAGS_DIFF | VD_IMAGE_FLAGS_NONE | VD_VDI_IMAGE_FLAGS_ZERO_EXPAND)
95
96/** Mask of all valid image flags for all formats. */
97#define VD_IMAGE_FLAGS_MASK (VD_VMDK_IMAGE_FLAGS_MASK | VD_VDI_IMAGE_FLAGS_MASK)
98
99/** Default image flags. */
100#define VD_IMAGE_FLAGS_DEFAULT (VD_IMAGE_FLAGS_NONE)
101/** @} */
102
103
104/**
105 * Auxiliary type for describing partitions on raw disks. The entries must be
106 * in ascending order (as far as uStart is concerned), and must not overlap.
107 * Note that this does not correspond 1:1 to partitions, it is describing the
108 * general meaning of contiguous areas on the disk.
109 */
110typedef struct VBOXHDDRAWPARTDESC
111{
112 /** Device to use for this partition/data area. Can be the disk device if
113 * the offset field is set appropriately. If this is NULL, then this
114 * partition will not be accessible to the guest. The size of the data area
115 * must still be set correctly. */
116 const char *pszRawDevice;
117 /** Pointer to the partitioning info. NULL means this is a regular data
118 * area on disk, non-NULL denotes data which should be copied to the
119 * partition data overlay. */
120 const void *pvPartitionData;
121 /** Offset where the data starts in this device. */
122 uint64_t uStartOffset;
123 /** Offset where the data starts in the disk. */
124 uint64_t uStart;
125 /** Size of the data area. */
126 uint64_t cbData;
127} VBOXHDDRAWPARTDESC, *PVBOXHDDRAWPARTDESC;
128
129/**
130 * Auxiliary data structure for creating raw disks.
131 */
132typedef struct VBOXHDDRAW
133{
134 /** Signature for structure. Must be 'R', 'A', 'W', '\\0'. Actually a trick
135 * to make logging of the comment string produce sensible results. */
136 char szSignature[4];
137 /** Flag whether access to full disk should be given (ignoring the
138 * partition information below). */
139 bool fRawDisk;
140 /** Filename for the raw disk. Ignored for partitioned raw disks.
141 * For Linux e.g. /dev/sda, and for Windows e.g. \\\\.\\PhysicalDisk0. */
142 const char *pszRawDisk;
143 /** Number of entries in the partition descriptor array. */
144 unsigned cPartDescs;
145 /** Pointer to the partition descriptor array. */
146 PVBOXHDDRAWPARTDESC pPartDescs;
147} VBOXHDDRAW, *PVBOXHDDRAW;
148
149/** @name VBox HDD container image open mode flags
150 * @{
151 */
152/** Try to open image in read/write exclusive access mode if possible, or in read-only elsewhere. */
153#define VD_OPEN_FLAGS_NORMAL 0
154/** Open image in read-only mode with sharing access with others. */
155#define VD_OPEN_FLAGS_READONLY RT_BIT(0)
156/** Honor zero block writes instead of ignoring them whenever possible.
157 * This is not supported by all formats. It is silently ignored in this case. */
158#define VD_OPEN_FLAGS_HONOR_ZEROES RT_BIT(1)
159/** Honor writes of the same data instead of ignoring whenever possible.
160 * This is handled generically, and is only meaningful for differential image
161 * formats. It is silently ignored otherwise. */
162#define VD_OPEN_FLAGS_HONOR_SAME RT_BIT(2)
163/** Do not perform the base/diff image check on open. This does NOT imply
164 * opening the image as readonly (would break e.g. adding UUIDs to VMDK files
165 * created by other products). Images opened with this flag should only be
166 * used for querying information, and nothing else. */
167#define VD_OPEN_FLAGS_INFO RT_BIT(3)
168/** Open image for asynchronous access. Only available if VD_CAP_ASYNC_IO is
169 * set. Check with VDIsAsynchonousIoSupported whether asynchronous I/O is
170 * really supported for this file. */
171#define VD_OPEN_FLAGS_ASYNC_IO RT_BIT(4)
172/** Allow sharing of the image for writable images. May be ignored if the
173 * format backend doesn't support this type of concurrent access. */
174#define VD_OPEN_FLAGS_SHAREABLE RT_BIT(5)
175/** Mask of valid flags. */
176#define VD_OPEN_FLAGS_MASK (VD_OPEN_FLAGS_NORMAL | VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_HONOR_ZEROES | VD_OPEN_FLAGS_HONOR_SAME | VD_OPEN_FLAGS_INFO | VD_OPEN_FLAGS_ASYNC_IO | VD_OPEN_FLAGS_SHAREABLE)
177/** @}*/
178
179/**
180 * Helper functions to handle open flags.
181 */
182
183/**
184 * Translate VD_OPEN_FLAGS_* to RTFile open flags.
185 *
186 * @return RTFile open flags.
187 * @param uOpenFlags VD_OPEN_FLAGS_* open flags.
188 * @param fCreate Flag that the file should be created.
189 */
190DECLINLINE(uint32_t) VDOpenFlagsToFileOpenFlags(unsigned uOpenFlags, bool fCreate)
191{
192 AssertMsg(!((uOpenFlags & VD_OPEN_FLAGS_READONLY) && fCreate), ("Image can't be opened readonly while being created\n"));
193
194 uint32_t fOpen = 0;
195
196 if (RT_UNLIKELY(uOpenFlags & VD_OPEN_FLAGS_READONLY))
197 fOpen |= RTFILE_O_READ | RTFILE_O_DENY_NONE;
198 else
199 {
200 fOpen |= RTFILE_O_READWRITE;
201
202 if (RT_UNLIKELY(uOpenFlags & VD_OPEN_FLAGS_SHAREABLE))
203 fOpen |= RTFILE_O_DENY_NONE;
204 else
205 fOpen |= RTFILE_O_DENY_WRITE;
206 }
207
208 if (RT_UNLIKELY(fCreate))
209 fOpen |= RTFILE_O_CREATE | RTFILE_O_NOT_CONTENT_INDEXED;
210 else
211 fOpen |= RTFILE_O_OPEN;
212
213 return fOpen;
214}
215
216
217/** @name VBox HDD container backend capability flags
218 * @{
219 */
220/** Supports UUIDs as expected by VirtualBox code. */
221#define VD_CAP_UUID RT_BIT(0)
222/** Supports creating fixed size images, allocating all space instantly. */
223#define VD_CAP_CREATE_FIXED RT_BIT(1)
224/** Supports creating dynamically growing images, allocating space on demand. */
225#define VD_CAP_CREATE_DYNAMIC RT_BIT(2)
226/** Supports creating images split in chunks of a bit less than 2GBytes. */
227#define VD_CAP_CREATE_SPLIT_2G RT_BIT(3)
228/** Supports being used as differencing image format backend. */
229#define VD_CAP_DIFF RT_BIT(4)
230/** Supports asynchronous I/O operations for at least some configurations. */
231#define VD_CAP_ASYNC RT_BIT(5)
232/** The backend operates on files. The caller needs to know to handle the
233 * location appropriately. */
234#define VD_CAP_FILE RT_BIT(6)
235/** The backend uses the config interface. The caller needs to know how to
236 * provide the mandatory configuration parts this way. */
237#define VD_CAP_CONFIG RT_BIT(7)
238/** The backend uses the network stack interface. The caller has to provide
239 * the appropriate interface. */
240#define VD_CAP_TCPNET RT_BIT(8)
241/** The backend supports VFS (virtual filesystem) functionality since it uses
242 * VDINTERFACEIO exclusively for all file operations. */
243#define VD_CAP_VFS RT_BIT(9)
244/** @}*/
245
246/**
247 * Supported interface types.
248 */
249typedef enum VDINTERFACETYPE
250{
251 /** First valid interface. */
252 VDINTERFACETYPE_FIRST = 0,
253 /** Interface to pass error message to upper layers. Per-disk. */
254 VDINTERFACETYPE_ERROR = VDINTERFACETYPE_FIRST,
255 /** Interface for asynchronous I/O operations. Per-disk. */
256 VDINTERFACETYPE_ASYNCIO,
257 /** Interface for progress notification. Per-operation. */
258 VDINTERFACETYPE_PROGRESS,
259 /** Interface for configuration information. Per-image. */
260 VDINTERFACETYPE_CONFIG,
261 /** Interface for TCP network stack. Per-disk. */
262 VDINTERFACETYPE_TCPNET,
263 /** Interface for getting parent image state. Per-operation. */
264 VDINTERFACETYPE_PARENTSTATE,
265 /** Interface for synchronizing accesses from several threads. Per-disk. */
266 VDINTERFACETYPE_THREADSYNC,
267 /** Interface for I/O between the generic VBoxHDD code and the backend. Per-image. */
268 VDINTERFACETYPE_IO,
269 /** invalid interface. */
270 VDINTERFACETYPE_INVALID
271} VDINTERFACETYPE;
272
273/**
274 * Common structure for all interfaces.
275 */
276typedef struct VDINTERFACE
277{
278 /** Human readable interface name. */
279 const char *pszInterfaceName;
280 /** The size of the struct. */
281 uint32_t cbSize;
282 /** Pointer to the next common interface structure. */
283 struct VDINTERFACE *pNext;
284 /** Interface type. */
285 VDINTERFACETYPE enmInterface;
286 /** Opaque user data which is passed on every call. */
287 void *pvUser;
288 /** Pointer to the function call table of the interface.
289 * As this is opaque this must be casted to the right interface
290 * struct defined below based on the interface type in enmInterface. */
291 void *pCallbacks;
292} VDINTERFACE;
293/** Pointer to a VDINTERFACE. */
294typedef VDINTERFACE *PVDINTERFACE;
295/** Pointer to a const VDINTERFACE. */
296typedef const VDINTERFACE *PCVDINTERFACE;
297
298/**
299 * Helper functions to handle interface lists.
300 *
301 * @note These interface lists are used consistently to pass per-disk,
302 * per-image and/or per-operation callbacks. Those three purposes are strictly
303 * separate. See the individual interface declarations for what context they
304 * apply to. The caller is responsible for ensuring that the lifetime of the
305 * interface descriptors is appropriate for the category of interface.
306 */
307
308/**
309 * Get a specific interface from a list of interfaces specified by the type.
310 *
311 * @return Pointer to the matching interface or NULL if none was found.
312 * @param pVDIfs Pointer to the VD interface list.
313 * @param enmInterface Interface to search for.
314 */
315DECLINLINE(PVDINTERFACE) VDInterfaceGet(PVDINTERFACE pVDIfs, VDINTERFACETYPE enmInterface)
316{
317 AssertMsgReturn( enmInterface >= VDINTERFACETYPE_FIRST
318 && enmInterface < VDINTERFACETYPE_INVALID,
319 ("enmInterface=%u", enmInterface), NULL);
320
321 while (pVDIfs)
322 {
323 /* Sanity checks. */
324 AssertMsgBreak(pVDIfs->cbSize == sizeof(VDINTERFACE),
325 ("cbSize=%u\n", pVDIfs->cbSize));
326
327 if (pVDIfs->enmInterface == enmInterface)
328 return pVDIfs;
329 pVDIfs = pVDIfs->pNext;
330 }
331
332 /* No matching interface was found. */
333 return NULL;
334}
335
336/**
337 * Add an interface to a list of interfaces.
338 *
339 * @return VBox status code.
340 * @param pInterface Pointer to an unitialized common interface structure.
341 * @param pszName Name of the interface.
342 * @param enmInterface Type of the interface.
343 * @param pCallbacks The callback table of the interface.
344 * @param pvUser Opaque user data passed on every function call.
345 * @param ppVDIfs Pointer to the VD interface list.
346 */
347DECLINLINE(int) VDInterfaceAdd(PVDINTERFACE pInterface, const char *pszName,
348 VDINTERFACETYPE enmInterface, void *pCallbacks,
349 void *pvUser, PVDINTERFACE *ppVDIfs)
350{
351 /* Argument checks. */
352 AssertMsgReturn( enmInterface >= VDINTERFACETYPE_FIRST
353 && enmInterface < VDINTERFACETYPE_INVALID,
354 ("enmInterface=%u", enmInterface), VERR_INVALID_PARAMETER);
355
356 AssertMsgReturn(VALID_PTR(pCallbacks),
357 ("pCallbacks=%#p", pCallbacks),
358 VERR_INVALID_PARAMETER);
359
360 AssertMsgReturn(VALID_PTR(ppVDIfs),
361 ("pInterfaceList=%#p", ppVDIfs),
362 VERR_INVALID_PARAMETER);
363
364 /* Fill out interface descriptor. */
365 pInterface->cbSize = sizeof(VDINTERFACE);
366 pInterface->pszInterfaceName = pszName;
367 pInterface->enmInterface = enmInterface;
368 pInterface->pCallbacks = pCallbacks;
369 pInterface->pvUser = pvUser;
370 pInterface->pNext = *ppVDIfs;
371
372 /* Remember the new start of the list. */
373 *ppVDIfs = pInterface;
374
375 return VINF_SUCCESS;
376}
377
378/**
379 * Removes an interface from a list of interfaces.
380 *
381 * @return VBox status code
382 * @param pInterface Pointer to an initialized common interface structure to remove.
383 * @param ppVDIfs Pointer to the VD interface list to remove from.
384 */
385DECLINLINE(int) VDInterfaceRemove(PVDINTERFACE pInterface, PVDINTERFACE *ppVDIfs)
386{
387 int rc = VERR_NOT_FOUND;
388
389 /* Argument checks. */
390 AssertMsgReturn(VALID_PTR(pInterface),
391 ("pInterface=%#p", pInterface),
392 VERR_INVALID_PARAMETER);
393
394 AssertMsgReturn(VALID_PTR(ppVDIfs),
395 ("pInterfaceList=%#p", ppVDIfs),
396 VERR_INVALID_PARAMETER);
397
398 if (*ppVDIfs)
399 {
400 PVDINTERFACE pPrev = NULL;
401 PVDINTERFACE pCurr = *ppVDIfs;
402
403 while ( pCurr
404 && (pCurr != pInterface))
405 {
406 pPrev = pCurr;
407 pCurr = pCurr->pNext;
408 }
409
410 /* First interface */
411 if (!pPrev)
412 {
413 *ppVDIfs = pCurr->pNext;
414 rc = VINF_SUCCESS;
415 }
416 else if (pCurr)
417 {
418 pPrev = pCurr->pNext;
419 rc = VINF_SUCCESS;
420 }
421 }
422
423 return rc;
424}
425
426/**
427 * Interface to deliver error messages (and also informational messages)
428 * to upper layers.
429 *
430 * Per disk interface. Optional, but think twice if you want to miss the
431 * opportunity of reporting better human-readable error messages.
432 */
433typedef struct VDINTERFACEERROR
434{
435 /**
436 * Size of the error interface.
437 */
438 uint32_t cbSize;
439
440 /**
441 * Interface type.
442 */
443 VDINTERFACETYPE enmInterface;
444
445 /**
446 * Error message callback. Must be able to accept special IPRT format
447 * strings.
448 *
449 * @param pvUser The opaque data passed on container creation.
450 * @param rc The VBox error code.
451 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
452 * @param pszFormat Error message format string.
453 * @param va Error message arguments.
454 */
455 DECLR3CALLBACKMEMBER(void, pfnError, (void *pvUser, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
456
457 /**
458 * Informational message callback. May be NULL. Used e.g. in
459 * VDDumpImages(). Must be able to accept special IPRT format strings.
460 *
461 * @return VBox status code.
462 * @param pvUser The opaque data passed on container creation.
463 * @param pszFormat Message format string.
464 * @param va Message arguments.
465 */
466 DECLR3CALLBACKMEMBER(int, pfnMessage, (void *pvUser, const char *pszFormat, va_list va));
467
468} VDINTERFACEERROR, *PVDINTERFACEERROR;
469
470/**
471 * Get error interface from opaque callback table.
472 *
473 * @return Pointer to the callback table.
474 * @param pInterface Pointer to the interface descriptor.
475 */
476DECLINLINE(PVDINTERFACEERROR) VDGetInterfaceError(PVDINTERFACE pInterface)
477{
478 PVDINTERFACEERROR pInterfaceError;
479
480 /* Check that the interface descriptor is a error interface. */
481 AssertMsgReturn( pInterface->enmInterface == VDINTERFACETYPE_ERROR
482 && pInterface->cbSize == sizeof(VDINTERFACE),
483 ("Not an error interface"), NULL);
484
485 pInterfaceError = (PVDINTERFACEERROR)pInterface->pCallbacks;
486
487 /* Do basic checks. */
488 AssertMsgReturn( pInterfaceError->cbSize == sizeof(VDINTERFACEERROR)
489 && pInterfaceError->enmInterface == VDINTERFACETYPE_ERROR,
490 ("A non error callback table attached to a error interface descriptor\n"), NULL);
491
492 return pInterfaceError;
493}
494
495/**
496 * Completion callback which is called by the interface owner
497 * to inform the backend that a task finished.
498 *
499 * @return VBox status code.
500 * @param pvUser Opaque user data which is passed on request submission.
501 * @param rcReq Status code of the completed request.
502 */
503typedef DECLCALLBACK(int) FNVDCOMPLETED(void *pvUser, int rcReq);
504/** Pointer to FNVDCOMPLETED() */
505typedef FNVDCOMPLETED *PFNVDCOMPLETED;
506
507/**
508 * Support interface for asynchronous I/O
509 *
510 * Per-disk. Optional.
511 */
512typedef struct VDINTERFACEASYNCIO
513{
514 /**
515 * Size of the async interface.
516 */
517 uint32_t cbSize;
518
519 /**
520 * Interface type.
521 */
522 VDINTERFACETYPE enmInterface;
523
524 /**
525 * Open callback
526 *
527 * @return VBox status code.
528 * @param pvUser The opaque data passed on container creation.
529 * @param pszLocation Name of the location to open.
530 * @param fOpen Flags for opening the backend.
531 * See RTFILE_O_* #defines, inventing another set
532 * of open flags is not worth the mapping effort.
533 * @param pfnCompleted The callback which is called whenever a task
534 * completed. The backend has to pass the user data
535 * of the request initiator (ie the one who calls
536 * VDAsyncRead or VDAsyncWrite) in pvCompletion
537 * if this is NULL.
538 * @param pVDIfsDisk Pointer to the per-disk VD interface list.
539 * @param ppStorage Where to store the opaque storage handle.
540 */
541 DECLR3CALLBACKMEMBER(int, pfnOpen, (void *pvUser, const char *pszLocation,
542 uint32_t fOpen,
543 PFNVDCOMPLETED pfnCompleted,
544 PVDINTERFACE pVDIfsDisk,
545 void **ppStorage));
546
547 /**
548 * Close callback.
549 *
550 * @return VBox status code.
551 * @param pvUser The opaque data passed on container creation.
552 * @param pStorage The opaque storage handle to close.
553 */
554 DECLR3CALLBACKMEMBER(int, pfnClose, (void *pvUser, void *pStorage));
555
556 /**
557 * Returns the size of the opened storage backend.
558 *
559 * @return VBox status code.
560 * @param pvUser The opaque data passed on container creation.
561 * @param pStorage The opaque storage handle to close.
562 * @param pcbSize Where to store the size of the storage backend.
563 */
564 DECLR3CALLBACKMEMBER(int, pfnGetSize, (void *pvUser, void *pStorage, uint64_t *pcbSize));
565
566 /**
567 * Sets the size of the opened storage backend if possible.
568 *
569 * @return VBox status code.
570 * @retval VERR_NOT_SUPPORTED if the backend does not support this operation.
571 * @param pvUser The opaque data passed on container creation.
572 * @param pStorage The opaque storage handle to close.
573 * @param cbSize The new size of the image.
574 */
575 DECLR3CALLBACKMEMBER(int, pfnSetSize, (void *pvUser, void *pStorage, uint64_t cbSize));
576
577 /**
578 * Synchronous write callback.
579 *
580 * @return VBox status code.
581 * @param pvUser The opaque data passed on container creation.
582 * @param pStorage The storage handle to use.
583 * @param uOffset The offset to start from.
584 * @param pvBuffer Pointer to the bits need to be written.
585 * @param cbBuffer How many bytes to write.
586 * @param pcbWritten Where to store how many bytes where actually written.
587 */
588 DECLR3CALLBACKMEMBER(int, pfnWriteSync, (void *pvUser, void *pStorage, uint64_t uOffset,
589 const void *pvBuffer, size_t cbBuffer, size_t *pcbWritten));
590
591 /**
592 * Synchronous read callback.
593 *
594 * @return VBox status code.
595 * @param pvUser The opaque data passed on container creation.
596 * @param pStorage The storage handle to use.
597 * @param uOffset The offset to start from.
598 * @param pvBuffer Where to store the read bits.
599 * @param cbBuffer How many bytes to read.
600 * @param pcbRead Where to store how many bytes where actually read.
601 */
602 DECLR3CALLBACKMEMBER(int, pfnReadSync, (void *pvUser, void *pStorage, uint64_t uOffset,
603 void *pvBuffer, size_t cbBuffer, size_t *pcbRead));
604
605 /**
606 * Flush data to the storage backend.
607 *
608 * @return VBox status code.
609 * @param pvUser The opaque data passed on container creation.
610 * @param pStorage The storage handle to flush.
611 */
612 DECLR3CALLBACKMEMBER(int, pfnFlushSync, (void *pvUser, void *pStorage));
613
614 /**
615 * Initiate a asynchronous read request.
616 *
617 * @return VBox status code.
618 * @param pvUser The opqaue user data passed on container creation.
619 * @param pStorage The storage handle.
620 * @param uOffset The offset to start reading from.
621 * @param paSegments Scatter gather list to store the data in.
622 * @param cSegments Number of segments in the list.
623 * @param cbRead How many bytes to read.
624 * @param pvCompletion The opaque user data which is returned upon completion.
625 * @param ppTask Where to store the opaque task handle.
626 */
627 DECLR3CALLBACKMEMBER(int, pfnReadAsync, (void *pvUser, void *pStorage, uint64_t uOffset,
628 PCRTSGSEG paSegments, size_t cSegments,
629 size_t cbRead, void *pvCompletion,
630 void **ppTask));
631
632 /**
633 * Initiate a asynchronous write request.
634 *
635 * @return VBox status code.
636 * @param pvUser The opaque user data passed on conatiner creation.
637 * @param pStorage The storage handle.
638 * @param uOffset The offset to start writing to.
639 * @param paSegments Scatter gather list of the data to write
640 * @param cSegments Number of segments in the list.
641 * @param cbWrite How many bytes to write.
642 * @param pvCompletion The opaque user data which is returned upon completion.
643 * @param ppTask Where to store the opaque task handle.
644 */
645 DECLR3CALLBACKMEMBER(int, pfnWriteAsync, (void *pvUser, void *pStorage, uint64_t uOffset,
646 PCRTSGSEG paSegments, size_t cSegments,
647 size_t cbWrite, void *pvCompletion,
648 void **ppTask));
649
650 /**
651 * Initiates a async flush request.
652 *
653 * @return VBox status code.
654 * @param pvUser The opaque data passed on container creation.
655 * @param pStorage The storage handle to flush.
656 * @param pvCompletion The opaque user data which is returned upon completion.
657 * @param ppTask Where to store the opaque task handle.
658 */
659 DECLR3CALLBACKMEMBER(int, pfnFlushAsync, (void *pvUser, void *pStorage,
660 void *pvCompletion, void **ppTask));
661
662} VDINTERFACEASYNCIO, *PVDINTERFACEASYNCIO;
663
664/**
665 * Get async I/O interface from opaque callback table.
666 *
667 * @return Pointer to the callback table.
668 * @param pInterface Pointer to the interface descriptor.
669 */
670DECLINLINE(PVDINTERFACEASYNCIO) VDGetInterfaceAsyncIO(PVDINTERFACE pInterface)
671{
672 PVDINTERFACEASYNCIO pInterfaceAsyncIO;
673
674 /* Check that the interface descriptor is a async I/O interface. */
675 AssertMsgReturn( (pInterface->enmInterface == VDINTERFACETYPE_ASYNCIO)
676 && (pInterface->cbSize == sizeof(VDINTERFACE)),
677 ("Not an async I/O interface"), NULL);
678
679 pInterfaceAsyncIO = (PVDINTERFACEASYNCIO)pInterface->pCallbacks;
680
681 /* Do basic checks. */
682 AssertMsgReturn( (pInterfaceAsyncIO->cbSize == sizeof(VDINTERFACEASYNCIO))
683 && (pInterfaceAsyncIO->enmInterface == VDINTERFACETYPE_ASYNCIO),
684 ("A non async I/O callback table attached to a async I/O interface descriptor\n"), NULL);
685
686 return pInterfaceAsyncIO;
687}
688
689/**
690 * Callback which provides progress information about a currently running
691 * lengthy operation.
692 *
693 * @return VBox status code.
694 * @param pvUser The opaque user data associated with this interface.
695 * @param uPercent Completion percentage.
696 */
697typedef DECLCALLBACK(int) FNVDPROGRESS(void *pvUser, unsigned uPercentage);
698/** Pointer to FNVDPROGRESS() */
699typedef FNVDPROGRESS *PFNVDPROGRESS;
700
701/**
702 * Progress notification interface
703 *
704 * Per-operation. Optional.
705 */
706typedef struct VDINTERFACEPROGRESS
707{
708 /**
709 * Size of the progress interface.
710 */
711 uint32_t cbSize;
712
713 /**
714 * Interface type.
715 */
716 VDINTERFACETYPE enmInterface;
717
718 /**
719 * Progress notification callbacks.
720 */
721 PFNVDPROGRESS pfnProgress;
722
723} VDINTERFACEPROGRESS, *PVDINTERFACEPROGRESS;
724
725/**
726 * Get progress interface from opaque callback table.
727 *
728 * @return Pointer to the callback table.
729 * @param pInterface Pointer to the interface descriptor.
730 */
731DECLINLINE(PVDINTERFACEPROGRESS) VDGetInterfaceProgress(PVDINTERFACE pInterface)
732{
733 PVDINTERFACEPROGRESS pInterfaceProgress;
734
735 /* Check that the interface descriptor is a progress interface. */
736 AssertMsgReturn( (pInterface->enmInterface == VDINTERFACETYPE_PROGRESS)
737 && (pInterface->cbSize == sizeof(VDINTERFACE)),
738 ("Not a progress interface"), NULL);
739
740
741 pInterfaceProgress = (PVDINTERFACEPROGRESS)pInterface->pCallbacks;
742
743 /* Do basic checks. */
744 AssertMsgReturn( (pInterfaceProgress->cbSize == sizeof(VDINTERFACEPROGRESS))
745 && (pInterfaceProgress->enmInterface == VDINTERFACETYPE_PROGRESS),
746 ("A non progress callback table attached to a progress interface descriptor\n"), NULL);
747
748 return pInterfaceProgress;
749}
750
751
752/**
753 * Configuration information interface
754 *
755 * Per-image. Optional for most backends, but mandatory for images which do
756 * not operate on files (including standard block or character devices).
757 */
758typedef struct VDINTERFACECONFIG
759{
760 /**
761 * Size of the configuration interface.
762 */
763 uint32_t cbSize;
764
765 /**
766 * Interface type.
767 */
768 VDINTERFACETYPE enmInterface;
769
770 /**
771 * Validates that the keys are within a set of valid names.
772 *
773 * @return true if all key names are found in pszzAllowed.
774 * @return false if not.
775 * @param pvUser The opaque user data associated with this interface.
776 * @param pszzValid List of valid key names separated by '\\0' and ending with
777 * a double '\\0'.
778 */
779 DECLR3CALLBACKMEMBER(bool, pfnAreKeysValid, (void *pvUser, const char *pszzValid));
780
781 /**
782 * Retrieves the length of the string value associated with a key (including
783 * the terminator, for compatibility with CFGMR3QuerySize).
784 *
785 * @return VBox status code.
786 * VERR_CFGM_VALUE_NOT_FOUND means that the key is not known.
787 * @param pvUser The opaque user data associated with this interface.
788 * @param pszName Name of the key to query.
789 * @param pcbValue Where to store the value length. Non-NULL.
790 */
791 DECLR3CALLBACKMEMBER(int, pfnQuerySize, (void *pvUser, const char *pszName, size_t *pcbValue));
792
793 /**
794 * Query the string value associated with a key.
795 *
796 * @return VBox status code.
797 * VERR_CFGM_VALUE_NOT_FOUND means that the key is not known.
798 * VERR_CFGM_NOT_ENOUGH_SPACE means that the buffer is not big enough.
799 * @param pvUser The opaque user data associated with this interface.
800 * @param pszName Name of the key to query.
801 * @param pszValue Pointer to buffer where to store value.
802 * @param cchValue Length of value buffer.
803 */
804 DECLR3CALLBACKMEMBER(int, pfnQuery, (void *pvUser, const char *pszName, char *pszValue, size_t cchValue));
805
806} VDINTERFACECONFIG, *PVDINTERFACECONFIG;
807
808/**
809 * Get configuration information interface from opaque callback table.
810 *
811 * @return Pointer to the callback table.
812 * @param pInterface Pointer to the interface descriptor.
813 */
814DECLINLINE(PVDINTERFACECONFIG) VDGetInterfaceConfig(PVDINTERFACE pInterface)
815{
816 PVDINTERFACECONFIG pInterfaceConfig;
817
818 /* Check that the interface descriptor is a config interface. */
819 AssertMsgReturn( (pInterface->enmInterface == VDINTERFACETYPE_CONFIG)
820 && (pInterface->cbSize == sizeof(VDINTERFACE)),
821 ("Not a config interface"), NULL);
822
823 pInterfaceConfig = (PVDINTERFACECONFIG)pInterface->pCallbacks;
824
825 /* Do basic checks. */
826 AssertMsgReturn( (pInterfaceConfig->cbSize == sizeof(VDINTERFACECONFIG))
827 && (pInterfaceConfig->enmInterface == VDINTERFACETYPE_CONFIG),
828 ("A non config callback table attached to a config interface descriptor\n"), NULL);
829
830 return pInterfaceConfig;
831}
832
833/**
834 * Query configuration, validates that the keys are within a set of valid names.
835 *
836 * @return true if all key names are found in pszzAllowed.
837 * @return false if not.
838 * @param pCfgIf Pointer to configuration callback table.
839 * @param pvUser The opaque user data associated with this interface.
840 * @param pszzValid List of valid names separated by '\\0' and ending with
841 * a double '\\0'.
842 */
843DECLINLINE(bool) VDCFGAreKeysValid(PVDINTERFACECONFIG pCfgIf, void *pvUser,
844 const char *pszzValid)
845{
846 return pCfgIf->pfnAreKeysValid(pvUser, pszzValid);
847}
848
849/**
850 * Query configuration, unsigned 64-bit integer value with default.
851 *
852 * @return VBox status code.
853 * @param pCfgIf Pointer to configuration callback table.
854 * @param pvUser The opaque user data associated with this interface.
855 * @param pszName Name of an integer value
856 * @param pu64 Where to store the value. Set to default on failure.
857 * @param u64Def The default value.
858 */
859DECLINLINE(int) VDCFGQueryU64Def(PVDINTERFACECONFIG pCfgIf, void *pvUser,
860 const char *pszName, uint64_t *pu64,
861 uint64_t u64Def)
862{
863 char aszBuf[32];
864 int rc = pCfgIf->pfnQuery(pvUser, pszName, aszBuf, sizeof(aszBuf));
865 if (RT_SUCCESS(rc))
866 {
867 rc = RTStrToUInt64Full(aszBuf, 0, pu64);
868 }
869 else if (rc == VERR_CFGM_VALUE_NOT_FOUND)
870 {
871 rc = VINF_SUCCESS;
872 *pu64 = u64Def;
873 }
874 return rc;
875}
876
877/**
878 * Query configuration, unsigned 32-bit integer value with default.
879 *
880 * @return VBox status code.
881 * @param pCfgIf Pointer to configuration callback table.
882 * @param pvUser The opaque user data associated with this interface.
883 * @param pszName Name of an integer value
884 * @param pu32 Where to store the value. Set to default on failure.
885 * @param u32Def The default value.
886 */
887DECLINLINE(int) VDCFGQueryU32Def(PVDINTERFACECONFIG pCfgIf, void *pvUser,
888 const char *pszName, uint32_t *pu32,
889 uint32_t u32Def)
890{
891 uint64_t u64;
892 int rc = VDCFGQueryU64Def(pCfgIf, pvUser, pszName, &u64, u32Def);
893 if (RT_SUCCESS(rc))
894 {
895 if (!(u64 & UINT64_C(0xffffffff00000000)))
896 *pu32 = (uint32_t)u64;
897 else
898 rc = VERR_CFGM_INTEGER_TOO_BIG;
899 }
900 return rc;
901}
902
903/**
904 * Query configuration, bool value with default.
905 *
906 * @return VBox status code.
907 * @param pCfgIf Pointer to configuration callback table.
908 * @param pvUser The opaque user data associated with this interface.
909 * @param pszName Name of an integer value
910 * @param pf Where to store the value. Set to default on failure.
911 * @param fDef The default value.
912 */
913DECLINLINE(int) VDCFGQueryBoolDef(PVDINTERFACECONFIG pCfgIf, void *pvUser,
914 const char *pszName, bool *pf,
915 bool fDef)
916{
917 uint64_t u64;
918 int rc = VDCFGQueryU64Def(pCfgIf, pvUser, pszName, &u64, fDef);
919 if (RT_SUCCESS(rc))
920 *pf = u64 ? true : false;
921 return rc;
922}
923
924/**
925 * Query configuration, dynamically allocated (RTMemAlloc) zero terminated
926 * character value.
927 *
928 * @return VBox status code.
929 * @param pCfgIf Pointer to configuration callback table.
930 * @param pvUser The opaque user data associated with this interface.
931 * @param pszName Name of an zero terminated character value
932 * @param ppszString Where to store the string pointer. Not set on failure.
933 * Free this using RTMemFree().
934 */
935DECLINLINE(int) VDCFGQueryStringAlloc(PVDINTERFACECONFIG pCfgIf,
936 void *pvUser, const char *pszName,
937 char **ppszString)
938{
939 size_t cb;
940 int rc = pCfgIf->pfnQuerySize(pvUser, pszName, &cb);
941 if (RT_SUCCESS(rc))
942 {
943 char *pszString = (char *)RTMemAlloc(cb);
944 if (pszString)
945 {
946 rc = pCfgIf->pfnQuery(pvUser, pszName, pszString, cb);
947 if (RT_SUCCESS(rc))
948 *ppszString = pszString;
949 else
950 RTMemFree(pszString);
951 }
952 else
953 rc = VERR_NO_MEMORY;
954 }
955 return rc;
956}
957
958/**
959 * Query configuration, dynamically allocated (RTMemAlloc) zero terminated
960 * character value with default.
961 *
962 * @return VBox status code.
963 * @param pCfgIf Pointer to configuration callback table.
964 * @param pvUser The opaque user data associated with this interface.
965 * @param pszName Name of an zero terminated character value
966 * @param ppszString Where to store the string pointer. Not set on failure.
967 * Free this using RTMemFree().
968 * @param pszDef The default value.
969 */
970DECLINLINE(int) VDCFGQueryStringAllocDef(PVDINTERFACECONFIG pCfgIf,
971 void *pvUser, const char *pszName,
972 char **ppszString,
973 const char *pszDef)
974{
975 size_t cb;
976 int rc = pCfgIf->pfnQuerySize(pvUser, pszName, &cb);
977 if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)
978 {
979 cb = strlen(pszDef) + 1;
980 rc = VINF_SUCCESS;
981 }
982 if (RT_SUCCESS(rc))
983 {
984 char *pszString = (char *)RTMemAlloc(cb);
985 if (pszString)
986 {
987 rc = pCfgIf->pfnQuery(pvUser, pszName, pszString, cb);
988 if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)
989 {
990 memcpy(pszString, pszDef, cb);
991 rc = VINF_SUCCESS;
992 }
993 if (RT_SUCCESS(rc))
994 *ppszString = pszString;
995 else
996 RTMemFree(pszString);
997 }
998 else
999 rc = VERR_NO_MEMORY;
1000 }
1001 return rc;
1002}
1003
1004/**
1005 * Query configuration, dynamically allocated (RTMemAlloc) byte string value.
1006 *
1007 * @return VBox status code.
1008 * @param pCfgIf Pointer to configuration callback table.
1009 * @param pvUser The opaque user data associated with this interface.
1010 * @param pszName Name of an zero terminated character value
1011 * @param ppvData Where to store the byte string pointer. Not set on failure.
1012 * Free this using RTMemFree().
1013 * @param pcbData Where to store the byte string length.
1014 */
1015DECLINLINE(int) VDCFGQueryBytesAlloc(PVDINTERFACECONFIG pCfgIf,
1016 void *pvUser, const char *pszName,
1017 void **ppvData, size_t *pcbData)
1018{
1019 size_t cb;
1020 int rc = pCfgIf->pfnQuerySize(pvUser, pszName, &cb);
1021 if (RT_SUCCESS(rc))
1022 {
1023 char *pbData;
1024 Assert(cb);
1025
1026 pbData = (char *)RTMemAlloc(cb);
1027 if (pbData)
1028 {
1029 rc = pCfgIf->pfnQuery(pvUser, pszName, pbData, cb);
1030 if (RT_SUCCESS(rc))
1031 {
1032 *ppvData = pbData;
1033 *pcbData = cb - 1; /* Exclude terminator of the queried string. */
1034 }
1035 else
1036 RTMemFree(pbData);
1037 }
1038 else
1039 rc = VERR_NO_MEMORY;
1040 }
1041 return rc;
1042}
1043
1044/** Forward declaration of a VD socket. */
1045typedef struct VDSOCKETINT *VDSOCKET;
1046/** Pointer to a VD socket. */
1047typedef VDSOCKET *PVDSOCKET;
1048/** Nil socket handle. */
1049#define NIL_VDSOCKET ((VDSOCKET)0)
1050
1051/** Connect flag to indicate that the backend wants to use the extended
1052 * socket I/O multiplexing call. This might not be supported on all configurations
1053 * (internal networking and iSCSI)
1054 * and the backend needs to take appropriate action.
1055 */
1056#define VD_INTERFACETCPNET_CONNECT_EXTENDED_SELECT RT_BIT_32(0)
1057
1058/** @name Select events
1059 * @{ */
1060/** Readable without blocking. */
1061#define VD_INTERFACETCPNET_EVT_READ RT_BIT_32(0)
1062/** Writable without blocking. */
1063#define VD_INTERFACETCPNET_EVT_WRITE RT_BIT_32(1)
1064/** Error condition, hangup, exception or similar. */
1065#define VD_INTERFACETCPNET_EVT_ERROR RT_BIT_32(2)
1066/** Hint for the select that getting interrupted while waiting is more likely.
1067 * The interface implementation can optimize the waiting strategy based on this.
1068 * It is assumed that it is more likely to get one of the above socket events
1069 * instead of being interrupted if the flag is not set. */
1070#define VD_INTERFACETCPNET_HINT_INTERRUPT RT_BIT_32(3)
1071/** Mask of the valid bits. */
1072#define VD_INTERFACETCPNET_EVT_VALID_MASK UINT32_C(0x0000000f)
1073/** @} */
1074
1075/**
1076 * TCP network stack interface
1077 *
1078 * Per-disk. Mandatory for backends which have the VD_CAP_TCPNET bit set.
1079 */
1080typedef struct VDINTERFACETCPNET
1081{
1082 /**
1083 * Size of the configuration interface.
1084 */
1085 uint32_t cbSize;
1086
1087 /**
1088 * Interface type.
1089 */
1090 VDINTERFACETYPE enmInterface;
1091
1092 /**
1093 * Creates a socket. The socket is not connected if this succeeds.
1094 *
1095 * @return iprt status code.
1096 * @retval VERR_NOT_SUPPORTED if the combination of flags is not supported.
1097 * @param fFlags Combination of the VD_INTERFACETCPNET_CONNECT_* #defines.
1098 * @param pSock Where to store the handle.
1099 */
1100 DECLR3CALLBACKMEMBER(int, pfnSocketCreate, (uint32_t fFlags, PVDSOCKET pSock));
1101
1102 /**
1103 * Destroys the socket.
1104 *
1105 * @return iprt status code.
1106 * @param Sock Socket descriptor.
1107 */
1108 DECLR3CALLBACKMEMBER(int, pfnSocketDestroy, (VDSOCKET Sock));
1109
1110 /**
1111 * Connect as a client to a TCP port.
1112 *
1113 * @return iprt status code.
1114 * @param Sock Socket descriptor.
1115 * @param pszAddress The address to connect to.
1116 * @param uPort The port to connect to.
1117 */
1118 DECLR3CALLBACKMEMBER(int, pfnClientConnect, (VDSOCKET Sock, const char *pszAddress, uint32_t uPort));
1119
1120 /**
1121 * Close a TCP connection.
1122 *
1123 * @return iprt status code.
1124 * @param Sock Socket descriptor.
1125 */
1126 DECLR3CALLBACKMEMBER(int, pfnClientClose, (VDSOCKET Sock));
1127
1128 /**
1129 * Returns whether the socket is currently connected to the client.
1130 *
1131 * @returns true if the socket is connected.
1132 * false otherwise.
1133 * @param Sock Socket descriptor.
1134 */
1135 DECLR3CALLBACKMEMBER(bool, pfnIsClientConnected, (VDSOCKET Sock));
1136
1137 /**
1138 * Socket I/O multiplexing.
1139 * Checks if the socket is ready for reading.
1140 *
1141 * @return iprt status code.
1142 * @param Sock Socket descriptor.
1143 * @param cMillies Number of milliseconds to wait for the socket.
1144 * Use RT_INDEFINITE_WAIT to wait for ever.
1145 */
1146 DECLR3CALLBACKMEMBER(int, pfnSelectOne, (VDSOCKET Sock, RTMSINTERVAL cMillies));
1147
1148 /**
1149 * Receive data from a socket.
1150 *
1151 * @return iprt status code.
1152 * @param Sock Socket descriptor.
1153 * @param pvBuffer Where to put the data we read.
1154 * @param cbBuffer Read buffer size.
1155 * @param pcbRead Number of bytes read.
1156 * If NULL the entire buffer will be filled upon successful return.
1157 * If not NULL a partial read can be done successfully.
1158 */
1159 DECLR3CALLBACKMEMBER(int, pfnRead, (VDSOCKET Sock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead));
1160
1161 /**
1162 * Send data to a socket.
1163 *
1164 * @return iprt status code.
1165 * @param Sock Socket descriptor.
1166 * @param pvBuffer Buffer to write data to socket.
1167 * @param cbBuffer How much to write.
1168 */
1169 DECLR3CALLBACKMEMBER(int, pfnWrite, (VDSOCKET Sock, const void *pvBuffer, size_t cbBuffer));
1170
1171 /**
1172 * Send data from scatter/gather buffer to a socket.
1173 *
1174 * @return iprt status code.
1175 * @param Sock Socket descriptor.
1176 * @param pSgBuffer Scatter/gather buffer to write data to socket.
1177 */
1178 DECLR3CALLBACKMEMBER(int, pfnSgWrite, (VDSOCKET Sock, PCRTSGBUF pSgBuffer));
1179
1180 /**
1181 * Receive data from a socket - not blocking.
1182 *
1183 * @return iprt status code.
1184 * @param Sock Socket descriptor.
1185 * @param pvBuffer Where to put the data we read.
1186 * @param cbBuffer Read buffer size.
1187 * @param pcbRead Number of bytes read.
1188 */
1189 DECLR3CALLBACKMEMBER(int, pfnReadNB, (VDSOCKET Sock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead));
1190
1191 /**
1192 * Send data to a socket - not blocking.
1193 *
1194 * @return iprt status code.
1195 * @param Sock Socket descriptor.
1196 * @param pvBuffer Buffer to write data to socket.
1197 * @param cbBuffer How much to write.
1198 * @param pcbWritten Number of bytes written.
1199 */
1200 DECLR3CALLBACKMEMBER(int, pfnWriteNB, (VDSOCKET Sock, const void *pvBuffer, size_t cbBuffer, size_t *pcbWritten));
1201
1202 /**
1203 * Send data from scatter/gather buffer to a socket - not blocking.
1204 *
1205 * @return iprt status code.
1206 * @param Sock Socket descriptor.
1207 * @param pSgBuffer Scatter/gather buffer to write data to socket.
1208 * @param pcbWritten Number of bytes written.
1209 */
1210 DECLR3CALLBACKMEMBER(int, pfnSgWriteNB, (VDSOCKET Sock, PRTSGBUF pSgBuffer, size_t *pcbWritten));
1211
1212 /**
1213 * Flush socket write buffers.
1214 *
1215 * @return iprt status code.
1216 * @param Sock Socket descriptor.
1217 */
1218 DECLR3CALLBACKMEMBER(int, pfnFlush, (VDSOCKET Sock));
1219
1220 /**
1221 * Enables or disables delaying sends to coalesce packets.
1222 *
1223 * @return iprt status code.
1224 * @param Sock Socket descriptor.
1225 * @param fEnable When set to true enables coalescing.
1226 */
1227 DECLR3CALLBACKMEMBER(int, pfnSetSendCoalescing, (VDSOCKET Sock, bool fEnable));
1228
1229 /**
1230 * Gets the address of the local side.
1231 *
1232 * @return iprt status code.
1233 * @param Sock Socket descriptor.
1234 * @param pAddr Where to store the local address on success.
1235 */
1236 DECLR3CALLBACKMEMBER(int, pfnGetLocalAddress, (VDSOCKET Sock, PRTNETADDR pAddr));
1237
1238 /**
1239 * Gets the address of the other party.
1240 *
1241 * @return iprt status code.
1242 * @param Sock Socket descriptor.
1243 * @param pAddr Where to store the peer address on success.
1244 */
1245 DECLR3CALLBACKMEMBER(int, pfnGetPeerAddress, (VDSOCKET Sock, PRTNETADDR pAddr));
1246
1247 /**
1248 * Socket I/O multiplexing - extended version which can be woken up.
1249 * Checks if the socket is ready for reading or writing.
1250 *
1251 * @return iprt status code.
1252 * @retval VERR_INTERRUPTED if the thread was woken up by a pfnPoke call.
1253 * @param Sock Socket descriptor.
1254 * @param fEvents Mask of events to wait for.
1255 * @param pfEvents Where to store the received events.
1256 * @param cMillies Number of milliseconds to wait for the socket.
1257 * Use RT_INDEFINITE_WAIT to wait for ever.
1258 */
1259 DECLR3CALLBACKMEMBER(int, pfnSelectOneEx, (VDSOCKET Sock, uint32_t fEvents,
1260 uint32_t *pfEvents, RTMSINTERVAL cMillies));
1261
1262 /**
1263 * Wakes up the thread waiting in pfnSelectOneEx.
1264 *
1265 * @return iprt status code.
1266 * @param Sock Socket descriptor.
1267 */
1268 DECLR3CALLBACKMEMBER(int, pfnPoke, (VDSOCKET Sock));
1269
1270} VDINTERFACETCPNET, *PVDINTERFACETCPNET;
1271
1272/**
1273 * Get TCP network stack interface from opaque callback table.
1274 *
1275 * @return Pointer to the callback table.
1276 * @param pInterface Pointer to the interface descriptor.
1277 */
1278DECLINLINE(PVDINTERFACETCPNET) VDGetInterfaceTcpNet(PVDINTERFACE pInterface)
1279{
1280 PVDINTERFACETCPNET pInterfaceTcpNet;
1281
1282 /* Check that the interface descriptor is a TCP network stack interface. */
1283 AssertMsgReturn( (pInterface->enmInterface == VDINTERFACETYPE_TCPNET)
1284 && (pInterface->cbSize == sizeof(VDINTERFACE)),
1285 ("Not a TCP network stack interface"), NULL);
1286
1287 pInterfaceTcpNet = (PVDINTERFACETCPNET)pInterface->pCallbacks;
1288
1289 /* Do basic checks. */
1290 AssertMsgReturn( (pInterfaceTcpNet->cbSize == sizeof(VDINTERFACETCPNET))
1291 && (pInterfaceTcpNet->enmInterface == VDINTERFACETYPE_TCPNET),
1292 ("A non TCP network stack callback table attached to a TCP network stack interface descriptor\n"), NULL);
1293
1294 return pInterfaceTcpNet;
1295}
1296
1297/**
1298 * Interface to get the parent state.
1299 *
1300 * Per operation interface. Optional, present only if there is a parent, and
1301 * used only internally for compacting.
1302 */
1303typedef struct VDINTERFACEPARENTSTATE
1304{
1305 /**
1306 * Size of the parent state interface.
1307 */
1308 uint32_t cbSize;
1309
1310 /**
1311 * Interface type.
1312 */
1313 VDINTERFACETYPE enmInterface;
1314
1315 /**
1316 * Read data callback.
1317 *
1318 * @return VBox status code.
1319 * @return VERR_VD_NOT_OPENED if no image is opened in HDD container.
1320 * @param pvUser The opaque data passed for the operation.
1321 * @param uOffset Offset of first reading byte from start of disk.
1322 * Must be aligned to a sector boundary.
1323 * @param pvBuffer Pointer to buffer for reading data.
1324 * @param cbBuffer Number of bytes to read.
1325 * Must be aligned to a sector boundary.
1326 */
1327 DECLR3CALLBACKMEMBER(int, pfnParentRead, (void *pvUser, uint64_t uOffset, void *pvBuffer, size_t cbBuffer));
1328
1329} VDINTERFACEPARENTSTATE, *PVDINTERFACEPARENTSTATE;
1330
1331
1332/**
1333 * Get parent state interface from opaque callback table.
1334 *
1335 * @return Pointer to the callback table.
1336 * @param pInterface Pointer to the interface descriptor.
1337 */
1338DECLINLINE(PVDINTERFACEPARENTSTATE) VDGetInterfaceParentState(PVDINTERFACE pInterface)
1339{
1340 PVDINTERFACEPARENTSTATE pInterfaceParentState;
1341
1342 /* Check that the interface descriptor is a parent state interface. */
1343 AssertMsgReturn( (pInterface->enmInterface == VDINTERFACETYPE_PARENTSTATE)
1344 && (pInterface->cbSize == sizeof(VDINTERFACE)),
1345 ("Not a parent state interface"), NULL);
1346
1347 pInterfaceParentState = (PVDINTERFACEPARENTSTATE)pInterface->pCallbacks;
1348
1349 /* Do basic checks. */
1350 AssertMsgReturn( (pInterfaceParentState->cbSize == sizeof(VDINTERFACEPARENTSTATE))
1351 && (pInterfaceParentState->enmInterface == VDINTERFACETYPE_PARENTSTATE),
1352 ("A non parent state callback table attached to a parent state interface descriptor\n"), NULL);
1353
1354 return pInterfaceParentState;
1355}
1356
1357/**
1358 * Interface to synchronize concurrent accesses by several threads.
1359 *
1360 * @note The scope of this interface is to manage concurrent accesses after
1361 * the HDD container has been created, and they must stop before destroying the
1362 * container. Opening or closing images is covered by the synchronization, but
1363 * that does not mean it is safe to close images while a thread executes
1364 * <link to="VDMerge"/> or <link to="VDCopy"/> operating on these images.
1365 * Making them safe would require the lock to be held during the entire
1366 * operation, which prevents other concurrent acitivities.
1367 *
1368 * @note Right now this is kept as simple as possible, and does not even
1369 * attempt to provide enough information to allow e.g. concurrent write
1370 * accesses to different areas of the disk. The reason is that it is very
1371 * difficult to predict which area of a disk is affected by a write,
1372 * especially when different image formats are mixed. Maybe later a more
1373 * sophisticated interface will be provided which has the necessary information
1374 * about worst case affected areas.
1375 *
1376 * Per disk interface. Optional, needed if the disk is accessed concurrently
1377 * by several threads, e.g. when merging diff images while a VM is running.
1378 */
1379typedef struct VDINTERFACETHREADSYNC
1380{
1381 /**
1382 * Size of the thread synchronization interface.
1383 */
1384 uint32_t cbSize;
1385
1386 /**
1387 * Interface type.
1388 */
1389 VDINTERFACETYPE enmInterface;
1390
1391 /**
1392 * Start a read operation.
1393 */
1394 DECLR3CALLBACKMEMBER(int, pfnStartRead, (void *pvUser));
1395
1396 /**
1397 * Finish a read operation.
1398 */
1399 DECLR3CALLBACKMEMBER(int, pfnFinishRead, (void *pvUser));
1400
1401 /**
1402 * Start a write operation.
1403 */
1404 DECLR3CALLBACKMEMBER(int, pfnStartWrite, (void *pvUser));
1405
1406 /**
1407 * Finish a write operation.
1408 */
1409 DECLR3CALLBACKMEMBER(int, pfnFinishWrite, (void *pvUser));
1410
1411} VDINTERFACETHREADSYNC, *PVDINTERFACETHREADSYNC;
1412
1413/**
1414 * Get thread synchronization interface from opaque callback table.
1415 *
1416 * @return Pointer to the callback table.
1417 * @param pInterface Pointer to the interface descriptor.
1418 */
1419DECLINLINE(PVDINTERFACETHREADSYNC) VDGetInterfaceThreadSync(PVDINTERFACE pInterface)
1420{
1421 PVDINTERFACETHREADSYNC pInterfaceThreadSync;
1422
1423 /* Check that the interface descriptor is a thread synchronization interface. */
1424 AssertMsgReturn( (pInterface->enmInterface == VDINTERFACETYPE_THREADSYNC)
1425 && (pInterface->cbSize == sizeof(VDINTERFACE)),
1426 ("Not a thread synchronization interface"), NULL);
1427
1428 pInterfaceThreadSync = (PVDINTERFACETHREADSYNC)pInterface->pCallbacks;
1429
1430 /* Do basic checks. */
1431 AssertMsgReturn( (pInterfaceThreadSync->cbSize == sizeof(VDINTERFACETHREADSYNC))
1432 && (pInterfaceThreadSync->enmInterface == VDINTERFACETYPE_THREADSYNC),
1433 ("A non thread synchronization callback table attached to a thread synchronization interface descriptor\n"), NULL);
1434
1435 return pInterfaceThreadSync;
1436}
1437
1438/** @name Configuration interface key handling flags.
1439 * @{
1440 */
1441/** Mandatory config key. Not providing a value for this key will cause
1442 * the backend to fail. */
1443#define VD_CFGKEY_MANDATORY RT_BIT(0)
1444/** Expert config key. Not showing it by default in the GUI is is probably
1445 * a good idea, as the average user won't understand it easily. */
1446#define VD_CFGKEY_EXPERT RT_BIT(1)
1447/** @}*/
1448
1449
1450/**
1451 * Configuration value type for configuration information interface.
1452 */
1453typedef enum VDCFGVALUETYPE
1454{
1455 /** Integer value. */
1456 VDCFGVALUETYPE_INTEGER = 1,
1457 /** String value. */
1458 VDCFGVALUETYPE_STRING,
1459 /** Bytestring value. */
1460 VDCFGVALUETYPE_BYTES
1461} VDCFGVALUETYPE;
1462
1463
1464/**
1465 * Structure describing configuration keys required/supported by a backend
1466 * through the config interface.
1467 */
1468typedef struct VDCONFIGINFO
1469{
1470 /** Key name of the configuration. */
1471 const char *pszKey;
1472 /** Pointer to default value (descriptor). NULL if no useful default value
1473 * can be specified. */
1474 const char *pszDefaultValue;
1475 /** Value type for this key. */
1476 VDCFGVALUETYPE enmValueType;
1477 /** Key handling flags (a combination of VD_CFGKEY_* flags). */
1478 uint64_t uKeyFlags;
1479} VDCONFIGINFO;
1480
1481/** Pointer to structure describing configuration keys. */
1482typedef VDCONFIGINFO *PVDCONFIGINFO;
1483
1484/** Pointer to const structure describing configuration keys. */
1485typedef const VDCONFIGINFO *PCVDCONFIGINFO;
1486
1487/**
1488 * Data structure for returning a list of backend capabilities.
1489 */
1490typedef struct VDBACKENDINFO
1491{
1492 /** Name of the backend. Must be unique even with case insensitive comparison. */
1493 const char *pszBackend;
1494 /** Capabilities of the backend (a combination of the VD_CAP_* flags). */
1495 uint64_t uBackendCaps;
1496 /** Pointer to a NULL-terminated array of strings, containing the supported
1497 * file extensions. Note that some backends do not work on files, so this
1498 * pointer may just contain NULL. */
1499 const char * const *papszFileExtensions;
1500 /** Pointer to an array of structs describing each supported config key.
1501 * Terminated by a NULL config key. Note that some backends do not support
1502 * the configuration interface, so this pointer may just contain NULL.
1503 * Mandatory if the backend sets VD_CAP_CONFIG. */
1504 PCVDCONFIGINFO paConfigInfo;
1505 /** Returns a human readable hard disk location string given a
1506 * set of hard disk configuration keys. The returned string is an
1507 * equivalent of the full file path for image-based hard disks.
1508 * Mandatory for backends with no VD_CAP_FILE and NULL otherwise. */
1509 DECLR3CALLBACKMEMBER(int, pfnComposeLocation, (PVDINTERFACE pConfig, char **pszLocation));
1510 /** Returns a human readable hard disk name string given a
1511 * set of hard disk configuration keys. The returned string is an
1512 * equivalent of the file name part in the full file path for
1513 * image-based hard disks. Mandatory for backends with no
1514 * VD_CAP_FILE and NULL otherwise. */
1515 DECLR3CALLBACKMEMBER(int, pfnComposeName, (PVDINTERFACE pConfig, char **pszName));
1516} VDBACKENDINFO, *PVDBACKENDINFO;
1517
1518
1519/** Forward declaration. Only visible in the VBoxHDD module. */
1520/** I/O context */
1521typedef struct VDIOCTX *PVDIOCTX;
1522/** Storage backend handle. */
1523typedef struct VDIOSTORAGE *PVDIOSTORAGE;
1524/** Pointer to a storage backend handle. */
1525typedef PVDIOSTORAGE *PPVDIOSTORAGE;
1526
1527/**
1528 * Completion callback for meta/userdata reads or writes.
1529 *
1530 * @return VBox status code.
1531 * VINF_SUCCESS if everything was successful and the transfer can continue.
1532 * VERR_VD_ASYNC_IO_IN_PROGRESS if there is another data transfer pending.
1533 * @param pBackendData The opaque backend data.
1534 * @param pIoCtx I/O context associated with this request.
1535 * @param pvUser Opaque user data passed during a read/write request.
1536 * @param rcReq Status code for the completed request.
1537 */
1538typedef DECLCALLBACK(int) FNVDXFERCOMPLETED(void *pBackendData, PVDIOCTX pIoCtx, void *pvUser, int rcReq);
1539/** Pointer to FNVDXFERCOMPLETED() */
1540typedef FNVDXFERCOMPLETED *PFNVDXFERCOMPLETED;
1541
1542/** Metadata transfer handle. */
1543typedef struct VDMETAXFER *PVDMETAXFER;
1544/** Pointer to a metadata transfer handle. */
1545typedef PVDMETAXFER *PPVDMETAXFER;
1546
1547
1548/**
1549 * Support interface for file I/O
1550 *
1551 * Per-image. Optional as input, always passed to backends.
1552 */
1553typedef struct VDINTERFACEIO
1554{
1555 /**
1556 * Size of the I/O interface.
1557 */
1558 uint32_t cbSize;
1559
1560 /**
1561 * Interface type.
1562 */
1563 VDINTERFACETYPE enmInterface;
1564
1565 /**
1566 * Open callback
1567 *
1568 * @return VBox status code.
1569 * @param pvUser The opaque data passed on container creation.
1570 * @param pszLocation Name of the location to open.
1571 * @param fOpen Flags for opening the backend.
1572 * See RTFILE_O_* #defines, inventing another set
1573 * of open flags is not worth the mapping effort.
1574 * @param ppStorage Where to store the storage handle.
1575 */
1576 DECLR3CALLBACKMEMBER(int, pfnOpen, (void *pvUser, const char *pszLocation,
1577 uint32_t fOpen, PPVDIOSTORAGE ppStorage));
1578
1579 /**
1580 * Close callback.
1581 *
1582 * @return VBox status code.
1583 * @param pvUser The opaque data passed on container creation.
1584 * @param pStorage The storage handle to close.
1585 */
1586 DECLR3CALLBACKMEMBER(int, pfnClose, (void *pvUser, PVDIOSTORAGE pStorage));
1587
1588 /**
1589 * Delete callback.
1590 *
1591 * @return VBox status code.
1592 * @param pvUser The opaque data passed on container creation.
1593 * @param pcszFilename Name of the file to delete.
1594 */
1595 DECLR3CALLBACKMEMBER(int, pfnDelete, (void *pvUser, const char *pcszFilename));
1596
1597 /**
1598 * Move callback.
1599 *
1600 * @return VBox status code.
1601 * @param pvUser The opaque data passed on container creation.
1602 * @param pcszSrc The path to the source file.
1603 * @param pcszDst The path to the destination file.
1604 * This file will be created.
1605 * @param fMove A combination of the RTFILEMOVE_* flags.
1606 */
1607 DECLR3CALLBACKMEMBER(int, pfnMove, (void *pvUser, const char *pcszSrc, const char *pcszDst, unsigned fMove));
1608
1609 /**
1610 * Returns the free space on a disk.
1611 *
1612 * @return VBox status code.
1613 * @param pvUser The opaque data passed on container creation.
1614 * @param pcszFilename Name of a file to identify the disk.
1615 * @param pcbFreeSpace Where to store the free space of the disk.
1616 */
1617 DECLR3CALLBACKMEMBER(int, pfnGetFreeSpace, (void *pvUser, const char *pcszFilename, int64_t *pcbFreeSpace));
1618
1619 /**
1620 * Returns the last modification timestamp of a file.
1621 *
1622 * @return VBox status code.
1623 * @param pvUser The opaque data passed on container creation.
1624 * @param pcszFilename Name of a file to identify the disk.
1625 * @param pModificationTime Where to store the timestamp of the file.
1626 */
1627 DECLR3CALLBACKMEMBER(int, pfnGetModificationTime, (void *pvUser, const char *pcszFilename, PRTTIMESPEC pModificationTime));
1628
1629 /**
1630 * Returns the size of the opened storage backend.
1631 *
1632 * @return VBox status code.
1633 * @param pvUser The opaque data passed on container creation.
1634 * @param pStorage The storage handle to get the size from.
1635 * @param pcbSize Where to store the size of the storage backend.
1636 */
1637 DECLR3CALLBACKMEMBER(int, pfnGetSize, (void *pvUser, PVDIOSTORAGE pStorage,
1638 uint64_t *pcbSize));
1639
1640 /**
1641 * Sets the size of the opened storage backend if possible.
1642 *
1643 * @return VBox status code.
1644 * @retval VERR_NOT_SUPPORTED if the backend does not support this operation.
1645 * @param pvUser The opaque data passed on container creation.
1646 * @param pStorage The storage handle.
1647 * @param cbSize The new size of the image.
1648 */
1649 DECLR3CALLBACKMEMBER(int, pfnSetSize, (void *pvUser, PVDIOSTORAGE pStorage,
1650 uint64_t cbSize));
1651
1652 /**
1653 * Synchronous write callback.
1654 *
1655 * @return VBox status code.
1656 * @param pvUser The opaque data passed on container creation.
1657 * @param pStorage The storage handle to use.
1658 * @param uOffset The offset to start from.
1659 * @param pvBuffer Pointer to the bits need to be written.
1660 * @param cbBuffer How many bytes to write.
1661 * @param pcbWritten Where to store how many bytes where actually written.
1662 *
1663 * @notes Do not use in code called from the async read/write entry points in the backends.
1664 * This should be only used during open/close of images and for the support functions
1665 * which are not called while a VM is running (pfnCompact).
1666 */
1667 DECLR3CALLBACKMEMBER(int, pfnWriteSync, (void *pvUser, PVDIOSTORAGE pStorage, uint64_t uOffset,
1668 const void *pvBuffer, size_t cbBuffer, size_t *pcbWritten));
1669
1670 /**
1671 * Synchronous read callback.
1672 *
1673 * @return VBox status code.
1674 * @param pvUser The opaque data passed on container creation.
1675 * @param pStorage The storage handle to use.
1676 * @param uOffset The offset to start from.
1677 * @param pvBuffer Where to store the read bits.
1678 * @param cbBuffer How many bytes to read.
1679 * @param pcbRead Where to store how many bytes where actually read.
1680 *
1681 * @notes See pfnWriteSync()
1682 */
1683 DECLR3CALLBACKMEMBER(int, pfnReadSync, (void *pvUser, PVDIOSTORAGE pStorage, uint64_t uOffset,
1684 void *pvBuffer, size_t cbBuffer, size_t *pcbRead));
1685
1686 /**
1687 * Flush data to the storage backend.
1688 *
1689 * @return VBox status code.
1690 * @param pvUser The opaque data passed on container creation.
1691 * @param pStorage The storage handle to flush.
1692 *
1693 * @notes See pfnWriteSync()
1694 */
1695 DECLR3CALLBACKMEMBER(int, pfnFlushSync, (void *pvUser, PVDIOSTORAGE pStorage));
1696
1697 /**
1698 * Initiate a asynchronous read request for user data.
1699 *
1700 * @return VBox status code.
1701 * @param pvUser The opaque user data passed on container creation.
1702 * @param pStorage The storage handle.
1703 * @param uOffset The offset to start reading from.
1704 * @param pIoCtx I/O context passed in VDAsyncRead/Write.
1705 * @param cbRead How many bytes to read.
1706 */
1707 DECLR3CALLBACKMEMBER(int, pfnReadUserAsync, (void *pvUser, PVDIOSTORAGE pStorage,
1708 uint64_t uOffset, PVDIOCTX pIoCtx,
1709 size_t cbRead));
1710
1711 /**
1712 * Initiate a asynchronous write request for user data.
1713 *
1714 * @return VBox status code.
1715 * @param pvUser The opaque user data passed on container creation.
1716 * @param pStorage The storage handle.
1717 * @param uOffset The offset to start writing to.
1718 * @param pIoCtx I/O context passed in VDAsyncRead/Write
1719 * @param cbWrite How many bytes to write.
1720 * @param pfnCompleted Completion callback.
1721 * @param pvCompleteUser Opaque user data passed in the completion callback.
1722 */
1723 DECLR3CALLBACKMEMBER(int, pfnWriteUserAsync, (void *pvUser, PVDIOSTORAGE pStorage,
1724 uint64_t uOffset, PVDIOCTX pIoCtx,
1725 size_t cbWrite,
1726 PFNVDXFERCOMPLETED pfnComplete,
1727 void *pvCompleteUser));
1728
1729 /**
1730 * Reads metadata asynchronously from storage.
1731 * The current I/O context will be halted.
1732 *
1733 * @returns VBox status code.
1734 * @param pvUser The opaque user data passed on container creation.
1735 * @param pStorage The storage handle.
1736 * @param uOffset Offset to start reading from.
1737 * @param pvBuffer Where to store the data.
1738 * @param cbBuffer How many bytes to read.
1739 * @param pIoCtx The I/O context which triggered the read.
1740 * @param ppMetaXfer Where to store the metadata transfer handle on success.
1741 * @param pfnCompleted Completion callback.
1742 * @param pvCompleteUser Opaque user data passed in the completion callback.
1743 */
1744 DECLR3CALLBACKMEMBER(int, pfnReadMetaAsync, (void *pvUser, PVDIOSTORAGE pStorage,
1745 uint64_t uOffset, void *pvBuffer,
1746 size_t cbBuffer, PVDIOCTX pIoCtx,
1747 PPVDMETAXFER ppMetaXfer,
1748 PFNVDXFERCOMPLETED pfnComplete,
1749 void *pvCompleteUser));
1750
1751 /**
1752 * Writes metadata asynchronously to storage.
1753 *
1754 * @returns VBox status code.
1755 * @param pvUser The opaque user data passed on container creation.
1756 * @param pStorage The storage handle.
1757 * @param uOffset Offset to start writing to.
1758 * @param pvBuffer Written data.
1759 * @param cbBuffer How many bytes to write.
1760 * @param pIoCtx The I/O context which triggered the write.
1761 * @param pfnCompleted Completion callback.
1762 * @param pvCompleteUser Opaque user data passed in the completion callback.
1763 */
1764 DECLR3CALLBACKMEMBER(int, pfnWriteMetaAsync, (void *pvUser, PVDIOSTORAGE pStorage,
1765 uint64_t uOffset, void *pvBuffer,
1766 size_t cbBuffer, PVDIOCTX pIoCtx,
1767 PFNVDXFERCOMPLETED pfnComplete,
1768 void *pvCompleteUser));
1769
1770 /**
1771 * Releases a metadata transfer handle.
1772 * The free space can be used for another transfer.
1773 *
1774 * @returns nothing.
1775 * @param pvUser The opaque user data passed on container creation.
1776 * @param pMetaXfer The metadata transfer handle to release.
1777 */
1778 DECLR3CALLBACKMEMBER(void, pfnMetaXferRelease, (void *pvUser, PVDMETAXFER pMetaXfer));
1779
1780 /**
1781 * Initiates a async flush request.
1782 *
1783 * @return VBox status code.
1784 * @param pvUser The opaque data passed on container creation.
1785 * @param pStorage The storage handle to flush.
1786 * @param pIoCtx I/O context which triggered the flush.
1787 * @param pfnCompleted Completion callback.
1788 * @param pvCompleteUser Opaque user data passed in the completion callback.
1789 */
1790 DECLR3CALLBACKMEMBER(int, pfnFlushAsync, (void *pvUser, PVDIOSTORAGE pStorage,
1791 PVDIOCTX pIoCtx,
1792 PFNVDXFERCOMPLETED pfnComplete,
1793 void *pvCompleteUser));
1794
1795 /**
1796 * Copies a buffer into the I/O context.
1797 *
1798 * @return Number of bytes copied.
1799 * @param pvUser The opaque user data passed on container creation.
1800 * @param pIoCtx I/O context to copy the data to.
1801 * @param pvBuffer Buffer to copy.
1802 * @param cbBuffer Number of bytes to copy.
1803 */
1804 DECLR3CALLBACKMEMBER(size_t, pfnIoCtxCopyTo, (void *pvUser, PVDIOCTX pIoCtx,
1805 void *pvBuffer, size_t cbBuffer));
1806
1807 /**
1808 * Copies data from the I/O context into a buffer.
1809 *
1810 * @return Number of bytes copied.
1811 * @param pvUser The opaque user data passed on container creation.
1812 * @param pIoCtx I/O context to copy the data from.
1813 * @param pvBuffer Destination buffer.
1814 * @param cbBuffer Number of bytes to copy.
1815 */
1816 DECLR3CALLBACKMEMBER(size_t, pfnIoCtxCopyFrom, (void *pvUser, PVDIOCTX pIoCtx,
1817 void *pvBuffer, size_t cbBuffer));
1818
1819 /**
1820 * Sets the buffer of the given context to a specific byte.
1821 *
1822 * @return Number of bytes set.
1823 * @param pvUser The opaque user data passed on container creation.
1824 * @param pIoCtx I/O context to copy the data from.
1825 * @param ch The byte to set.
1826 * @param cbSet Number of bytes to set.
1827 */
1828 DECLR3CALLBACKMEMBER(size_t, pfnIoCtxSet, (void *pvUser, PVDIOCTX pIoCtx,
1829 int ch, size_t cbSet));
1830
1831 /**
1832 * Creates a segment array from the I/O context data buffer.
1833 *
1834 * @returns Number of bytes the array describes.
1835 * @param pvUser The opaque user data passed on container creation.
1836 * @param pIoCtx I/O context to copy the data from.
1837 * @param paSeg The uninitialized segment array.
1838 * If NULL pcSeg will contain the number of segments needed
1839 * to describe the requested amount of data.
1840 * @param pcSeg The number of segments the given array has.
1841 * This will hold the actual number of entries needed upon return.
1842 * @param cbData Number of bytes the new array should describe.
1843 */
1844 DECLR3CALLBACKMEMBER(size_t, pfnIoCtxSegArrayCreate, (void *pvUser, PVDIOCTX pIoCtx,
1845 PRTSGSEG paSeg, unsigned *pcSeg,
1846 size_t cbData));
1847 /**
1848 * Marks the given number of bytes as completed and continues the I/O context.
1849 *
1850 * @returns nothing.
1851 * @param pvUser The opaque user data passed on container creation.
1852 * @param pIoCtx The I/O context.
1853 * @param rcReq Status code the request completed with.
1854 * @param cbCompleted Number of bytes completed.
1855 */
1856 DECLR3CALLBACKMEMBER(void, pfnIoCtxCompleted, (void *pvUser, PVDIOCTX pIoCtx,
1857 int rcReq, size_t cbCompleted));
1858} VDINTERFACEIO, *PVDINTERFACEIO;
1859
1860/**
1861 * Get async I/O interface from opaque callback table.
1862 *
1863 * @return Pointer to the callback table.
1864 * @param pInterface Pointer to the interface descriptor.
1865 */
1866DECLINLINE(PVDINTERFACEIO) VDGetInterfaceIO(PVDINTERFACE pInterface)
1867{
1868 PVDINTERFACEIO pInterfaceIO;
1869
1870 /* Check that the interface descriptor is a async I/O interface. */
1871 AssertMsgReturn( (pInterface->enmInterface == VDINTERFACETYPE_IO)
1872 && (pInterface->cbSize == sizeof(VDINTERFACE)),
1873 ("Not an I/O interface"), NULL);
1874
1875 pInterfaceIO = (PVDINTERFACEIO)pInterface->pCallbacks;
1876
1877 /* Do basic checks. */
1878 AssertMsgReturn( (pInterfaceIO->cbSize == sizeof(VDINTERFACEIO))
1879 && (pInterfaceIO->enmInterface == VDINTERFACETYPE_IO),
1880 ("A non I/O callback table attached to a I/O interface descriptor\n"), NULL);
1881
1882 return pInterfaceIO;
1883}
1884
1885/**
1886 * Request completion callback for the async read/write API.
1887 */
1888typedef void (FNVDASYNCTRANSFERCOMPLETE) (void *pvUser1, void *pvUser2, int rcReq);
1889/** Pointer to a transfer compelte callback. */
1890typedef FNVDASYNCTRANSFERCOMPLETE *PFNVDASYNCTRANSFERCOMPLETE;
1891
1892/**
1893 * Disk geometry.
1894 */
1895typedef struct VDGEOMETRY
1896{
1897 /** Number of cylinders. */
1898 uint32_t cCylinders;
1899 /** Number of heads. */
1900 uint32_t cHeads;
1901 /** Number of sectors. */
1902 uint32_t cSectors;
1903} VDGEOMETRY;
1904
1905/** Pointer to disk geometry. */
1906typedef VDGEOMETRY *PVDGEOMETRY;
1907/** Pointer to constant disk geometry. */
1908typedef const VDGEOMETRY *PCVDGEOMETRY;
1909
1910/**
1911 * VBox HDD Container main structure.
1912 */
1913/* Forward declaration, VBOXHDD structure is visible only inside VBox HDD module. */
1914struct VBOXHDD;
1915typedef struct VBOXHDD VBOXHDD;
1916typedef VBOXHDD *PVBOXHDD;
1917
1918/**
1919 * Initializes HDD backends.
1920 *
1921 * @returns VBox status code.
1922 */
1923VBOXDDU_DECL(int) VDInit(void);
1924
1925/**
1926 * Destroys loaded HDD backends.
1927 *
1928 * @returns VBox status code.
1929 */
1930VBOXDDU_DECL(int) VDShutdown(void);
1931
1932/**
1933 * Lists all HDD backends and their capabilities in a caller-provided buffer.
1934 *
1935 * @return VBox status code.
1936 * VERR_BUFFER_OVERFLOW if not enough space is passed.
1937 * @param cEntriesAlloc Number of list entries available.
1938 * @param pEntries Pointer to array for the entries.
1939 * @param pcEntriesUsed Number of entries returned.
1940 */
1941VBOXDDU_DECL(int) VDBackendInfo(unsigned cEntriesAlloc, PVDBACKENDINFO pEntries,
1942 unsigned *pcEntriesUsed);
1943
1944/**
1945 * Lists the capablities of a backend indentified by its name.
1946 *
1947 * @return VBox status code.
1948 * @param pszBackend The backend name (case insensitive).
1949 * @param pEntries Pointer to an entry.
1950 */
1951VBOXDDU_DECL(int) VDBackendInfoOne(const char *pszBackend, PVDBACKENDINFO pEntry);
1952
1953/**
1954 * Allocates and initializes an empty HDD container.
1955 * No image files are opened.
1956 *
1957 * @return VBox status code.
1958 * @param pVDIfsDisk Pointer to the per-disk VD interface list.
1959 * @param ppDisk Where to store the reference to HDD container.
1960 */
1961VBOXDDU_DECL(int) VDCreate(PVDINTERFACE pVDIfsDisk, PVBOXHDD *ppDisk);
1962
1963/**
1964 * Destroys HDD container.
1965 * If container has opened image files they will be closed.
1966 *
1967 * @param pDisk Pointer to HDD container.
1968 */
1969VBOXDDU_DECL(void) VDDestroy(PVBOXHDD pDisk);
1970
1971/**
1972 * Try to get the backend name which can use this image.
1973 *
1974 * @return VBox status code.
1975 * VINF_SUCCESS if a plugin was found.
1976 * ppszFormat contains the string which can be used as backend name.
1977 * VERR_NOT_SUPPORTED if no backend was found.
1978 * @param pVDIfsDisk Pointer to the per-disk VD interface list.
1979 * @param pVDIfsImage Pointer to the per-image VD interface list.
1980 * @param pszFilename Name of the image file for which the backend is queried.
1981 * @param ppszFormat Receives pointer of the UTF-8 string which contains the format name.
1982 * The returned pointer must be freed using RTStrFree().
1983 */
1984VBOXDDU_DECL(int) VDGetFormat(PVDINTERFACE pVDIfsDisk, PVDINTERFACE pVDIfsImage,
1985 const char *pszFilename, char **ppszFormat);
1986
1987/**
1988 * Opens an image file.
1989 *
1990 * The first opened image file in HDD container must have a base image type,
1991 * others (next opened images) must be differencing or undo images.
1992 * Linkage is checked for differencing image to be consistent with the previously opened image.
1993 * When another differencing image is opened and the last image was opened in read/write access
1994 * mode, then the last image is reopened in read-only with deny write sharing mode. This allows
1995 * other processes to use images in read-only mode too.
1996 *
1997 * Note that the image is opened in read-only mode if a read/write open is not possible.
1998 * Use VDIsReadOnly to check open mode.
1999 *
2000 * @return VBox status code.
2001 * @param pDisk Pointer to HDD container.
2002 * @param pszBackend Name of the image file backend to use (case insensitive).
2003 * @param pszFilename Name of the image file to open.
2004 * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
2005 * @param pVDIfsImage Pointer to the per-image VD interface list.
2006 */
2007VBOXDDU_DECL(int) VDOpen(PVBOXHDD pDisk, const char *pszBackend,
2008 const char *pszFilename, unsigned uOpenFlags,
2009 PVDINTERFACE pVDIfsImage);
2010
2011/**
2012 * Opens a cache image.
2013 *
2014 * @return VBox status code.
2015 * @param pDisk Pointer to the HDD container which should use the cache image.
2016 * @param pszBackend Name of the cache file backend to use (case insensitive).
2017 * @param pszFilename Name of the cache image to open.
2018 * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
2019 * @param pVDIfsCache Pointer to the per-cache VD interface list.
2020 */
2021VBOXDDU_DECL(int) VDCacheOpen(PVBOXHDD pDisk, const char *pszBackend,
2022 const char *pszFilename, unsigned uOpenFlags,
2023 PVDINTERFACE pVDIfsCache);
2024
2025/**
2026 * Creates and opens a new base image file.
2027 *
2028 * @return VBox status code.
2029 * @param pDisk Pointer to HDD container.
2030 * @param pszBackend Name of the image file backend to use (case insensitive).
2031 * @param pszFilename Name of the image file to create.
2032 * @param cbSize Image size in bytes.
2033 * @param uImageFlags Flags specifying special image features.
2034 * @param pszComment Pointer to image comment. NULL is ok.
2035 * @param pPCHSGeometry Pointer to physical disk geometry <= (16383,16,63). Not NULL.
2036 * @param pLCHSGeometry Pointer to logical disk geometry <= (x,255,63). Not NULL.
2037 * @param pUuid New UUID of the image. If NULL, a new UUID is created.
2038 * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
2039 * @param pVDIfsImage Pointer to the per-image VD interface list.
2040 * @param pVDIfsOperation Pointer to the per-operation VD interface list.
2041 */
2042VBOXDDU_DECL(int) VDCreateBase(PVBOXHDD pDisk, const char *pszBackend,
2043 const char *pszFilename, uint64_t cbSize,
2044 unsigned uImageFlags, const char *pszComment,
2045 PCVDGEOMETRY pPCHSGeometry,
2046 PCVDGEOMETRY pLCHSGeometry,
2047 PCRTUUID pUuid, unsigned uOpenFlags,
2048 PVDINTERFACE pVDIfsImage,
2049 PVDINTERFACE pVDIfsOperation);
2050
2051/**
2052 * Creates and opens a new differencing image file in HDD container.
2053 * See comments for VDOpen function about differencing images.
2054 *
2055 * @return VBox status code.
2056 * @param pDisk Pointer to HDD container.
2057 * @param pszBackend Name of the image file backend to use (case insensitive).
2058 * @param pszFilename Name of the differencing image file to create.
2059 * @param uImageFlags Flags specifying special image features.
2060 * @param pszComment Pointer to image comment. NULL is ok.
2061 * @param pUuid New UUID of the image. If NULL, a new UUID is created.
2062 * @param pParentUuid New parent UUID of the image. If NULL, the UUID is queried automatically.
2063 * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
2064 * @param pVDIfsImage Pointer to the per-image VD interface list.
2065 * @param pVDIfsOperation Pointer to the per-operation VD interface list.
2066 */
2067VBOXDDU_DECL(int) VDCreateDiff(PVBOXHDD pDisk, const char *pszBackend,
2068 const char *pszFilename, unsigned uImageFlags,
2069 const char *pszComment, PCRTUUID pUuid,
2070 PCRTUUID pParentUuid, unsigned uOpenFlags,
2071 PVDINTERFACE pVDIfsImage,
2072 PVDINTERFACE pVDIfsOperation);
2073
2074/**
2075 * Creates and opens new cache image file in HDD container.
2076 *
2077 * @return VBox status code.
2078 * @param pDisk Name of the cache file backend to use (case insensitive).
2079 * @param pszFilename Name of the differencing cache file to create.
2080 * @param cbSize Maximum size of the cache.
2081 * @param uImageFlags Flags specifying special cache features.
2082 * @param pszComment Pointer to image comment. NULL is ok.
2083 * @param pUuid New UUID of the image. If NULL, a new UUID is created.
2084 * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
2085 * @param pVDIfsCache Pointer to the per-cache VD interface list.
2086 * @param pVDIfsOperation Pointer to the per-operation VD interface list.
2087 */
2088VBOXDDU_DECL(int) VDCreateCache(PVBOXHDD pDisk, const char *pszBackend,
2089 const char *pszFilename, uint64_t cbSize,
2090 unsigned uImageFlags, const char *pszComment,
2091 PCRTUUID pUuid, unsigned uOpenFlags,
2092 PVDINTERFACE pVDIfsCache, PVDINTERFACE pVDIfsOperation);
2093
2094/**
2095 * Merges two images (not necessarily with direct parent/child relationship).
2096 * As a side effect the source image and potentially the other images which
2097 * are also merged to the destination are deleted from both the disk and the
2098 * images in the HDD container.
2099 *
2100 * @return VBox status code.
2101 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2102 * @param pDisk Pointer to HDD container.
2103 * @param nImageFrom Image number to merge from, counts from 0. 0 is always base image of container.
2104 * @param nImageTo Image number to merge to, counts from 0. 0 is always base image of container.
2105 * @param pVDIfsOperation Pointer to the per-operation VD interface list.
2106 */
2107VBOXDDU_DECL(int) VDMerge(PVBOXHDD pDisk, unsigned nImageFrom,
2108 unsigned nImageTo, PVDINTERFACE pVDIfsOperation);
2109
2110/**
2111 * Copies an image from one HDD container to another.
2112 * The copy is opened in the target HDD container.
2113 * It is possible to convert between different image formats, because the
2114 * backend for the destination may be different from the source.
2115 * If both the source and destination reference the same HDD container,
2116 * then the image is moved (by copying/deleting or renaming) to the new location.
2117 * The source container is unchanged if the move operation fails, otherwise
2118 * the image at the new location is opened in the same way as the old one was.
2119 *
2120 * @note The read/write accesses across disks are not synchronized, just the
2121 * accesses to each disk. Once there is a use case which requires a defined
2122 * read/write behavior in this situation this needs to be extended.
2123 *
2124 * @return VBox status code.
2125 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2126 * @param pDiskFrom Pointer to source HDD container.
2127 * @param nImage Image number, counts from 0. 0 is always base image of container.
2128 * @param pDiskTo Pointer to destination HDD container.
2129 * @param pszBackend Name of the image file backend to use (may be NULL to use the same as the source, case insensitive).
2130 * @param pszFilename New name of the image (may be NULL to specify that the
2131 * copy destination is the destination container, or
2132 * if pDiskFrom == pDiskTo, i.e. when moving).
2133 * @param fMoveByRename If true, attempt to perform a move by renaming (if successful the new size is ignored).
2134 * @param cbSize New image size (0 means leave unchanged).
2135 * @param uImageFlags Flags specifying special destination image features.
2136 * @param pDstUuid New UUID of the destination image. If NULL, a new UUID is created.
2137 * This parameter is used if and only if a true copy is created.
2138 * In all rename/move cases or copy to existing image cases the modification UUIDs are copied over.
2139 * @param pVDIfsOperation Pointer to the per-operation VD interface list.
2140 * @param pDstVDIfsImage Pointer to the per-image VD interface list, for the
2141 * destination image.
2142 * @param pDstVDIfsOperation Pointer to the per-operation VD interface list,
2143 * for the destination operation.
2144 */
2145VBOXDDU_DECL(int) VDCopy(PVBOXHDD pDiskFrom, unsigned nImage, PVBOXHDD pDiskTo,
2146 const char *pszBackend, const char *pszFilename,
2147 bool fMoveByRename, uint64_t cbSize,
2148 unsigned uImageFlags, PCRTUUID pDstUuid,
2149 PVDINTERFACE pVDIfsOperation,
2150 PVDINTERFACE pDstVDIfsImage,
2151 PVDINTERFACE pDstVDIfsOperation);
2152
2153/**
2154 * Optimizes the storage consumption of an image. Typically the unused blocks
2155 * have to be wiped with zeroes to achieve a substantial reduced storage use.
2156 * Another optimization done is reordering the image blocks, which can provide
2157 * a significant performance boost, as reads and writes tend to use less random
2158 * file offsets.
2159 *
2160 * @note Compaction is treated as a single operation with regard to thread
2161 * synchronization, which means that it potentially blocks other activities for
2162 * a long time. The complexity of compaction would grow even more if concurrent
2163 * accesses have to be handled.
2164 *
2165 * @return VBox status code.
2166 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2167 * @return VERR_VD_IMAGE_READ_ONLY if image is not writable.
2168 * @return VERR_NOT_SUPPORTED if this kind of image can be compacted, but
2169 * this isn't supported yet.
2170 * @param pDisk Pointer to HDD container.
2171 * @param nImage Image number, counts from 0. 0 is always base image of container.
2172 * @param pVDIfsOperation Pointer to the per-operation VD interface list.
2173 */
2174VBOXDDU_DECL(int) VDCompact(PVBOXHDD pDisk, unsigned nImage,
2175 PVDINTERFACE pVDIfsOperation);
2176
2177/**
2178 * Resizes the given disk image to the given size.
2179 *
2180 * @return VBox status
2181 * @return VERR_VD_IMAGE_READ_ONLY if image is not writable.
2182 * @return VERR_NOT_SUPPORTED if this kind of image can be compacted, but
2183 *
2184 * @param pDisk Pointer to the HDD container.
2185 * @param cbSize New size of the image.
2186 * @param pPCHSGeometry Pointer to the new physical disk geometry <= (16383,16,63). Not NULL.
2187 * @param pLCHSGeometry Pointer to the new logical disk geometry <= (x,255,63). Not NULL.
2188 * @param pVDIfsOperation Pointer to the per-operation VD interface list.
2189 */
2190VBOXDDU_DECL(int) VDResize(PVBOXHDD pDisk, uint64_t cbSize,
2191 PCVDGEOMETRY pPCHSGeometry,
2192 PCVDGEOMETRY pLCHSGeometry,
2193 PVDINTERFACE pVDIfsOperation);
2194
2195/**
2196 * Closes the last opened image file in HDD container.
2197 * If previous image file was opened in read-only mode (the normal case) and
2198 * the last opened image is in read-write mode then the previous image will be
2199 * reopened in read/write mode.
2200 *
2201 * @return VBox status code.
2202 * @return VERR_VD_NOT_OPENED if no image is opened in HDD container.
2203 * @param pDisk Pointer to HDD container.
2204 * @param fDelete If true, delete the image from the host disk.
2205 */
2206VBOXDDU_DECL(int) VDClose(PVBOXHDD pDisk, bool fDelete);
2207
2208/**
2209 * Closes the currently opened cache image file in HDD container.
2210 *
2211 * @return VBox status code.
2212 * @return VERR_VD_NOT_OPENED if no cache is opened in HDD container.
2213 * @param pDisk Pointer to HDD container.
2214 * @param fDelete If true, delete the image from the host disk.
2215 */
2216VBOXDDU_DECL(int) VDCacheClose(PVBOXHDD pDisk, bool fDelete);
2217
2218/**
2219 * Closes all opened image files in HDD container.
2220 *
2221 * @return VBox status code.
2222 * @param pDisk Pointer to HDD container.
2223 */
2224VBOXDDU_DECL(int) VDCloseAll(PVBOXHDD pDisk);
2225
2226/**
2227 * Read data from virtual HDD.
2228 *
2229 * @return VBox status code.
2230 * @return VERR_VD_NOT_OPENED if no image is opened in HDD container.
2231 * @param pDisk Pointer to HDD container.
2232 * @param uOffset Offset of first reading byte from start of disk.
2233 * Must be aligned to a sector boundary.
2234 * @param pvBuffer Pointer to buffer for reading data.
2235 * @param cbBuffer Number of bytes to read.
2236 * Must be aligned to a sector boundary.
2237 */
2238VBOXDDU_DECL(int) VDRead(PVBOXHDD pDisk, uint64_t uOffset, void *pvBuffer, size_t cbBuffer);
2239
2240/**
2241 * Write data to virtual HDD.
2242 *
2243 * @return VBox status code.
2244 * @return VERR_VD_NOT_OPENED if no image is opened in HDD container.
2245 * @param pDisk Pointer to HDD container.
2246 * @param uOffset Offset of first writing byte from start of disk.
2247 * Must be aligned to a sector boundary.
2248 * @param pvBuffer Pointer to buffer for writing data.
2249 * @param cbBuffer Number of bytes to write.
2250 * Must be aligned to a sector boundary.
2251 */
2252VBOXDDU_DECL(int) VDWrite(PVBOXHDD pDisk, uint64_t uOffset, const void *pvBuffer, size_t cbBuffer);
2253
2254/**
2255 * Make sure the on disk representation of a virtual HDD is up to date.
2256 *
2257 * @return VBox status code.
2258 * @return VERR_VD_NOT_OPENED if no image is opened in HDD container.
2259 * @param pDisk Pointer to HDD container.
2260 */
2261VBOXDDU_DECL(int) VDFlush(PVBOXHDD pDisk);
2262
2263/**
2264 * Get number of opened images in HDD container.
2265 *
2266 * @return Number of opened images for HDD container. 0 if no images have been opened.
2267 * @param pDisk Pointer to HDD container.
2268 */
2269VBOXDDU_DECL(unsigned) VDGetCount(PVBOXHDD pDisk);
2270
2271/**
2272 * Get read/write mode of HDD container.
2273 *
2274 * @return Virtual disk ReadOnly status.
2275 * @return true if no image is opened in HDD container.
2276 * @param pDisk Pointer to HDD container.
2277 */
2278VBOXDDU_DECL(bool) VDIsReadOnly(PVBOXHDD pDisk);
2279
2280/**
2281 * Get total capacity of an image in HDD container.
2282 *
2283 * @return Virtual disk size in bytes.
2284 * @return 0 if image with specified number was not opened.
2285 * @param pDisk Pointer to HDD container.
2286 * @param nImage Image number, counts from 0. 0 is always base image of container.
2287 */
2288VBOXDDU_DECL(uint64_t) VDGetSize(PVBOXHDD pDisk, unsigned nImage);
2289
2290/**
2291 * Get total file size of an image in HDD container.
2292 *
2293 * @return Virtual disk size in bytes.
2294 * @return 0 if image with specified number was not opened.
2295 * @param pDisk Pointer to HDD container.
2296 * @param nImage Image number, counts from 0. 0 is always base image of container.
2297 */
2298VBOXDDU_DECL(uint64_t) VDGetFileSize(PVBOXHDD pDisk, unsigned nImage);
2299
2300/**
2301 * Get virtual disk PCHS geometry of an image in HDD container.
2302 *
2303 * @return VBox status code.
2304 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2305 * @return VERR_VD_GEOMETRY_NOT_SET if no geometry present in the HDD container.
2306 * @param pDisk Pointer to HDD container.
2307 * @param nImage Image number, counts from 0. 0 is always base image of container.
2308 * @param pPCHSGeometry Where to store PCHS geometry. Not NULL.
2309 */
2310VBOXDDU_DECL(int) VDGetPCHSGeometry(PVBOXHDD pDisk, unsigned nImage,
2311 PVDGEOMETRY pPCHSGeometry);
2312
2313/**
2314 * Store virtual disk PCHS geometry of an image in HDD container.
2315 *
2316 * @return VBox status code.
2317 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2318 * @param pDisk Pointer to HDD container.
2319 * @param nImage Image number, counts from 0. 0 is always base image of container.
2320 * @param pPCHSGeometry Where to load PCHS geometry from. Not NULL.
2321 */
2322VBOXDDU_DECL(int) VDSetPCHSGeometry(PVBOXHDD pDisk, unsigned nImage,
2323 PCVDGEOMETRY pPCHSGeometry);
2324
2325/**
2326 * Get virtual disk LCHS geometry of an image in HDD container.
2327 *
2328 * @return VBox status code.
2329 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2330 * @return VERR_VD_GEOMETRY_NOT_SET if no geometry present in the HDD container.
2331 * @param pDisk Pointer to HDD container.
2332 * @param nImage Image number, counts from 0. 0 is always base image of container.
2333 * @param pLCHSGeometry Where to store LCHS geometry. Not NULL.
2334 */
2335VBOXDDU_DECL(int) VDGetLCHSGeometry(PVBOXHDD pDisk, unsigned nImage,
2336 PVDGEOMETRY pLCHSGeometry);
2337
2338/**
2339 * Store virtual disk LCHS geometry of an image in HDD container.
2340 *
2341 * @return VBox status code.
2342 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2343 * @param pDisk Pointer to HDD container.
2344 * @param nImage Image number, counts from 0. 0 is always base image of container.
2345 * @param pLCHSGeometry Where to load LCHS geometry from. Not NULL.
2346 */
2347VBOXDDU_DECL(int) VDSetLCHSGeometry(PVBOXHDD pDisk, unsigned nImage,
2348 PCVDGEOMETRY pLCHSGeometry);
2349
2350/**
2351 * Get version of image in HDD container.
2352 *
2353 * @return VBox status code.
2354 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2355 * @param pDisk Pointer to HDD container.
2356 * @param nImage Image number, counts from 0. 0 is always base image of container.
2357 * @param puVersion Where to store the image version.
2358 */
2359VBOXDDU_DECL(int) VDGetVersion(PVBOXHDD pDisk, unsigned nImage,
2360 unsigned *puVersion);
2361
2362/**
2363 * List the capabilities of image backend in HDD container.
2364 *
2365 * @return VBox status code.
2366 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2367 * @param pDisk Pointer to the HDD container.
2368 * @param nImage Image number, counts from 0. 0 is always base image of container.
2369 * @param pbackendInfo Where to store the backend information.
2370 */
2371VBOXDDU_DECL(int) VDBackendInfoSingle(PVBOXHDD pDisk, unsigned nImage,
2372 PVDBACKENDINFO pBackendInfo);
2373
2374/**
2375 * Get flags of image in HDD container.
2376 *
2377 * @return VBox status code.
2378 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2379 * @param pDisk Pointer to HDD container.
2380 * @param nImage Image number, counts from 0. 0 is always base image of container.
2381 * @param puImageFlags Where to store the image flags.
2382 */
2383VBOXDDU_DECL(int) VDGetImageFlags(PVBOXHDD pDisk, unsigned nImage, unsigned *puImageFlags);
2384
2385/**
2386 * Get open flags of image in HDD container.
2387 *
2388 * @return VBox status code.
2389 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2390 * @param pDisk Pointer to HDD container.
2391 * @param nImage Image number, counts from 0. 0 is always base image of container.
2392 * @param puOpenFlags Where to store the image open flags.
2393 */
2394VBOXDDU_DECL(int) VDGetOpenFlags(PVBOXHDD pDisk, unsigned nImage,
2395 unsigned *puOpenFlags);
2396
2397/**
2398 * Set open flags of image in HDD container.
2399 * This operation may cause file locking changes and/or files being reopened.
2400 * Note that in case of unrecoverable error all images in HDD container will be closed.
2401 *
2402 * @return VBox status code.
2403 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2404 * @param pDisk Pointer to HDD container.
2405 * @param nImage Image number, counts from 0. 0 is always base image of container.
2406 * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
2407 */
2408VBOXDDU_DECL(int) VDSetOpenFlags(PVBOXHDD pDisk, unsigned nImage,
2409 unsigned uOpenFlags);
2410
2411/**
2412 * Get base filename of image in HDD container. Some image formats use
2413 * other filenames as well, so don't use this for anything but informational
2414 * purposes.
2415 *
2416 * @return VBox status code.
2417 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2418 * @return VERR_BUFFER_OVERFLOW if pszFilename buffer too small to hold filename.
2419 * @param pDisk Pointer to HDD container.
2420 * @param nImage Image number, counts from 0. 0 is always base image of container.
2421 * @param pszFilename Where to store the image file name.
2422 * @param cbFilename Size of buffer pszFilename points to.
2423 */
2424VBOXDDU_DECL(int) VDGetFilename(PVBOXHDD pDisk, unsigned nImage,
2425 char *pszFilename, unsigned cbFilename);
2426
2427/**
2428 * Get the comment line of image in HDD container.
2429 *
2430 * @return VBox status code.
2431 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2432 * @return VERR_BUFFER_OVERFLOW if pszComment buffer too small to hold comment text.
2433 * @param pDisk Pointer to HDD container.
2434 * @param nImage Image number, counts from 0. 0 is always base image of container.
2435 * @param pszComment Where to store the comment string of image. NULL is ok.
2436 * @param cbComment The size of pszComment buffer. 0 is ok.
2437 */
2438VBOXDDU_DECL(int) VDGetComment(PVBOXHDD pDisk, unsigned nImage,
2439 char *pszComment, unsigned cbComment);
2440
2441/**
2442 * Changes the comment line of image in HDD container.
2443 *
2444 * @return VBox status code.
2445 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2446 * @param pDisk Pointer to HDD container.
2447 * @param nImage Image number, counts from 0. 0 is always base image of container.
2448 * @param pszComment New comment string (UTF-8). NULL is allowed to reset the comment.
2449 */
2450VBOXDDU_DECL(int) VDSetComment(PVBOXHDD pDisk, unsigned nImage,
2451 const char *pszComment);
2452
2453/**
2454 * Get UUID of image in HDD container.
2455 *
2456 * @return VBox status code.
2457 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2458 * @param pDisk Pointer to HDD container.
2459 * @param nImage Image number, counts from 0. 0 is always base image of container.
2460 * @param pUuid Where to store the image UUID.
2461 */
2462VBOXDDU_DECL(int) VDGetUuid(PVBOXHDD pDisk, unsigned nImage, PRTUUID pUuid);
2463
2464/**
2465 * Set the image's UUID. Should not be used by normal applications.
2466 *
2467 * @return VBox status code.
2468 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2469 * @param pDisk Pointer to HDD container.
2470 * @param nImage Image number, counts from 0. 0 is always base image of container.
2471 * @param pUuid New UUID of the image. If NULL, a new UUID is created.
2472 */
2473VBOXDDU_DECL(int) VDSetUuid(PVBOXHDD pDisk, unsigned nImage, PCRTUUID pUuid);
2474
2475/**
2476 * Get last modification UUID of image in HDD container.
2477 *
2478 * @return VBox status code.
2479 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2480 * @param pDisk Pointer to HDD container.
2481 * @param nImage Image number, counts from 0. 0 is always base image of container.
2482 * @param pUuid Where to store the image modification UUID.
2483 */
2484VBOXDDU_DECL(int) VDGetModificationUuid(PVBOXHDD pDisk, unsigned nImage,
2485 PRTUUID pUuid);
2486
2487/**
2488 * Set the image's last modification UUID. Should not be used by normal applications.
2489 *
2490 * @return VBox status code.
2491 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2492 * @param pDisk Pointer to HDD container.
2493 * @param nImage Image number, counts from 0. 0 is always base image of container.
2494 * @param pUuid New modification UUID of the image. If NULL, a new UUID is created.
2495 */
2496VBOXDDU_DECL(int) VDSetModificationUuid(PVBOXHDD pDisk, unsigned nImage,
2497 PCRTUUID pUuid);
2498
2499/**
2500 * Get parent UUID of image in HDD container.
2501 *
2502 * @return VBox status code.
2503 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2504 * @param pDisk Pointer to HDD container.
2505 * @param nImage Image number, counts from 0. 0 is always base image of the container.
2506 * @param pUuid Where to store the parent image UUID.
2507 */
2508VBOXDDU_DECL(int) VDGetParentUuid(PVBOXHDD pDisk, unsigned nImage,
2509 PRTUUID pUuid);
2510
2511/**
2512 * Set the image's parent UUID. Should not be used by normal applications.
2513 *
2514 * @return VBox status code.
2515 * @param pDisk Pointer to HDD container.
2516 * @param nImage Image number, counts from 0. 0 is always base image of container.
2517 * @param pUuid New parent UUID of the image. If NULL, a new UUID is created.
2518 */
2519VBOXDDU_DECL(int) VDSetParentUuid(PVBOXHDD pDisk, unsigned nImage,
2520 PCRTUUID pUuid);
2521
2522
2523/**
2524 * Debug helper - dumps all opened images in HDD container into the log file.
2525 *
2526 * @param pDisk Pointer to HDD container.
2527 */
2528VBOXDDU_DECL(void) VDDumpImages(PVBOXHDD pDisk);
2529
2530
2531/**
2532 * Query if asynchronous operations are supported for this disk.
2533 *
2534 * @return VBox status code.
2535 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2536 * @param pDisk Pointer to the HDD container.
2537 * @param nImage Image number, counts from 0. 0 is always base image of container.
2538 * @param pfAIOSupported Where to store if async IO is supported.
2539 */
2540VBOXDDU_DECL(int) VDImageIsAsyncIOSupported(PVBOXHDD pDisk, unsigned nImage, bool *pfAIOSupported);
2541
2542
2543/**
2544 * Start a asynchronous read request.
2545 *
2546 * @return VBox status code.
2547 * @param pDisk Pointer to the HDD container.
2548 * @param uOffset The offset of the virtual disk to read from.
2549 * @param cbRead How many bytes to read.
2550 * @param paSeg Pointer to an array of segments.
2551 * @param cSeg Number of segments in the array.
2552 * @param pfnComplete Completion callback.
2553 * @param pvUser User data which is passed on completion
2554 */
2555VBOXDDU_DECL(int) VDAsyncRead(PVBOXHDD pDisk, uint64_t uOffset, size_t cbRead,
2556 PCRTSGSEG paSeg, unsigned cSeg,
2557 PFNVDASYNCTRANSFERCOMPLETE pfnComplete,
2558 void *pvUser1, void *pvUser2);
2559
2560
2561/**
2562 * Start a asynchronous write request.
2563 *
2564 * @return VBox status code.
2565 * @param pDisk Pointer to the HDD container.
2566 * @param uOffset The offset of the virtual disk to write to.
2567 * @param cbWrtie How many bytes to write.
2568 * @param paSeg Pointer to an array of segments.
2569 * @param cSeg Number of segments in the array.
2570 * @param pfnComplete Completion callback.
2571 * @param pvUser User data which is passed on completion.
2572 */
2573VBOXDDU_DECL(int) VDAsyncWrite(PVBOXHDD pDisk, uint64_t uOffset, size_t cbWrite,
2574 PCRTSGSEG paSeg, unsigned cSeg,
2575 PFNVDASYNCTRANSFERCOMPLETE pfnComplete,
2576 void *pvUser1, void *pvUser2);
2577
2578
2579/**
2580 * Start a asynchronous flush request.
2581 *
2582 * @return VBox status code.
2583 * @param pDisk Pointer to the HDD container.
2584 * @param pfnComplete Completion callback.
2585 * @param pvUser User data which is passed on completion.
2586 */
2587VBOXDDU_DECL(int) VDAsyncFlush(PVBOXHDD pDisk,
2588 PFNVDASYNCTRANSFERCOMPLETE pfnComplete,
2589 void *pvUser1, void *pvUser2);
2590RT_C_DECLS_END
2591
2592/** @} */
2593
2594#endif
Note: See TracBrowser for help on using the repository browser.

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