Changeset 32768 in vbox for trunk/src/VBox/Devices/Storage
- Timestamp:
- Sep 26, 2010 6:04:06 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DMGHDDCore.cpp
r32553 r32768 29 29 #include <iprt/string.h> 30 30 #include <iprt/base64.h> 31 #ifdef VBOXDMG_TESTING 32 # include <iprt/initterm.h> 33 # include <iprt/stream.h> 34 #endif 31 #include <iprt/zip.h> 35 32 36 33 /******************************************************************************* … … 39 36 40 37 /** Sector size, multiply with all sector counts to get number of bytes. */ 41 #define VBOXDMG_SECTOR_SIZE 512 38 #define DMG_SECTOR_SIZE 512 39 40 /** Convert block number/size to byte offset/size. */ 41 #define DMG_BLOCK2BYTE(u) ((uint64_t)(u) << 9) 42 43 /** Convert byte offset/size to block number/size. */ 44 #define DMG_BYTE2BLOCK(u) ((u) >> 9) 42 45 43 46 /** 44 47 * UDIF checksum structure. 45 48 */ 46 typedef struct VBOXUDIFCKSUM49 typedef struct DMGUDIFCKSUM 47 50 { 48 51 uint32_t u32Kind; /**< The kind of checksum. */ … … 53 56 uint32_t au32[32]; /**< 32-bit view. */ 54 57 } uSum; /**< The checksum. */ 55 } VBOXUDIFCKSUM;56 AssertCompileSize( VBOXUDIFCKSUM, 8 + 128);57 typedef VBOXUDIFCKSUM *PVBOXUDIFCKSUM;58 typedef const VBOXUDIFCKSUM *PCVBOXUDIFCKSUM;59 60 /** @name Checksum Kind ( VBOXUDIFCKSUM::u32Kind)58 } DMGUDIFCKSUM; 59 AssertCompileSize(DMGUDIFCKSUM, 8 + 128); 60 typedef DMGUDIFCKSUM *PDMGUDIFCKSUM; 61 typedef const DMGUDIFCKSUM *PCDMGUDIFCKSUM; 62 63 /** @name Checksum Kind (DMGUDIFCKSUM::u32Kind) 61 64 * @{ */ 62 65 /** No checksum. */ 63 #define VBOXUDIFCKSUM_NONE UINT32_C(0)66 #define DMGUDIFCKSUM_NONE UINT32_C(0) 64 67 /** CRC-32. */ 65 #define VBOXUDIFCKSUM_CRC32 UINT32_C(2)68 #define DMGUDIFCKSUM_CRC32 UINT32_C(2) 66 69 /** @} */ 67 70 … … 71 74 * representation of it for simplicity. 72 75 */ 73 typedef RTUUID VBOXUDIFID;74 AssertCompileSize( VBOXUDIFID, 16);75 typedef VBOXUDIFID *PVBOXUDIFID;76 typedef const VBOXUDIFID *PCVBOXUDIFID;76 typedef RTUUID DMGUDIFID; 77 AssertCompileSize(DMGUDIFID, 16); 78 typedef DMGUDIFID *PDMGUDIFID; 79 typedef const DMGUDIFID *PCDMGUDIFID; 77 80 78 81 /** … … 86 89 */ 87 90 #pragma pack(1) 88 typedef struct VBOXUDIF89 { 90 uint32_t u32Magic; /**< 0x000 - Magic, 'koly' ( VBOXUDIF_MAGIC). (fUDIFSignature) */91 uint32_t u32Version; /**< 0x004 - The UDIF version ( VBOXUDIF_VER_CURRENT). (fUDIFVersion) */91 typedef struct DMGUDIF 92 { 93 uint32_t u32Magic; /**< 0x000 - Magic, 'koly' (DMGUDIF_MAGIC). (fUDIFSignature) */ 94 uint32_t u32Version; /**< 0x004 - The UDIF version (DMGUDIF_VER_CURRENT). (fUDIFVersion) */ 92 95 uint32_t cbFooter; /**< 0x008 - The size of the this structure (512). (fUDIFHeaderSize) */ 93 96 uint32_t fFlags; /**< 0x00c - Flags. (fUDIFFlags) */ … … 99 102 uint32_t iSegment; /**< 0x038 - The segment number of this file. (fUDIFSegmentNumber) */ 100 103 uint32_t cSegments; /**< 0x03c - The number of segments. (fUDIFSegmentCount) */ 101 VBOXUDIFIDSegmentId; /**< 0x040 - The segment ID. (fUDIFSegmentID) */102 VBOXUDIFCKSUMDataCkSum; /**< 0x050 - The data checksum. (fUDIFDataForkChecksum) */104 DMGUDIFID SegmentId; /**< 0x040 - The segment ID. (fUDIFSegmentID) */ 105 DMGUDIFCKSUM DataCkSum; /**< 0x050 - The data checksum. (fUDIFDataForkChecksum) */ 103 106 uint64_t offXml; /**< 0x0d8 - The XML offset (.plist kind of data). (fUDIFXMLOffset) */ 104 107 uint64_t cbXml; /**< 0x0e0 - The size of the XML. (fUDIFXMLSize) */ 105 108 uint8_t abUnknown[120]; /**< 0x0e8 - Unknown stuff, hdiutil doesn't dump it... */ 106 VBOXUDIFCKSUMMasterCkSum; /**< 0x160 - The master checksum. (fUDIFMasterChecksum) */109 DMGUDIFCKSUM MasterCkSum; /**< 0x160 - The master checksum. (fUDIFMasterChecksum) */ 107 110 uint32_t u32Type; /**< 0x1e8 - The image type. (fUDIFImageVariant) */ 108 111 uint64_t cSectors; /**< 0x1ec - The sector count. Warning! Unaligned! (fUDISectorCount) */ 109 112 uint32_t au32Unknown[3]; /**< 0x1f4 - Unknown stuff, hdiutil doesn't dump it... */ 110 } VBOXUDIF;113 } DMGUDIF; 111 114 #pragma pack(0) 112 AssertCompileSize( VBOXUDIF, 512);113 AssertCompileMemberOffset( VBOXUDIF, cbRsrc, 0x030);114 AssertCompileMemberOffset( VBOXUDIF, cbXml, 0x0e0);115 AssertCompileMemberOffset( VBOXUDIF, cSectors, 0x1ec);116 117 typedef VBOXUDIF *PVBOXUDIF;118 typedef const VBOXUDIF *PCVBOXUDIF;119 120 /** The UDIF magic 'koly' ( VBOXUDIF::u32Magic). */121 #define VBOXUDIF_MAGIC UINT32_C(0x6b6f6c79)122 123 /** The current UDIF version ( VBOXUDIF::u32Version).115 AssertCompileSize(DMGUDIF, 512); 116 AssertCompileMemberOffset(DMGUDIF, cbRsrc, 0x030); 117 AssertCompileMemberOffset(DMGUDIF, cbXml, 0x0e0); 118 AssertCompileMemberOffset(DMGUDIF, cSectors, 0x1ec); 119 120 typedef DMGUDIF *PDMGUDIF; 121 typedef const DMGUDIF *PCDMGUDIF; 122 123 /** The UDIF magic 'koly' (DMGUDIF::u32Magic). */ 124 #define DMGUDIF_MAGIC UINT32_C(0x6b6f6c79) 125 126 /** The current UDIF version (DMGUDIF::u32Version). 124 127 * This is currently the only we recognizes and will create. */ 125 #define VBOXUDIF_VER_CURRENT 4126 127 /** @name UDIF flags ( VBOXUDIF::fFlags).128 #define DMGUDIF_VER_CURRENT 4 129 130 /** @name UDIF flags (DMGUDIF::fFlags). 128 131 * @{ */ 129 132 /** Flatten image whatever that means. 130 133 * (hdiutil -debug calls it kUDIFFlagsFlattened.) */ 131 #define VBOXUDIF_FLAGS_FLATTENED RT_BIT_32(0)134 #define DMGUDIF_FLAGS_FLATTENED RT_BIT_32(0) 132 135 /** Internet enabled image. 133 136 * (hdiutil -debug calls it kUDIFFlagsInternetEnabled) */ 134 #define VBOXUDIF_FLAGS_INET_ENABLED RT_BIT_32(2)137 #define DMGUDIF_FLAGS_INET_ENABLED RT_BIT_32(2) 135 138 /** Mask of known bits. */ 136 #define VBOXUDIF_FLAGS_KNOWN_MASK (RT_BIT_32(0) | RT_BIT_32(2))139 #define DMGUDIF_FLAGS_KNOWN_MASK (RT_BIT_32(0) | RT_BIT_32(2)) 137 140 /** @} */ 138 141 139 /** @name UDIF Image Types ( VBOXUDIF::u32Type).142 /** @name UDIF Image Types (DMGUDIF::u32Type). 140 143 * @{ */ 141 144 /** Device image type. (kUDIFDeviceImageType) */ 142 #define VBOXUDIF_TYPE_DEVICE 1145 #define DMGUDIF_TYPE_DEVICE 1 143 146 /** Device image type. (kUDIFPartitionImageType) */ 144 #define VBOXUDIF_TYPE_PARTITION 2147 #define DMGUDIF_TYPE_PARTITION 2 145 148 /** @} */ 146 149 … … 153 156 */ 154 157 #pragma pack(1) 155 typedef struct VBOXBLKX156 { 157 uint32_t u32Magic; /**< 0x000 - Magic, 'mish' ( VBOXBLKX_MAGIC). */158 uint32_t u32Version; /**< 0x004 - The BLKX version ( VBOXBLKX_VER_CURRENT). */158 typedef struct DMGBLKX 159 { 160 uint32_t u32Magic; /**< 0x000 - Magic, 'mish' (DMGBLKX_MAGIC). */ 161 uint32_t u32Version; /**< 0x004 - The BLKX version (DMGBLKX_VER_CURRENT). */ 159 162 uint64_t cSectornumberFirst; /**< 0x008 - The first sector number the block represents in the virtual device. */ 160 163 uint64_t cSectors; /**< 0x010 - Number of sectors this block represents. */ … … 163 166 uint32_t u32BlocksDescriptor; /**< 0x024 - Blocks descriptor. */ 164 167 uint8_t abReserved[24]; 165 VBOXUDIFCKSUMBlkxCkSum; /**< 0x03c - Checksum for the BLKX table. */168 DMGUDIFCKSUM BlkxCkSum; /**< 0x03c - Checksum for the BLKX table. */ 166 169 uint32_t cBlocksRunCount; /**< 0x - Number of entries in the blkx run table afterwards. */ 167 } VBOXBLKX;170 } DMGBLKX; 168 171 #pragma pack(0) 169 AssertCompileSize( VBOXBLKX, 204);170 171 typedef VBOXBLKX *PVBOXBLKX;172 typedef const VBOXBLKX *PCVBOXBLKX;173 174 /** The BLKX magic 'mish' ( VBOXBLKX::u32Magic). */175 #define VBOXBLKX_MAGIC UINT32_C(0x6d697368)176 /** BLKX version ( VBOXBLKX::u32Version). */177 #define VBOXBLKX_VERSION UINT32_C(0x00000001)172 AssertCompileSize(DMGBLKX, 204); 173 174 typedef DMGBLKX *PDMGBLKX; 175 typedef const DMGBLKX *PCDMGBLKX; 176 177 /** The BLKX magic 'mish' (DMGBLKX::u32Magic). */ 178 #define DMGBLKX_MAGIC UINT32_C(0x6d697368) 179 /** BLKX version (DMGBLKX::u32Version). */ 180 #define DMGBLKX_VERSION UINT32_C(0x00000001) 178 181 179 182 /** Blocks descriptor type: entire device. */ 180 #define VBOXBLKX_DESC_ENTIRE_DEVICE UINT32_C(0xfffffffe)183 #define DMGBLKX_DESC_ENTIRE_DEVICE UINT32_C(0xfffffffe) 181 184 182 185 /** … … 186 189 */ 187 190 #pragma pack(1) 188 typedef struct VBOXBLKXDESC191 typedef struct DMGBLKXDESC 189 192 { 190 193 uint32_t u32Type; /**< 0x000 - Type of the descriptor. */ … … 194 197 uint64_t offData; /**< 0x018 - Offset in the image where the data starts. */ 195 198 uint64_t cbData; /**< 0x020 - Number of bytes in the image. */ 196 } VBOXBLKXDESC;199 } DMGBLKXDESC; 197 200 #pragma pack(0) 198 AssertCompileSize( VBOXBLKXDESC, 40);199 200 typedef VBOXBLKXDESC *PVBOXBLKXDESC;201 typedef const VBOXBLKXDESC *PCVBOXBLKXDESC;201 AssertCompileSize(DMGBLKXDESC, 40); 202 203 typedef DMGBLKXDESC *PDMGBLKXDESC; 204 typedef const DMGBLKXDESC *PCDMGBLKXDESC; 202 205 203 206 /** Raw image data type. */ 204 #define VBOXBLKXDESC_TYPE_RAW 1207 #define DMGBLKXDESC_TYPE_RAW 1 205 208 /** Ignore type. */ 206 #define VBOXBLKXDESC_TYPE_IGNORE 2 209 #define DMGBLKXDESC_TYPE_IGNORE 2 210 /** Compressed with zlib type. */ 211 #define DMGBLKXDESC_TYPE_ZLIB UINT32_C(0x80000005) 207 212 /** Comment type. */ 208 #define VBOXBLKXDESC_TYPE_COMMENT UINT32_C(0x7ffffffe)213 #define DMGBLKXDESC_TYPE_COMMENT UINT32_C(0x7ffffffe) 209 214 /** Terminator type. */ 210 #define VBOXBLKXDESC_TYPE_TERMINATOR UINT32_C(0xffffffff)215 #define DMGBLKXDESC_TYPE_TERMINATOR UINT32_C(0xffffffff) 211 216 212 217 /** 213 218 * UDIF Resource Entry. 214 219 */ 215 typedef struct VBOXUDIFRSRCENTRY220 typedef struct DMGUDIFRSRCENTRY 216 221 { 217 222 /** The ID. */ … … 227 232 /** The raw data. */ 228 233 uint8_t *pbData; 229 } VBOXUDIFRSRCENTRY;234 } DMGUDIFRSRCENTRY; 230 235 /** Pointer to an UDIF resource entry. */ 231 typedef VBOXUDIFRSRCENTRY *PVBOXUDIFRSRCENTRY;236 typedef DMGUDIFRSRCENTRY *PDMGUDIFRSRCENTRY; 232 237 /** Pointer to a const UDIF resource entry. */ 233 typedef VBOXUDIFRSRCENTRY const *PCVBOXUDIFRSRCENTRY;238 typedef DMGUDIFRSRCENTRY const *PCDMGUDIFRSRCENTRY; 234 239 235 240 /** 236 241 * UDIF Resource Array. 237 242 */ 238 typedef struct VBOXUDIFRSRCARRAY243 typedef struct DMGUDIFRSRCARRAY 239 244 { 240 245 /** The array name. */ … … 246 251 * size if DMGs with more are found. 247 252 * r=aeichner: Saw one with 6 here (image of a whole DVD) */ 248 VBOXUDIFRSRCENTRYaEntries[10];249 } VBOXUDIFRSRCARRAY;253 DMGUDIFRSRCENTRY aEntries[10]; 254 } DMGUDIFRSRCARRAY; 250 255 /** Pointer to a UDIF resource array. */ 251 typedef VBOXUDIFRSRCARRAY *PVBOXUDIFRSRCARRAY;256 typedef DMGUDIFRSRCARRAY *PDMGUDIFRSRCARRAY; 252 257 /** Pointer to a const UDIF resource array. */ 253 typedef VBOXUDIFRSRCARRAY const *PCVBOXUDIFRSRCARRAY;258 typedef DMGUDIFRSRCARRAY const *PCDMGUDIFRSRCARRAY; 254 259 255 260 /** … … 264 269 /** Zero extent, reads return 0 and writes have no effect. */ 265 270 DMGEXTENTTYPE_ZERO, 271 /** Compressed extent - compression method ZLIB. */ 272 DMGEXTENTTYPE_COMP_ZLIB, 266 273 /** 32bit hack. */ 267 274 DMGEXTENTTYPE_32BIT_HACK = 0x7fffffff … … 273 280 typedef struct DMGEXTENT 274 281 { 275 /** Next DMG extent, sorted by virtual sector count. */276 struct DMGEXTENT *pNext;277 282 /** Extent type. */ 278 283 DMGEXTENTTYPE enmType; 279 /** First bytethis extent describes. */280 uint64_t offExtent;281 /** Number of bytes this extent describes. */282 uint64_t c bExtent;284 /** First sector this extent describes. */ 285 uint64_t uSectorExtent; 286 /** Number of sectors this extent describes. */ 287 uint64_t cSectorsExtent; 283 288 /** Start offset in the real file. */ 284 289 uint64_t offFileStart; 290 /** Number of bytes for the extent data in the file. */ 291 uint64_t cbFile; 285 292 } DMGEXTENT; 286 293 /** Pointer to an DMG extent. */ … … 328 335 * A lazy bird ASSUME there are only two arrays in the resource-fork section in 329 336 * the XML, namely 'blkx' and 'plst'. These have been assigned fixed indexes. */ 330 VBOXUDIFRSRCARRAYaRsrcs[2];337 DMGUDIFRSRCARRAY aRsrcs[2]; 331 338 /** The UDIF footer. */ 332 VBOXUDIF Ftr; 333 334 /** First extent in the list. */ 335 PDMGEXTENT pExtentFirst; 336 /** Last extent in the list. */ 337 PDMGEXTENT pExtentLast; 339 DMGUDIF Ftr; 340 341 /** Number of valid extents in the array. */ 342 unsigned cExtents; 343 /** Number of entries the array can hold. */ 344 unsigned cExtentsMax; 345 /** Pointer to the extent array. */ 346 PDMGEXTENT paExtents; 347 /** Index of the last accessed extent. */ 348 unsigned idxExtentLast; 349 350 /** Extent which owns the data in the buffer. */ 351 PDMGEXTENT pExtentDecomp; 352 /** Buffer holding the decompressed data for a extent. */ 353 void *pvDecompExtent; 354 /** Size of the buffer. */ 355 size_t cbDecompExtent; 338 356 } DMGIMAGE; 339 357 /** Pointer to an instance of the DMG Image Interpreter. */ 340 358 typedef DMGIMAGE *PDMGIMAGE; 341 359 342 /** @name Resources indexes (into VBOXDMG::aRsrcs).360 /** @name Resources indexes (into DMG::aRsrcs). 343 361 * @{ */ 344 #define VBOXDMG_RSRC_IDX_BLKX 0345 #define VBOXDMG_RSRC_IDX_PLST 1362 #define DMG_RSRC_IDX_BLKX 0 363 #define DMG_RSRC_IDX_PLST 1 346 364 /** @} */ 347 365 366 /** State for the input callout of the inflate reader. */ 367 typedef struct DMGINFLATESTATE 368 { 369 /* Image this operation relates to. */ 370 PDMGIMAGE pImage; 371 /* Total size of the data to read. */ 372 size_t cbSize; 373 /* Offset in the file to read. */ 374 uint64_t uFileOffset; 375 /* Current read position. */ 376 ssize_t iOffset; 377 } DMGINFLATESTATE; 348 378 349 379 /******************************************************************************* 350 380 * Defined Constants And Macros * 351 381 *******************************************************************************/ 352 /** @def VBOXDMG_PRINTF 353 * Wrapper for RTPrintf/LogRel. 354 */ 355 #ifdef VBOXDMG_TESTING 356 # define VBOXDMG_PRINTF(a) RTPrintf a 357 #else 358 # define VBOXDMG_PRINTF(a) LogRel(a) 359 #endif 360 361 /** @def VBOXDMG_VALIDATE 382 /** @def DMG_PRINTF 383 * Wrapper for LogRel. 384 */ 385 #define DMG_PRINTF(a) LogRel(a) 386 387 /** @def DMG_VALIDATE 362 388 * For validating a struct thing and log/print what's wrong. 363 389 */ 364 #ifdef VBOXDMG_TESTING 365 # define VBOXDMG_VALIDATE(expr, logstuff) \ 390 # define DMG_VALIDATE(expr, logstuff) \ 366 391 do { \ 367 392 if (!(expr)) \ 368 393 { \ 369 RTPrintf("tstVBoxDMG: validation failed: %s\ntstVBoxDMG: ", #expr); \ 370 RTPrintf logstuff; \ 371 fRc = false; \ 372 } \ 373 } while (0) 374 #else 375 # define VBOXDMG_VALIDATE(expr, logstuff) \ 376 do { \ 377 if (!(expr)) \ 378 { \ 379 LogRel(("vboxdmg: validation failed: %s\nvboxdmg: ", #expr)); \ 394 LogRel(("DMG: validation failed: %s\nDMG: ", #expr)); \ 380 395 LogRel(logstuff); \ 381 396 fRc = false; \ 382 397 } \ 383 398 } while (0) 384 #endif385 386 399 387 400 /** VBoxDMG: Unable to parse the XML. */ … … 403 416 * Internal Functions * 404 417 *******************************************************************************/ 405 static void vboxdmgUdifFtrHost2FileEndian(PVBOXUDIF pUdif);406 static void vboxdmgUdifFtrFile2HostEndian(PVBOXUDIF pUdif);407 408 static void vboxdmgUdifIdHost2FileEndian(PVBOXUDIFID pId);409 static void vboxdmgUdifIdFile2HostEndian(PVBOXUDIFID pId);410 411 static void vboxdmgUdifCkSumHost2FileEndian(PVBOXUDIFCKSUM pCkSum);412 static void vboxdmgUdifCkSumFile2HostEndian(PVBOXUDIFCKSUM pCkSum);413 static bool vboxdmgUdifCkSumIsValid(PCVBOXUDIFCKSUM pCkSum, const char *pszPrefix);418 static void dmgUdifFtrHost2FileEndian(PDMGUDIF pUdif); 419 static void dmgUdifFtrFile2HostEndian(PDMGUDIF pUdif); 420 421 static void dmgUdifIdHost2FileEndian(PDMGUDIFID pId); 422 static void dmgUdifIdFile2HostEndian(PDMGUDIFID pId); 423 424 static void dmgUdifCkSumHost2FileEndian(PDMGUDIFCKSUM pCkSum); 425 static void dmgUdifCkSumFile2HostEndian(PDMGUDIFCKSUM pCkSum); 426 static bool dmgUdifCkSumIsValid(PCDMGUDIFCKSUM pCkSum, const char *pszPrefix); 414 427 415 428 /** … … 513 526 } 514 527 528 static DECLCALLBACK(int) dmgFileInflateHelper(void *pvUser, void *pvBuf, size_t cbBuf, size_t *pcbBuf) 529 { 530 DMGINFLATESTATE *pInflateState = (DMGINFLATESTATE *)pvUser; 531 532 Assert(cbBuf); 533 if (pInflateState->iOffset < 0) 534 { 535 *(uint8_t *)pvBuf = RTZIPTYPE_ZLIB; 536 if (pcbBuf) 537 *pcbBuf = 1; 538 pInflateState->iOffset = 0; 539 return VINF_SUCCESS; 540 } 541 cbBuf = RT_MIN(cbBuf, pInflateState->cbSize); 542 int rc = dmgFileReadSync(pInflateState->pImage, pInflateState->uFileOffset, 543 pvBuf, cbBuf, NULL); 544 if (RT_FAILURE(rc)) 545 return rc; 546 pInflateState->uFileOffset += cbBuf; 547 pInflateState->iOffset += cbBuf; 548 pInflateState->cbSize -= cbBuf; 549 Assert(pcbBuf); 550 *pcbBuf = cbBuf; 551 return VINF_SUCCESS; 552 } 553 554 /** 555 * Internal: read from a file and inflate the compressed data, 556 * distinguishing between async and normal operation 557 */ 558 DECLINLINE(int) dmgFileInflateSync(PDMGIMAGE pImage, uint64_t uOffset, size_t cbToRead, 559 void *pvBuf, size_t cbBuf) 560 { 561 int rc; 562 PRTZIPDECOMP pZip = NULL; 563 DMGINFLATESTATE InflateState; 564 size_t cbActuallyRead; 565 566 InflateState.pImage = pImage; 567 InflateState.cbSize = cbToRead; 568 InflateState.uFileOffset = uOffset; 569 InflateState.iOffset = -1; 570 571 rc = RTZipDecompCreate(&pZip, &InflateState, dmgFileInflateHelper); 572 if (RT_FAILURE(rc)) 573 return rc; 574 rc = RTZipDecompress(pZip, pvBuf, cbBuf, &cbActuallyRead); 575 RTZipDecompDestroy(pZip); 576 if (RT_FAILURE(rc)) 577 return rc; 578 if (cbActuallyRead != cbBuf) 579 rc = VERR_VD_VMDK_INVALID_FORMAT; 580 return rc; 581 } 515 582 516 583 /** … … 518 585 * @param pUdif The structure. 519 586 */ 520 static void vboxdmgSwapEndianUdif(PVBOXUDIF pUdif)587 static void dmgSwapEndianUdif(PDMGUDIF pUdif) 521 588 { 522 589 #ifndef RT_BIG_ENDIAN … … 544 611 * @param pUdif The structure. 545 612 */ 546 static void vboxdmgUdifFtrHost2FileEndian(PVBOXUDIF pUdif)547 { 548 vboxdmgSwapEndianUdif(pUdif);549 vboxdmgUdifIdHost2FileEndian(&pUdif->SegmentId);550 vboxdmgUdifCkSumHost2FileEndian(&pUdif->DataCkSum);551 vboxdmgUdifCkSumHost2FileEndian(&pUdif->MasterCkSum);613 static void dmgUdifFtrHost2FileEndian(PDMGUDIF pUdif) 614 { 615 dmgSwapEndianUdif(pUdif); 616 dmgUdifIdHost2FileEndian(&pUdif->SegmentId); 617 dmgUdifCkSumHost2FileEndian(&pUdif->DataCkSum); 618 dmgUdifCkSumHost2FileEndian(&pUdif->MasterCkSum); 552 619 } 553 620 … … 557 624 * @param pUdif The structure. 558 625 */ 559 static void vboxdmgUdifFtrFile2HostEndian(PVBOXUDIF pUdif)560 { 561 vboxdmgSwapEndianUdif(pUdif);562 vboxdmgUdifIdFile2HostEndian(&pUdif->SegmentId);563 vboxdmgUdifCkSumFile2HostEndian(&pUdif->DataCkSum);564 vboxdmgUdifCkSumFile2HostEndian(&pUdif->MasterCkSum);626 static void dmgUdifFtrFile2HostEndian(PDMGUDIF pUdif) 627 { 628 dmgSwapEndianUdif(pUdif); 629 dmgUdifIdFile2HostEndian(&pUdif->SegmentId); 630 dmgUdifCkSumFile2HostEndian(&pUdif->DataCkSum); 631 dmgUdifCkSumFile2HostEndian(&pUdif->MasterCkSum); 565 632 } 566 633 … … 569 636 * @param pBlkx The blkx structure. 570 637 */ 571 static void vboxdmgBlkxFile2HostEndian(PVBOXBLKX pBlkx)638 static void dmgBlkxFile2HostEndian(PDMGBLKX pBlkx) 572 639 { 573 640 pBlkx->u32Magic = RT_BE2H_U32(pBlkx->u32Magic); … … 579 646 pBlkx->u32BlocksDescriptor = RT_BE2H_U32(pBlkx->u32BlocksDescriptor); 580 647 pBlkx->cBlocksRunCount = RT_BE2H_U32(pBlkx->cBlocksRunCount); 581 vboxdmgUdifCkSumFile2HostEndian(&pBlkx->BlkxCkSum);648 dmgUdifCkSumFile2HostEndian(&pBlkx->BlkxCkSum); 582 649 } 583 650 … … 586 653 * @param pBlkxDesc The blkx descriptor structure. 587 654 */ 588 static void vboxdmgBlkxDescFile2HostEndian(PVBOXBLKXDESC pBlkxDesc)655 static void dmgBlkxDescFile2HostEndian(PDMGBLKXDESC pBlkxDesc) 589 656 { 590 657 pBlkxDesc->u32Type = RT_BE2H_U32(pBlkxDesc->u32Type); … … 603 670 * @param offFtr The offset of the structure. 604 671 */ 605 static bool vboxdmgUdifFtrIsValid(PCVBOXUDIF pFtr, uint64_t offFtr)672 static bool dmgUdifFtrIsValid(PCDMGUDIF pFtr, uint64_t offFtr) 606 673 { 607 674 bool fRc = true; 608 675 609 VBOXDMG_VALIDATE(!(pFtr->fFlags & ~VBOXUDIF_FLAGS_KNOWN_MASK), ("fFlags=%#RX32 fKnown=%RX32\n", pFtr->fFlags, VBOXUDIF_FLAGS_KNOWN_MASK));610 VBOXDMG_VALIDATE(pFtr->offRunData < offFtr, ("offRunData=%#RX64\n", pFtr->offRunData));611 VBOXDMG_VALIDATE(pFtr->cbData <= offFtr && pFtr->offData + pFtr->cbData <= offFtr, ("cbData=%#RX64 offData=%#RX64 offFtr=%#RX64\n", pFtr->cbData, pFtr->offData, offFtr));612 VBOXDMG_VALIDATE(pFtr->offData < offFtr, ("offData=%#RX64\n", pFtr->offData));613 VBOXDMG_VALIDATE(pFtr->cbRsrc <= offFtr && pFtr->offRsrc + pFtr->cbRsrc <= offFtr, ("cbRsrc=%#RX64 offRsrc=%#RX64 offFtr=%#RX64\n", pFtr->cbRsrc, pFtr->offRsrc, offFtr));614 VBOXDMG_VALIDATE(pFtr->offRsrc < offFtr, ("offRsrc=%#RX64\n", pFtr->offRsrc));615 VBOXDMG_VALIDATE(pFtr->cSegments <= 1, ("cSegments=%RU32\n", pFtr->cSegments));616 VBOXDMG_VALIDATE(pFtr->iSegment == 0 || pFtr->iSegment == 1, ("iSegment=%RU32 cSegments=%RU32\n", pFtr->iSegment, pFtr->cSegments));617 VBOXDMG_VALIDATE(pFtr->cbXml <= offFtr && pFtr->offXml + pFtr->cbXml <= offFtr, ("cbXml=%#RX64 offXml=%#RX64 offFtr=%#RX64\n", pFtr->cbXml, pFtr->offXml, offFtr));618 VBOXDMG_VALIDATE(pFtr->offXml < offFtr, ("offXml=%#RX64\n", pFtr->offXml));619 VBOXDMG_VALIDATE(pFtr->cbXml > 128, ("cbXml=%#RX64\n", pFtr->cbXml));620 VBOXDMG_VALIDATE(pFtr->cbXml <_1M, ("cbXml=%#RX64\n", pFtr->cbXml));621 VBOXDMG_VALIDATE(pFtr->u32Type == VBOXUDIF_TYPE_DEVICE || pFtr->u32Type == VBOXUDIF_TYPE_PARTITION, ("u32Type=%RU32\n", pFtr->u32Type));622 VBOXDMG_VALIDATE(pFtr->cSectors != 0, ("cSectors=%#RX64\n", pFtr->cSectors));623 fRc &= vboxdmgUdifCkSumIsValid(&pFtr->DataCkSum, "DataCkSum");624 fRc &= vboxdmgUdifCkSumIsValid(&pFtr->MasterCkSum, "MasterCkSum");676 DMG_VALIDATE(!(pFtr->fFlags & ~DMGUDIF_FLAGS_KNOWN_MASK), ("fFlags=%#RX32 fKnown=%RX32\n", pFtr->fFlags, DMGUDIF_FLAGS_KNOWN_MASK)); 677 DMG_VALIDATE(pFtr->offRunData < offFtr, ("offRunData=%#RX64\n", pFtr->offRunData)); 678 DMG_VALIDATE(pFtr->cbData <= offFtr && pFtr->offData + pFtr->cbData <= offFtr, ("cbData=%#RX64 offData=%#RX64 offFtr=%#RX64\n", pFtr->cbData, pFtr->offData, offFtr)); 679 DMG_VALIDATE(pFtr->offData < offFtr, ("offData=%#RX64\n", pFtr->offData)); 680 DMG_VALIDATE(pFtr->cbRsrc <= offFtr && pFtr->offRsrc + pFtr->cbRsrc <= offFtr, ("cbRsrc=%#RX64 offRsrc=%#RX64 offFtr=%#RX64\n", pFtr->cbRsrc, pFtr->offRsrc, offFtr)); 681 DMG_VALIDATE(pFtr->offRsrc < offFtr, ("offRsrc=%#RX64\n", pFtr->offRsrc)); 682 DMG_VALIDATE(pFtr->cSegments <= 1, ("cSegments=%RU32\n", pFtr->cSegments)); 683 DMG_VALIDATE(pFtr->iSegment == 0 || pFtr->iSegment == 1, ("iSegment=%RU32 cSegments=%RU32\n", pFtr->iSegment, pFtr->cSegments)); 684 DMG_VALIDATE(pFtr->cbXml <= offFtr && pFtr->offXml + pFtr->cbXml <= offFtr, ("cbXml=%#RX64 offXml=%#RX64 offFtr=%#RX64\n", pFtr->cbXml, pFtr->offXml, offFtr)); 685 DMG_VALIDATE(pFtr->offXml < offFtr, ("offXml=%#RX64\n", pFtr->offXml)); 686 DMG_VALIDATE(pFtr->cbXml > 128, ("cbXml=%#RX64\n", pFtr->cbXml)); 687 DMG_VALIDATE(pFtr->cbXml < 10 * _1M, ("cbXml=%#RX64\n", pFtr->cbXml)); 688 DMG_VALIDATE(pFtr->u32Type == DMGUDIF_TYPE_DEVICE || pFtr->u32Type == DMGUDIF_TYPE_PARTITION, ("u32Type=%RU32\n", pFtr->u32Type)); 689 DMG_VALIDATE(pFtr->cSectors != 0, ("cSectors=%#RX64\n", pFtr->cSectors)); 690 fRc &= dmgUdifCkSumIsValid(&pFtr->DataCkSum, "DataCkSum"); 691 fRc &= dmgUdifCkSumIsValid(&pFtr->MasterCkSum, "MasterCkSum"); 625 692 626 693 return fRc; … … 628 695 629 696 630 static bool vboxdmgBlkxIsValid(PCVBOXBLKX pBlkx)697 static bool dmgBlkxIsValid(PCDMGBLKX pBlkx) 631 698 { 632 699 bool fRc = true; 633 700 634 fRc &= vboxdmgUdifCkSumIsValid(&pBlkx->BlkxCkSum, "BlkxCkSum");635 VBOXDMG_VALIDATE(pBlkx->u32Magic == VBOXBLKX_MAGIC, ("u32Magic=%#RX32 u32MagicExpected=%#RX32\n", pBlkx->u32Magic, VBOXBLKX_MAGIC));636 VBOXDMG_VALIDATE(pBlkx->u32Version == VBOXBLKX_VERSION, ("u32Version=%#RX32 u32VersionExpected=%#RX32\n", pBlkx->u32Magic, VBOXBLKX_VERSION));701 fRc &= dmgUdifCkSumIsValid(&pBlkx->BlkxCkSum, "BlkxCkSum"); 702 DMG_VALIDATE(pBlkx->u32Magic == DMGBLKX_MAGIC, ("u32Magic=%#RX32 u32MagicExpected=%#RX32\n", pBlkx->u32Magic, DMGBLKX_MAGIC)); 703 DMG_VALIDATE(pBlkx->u32Version == DMGBLKX_VERSION, ("u32Version=%#RX32 u32VersionExpected=%#RX32\n", pBlkx->u32Magic, DMGBLKX_VERSION)); 637 704 638 705 return fRc; … … 643 710 * @param pId The structure. 644 711 */ 645 static void vboxdmgUdifIdHost2FileEndian(PVBOXUDIFID pId)712 static void dmgUdifIdHost2FileEndian(PDMGUDIFID pId) 646 713 { 647 714 NOREF(pId); … … 653 720 * @param pId The structure. 654 721 */ 655 static void vboxdmgUdifIdFile2HostEndian(PVBOXUDIFID pId)656 { 657 vboxdmgUdifIdHost2FileEndian(pId);722 static void dmgUdifIdFile2HostEndian(PDMGUDIFID pId) 723 { 724 dmgUdifIdHost2FileEndian(pId); 658 725 } 659 726 … … 663 730 * @param pCkSum The structure. 664 731 */ 665 static void vboxdmgSwapEndianUdifCkSum(PVBOXUDIFCKSUM pCkSum, uint32_t u32Kind, uint32_t cBits)732 static void dmgSwapEndianUdifCkSum(PDMGUDIFCKSUM pCkSum, uint32_t u32Kind, uint32_t cBits) 666 733 { 667 734 #ifdef RT_BIG_ENDIAN … … 672 739 switch (u32Kind) 673 740 { 674 case VBOXUDIFCKSUM_NONE:741 case DMGUDIFCKSUM_NONE: 675 742 /* nothing to do here */ 676 743 break; 677 744 678 case VBOXUDIFCKSUM_CRC32:745 case DMGUDIFCKSUM_CRC32: 679 746 Assert(cBits == 32); 680 747 pCkSum->u32Kind = RT_BSWAP_U32(pCkSum->u32Kind); … … 696 763 * @param pCkSum The structure. 697 764 */ 698 static void vboxdmgUdifCkSumHost2FileEndian(PVBOXUDIFCKSUM pCkSum)699 { 700 vboxdmgSwapEndianUdifCkSum(pCkSum, pCkSum->u32Kind, pCkSum->cBits);765 static void dmgUdifCkSumHost2FileEndian(PDMGUDIFCKSUM pCkSum) 766 { 767 dmgSwapEndianUdifCkSum(pCkSum, pCkSum->u32Kind, pCkSum->cBits); 701 768 } 702 769 … … 706 773 * @param pCkSum The structure. 707 774 */ 708 static void vboxdmgUdifCkSumFile2HostEndian(PVBOXUDIFCKSUM pCkSum)709 { 710 vboxdmgSwapEndianUdifCkSum(pCkSum, RT_BE2H_U32(pCkSum->u32Kind), RT_BE2H_U32(pCkSum->cBits));775 static void dmgUdifCkSumFile2HostEndian(PDMGUDIFCKSUM pCkSum) 776 { 777 dmgSwapEndianUdifCkSum(pCkSum, RT_BE2H_U32(pCkSum->u32Kind), RT_BE2H_U32(pCkSum->cBits)); 711 778 } 712 779 … … 720 787 * @remarks This does not check the checksummed data. 721 788 */ 722 static bool vboxdmgUdifCkSumIsValid(PCVBOXUDIFCKSUM pCkSum, const char *pszPrefix)789 static bool dmgUdifCkSumIsValid(PCDMGUDIFCKSUM pCkSum, const char *pszPrefix) 723 790 { 724 791 bool fRc = true; … … 726 793 switch (pCkSum->u32Kind) 727 794 { 728 case VBOXUDIFCKSUM_NONE:729 VBOXDMG_VALIDATE(pCkSum->cBits == 0, ("%s/NONE: cBits=%d\n", pszPrefix, pCkSum->cBits));795 case DMGUDIFCKSUM_NONE: 796 DMG_VALIDATE(pCkSum->cBits == 0, ("%s/NONE: cBits=%d\n", pszPrefix, pCkSum->cBits)); 730 797 break; 731 798 732 case VBOXUDIFCKSUM_CRC32:733 VBOXDMG_VALIDATE(pCkSum->cBits == 32, ("%s/NONE: cBits=%d\n", pszPrefix, pCkSum->cBits));799 case DMGUDIFCKSUM_CRC32: 800 DMG_VALIDATE(pCkSum->cBits == 32, ("%s/NONE: cBits=%d\n", pszPrefix, pCkSum->cBits)); 734 801 break; 735 802 736 803 default: 737 VBOXDMG_VALIDATE(0, ("%s: u32Kind=%#RX32\n", pszPrefix, pCkSum->u32Kind));804 DMG_VALIDATE(0, ("%s: u32Kind=%#RX32\n", pszPrefix, pCkSum->u32Kind)); 738 805 break; 739 806 } … … 803 870 if (fDelete && pThis->pszFilename) 804 871 dmgFileDelete(pThis, pThis->pszFilename); 872 873 if (pThis->pvDecompExtent) 874 { 875 RTMemFree(pThis->pvDecompExtent); 876 pThis->pvDecompExtent = NULL; 877 pThis->cbDecompExtent = 0; 878 } 879 805 880 } 806 881 … … 857 932 * @param pszCur The current position. 858 933 */ 859 static const char * vboxdmgXmlFindTagEnd(const char *pszCur)934 static const char *dmgXmlFindTagEnd(const char *pszCur) 860 935 { 861 936 /* Might want to take quoted '>' into account? */ … … 877 952 * @param pszTag The tag name. 878 953 */ 879 static const char * vboxdmgXmlFindEndTag(const char **ppszCur, const char *pszTag)954 static const char *dmgXmlFindEndTag(const char **ppszCur, const char *pszTag) 880 955 { 881 956 const char *psz = *ppszCur; … … 908 983 * @param pi32 Where to store the value. 909 984 */ 910 static const char * vboxdmgXmlParseS32(const char **ppszCur, int32_t *pi32)985 static const char *dmgXmlParseS32(const char **ppszCur, int32_t *pi32) 911 986 { 912 987 const char *psz = *ppszCur; … … 936 1011 * @param pu32 Where to store the value. 937 1012 */ 938 static const char * vboxdmgXmlParseU32(const char **ppszCur, uint32_t *pu32)1013 static const char *dmgXmlParseU32(const char **ppszCur, uint32_t *pu32) 939 1014 { 940 1015 const char *psz = *ppszCur; … … 965 1040 * must free this using RTMemFree. 966 1041 */ 967 static const char * vboxdmgXmlParseString(const char **ppszCur, char **ppszString)1042 static const char *dmgXmlParseString(const char **ppszCur, char **ppszString) 968 1043 { 969 1044 const char *psz = *ppszCur; … … 975 1050 976 1051 const char *pszStart = psz; 977 const char *pszEnd = vboxdmgXmlFindEndTag(&psz, "string");1052 const char *pszEnd = dmgXmlFindEndTag(&psz, "string"); 978 1053 if (!pszEnd) 979 1054 return *ppszCur; … … 998 1073 * @param pcbData The number of bytes we're returning. 999 1074 */ 1000 static const char * vboxdmgXmlParseData(const char **ppszCur, uint8_t **ppbData, size_t *pcbData)1075 static const char *dmgXmlParseData(const char **ppszCur, uint8_t **ppbData, size_t *pcbData) 1001 1076 { 1002 1077 const char *psz = *ppszCur; … … 1035 1110 * Parses the XML resource-fork in a rather presumptive manner. 1036 1111 * 1037 * This function is supposed to construct the VBOXDMG::aRsrcs instance data1112 * This function is supposed to construct the DMG::aRsrcs instance data 1038 1113 * parts. 1039 1114 * … … 1043 1118 * @param cch The size of the the XML text. 1044 1119 */ 1045 static const char * vboxdmgOpenXmlToRsrc(PDMGIMAGE pThis, char const *pszXml)1120 static const char *dmgOpenXmlToRsrc(PDMGIMAGE pThis, char const *pszXml) 1046 1121 { 1047 1122 const char *psz = pszXml; … … 1077 1152 REQUIRE_WORD(psz, "plist"); 1078 1153 REQUIRE_WORD(psz, "PUBLIC"); 1079 psz = vboxdmgXmlFindTagEnd(psz);1154 psz = dmgXmlFindTagEnd(psz); 1080 1155 REQUIRE_WORD(psz, ">"); 1081 1156 … … 1108 1183 { 1109 1184 REQUIRE_WORD(psz, "<key>blkx</key>"); 1110 iRsrc = VBOXDMG_RSRC_IDX_BLKX;1185 iRsrc = DMG_RSRC_IDX_BLKX; 1111 1186 strcpy(&pThis->aRsrcs[iRsrc].szName[0], "blkx"); 1112 1187 } … … 1114 1189 { 1115 1190 REQUIRE_WORD(psz, "<key>plst</key>"); 1116 iRsrc = VBOXDMG_RSRC_IDX_PLST;1191 iRsrc = DMG_RSRC_IDX_PLST; 1117 1192 strcpy(&pThis->aRsrcs[iRsrc].szName[0], "plst"); 1118 1193 } … … 1140 1215 { 1141 1216 REQUIRE_WORD(psz, "<key>Attributes</key>"); 1142 pszErr = vboxdmgXmlParseU32(&psz, &pThis->aRsrcs[iRsrc].aEntries[i].fAttributes);1217 pszErr = dmgXmlParseU32(&psz, &pThis->aRsrcs[iRsrc].aEntries[i].fAttributes); 1143 1218 } 1144 1219 else if (STARTS_WITH_WORD(psz, "<key>ID</key>")) 1145 1220 { 1146 1221 REQUIRE_WORD(psz, "<key>ID</key>"); 1147 pszErr = vboxdmgXmlParseS32(&psz, &pThis->aRsrcs[iRsrc].aEntries[i].iId);1222 pszErr = dmgXmlParseS32(&psz, &pThis->aRsrcs[iRsrc].aEntries[i].iId); 1148 1223 } 1149 1224 else if (STARTS_WITH_WORD(psz, "<key>Name</key>")) 1150 1225 { 1151 1226 REQUIRE_WORD(psz, "<key>Name</key>"); 1152 pszErr = vboxdmgXmlParseString(&psz, &pThis->aRsrcs[iRsrc].aEntries[i].pszName);1227 pszErr = dmgXmlParseString(&psz, &pThis->aRsrcs[iRsrc].aEntries[i].pszName); 1153 1228 } 1154 1229 else if (STARTS_WITH_WORD(psz, "<key>CFName</key>")) 1155 1230 { 1156 1231 REQUIRE_WORD(psz, "<key>CFName</key>"); 1157 pszErr = vboxdmgXmlParseString(&psz, &pThis->aRsrcs[iRsrc].aEntries[i].pszCFName);1232 pszErr = dmgXmlParseString(&psz, &pThis->aRsrcs[iRsrc].aEntries[i].pszCFName); 1158 1233 } 1159 1234 else if (STARTS_WITH_WORD(psz, "<key>Data</key>")) 1160 1235 { 1161 1236 REQUIRE_WORD(psz, "<key>Data</key>"); 1162 pszErr = vboxdmgXmlParseData(&psz, &pThis->aRsrcs[iRsrc].aEntries[i].pbData, &pThis->aRsrcs[iRsrc].aEntries[i].cbData);1237 pszErr = dmgXmlParseData(&psz, &pThis->aRsrcs[iRsrc].aEntries[i].pbData, &pThis->aRsrcs[iRsrc].aEntries[i].cbData); 1163 1238 } 1164 1239 else … … 1207 1282 */ 1208 1283 static int dmgGetRsrcData(PDMGIMAGE pThis, const char *pcszRsrcName, 1209 PC VBOXUDIFRSRCARRAY *ppcRsrc)1284 PCDMGUDIFRSRCARRAY *ppcRsrc) 1210 1285 { 1211 1286 int rc = VERR_NOT_FOUND; … … 1228 1303 * 1229 1304 * @returns VBox status code. 1230 * @param pThis DMG instance data. 1231 * @param pBlkxDesc The blkx descriptor. 1232 */ 1233 static int vboxdmgExtentCreateFromBlkxDesc(PDMGIMAGE pThis, uint64_t offDevice, PVBOXBLKXDESC pBlkxDesc) 1305 * @param pThis DMG instance data. 1306 * @param uSectorPart First sector the partition owning the blkx descriptor has. 1307 * @param pBlkxDesc The blkx descriptor. 1308 */ 1309 static int dmgExtentCreateFromBlkxDesc(PDMGIMAGE pThis, uint64_t uSectorPart, PDMGBLKXDESC pBlkxDesc) 1234 1310 { 1235 1311 int rc = VINF_SUCCESS; … … 1237 1313 PDMGEXTENT pExtentNew = NULL; 1238 1314 1239 if (pBlkxDesc->u32Type == VBOXBLKXDESC_TYPE_RAW)1315 if (pBlkxDesc->u32Type == DMGBLKXDESC_TYPE_RAW) 1240 1316 enmExtentTypeNew = DMGEXTENTTYPE_RAW; 1241 else if (pBlkxDesc->u32Type == VBOXBLKXDESC_TYPE_IGNORE)1317 else if (pBlkxDesc->u32Type == DMGBLKXDESC_TYPE_IGNORE) 1242 1318 enmExtentTypeNew = DMGEXTENTTYPE_ZERO; 1319 else if (pBlkxDesc->u32Type == DMGBLKXDESC_TYPE_ZLIB) 1320 enmExtentTypeNew = DMGEXTENTTYPE_COMP_ZLIB; 1243 1321 else 1322 { 1244 1323 AssertMsgFailed(("This method supports only raw or zero extents!\n")); 1245 1324 return VERR_NOT_SUPPORTED; 1325 } 1326 1327 /** @todo: Merge raw extents if possible to save memory. */ 1246 1328 #if 0 1247 1329 pExtentNew = pThis->pExtentLast; 1248 1330 if ( pExtentNew 1249 1331 && pExtentNew->enmType == enmExtentTypeNew 1250 && pExtentNew->offExtent + pExtentNew->cbExtent == offDevice + pBlkxDesc->u64SectorStart * VBOXDMG_SECTOR_SIZE; 1332 && enmExtentTypeNew == DMGEXTENTTYPE_RAW 1333 && pExtentNew->uSectorExtent + pExtentNew->cSectorsExtent == offDevice + pBlkxDesc->u64SectorStart * DMG_SECTOR_SIZE; 1251 1334 && pExtentNew->offFileStart + pExtentNew->cbExtent == pBlkxDesc->offData) 1252 1335 { … … 1257 1340 #endif 1258 1341 { 1259 /* Create a new extent. */ 1260 pExtentNew = (PDMGEXTENT)RTMemAllocZ(sizeof(DMGEXTENT)); 1261 if (pExtentNew) 1342 if (pThis->cExtentsMax == pThis->cExtents) 1262 1343 { 1263 pExtentNew->pNext = NULL; 1264 pExtentNew->enmType = enmExtentTypeNew; 1265 pExtentNew->offExtent = offDevice + pBlkxDesc->u64SectorStart * VBOXDMG_SECTOR_SIZE; 1266 pExtentNew->offFileStart = pBlkxDesc->offData; 1267 pExtentNew->cbExtent = pBlkxDesc->u64SectorCount * VBOXDMG_SECTOR_SIZE; 1268 Assert( pBlkxDesc->cbData == pBlkxDesc->u64SectorCount * VBOXDMG_SECTOR_SIZE 1269 || enmExtentTypeNew == DMGEXTENTTYPE_ZERO); 1270 1271 if (!pThis->pExtentLast) 1344 pThis->cExtentsMax += 64; 1345 1346 /* Increase the array. */ 1347 PDMGEXTENT paExtentsNew = (PDMGEXTENT)RTMemRealloc(pThis->paExtents, sizeof(DMGEXTENT) * pThis->cExtentsMax); 1348 if (!paExtentsNew) 1272 1349 { 1273 pThis->pExtentFirst = pExtentNew;1274 pThis-> pExtentLast = pExtentNew;1350 rc = VERR_NO_MEMORY; 1351 pThis->cExtentsMax -= 64; 1275 1352 } 1276 1353 else 1277 { 1278 pThis->pExtentLast->pNext = pExtentNew; 1279 pThis->pExtentLast = pExtentNew; 1280 } 1354 pThis->paExtents = paExtentsNew; 1355 } 1356 1357 if (RT_SUCCESS(rc)) 1358 { 1359 pExtentNew = &pThis->paExtents[pThis->cExtents++]; 1360 1361 pExtentNew->enmType = enmExtentTypeNew; 1362 pExtentNew->uSectorExtent = uSectorPart + pBlkxDesc->u64SectorStart; 1363 pExtentNew->cSectorsExtent = pBlkxDesc->u64SectorCount; 1364 pExtentNew->offFileStart = pBlkxDesc->offData; 1365 pExtentNew->cbFile = pBlkxDesc->cbData; 1366 } 1367 } 1368 1369 return rc; 1370 } 1371 1372 /** 1373 * Find the extent for the given sector number. 1374 */ 1375 static PDMGEXTENT dmgExtentGetFromOffset(PDMGIMAGE pThis, uint64_t uSector) 1376 { 1377 /* 1378 * We assume that the array is ordered from lower to higher sector 1379 * numbers. 1380 * This makes it possible to bisect the array to find the extent 1381 * faster than using a linked list. 1382 */ 1383 PDMGEXTENT pExtent = NULL; 1384 unsigned idxCur = pThis->idxExtentLast; 1385 unsigned idxMax = pThis->cExtents; 1386 unsigned idxMin = 0; 1387 1388 while (idxMin < idxMax) 1389 { 1390 PDMGEXTENT pExtentCur = &pThis->paExtents[idxCur]; 1391 1392 /* Determine the search direction. */ 1393 if (uSector < pExtentCur->uSectorExtent) 1394 { 1395 /* Search left from the current extent. */ 1396 idxMax = idxCur; 1397 } 1398 else if (uSector >= pExtentCur->uSectorExtent + pExtentCur->cSectorsExtent) 1399 { 1400 /* Search right from the current extent. */ 1401 idxMin = idxCur; 1281 1402 } 1282 1403 else 1283 rc = VERR_NO_MEMORY; 1284 } 1285 1286 return rc; 1287 } 1288 1289 /** 1290 * Find the extent for the given offset. 1291 */ 1292 static PDMGEXTENT dmgExtentGetFromOffset(PDMGIMAGE pThis, uint64_t uOffset) 1293 { 1294 PDMGEXTENT pExtent = pThis->pExtentFirst; 1295 1296 while ( pExtent 1297 && ( uOffset < pExtent->offExtent 1298 || uOffset - pExtent->offExtent >= pExtent->cbExtent)) 1299 pExtent = pExtent->pNext; 1404 { 1405 /* The sector lies in the extent, stop searching. */ 1406 pExtent = pExtentCur; 1407 break; 1408 } 1409 1410 idxCur = idxMin + (idxMax - idxMin) / 2; 1411 } 1412 1413 if (pExtent) 1414 pThis->idxExtentLast = idxCur; 1300 1415 1301 1416 return pExtent; … … 1305 1420 * Goes through the BLKX structure and creates the necessary extents. 1306 1421 */ 1307 static int vboxdmgBlkxParse(PDMGIMAGE pThis, PVBOXBLKX pBlkx)1422 static int dmgBlkxParse(PDMGIMAGE pThis, PDMGBLKX pBlkx) 1308 1423 { 1309 1424 int rc = VINF_SUCCESS; 1310 P VBOXBLKXDESC pBlkxDesc = (PVBOXBLKXDESC)(pBlkx + 1);1425 PDMGBLKXDESC pBlkxDesc = (PDMGBLKXDESC)(pBlkx + 1); 1311 1426 1312 1427 for (unsigned i = 0; i < pBlkx->cBlocksRunCount; i++) 1313 1428 { 1314 vboxdmgBlkxDescFile2HostEndian(pBlkxDesc);1429 dmgBlkxDescFile2HostEndian(pBlkxDesc); 1315 1430 1316 1431 switch (pBlkxDesc->u32Type) 1317 1432 { 1318 case VBOXBLKXDESC_TYPE_RAW: 1319 case VBOXBLKXDESC_TYPE_IGNORE: 1433 case DMGBLKXDESC_TYPE_RAW: 1434 case DMGBLKXDESC_TYPE_IGNORE: 1435 case DMGBLKXDESC_TYPE_ZLIB: 1320 1436 { 1321 rc = vboxdmgExtentCreateFromBlkxDesc(pThis, pBlkx->cSectornumberFirst * VBOXDMG_SECTOR_SIZE, pBlkxDesc);1437 rc = dmgExtentCreateFromBlkxDesc(pThis, pBlkx->cSectornumberFirst, pBlkxDesc); 1322 1438 break; 1323 1439 } 1324 case VBOXBLKXDESC_TYPE_COMMENT:1325 case VBOXBLKXDESC_TYPE_TERMINATOR:1440 case DMGBLKXDESC_TYPE_COMMENT: 1441 case DMGBLKXDESC_TYPE_TERMINATOR: 1326 1442 break; 1327 1443 default: … … 1330 1446 } 1331 1447 1332 if ( pBlkxDesc->u32Type == VBOXBLKXDESC_TYPE_TERMINATOR1448 if ( pBlkxDesc->u32Type == DMGBLKXDESC_TYPE_TERMINATOR 1333 1449 || RT_FAILURE(rc)) 1334 1450 break; … … 1383 1499 if (RT_FAILURE(rc)) 1384 1500 return rc; 1385 vboxdmgUdifFtrFile2HostEndian(&pThis->Ftr);1501 dmgUdifFtrFile2HostEndian(&pThis->Ftr); 1386 1502 1387 1503 /* 1388 1504 * Do we recognize the footer structure? If so, is it valid? 1389 1505 */ 1390 if (pThis->Ftr.u32Magic != VBOXUDIF_MAGIC)1506 if (pThis->Ftr.u32Magic != DMGUDIF_MAGIC) 1391 1507 return VERR_VD_DMG_INVALID_HEADER; 1392 if (pThis->Ftr.u32Version != VBOXUDIF_VER_CURRENT)1508 if (pThis->Ftr.u32Version != DMGUDIF_VER_CURRENT) 1393 1509 return VERR_VD_DMG_INVALID_HEADER; 1394 1510 if (pThis->Ftr.cbFooter != sizeof(pThis->Ftr)) 1395 1511 return VERR_VD_DMG_INVALID_HEADER; 1396 1512 1397 if (! vboxdmgUdifFtrIsValid(&pThis->Ftr, pThis->cbFile - sizeof(pThis->Ftr)))1398 { 1399 VBOXDMG_PRINTF(("Bad DMG: '%s' cbFile=%RTfoff\n", pThis->pszFilename, pThis->cbFile));1513 if (!dmgUdifFtrIsValid(&pThis->Ftr, pThis->cbFile - sizeof(pThis->Ftr))) 1514 { 1515 DMG_PRINTF(("Bad DMG: '%s' cbFile=%RTfoff\n", pThis->pszFilename, pThis->cbFile)); 1400 1516 return VERR_VD_DMG_INVALID_HEADER; 1401 1517 } 1402 1518 1403 pThis->cbSize = pThis->Ftr.cSectors * VBOXDMG_SECTOR_SIZE;1519 pThis->cbSize = pThis->Ftr.cSectors * DMG_SECTOR_SIZE; 1404 1520 1405 1521 /* … … 1414 1530 { 1415 1531 pszXml[cchXml] = '\0'; 1416 const char *pszError = vboxdmgOpenXmlToRsrc(pThis, pszXml);1532 const char *pszError = dmgOpenXmlToRsrc(pThis, pszXml); 1417 1533 if (!pszError) 1418 1534 { 1419 PC VBOXUDIFRSRCARRAY pRsrcBlkx = NULL;1535 PCDMGUDIFRSRCARRAY pRsrcBlkx = NULL; 1420 1536 1421 1537 rc = dmgGetRsrcData(pThis, "blkx", &pRsrcBlkx); … … 1424 1540 for (unsigned idxBlkx = 0; idxBlkx < pRsrcBlkx->cEntries; idxBlkx++) 1425 1541 { 1426 P VBOXBLKX pBlkx = NULL;1427 1428 if (pRsrcBlkx->aEntries[idxBlkx].cbData < sizeof( VBOXBLKX))1542 PDMGBLKX pBlkx = NULL; 1543 1544 if (pRsrcBlkx->aEntries[idxBlkx].cbData < sizeof(DMGBLKX)) 1429 1545 { 1430 1546 rc = VERR_VD_DMG_INVALID_HEADER; … … 1432 1548 } 1433 1549 1434 pBlkx = (P VBOXBLKX)RTMemAllocZ(pRsrcBlkx->aEntries[idxBlkx].cbData);1550 pBlkx = (PDMGBLKX)RTMemAllocZ(pRsrcBlkx->aEntries[idxBlkx].cbData); 1435 1551 if (!pBlkx) 1436 1552 { … … 1441 1557 memcpy(pBlkx, pRsrcBlkx->aEntries[idxBlkx].pbData, pRsrcBlkx->aEntries[idxBlkx].cbData); 1442 1558 1443 vboxdmgBlkxFile2HostEndian(pBlkx);1444 1445 if ( vboxdmgBlkxIsValid(pBlkx)1446 && pRsrcBlkx->aEntries[idxBlkx].cbData == pBlkx->cBlocksRunCount * sizeof( VBOXBLKXDESC) + sizeof(VBOXBLKX))1447 rc = vboxdmgBlkxParse(pThis, pBlkx);1559 dmgBlkxFile2HostEndian(pBlkx); 1560 1561 if ( dmgBlkxIsValid(pBlkx) 1562 && pRsrcBlkx->aEntries[idxBlkx].cbData == pBlkx->cBlocksRunCount * sizeof(DMGBLKXDESC) + sizeof(DMGBLKX)) 1563 rc = dmgBlkxParse(pThis, pBlkx); 1448 1564 else 1449 1565 rc = VERR_VD_DMG_INVALID_HEADER; … … 1461 1577 else 1462 1578 { 1463 VBOXDMG_PRINTF(("**** XML DUMP BEGIN ***\n%s\n**** XML DUMP END ****\n", pszXml));1464 VBOXDMG_PRINTF(("**** Bad XML at %#lx (%lu) ***\n%.256s\n**** Bad XML END ****\n",1579 DMG_PRINTF(("**** XML DUMP BEGIN ***\n%s\n**** XML DUMP END ****\n", pszXml)); 1580 DMG_PRINTF(("**** Bad XML at %#lx (%lu) ***\n%.256s\n**** Bad XML END ****\n", 1465 1581 (unsigned long)(pszError - pszXml), (unsigned long)(pszError - pszXml), pszError)); 1466 1582 rc = VERR_VD_DMG_XML_PARSE_ERROR; … … 1483 1599 PVDIOSTORAGE pStorage; 1484 1600 uint64_t cbFile, offFtr = 0; 1485 VBOXUDIF Ftr;1601 DMGUDIF Ftr; 1486 1602 1487 1603 /* Get I/O interface. */ … … 1514 1630 if (RT_SUCCESS(rc)) 1515 1631 { 1516 vboxdmgUdifFtrFile2HostEndian(&Ftr);1632 dmgUdifFtrFile2HostEndian(&Ftr); 1517 1633 1518 1634 /* 1519 1635 * Do we recognize this stuff? Does it look valid? 1520 1636 */ 1521 if ( Ftr.u32Magic == VBOXUDIF_MAGIC1522 && Ftr.u32Version == VBOXUDIF_VER_CURRENT1637 if ( Ftr.u32Magic == DMGUDIF_MAGIC 1638 && Ftr.u32Version == DMGUDIF_VER_CURRENT 1523 1639 && Ftr.cbFooter == sizeof(Ftr)) 1524 1640 { 1525 if ( vboxdmgUdifFtrIsValid(&Ftr, offFtr))1641 if (dmgUdifFtrIsValid(&Ftr, offFtr)) 1526 1642 rc = VINF_SUCCESS; 1527 1643 else 1528 1644 { 1529 VBOXDMG_PRINTF(("Bad DMG: '%s' offFtr=%RTfoff\n", pszFilename, offFtr));1645 DMG_PRINTF(("Bad DMG: '%s' offFtr=%RTfoff\n", pszFilename, offFtr)); 1530 1646 rc = VERR_VD_DMG_INVALID_HEADER; 1531 1647 } … … 1655 1771 1656 1772 AssertPtr(pThis); 1657 Assert(uOffset % 512== 0);1658 Assert(cbToRead % 512== 0);1773 Assert(uOffset % DMG_SECTOR_SIZE == 0); 1774 Assert(cbToRead % DMG_SECTOR_SIZE == 0); 1659 1775 1660 1776 if ( uOffset + cbToRead > pThis->cbSize … … 1665 1781 } 1666 1782 1667 pExtent = dmgExtentGetFromOffset(pThis, uOffset);1783 pExtent = dmgExtentGetFromOffset(pThis, DMG_BYTE2BLOCK(uOffset)); 1668 1784 1669 1785 if (pExtent) 1670 1786 { 1671 uint64_t offExtentRel = uOffset - pExtent->offExtent;1787 uint64_t uExtentRel = DMG_BYTE2BLOCK(uOffset) - pExtent->uSectorExtent; 1672 1788 1673 1789 /* Remain in this extent. */ 1674 cbToRead = RT_MIN(cbToRead, pExtent->cbExtent - offExtentRel);1790 cbToRead = RT_MIN(cbToRead, DMG_BLOCK2BYTE(pExtent->cSectorsExtent - uExtentRel)); 1675 1791 1676 1792 switch (pExtent->enmType) … … 1678 1794 case DMGEXTENTTYPE_RAW: 1679 1795 { 1680 rc = dmgFileReadSync(pThis, pExtent->offFileStart + offExtentRel, pvBuf, cbToRead, NULL);1796 rc = dmgFileReadSync(pThis, pExtent->offFileStart + DMG_BLOCK2BYTE(uExtentRel), pvBuf, cbToRead, NULL); 1681 1797 break; 1682 1798 } … … 1684 1800 { 1685 1801 memset(pvBuf, 0, cbToRead); 1802 break; 1803 } 1804 case DMGEXTENTTYPE_COMP_ZLIB: 1805 { 1806 if (pThis->pExtentDecomp != pExtent) 1807 { 1808 if (DMG_BLOCK2BYTE(pExtent->cSectorsExtent) > pThis->cbDecompExtent) 1809 { 1810 if (RT_LIKELY(pThis->pvDecompExtent)) 1811 RTMemFree(pThis->pvDecompExtent); 1812 1813 pThis->pvDecompExtent = RTMemAllocZ(DMG_BLOCK2BYTE(pExtent->cSectorsExtent)); 1814 if (!pThis->pvDecompExtent) 1815 rc = VERR_NO_MEMORY; 1816 else 1817 pThis->cbDecompExtent = DMG_BLOCK2BYTE(pExtent->cSectorsExtent); 1818 } 1819 1820 if (RT_SUCCESS(rc)) 1821 { 1822 rc = dmgFileInflateSync(pThis, pExtent->offFileStart, pExtent->cbFile, 1823 pThis->pvDecompExtent, 1824 RT_MIN(pThis->cbDecompExtent, DMG_BLOCK2BYTE(pExtent->cSectorsExtent))); 1825 if (RT_SUCCESS(rc)) 1826 pThis->pExtentDecomp = pExtent; 1827 } 1828 } 1829 1830 if (RT_SUCCESS(rc)) 1831 memcpy(pvBuf, (uint8_t *)pThis->pvDecompExtent + DMG_BLOCK2BYTE(uExtentRel), cbToRead); 1686 1832 break; 1687 1833 }
Note:
See TracChangeset
for help on using the changeset viewer.