- Timestamp:
- Apr 13, 2012 7:38:21 PM (13 years ago)
- Location:
- trunk/src/VBox/Storage
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Storage/VDI.cpp
r40739 r40906 32 32 33 33 #define VDI_IMAGE_DEFAULT_BLOCK_SIZE _1M 34 35 /** Macros for endianess conversion. */ 36 #define SET_ENDIAN_U32(conv, u32) (conv == VDIECONV_H2F ? RT_H2LE_U32(u32) : RT_LE2H_U32(u32)) 37 #define SET_ENDIAN_U64(conv, u64) (conv == VDIECONV_H2F ? RT_H2LE_U64(u64) : RT_LE2H_U64(u64)) 34 38 35 39 /******************************************************************************* … … 62 66 63 67 /** 68 * Internal: Convert the PreHeader fields to the appropriate endianess. 69 * @param enmConv Direction of the conversion. 70 * @param pPreHdrConv Where to store the converted pre header. 71 * @param pPreHdr PreHeader pointer. 72 */ 73 static void vdiConvPreHeaderEndianess(VDIECONV enmConv, PVDIPREHEADER pPreHdrConv, 74 PVDIPREHEADER pPreHdr) 75 { 76 pPreHdrConv->u32Signature = SET_ENDIAN_U32(enmConv, pPreHdr->u32Signature); 77 pPreHdrConv->u32Version = SET_ENDIAN_U32(enmConv, pPreHdr->u32Version); 78 } 79 80 /** 81 * Internal: Convert the VDIDISKGEOMETRY fields to the appropriate endianess. 82 * @param enmConv Direction of the conversion. 83 * @param pDiskGeoConv Where to store the converted geometry. 84 * @param pDiskGeo Pointer to the disk geometry to convert. 85 */ 86 static void vdiConvGeometryEndianess(VDIECONV enmConv, PVDIDISKGEOMETRY pDiskGeoConv, 87 PVDIDISKGEOMETRY pDiskGeo) 88 { 89 pDiskGeoConv->cCylinders = SET_ENDIAN_U32(enmConv, pDiskGeo->cCylinders); 90 pDiskGeoConv->cHeads = SET_ENDIAN_U32(enmConv, pDiskGeo->cHeads); 91 pDiskGeoConv->cSectors = SET_ENDIAN_U32(enmConv, pDiskGeo->cSectors); 92 pDiskGeoConv->cbSector = SET_ENDIAN_U32(enmConv, pDiskGeo->cbSector); 93 } 94 95 /** 96 * Internal: Convert the Header - version 0 fields to the appropriate endianess. 97 * @param enmConv Direction of the conversion. 98 * @param pHdrConv Where to store the converted header. 99 * @param pHdr Pointer to the version 0 header. 100 */ 101 static void vdiConvHeaderEndianessV0(VDIECONV enmConv, PVDIHEADER0 pHdrConv, 102 PVDIHEADER0 pHdr) 103 { 104 pHdrConv->u32Type = SET_ENDIAN_U32(enmConv, pHdr->u32Type); 105 pHdrConv->fFlags = SET_ENDIAN_U32(enmConv, pHdr->fFlags); 106 vdiConvGeometryEndianess(enmConv, &pHdrConv->LegacyGeometry, &pHdr->LegacyGeometry); 107 pHdrConv->cbDisk = SET_ENDIAN_U64(enmConv, pHdr->cbDisk); 108 pHdrConv->cbBlock = SET_ENDIAN_U32(enmConv, pHdr->cbBlock); 109 pHdrConv->cBlocks = SET_ENDIAN_U32(enmConv, pHdr->cBlocks); 110 pHdrConv->cBlocksAllocated = SET_ENDIAN_U32(enmConv, pHdr->cBlocksAllocated); 111 /* Don't touch the RTUUID fields. */ 112 } 113 114 /** 115 * Internal: Set the Header - version 1 fields to the appropriate endianess. 116 * @param enmConv Direction of the conversion. 117 * @param pHdrConv Where to store the converted header. 118 * @param pHdr Version 1 Header pointer. 119 */ 120 static void vdiConvHeaderEndianessV1(VDIECONV enmConv, PVDIHEADER1 pHdrConv, 121 PVDIHEADER1 pHdr) 122 { 123 pHdrConv->cbHeader = SET_ENDIAN_U32(enmConv, pHdr->cbHeader); 124 pHdrConv->u32Type = SET_ENDIAN_U32(enmConv, pHdr->u32Type); 125 pHdrConv->fFlags = SET_ENDIAN_U32(enmConv, pHdr->fFlags); 126 pHdrConv->offBlocks = SET_ENDIAN_U32(enmConv, pHdr->offBlocks); 127 pHdrConv->offData = SET_ENDIAN_U32(enmConv, pHdr->offData); 128 vdiConvGeometryEndianess(enmConv, &pHdrConv->LegacyGeometry, &pHdr->LegacyGeometry); 129 pHdrConv->u32Dummy = SET_ENDIAN_U32(enmConv, pHdr->u32Dummy); 130 pHdrConv->cbDisk = SET_ENDIAN_U64(enmConv, pHdr->cbDisk); 131 pHdrConv->cbBlock = SET_ENDIAN_U32(enmConv, pHdr->cbBlock); 132 pHdrConv->cbBlockExtra = SET_ENDIAN_U32(enmConv, pHdr->cbBlockExtra); 133 pHdrConv->cBlocks = SET_ENDIAN_U32(enmConv, pHdr->cBlocks); 134 pHdrConv->cBlocksAllocated = SET_ENDIAN_U32(enmConv, pHdr->cBlocksAllocated); 135 /* don't touch the RTUUID */ 136 } 137 138 /** 139 * Internal: Set the Header - version 1plus fields to the appropriate endianess. 140 * @param enmConv Direction of the conversion. 141 * @param pHdrConv Where to store the converted header. 142 * @param pHdr Version 1+ Header pointer. 143 */ 144 static void vdiConvHeaderEndianessV1p(VDIECONV enmConv, PVDIHEADER1PLUS pHdrConv, 145 PVDIHEADER1PLUS pHdr) 146 { 147 pHdrConv->cbHeader = SET_ENDIAN_U32(enmConv, pHdr->cbHeader); 148 pHdrConv->u32Type = SET_ENDIAN_U32(enmConv, pHdr->u32Type); 149 pHdrConv->fFlags = SET_ENDIAN_U32(enmConv, pHdr->fFlags); 150 pHdrConv->offBlocks = SET_ENDIAN_U32(enmConv, pHdr->offBlocks); 151 pHdrConv->offData = SET_ENDIAN_U32(enmConv, pHdr->offData); 152 vdiConvGeometryEndianess(enmConv, &pHdrConv->LegacyGeometry, &pHdr->LegacyGeometry); 153 pHdrConv->u32Dummy = SET_ENDIAN_U32(enmConv, pHdr->u32Dummy); 154 pHdrConv->cbDisk = SET_ENDIAN_U64(enmConv, pHdr->cbDisk); 155 pHdrConv->cbBlock = SET_ENDIAN_U32(enmConv, pHdr->cbBlock); 156 pHdrConv->cbBlockExtra = SET_ENDIAN_U32(enmConv, pHdr->cbBlockExtra); 157 pHdrConv->cBlocks = SET_ENDIAN_U32(enmConv, pHdr->cBlocks); 158 pHdrConv->cBlocksAllocated = SET_ENDIAN_U32(enmConv, pHdr->cBlocksAllocated); 159 /* don't touch the RTUUID */ 160 vdiConvGeometryEndianess(enmConv, &pHdrConv->LCHSGeometry, &pHdr->LCHSGeometry); 161 } 162 163 /** 164 * Internal: Set the appropriate endianess on all the Blocks pointed. 165 * @param enmConv Direction of the conversion. 166 * @param paBlocks Pointer to the block array. 167 * @param cEntries Number of entries in the block array. 168 * 169 * @note Unlike the other conversion functions this method does an in place conversion 170 * to avoid temporary memory allocations when writing the block array. 171 */ 172 static void vdiConvBlocksEndianess(VDIECONV enmConv, PVDIIMAGEBLOCKPOINTER paBlocks, 173 unsigned cEntries) 174 { 175 for (unsigned i = 0; i < cEntries; i++) 176 paBlocks[i] = SET_ENDIAN_U32(enmConv, paBlocks[i]); 177 } 178 179 /** 64 180 * Internal: Flush the image file to disk. 65 181 */ … … 509 625 510 626 /* Write pre-header. */ 627 VDIPREHEADER PreHeader; 628 vdiConvPreHeaderEndianess(VDIECONV_H2F, &PreHeader, &pImage->PreHeader); 511 629 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, 0, 512 & pImage->PreHeader, sizeof(pImage->PreHeader), NULL);630 &PreHeader, sizeof(PreHeader), NULL); 513 631 if (RT_FAILURE(rc)) 514 632 { … … 519 637 520 638 /* Write header. */ 639 VDIHEADER1PLUS Hdr; 640 vdiConvHeaderEndianessV1p(VDIECONV_H2F, &Hdr, &pImage->Header.u.v1plus); 521 641 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, sizeof(pImage->PreHeader), 522 & pImage->Header.u.v1plus, sizeof(pImage->Header.u.v1plus), NULL);642 &Hdr, sizeof(Hdr), NULL); 523 643 if (RT_FAILURE(rc)) 524 644 { … … 528 648 } 529 649 650 vdiConvBlocksEndianess(VDIECONV_H2F, pImage->paBlocks, getImageBlocks(&pImage->Header)); 530 651 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, pImage->offStartBlocks, pImage->paBlocks, 531 652 getImageBlocks(&pImage->Header) * sizeof(VDIIMAGEBLOCKPOINTER), 532 653 NULL); 654 vdiConvBlocksEndianess(VDIECONV_F2H, pImage->paBlocks, getImageBlocks(&pImage->Header)); 533 655 if (RT_FAILURE(rc)) 534 656 { … … 631 753 632 754 /* Read pre-header. */ 755 VDIPREHEADER PreHeader; 633 756 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, 0, 634 & pImage->PreHeader, sizeof(pImage->PreHeader), NULL);757 &PreHeader, sizeof(PreHeader), NULL); 635 758 if (RT_FAILURE(rc)) 636 759 { … … 639 762 goto out; 640 763 } 764 vdiConvPreHeaderEndianess(VDIECONV_F2H, &pImage->PreHeader, &PreHeader); 641 765 rc = vdiValidatePreHeader(&pImage->PreHeader); 642 766 if (RT_FAILURE(rc)) … … 659 783 goto out; 660 784 } 785 vdiConvHeaderEndianessV0(VDIECONV_F2H, &pImage->Header.u.v0, &pImage->Header.u.v0); 661 786 break; 662 787 case 1: … … 669 794 goto out; 670 795 } 796 vdiConvHeaderEndianessV1(VDIECONV_F2H, &pImage->Header.u.v1, &pImage->Header.u.v1); 671 797 /* Convert VDI 1.1 images to VDI 1.1+ on open in read/write mode. 672 798 * Conversion is harmless, as any VirtualBox version supporting VDI … … 694 820 goto out; 695 821 } 822 vdiConvHeaderEndianessV1p(VDIECONV_F2H, &pImage->Header.u.v1plus, &pImage->Header.u.v1plus); 696 823 } 697 824 break; … … 723 850 getImageBlocks(&pImage->Header) * sizeof(VDIIMAGEBLOCKPOINTER), 724 851 NULL); 852 if (RT_FAILURE(rc)) 853 { 854 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VDI: Error reading the block table in '%s'"), pImage->pszFilename); 855 goto out; 856 } 857 vdiConvBlocksEndianess(VDIECONV_F2H, pImage->paBlocks, getImageBlocks(&pImage->Header)); 725 858 726 859 if (uOpenFlags & VD_OPEN_FLAGS_DISCARD) … … 782 915 { 783 916 case 0: 917 { 918 VDIHEADER0 Hdr; 919 vdiConvHeaderEndianessV0(VDIECONV_H2F, &Hdr, &pImage->Header.u.v0); 784 920 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, sizeof(VDIPREHEADER), 785 &pImage->Header.u.v0, sizeof(pImage->Header.u.v0), 786 NULL); 921 &Hdr, sizeof(Hdr), NULL); 787 922 break; 923 } 788 924 case 1: 789 925 if (pImage->Header.u.v1plus.cbHeader < sizeof(pImage->Header.u.v1plus)) 926 { 927 VDIHEADER1 Hdr; 928 vdiConvHeaderEndianessV1(VDIECONV_H2F, &Hdr, &pImage->Header.u.v1); 790 929 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, sizeof(VDIPREHEADER), 791 & pImage->Header.u.v1, sizeof(pImage->Header.u.v1),792 NULL);930 &Hdr, sizeof(Hdr), NULL); 931 } 793 932 else 933 { 934 VDIHEADER1PLUS Hdr; 935 vdiConvHeaderEndianessV1p(VDIECONV_H2F, &Hdr, &pImage->Header.u.v1plus); 794 936 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, sizeof(VDIPREHEADER), 795 & pImage->Header.u.v1plus, sizeof(pImage->Header.u.v1plus),796 NULL);937 &Hdr, sizeof(Hdr), NULL); 938 } 797 939 break; 798 940 default: … … 813 955 { 814 956 case 0: 957 { 958 VDIHEADER0 Hdr; 959 vdiConvHeaderEndianessV0(VDIECONV_H2F, &Hdr, &pImage->Header.u.v0); 815 960 rc = vdIfIoIntFileWriteMetaAsync(pImage->pIfIo, pImage->pStorage, 816 sizeof(VDIPREHEADER), &pImage->Header.u.v0, 817 sizeof(pImage->Header.u.v0), 961 sizeof(VDIPREHEADER), &Hdr, sizeof(Hdr), 818 962 pIoCtx, NULL, NULL); 819 963 break; 964 } 820 965 case 1: 821 966 if (pImage->Header.u.v1plus.cbHeader < sizeof(pImage->Header.u.v1plus)) 967 { 968 VDIHEADER1 Hdr; 969 vdiConvHeaderEndianessV1(VDIECONV_H2F, &Hdr, &pImage->Header.u.v1); 822 970 rc = vdIfIoIntFileWriteMetaAsync(pImage->pIfIo, pImage->pStorage, 823 sizeof(VDIPREHEADER), &pImage->Header.u.v1, 824 sizeof(pImage->Header.u.v1), 971 sizeof(VDIPREHEADER), &Hdr, sizeof(Hdr), 825 972 pIoCtx, NULL, NULL); 973 } 826 974 else 975 { 976 VDIHEADER1PLUS Hdr; 977 vdiConvHeaderEndianessV1p(VDIECONV_H2F, &Hdr, &pImage->Header.u.v1plus); 827 978 rc = vdIfIoIntFileWriteMetaAsync(pImage->pIfIo, pImage->pStorage, 828 sizeof(VDIPREHEADER), &pImage->Header.u.v1plus, 829 sizeof(pImage->Header.u.v1plus), 979 sizeof(VDIPREHEADER), &Hdr, sizeof(Hdr), 830 980 pIoCtx, NULL, NULL); 981 } 831 982 break; 832 983 default: … … 849 1000 { 850 1001 /* write only one block pointer. */ 1002 VDIIMAGEBLOCKPOINTER ptrBlock = RT_H2LE_U32(pImage->paBlocks[uBlock]); 851 1003 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, 852 1004 pImage->offStartBlocks + uBlock * sizeof(VDIIMAGEBLOCKPOINTER), 853 &p Image->paBlocks[uBlock], sizeof(VDIIMAGEBLOCKPOINTER),1005 &ptrBlock, sizeof(VDIIMAGEBLOCKPOINTER), 854 1006 NULL); 855 1007 AssertMsgRC(rc, ("vdiUpdateBlockInfo failed to update block=%u, filename=\"%s\", rc=%Rrc\n", … … 874 1026 { 875 1027 /* write only one block pointer. */ 1028 VDIIMAGEBLOCKPOINTER ptrBlock = RT_H2LE_U32(pImage->paBlocks[uBlock]); 876 1029 rc = vdIfIoIntFileWriteMetaAsync(pImage->pIfIo, pImage->pStorage, 877 1030 pImage->offStartBlocks + uBlock * sizeof(VDIIMAGEBLOCKPOINTER), 878 &pImage->paBlocks[uBlock], 879 sizeof(VDIIMAGEBLOCKPOINTER), 1031 &ptrBlock, sizeof(VDIIMAGEBLOCKPOINTER), 880 1032 pIoCtx, NULL, NULL); 881 1033 AssertMsg(RT_SUCCESS(rc) || rc == VERR_VD_ASYNC_IO_IN_PROGRESS, … … 2880 3032 2881 3033 /* Write the block array before updating the rest. */ 3034 vdiConvBlocksEndianess(VDIECONV_H2F, pImage->paBlocks, cBlocksNew); 2882 3035 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, pImage->offStartBlocks, 2883 3036 pImage->paBlocks, cbBlockspaceNew, NULL); 3037 vdiConvBlocksEndianess(VDIECONV_F2H, pImage->paBlocks, cBlocksNew); 2884 3038 2885 3039 if (RT_SUCCESS(rc)) … … 3232 3386 break; 3233 3387 } 3388 vdiConvPreHeaderEndianess(VDIECONV_F2H, &PreHdr, &PreHdr); 3234 3389 rc = vdiValidatePreHeader(&PreHdr); 3235 3390 if (RT_FAILURE(rc)) … … 3241 3396 3242 3397 /* Read header. */ 3243 Hdr.uVersion = RT_H2LE_U32(PreHdr.u32Version);3398 Hdr.uVersion = PreHdr.u32Version; 3244 3399 switch (GET_MAJOR_HEADER_VERSION(&Hdr)) 3245 3400 { … … 3251 3406 rc = vdIfError(pIfError, rc, RT_SRC_POS, N_("VDI: error reading v0 header in '%s'"), 3252 3407 pszFilename); 3408 vdiConvHeaderEndianessV0(VDIECONV_F2H, &Hdr.u.v0, &Hdr.u.v0); 3253 3409 break; 3254 3410 case 1: … … 3260 3416 pszFilename); 3261 3417 } 3418 vdiConvHeaderEndianessV1(VDIECONV_F2H, &Hdr.u.v1, &Hdr.u.v1); 3262 3419 if (Hdr.u.v1.cbHeader >= sizeof(Hdr.u.v1plus)) 3263 3420 { … … 3269 3426 rc = vdIfError(pIfError, rc, RT_SRC_POS, N_("VDI: error reading v1.1+ header in '%s'"), 3270 3427 pszFilename); 3428 vdiConvHeaderEndianessV1p(VDIECONV_F2H, &Hdr.u.v1plus, &Hdr.u.v1plus); 3271 3429 } 3272 3430 break; … … 3317 3475 break; 3318 3476 } 3319 3320 for (uint32_t i = 0; i < getImageBlocks(&Hdr); i++) 3321 paBlocks[i] = RT_LE2H_U32(paBlocks[i]); 3477 vdiConvBlocksEndianess(VDIECONV_F2H, paBlocks, getImageBlocks(&Hdr)); 3322 3478 3323 3479 pu32BlockBitmap = (uint32_t *)RTMemAllocZ(RT_ALIGN_Z(getImageBlocks(&Hdr) / 8, 4)); … … 3362 3518 else if (!(fFlags & VD_REPAIR_DRY_RUN)) 3363 3519 { 3364 for (uint32_t i = 0; i < getImageBlocks(&Hdr); i++)3365 paBlocks[i] = RT_H2LE_U32(paBlocks[i]);3366 3367 3520 vdIfErrorMessage(pIfError, "Writing repaired block allocation table...\n"); 3368 3521 3522 vdiConvBlocksEndianess(VDIECONV_H2F, paBlocks, getImageBlocks(&Hdr)); 3369 3523 rc = vdIfIoIntFileWriteSync(pIfIo, pStorage, offStartBlocks, paBlocks, 3370 3524 getImageBlocks(&Hdr) * sizeof(VDIIMAGEBLOCKPOINTER), -
trunk/src/VBox/Storage/VDICore.h
r40713 r40906 605 605 } VDIASYNCBLOCKALLOC, *PVDIASYNCBLOCKALLOC; 606 606 607 /** 608 * Endianess conversion direction. 609 */ 610 typedef enum VDIECONV 611 { 612 /** Host to file endianess. */ 613 VDIECONV_H2F = 0, 614 /** File to host endianess. */ 615 VDIECONV_F2H 616 } VDIECONV; 617 607 618 #endif 608 619
Note:
See TracChangeset
for help on using the changeset viewer.