- Timestamp:
- May 21, 2007 3:14:37 PM (18 years ago)
- Location:
- trunk/src/VBox/Devices/Storage
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/VBoxHDD-new.cpp
r2728 r2742 309 309 void *pvTmp) 310 310 { 311 int rc ;311 int rc = VINF_SUCCESS; 312 312 313 313 /* Read the data that goes before the write to fill the block. */ … … 1591 1591 char *pszComment, unsigned cbComment) 1592 1592 { 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; 1594 1609 } 1595 1610 … … 1606 1621 const char *pszComment) 1607 1622 { 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; 1609 1637 } 1610 1638 -
trunk/src/VBox/Devices/Storage/VBoxHDD-newInternal.h
r2650 r2742 205 205 206 206 /** 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 /** 207 228 * Get UUID of a disk image. 208 229 * -
trunk/src/VBox/Devices/Storage/VmdkHDDCore.cpp
r2718 r2742 343 343 static int vmdkOpenImage(PVMDKIMAGE pImage, const char *pszFilename, unsigned uOpenFlags); 344 344 static int vmdkFlushImage(PVMDKIMAGE pImage); 345 static int vmdkSetImageComment(PVMDKIMAGE pImage, const char *pszComment); 345 346 static void vmdkFreeImage(PVMDKIMAGE pImage, bool fDelete); 346 347 … … 356 357 va_end(va); 357 358 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 */ 365 static 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 */ 374 static 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; 358 382 } 359 383 … … 656 680 if (uStart) 657 681 { 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 } 672 718 } 673 719 else 674 720 { 675 721 /* 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 } 676 727 size_t cbKey = strlen(pszKey); 677 728 size_t cbValue = strlen(pszValue); … … 723 774 } 724 775 776 static 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 791 static 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 725 804 static void vmdkDescExtRemoveDummy(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor) 726 805 { … … 821 900 } 822 901 823 static int vmdkDescDDBGet U32(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor,824 const char *pszKey, uint32_t *puValue)902 static int vmdkDescDDBGetStr(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor, 903 const char *pszKey, const char **ppszValue) 825 904 { 826 905 const char *pszValue; … … 832 911 if (VBOX_FAILURE(rc)) 833 912 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 917 static int vmdkDescDDBGetU32(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor, 918 const char *pszKey, uint32_t *puValue) 841 919 { 842 920 const char *pszValue; … … 848 926 if (VBOX_FAILURE(rc)) 849 927 return rc; 928 rc = RTStrToUInt32Ex(pszValueUnquoted, NULL, 10, puValue); 929 RTMemTmpFree(pszValueUnquoted); 930 return rc; 931 } 932 933 static 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; 850 944 rc = RTUuidFromStr(pUuid, pszValueUnquoted); 851 945 RTMemTmpFree(pszValueUnquoted); … … 853 947 } 854 948 855 int vmdkDescDDBSetStr(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor, const char *pszKey, const char *pszVal) 856 { 949 static int vmdkDescDDBSetStr(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor, const char *pszKey, const char *pszVal) 950 { 951 int rc; 857 952 char *pszValQuoted; 858 953 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; 862 962 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 968 static int vmdkDescDDBSetUuid(PVMDKIMAGE pImage, PVMDKDESCRIPTOR pDescriptor, const char *pszKey, PCRTUUID pUuid) 868 969 { 869 970 char *pszUuid; … … 1089 1190 return vmdkError(pImage, VERR_VDI_UNSUPPORTED_VERSION, RT_SRC_POS, N_("VMDK: unsupported format version in descriptor in '%s'"), pImage->pszFilename); 1090 1191 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 1091 1208 /* Count the number of extent config entries. */ 1092 1209 for (uLine = pImage->Descriptor.uFirstExtent, cExtents = 0; … … 1610 1727 return VINF_SUCCESS; 1611 1728 } 1729 1612 1730 static int vmdkCreateExtents(PVMDKIMAGE pImage, unsigned cExtents) 1613 1731 { … … 1667 1785 goto out; 1668 1786 } 1669 1670 /** @todo set up pImage->uImageFlags accordingly somewhere during open. */1671 1787 1672 1788 /* Handle the file according to its magic number. */ … … 1916 2032 { 1917 2033 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; 1918 2037 if (pRaw->fRawDisk) 1919 2038 { … … 1959 2078 1960 2079 pImage->enmImageType = enmType; 1961 rc = vmdkDesc SetStr(pImage, &pImage->Descriptor, pImage->Descriptor.uFirstDesc, "createType", "\"fullDevice\"");2080 rc = vmdkDescBaseSetStr(pImage, &pImage->Descriptor, "createType", "fullDevice"); 1962 2081 if (VBOX_FAILURE(rc)) 1963 2082 { … … 2192 2311 2193 2312 pImage->enmImageType = enmType; 2194 rc = vmdkDesc SetStr(pImage, &pImage->Descriptor, pImage->Descriptor.uFirstDesc, "createType", "\"partitionedDevice\"");2313 rc = vmdkDescBaseSetStr(pImage, &pImage->Descriptor, "createType", "partitionedDevice"); 2195 2314 if (VBOX_FAILURE(rc)) 2196 2315 { … … 2269 2388 2270 2389 pImage->enmImageType = enmType; 2271 rc = vmdkDesc SetStr(pImage, &pImage->Descriptor, pImage->Descriptor.uFirstDesc, "createType", "\"monolithicSparse\"");2390 rc = vmdkDescBaseSetStr(pImage, &pImage->Descriptor, "createType", "monolithicSparse"); 2272 2391 if (VBOX_FAILURE(rc)) 2273 2392 { … … 2350 2469 goto out; 2351 2470 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 2352 2478 rc = vmdkFlushImage(pImage); 2353 2479 … … 2356 2482 vmdkFreeImage(pImage, rc != VERR_ALREADY_EXISTS); 2357 2483 return rc; 2484 } 2485 2486 static 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; 2358 2504 } 2359 2505 … … 3157 3303 } 3158 3304 3305 static 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 3335 out: 3336 LogFlow(("%s: returned %Vrc comment='%s'\n", __FUNCTION__, rc, pszComment)); 3337 return rc; 3338 } 3339 3340 static 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 3355 out: 3356 LogFlow(("%s: returned %Vrc\n", __FUNCTION__, rc)); 3357 return rc; 3358 } 3359 3159 3360 static int vmdkGetUuid(void *pBackendData, PRTUUID pUuid) 3160 3361 { … … 3311 3512 /* pfnSetOpenFlags */ 3312 3513 vmdkSetOpenFlags, 3514 /* pfnGetComment */ 3515 vmdkGetComment, 3516 /* pfnSetComment */ 3517 vmdkSetComment, 3313 3518 /* pfnGetUuid */ 3314 3519 vmdkGetUuid, 3315 /* pfn GetUuid */3520 /* pfnSetUuid */ 3316 3521 vmdkSetUuid, 3317 3522 /* pfnGetModificationUuid */
Note:
See TracChangeset
for help on using the changeset viewer.