VirtualBox

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

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

Devices/Storage: implement sequential reading of streamOptimized VMDK images

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