Changeset 19685 in vbox for trunk/src/VBox/Devices/Storage
- Timestamp:
- May 14, 2009 10:20:15 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/VHDHDDCore.cpp
r18965 r19685 36 36 #include <iprt/string.h> 37 37 #include <iprt/rand.h> 38 #include <iprt/stream.h> 38 39 39 40 #define VHD_RELATIVE_MAX_PATH 512 … … 41 42 42 43 #define VHD_SECTOR_SIZE 512 43 #define VHD_BLOCK_SIZE 0x0020000044 #define VHD_BLOCK_SIZE (2 * _1M) 44 45 45 46 /* This is common to all VHD disk types and is located at the end of the image */ 46 47 #pragma pack(1) 47 typedef struct VHDFooter { 48 typedef struct VHDFooter 49 { 48 50 char Cookie[8]; 49 51 uint32_t Features; … … 325 327 } 326 328 rc = RTFileWriteAt(pImage->File, RT_BE2H_U64(pLocator->u64DataOffset), pvBuf, 327 RT_BE2H_U32(pLocator->u32DataSpace) * VHD_SECTOR_SIZE, NULL);329 RT_BE2H_U32(pLocator->u32DataSpace) * VHD_SECTOR_SIZE, NULL); 328 330 329 331 out: … … 348 350 return rc; 349 351 if (memcmp(ddh.Cookie, VHD_DYNAMIC_DISK_HEADER_COOKIE, VHD_DYNAMIC_DISK_HEADER_COOKIE_SIZE) != 0) 350 {351 352 return VERR_VD_VHD_INVALID_HEADER; 352 } 353 353 354 uint32_t u32Checksum = RT_BE2H_U32(ddh.Checksum); 354 355 ddh.Checksum = 0; 355 356 if (u32Checksum != vhdChecksum(&ddh, sizeof(ddh))) 356 {357 357 return VERR_VD_VHD_INVALID_HEADER; 358 } 358 359 359 /* Update parent's timestamp. */ 360 360 ddh.ParentTimeStamp = RT_H2BE_U32(pImage->u32ParentTimeStamp); … … 420 420 421 421 rc = RTFileReadAt(File, pImage->uCurrentEndOfFile, &vhdFooter, sizeof(VHDFooter), NULL); 422 if (memcmp(vhdFooter.Cookie, VHD_FOOTER_COOKIE, VHD_FOOTER_COOKIE_SIZE) != 0) {422 if (memcmp(vhdFooter.Cookie, VHD_FOOTER_COOKIE, VHD_FOOTER_COOKIE_SIZE) != 0) 423 423 return VERR_VD_VHD_INVALID_HEADER; 424 }425 424 426 425 switch (RT_BE2H_U32(vhdFooter.DiskType)) … … 526 525 pImage->cBlockAllocationTableEntries = RT_BE2H_U32(vhdDynamicDiskHeader.MaxTableEntries); 527 526 LogFlowFunc(("MaxTableEntries=%lu\n", pImage->cBlockAllocationTableEntries)); 528 AssertMsg(!(pImage->cbDataBlock % 512), ("%s: Data block size is not a multiple of 512!!\n", __FUNCTION__));529 530 pImage->cSectorsPerDataBlock = pImage->cbDataBlock / 512;527 AssertMsg(!(pImage->cbDataBlock % VHD_SECTOR_SIZE), ("%s: Data block size is not a multiple of %!\n", __FUNCTION__, VHD_SECTOR_SIZE)); 528 529 pImage->cSectorsPerDataBlock = pImage->cbDataBlock / VHD_SECTOR_SIZE; 531 530 LogFlowFunc(("SectorsPerDataBlock=%u\n", pImage->cSectorsPerDataBlock)); 532 531 … … 536 535 */ 537 536 pImage->cbDataBlockBitmap = pImage->cSectorsPerDataBlock / 8; 538 pImage->cDataBlockBitmapSectors = pImage->cbDataBlockBitmap / 512;537 pImage->cDataBlockBitmapSectors = pImage->cbDataBlockBitmap / VHD_SECTOR_SIZE; 539 538 LogFlowFunc(("cbDataBlockBitmap=%u\n", pImage->cbDataBlockBitmap)); 540 539 … … 566 565 567 566 for (i = 0; i < pImage->cBlockAllocationTableEntries; i++) 568 {569 567 pImage->pBlockAllocationTable[i] = RT_BE2H_U32(pBlockAllocationTable[i]); 570 }571 568 572 569 RTMemFree(pBlockAllocationTable); … … 747 744 uOpenFlags = 0; 748 745 749 LogFlowFunc(("returned % d\n", uOpenFlags));746 LogFlowFunc(("returned %#x\n", uOpenFlags)); 750 747 return uOpenFlags; 751 748 } … … 849 846 /* Freeing a never allocated image (e.g. because the open failed) is 850 847 * not signalled as an error. After all nothing bad happens. */ 851 if (pImage) { 848 if (pImage) 849 { 852 850 vhdFlush(pImage); 853 851 RTFileClose(pImage->File); … … 866 864 /* Freeing a never allocated image (e.g. because the open failed) is 867 865 * not signalled as an error. After all nothing bad happens. */ 868 if (pImage) { 866 if (pImage) 867 { 869 868 if (fDelete) 870 869 { … … 900 899 * Get the data block first. 901 900 */ 902 uint32_t cBlockAllocationTableEntry = (uOffset / 512) / pImage->cSectorsPerDataBlock;903 uint32_t cBATEntryIndex = (uOffset / 512) % pImage->cSectorsPerDataBlock;901 uint32_t cBlockAllocationTableEntry = (uOffset / VHD_SECTOR_SIZE) / pImage->cSectorsPerDataBlock; 902 uint32_t cBATEntryIndex = (uOffset / VHD_SECTOR_SIZE) % pImage->cSectorsPerDataBlock; 904 903 uint64_t uVhdOffset; 905 904 … … 917 916 } 918 917 919 uVhdOffset = ((uint64_t)pImage->pBlockAllocationTable[cBlockAllocationTableEntry] + pImage->cDataBlockBitmapSectors + cBATEntryIndex) * 512;918 uVhdOffset = ((uint64_t)pImage->pBlockAllocationTable[cBlockAllocationTableEntry] + pImage->cDataBlockBitmapSectors + cBATEntryIndex) * VHD_SECTOR_SIZE; 920 919 LogFlowFunc(("uVhdOffset=%llu cbRead=%u\n", uVhdOffset, cbRead)); 921 920 … … 923 922 * Clip read range to remain in this data block. 924 923 */ 925 cbRead = RT_MIN(cbRead, (pImage->cbDataBlock - (cBATEntryIndex * 512)));924 cbRead = RT_MIN(cbRead, (pImage->cbDataBlock - (cBATEntryIndex * VHD_SECTOR_SIZE))); 926 925 927 926 /* Read in the block's bitmap. */ 928 927 rc = RTFileReadAt(pImage->File, 929 ((uint64_t)pImage->pBlockAllocationTable[cBlockAllocationTableEntry]) * VHD_SECTOR_SIZE,930 pImage->pu8Bitmap, pImage->cbDataBlockBitmap, NULL);928 ((uint64_t)pImage->pBlockAllocationTable[cBlockAllocationTableEntry]) * VHD_SECTOR_SIZE, 929 pImage->pu8Bitmap, pImage->cbDataBlockBitmap, NULL); 931 930 if (RT_SUCCESS(rc)) 932 931 { … … 1026 1025 1027 1026 LogFlowFunc(("pBackendData=%p uOffset=%llu pvBuf=%p cbToWrite=%u pcbWriteProcess=%p pcbPreRead=%p pcbPostRead=%p fWrite=%u\n", 1028 pBackendData, uOffset, pvBuf, cbToWrite, pcb PreRead, pcbPostRead, fWrite));1029 1030 AssertPtr(pImage); 1031 Assert(uOffset % 512== 0);1032 Assert(cbToWrite % 512== 0);1027 pBackendData, uOffset, pvBuf, cbToWrite, pcbWriteProcess, pcbPreRead, pcbPostRead, fWrite)); 1028 1029 AssertPtr(pImage); 1030 Assert(uOffset % VHD_SECTOR_SIZE == 0); 1031 Assert(cbToWrite % VHD_SECTOR_SIZE == 0); 1033 1032 1034 1033 if (pImage->pBlockAllocationTable) … … 1037 1036 * Get the data block first. 1038 1037 */ 1039 uint32_t cSector = uOffset / 512;1038 uint32_t cSector = uOffset / VHD_SECTOR_SIZE; 1040 1039 uint32_t cBlockAllocationTableEntry = cSector / pImage->cSectorsPerDataBlock; 1041 1040 uint32_t cBATEntryIndex = cSector % pImage->cSectorsPerDataBlock; … … 1066 1065 * Set the new end of the file and link the new block into the BAT. 1067 1066 */ 1068 pImage->pBlockAllocationTable[cBlockAllocationTableEntry] = pImage->uCurrentEndOfFile / 512;1067 pImage->pBlockAllocationTable[cBlockAllocationTableEntry] = pImage->uCurrentEndOfFile / VHD_SECTOR_SIZE; 1069 1068 pImage->uCurrentEndOfFile += cbNewBlock; 1070 1069 RTMemFree(pNewBlock); … … 1074 1073 * Calculate the real offset in the file. 1075 1074 */ 1076 uVhdOffset = ((uint64_t)pImage->pBlockAllocationTable[cBlockAllocationTableEntry] + pImage->cDataBlockBitmapSectors + cBATEntryIndex) * 512;1075 uVhdOffset = ((uint64_t)pImage->pBlockAllocationTable[cBlockAllocationTableEntry] + pImage->cDataBlockBitmapSectors + cBATEntryIndex) * VHD_SECTOR_SIZE; 1077 1076 1078 1077 /* 1079 1078 * Clip write range. 1080 1079 */ 1081 cbToWrite = RT_MIN(cbToWrite, (pImage->cbDataBlock - (cBATEntryIndex * 512)));1080 cbToWrite = RT_MIN(cbToWrite, (pImage->cbDataBlock - (cBATEntryIndex * VHD_SECTOR_SIZE))); 1082 1081 RTFileWriteAt(pImage->File, uVhdOffset, pvBuf, cbToWrite, NULL); 1083 1082 … … 1142 1141 * The BAT entries have to be stored in big endian format. 1143 1142 */ 1144 unsigned i = 0; 1145 for (i = 0; i < pImage->cBlockAllocationTableEntries; i++) 1146 { 1143 for (unsigned i = 0; i < pImage->cBlockAllocationTableEntries; i++) 1147 1144 pBlockAllocationTableToWrite[i] = RT_H2BE_U32(pImage->pBlockAllocationTable[i]); 1148 }1149 1145 1150 1146 /* … … 1390 1386 static void vhdSetDiskGeometry(PVHDIMAGE pImage, uint64_t cbSize) 1391 1387 { 1392 uint64_t u64TotalSectors = cbSize / 512;1388 uint64_t u64TotalSectors = cbSize / VHD_SECTOR_SIZE; 1393 1389 uint32_t u32CylinderTimesHeads, u32Heads, u32SectorsPerTrack; 1394 1390
Note:
See TracChangeset
for help on using the changeset viewer.