Changeset 139 in vbox
- Timestamp:
- Jan 18, 2007 2:59:33 PM (18 years ago)
- svn:sync-xref-src-repo-rev:
- 17590
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/VBoxHDD.cpp
r124 r139 213 213 * Internal Functions for header access * 214 214 *******************************************************************************/ 215 static VDIIMAGETYPE getImageType(PVDIHEADER ph)215 static inline VDIIMAGETYPE getImageType(PVDIHEADER ph) 216 216 { 217 217 switch (GET_MAJOR_HEADER_VERSION(ph)) … … 224 224 } 225 225 226 static unsigned getImageFlags(PVDIHEADER ph)226 static inline unsigned getImageFlags(PVDIHEADER ph) 227 227 { 228 228 switch (GET_MAJOR_HEADER_VERSION(ph)) … … 235 235 } 236 236 237 static char *getImageComment(PVDIHEADER ph)237 static inline char *getImageComment(PVDIHEADER ph) 238 238 { 239 239 switch (GET_MAJOR_HEADER_VERSION(ph)) … … 246 246 } 247 247 248 static unsigned getImageBlocksOffset(PVDIHEADER ph)248 static inline unsigned getImageBlocksOffset(PVDIHEADER ph) 249 249 { 250 250 switch (GET_MAJOR_HEADER_VERSION(ph)) … … 257 257 } 258 258 259 static unsigned getImageDataOffset(PVDIHEADER ph)259 static inline unsigned getImageDataOffset(PVDIHEADER ph) 260 260 { 261 261 switch (GET_MAJOR_HEADER_VERSION(ph)) … … 269 269 } 270 270 271 static PVDIDISKGEOMETRY getImageGeometry(PVDIHEADER ph)271 static inline PVDIDISKGEOMETRY getImageGeometry(PVDIHEADER ph) 272 272 { 273 273 switch (GET_MAJOR_HEADER_VERSION(ph)) … … 280 280 } 281 281 282 static PDMBIOSTRANSLATION getImageTranslation(PVDIHEADER ph)282 static inline PDMBIOSTRANSLATION getImageTranslation(PVDIHEADER ph) 283 283 { 284 284 switch (GET_MAJOR_HEADER_VERSION(ph)) … … 291 291 } 292 292 293 static void setImageTranslation(PVDIHEADER ph, PDMBIOSTRANSLATION enmTranslation)293 static inline void setImageTranslation(PVDIHEADER ph, PDMBIOSTRANSLATION enmTranslation) 294 294 { 295 295 switch (GET_MAJOR_HEADER_VERSION(ph)) 296 296 { 297 case 0: 298 return; 299 case 1: 300 ph->u.v1.u32Translation = (uint32_t)enmTranslation; 301 return; 297 case 0: return; 298 case 1: ph->u.v1.u32Translation = (uint32_t)enmTranslation; return; 302 299 } 303 300 AssertFailed(); 304 301 } 305 302 306 static uint64_t getImageDiskSize(PVDIHEADER ph)303 static inline uint64_t getImageDiskSize(PVDIHEADER ph) 307 304 { 308 305 switch (GET_MAJOR_HEADER_VERSION(ph)) … … 315 312 } 316 313 317 static unsigned getImageBlockSize(PVDIHEADER ph)314 static inline unsigned getImageBlockSize(PVDIHEADER ph) 318 315 { 319 316 switch (GET_MAJOR_HEADER_VERSION(ph)) … … 326 323 } 327 324 328 static unsigned getImageExtraBlockSize(PVDIHEADER ph)325 static inline unsigned getImageExtraBlockSize(PVDIHEADER ph) 329 326 { 330 327 switch (GET_MAJOR_HEADER_VERSION(ph)) … … 337 334 } 338 335 339 static unsigned getImageBlocks(PVDIHEADER ph)336 static inline unsigned getImageBlocks(PVDIHEADER ph) 340 337 { 341 338 switch (GET_MAJOR_HEADER_VERSION(ph)) … … 348 345 } 349 346 350 static unsigned getImageBlocksAllocated(PVDIHEADER ph)347 static inline unsigned getImageBlocksAllocated(PVDIHEADER ph) 351 348 { 352 349 switch (GET_MAJOR_HEADER_VERSION(ph)) … … 359 356 } 360 357 361 static void setImageBlocksAllocated(PVDIHEADER ph, unsigned cBlocks)358 static inline void setImageBlocksAllocated(PVDIHEADER ph, unsigned cBlocks) 362 359 { 363 360 switch (GET_MAJOR_HEADER_VERSION(ph)) 364 361 { 365 case 0: 366 ph->u.v0.cBlocksAllocated = cBlocks; 367 return; 368 case 1: 369 ph->u.v1.cBlocksAllocated = cBlocks; 370 return; 362 case 0: ph->u.v0.cBlocksAllocated = cBlocks; return; 363 case 1: ph->u.v1.cBlocksAllocated = cBlocks; return; 371 364 } 372 365 AssertFailed(); 373 366 } 374 367 375 static PRTUUID getImageCreationUUID(PVDIHEADER ph)368 static inline PRTUUID getImageCreationUUID(PVDIHEADER ph) 376 369 { 377 370 switch (GET_MAJOR_HEADER_VERSION(ph)) … … 384 377 } 385 378 386 static PRTUUID getImageModificationUUID(PVDIHEADER ph)379 static inline PRTUUID getImageModificationUUID(PVDIHEADER ph) 387 380 { 388 381 switch (GET_MAJOR_HEADER_VERSION(ph)) … … 395 388 } 396 389 397 static PRTUUID getImageParentUUID(PVDIHEADER ph)390 static inline PRTUUID getImageParentUUID(PVDIHEADER ph) 398 391 { 399 392 switch (GET_MAJOR_HEADER_VERSION(ph)) … … 406 399 } 407 400 408 static PRTUUID getImageParentModificationUUID(PVDIHEADER ph)401 static inline PRTUUID getImageParentModificationUUID(PVDIHEADER ph) 409 402 { 410 403 switch (GET_MAJOR_HEADER_VERSION(ph)) … … 421 414 * Note: for speed reasons block size should be a power of 2 ! 422 415 */ 423 #define VDI_IMAGE_DEFAULT_BLOCK_SIZE (1 * 1024 * 1024)416 #define VDI_IMAGE_DEFAULT_BLOCK_SIZE _1M 424 417 425 418 /** 426 419 * fModified bit flags. 427 420 */ 428 #define VDI_IMAGE_MODIFIED_FLAG (0x01)429 #define VDI_IMAGE_MODIFIED_FIRST (0x02)430 #define VDI_IMAGE_MODIFIED_DISABLE_UUID_UPDATE (0x04)421 #define VDI_IMAGE_MODIFIED_FLAG BIT(0) 422 #define VDI_IMAGE_MODIFIED_FIRST BIT(1) 423 #define VDI_IMAGE_MODIFIED_DISABLE_UUID_UPDATE BIT(2) 431 424 432 425 /** … … 533 526 static unsigned getPowerOfTwo(unsigned uNumber); 534 527 static void vdiInitPreHeader(PVDIPREHEADER pPreHdr); 535 static int vdiValidatePreHeader(PVDIPREHEADER pPreHdr); 536 static void vdiInitHeader(PVDIHEADER pHeader, 537 VDIIMAGETYPE enmType, 538 uint32_t fFlags, 539 const char *pszComment, 540 uint64_t cbDisk, 541 uint32_t cbBlock, 528 static int vdiValidatePreHeader(PVDIPREHEADER pPreHdr); 529 static void vdiInitHeader(PVDIHEADER pHeader, VDIIMAGETYPE enmType, uint32_t fFlags, 530 const char *pszComment, uint64_t cbDisk, uint32_t cbBlock, 542 531 uint32_t cbBlockExtra); 543 static int vdiValidateHeader(PVDIHEADER pHeader); 544 static int vdiCreateImage(const char *pszFilename, 545 VDIIMAGETYPE enmType, 546 unsigned fFlags, 547 uint64_t cbSize, 548 const char *pszComment, 549 PVDIIMAGEDESC pParent, 532 static int vdiValidateHeader(PVDIHEADER pHeader); 533 static int vdiCreateImage(const char *pszFilename, VDIIMAGETYPE enmType, unsigned fFlags, 534 uint64_t cbSize, const char *pszComment, PVDIIMAGEDESC pParent, 550 535 PFNVMPROGRESS pfnProgress, void *pvUser); 551 536 static void vdiInitImageDesc(PVDIIMAGEDESC pImage); 552 537 static void vdiSetupImageDesc(PVDIIMAGEDESC pImage); 553 static int vdiOpenImage(PVDIIMAGEDESC *ppImage, 554 const char *pszFilename, 555 unsigned fOpen, 538 static int vdiOpenImage(PVDIIMAGEDESC *ppImage, const char *pszFilename, unsigned fOpen, 556 539 PVDIIMAGEDESC pParent); 557 static int vdiUpdateHeader(PVDIIMAGEDESC pImage);558 static int vdiUpdateBlockInfo(PVDIIMAGEDESC pImage, unsigned uBlock);559 static int vdiUpdateBlocks(PVDIIMAGEDESC pImage);540 static int vdiUpdateHeader(PVDIIMAGEDESC pImage); 541 static int vdiUpdateBlockInfo(PVDIIMAGEDESC pImage, unsigned uBlock); 542 static int vdiUpdateBlocks(PVDIIMAGEDESC pImage); 560 543 static void vdiSetModifiedFlag(PVDIIMAGEDESC pImage); 561 544 static void vdiResetModifiedFlag(PVDIIMAGEDESC pImage); … … 566 549 static void vdiFlushImage(PVDIIMAGEDESC pImage); 567 550 static void vdiCloseImage(PVDIIMAGEDESC pImage); 568 static int vdiReadInBlock(PVDIIMAGEDESC pImage, unsigned uBlock, unsigned offRead, unsigned cbToRead, void *pvBuf); 569 static int vdiFillBlockByZeroes(PVDIDISK pDisk, PVDIIMAGEDESC pImage, unsigned uBlock); 570 static int vdiWriteInBlock(PVDIDISK pDisk, PVDIIMAGEDESC pImage, unsigned uBlock, unsigned offWrite, unsigned cbToWrite, const void *pvBuf); 571 static int vdiCopyBlock(PVDIDISK pDisk, PVDIIMAGEDESC pImage, unsigned uBlock); 572 static int vdiMergeImages(PVDIIMAGEDESC pImageFrom, PVDIIMAGEDESC pImageTo, bool fParentToChild, 551 static int vdiReadInBlock(PVDIIMAGEDESC pImage, unsigned uBlock, unsigned offRead, 552 unsigned cbToRead, void *pvBuf); 553 static int vdiFillBlockByZeroes(PVDIDISK pDisk, PVDIIMAGEDESC pImage, unsigned uBlock); 554 static int vdiWriteInBlock(PVDIDISK pDisk, PVDIIMAGEDESC pImage, unsigned uBlock, 555 unsigned offWrite, unsigned cbToWrite, const void *pvBuf); 556 static int vdiCopyBlock(PVDIDISK pDisk, PVDIIMAGEDESC pImage, unsigned uBlock); 557 static int vdiMergeImages(PVDIIMAGEDESC pImageFrom, PVDIIMAGEDESC pImageTo, bool fParentToChild, 573 558 PFNVMPROGRESS pfnProgress, void *pvUser); 574 static int vdiCommitToImage(PVDIDISK pDisk, PVDIIMAGEDESC pDstImage,575 PFNVMPROGRESS pfnProgress, void *pvUser);576 559 static void vdiInitVDIDisk(PVDIDISK pDisk); 577 560 static void vdiAddImageToList(PVDIDISK pDisk, PVDIIMAGEDESC pImage); 578 561 static void vdiRemoveImageFromList(PVDIDISK pDisk, PVDIIMAGEDESC pImage); 579 562 static PVDIIMAGEDESC vdiGetImageByNumber(PVDIDISK pDisk, int nImage); 580 static int vdiChangeImageMode(PVDIIMAGEDESC pImage, bool fReadOnly); 581 static int vdiUpdateReadOnlyHeader(PVDIIMAGEDESC pImage); 563 static int vdiChangeImageMode(PVDIIMAGEDESC pImage, bool fReadOnly); 564 static int vdiUpdateReadOnlyHeader(PVDIIMAGEDESC pImage); 565 566 static int vdiCommitToImage(PVDIDISK pDisk, PVDIIMAGEDESC pDstImage, 567 PFNVMPROGRESS pfnProgress, void *pvUser); 582 568 static void vdiDumpImage(PVDIIMAGEDESC pImage); 583 569 584 static DECLCALLBACK(int) vdiConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle);570 static DECLCALLBACK(int) vdiConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle); 585 571 static DECLCALLBACK(void) vdiDestruct(PPDMDRVINS pDrvIns); 586 static DECLCALLBACK(int) vdiRead(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead); 587 static DECLCALLBACK(int) vdiWrite(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite); 588 static DECLCALLBACK(int) vdiFlush(PPDMIMEDIA pInterface); 572 static DECLCALLBACK(int) vdiRead(PPDMIMEDIA pInterface, 573 uint64_t off, void *pvBuf, size_t cbRead); 574 static DECLCALLBACK(int) vdiWrite(PPDMIMEDIA pInterface, 575 uint64_t off, const void *pvBuf, size_t cbWrite); 576 static DECLCALLBACK(int) vdiFlush(PPDMIMEDIA pInterface); 589 577 static DECLCALLBACK(uint64_t) vdiGetSize(PPDMIMEDIA pInterface); 590 static DECLCALLBACK(int) vdiBiosGetGeometry(PPDMIMEDIA pInterface, uint32_t *pcCylinders, uint32_t *pcHeads, uint32_t *pcSectors); 591 static DECLCALLBACK(int) vdiBiosSetGeometry(PPDMIMEDIA pInterface, uint32_t cCylinders, uint32_t cHeads, uint32_t cSectors); 592 static DECLCALLBACK(int) vdiGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid); 578 static DECLCALLBACK(int) vdiBiosGetGeometry(PPDMIMEDIA pInterface, uint32_t *pcCylinders, 579 uint32_t *pcHeads, uint32_t *pcSectors); 580 static DECLCALLBACK(int) vdiBiosSetGeometry(PPDMIMEDIA pInterface, uint32_t cCylinders, 581 uint32_t cHeads, uint32_t cSectors); 582 static DECLCALLBACK(int) vdiGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid); 593 583 static DECLCALLBACK(bool) vdiIsReadOnly(PPDMIMEDIA pInterface); 594 static DECLCALLBACK(int) vdiBiosGetTranslation(PPDMIMEDIA pInterface, PPDMBIOSTRANSLATION penmTranslation); 595 static DECLCALLBACK(int) vdiBiosSetTranslation(PPDMIMEDIA pInterface, PDMBIOSTRANSLATION enmTranslation); 584 static DECLCALLBACK(int) vdiBiosGetTranslation(PPDMIMEDIA pInterface, 585 PPDMBIOSTRANSLATION penmTranslation); 586 static DECLCALLBACK(int) vdiBiosSetTranslation(PPDMIMEDIA pInterface, 587 PDMBIOSTRANSLATION enmTranslation); 596 588 static DECLCALLBACK(void *) vdiQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface); 597 589 … … 643 635 * @param pHeader Assumes it was initially initialized to all zeros. 644 636 */ 645 static void vdiInitHeader(PVDIHEADER pHeader, 646 VDIIMAGETYPE enmType, 647 uint32_t fFlags, 648 const char *pszComment, 649 uint64_t cbDisk, 650 uint32_t cbBlock, 637 static void vdiInitHeader(PVDIHEADER pHeader, VDIIMAGETYPE enmType, uint32_t fFlags, 638 const char *pszComment, uint64_t cbDisk, uint32_t cbBlock, 651 639 uint32_t cbBlockExtra) 652 640 { … … 755 743 /* Check common header parameters. */ 756 744 745 bool failure = false; 746 757 747 if ( getImageType(pHeader) < VDI_IMAGE_TYPE_FIRST 758 748 || getImageType(pHeader) > VDI_IMAGE_TYPE_LAST) 759 return VERR_VDI_INVALID_TYPE; 749 { 750 LogRel(("VDI: bad image type %d\n", getImageType(pHeader))); 751 failure = true; 752 } 760 753 761 754 if (getImageFlags(pHeader) & ~VDI_IMAGE_FLAGS_MASK) 762 return VERR_VDI_INVALID_FLAGS; 755 { 756 LogRel(("VDI: bad image flags %08x\n", getImageFlags(pHeader))); 757 failure = true; 758 } 763 759 764 760 if ((getImageGeometry(pHeader))->cbSector != VDI_GEOMETRY_SECTOR_SIZE) 765 761 { 766 LogRel(("VDI: wrong sect ionsize (%d != %d)\n",762 LogRel(("VDI: wrong sector size (%d != %d)\n", 767 763 (getImageGeometry(pHeader))->cbSector, VDI_GEOMETRY_SECTOR_SIZE)); 768 return VERR_VDI_INVALID_HEADER;764 failure = true; 769 765 } 770 766 … … 777 773 getImageDiskSize(pHeader), getImageBlockSize(pHeader), 778 774 getImageBlocks(pHeader), getPowerOfTwo(getImageBlockSize(pHeader)))); 779 return VERR_VDI_INVALID_HEADER;775 failure = true; 780 776 } 781 777 … … 786 782 getImageBlocksAllocated(pHeader), getImageBlocks(pHeader), 787 783 getImageBlockSize(pHeader), getImageDiskSize(pHeader))); 788 return VERR_VDI_INVALID_HEADER;784 failure = true; 789 785 } 790 786 … … 794 790 LogRel(("VDI: wrong extra size (%d, %d)\n", 795 791 getImageExtraBlockSize(pHeader), getPowerOfTwo(getImageExtraBlockSize(pHeader)))); 796 return VERR_VDI_INVALID_HEADER;797 } 798 799 if ( 792 failure = true; 793 } 794 795 if ((uint64_t)getImageBlockSize(pHeader) * getImageBlocks(pHeader) < getImageDiskSize(pHeader)) 800 796 { 801 797 LogRel(("VDI: wrong disk size (%d, %d, %lld)\n", 802 getImageBlockSize(pHeader), 803 getImageBlocks(pHeader), 804 getImageDiskSize(pHeader))); 805 return VERR_VDI_INVALID_HEADER; 798 getImageBlockSize(pHeader), getImageBlocks(pHeader), getImageDiskSize(pHeader))); 799 failure = true; 806 800 } 807 801 … … 809 803 { 810 804 LogRel(("VDI: uuid of creator is 0\n")); 811 return VERR_VDI_INVALID_HEADER; 812 } 805 failure = true; 806 } 807 813 808 if (RTUuidIsNull(getImageModificationUUID(pHeader))) 814 809 { 815 810 LogRel(("VDI: uuid of modificator is 0\n")); 816 return VERR_VDI_INVALID_HEADER;817 } 818 819 return VINF_SUCCESS;811 failure = true; 812 } 813 814 return failure ? VERR_VDI_INVALID_HEADER : VINF_SUCCESS; 820 815 } 821 816 … … 836 831 static void vdiSetupImageDesc(PVDIIMAGEDESC pImage) 837 832 { 838 pImage->fFlags = getImageFlags(&pImage->Header); 839 pImage->offStartBlocks = getImageBlocksOffset(&pImage->Header); 840 pImage->offStartData = getImageDataOffset(&pImage->Header); 841 pImage->uBlockMask = getImageBlockSize(&pImage->Header) - 1; 842 pImage->uShiftIndex2Offset = pImage->uShiftOffset2Index = getPowerOfTwo(getImageBlockSize(&pImage->Header)); 843 pImage->offStartBlockData = getImageExtraBlockSize(&pImage->Header); 833 pImage->fFlags = getImageFlags(&pImage->Header); 834 pImage->offStartBlocks = getImageBlocksOffset(&pImage->Header); 835 pImage->offStartData = getImageDataOffset(&pImage->Header); 836 pImage->uBlockMask = getImageBlockSize(&pImage->Header) - 1; 837 pImage->uShiftIndex2Offset = 838 pImage->uShiftOffset2Index = getPowerOfTwo(getImageBlockSize(&pImage->Header)); 839 pImage->offStartBlockData = getImageExtraBlockSize(&pImage->Header); 844 840 if (pImage->offStartBlockData != 0) 845 841 pImage->uShiftIndex2Offset += getPowerOfTwo(pImage->offStartBlockData); … … 849 845 * internal: create image. 850 846 */ 851 static int vdiCreateImage(const char *pszFilename, 852 VDIIMAGETYPE enmType, 853 unsigned fFlags, 854 uint64_t cbSize, 855 const char *pszComment, 856 PVDIIMAGEDESC pParent, 847 static int vdiCreateImage(const char *pszFilename, VDIIMAGETYPE enmType, unsigned fFlags, 848 uint64_t cbSize, const char *pszComment, PVDIIMAGEDESC pParent, 857 849 PFNVMPROGRESS pfnProgress, void *pvUser) 858 850 { … … 1015 1007 if (pfnProgress) 1016 1008 { 1017 rc = pfnProgress(NULL /* Achtung! pVM=NULL */,1009 rc = pfnProgress(NULL /* WARNING! pVM=NULL */, 1018 1010 (unsigned)(((cbDisk - cbFill) * 100) / cbDisk), 1019 1011 pvUser); … … 1048 1040 if ( VBOX_SUCCESS(rc) 1049 1041 && pfnProgress) 1050 pfnProgress(NULL /* Achtung! pVM=NULL */, 100, pvUser);1042 pfnProgress(NULL /* WARNING! pVM=NULL */, 100, pvUser); 1051 1043 1052 1044 Log(("vdiCreateImage: done, filename=\"%s\", rc=%Vrc\n", pszFilename, rc)); … … 1059 1051 * @internal 1060 1052 */ 1061 static int vdiOpenImage(PVDIIMAGEDESC *ppImage, 1062 const char *pszFilename, 1063 unsigned fOpen, 1064 PVDIIMAGEDESC pParent) 1053 static int vdiOpenImage(PVDIIMAGEDESC *ppImage, const char *pszFilename, 1054 unsigned fOpen, PVDIIMAGEDESC pParent) 1065 1055 { 1066 1056 /* … … 1151 1141 if (VBOX_FAILURE(rc)) 1152 1142 goto l_open_failed; 1143 1153 1144 rc = vdiValidateHeader(&pImage->Header); 1154 1145 if (VBOX_FAILURE(rc)) … … 1181 1172 1182 1173 /* Check linkage data. */ 1183 if ( RTUuidCompare(getImageParentUUID(&pImage->Header), getImageCreationUUID(&pParent->Header)) 1184 || RTUuidCompare(getImageParentModificationUUID(&pImage->Header), getImageModificationUUID(&pParent->Header))) 1174 if ( RTUuidCompare(getImageParentUUID(&pImage->Header), 1175 getImageCreationUUID(&pParent->Header)) 1176 || RTUuidCompare(getImageParentModificationUUID(&pImage->Header), 1177 getImageModificationUUID(&pParent->Header))) 1185 1178 { 1186 1179 rc = VERR_VDI_IMAGES_UUID_MISMATCH; … … 1233 1226 if (VBOX_FAILURE(rc)) 1234 1227 goto l_open_failed; 1235 rc = RTFileRead(pImage->File, 1236 pImage->paBlocks, 1237 getImageBlocks(&pImage->Header) * sizeof(VDIIMAGEBLOCKPOINTER), 1238 NULL); 1228 rc = RTFileRead(pImage->File, pImage->paBlocks, 1229 getImageBlocks(&pImage->Header) * sizeof(VDIIMAGEBLOCKPOINTER), NULL); 1239 1230 if (VBOX_FAILURE(rc)) 1240 1231 goto l_open_failed; … … 1432 1423 * note: uBlock must be valid, readed data must not overlap block bounds. 1433 1424 */ 1434 static int vdiReadInBlock(PVDIIMAGEDESC pImage, unsigned uBlock, unsigned offRead, unsigned cbToRead, void *pvBuf) 1425 static int vdiReadInBlock(PVDIIMAGEDESC pImage, unsigned uBlock, unsigned offRead, 1426 unsigned cbToRead, void *pvBuf) 1435 1427 { 1436 1428 if (IS_VDI_IMAGE_BLOCK_ALLOCATED(pImage->paBlocks[uBlock])) … … 1610 1602 } 1611 1603 1604 unsigned cBlocksAllocated = getImageBlocksAllocated(&pImage->Header); 1605 pImage->paBlocks[uBlock] = cBlocksAllocated; 1606 setImageBlocksAllocated(&pImage->Header, cBlocksAllocated + 1); 1607 1612 1608 if ( pImage->fFlags & VDI_IMAGE_FLAGS_ZERO_EXPAND 1613 1609 || pImage->paBlocks[uBlock] == VDI_IMAGE_BLOCK_ZERO) 1614 1610 { 1615 1611 /* Fill newly allocated block by zeroes. */ 1616 unsigned cBlocksAllocated = getImageBlocksAllocated(&pImage->Header); 1617 pImage->paBlocks[uBlock] = cBlocksAllocated; 1618 setImageBlocksAllocated(&pImage->Header, cBlocksAllocated + 1); 1619 1620 if ( offWrite != 0 1621 || cbToWrite != getImageBlockSize(&pImage->Header)) 1612 1613 if (offWrite || cbToWrite != getImageBlockSize(&pImage->Header)) 1622 1614 { 1623 1615 rc = vdiFillBlockByZeroes(pDisk, pImage, uBlock); … … 1626 1618 } 1627 1619 } 1628 else 1629 { 1630 /* No need to fill block by zeroes. */ 1631 unsigned cBlocksAllocated = getImageBlocksAllocated(&pImage->Header); 1632 pImage->paBlocks[uBlock] = cBlocksAllocated; 1633 setImageBlocksAllocated(&pImage->Header, cBlocksAllocated + 1); 1634 } 1620 1635 1621 rc = vdiUpdateBlockInfo(pImage, uBlock); 1636 1622 if (VBOX_FAILURE(rc)) … … 1729 1715 1730 1716 /* Calculate starting block number and offset inside it. */ 1731 unsigned uBlock = (unsigned)(offStart >> pImage->uShiftOffset2Index); 1732 unsigned offWrite = (unsigned)offStart & pImage->uBlockMask; 1733 1734 /* Save block size here for speed optimization. */ 1735 unsigned cbBlock = getImageBlockSize(&pImage->Header); 1717 unsigned uBlock = (unsigned)(offStart >> pImage->uShiftOffset2Index); 1718 unsigned offWrite = (unsigned)offStart & pImage->uBlockMask; 1719 unsigned cbBlock = getImageBlockSize(&pImage->Header); 1736 1720 1737 1721 /* loop through blocks */ … … 1870 1854 if (pfnProgress) 1871 1855 { 1872 pfnProgress(NULL /* Achtung! pVM=NULL */,1856 pfnProgress(NULL /* WARNING! pVM=NULL */, 1873 1857 (uBlock * 100) / cBlocks, 1874 1858 pvUser); … … 1931 1915 if (pfnProgress) 1932 1916 { 1933 pfnProgress(NULL /* Achtung! pVM=NULL */,1917 pfnProgress(NULL /* WARNING! pVM=NULL */, 1934 1918 (uBlock * 100) / cBlocks, 1935 1919 pvUser); … … 1944 1928 1945 1929 /** 1930 * @note Only used by tstVDI. 1931 * 1946 1932 * internal: commit last image(s) to selected previous image. 1947 1933 * note: all images accessed across this call must be opened in R/W mode. … … 2032 2018 if (pfnProgress) 2033 2019 { 2034 pfnProgress(NULL /* Achtung! pVM=NULL */,2020 pfnProgress(NULL /* WARNING! pVM=NULL */, 2035 2021 (uBlock * 100) / cBlocks, 2036 2022 pvUser); … … 2083 2069 if (pfnProgress) 2084 2070 { 2085 pfnProgress(NULL /* Achtung! pVM=NULL*/, 100, pvUser);2071 pfnProgress(NULL /* WARNING! pVM=NULL */, 100, pvUser); 2086 2072 /* Note: commiting is non breakable operation, skipping rc here. */ 2087 2073 } … … 2105 2091 * @param cbComment The size of pszComment buffer. 0 is ok. 2106 2092 */ 2107 IDER3DECL(int) VDICheckImage(const char *pszFilename, 2108 unsigned *puVersion, 2109 PVDIIMAGETYPE penmType, 2110 uint64_t *pcbSize, 2111 PRTUUID pUuid, 2112 PRTUUID pParentUuid, 2113 char *pszComment, 2114 unsigned cbComment) 2093 IDER3DECL(int) VDICheckImage(const char *pszFilename, unsigned *puVersion, PVDIIMAGETYPE penmType, 2094 uint64_t *pcbSize, PRTUUID pUuid, PRTUUID pParentUuid, 2095 char *pszComment, unsigned cbComment) 2115 2096 { 2116 2097 LogFlow(("VDICheckImage:\n")); … … 2246 2227 * @param pvUser User argument for the progress callback. 2247 2228 */ 2248 IDER3DECL(int) VDICreateBaseImage(const char *pszFilename, VDIIMAGETYPE enmType, uint64_t cbSize, const char *pszComment,2249 PFNVMPROGRESS pfnProgress, void *pvUser)2229 IDER3DECL(int) VDICreateBaseImage(const char *pszFilename, VDIIMAGETYPE enmType, uint64_t cbSize, 2230 const char *pszComment, PFNVMPROGRESS pfnProgress, void *pvUser) 2250 2231 { 2251 2232 LogFlow(("VDICreateBaseImage:\n")); … … 2278 2259 * @param pvUser User argument for the progress callback. 2279 2260 */ 2280 IDER3DECL(int) VDICreateDifferenceImage(const char *pszFilename, const char *pszParent, const char *pszComment, 2281 PFNVMPROGRESS pfnProgress, void *pvUser) 2261 IDER3DECL(int) VDICreateDifferenceImage(const char *pszFilename, const char *pszParent, 2262 const char *pszComment, PFNVMPROGRESS pfnProgress, 2263 void *pvUser) 2282 2264 { 2283 2265 LogFlow(("VDICreateDifferenceImage:\n")); … … 2343 2325 * @param pvUser User argument for the progress callback. 2344 2326 */ 2345 IDER3DECL(int) VDICopyImage(const char *pszDstFilename, const char *pszSrcFilename, const char *pszComment,2346 PFNVMPROGRESS pfnProgress, void *pvUser)2327 IDER3DECL(int) VDICopyImage(const char *pszDstFilename, const char *pszSrcFilename, 2328 const char *pszComment, PFNVMPROGRESS pfnProgress, void *pvUser) 2347 2329 { 2348 2330 LogFlow(("VDICopyImage:\n")); … … 2461 2443 { 2462 2444 c++; 2463 rc = pfnProgress(NULL /* Achtung! pVM=NULL */,2445 rc = pfnProgress(NULL /* WARNING! pVM=NULL */, 2464 2446 (c * 100) / cBlocks, 2465 2447 pvUser); … … 2486 2468 2487 2469 if (pfnProgress) 2488 pfnProgress(NULL /* Achtung! pVM=NULL */, 100, pvUser);2470 pfnProgress(NULL /* WARNING! pVM=NULL */, 100, pvUser); 2489 2471 } 2490 2472 … … 2498 2480 /** 2499 2481 * Shrinks growing image file by removing zeroed data blocks. 2482 * @note Only used by vditool 2500 2483 * 2501 2484 * @returns VBox status code. … … 2534 2517 2535 2518 /* Working data. */ 2536 unsigned cbBlock = getImageBlockSize(&pImage->Header);2537 unsigned cBlocks = getImageBlocks(&pImage->Header);2519 unsigned cbBlock = getImageBlockSize(&pImage->Header); 2520 unsigned cBlocks = getImageBlocks(&pImage->Header); 2538 2521 unsigned cBlocksAllocated = getImageBlocksAllocated(&pImage->Header); 2539 2522 … … 2550 2533 unsigned cBlocksAllocated2 = (unsigned)(cbData >> pImage->uShiftIndex2Offset); 2551 2534 if (cbData != (uint64_t)cBlocksAllocated << pImage->uShiftIndex2Offset) 2552 Log(("VDIShrinkImage: invalid image file length, cbBlock=%u cBlocks=%u cBlocksAllocated=%u cBlocksAllocated2=%u cbData=%llu\n", 2535 Log(("VDIShrinkImage: invalid image file length, cbBlock=%u cBlocks=%u " 2536 "cBlocksAllocated=%u cBlocksAllocated2=%u cbData=%llu\n", 2553 2537 cbBlock, cBlocks, cBlocksAllocated, cBlocksAllocated2, cbData)); 2554 2538 2555 2539 /* Allocate second blocks array for back resolving. */ 2556 PVDIIMAGEBLOCKPOINTER paBlocks2 = (PVDIIMAGEBLOCKPOINTER)RTMemTmpAlloc(sizeof(VDIIMAGEBLOCKPOINTER) * cBlocks); 2540 PVDIIMAGEBLOCKPOINTER paBlocks2 = 2541 (PVDIIMAGEBLOCKPOINTER)RTMemTmpAlloc(sizeof(VDIIMAGEBLOCKPOINTER) * cBlocks); 2557 2542 if (!paBlocks2) 2558 2543 { … … 2586 2571 else 2587 2572 { 2588 Log(("VDIShrinkImage: block n=%u -> uBlock=%u is out of blocks range! (cbBlock=%u cBlocks=%u cBlocksAllocated=%u cBlocksAllocated2=%u cbData=%llu)\n", 2573 Log(("VDIShrinkImage: block n=%u -> uBlock=%u is out of blocks range! (cbBlock=%u " 2574 "cBlocks=%u cBlocksAllocated=%u cBlocksAllocated2=%u cbData=%llu)\n", 2589 2575 n, uBlock, cbBlock, cBlocks, cBlocksAllocated, cBlocksAllocated2, cbData)); 2590 2576 /* free link to invalid block. */ … … 2610 2596 if (VBOX_FAILURE(rc)) 2611 2597 { 2612 Log(("VDIShrinkImage: seek rc=%Vrc filename=\"%s\" uBlock=%u cBlocks=%u cBlocksAllocated=%u cBlocksAllocated2=%u cbData=%llu\n", 2613 rc, pImage->szFilename, uBlock, cBlocks, cBlocksAllocated, cBlocksAllocated2, cbData)); 2598 Log(("VDIShrinkImage: seek rc=%Vrc filename=\"%s\" uBlock=%u cBlocks=%u " 2599 "cBlocksAllocated=%u cBlocksAllocated2=%u cbData=%llu\n", 2600 rc, pImage->szFilename, uBlock, cBlocks, cBlocksAllocated, 2601 cBlocksAllocated2, cbData)); 2614 2602 break; 2615 2603 } … … 2617 2605 if (VBOX_FAILURE(rc)) 2618 2606 { 2619 Log(("VDIShrinkImage: read rc=%Vrc filename=\"%s\" cbBlock=%u uBlock=%u cBlocks=%u cBlocksAllocated=%u cBlocksAllocated2=%u cbData=%llu\n", 2620 rc, pImage->szFilename, cbBlock, uBlock, cBlocks, cBlocksAllocated, cBlocksAllocated2, cbData)); 2607 Log(("VDIShrinkImage: read rc=%Vrc filename=\"%s\" cbBlock=%u uBlock=%u " 2608 "cBlocks=%u cBlocksAllocated=%u cBlocksAllocated2=%u cbData=%llu\n", 2609 rc, pImage->szFilename, cbBlock, uBlock, cBlocks, cBlocksAllocated, 2610 cBlocksAllocated2, cbData)); 2621 2611 break; 2622 2612 } … … 2643 2633 if (VBOX_FAILURE(rc)) 2644 2634 { 2645 Log(("VDIShrinkImage: seek(2) rc=%Vrc filename=\"%s\" uBlockWrite=%u cBlocks=%u cBlocksAllocated=%u cBlocksAllocated2=%u cbData=%llu\n", 2646 rc, pImage->szFilename, uBlockWrite, cBlocks, cBlocksAllocated, cBlocksAllocated2, cbData)); 2635 Log(("VDIShrinkImage: seek(2) rc=%Vrc filename=\"%s\" uBlockWrite=%u " 2636 "cBlocks=%u cBlocksAllocated=%u cBlocksAllocated2=%u cbData=%llu\n", 2637 rc, pImage->szFilename, uBlockWrite, cBlocks, cBlocksAllocated, 2638 cBlocksAllocated2, cbData)); 2647 2639 break; 2648 2640 } … … 2650 2642 if (VBOX_FAILURE(rc)) 2651 2643 { 2652 Log(("VDIShrinkImage: write rc=%Vrc filename=\"%s\" cbBlock=%u uBlockWrite=%u cBlocks=%u cBlocksAllocated=%u cBlocksAllocated2=%u cbData=%llu\n", 2653 rc, pImage->szFilename, cbBlock, uBlockWrite, cBlocks, cBlocksAllocated, cBlocksAllocated2, cbData)); 2644 Log(("VDIShrinkImage: write rc=%Vrc filename=\"%s\" cbBlock=%u " 2645 "uBlockWrite=%u cBlocks=%u cBlocksAllocated=%u " 2646 "cBlocksAllocated2=%u cbData=%llu\n", 2647 rc, pImage->szFilename, cbBlock, uBlockWrite, cBlocks, 2648 cBlocksAllocated, cBlocksAllocated2, cbData)); 2654 2649 break; 2655 2650 } … … 2672 2667 if (pfnProgress) 2673 2668 { 2674 pfnProgress(NULL /* Achtung! pVM=NULL */,2669 pfnProgress(NULL /* WARNING! pVM=NULL */, 2675 2670 (uBlock * 100) / cBlocksAllocated2, 2676 2671 pvUser); … … 2707 2702 rc = vdiUpdateBlocks(pImage); 2708 2703 if (pfnProgress) 2709 pfnProgress(NULL /* Achtung! pVM=NULL*/, 100, pvUser);2704 pfnProgress(NULL /* WARNING! pVM=NULL */, 100, pvUser); 2710 2705 } 2711 2706 … … 2723 2718 /** 2724 2719 * Converts image file from older VDI formats to current one. 2720 * @note Only used by vditool 2725 2721 * 2726 2722 * @returns VBox status code. … … 2849 2845 { 2850 2846 c++; 2851 pfnProgress(NULL /* Achtung! pVM=NULL */,2847 pfnProgress(NULL /* WARNING! pVM=NULL */, 2852 2848 (c * 100) / cMoves, 2853 2849 pvUser); … … 2888 2884 if (pfnProgress) 2889 2885 { 2890 pfnProgress(NULL /* Achtung! pVM=NULL */, 100, pvUser);2886 pfnProgress(NULL /* WARNING! pVM=NULL */, 100, pvUser); 2891 2887 /* Note: conversion is non breakable operation, skipping rc here. */ 2892 2888 } … … 3155 3151 if (pfnProgress) 3156 3152 { 3157 pfnProgress(NULL /* Achtung! pVM=NULL*/, 100, pvUser);3153 pfnProgress(NULL /* WARNING! pVM=NULL */, 100, pvUser); 3158 3154 /* Note: commiting is non breakable operation, skipping rc here. */ 3159 3155 } … … 4007 4003 * Note that in case of unrecoverable error all images of HDD container will be closed. 4008 4004 * 4005 * @note Only used by tstVDI. 4006 * 4009 4007 * @returns VBox status code. 4010 4008 * @param pDisk Pointer to VDI HDD container. … … 4069 4067 4070 4068 /** 4069 * @note Only used by tstVDI. 4070 * 4071 4071 * Creates and opens a new differencing image file in HDD container. 4072 4072 * See comments for VDIDiskOpenImage function about differencing images. … … 4079 4079 * @param pvUser User argument for the progress callback. 4080 4080 */ 4081 IDER3DECL(int) VDIDiskCreateOpenDifferenceImage(PVDIDISK pDisk, const char *pszFilename, const char *pszComment, 4082 PFNVMPROGRESS pfnProgress, void *pvUser) 4081 IDER3DECL(int) VDIDiskCreateOpenDifferenceImage(PVDIDISK pDisk, const char *pszFilename, 4082 const char *pszComment, PFNVMPROGRESS pfnProgress, 4083 void *pvUser) 4083 4084 { 4084 4085 LogFlow(("VDIDiskCreateOpenDifferenceImage:\n")); … … 4115 4116 4116 4117 /** 4118 * @note Only used by tstVDI. 4119 * 4117 4120 * internal: debug image dump. 4118 4121 */ … … 4138 4141 getImageDataOffset(&pImage->Header)); 4139 4142 PVDIDISKGEOMETRY pg = getImageGeometry(&pImage->Header); 4140 RTLogPrintf("Header ->Geometry: C/H/S=%u/%u/%u cbSector=%u Mode=%u\n",4143 RTLogPrintf("Header: Geometry: C/H/S=%u/%u/%u cbSector=%u Mode=%u\n", 4141 4144 pg->cCylinders, pg->cHeads, pg->cSectors, pg->cbSector, 4142 4145 getImageTranslation(&pImage->Header)); … … 4146 4149 if (GET_MAJOR_HEADER_VERSION(&pImage->Header) >= 1) 4147 4150 RTLogPrintf("Header: uuidParentModification={%Vuuid}\n", getImageParentModificationUUID(&pImage->Header)); 4148 RTLogPrintf("Image: fFlags=%08X offStartBlocks=%u offStartData=%u\n",4151 RTLogPrintf("Image: fFlags=%08X offStartBlocks=%u offStartData=%u\n", 4149 4152 pImage->fFlags, pImage->offStartBlocks, pImage->offStartData); 4150 RTLogPrintf("Image: uBlockMask=%08X uShiftIndex2Offset=%u uShiftOffset2Index=%u offStartBlockData=%u\n",4153 RTLogPrintf("Image: uBlockMask=%08X uShiftIndex2Offset=%u uShiftOffset2Index=%u offStartBlockData=%u\n", 4151 4154 pImage->uBlockMask, 4152 4155 pImage->uShiftIndex2Offset, 4153 4156 pImage->uShiftOffset2Index, 4154 4157 pImage->offStartBlockData); 4158 4159 unsigned uBlock, cBlocksNotFree, cBadBlocks, cBlocks = getImageBlocks(&pImage->Header); 4160 for (uBlock=0, cBlocksNotFree=0, cBadBlocks=0; uBlock<cBlocks; uBlock++) 4161 { 4162 if (IS_VDI_IMAGE_BLOCK_ALLOCATED(pImage->paBlocks[uBlock])) 4163 { 4164 cBlocksNotFree++; 4165 if (pImage->paBlocks[uBlock] >= cBlocks) 4166 cBadBlocks++; 4167 } 4168 } 4169 if (cBlocksNotFree != getImageBlocksAllocated(&pImage->Header)) 4170 { 4171 RTLogPrintf("!! WARNING: %u blocks actually allocated (cBlocksAllocated=%u) !!\n", 4172 cBlocksNotFree, getImageBlocksAllocated(&pImage->Header)); 4173 } 4174 if (cBadBlocks) 4175 { 4176 RTLogPrintf("!! WARNING: %u bad blocks found !!\n", 4177 cBadBlocks); 4178 } 4155 4179 } 4156 4180 4157 4181 /** 4158 4182 * Debug helper - dumps all opened images of HDD container into the log file. 4183 * @note Only used by tstVDI and vditool 4159 4184 * 4160 4185 * @param pDisk Pointer to VDI HDD container. … … 4243 4268 int rc = CFGMR3QueryStringAlloc(pCurNode, "Path", &pszName); 4244 4269 if (VBOX_FAILURE(rc)) 4245 { 4246 AssertMsgFailed(("Configuration error: %d - query for \"Path\" string return %Vrc.\n", iLevel, rc)); 4247 return rc; 4248 } 4270 return PDMDRV_SET_ERROR(pDrvIns, rc, 4271 N_("VHDD: Configuration error: Querying \"Path\" as " 4272 "string failed")); 4249 4273 4250 4274 bool fReadOnly; … … 4254 4278 else if (VBOX_FAILURE(rc)) 4255 4279 { 4256 AssertMsgFailed(("Configuration error: %d - query for \"ReadOnly\" boolean return %Vrc.\n", iLevel, rc));4257 4280 MMR3HeapFree(pszName); 4258 return rc; 4281 return PDMDRV_SET_ERROR(pDrvIns, rc, 4282 N_("VHDD: Configuration error: Querying \"ReadOnly\" as " 4283 "boolean failed")); 4259 4284 } 4260 4285 … … 4262 4287 * Open the image. 4263 4288 */ 4264 rc = VDIDiskOpenImage(pData, pszName, !fReadOnly ? VDI_OPEN_FLAGS_NORMAL : VDI_OPEN_FLAGS_READONLY); 4289 rc = VDIDiskOpenImage(pData, pszName, fReadOnly ? VDI_OPEN_FLAGS_READONLY 4290 : VDI_OPEN_FLAGS_NORMAL); 4265 4291 if (VBOX_SUCCESS(rc)) 4266 4292 Log(("vdiConstruct: %d - Opened '%s' in %s mode\n", … … 4284 4310 int rc = CFGMR3QueryStringAlloc(pCfgHandle, "Path", &pszName); 4285 4311 if (VBOX_FAILURE(rc)) 4286 { 4287 AssertMsgFailed(("Configuration error: query for \"Path\" string return %Vrc.\n", rc)); 4288 return rc; 4289 } 4312 return PDMDRV_SET_ERROR(pDrvIns, rc, 4313 N_("VHDD: Configuration error: Querying \"Path\" as " 4314 "string failed")); 4290 4315 4291 4316 /** True if the media is readonly. */ … … 4296 4321 else if (VBOX_FAILURE(rc)) 4297 4322 { 4298 AssertMsgFailed(("Configuration error: query for \"ReadOnly\" boolean return %Vrc.\n", rc));4299 4323 MMR3HeapFree(pszName); 4324 return PDMDRV_SET_ERROR(pDrvIns, rc, 4325 N_("VHDD: Configuration error: Querying \"ReadOnly\" as " 4326 "boolean failed")); 4300 4327 return rc; 4301 4328 } … … 4304 4331 * Open the image. 4305 4332 */ 4306 rc = VDIDiskOpenImage(pData, pszName, !fReadOnly ? VDI_OPEN_FLAGS_NORMAL : VDI_OPEN_FLAGS_READONLY); 4333 rc = VDIDiskOpenImage(pData, pszName, fReadOnly ? VDI_OPEN_FLAGS_READONLY 4334 : VDI_OPEN_FLAGS_NORMAL); 4307 4335 if (VBOX_SUCCESS(rc)) 4308 Log(("vdiConstruct: Opened '%s' in %s mode\n", pszName, VDIDiskIsReadOnly(pData) ? "read-only" : "read-write")); 4336 Log(("vdiConstruct: Opened '%s' in %s mode\n", 4337 pszName, VDIDiskIsReadOnly(pData) ? "read-only" : "read-write")); 4309 4338 else 4310 4339 AssertMsgFailed(("Failed to open image '%s' rc=%Vrc\n", pszName, rc)); … … 4325 4354 * @param pDrvIns The driver instance data. 4326 4355 */ 4327 static DECLCALLBACK(void) 4356 static DECLCALLBACK(void) vdiDestruct(PPDMDRVINS pDrvIns) 4328 4357 { 4329 4358 LogFlow(("vdiDestruct:\n")); … … 4480 4509 4481 4510 /** @copydoc PDMIMEDIA::pfnBiosGetTranslation */ 4482 static DECLCALLBACK(int) vdiBiosGetTranslation(PPDMIMEDIA pInterface, PPDMBIOSTRANSLATION penmTranslation) 4511 static DECLCALLBACK(int) vdiBiosGetTranslation(PPDMIMEDIA pInterface, 4512 PPDMBIOSTRANSLATION penmTranslation) 4483 4513 { 4484 4514 PVDIDISK pData = PDMIMEDIA_2_VDIDISK(pInterface); … … 4489 4519 4490 4520 /** @copydoc PDMIMEDIA::pfnBiosSetTranslation */ 4491 static DECLCALLBACK(int) vdiBiosSetTranslation(PPDMIMEDIA pInterface, PDMBIOSTRANSLATION enmTranslation) 4521 static DECLCALLBACK(int) vdiBiosSetTranslation(PPDMIMEDIA pInterface, 4522 PDMBIOSTRANSLATION enmTranslation) 4492 4523 { 4493 4524 PVDIDISK pData = PDMIMEDIA_2_VDIDISK(pInterface);
Note:
See TracChangeset
for help on using the changeset viewer.