~ubuntu-branches/ubuntu/raring/virtualbox-ose/raring

« back to all changes in this revision

Viewing changes to include/VBox/VBoxHDD.h

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2011-01-30 23:27:25 UTC
  • mfrom: (0.3.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20110130232725-2ouajjd2ggdet0zd
Tags: 4.0.2-dfsg-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - Add Apport hook.
    - debian/virtualbox-ose.files/source_virtualbox-ose.py
    - debian/virtualbox-ose.install
  - Drop *-source packages.
* Drop ubuntu-01-fix-build-gcc45.patch, fixed upstream.
* Drop ubuntu-02-as-needed.patch, added to the Debian package.

Show diffs side-by-side

added added

removed removed

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