VirtualBox

source: vbox/trunk/src/VBox/Storage/VDICore.h@ 34891

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

VD: Move the generic virtual disk framework + backends to src/VBox/Storage and rename the files to get rid of the HDD part because it supports floppy and DVD images too

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.9 KB
Line 
1/* $Id: VDICore.h 33567 2010-10-28 15:37:21Z vboxsync $ */
2/** @file
3 * Virtual Disk Image (VDI), Core Code Header (internal).
4 */
5
6/*
7 * Copyright (C) 2006-2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef __VDICore_h__
19
20
21/*******************************************************************************
22* Header Files *
23*******************************************************************************/
24#include <VBox/vd.h>
25#ifndef VBOX_VDICORE_VD
26#include <VBox/pdm.h>
27#endif /* !VBOX_VDICORE_VD */
28#include <VBox/mm.h>
29#include <VBox/err.h>
30
31#include <VBox/log.h>
32#include <iprt/alloc.h>
33#include <iprt/assert.h>
34#include <iprt/uuid.h>
35#include <iprt/string.h>
36#include <iprt/asm.h>
37
38
39/*******************************************************************************
40* Constants And Macros, Structures and Typedefs *
41*******************************************************************************/
42
43/** Image info, not handled anyhow.
44 * Must be less than 64 bytes in length, including the trailing 0.
45 */
46#define VDI_IMAGE_FILE_INFO "<<< Oracle VM VirtualBox Disk Image >>>\n"
47
48/** The Sector size.
49 * Currently we support only 512 bytes sectors.
50 */
51#define VDI_GEOMETRY_SECTOR_SIZE (512)
52/** 512 = 2^^9 */
53#define VDI_GEOMETRY_SECTOR_SHIFT (9)
54
55/**
56 * Harddisk geometry.
57 */
58#pragma pack(1)
59typedef struct VDIDISKGEOMETRY
60{
61 /** Cylinders. */
62 uint32_t cCylinders;
63 /** Heads. */
64 uint32_t cHeads;
65 /** Sectors per track. */
66 uint32_t cSectors;
67 /** Sector size. (bytes per sector) */
68 uint32_t cbSector;
69} VDIDISKGEOMETRY, *PVDIDISKGEOMETRY;
70#pragma pack()
71
72/** Image signature. */
73#define VDI_IMAGE_SIGNATURE (0xbeda107f)
74
75/**
76 * Pre-Header to be stored in image file - used for version control.
77 */
78#pragma pack(1)
79typedef struct VDIPREHEADER
80{
81 /** Just text info about image type, for eyes only. */
82 char szFileInfo[64];
83 /** The image signature (VDI_IMAGE_SIGNATURE). */
84 uint32_t u32Signature;
85 /** The image version (VDI_IMAGE_VERSION). */
86 uint32_t u32Version;
87} VDIPREHEADER, *PVDIPREHEADER;
88#pragma pack()
89
90/**
91 * Size of szComment field of HDD image header.
92 */
93#define VDI_IMAGE_COMMENT_SIZE 256
94
95/**
96 * Header to be stored in image file, VDI_IMAGE_VERSION_MAJOR = 0.
97 * Prepended by VDIPREHEADER.
98 */
99#pragma pack(1)
100typedef struct VDIHEADER0
101{
102 /** The image type (VDI_IMAGE_TYPE_*). */
103 uint32_t u32Type;
104 /** Image flags (VDI_IMAGE_FLAGS_*). */
105 uint32_t fFlags;
106 /** Image comment. (UTF-8) */
107 char szComment[VDI_IMAGE_COMMENT_SIZE];
108 /** Legacy image geometry (previous code stored PCHS there). */
109 VDIDISKGEOMETRY LegacyGeometry;
110 /** Size of disk (in bytes). */
111 uint64_t cbDisk;
112 /** Block size. (For instance VDI_IMAGE_BLOCK_SIZE.) */
113 uint32_t cbBlock;
114 /** Number of blocks. */
115 uint32_t cBlocks;
116 /** Number of allocated blocks. */
117 uint32_t cBlocksAllocated;
118 /** UUID of image. */
119 RTUUID uuidCreate;
120 /** UUID of image's last modification. */
121 RTUUID uuidModify;
122 /** Only for secondary images - UUID of primary image. */
123 RTUUID uuidLinkage;
124} VDIHEADER0, *PVDIHEADER0;
125#pragma pack()
126
127/**
128 * Header to be stored in image file, VDI_IMAGE_VERSION_MAJOR = 1,
129 * VDI_IMAGE_VERSION_MINOR = 1. Prepended by VDIPREHEADER.
130 */
131#pragma pack(1)
132typedef struct VDIHEADER1
133{
134 /** Size of this structure in bytes. */
135 uint32_t cbHeader;
136 /** The image type (VDI_IMAGE_TYPE_*). */
137 uint32_t u32Type;
138 /** Image flags (VDI_IMAGE_FLAGS_*). */
139 uint32_t fFlags;
140 /** Image comment. (UTF-8) */
141 char szComment[VDI_IMAGE_COMMENT_SIZE];
142 /** Offset of Blocks array from the beginning of image file.
143 * Should be sector-aligned for HDD access optimization. */
144 uint32_t offBlocks;
145 /** Offset of image data from the beginning of image file.
146 * Should be sector-aligned for HDD access optimization. */
147 uint32_t offData;
148 /** Legacy image geometry (previous code stored PCHS there). */
149 VDIDISKGEOMETRY LegacyGeometry;
150 /** Was BIOS HDD translation mode, now unused. */
151 uint32_t u32Dummy;
152 /** Size of disk (in bytes). */
153 uint64_t cbDisk;
154 /** Block size. (For instance VDI_IMAGE_BLOCK_SIZE.) Should be a power of 2! */
155 uint32_t cbBlock;
156 /** Size of additional service information of every data block.
157 * Prepended before block data. May be 0.
158 * Should be a power of 2 and sector-aligned for optimization reasons. */
159 uint32_t cbBlockExtra;
160 /** Number of blocks. */
161 uint32_t cBlocks;
162 /** Number of allocated blocks. */
163 uint32_t cBlocksAllocated;
164 /** UUID of image. */
165 RTUUID uuidCreate;
166 /** UUID of image's last modification. */
167 RTUUID uuidModify;
168 /** Only for secondary images - UUID of previous image. */
169 RTUUID uuidLinkage;
170 /** Only for secondary images - UUID of previous image's last modification. */
171 RTUUID uuidParentModify;
172} VDIHEADER1, *PVDIHEADER1;
173#pragma pack()
174
175/**
176 * Header to be stored in image file, VDI_IMAGE_VERSION_MAJOR = 1,
177 * VDI_IMAGE_VERSION_MINOR = 1, the slightly changed variant necessary as the
178 * old released code doesn't support changing the minor version at all.
179 */
180#pragma pack(1)
181typedef struct VDIHEADER1PLUS
182{
183 /** Size of this structure in bytes. */
184 uint32_t cbHeader;
185 /** The image type (VDI_IMAGE_TYPE_*). */
186 uint32_t u32Type;
187 /** Image flags (VDI_IMAGE_FLAGS_*). */
188 uint32_t fFlags;
189 /** Image comment. (UTF-8) */
190 char szComment[VDI_IMAGE_COMMENT_SIZE];
191 /** Offset of blocks array from the beginning of image file.
192 * Should be sector-aligned for HDD access optimization. */
193 uint32_t offBlocks;
194 /** Offset of image data from the beginning of image file.
195 * Should be sector-aligned for HDD access optimization. */
196 uint32_t offData;
197 /** Legacy image geometry (previous code stored PCHS there). */
198 VDIDISKGEOMETRY LegacyGeometry;
199 /** Was BIOS HDD translation mode, now unused. */
200 uint32_t u32Dummy;
201 /** Size of disk (in bytes). */
202 uint64_t cbDisk;
203 /** Block size. (For instance VDI_IMAGE_BLOCK_SIZE.) Should be a power of 2! */
204 uint32_t cbBlock;
205 /** Size of additional service information of every data block.
206 * Prepended before block data. May be 0.
207 * Should be a power of 2 and sector-aligned for optimization reasons. */
208 uint32_t cbBlockExtra;
209 /** Number of blocks. */
210 uint32_t cBlocks;
211 /** Number of allocated blocks. */
212 uint32_t cBlocksAllocated;
213 /** UUID of image. */
214 RTUUID uuidCreate;
215 /** UUID of image's last modification. */
216 RTUUID uuidModify;
217 /** Only for secondary images - UUID of previous image. */
218 RTUUID uuidLinkage;
219 /** Only for secondary images - UUID of previous image's last modification. */
220 RTUUID uuidParentModify;
221 /** LCHS image geometry (new field in VDI1.2 version. */
222 VDIDISKGEOMETRY LCHSGeometry;
223} VDIHEADER1PLUS, *PVDIHEADER1PLUS;
224#pragma pack()
225
226/**
227 * Header structure for all versions.
228 */
229typedef struct VDIHEADER
230{
231 unsigned uVersion;
232 union
233 {
234 VDIHEADER0 v0;
235 VDIHEADER1 v1;
236 VDIHEADER1PLUS v1plus;
237 } u;
238} VDIHEADER, *PVDIHEADER;
239
240/**
241 * File alignment boundary for both the block array and data area. Should be
242 * at least the size of a physical sector on disk for performance reasons.
243 * With the growing market share of disks with 4K sectors this needs to be
244 * bumped, and maybe again later. */
245#define VDI_DATA_ALIGN _4K
246
247/** Block 'pointer'. */
248typedef uint32_t VDIIMAGEBLOCKPOINTER;
249/** Pointer to a block 'pointer'. */
250typedef VDIIMAGEBLOCKPOINTER *PVDIIMAGEBLOCKPOINTER;
251
252/**
253 * Block marked as free is not allocated in image file, read from this
254 * block may returns any random data.
255 */
256#define VDI_IMAGE_BLOCK_FREE ((VDIIMAGEBLOCKPOINTER)~0)
257
258/**
259 * Block marked as zero is not allocated in image file, read from this
260 * block returns zeroes.
261 */
262#define VDI_IMAGE_BLOCK_ZERO ((VDIIMAGEBLOCKPOINTER)~1)
263
264/**
265 * Block 'pointer' >= VDI_IMAGE_BLOCK_UNALLOCATED indicates block is not
266 * allocated in image file.
267 */
268#define VDI_IMAGE_BLOCK_UNALLOCATED (VDI_IMAGE_BLOCK_ZERO)
269#define IS_VDI_IMAGE_BLOCK_ALLOCATED(bp) (bp < VDI_IMAGE_BLOCK_UNALLOCATED)
270
271#define GET_MAJOR_HEADER_VERSION(ph) (VDI_GET_VERSION_MAJOR((ph)->uVersion))
272#define GET_MINOR_HEADER_VERSION(ph) (VDI_GET_VERSION_MINOR((ph)->uVersion))
273
274#ifdef VBOX_VDICORE_VD
275/** @name VDI image types
276 * @{ */
277typedef enum VDIIMAGETYPE
278{
279 /** Normal dynamically growing base image file. */
280 VDI_IMAGE_TYPE_NORMAL = 1,
281 /** Preallocated base image file of a fixed size. */
282 VDI_IMAGE_TYPE_FIXED,
283 /** Dynamically growing image file for undo/commit changes support. */
284 VDI_IMAGE_TYPE_UNDO,
285 /** Dynamically growing image file for differencing support. */
286 VDI_IMAGE_TYPE_DIFF,
287
288 /** First valid image type value. */
289 VDI_IMAGE_TYPE_FIRST = VDI_IMAGE_TYPE_NORMAL,
290 /** Last valid image type value. */
291 VDI_IMAGE_TYPE_LAST = VDI_IMAGE_TYPE_DIFF
292} VDIIMAGETYPE;
293/** Pointer to VDI image type. */
294typedef VDIIMAGETYPE *PVDIIMAGETYPE;
295/** @} */
296#endif /* VBOX_VDICORE_VD */
297
298/*******************************************************************************
299* Internal Functions for header access *
300*******************************************************************************/
301DECLINLINE(VDIIMAGETYPE) getImageType(PVDIHEADER ph)
302{
303 switch (GET_MAJOR_HEADER_VERSION(ph))
304 {
305 case 0: return (VDIIMAGETYPE)ph->u.v0.u32Type;
306 case 1: return (VDIIMAGETYPE)ph->u.v1.u32Type;
307 }
308 AssertFailed();
309 return (VDIIMAGETYPE)0;
310}
311
312#ifdef VBOX_VDICORE_VD
313DECLINLINE(unsigned) getImageFlags(PVDIHEADER ph)
314{
315 switch (GET_MAJOR_HEADER_VERSION(ph))
316 {
317 case 0:
318 /* VDI image flag conversion to VD image flags. */
319 return ph->u.v0.fFlags << 8;
320 case 1:
321 /* VDI image flag conversion to VD image flags. */
322 return ph->u.v1.fFlags << 8;
323 }
324 AssertFailed();
325 return 0;
326}
327#else /* !VBOX_VDICORE_VD */
328DECLINLINE(unsigned) getImageFlags(PVDIHEADER ph)
329{
330 switch (GET_MAJOR_HEADER_VERSION(ph))
331 {
332 case 0: return ph->u.v0.fFlags;
333 case 1: return ph->u.v1.fFlags;
334 }
335 AssertFailed();
336 return 0;
337}
338#endif /* !VBOX_VDICORE_VD */
339
340DECLINLINE(char *) getImageComment(PVDIHEADER ph)
341{
342 switch (GET_MAJOR_HEADER_VERSION(ph))
343 {
344 case 0: return &ph->u.v0.szComment[0];
345 case 1: return &ph->u.v1.szComment[0];
346 }
347 AssertFailed();
348 return NULL;
349}
350
351DECLINLINE(unsigned) getImageBlocksOffset(PVDIHEADER ph)
352{
353 switch (GET_MAJOR_HEADER_VERSION(ph))
354 {
355 case 0: return (sizeof(VDIPREHEADER) + sizeof(VDIHEADER0));
356 case 1: return ph->u.v1.offBlocks;
357 }
358 AssertFailed();
359 return 0;
360}
361
362DECLINLINE(uint32_t) getImageDataOffset(PVDIHEADER ph)
363{
364 switch (GET_MAJOR_HEADER_VERSION(ph))
365 {
366 case 0: return sizeof(VDIPREHEADER) + sizeof(VDIHEADER0) + \
367 (ph->u.v0.cBlocks * sizeof(VDIIMAGEBLOCKPOINTER));
368 case 1: return ph->u.v1.offData;
369 }
370 AssertFailed();
371 return 0;
372}
373
374DECLINLINE(void) setImageDataOffset(PVDIHEADER ph, uint32_t offData)
375{
376 switch (GET_MAJOR_HEADER_VERSION(ph))
377 {
378 case 0: return;
379 case 1: ph->u.v1.offData = offData; return;
380 }
381 AssertFailed();
382}
383
384DECLINLINE(PVDIDISKGEOMETRY) getImageLCHSGeometry(PVDIHEADER ph)
385{
386 switch (GET_MAJOR_HEADER_VERSION(ph))
387 {
388 case 0: return NULL;
389 case 1:
390 switch (GET_MINOR_HEADER_VERSION(ph))
391 {
392 case 1:
393 if (ph->u.v1.cbHeader < sizeof(ph->u.v1plus))
394 return NULL;
395 else
396 return &ph->u.v1plus.LCHSGeometry;
397 }
398 }
399 AssertFailed();
400 return NULL;
401}
402
403DECLINLINE(uint64_t) getImageDiskSize(PVDIHEADER ph)
404{
405 switch (GET_MAJOR_HEADER_VERSION(ph))
406 {
407 case 0: return ph->u.v0.cbDisk;
408 case 1: return ph->u.v1.cbDisk;
409 }
410 AssertFailed();
411 return 0;
412}
413
414DECLINLINE(void) setImageDiskSize(PVDIHEADER ph, uint64_t cbDisk)
415{
416 switch (GET_MAJOR_HEADER_VERSION(ph))
417 {
418 case 0: ph->u.v0.cbDisk = cbDisk; return;
419 case 1: ph->u.v1.cbDisk = cbDisk; return;
420 }
421 AssertFailed();
422}
423
424DECLINLINE(unsigned) getImageBlockSize(PVDIHEADER ph)
425{
426 switch (GET_MAJOR_HEADER_VERSION(ph))
427 {
428 case 0: return ph->u.v0.cbBlock;
429 case 1: return ph->u.v1.cbBlock;
430 }
431 AssertFailed();
432 return 0;
433}
434
435DECLINLINE(unsigned) getImageExtraBlockSize(PVDIHEADER ph)
436{
437 switch (GET_MAJOR_HEADER_VERSION(ph))
438 {
439 case 0: return 0;
440 case 1: return ph->u.v1.cbBlockExtra;
441 }
442 AssertFailed();
443 return 0;
444}
445
446DECLINLINE(unsigned) getImageBlocks(PVDIHEADER ph)
447{
448 switch (GET_MAJOR_HEADER_VERSION(ph))
449 {
450 case 0: return ph->u.v0.cBlocks;
451 case 1: return ph->u.v1.cBlocks;
452 }
453 AssertFailed();
454 return 0;
455}
456
457DECLINLINE(void) setImageBlocks(PVDIHEADER ph, unsigned cBlocks)
458{
459 switch (GET_MAJOR_HEADER_VERSION(ph))
460 {
461 case 0: ph->u.v0.cBlocks = cBlocks; return;
462 case 1: ph->u.v1.cBlocks = cBlocks; return;
463 }
464 AssertFailed();
465}
466
467
468DECLINLINE(unsigned) getImageBlocksAllocated(PVDIHEADER ph)
469{
470 switch (GET_MAJOR_HEADER_VERSION(ph))
471 {
472 case 0: return ph->u.v0.cBlocksAllocated;
473 case 1: return ph->u.v1.cBlocksAllocated;
474 }
475 AssertFailed();
476 return 0;
477}
478
479DECLINLINE(void) setImageBlocksAllocated(PVDIHEADER ph, unsigned cBlocks)
480{
481 switch (GET_MAJOR_HEADER_VERSION(ph))
482 {
483 case 0: ph->u.v0.cBlocksAllocated = cBlocks; return;
484 case 1: ph->u.v1.cBlocksAllocated = cBlocks; return;
485 }
486 AssertFailed();
487}
488
489DECLINLINE(PRTUUID) getImageCreationUUID(PVDIHEADER ph)
490{
491 switch (GET_MAJOR_HEADER_VERSION(ph))
492 {
493 case 0: return &ph->u.v0.uuidCreate;
494 case 1: return &ph->u.v1.uuidCreate;
495 }
496 AssertFailed();
497 return NULL;
498}
499
500DECLINLINE(PRTUUID) getImageModificationUUID(PVDIHEADER ph)
501{
502 switch (GET_MAJOR_HEADER_VERSION(ph))
503 {
504 case 0: return &ph->u.v0.uuidModify;
505 case 1: return &ph->u.v1.uuidModify;
506 }
507 AssertFailed();
508 return NULL;
509}
510
511DECLINLINE(PRTUUID) getImageParentUUID(PVDIHEADER ph)
512{
513 switch (GET_MAJOR_HEADER_VERSION(ph))
514 {
515 case 0: return &ph->u.v0.uuidLinkage;
516 case 1: return &ph->u.v1.uuidLinkage;
517 }
518 AssertFailed();
519 return NULL;
520}
521
522DECLINLINE(PRTUUID) getImageParentModificationUUID(PVDIHEADER ph)
523{
524 switch (GET_MAJOR_HEADER_VERSION(ph))
525 {
526 case 1: return &ph->u.v1.uuidParentModify;
527 }
528 AssertFailed();
529 return NULL;
530}
531
532#ifndef VBOX_VDICORE_VD
533/**
534 * Default image block size, may be changed by setBlockSize/getBlockSize.
535 *
536 * Note: for speed reasons block size should be a power of 2 !
537 */
538#define VDI_IMAGE_DEFAULT_BLOCK_SIZE _1M
539#endif /* !VBOX_VDICORE_VD */
540
541#ifndef VBOX_VDICORE_VD
542/**
543 * fModified bit flags.
544 */
545#define VDI_IMAGE_MODIFIED_FLAG RT_BIT(0)
546#define VDI_IMAGE_MODIFIED_FIRST RT_BIT(1)
547#define VDI_IMAGE_MODIFIED_DISABLE_UUID_UPDATE RT_BIT(2)
548#endif /* !VBOX_VDICORE_VD */
549
550/**
551 * Image structure
552 */
553typedef struct VDIIMAGEDESC
554{
555#ifndef VBOX_VDICORE_VD
556 /** Link to parent image descriptor, if any. */
557 struct VDIIMAGEDESC *pPrev;
558 /** Link to child image descriptor, if any. */
559 struct VDIIMAGEDESC *pNext;
560#endif /* !VBOX_VDICORE_VD */
561 /** Opaque storage handle. */
562 PVDIOSTORAGE pStorage;
563#ifndef VBOX_VDICORE_VD
564 /** True if the image is operating in readonly mode. */
565 bool fReadOnly;
566 /** Image open flags, VDI_OPEN_FLAGS_*. */
567 unsigned fOpen;
568#else /* VBOX_VDICORE_VD */
569 /** Image open flags, VD_OPEN_FLAGS_*. */
570 unsigned uOpenFlags;
571#endif /* VBOX_VDICORE_VD */
572 /** Image pre-header. */
573 VDIPREHEADER PreHeader;
574 /** Image header. */
575 VDIHEADER Header;
576 /** Pointer to a block array. */
577 PVDIIMAGEBLOCKPOINTER paBlocks;
578#ifndef VBOX_VDICORE_VD
579 /** fFlags copy from image header, for speed optimization. */
580 unsigned fFlags;
581#else /* VBOX_VDICORE_VD */
582 /** fFlags copy from image header, for speed optimization. */
583 unsigned uImageFlags;
584#endif /* VBOX_VDICORE_VD */
585 /** Start offset of block array in image file, here for speed optimization. */
586 unsigned offStartBlocks;
587 /** Start offset of data in image file, here for speed optimization. */
588 unsigned offStartData;
589 /** Block mask for getting the offset into a block from a byte hdd offset. */
590 unsigned uBlockMask;
591 /** Block shift value for converting byte hdd offset into paBlock index. */
592 unsigned uShiftOffset2Index;
593#ifndef VBOX_VDICORE_VD
594 /** Block shift value for converting block index into offset in image. */
595 unsigned uShiftIndex2Offset;
596#endif /* !VBOX_VDICORE_VD */
597 /** Offset of data from the beginning of block. */
598 unsigned offStartBlockData;
599#ifndef VBOX_VDICORE_VD
600 /** Image is modified flags (VDI_IMAGE_MODIFIED*). */
601 unsigned fModified;
602 /** Container filename. (UTF-8)
603 * @todo Make this variable length to save a bunch of bytes. (low prio) */
604 char szFilename[RTPATH_MAX];
605#else /* VBOX_VDICORE_VD */
606 /** Total size of image block (including the extra data). */
607 unsigned cbTotalBlockData;
608 /** Container filename. (UTF-8) */
609 const char *pszFilename;
610 /** Physical geometry of this image (never actually stored). */
611 VDGEOMETRY PCHSGeometry;
612 /** Pointer to the per-disk VD interface list. */
613 PVDINTERFACE pVDIfsDisk;
614 /** Pointer to the per-image VD interface list. */
615 PVDINTERFACE pVDIfsImage;
616 /** Error interface. */
617 PVDINTERFACE pInterfaceError;
618 /** Error interface callback table. */
619 PVDINTERFACEERROR pInterfaceErrorCallbacks;
620 /** I/O interface. */
621 PVDINTERFACE pInterfaceIO;
622 /** I/O interface callbacks. */
623 PVDINTERFACEIOINT pInterfaceIOCallbacks;
624#endif /* VBOX_VDICORE_VD */
625} VDIIMAGEDESC, *PVDIIMAGEDESC;
626
627#ifndef VBOX_VDICORE_VD
628/**
629 * Default work buffer size, may be changed by setBufferSize() method.
630 *
631 * For best speed performance it must be equal to image block size.
632 */
633#define VDIDISK_DEFAULT_BUFFER_SIZE (VDI_IMAGE_DEFAULT_BLOCK_SIZE)
634#endif /* !VBOX_VDICORE_VD */
635
636/** VDIDISK Signature. */
637#define VDIDISK_SIGNATURE (0xbedafeda)
638
639/**
640 * VBox HDD Container main structure, private part.
641 */
642struct VDIDISK
643{
644 /** Structure signature (VDIDISK_SIGNATURE). */
645 uint32_t u32Signature;
646
647 /** Number of opened images. */
648 unsigned cImages;
649
650 /** Base image. */
651 PVDIIMAGEDESC pBase;
652
653 /** Last opened image in the chain.
654 * The same as pBase if only one image is used or the last opened diff image. */
655 PVDIIMAGEDESC pLast;
656
657 /** Default block size for newly created images. */
658 unsigned cbBlock;
659
660 /** Working buffer size, allocated only while committing data,
661 * copying block from primary image to secondary and saving previously
662 * zero block. Buffer deallocated after operation complete.
663 * @remark For best performance buffer size must be equal to image's
664 * block size, however it may be decreased for memory saving.
665 */
666 unsigned cbBuf;
667
668 /** Flag whether zero writes should be handled normally or optimized
669 * away if possible. */
670 bool fHonorZeroWrites;
671
672#ifndef VBOX_VDICORE_VD
673 /** The media interface. */
674 PDMIMEDIA IMedia;
675 /** Pointer to the driver instance. */
676 PPDMDRVINS pDrvIns;
677#endif /* !VBOX_VDICORE_VD */
678};
679
680
681/*******************************************************************************
682* Internal Functions *
683*******************************************************************************/
684RT_C_DECLS_BEGIN
685
686#ifndef VBOX_VDICORE_VD
687VBOXDDU_DECL(void) vdiInitVDIDisk(PVDIDISK pDisk);
688VBOXDDU_DECL(void) VDIFlushImage(PVDIIMAGEDESC pImage);
689VBOXDDU_DECL(int) vdiChangeImageMode(PVDIIMAGEDESC pImage, bool fReadOnly);
690#endif /* !VBOX_VDICORE_VD */
691
692RT_C_DECLS_END
693
694#endif
Note: See TracBrowser for help on using the repository browser.

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