VirtualBox

Changeset 6363 in vbox


Ignore:
Timestamp:
Jan 16, 2008 3:40:29 PM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
27295
Message:

Fix compatibility issues with VDIs being used both by VBox version
before the big geometry code change and after.

Location:
trunk/src/VBox/Devices/Storage
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/VDICore.cpp

    r6291 r6363  
    112112        return VERR_VDI_INVALID_SIGNATURE;
    113113
    114     if (    pPreHdr->u32Version != VDI_IMAGE_VERSION
     114    if (    VDI_GET_VERSION_MAJOR(pPreHdr->u32Version) != VDI_IMAGE_VERSION_MAJOR
    115115        &&  pPreHdr->u32Version != 0x00000002)    /* old version. */
    116116        return VERR_VDI_UNSUPPORTED_VERSION;
     
    143143    }
    144144
    145     /* Mark the geometry not-calculated. */
    146     pHeader->u.v1.LCHSGeometry.cCylinders = 0;
    147     pHeader->u.v1.LCHSGeometry.cHeads = 0;
    148     pHeader->u.v1.LCHSGeometry.cSectors = 0;
    149     pHeader->u.v1.LCHSGeometry.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 */
    151151
    152152    pHeader->u.v1.cbDisk = cbDisk;
     
    167167    RTUuidClear(&pHeader->u.v1.uuidLinkage);
    168168    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;
    169175}
    170176
     
    246252    }
    247253
    248     if ((getImageLCHSGeometry(pHeader))->cbSector != VDI_GEOMETRY_SECTOR_SIZE)
     254    if (   getImageLCHSGeometry(pHeader)
     255        && (getImageLCHSGeometry(pHeader))->cbSector != VDI_GEOMETRY_SECTOR_SIZE)
    249256    {
    250257        LogRel(("VDI: wrong sector size (%d != %d)\n",
     
    355362    {
    356363        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)
    358365        {
    359366            /* Invalid parent image version. */
     
    451458
    452459        /* 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);
    454461        if (VBOX_FAILURE(rc))
    455462            goto l_create_failed;
     
    624631            break;
    625632        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            }
    627663            break;
    628664        default:
     
    753789                break;
    754790            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                }
    756803                break;
    757804            default:
     
    22662313                  0);
    22672314    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    }
    22692322    *getImageCreationUUID(&Header) = *getImageCreationUUID(&pImage->Header);
    22702323    *getImageModificationUUID(&Header) = *getImageModificationUUID(&pImage->Header);
     
    28662919    {
    28672920        int rc = VINF_SUCCESS;
     2921        VDIDISKGEOMETRY DummyGeo = { 0, 0, 0, VDI_GEOMETRY_SECTOR_SIZE };
    28682922        PVDIDISKGEOMETRY pGeometry = getImageLCHSGeometry(&pDisk->pBase->Header);
     2923        if (!pGeometry)
     2924            pGeometry = &DummyGeo;
     2925
    28692926        LogFlow(("%s: C/H/S = %u/%u/%u\n",
    28702927                 __FUNCTION__, pGeometry->cCylinders, pGeometry->cHeads, pGeometry->cSectors));
     
    29072964    if (pDisk->pBase)
    29082965    {
     2966        int rc = VINF_SUCCESS;
    29092967        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        }
    29172978        LogFlow(("%s: returns %Vrc\n", __FUNCTION__, rc));
    29182979        return rc;
     
    35823643                getImageDataOffset(&pImage->Header));
    35833644    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);
    35863648    RTLogPrintf("Header: uuidCreation={%Vuuid}\n", getImageCreationUUID(&pImage->Header));
    35873649    RTLogPrintf("Header: uuidModification={%Vuuid}\n", getImageModificationUUID(&pImage->Header));
  • trunk/src/VBox/Devices/Storage/VDICore.h

    r6291 r6363  
    105105    /** Image comment. (UTF-8) */
    106106    char            szComment[VDI_IMAGE_COMMENT_SIZE];
    107     /** Image geometry. */
    108     VDIDISKGEOMETRY LCHSGeometry;
     107    /** Legacy image geometry (previous code stored PCHS there). */
     108    VDIDISKGEOMETRY LegacyGeometry;
    109109    /** Size of disk (in bytes). */
    110110    uint64_t        cbDisk;
     
    125125
    126126/**
    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.
    129129 */
    130130#pragma pack(1)
     
    145145     * Should be sector-aligned for HDD access optimization. */
    146146    uint32_t        offData;
    147     /** Image geometry. */
    148     VDIDISKGEOMETRY LCHSGeometry;
     147    /** Legacy image geometry (previous code stored PCHS there). */
     148    VDIDISKGEOMETRY LegacyGeometry;
    149149    /** Was BIOS HDD translation mode, now unused. */
    150150    uint32_t        u32Dummy;
     
    173173
    174174/**
     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)
     180typedef 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/**
    175226 * Header structure for all versions.
    176227 */
     
    182233        VDIHEADER0    v0;
    183234        VDIHEADER1    v1;
     235        VDIHEADER1PLUS v1plus;
    184236    } u;
    185237} VDIHEADER, *PVDIHEADER;
     
    276328    switch (GET_MAJOR_HEADER_VERSION(ph))
    277329    {
    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            }
    280340    }
    281341    AssertFailed();
Note: See TracChangeset for help on using the changeset viewer.

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