VirtualBox

Changeset 2742 in vbox for trunk/src


Ignore:
Timestamp:
May 21, 2007 3:14:37 PM (18 years ago)
Author:
vboxsync
Message:

Implement determining image flags on open. Also partial implementation
of comment support. Don't put anything non-ASCII in there. Comment
support is untested.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/VBoxHDD-new.cpp

    r2728 r2742  
    309309                                 void *pvTmp)
    310310{
    311     int rc;
     311    int rc = VINF_SUCCESS;
    312312
    313313    /* Read the data that goes before the write to fill the block. */
     
    15911591                               char *pszComment, unsigned cbComment)
    15921592{
    1593     return VERR_NOT_IMPLEMENTED;
     1593    /* sanity check */
     1594    Assert(pDisk);
     1595    AssertMsg(pDisk->u32Signature == VBOXHDDDISK_SIGNATURE, ("u32Signature=%08x\n", pDisk->u32Signature));
     1596    Assert(pszComment);
     1597
     1598    PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
     1599    int rc;
     1600    if (pImage)
     1601        rc = pDisk->Backend->pfnGetComment(pImage->pvBackendData, pszComment,
     1602                                           cbComment);
     1603    else
     1604        rc = VERR_VDI_IMAGE_NOT_FOUND;
     1605
     1606    LogFlow(("%s: returns %Vrc, comment='%s' nImage=%u\n", __FUNCTION__,
     1607             rc, pszComment, nImage));
     1608    return rc;
    15941609}
    15951610
     
    16061621                               const char *pszComment)
    16071622{
    1608     return VERR_NOT_IMPLEMENTED;
     1623    /* sanity check */
     1624    Assert(pDisk);
     1625    AssertMsg(pDisk->u32Signature == VBOXHDDDISK_SIGNATURE, ("u32Signature=%08x\n", pDisk->u32Signature));
     1626    LogFlow(("%s: comment='%s' nImage=%u\n", __FUNCTION__, pszComment, nImage));
     1627
     1628    PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
     1629    int rc;
     1630    if (pImage)
     1631        rc = pDisk->Backend->pfnSetComment(pImage->pvBackendData, pszComment);
     1632    else
     1633        rc = VERR_VDI_IMAGE_NOT_FOUND;
     1634
     1635    LogFlow(("%s: returns %Vrc\n", __FUNCTION__, rc));
     1636    return rc;
    16091637}
    16101638
  • trunk/src/VBox/Devices/Storage/VBoxHDD-newInternal.h

    r2650 r2742  
    205205
    206206    /**
     207     * Get comment of a disk image.
     208     *
     209     * @returns VBox status code.
     210     * @param   pvBackendData   Opaque state data for this image.
     211     * @param   pszComment      Where to store the comment.
     212     * @param   cbComment       Size of the comment buffer.
     213     */
     214    DECLR3CALLBACKMEMBER(int, pfnGetComment, (void *pvBackendData, char *pszComment, size_t cbComment));
     215
     216    /**
     217     * Set comment of a disk image.
     218     *
     219     * @returns VBox status code.
     220     * @param   pvBackendData   Opaque state data for this image.
     221     * @param   pszComment      Where to get the comment from. NULL resets comment.
     222     *                          The comment is silently truncated if the image format
     223     *                          limit is exceeded.
     224     */
     225    DECLR3CALLBACKMEMBER(int, pfnSetComment, (void *pvBackendData, const char *pszComment));
     226
     227    /**
    207228     * Get UUID of a disk image.
    208229     *
  • trunk/src/VBox/Devices/Storage/VmdkHDDCore.cpp

    r2718 r2742  
    343343static int vmdkOpenImage(PVMDKIMAGE pImage, const char *pszFilename, unsigned uOpenFlags);
    344344static int vmdkFlushImage(PVMDKIMAGE pImage);
     345static int vmdkSetImageComment(PVMDKIMAGE pImage, const char *pszComment);
    345346static void vmdkFreeImage(PVMDKIMAGE pImage, bool fDelete);
    346347
     
    356357    va_end(va);
    357358    return rc;
     359}
     360
     361/**
     362 * Internal: truncate a string (at a UTF8 code point boundary) and encode the
     363 * critical non-ASCII characters.
     364 */
     365static char *vmdkEncodeString(const char *psz)
     366{
     367    /** @todo implement me. */
     368    return RTStrDup(psz);
     369}
     370
     371/**
     372 * Internal: decode a string and store it into the specified string.
     373 */
     374static int vmdkDecodeString(const char *pszEncoded, char *psz, size_t cb)
     375{
     376    /** @todo implement me. */
     377    if (!cb)
     378        return VINF_SUCCESS;
     379    strncpy(psz, pszEncoded, cb);
     380    psz[cb - 1] = '\0';
     381    return VINF_SUCCESS;
    358382}
    359383
     
    656680    if (uStart)
    657681    {
    658         /* Key already exists, replace existing value. */
    659         size_t cbOldVal = strlen(pszTmp);
    660         size_t cbNewVal = strlen(pszValue);
    661         ssize_t cbDiff = cbNewVal - cbOldVal;
    662         /* Check for buffer overflow. */
    663         if (    pDescriptor->aLines[pDescriptor->cLines]
    664             -   pDescriptor->aLines[0] > (ptrdiff_t)pDescriptor->cbDescAlloc - cbDiff)
    665             return vmdkError(pImage, VERR_BUFFER_OVERFLOW, RT_SRC_POS, N_("VMDK: descriptor too big in '%s'"), pImage->pszFilename);
    666 
    667         memmove(pszTmp + cbNewVal, pszTmp + cbOldVal,
    668                 pDescriptor->aLines[pDescriptor->cLines] - pszTmp - cbOldVal);
    669         memcpy(pszTmp, pszValue, cbNewVal + 1);
    670         for (unsigned i = uStart + 1; i <= pDescriptor->cLines; i++)
    671             pDescriptor->aLines[i] += cbDiff;
     682        if (pszValue)
     683        {
     684            /* Key already exists, replace existing value. */
     685            size_t cbOldVal = strlen(pszTmp);
     686            size_t cbNewVal = strlen(pszValue);
     687            ssize_t cbDiff = cbNewVal - cbOldVal;
     688            /* Check for buffer overflow. */
     689            if (    pDescriptor->aLines[pDescriptor->cLines]
     690                -   pDescriptor->aLines[0] > (ptrdiff_t)pDescriptor->cbDescAlloc - cbDiff)
     691                return vmdkError(pImage, VERR_BUFFER_OVERFLOW, RT_SRC_POS, N_("VMDK: descriptor too big in '%s'"), pImage->pszFilename);
     692
     693            memmove(pszTmp + cbNewVal, pszTmp + cbOldVal,
     694                    pDescriptor->aLines[pDescriptor->cLines] - pszTmp - cbOldVal);
     695            memcpy(pszTmp, pszValue, cbNewVal + 1);
     696            for (unsigned i = uStart + 1; i <= pDescriptor->cLines; i++)
     697                pDescriptor->aLines[i] += cbDiff;
     698        }
     699        else
     700        {
     701            memmove(pDescriptor->aLines[uStart], pDescriptor->aLines[uStart+1],
     702                    pDescriptor->aLines[pDescriptor->cLines] - pDescriptor->aLines[uStart+1] + 1);
     703            for (unsigned i = uStart + 1; i <= pDescriptor->cLines; i++)
     704            {
     705                pDescriptor->aLines[i-1] = pDescriptor->aLines[i];
     706                if (pDescriptor->aNextLines[i])
     707                    pDescriptor->aNextLines[i-1] = pDescriptor->aNextLines[i] - 1;
     708                else
     709                    pDescriptor->aNextLines[i-1] = 0;
     710            }
     711            pDescriptor->cLines--;
     712            /* Adjust starting line numbers of following descriptor sections. */
     713            if (uStart < pDescriptor->uFirstExtent)
     714                pDescriptor->uFirstExtent--;
     715            if (uStart < pDescriptor->uFirstDDB)
     716                pDescriptor->uFirstDDB--;
     717        }
    672718    }
    673719    else
    674720    {
    675721        /* Key doesn't exist, append it after the last entry in this category. */
     722        if (!pszValue)
     723        {
     724            /* Key doesn't exist, and it should be removed. Simply a no-op. */
     725            return VINF_SUCCESS;
     726        }
    676727        size_t cbKey = strlen(pszKey);
    677728        size_t cbValue = strlen(pszValue);
     
    723774}
    724775
     776static int vmdkDescBaseGetStr(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor,
     777                              const char *pszKey, const char **ppszValue)
     778{
     779    const char *pszValue;
     780    char *pszValueUnquoted;
     781
     782    if (!vmdkDescGetStr(pDescriptor, pDescriptor->uFirstDesc, pszKey, &pszValue))
     783        return VERR_VDI_VALUE_NOT_FOUND;
     784    int rc = vmdkStringUnquote(pImage, pszValue, &pszValueUnquoted, NULL);
     785    if (VBOX_FAILURE(rc))
     786        return rc;
     787    *ppszValue = pszValueUnquoted;
     788    return rc;
     789}
     790
     791static int vmdkDescBaseSetStr(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor,
     792                              const char *pszKey, const char *pszValue)
     793{
     794    char *pszValueQuoted;
     795
     796    int rc = RTStrAPrintf(&pszValueQuoted, "\"%s\"", pszValue);
     797    if (VBOX_FAILURE(rc))
     798        return rc;
     799    rc = vmdkDescSetStr(pImage, pDescriptor, pDescriptor->uFirstDesc, pszKey, pszValueQuoted);
     800    RTStrFree(pszValueQuoted);
     801    return rc;
     802}
     803
    725804static void vmdkDescExtRemoveDummy(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor)
    726805{
     
    821900}
    822901
    823 static int vmdkDescDDBGetU32(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor,
    824                              const char *pszKey, uint32_t *puValue)
     902static int vmdkDescDDBGetStr(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor,
     903                             const char *pszKey, const char **ppszValue)
    825904{
    826905    const char *pszValue;
     
    832911    if (VBOX_FAILURE(rc))
    833912        return rc;
    834     rc = RTStrToUInt32Ex(pszValueUnquoted, NULL, 10, puValue);
    835     RTMemTmpFree(pszValueUnquoted);
    836     return rc;
    837 }
    838 
    839 static int vmdkDescDDBGetUuid(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor,
    840                               const char *pszKey, PRTUUID pUuid)
     913    *ppszValue = pszValueUnquoted;
     914    return rc;
     915}
     916
     917static int vmdkDescDDBGetU32(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor,
     918                             const char *pszKey, uint32_t *puValue)
    841919{
    842920    const char *pszValue;
     
    848926    if (VBOX_FAILURE(rc))
    849927        return rc;
     928    rc = RTStrToUInt32Ex(pszValueUnquoted, NULL, 10, puValue);
     929    RTMemTmpFree(pszValueUnquoted);
     930    return rc;
     931}
     932
     933static int vmdkDescDDBGetUuid(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor,
     934                              const char *pszKey, PRTUUID pUuid)
     935{
     936    const char *pszValue;
     937    char *pszValueUnquoted;
     938
     939    if (!vmdkDescGetStr(pDescriptor, pDescriptor->uFirstDDB, pszKey, &pszValue))
     940        return VERR_VDI_VALUE_NOT_FOUND;
     941    int rc = vmdkStringUnquote(pImage, pszValue, &pszValueUnquoted, NULL);
     942    if (VBOX_FAILURE(rc))
     943        return rc;
    850944    rc = RTUuidFromStr(pUuid, pszValueUnquoted);
    851945    RTMemTmpFree(pszValueUnquoted);
     
    853947}
    854948
    855 int vmdkDescDDBSetStr(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor, const char *pszKey, const char *pszVal)
    856 {
     949static int vmdkDescDDBSetStr(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor, const char *pszKey, const char *pszVal)
     950{
     951    int rc;
    857952    char *pszValQuoted;
    858953
    859     int rc = RTStrAPrintf(&pszValQuoted, "\"%s\"", pszVal);
    860     if (VBOX_FAILURE(rc))
    861         return rc;
     954    if (pszVal)
     955    {
     956        rc = RTStrAPrintf(&pszValQuoted, "\"%s\"", pszVal);
     957        if (VBOX_FAILURE(rc))
     958            return rc;
     959    }
     960    else
     961        pszValQuoted = NULL;
    862962    rc = vmdkDescSetStr(pImage, pDescriptor, pDescriptor->uFirstDDB, pszKey, pszValQuoted);
    863     RTStrFree(pszValQuoted);
    864     return rc;
    865 }
    866 
    867 int vmdkDescDDBSetUuid(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor, const char *pszKey, PCRTUUID pUuid)
     963    if (pszValQuoted)
     964        RTStrFree(pszValQuoted);
     965    return rc;
     966}
     967
     968static int vmdkDescDDBSetUuid(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor, const char *pszKey, PCRTUUID pUuid)
    868969{
    869970    char *pszUuid;
     
    10891190        return vmdkError(pImage, VERR_VDI_UNSUPPORTED_VERSION, RT_SRC_POS, N_("VMDK: unsupported format version in descriptor in '%s'"), pImage->pszFilename);
    10901191
     1192    /* Get image creation type and determine image flags. */
     1193    const char *pszCreateType;
     1194    rc = vmdkDescBaseGetStr(pImage, &pImage->Descriptor, "createType",
     1195                            &pszCreateType);
     1196    if (VBOX_FAILURE(rc))
     1197        return vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: cannot get image type from descriptor in '%s'"), pImage->pszFilename);
     1198    if (    !strcmp(pszCreateType, "twoGbMaxExtentSparse")
     1199        ||  !strcmp(pszCreateType, "twoGbMaxExtentFlat"))
     1200        pImage->uImageFlags = VD_VMDK_IMAGE_FLAGS_SPLIT_2G;
     1201    if (    !strcmp(pszCreateType, "partitionedDevice")
     1202        ||  !strcmp(pszCreateType, "fullDevice"))
     1203        pImage->uImageFlags = VD_VMDK_IMAGE_FLAGS_RAWDISK;
     1204    else
     1205        pImage->uImageFlags = 0;
     1206    RTStrFree((char *)(void *)pszCreateType);
     1207
    10911208    /* Count the number of extent config entries. */
    10921209    for (uLine = pImage->Descriptor.uFirstExtent, cExtents = 0;
     
    16101727    return VINF_SUCCESS;
    16111728}
     1729
    16121730static int vmdkCreateExtents(PVMDKIMAGE pImage, unsigned cExtents)
    16131731{
     
    16671785        goto out;
    16681786    }
    1669 
    1670     /** @todo set up pImage->uImageFlags accordingly somewhere during open. */
    16711787
    16721788    /* Handle the file according to its magic number. */
     
    19162032        {
    19172033            PVBOXHDDRAW pRaw = (PVBOXHDDRAW)(void *)pszComment;
     2034            /* As the comment is misused, zap it so that no garbage comment
     2035             * is set below. */
     2036            pszComment = NULL;
    19182037            if (pRaw->fRawDisk)
    19192038            {
     
    19592078
    19602079                pImage->enmImageType = enmType;
    1961                 rc = vmdkDescSetStr(pImage, &pImage->Descriptor, pImage->Descriptor.uFirstDesc, "createType", "\"fullDevice\"");
     2080                rc = vmdkDescBaseSetStr(pImage, &pImage->Descriptor, "createType", "fullDevice");
    19622081                if (VBOX_FAILURE(rc))
    19632082                {
     
    21922311
    21932312                pImage->enmImageType = enmType;
    2194                 rc = vmdkDescSetStr(pImage, &pImage->Descriptor, pImage->Descriptor.uFirstDesc, "createType", "\"partitionedDevice\"");
     2313                rc = vmdkDescBaseSetStr(pImage, &pImage->Descriptor, "createType", "partitionedDevice");
    21952314                if (VBOX_FAILURE(rc))
    21962315                {
     
    22692388
    22702389        pImage->enmImageType = enmType;
    2271         rc = vmdkDescSetStr(pImage, &pImage->Descriptor, pImage->Descriptor.uFirstDesc, "createType", "\"monolithicSparse\"");
     2390        rc = vmdkDescBaseSetStr(pImage, &pImage->Descriptor, "createType", "monolithicSparse");
    22722391        if (VBOX_FAILURE(rc))
    22732392        {
     
    23502469        goto out;
    23512470
     2471    rc = vmdkSetImageComment(pImage, pszComment);
     2472    if (VBOX_FAILURE(rc))
     2473    {
     2474        rc = vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: cannot set image comment in '%s'"), pszFilename);
     2475        goto out;
     2476    }
     2477
    23522478    rc = vmdkFlushImage(pImage);
    23532479
     
    23562482        vmdkFreeImage(pImage, rc != VERR_ALREADY_EXISTS);
    23572483    return rc;
     2484}
     2485
     2486static int vmdkSetImageComment(PVMDKIMAGE pImage, const char *pszComment)
     2487{
     2488    char *pszCommentEncoded;
     2489    if (pszComment)
     2490    {
     2491        pszCommentEncoded = vmdkEncodeString(pszComment);
     2492        if (!pszCommentEncoded)
     2493            return VERR_NO_MEMORY;
     2494    }
     2495    else
     2496        pszCommentEncoded = NULL;
     2497    int rc = vmdkDescDDBSetStr(pImage, &pImage->Descriptor,
     2498                          "ddb.comment", pszCommentEncoded);
     2499    if (pszComment)
     2500        RTStrFree(pszCommentEncoded);
     2501    if (VBOX_FAILURE(rc))
     2502        return vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: error storing image comment in descriptor in '%s'"), pImage->pszFilename);
     2503    return VINF_SUCCESS;
    23582504}
    23592505
     
    31573303}
    31583304
     3305static int vmdkGetComment(void *pBackendData, char *pszComment, size_t cbComment)
     3306{
     3307    PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
     3308    int rc;
     3309
     3310    Assert(pImage);
     3311
     3312    if (pImage)
     3313    {
     3314        const char *pszCommentEncoded;
     3315        rc = vmdkDescDDBGetStr(pImage, &pImage->Descriptor,
     3316                              "ddb.comment", &pszCommentEncoded);
     3317        if (rc == VERR_VDI_VALUE_NOT_FOUND)
     3318            pszCommentEncoded = NULL;
     3319        else if (VBOX_FAILURE(rc))
     3320            goto out;
     3321
     3322        if (pszComment)
     3323            rc = vmdkDecodeString(pszCommentEncoded, pszComment, cbComment);
     3324        else
     3325        {
     3326            *pszComment = '\0';
     3327            rc = VINF_SUCCESS;
     3328        }
     3329        if (pszCommentEncoded)
     3330            RTStrFree((char *)(void *)pszCommentEncoded);
     3331    }
     3332    else
     3333        rc = VERR_VDI_NOT_OPENED;
     3334
     3335out:
     3336    LogFlow(("%s: returned %Vrc comment='%s'\n", __FUNCTION__, rc, pszComment));
     3337    return rc;
     3338}
     3339
     3340static int vmdkSetComment(void *pBackendData, const char *pszComment)
     3341{
     3342    PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
     3343    int rc;
     3344
     3345    LogFlow(("%s: comment '%s'\n", pszComment));
     3346    Assert(pImage);
     3347
     3348    if (pImage)
     3349    {
     3350        rc = vmdkSetImageComment(pImage, pszComment);
     3351    }
     3352    else
     3353        rc = VERR_VDI_NOT_OPENED;
     3354
     3355out:
     3356    LogFlow(("%s: returned %Vrc\n", __FUNCTION__, rc));
     3357    return rc;
     3358}
     3359
    31593360static int vmdkGetUuid(void *pBackendData, PRTUUID pUuid)
    31603361{
     
    33113512    /* pfnSetOpenFlags */
    33123513    vmdkSetOpenFlags,
     3514    /* pfnGetComment */
     3515    vmdkGetComment,
     3516    /* pfnSetComment */
     3517    vmdkSetComment,
    33133518    /* pfnGetUuid */
    33143519    vmdkGetUuid,
    3315     /* pfnGetUuid */
     3520    /* pfnSetUuid */
    33163521    vmdkSetUuid,
    33173522    /* pfnGetModificationUuid */
Note: See TracChangeset for help on using the changeset viewer.

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