2 * VBox HDD Container, Virtual Disk Image (VDI) API.
6 * Copyright (C) 2006-2007 innotek GmbH
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 as published by the Free Software Foundation,
12 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
13 * distribution. VirtualBox OSE is distributed in the hope that it will
14 * be useful, but WITHOUT ANY WARRANTY of any kind.
17 #ifndef ___VBox_VBoxHDD_h
18 #define ___VBox_VBoxHDD_h
26 # error "There are no VDI APIs available in Ring-0 Host Context!"
29 /** @defgroup grp_vbox_hdd VBox HDD Container
33 /** Image info, not handled anyhow.
34 * Must be less than 64 bytes in length, including the trailing 0.
36 #define VDI_IMAGE_FILE_INFO "<<< innotek VirtualBox Disk Image >>>\n"
38 /** Current image major version. */
39 #define VDI_IMAGE_VERSION_MAJOR (0x0001)
40 /** Current image minor version. */
41 #define VDI_IMAGE_VERSION_MINOR (0x0001)
42 /** Current image version. */
43 #define VDI_IMAGE_VERSION ((VDI_IMAGE_VERSION_MAJOR << 16) | VDI_IMAGE_VERSION_MINOR)
45 /** Get major version from combined version. */
46 #define VDI_GET_VERSION_MAJOR(uVer) ((uVer) >> 16)
47 /** Get minor version from combined version. */
48 #define VDI_GET_VERSION_MINOR(uVer) ((uVer) & 0xffff)
50 /** @name VDI image types
52 typedef enum VDIIMAGETYPE
54 /** Normal dynamically growing base image file. */
55 VDI_IMAGE_TYPE_NORMAL
= 1,
56 /** Preallocated base image file of a fixed size. */
58 /** Dynamically growing image file for undo/commit changes support. */
60 /** Dynamically growing image file for differencing support. */
63 /** First valid image type value. */
64 VDI_IMAGE_TYPE_FIRST
= VDI_IMAGE_TYPE_NORMAL
,
65 /** Last valid image type value. */
66 VDI_IMAGE_TYPE_LAST
= VDI_IMAGE_TYPE_DIFF
68 /** Pointer to VDI image type. */
69 typedef VDIIMAGETYPE
*PVDIIMAGETYPE
;
72 /** @name VDI image flags
75 #define VDI_IMAGE_FLAGS_NONE (0x00)
76 /** Fill new blocks with zeroes while expanding image file. */
77 #define VDI_IMAGE_FLAGS_ZERO_EXPAND (0x01)
79 /** Mask of valid image flags. */
80 #define VDI_IMAGE_FLAGS_MASK (VDI_IMAGE_FLAGS_NONE | VDI_IMAGE_FLAGS_ZERO_EXPAND)
82 /** Default image flags. */
83 #define VDI_IMAGE_FLAGS_DEFAULT (VDI_IMAGE_FLAGS_NONE)
86 /** @name VDI image open mode flags
89 /** Try to open image in read/write exclusive access mode if possible, or in read-only elsewhere. */
90 #define VDI_OPEN_FLAGS_NORMAL (0)
91 /** Open image in read-only mode with sharing access with others. */
92 #define VDI_OPEN_FLAGS_READONLY (1)
93 /** Mask of valid flags. */
94 #define VDI_OPEN_FLAGS_MASK (VDI_OPEN_FLAGS_NORMAL | VDI_OPEN_FLAGS_READONLY)
98 * VBox VDI disk Container main structure.
100 /* Forward declaration, VDIDISK structure is visible only inside VDI module. */
102 typedef struct VDIDISK VDIDISK
;
103 typedef VDIDISK
*PVDIDISK
;
106 * Creates a new base image file.
108 * @returns VBox status code.
109 * @param pszFilename Name of the image file to create.
110 * @param enmType Image type, only base image types are acceptable.
111 * @param cbSize Image size in bytes.
112 * @param pszComment Pointer to image comment. NULL is ok.
113 * @param pfnProgress Progress callback. Optional. NULL if not to be used.
114 * @param pvUser User argument for the progress callback.
116 int VDICreateBaseImage(const char *pszFilename
, VDIIMAGETYPE enmType
, uint64_t cbSize
, const char *pszComment
,
117 PFNVMPROGRESS pfnProgress
, void *pvUser
);
120 * Creates a differencing dynamically growing image file for specified parent image.
122 * @returns VBox status code.
123 * @param pszFilename Name of the differencing image file to create.
124 * @param pszParent Name of the parent image file. May be base or diff image type.
125 * @param pszComment Pointer to image comment. NULL is ok.
126 * @param pfnProgress Progress callback. Optional. NULL if not to be used.
127 * @param pvUser User argument for the progress callback.
129 int VDICreateDifferenceImage(const char *pszFilename
, const char *pszParent
, const char *pszComment
,
130 PFNVMPROGRESS pfnProgress
, void *pvUser
);
133 * Checks if image is available and not broken, returns some useful image parameters if requested.
135 * @returns VBox status code.
136 * @param pszFilename Name of the image file to check.
137 * @param puVersion Where to store the version of image. NULL is ok.
138 * @param penmType Where to store the type of image. NULL is ok.
139 * @param pcbSize Where to store the size of image in bytes. NULL is ok.
140 * @param pUuid Where to store the uuid of image creation. NULL is ok.
141 * @param pParentUuid Where to store the uuid of the parent image (if any). NULL is ok.
142 * @param pszComment Where to store the comment string of image. NULL is ok.
143 * @param cbComment The size of pszComment buffer. 0 is ok.
145 int VDICheckImage(const char *pszFilename
,
147 PVDIIMAGETYPE penmType
,
155 * Changes an image's comment string.
157 * @returns VBox status code.
158 * @param pszFilename Name of the image file to operate on.
159 * @param pszComment New comment string (UTF-8). NULL is allowed to reset the comment.
161 int VDISetImageComment(const char *pszFilename
, const char *pszComment
);
164 * Deletes a valid image file. Fails if specified file is not an image.
166 * @returns VBox status code.
167 * @param pszFilename Name of the image file to check.
169 int VDIDeleteImage(const char *pszFilename
);
172 * Makes a copy of image file with a new (other) creation uuid.
174 * @returns VBox status code.
175 * @param pszDstFilename Name of the image file to create.
176 * @param pszSrcFilename Name of the image file to copy from.
177 * @param pszComment Pointer to image comment. If NULL, the comment
178 * will be copied from the source image.
179 * @param pfnProgress Progress callback. Optional. NULL if not to be used.
180 * @param pvUser User argument for the progress callback.
182 int VDICopyImage(const char *pszDstFilename
, const char *pszSrcFilename
, const char *pszComment
,
183 PFNVMPROGRESS pfnProgress
, void *pvUser
);
186 * Converts image file from older VDI formats to current one.
188 * @returns VBox status code.
189 * @param pszFilename Name of the image file to convert.
190 * @param pfnProgress Progress callback. Optional. NULL if not to be used.
191 * @param pvUser User argument for the progress callback.
193 int VDIConvertImage(const char *pszFilename
, PFNVMPROGRESS pfnProgress
, void *pvUser
);
196 * Shrinks growing image file by removing zeroed data blocks.
198 * @returns VBox status code.
199 * @param pszFilename Name of the image file to shrink.
200 * @param pfnProgress Progress callback. Optional. NULL if not to be used.
201 * @param pvUser User argument for the progress callback.
203 int VDIShrinkImage(const char *pszFilename
, PFNVMPROGRESS pfnProgress
, void *pvUser
);
206 * Queries the image's UUID and parent UUIDs.
208 * @returns VBox status code.
209 * @param pszFilename Name of the image file to operate on.
210 * @param pUuid Where to store image UUID (can be NULL).
211 * @param pModificationUuid Where to store modification UUID (can be NULL).
212 * @param pParentUuuid Where to store parent UUID (can be NULL).
213 * @param pParentModificationUuid Where to store parent modification UUID (can be NULL).
215 int VDIGetImageUUIDs(const char *pszFilename
,
216 PRTUUID pUuid
, PRTUUID pModificationUuid
,
217 PRTUUID pParentUuid
, PRTUUID pParentModificationUuid
);
221 * Changes the image's UUID and parent UUIDs.
223 * @returns VBox status code.
224 * @param pszFilename Name of the image file to operate on.
225 * @param pUuid Optional parameter, new UUID of the image.
226 * @param pModificationUuid Optional parameter, new modification UUID of the image.
227 * @param pParentUuuid Optional parameter, new parent UUID of the image.
228 * @param pParentModificationUuid Optional parameter, new parent modification UUID of the image.
230 int VDISetImageUUIDs(const char *pszFilename
,
231 PCRTUUID pUuid
, PCRTUUID pModificationUuid
,
232 PCRTUUID pParentUuid
, PCRTUUID pParentModificationUuid
);
235 * Merges two images having a parent/child relationship (both directions).
237 * @returns VBox status code.
238 * @param pszFilenameFrom Name of the image file to merge from.
239 * @param pszFilenameTo Name of the image file to merge into.
240 * @param pfnProgress Progress callback. Optional. NULL if not to be used.
241 * @param pvUser User argument for the progress callback.
243 int VDIMergeImage(const char *pszFilenameFrom
, const char *pszFilenameTo
,
244 PFNVMPROGRESS pfnProgress
, void *pvUser
);
248 * Allocates and initializes an empty VDI HDD container.
249 * No image files are opened.
251 * @returns Pointer to newly created empty HDD container.
252 * @returns NULL on failure, typically out of memory.
254 PVDIDISK
VDIDiskCreate(void);
257 * Destroys the VDI HDD container. If container has opened image files they will be closed.
259 * @param pDisk Pointer to VDI HDD container.
261 void VDIDiskDestroy(PVDIDISK pDisk
);
264 * Opens an image file.
266 * The first opened image file in a HDD container must have a base image type,
267 * others (next opened images) must be a differencing or undo images.
268 * Linkage is checked for differencing image to be in consistence with the previously opened image.
269 * When a next differencing image is opened and the last image was opened in read/write access
270 * mode, then the last image is reopened in read-only with deny write sharing mode. This allows
271 * other processes to use images in read-only mode too.
273 * Note that the image can be opened in read-only mode if a read/write open is not possible.
274 * Use VDIDiskIsReadOnly to check open mode.
276 * @returns VBox status code.
277 * @param pDisk Pointer to VDI HDD container.
278 * @param pszFilename Name of the image file to open.
279 * @param fOpen Image file open mode, see VDI_OPEN_FLAGS_* constants.
281 int VDIDiskOpenImage(PVDIDISK pDisk
, const char *pszFilename
, unsigned fOpen
);
284 * Creates and opens a new differencing image file in HDD container.
285 * See comments for VDIDiskOpenImage function about differencing images.
287 * @returns VBox status code.
288 * @param pDisk Pointer to VDI HDD container.
289 * @param pszFilename Name of the image file to create and open.
290 * @param pszComment Pointer to image comment. NULL is ok.
291 * @param pfnProgress Progress callback. Optional. NULL if not to be used.
292 * @param pvUser User argument for the progress callback.
294 int VDIDiskCreateOpenDifferenceImage(PVDIDISK pDisk
, const char *pszFilename
, const char *pszComment
,
295 PFNVMPROGRESS pfnProgress
, void *pvUser
);
298 * Closes the last opened image file in the HDD container. Leaves all changes inside it.
299 * If previous image file was opened in read-only mode (that is normal) and closing image
300 * was opened in read-write mode (the whole disk was in read-write mode) - the previous image
301 * will be reopened in read/write mode.
303 * @param pDisk Pointer to VDI HDD container.
305 void VDIDiskCloseImage(PVDIDISK pDisk
);
308 * Closes all opened image files in HDD container.
310 * @param pDisk Pointer to VDI HDD container.
312 void VDIDiskCloseAllImages(PVDIDISK pDisk
);
315 * Commits last opened differencing/undo image file of the HDD container to previous image.
316 * If the previous image file was opened in read-only mode (that must be always so) it is reopened
317 * as read/write to do commit operation.
318 * After successfull commit the previous image file again reopened in read-only mode, last opened
319 * image file is cleared of data and remains open and active in HDD container.
320 * If you want to delete image after commit you must do it manually by VDIDiskCloseImage and
321 * VDIDeleteImage calls.
323 * Note that in case of unrecoverable error all images of HDD container will be closed.
325 * @returns VBox status code.
326 * @param pDisk Pointer to VDI HDD container.
327 * @param pfnProgress Progress callback. Optional.
328 * @param pvUser User argument for the progress callback.
330 int VDIDiskCommitLastDiff(PVDIDISK pDisk
, PFNVMPROGRESS pfnProgress
, void *pvUser
);
333 * Get read/write mode of VDI HDD.
335 * @returns Disk ReadOnly status.
336 * @returns true if no one VDI image is opened in HDD container.
338 bool VDIDiskIsReadOnly(PVDIDISK pDisk
);
341 * Get total disk size of the VDI HDD container.
343 * @returns Virtual disk size in bytes.
344 * @returns 0 if no one VDI image is opened in HDD container.
346 uint64_t VDIDiskGetSize(PVDIDISK pDisk
);
349 * Get block size of the VDI HDD container.
351 * @returns VDI image block size in bytes.
352 * @returns 0 if no one VDI image is opened in HDD container.
354 unsigned VDIDiskGetBlockSize(PVDIDISK pDisk
);
357 * Get working buffer size of the VDI HDD container.
359 * @returns Working buffer size in bytes.
361 unsigned VDIDiskGetBufferSize(PVDIDISK pDisk
);
364 * Get virtual disk geometry stored in image file.
366 * @returns VBox status code.
367 * @returns VERR_VDI_NOT_OPENED if no one VDI image is opened in HDD container.
368 * @returns VERR_VDI_GEOMETRY_NOT_SET if no geometry present in the HDD container.
369 * @param pDisk Pointer to VDI HDD container.
370 * @param pcCylinders Where to store the number of cylinders. NULL is ok.
371 * @param pcHeads Where to store the number of heads. NULL is ok.
372 * @param pcSectors Where to store the number of sectors. NULL is ok.
374 int VDIDiskGetGeometry(PVDIDISK pDisk
, unsigned *pcCylinders
, unsigned *pcHeads
, unsigned *pcSectors
);
377 * Store virtual disk geometry into base image file of HDD container.
379 * Note that in case of unrecoverable error all images of HDD container will be closed.
381 * @returns VBox status code.
382 * @returns VERR_VDI_NOT_OPENED if no one VDI image is opened in HDD container.
383 * @param pDisk Pointer to VDI HDD container.
384 * @param cCylinders Number of cylinders.
385 * @param cHeads Number of heads.
386 * @param cSectors Number of sectors.
388 int VDIDiskSetGeometry(PVDIDISK pDisk
, unsigned cCylinders
, unsigned cHeads
, unsigned cSectors
);
391 * Get virtual disk translation mode stored in image file.
393 * @returns VBox status code.
394 * @returns VERR_VDI_NOT_OPENED if no one VDI image is opened in HDD container.
395 * @param pDisk Pointer to VDI HDD container.
396 * @param penmTranslation Where to store the translation mode (see pdm.h).
398 int VDIDiskGetTranslation(PVDIDISK pDisk
, PPDMBIOSTRANSLATION penmTranslation
);
401 * Store virtual disk translation mode into base image file of HDD container.
403 * Note that in case of unrecoverable error all images of HDD container will be closed.
405 * @returns VBox status code.
406 * @returns VERR_VDI_NOT_OPENED if no one VDI image is opened in HDD container.
407 * @param pDisk Pointer to VDI HDD container.
408 * @param enmTranslation Translation mode (see pdm.h).
410 int VDIDiskSetTranslation(PVDIDISK pDisk
, PDMBIOSTRANSLATION enmTranslation
);
413 * Get number of opened images in HDD container.
415 * @returns Number of opened images for HDD container. 0 if no images has been opened.
416 * @param pDisk Pointer to VDI HDD container.
418 int VDIDiskGetImagesCount(PVDIDISK pDisk
);
421 * Get version of opened image of HDD container.
423 * @returns VBox status code.
424 * @returns VERR_VDI_IMAGE_NOT_FOUND if image with specified number was not opened.
425 * @param pDisk Pointer to VDI HDD container.
426 * @param nImage Image number, counts from 0. 0 is always base image of container.
427 * @param puVersion Where to store the image version.
429 int VDIDiskGetImageVersion(PVDIDISK pDisk
, int nImage
, unsigned *puVersion
);
432 * Get type of opened image of HDD container.
434 * @returns VBox status code.
435 * @returns VERR_VDI_IMAGE_NOT_FOUND if image with specified number was not opened.
436 * @param pDisk Pointer to VDI HDD container.
437 * @param nImage Image number, counts from 0. 0 is always base image of container.
438 * @param penmType Where to store the image type.
440 int VDIDiskGetImageType(PVDIDISK pDisk
, int nImage
, PVDIIMAGETYPE penmType
);
443 * Get flags of opened image of HDD container.
445 * @returns VBox status code.
446 * @returns VERR_VDI_IMAGE_NOT_FOUND if image with specified number was not opened.
447 * @param pDisk Pointer to VDI HDD container.
448 * @param nImage Image number, counts from 0. 0 is always base image of container.
449 * @param pfFlags Where to store the image flags.
451 int VDIDiskGetImageFlags(PVDIDISK pDisk
, int nImage
, unsigned *pfFlags
);
454 * Get filename of opened image of HDD container.
456 * @returns VBox status code.
457 * @returns VERR_VDI_IMAGE_NOT_FOUND if image with specified number was not opened.
458 * @returns VERR_BUFFER_OVERFLOW if pszFilename buffer too small to hold filename.
459 * @param pDisk Pointer to VDI HDD container.
460 * @param nImage Image number, counts from 0. 0 is always base image of container.
461 * @param pszFilename Where to store the image file name.
462 * @param cbFilename Size of buffer pszFilename points to.
464 int VDIDiskGetImageFilename(PVDIDISK pDisk
, int nImage
, char *pszFilename
, unsigned cbFilename
);
467 * Get the comment line of opened image of HDD container.
469 * @returns VBox status code.
470 * @returns VERR_VDI_IMAGE_NOT_FOUND if image with specified number was not opened.
471 * @returns VERR_BUFFER_OVERFLOW if pszComment buffer too small to hold comment text.
472 * @param pDisk Pointer to VDI HDD container.
473 * @param nImage Image number, counts from 0. 0 is always base image of container.
474 * @param pszComment Where to store the comment string of image. NULL is ok.
475 * @param cbComment The size of pszComment buffer. 0 is ok.
477 int VDIDiskGetImageComment(PVDIDISK pDisk
, int nImage
, char *pszComment
, unsigned cbComment
);
480 * Get Uuid of opened image of HDD container.
482 * @returns VBox status code.
483 * @returns VERR_VDI_IMAGE_NOT_FOUND if image with specified number was not opened.
484 * @param pDisk Pointer to VDI HDD container.
485 * @param nImage Image number, counts from 0. 0 is always base image of container.
486 * @param pUuid Where to store the image creation uuid.
488 int VDIDiskGetImageUuid(PVDIDISK pDisk
, int nImage
, PRTUUID pUuid
);
491 * Get last modification Uuid of opened image of HDD container.
493 * @returns VBox status code.
494 * @returns VERR_VDI_IMAGE_NOT_FOUND if image with specified number was not opened.
495 * @param pDisk Pointer to VDI HDD container.
496 * @param nImage Image number, counts from 0. 0 is always base image of container.
497 * @param pUuid Where to store the image modification uuid.
499 int VDIDiskGetImageModificationUuid(PVDIDISK pDisk
, int nImage
, PRTUUID pUuid
);
502 * Get Uuid of opened image's parent image.
504 * @returns VBox status code.
505 * @returns VERR_VDI_IMAGE_NOT_FOUND if image with specified number was not opened.
506 * @param pDisk Pointer to VDI HDD container.
507 * @param nImage Image number, counts from 0. 0 is always base image of the container.
508 * @param pUuid Where to store the image creation uuid.
510 int VDIDiskGetParentImageUuid(PVDIDISK pDisk
, int nImage
, PRTUUID pUuid
);
513 * Read data from virtual HDD.
515 * @returns VBox status code.
516 * @param pDisk Pointer to VDI HDD container.
517 * @param offStart Offset of first reading byte from start of disk.
518 * @param pvBuf Pointer to buffer for reading data.
519 * @param cbToRead Number of bytes to read.
521 int VDIDiskRead(PVDIDISK pDisk
, uint64_t offStart
, void *pvBuf
, size_t cbToRead
);
524 * Write data to virtual HDD.
526 * @returns VBox status code.
527 * @param pDisk Pointer to VDI HDD container.
528 * @param offStart Offset of first writing byte from start of HDD.
529 * @param pvBuf Pointer to buffer of writing data.
530 * @param cbToWrite Number of bytes to write.
532 int VDIDiskWrite(PVDIDISK pDisk
, uint64_t offStart
, const void *pvBuf
, size_t cbToWrite
);
537 * Debug helper - dumps all opened images of HDD container into the log file.
539 * @param pDisk Pointer to VDI HDD container.
541 void VDIDiskDumpImages(PVDIDISK pDisk
);