VirtualBox

Changeset 41447 in vbox for trunk/src/VBox/Storage


Ignore:
Timestamp:
May 25, 2012 12:02:11 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
78181
Message:

Storage/VHDX: Work around data alignment issues by allocating memory for theheaders dynamically + fix uuid handling

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Storage/VHDX.cpp

    r41353 r41447  
    625625DECLINLINE(void) vhdxConvUuidEndianess(VHDXECONV enmConv, PRTUUID pUuidConv, PRTUUID pUuid)
    626626{
     627#if 1
     628    memcpy(pUuidConv, pUuid, sizeof(RTUUID));
     629#else
    627630    pUuidConv->Gen.u32TimeLow              = SET_ENDIAN_U32(pUuid->Gen.u32TimeLow);
    628631    pUuidConv->Gen.u16TimeMid              = SET_ENDIAN_U16(pUuid->Gen.u16TimeMid);
     
    632635    for (unsigned i = 0; i < RT_ELEMENTS(pUuidConv->Gen.au8Node); i++)
    633636        pUuidConv->Gen.au8Node[i] = pUuid->Gen.au8Node[i];
     637#endif
    634638}
    635639
     
    10311035static int vhdxFindAndLoadCurrentHeader(PVHDXIMAGE pImage)
    10321036{
    1033     VhdxHeader Hdr1, Hdr2;
     1037    PVhdxHeader pHdr1, pHdr2;
    10341038    uint32_t u32ChkSum = 0;
    10351039    uint32_t u32ChkSumSaved = 0;
     
    10451049     * sequence number and checksum fields in the header.
    10461050     */
    1047 
    1048     /* Read the first header. */
    1049     rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, VHDX_HEADER1_OFFSET,
    1050                                &Hdr1, sizeof(Hdr1), NULL);
    1051     if (RT_SUCCESS(rc))
     1051    pHdr1 = (PVhdxHeader)RTMemAllocZ(sizeof(VhdxHeader));
     1052    pHdr2 = (PVhdxHeader)RTMemAllocZ(sizeof(VhdxHeader));
     1053
     1054    if (pHdr1 && pHdr2)
    10521055    {
    1053         vhdxConvHeaderEndianess(VHDXECONV_F2H, &Hdr1, &Hdr1);
    1054 
    1055         /* Validate checksum. */
    1056         u32ChkSumSaved = Hdr1.u32Checksum;
    1057         Hdr1.u32Checksum = 0;
    1058         //u32ChkSum = RTCrc32C(&Hdr1, sizeof(Hdr1));
    1059 
    1060         if (   Hdr1.u32Signature == VHDX_HEADER_SIGNATURE
    1061             /*&& u32ChkSum == u32ChkSumSaved*/)
    1062             fHdr1Valid = true;
     1056        /* Read the first header. */
     1057        rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, VHDX_HEADER1_OFFSET,
     1058                                   pHdr1, sizeof(*pHdr1), NULL);
     1059        if (RT_SUCCESS(rc))
     1060        {
     1061            vhdxConvHeaderEndianess(VHDXECONV_F2H, pHdr1, pHdr1);
     1062
     1063            /* Validate checksum. */
     1064            u32ChkSumSaved = pHdr1->u32Checksum;
     1065            pHdr1->u32Checksum = 0;
     1066            //u32ChkSum = RTCrc32C(pHdr1, sizeof(*pHdr1));
     1067
     1068            if (   pHdr1->u32Signature == VHDX_HEADER_SIGNATURE
     1069                /*&& u32ChkSum == u32ChkSumSaved*/)
     1070                fHdr1Valid = true;
     1071        }
     1072
     1073        /* Try to read the second header in any case (even if reading the first failed). */
     1074        rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, VHDX_HEADER2_OFFSET,
     1075                                   pHdr2, sizeof(*pHdr2), NULL);
     1076        if (RT_SUCCESS(rc))
     1077        {
     1078            vhdxConvHeaderEndianess(VHDXECONV_F2H, pHdr2, pHdr2);
     1079
     1080            /* Validate checksum. */
     1081            u32ChkSumSaved = pHdr2->u32Checksum;
     1082            pHdr2->u32Checksum = 0;
     1083            //u32ChkSum = RTCrc32C(pHdr2, sizeof(*pHdr2));
     1084
     1085            if (   pHdr2->u32Signature == VHDX_HEADER_SIGNATURE
     1086                /*&& u32ChkSum == u32ChkSumSaved*/)
     1087                fHdr2Valid = true;
     1088        }
     1089
     1090        /* Determine the current header. */
     1091        if (fHdr1Valid != fHdr2Valid)
     1092        {
     1093            /* Only one header is valid - use it. */
     1094            rc = vhdxLoadHeader(pImage, fHdr1Valid ? pHdr1 : pHdr2);
     1095        }
     1096        else if (!fHdr1Valid && !fHdr2Valid)
     1097        {
     1098            /* Crap, both headers are corrupt, refuse to load the image. */
     1099            rc = vdIfError(pImage->pIfError, VERR_VD_GEN_INVALID_HEADER, RT_SRC_POS,
     1100                           "VHDX: Can not load the image because both headers are corrupt");
     1101        }
     1102        else
     1103        {
     1104            /* Both headers are valid. Use the sequence number to find the current one. */
     1105            if (pHdr1->u64SequenceNumber > pHdr2->u64SequenceNumber)
     1106                rc = vhdxLoadHeader(pImage, pHdr1);
     1107            else
     1108                rc = vhdxLoadHeader(pImage, pHdr2);
     1109        }
    10631110    }
    1064 
    1065     /* Try to read the second header in any case (even if reading the first failed). */
    1066     rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, VHDX_HEADER2_OFFSET,
    1067                                &Hdr2, sizeof(Hdr2), NULL);
    1068     if (RT_SUCCESS(rc))
    1069     {
    1070         vhdxConvHeaderEndianess(VHDXECONV_F2H, &Hdr2, &Hdr2);
    1071 
    1072         /* Validate checksum. */
    1073         u32ChkSumSaved = Hdr2.u32Checksum;
    1074         Hdr2.u32Checksum = 0;
    1075         //u32ChkSum = RTCrc32C(&Hdr2, sizeof(Hdr2));
    1076 
    1077         if (   Hdr2.u32Signature == VHDX_HEADER_SIGNATURE
    1078             /*&& u32ChkSum == u32ChkSumSaved*/)
    1079             fHdr2Valid = true;
    1080     }
    1081 
    1082     /* Determine the current header. */
    1083     if (fHdr1Valid != fHdr2Valid)
    1084     {
    1085         /* Only one header is valid - use it. */
    1086         rc = vhdxLoadHeader(pImage, fHdr1Valid ? &Hdr1 : &Hdr2);
    1087     }
    1088     else if (!fHdr1Valid && !fHdr2Valid)
    1089     {
    1090         /* Crap, both headers are corrupt, refuse to load the image. */
    1091         rc = vdIfError(pImage->pIfError, VERR_VD_GEN_INVALID_HEADER, RT_SRC_POS,
    1092                        "VHDX: Can not load the image because both headers are corrupt");
    1093     }
    1094     else
    1095     {
    1096         /* Both headers are valid. Use the sequence number to find the current one. */
    1097         if (Hdr1.u64SequenceNumber > Hdr2.u64SequenceNumber)
    1098             rc = vhdxLoadHeader(pImage, &Hdr1);
    1099         else
    1100             rc = vhdxLoadHeader(pImage, &Hdr2);
    1101     }
     1111    else
     1112        rc = vdIfError(pImage->pIfError, VERR_NO_MEMORY, RT_SRC_POS,
     1113                       "VHDX: Out of memory while allocating memory for the header");
     1114
     1115    if (pHdr1)
     1116        RTMemFree(pHdr1);
     1117    if (pHdr2)
     1118        RTMemFree(pHdr2);
    11021119
    11031120    LogFlowFunc(("returns rc=%Rrc\n", rc));
     
    23742391    if (pImage)
    23752392    {
    2376         vdIfErrorMessage(pImage->pIfError, "Header: Geometry PCHS=%u/%u/%u LCHS=%u/%u/%u cbSector=%llu\n",
     2393        vdIfErrorMessage(pImage->pIfError, "Header: Geometry PCHS=%u/%u/%u LCHS=%u/%u/%u cbSector=%zu\n",
    23772394                        pImage->PCHSGeometry.cCylinders, pImage->PCHSGeometry.cHeads, pImage->PCHSGeometry.cSectors,
    23782395                        pImage->LCHSGeometry.cCylinders, pImage->LCHSGeometry.cHeads, pImage->LCHSGeometry.cSectors,
    2379                         pImage->cbSize / 512);
     2396                        pImage->cbLogicalSector);
    23802397    }
    23812398}
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