VirtualBox

Changeset 44671 in vbox


Ignore:
Timestamp:
Feb 13, 2013 4:38:47 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
83765
Message:

Storage/VHD: Fix incompatibility with Hyper-V. The WI2K and WI2R parent locators are deprecated and Hyper-V refuses to load images with such locators. Furthermore the DataSpace field holds the number of bytes and not sectors to store the parent locator path

File:
1 edited

Legend:

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

    r44528 r44671  
    305305
    306306    if (!pvBuf)
    307     {
    308         rc = VERR_NO_MEMORY;
    309         goto out;
    310     }
     307        return VERR_NO_MEMORY;
    311308
    312309    switch (RT_BE2H_U32(pLocator->u32Code))
    313310    {
    314311        case VHD_PLATFORM_CODE_WI2R:
    315             /* Update plain relative name. */
    316             cb = (uint32_t)strlen(pszFilename);
    317             if (cb > cbMaxLen)
    318             {
    319                 rc = VERR_FILENAME_TOO_LONG;
    320                 goto out;
    321             }
    322             memcpy(pvBuf, pszFilename, cb);
     312        {
     313            if (RTPathStartsWithRoot(pszFilename))
     314            {
     315                /* Convert to relative path. */
     316                char szPath[RTPATH_MAX];
     317                rc = RTPathCalcRelative(szPath, sizeof(szPath), pImage->pszFilename,
     318                                        pszFilename);
     319                if (RT_SUCCESS(rc))
     320                {
     321                    /* Update plain relative name. */
     322                    cb = (uint32_t)strlen(szPath);
     323                    if (cb > cbMaxLen)
     324                    {
     325                        rc = VERR_FILENAME_TOO_LONG;
     326                        break;
     327                    }
     328                    memcpy(pvBuf, szPath, cb);
     329                }
     330            }
     331            else
     332            {
     333                /* Update plain relative name. */
     334                cb = (uint32_t)strlen(pszFilename);
     335                if (cb > cbMaxLen)
     336                {
     337                    rc = VERR_FILENAME_TOO_LONG;
     338                    break;
     339                }
     340                memcpy(pvBuf, pszFilename, cb);
     341            }
    323342            pLocator->u32DataLength = RT_H2BE_U32(cb);
    324343            break;
     344        }
    325345        case VHD_PLATFORM_CODE_WI2K:
    326346            /* Update plain absolute name. */
    327347            rc = RTPathAbs(pszFilename, (char *)pvBuf, cbMaxLen);
    328             if (RT_FAILURE(rc))
    329                 goto out;
    330             pLocator->u32DataLength = RT_H2BE_U32((uint32_t)strlen((const char *)pvBuf));
     348            if (RT_SUCCESS(rc))
     349                pLocator->u32DataLength = RT_H2BE_U32((uint32_t)strlen((const char *)pvBuf));
    331350            break;
    332351        case VHD_PLATFORM_CODE_W2RU:
    333             /* Update unicode relative name. */
    334             rc = vhdFilenameToUtf16(pszFilename, (uint16_t *)pvBuf, cbMaxLen, &cb, false);
    335             if (RT_FAILURE(rc))
    336                 goto out;
    337             pLocator->u32DataLength = RT_H2BE_U32(cb);
     352            if (RTPathStartsWithRoot(pszFilename))
     353            {
     354                /* Convert to relative path. */
     355                char szPath[RTPATH_MAX];
     356                rc = RTPathCalcRelative(szPath, sizeof(szPath), pImage->pszFilename,
     357                                        pszFilename);
     358                if (RT_SUCCESS(rc))
     359                    rc = vhdFilenameToUtf16(szPath, (uint16_t *)pvBuf, cbMaxLen, &cb, false);
     360            }
     361            else
     362            {
     363                /* Update unicode relative name. */
     364                rc = vhdFilenameToUtf16(pszFilename, (uint16_t *)pvBuf, cbMaxLen, &cb, false);
     365            }
     366
     367            if (RT_SUCCESS(rc))
     368                pLocator->u32DataLength = RT_H2BE_U32(cb);
    338369            break;
    339370        case VHD_PLATFORM_CODE_W2KU:
     
    343374            {
    344375                rc = VERR_NO_MEMORY;
    345                 goto out;
     376                break;
    346377            }
    347378            rc = RTPathAbs(pszFilename, pszTmp, cbMaxLen);
     
    349380            {
    350381                RTMemTmpFree(pszTmp);
    351                 goto out;
     382                break;
    352383            }
    353384            rc = vhdFilenameToUtf16(pszTmp, (uint16_t *)pvBuf, cbMaxLen, &cb, false);
    354385            RTMemTmpFree(pszTmp);
    355             if (RT_FAILURE(rc))
    356                 goto out;
    357             pLocator->u32DataLength = RT_H2BE_U32(cb);
     386            if (RT_SUCCESS(rc))
     387                pLocator->u32DataLength = RT_H2BE_U32(cb);
    358388            break;
    359389        default:
    360390            rc = VERR_NOT_IMPLEMENTED;
    361             goto out;
    362     }
    363     rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage,
    364                                 RT_BE2H_U64(pLocator->u64DataOffset),
    365                                 pvBuf, RT_BE2H_U32(pLocator->u32DataSpace) * VHD_SECTOR_SIZE);
    366 
    367 out:
     391            break;
     392    }
     393
     394    if (RT_SUCCESS(rc))
     395        rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage,
     396                                    RT_BE2H_U64(pLocator->u64DataOffset),
     397                                    pvBuf, RT_BE2H_U32(pLocator->u32DataSpace) * VHD_SECTOR_SIZE);
     398
    368399    if (pvBuf)
    369400        RTMemTmpFree(pvBuf);
     
    956987{
    957988    PVHDPLE pLocator = pDDH->ParentLocatorEntry;
    958     /* Relative Windows path. */
    959     pLocator->u32Code = RT_H2BE_U32(VHD_PLATFORM_CODE_WI2R);
    960     pLocator->u32DataSpace = RT_H2BE_U32(VHD_RELATIVE_MAX_PATH / VHD_SECTOR_SIZE);
     989
     990    /*
     991     * The VHD spec states that the DataSpace field holds the number of sectors
     992     * required to store the parent locator path.
     993     * As it turned out VPC and Hyper-V store the amount of bytes reserved for the
     994     * path and not the number of sectors.
     995     */
     996
     997    /* Unicode absolute Windows path. */
     998    pLocator->u32Code = RT_H2BE_U32(VHD_PLATFORM_CODE_W2KU);
     999    pLocator->u32DataSpace = RT_H2BE_U32(VHD_ABSOLUTE_MAX_PATH * sizeof(RTUTF16));
    9611000    pLocator->u64DataOffset = RT_H2BE_U64(u64Offset);
    962     u64Offset += VHD_RELATIVE_MAX_PATH;
    9631001    pLocator++;
    964     /* Absolute Windows path. */
    965     pLocator->u32Code = RT_H2BE_U32(VHD_PLATFORM_CODE_WI2K);
    966     pLocator->u32DataSpace = RT_H2BE_U32(VHD_ABSOLUTE_MAX_PATH / VHD_SECTOR_SIZE);
    967     pLocator->u64DataOffset = RT_H2BE_U64(u64Offset);
    968     u64Offset += VHD_ABSOLUTE_MAX_PATH;
    969     pLocator++;
     1002    u64Offset += VHD_ABSOLUTE_MAX_PATH * sizeof(RTUTF16);
    9701003    /* Unicode relative Windows path. */
    9711004    pLocator->u32Code = RT_H2BE_U32(VHD_PLATFORM_CODE_W2RU);
    972     pLocator->u32DataSpace = RT_H2BE_U32(VHD_RELATIVE_MAX_PATH * sizeof(RTUTF16) / VHD_SECTOR_SIZE);
     1005    pLocator->u32DataSpace = RT_H2BE_U32(VHD_RELATIVE_MAX_PATH * sizeof(RTUTF16));
    9731006    pLocator->u64DataOffset = RT_H2BE_U64(u64Offset);
    9741007    u64Offset += VHD_RELATIVE_MAX_PATH * sizeof(RTUTF16);
    975     pLocator++;
    976     /* Unicode absolute Windows path. */
    977     pLocator->u32Code = RT_H2BE_U32(VHD_PLATFORM_CODE_W2KU);
    978     pLocator->u32DataSpace = RT_H2BE_U32(VHD_ABSOLUTE_MAX_PATH * sizeof(RTUTF16) / VHD_SECTOR_SIZE);
    979     pLocator->u64DataOffset = RT_H2BE_U64(u64Offset);
    980     return u64Offset + VHD_ABSOLUTE_MAX_PATH * sizeof(RTUTF16);
     1008    return u64Offset;
    9811009}
    9821010
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