Changeset 6363 in vbox
- Timestamp:
- Jan 16, 2008 3:40:29 PM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 27295
- Location:
- trunk/src/VBox/Devices/Storage
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/VDICore.cpp
r6291 r6363 112 112 return VERR_VDI_INVALID_SIGNATURE; 113 113 114 if ( pPreHdr->u32Version != VDI_IMAGE_VERSION114 if ( VDI_GET_VERSION_MAJOR(pPreHdr->u32Version) != VDI_IMAGE_VERSION_MAJOR 115 115 && pPreHdr->u32Version != 0x00000002) /* old version. */ 116 116 return VERR_VDI_UNSUPPORTED_VERSION; … … 143 143 } 144 144 145 /* Mark the geometry not-calculated. */146 pHeader->u.v1.L CHSGeometry.cCylinders = 0;147 pHeader->u.v1.L CHSGeometry.cHeads = 0;148 pHeader->u.v1.L CHSGeometry.cSectors = 0;149 pHeader->u.v1.L CHSGeometry.cbSector = VDI_GEOMETRY_SECTOR_SIZE;150 pHeader->u.v1.u32Dummy = 0; 145 /* Mark the legacy geometry not-calculated. */ 146 pHeader->u.v1.LegacyGeometry.cCylinders = 0; 147 pHeader->u.v1.LegacyGeometry.cHeads = 0; 148 pHeader->u.v1.LegacyGeometry.cSectors = 0; 149 pHeader->u.v1.LegacyGeometry.cbSector = VDI_GEOMETRY_SECTOR_SIZE; 150 pHeader->u.v1.u32Dummy = 0; /* used to be the translation value */ 151 151 152 152 pHeader->u.v1.cbDisk = cbDisk; … … 167 167 RTUuidClear(&pHeader->u.v1.uuidLinkage); 168 168 RTUuidClear(&pHeader->u.v1.uuidParentModify); 169 170 /* Mark LCHS geometry not-calculated. */ 171 pHeader->u.v1plus.LCHSGeometry.cCylinders = 0; 172 pHeader->u.v1plus.LCHSGeometry.cHeads = 0; 173 pHeader->u.v1plus.LCHSGeometry.cSectors = 0; 174 pHeader->u.v1plus.LCHSGeometry.cbSector = VDI_GEOMETRY_SECTOR_SIZE; 169 175 } 170 176 … … 246 252 } 247 253 248 if ((getImageLCHSGeometry(pHeader))->cbSector != VDI_GEOMETRY_SECTOR_SIZE) 254 if ( getImageLCHSGeometry(pHeader) 255 && (getImageLCHSGeometry(pHeader))->cbSector != VDI_GEOMETRY_SECTOR_SIZE) 249 256 { 250 257 LogRel(("VDI: wrong sector size (%d != %d)\n", … … 355 362 { 356 363 Assert(pParent); 357 if ( (pParent->PreHeader.u32Version >> 16) != VDI_IMAGE_VERSION_MAJOR)364 if (VDI_GET_VERSION_MAJOR(pParent->PreHeader.u32Version) != VDI_IMAGE_VERSION_MAJOR) 358 365 { 359 366 /* Invalid parent image version. */ … … 451 458 452 459 /* Write header. */ 453 rc = RTFileWrite(pImage->File, &pImage->Header.u.v1 , sizeof(pImage->Header.u.v1), NULL);460 rc = RTFileWrite(pImage->File, &pImage->Header.u.v1plus, sizeof(pImage->Header.u.v1plus), NULL); 454 461 if (VBOX_FAILURE(rc)) 455 462 goto l_create_failed; … … 624 631 break; 625 632 case 1: 626 rc = RTFileRead(pImage->File, &pImage->Header.u.v1, sizeof(pImage->Header.u.v1), NULL); 633 switch (GET_MINOR_HEADER_VERSION(&pImage->Header)) 634 { 635 case 1: 636 rc = RTFileRead(pImage->File, &pImage->Header.u.v1, sizeof(pImage->Header.u.v1), NULL); 637 /* Convert VDI 1.1 images to VDI 1.1+ on open in read/write 638 * mode. Conversion is harmless, as any VirtualBox version 639 * supporting VDI 1.1 doesn't touch fields it doesn't know 640 * about. And it accepts bigger headers. */ 641 if ( VBOX_SUCCESS(rc) 642 && !pImage->fReadOnly 643 && pImage->Header.u.v1.cbHeader < sizeof(pImage->Header.u.v1plus)) 644 { 645 pImage->Header.u.v1plus.cbHeader = sizeof(pImage->Header.u.v1plus); 646 /* Mark LCHS geometry not-calculated. */ 647 pImage->Header.u.v1plus.LCHSGeometry.cCylinders = 0; 648 pImage->Header.u.v1plus.LCHSGeometry.cHeads = 0; 649 pImage->Header.u.v1plus.LCHSGeometry.cSectors = 0; 650 pImage->Header.u.v1plus.LCHSGeometry.cbSector = VDI_GEOMETRY_SECTOR_SIZE; 651 } 652 else if ( VBOX_SUCCESS(rc) 653 && pImage->Header.u.v1.cbHeader >= sizeof(pImage->Header.u.v1plus)) 654 { 655 /* Read the actual VDI 1.1+ header completely. */ 656 rc = RTFileReadAt(pImage->File, sizeof(pImage->PreHeader), &pImage->Header.u.v1plus, sizeof(pImage->Header.u.v1plus), NULL); 657 } 658 break; 659 default: 660 rc = VERR_VDI_UNSUPPORTED_VERSION; 661 break; 662 } 627 663 break; 628 664 default: … … 753 789 break; 754 790 case 1: 755 rc = RTFileWrite(pImage->File, &pImage->Header.u.v1, sizeof(pImage->Header.u.v1), NULL); 791 switch (GET_MAJOR_HEADER_VERSION(&pImage->Header)) 792 { 793 case 1: 794 if (pImage->Header.u.v1plus.cbHeader < sizeof(pImage->Header.u.v1plus)) 795 rc = RTFileWrite(pImage->File, &pImage->Header.u.v1, sizeof(pImage->Header.u.v1), NULL); 796 else 797 rc = RTFileWrite(pImage->File, &pImage->Header.u.v1plus, sizeof(pImage->Header.u.v1plus), NULL); 798 break; 799 default: 800 rc = VERR_VDI_UNSUPPORTED_VERSION; 801 break; 802 } 756 803 break; 757 804 default: … … 2266 2313 0); 2267 2314 setImageBlocksAllocated(&Header, getImageBlocksAllocated(&pImage->Header)); 2268 *getImageLCHSGeometry(&Header) = *getImageLCHSGeometry(&pImage->Header); 2315 /* Set both the LCHSGeometry and LegacyGeometry. If they're wrong they 2316 * will be fixed later when the image is used. */ 2317 if (getImageLCHSGeometry(&pImage->Header)) 2318 { 2319 Header.u.v1.LegacyGeometry = *getImageLCHSGeometry(&pImage->Header); 2320 Header.u.v1plus.LCHSGeometry = *getImageLCHSGeometry(&pImage->Header); 2321 } 2269 2322 *getImageCreationUUID(&Header) = *getImageCreationUUID(&pImage->Header); 2270 2323 *getImageModificationUUID(&Header) = *getImageModificationUUID(&pImage->Header); … … 2866 2919 { 2867 2920 int rc = VINF_SUCCESS; 2921 VDIDISKGEOMETRY DummyGeo = { 0, 0, 0, VDI_GEOMETRY_SECTOR_SIZE }; 2868 2922 PVDIDISKGEOMETRY pGeometry = getImageLCHSGeometry(&pDisk->pBase->Header); 2923 if (!pGeometry) 2924 pGeometry = &DummyGeo; 2925 2869 2926 LogFlow(("%s: C/H/S = %u/%u/%u\n", 2870 2927 __FUNCTION__, pGeometry->cCylinders, pGeometry->cHeads, pGeometry->cSectors)); … … 2907 2964 if (pDisk->pBase) 2908 2965 { 2966 int rc = VINF_SUCCESS; 2909 2967 PVDIDISKGEOMETRY pGeometry = getImageLCHSGeometry(&pDisk->pBase->Header); 2910 pGeometry->cCylinders = pLCHSGeometry->cCylinders; 2911 pGeometry->cHeads = pLCHSGeometry->cHeads; 2912 pGeometry->cSectors = pLCHSGeometry->cSectors; 2913 pGeometry->cbSector = VDI_GEOMETRY_SECTOR_SIZE; 2914 2915 /* Update header information in base image file. */ 2916 int rc = vdiUpdateReadOnlyHeader(pDisk->pBase); 2968 if (pGeometry) 2969 { 2970 pGeometry->cCylinders = pLCHSGeometry->cCylinders; 2971 pGeometry->cHeads = pLCHSGeometry->cHeads; 2972 pGeometry->cSectors = pLCHSGeometry->cSectors; 2973 pGeometry->cbSector = VDI_GEOMETRY_SECTOR_SIZE; 2974 2975 /* Update header information in base image file. */ 2976 rc = vdiUpdateReadOnlyHeader(pDisk->pBase); 2977 } 2917 2978 LogFlow(("%s: returns %Vrc\n", __FUNCTION__, rc)); 2918 2979 return rc; … … 3582 3643 getImageDataOffset(&pImage->Header)); 3583 3644 PVDIDISKGEOMETRY pg = getImageLCHSGeometry(&pImage->Header); 3584 RTLogPrintf("Header: Geometry: C/H/S=%u/%u/%u cbSector=%u\n", 3585 pg->cCylinders, pg->cHeads, pg->cSectors, pg->cbSector); 3645 if (pg) 3646 RTLogPrintf("Header: Geometry: C/H/S=%u/%u/%u cbSector=%u\n", 3647 pg->cCylinders, pg->cHeads, pg->cSectors, pg->cbSector); 3586 3648 RTLogPrintf("Header: uuidCreation={%Vuuid}\n", getImageCreationUUID(&pImage->Header)); 3587 3649 RTLogPrintf("Header: uuidModification={%Vuuid}\n", getImageModificationUUID(&pImage->Header)); -
trunk/src/VBox/Devices/Storage/VDICore.h
r6291 r6363 105 105 /** Image comment. (UTF-8) */ 106 106 char szComment[VDI_IMAGE_COMMENT_SIZE]; 107 /** Image geometry. */108 VDIDISKGEOMETRY L CHSGeometry;107 /** Legacy image geometry (previous code stored PCHS there). */ 108 VDIDISKGEOMETRY LegacyGeometry; 109 109 /** Size of disk (in bytes). */ 110 110 uint64_t cbDisk; … … 125 125 126 126 /** 127 * Header to be stored in image file, VDI_IMAGE_VERSION_MAJOR = 1 .128 * Prepended by VDIPREHEADER.127 * Header to be stored in image file, VDI_IMAGE_VERSION_MAJOR = 1, 128 * VDI_IMAGE_VERSION_MINOR = 1. Prepended by VDIPREHEADER. 129 129 */ 130 130 #pragma pack(1) … … 145 145 * Should be sector-aligned for HDD access optimization. */ 146 146 uint32_t offData; 147 /** Image geometry. */148 VDIDISKGEOMETRY L CHSGeometry;147 /** Legacy image geometry (previous code stored PCHS there). */ 148 VDIDISKGEOMETRY LegacyGeometry; 149 149 /** Was BIOS HDD translation mode, now unused. */ 150 150 uint32_t u32Dummy; … … 173 173 174 174 /** 175 * Header to be stored in image file, VDI_IMAGE_VERSION_MAJOR = 1, 176 * VDI_IMAGE_VERSION_MINOR = 1, the slightly changed variant necessary as the 177 * old released code doesn't support changing the minor version at all. 178 */ 179 #pragma pack(1) 180 typedef struct VDIHEADER1PLUS 181 { 182 /** Size of this structure in bytes. */ 183 uint32_t cbHeader; 184 /** The image type (VDI_IMAGE_TYPE_*). */ 185 uint32_t u32Type; 186 /** Image flags (VDI_IMAGE_FLAGS_*). */ 187 uint32_t fFlags; 188 /** Image comment. (UTF-8) */ 189 char szComment[VDI_IMAGE_COMMENT_SIZE]; 190 /** Offset of Blocks array from the begining of image file. 191 * Should be sector-aligned for HDD access optimization. */ 192 uint32_t offBlocks; 193 /** Offset of image data from the begining of image file. 194 * Should be sector-aligned for HDD access optimization. */ 195 uint32_t offData; 196 /** Legacy image geometry (previous code stored PCHS there). */ 197 VDIDISKGEOMETRY LegacyGeometry; 198 /** Was BIOS HDD translation mode, now unused. */ 199 uint32_t u32Dummy; 200 /** Size of disk (in bytes). */ 201 uint64_t cbDisk; 202 /** Block size. (For instance VDI_IMAGE_BLOCK_SIZE.) Should be a power of 2! */ 203 uint32_t cbBlock; 204 /** Size of additional service information of every data block. 205 * Prepended before block data. May be 0. 206 * Should be a power of 2 and sector-aligned for optimization reasons. */ 207 uint32_t cbBlockExtra; 208 /** Number of blocks. */ 209 uint32_t cBlocks; 210 /** Number of allocated blocks. */ 211 uint32_t cBlocksAllocated; 212 /** UUID of image. */ 213 RTUUID uuidCreate; 214 /** UUID of image's last modification. */ 215 RTUUID uuidModify; 216 /** Only for secondary images - UUID of previous image. */ 217 RTUUID uuidLinkage; 218 /** Only for secondary images - UUID of previous image's last modification. */ 219 RTUUID uuidParentModify; 220 /** LCHS image geometry (new field in VDI1.2 version. */ 221 VDIDISKGEOMETRY LCHSGeometry; 222 } VDIHEADER1PLUS, *PVDIHEADER1PLUS; 223 #pragma pack() 224 225 /** 175 226 * Header structure for all versions. 176 227 */ … … 182 233 VDIHEADER0 v0; 183 234 VDIHEADER1 v1; 235 VDIHEADER1PLUS v1plus; 184 236 } u; 185 237 } VDIHEADER, *PVDIHEADER; … … 276 328 switch (GET_MAJOR_HEADER_VERSION(ph)) 277 329 { 278 case 0: return &ph->u.v0.LCHSGeometry; 279 case 1: return &ph->u.v1.LCHSGeometry; 330 case 0: return NULL; 331 case 1: 332 switch (GET_MINOR_HEADER_VERSION(ph)) 333 { 334 case 1: 335 if (ph->u.v1.cbHeader < sizeof(ph->u.v1plus)) 336 return NULL; 337 else 338 return &ph->u.v1plus.LCHSGeometry; 339 } 280 340 } 281 341 AssertFailed();
Note:
See TracChangeset
for help on using the changeset viewer.